Reading MXS files
Reading MXS files is useful for importing data from them into a 3D platform. All the functions needed are in maxwell.h header, every "set" function has a "get" function.
This is an example of how to read an MXS file:
#include "maxwell.h" //------------------------ // MXS READER EXAMPLE //------------------------ class MxsReader { public: enum ReadStatus { MXS_READED_OK = 0, MXS_ERR_NO_FILENAME, // no me has pasado nombre MXS_ERR_CANT_OPEN, // no se puede abrir el archivo MXS_ERR_BAD_FORMAT, // formato chungo MXS_ERR_BAD_GEOMETRY, // no hay geometria MXS_ERR_MEM_ERROR, // error memoria MXS_ERR_SYNTAX_ERROR, // error de sintaxis MXS_ERR_UNKN_WRITE_FORMAT, // tipo desconocido para escribir MXS_ERR_UNEXPECTED_FEOF, // fin de archivo antes de tiempo }; public: MxsReader( void ) { } ~MxsReader() { } int readScene( const bool& reload = false, const bool& importFromLibrary = false ); void readRenderOptions( void ); void readCameras( void ); void readSky( void ); void readHdr( void ); void readMaterials( void ); void readGeometry( void ); void readMatrixAndAttributesOfObject( Cmaxwell::Cobject curObj ); void readMaterialsOfObject( Cmaxwell::Cobject curObj ); void readGeometryOfObject( Cmaxwell::Cobject curObj ); void readInstance( Cmaxwell::Cobject curObj ); private: Cmaxwell* pScene; }; /////////////////////////////////////////////////////////////////////////////////////////////////// byte mxsReadCallback( byte type, const char* pMethod, const char* pError, const void* pValue ) { // Callback used by Maxwell to give info during import/export process if( type == 0 ) { // There is an error String msgError = "Errors in loading Mxs process! \n"; msgError += String( "%1: %2" ).arg( pMethod ).arg( pError ); return ( 0 ); } return ( 1 ); } /////////////////////////////////////////////////////////////////////////////////////////////////// int MxsReader::readScene( const char& mxsPath ) { Cmaxwell* pScene = new Cmaxwell( mxsReadCallback ); byte mxsReadStatus = pScene->readMXS( mxsPath ); if ( mxsReadStatus != 1 ) { printMsg( "Error reading MXS file!" ); return 0; } dword nObjects_; dword nMaterials_; dword nTriangleGroups_; dword nCameras_; pScene->getNumObjects( nObjects_ ); pScene->getNumMaterials( nMaterials_ ); pScene->getNumClusters( nTriangleGroups_ ); pScene->getNumCameras( nCameras_ ); // Read all the scene readRenderOptions(); readCameras(); readSky(); readHdr(); readMaterials(); readGeometry(); readGroups(); readTriangleGroups(); pScene->freeScene(); delete ( pScene ); pScene = NULL; return MXS_READED_OK; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void MxsReader::readRenderOptions( void ) { dword maxTime, numThreads; float samplingLevel; real monitorGamma, burn, advancedMonitorGamma, advancedBurn; byte doMultilight, enableHD; byte disableBitmaps = 0; byte doDirectLayer, doIndirectLayer, doDRFL, doDRFR, doIRFL, doIRFR; byte outputBitDepthMode; const char* imagePath = pScene->getPath( "RENDER", outputBitDepthMode ); char mxiChar[512]; pScene->getRenderParameter ( "MXI FULLNAME", 0, &mxiChar ); // Color space dword colorSpace = 0; pScene->getColorSpace( colorSpace ); renderOptns->colorSpaceCombo->setCurrentIndex( colorSpace ); pScene->getRenderParameter( "STOP TIME", sizeof ( dword ), &maxTime ); pScene->getRenderParameter( "SAMPLING LEVEL", sizeof ( float ), &samplingLevel ); pScene->getRenderParameter( "NUM THREADS", sizeof ( dword ), &numThreads ); pScene->getRenderParameter ("USE MULTILIGHT",sizeof(byte), &doMultilight); pScene->getRenderParameter ("USE HARDDISK",sizeof(byte), &enableHD); pScene->getRenderParameter ("DO DIRECT LAYER",sizeof(byte), &doDirectLayer); pScene->getRenderParameter ("DO INDIRECT LAYER",sizeof(byte), &doIndirectLayer); pScene->getRenderParameter ("DO DIRECT REFLECTION CAUSTIC LAYER",sizeof(byte), &doDRFL); pScene->getRenderParameter ("DO INDIRECT REFLECTION CAUSTIC LAYER",sizeof(byte), &doIRFL); pScene->getRenderParameter ("DO DIRECT REFRACTION CAUSTIC LAYER",sizeof(byte), &doDRFR); pScene->getRenderParameter ("DO INDIRECT REFRACTION CAUSTIC LAYER",sizeof(byte), &doIRFR); byte doRenderChannel, doAlphaChannel, doAlphaOpaqueChannel, doIdObjectChannel, doIdMaterialChannel; byte doShadowsChannel, doVelocityChannel, doZbufferChannel, doDiffussePass, doReflectionPass; real zRange[2]; pScene->getRenderParameter ("DO RENDER CHANNEL",sizeof(byte), &doRenderChannel); pScene->getRenderParameter ("DO ALPHA CHANNEL",sizeof(byte), &doAlphaChannel); pScene->getRenderParameter ("OPAQUE ALPHA",sizeof(byte), &doAlphaOpaqueChannel); pScene->getRenderParameter ("DO IDOBJECT CHANNEL",sizeof(byte), &doIdObjectChannel); pScene->getRenderParameter ("DO IDMATERIAL CHANNEL",sizeof(byte), &doIdMaterialChannel); pScene->getRenderParameter ("DO SHADOW PASS CHANNEL",sizeof(byte), &doShadowsChannel); pScene->getRenderParameter ("DO VELOCITY CHANNEL",sizeof(byte), &doVelocityChannel); pScene->getRenderParameter ("DO ZBUFFER CHANNEL",sizeof(byte), &doZbufferChannel); pScene->getRenderParameter ("ZBUFFER RANGE", 2 * sizeof( real ), zRange); pScene->getRenderParameter( "DO DIFFUSE LAYER",sizeof(byte), &doDiffussePass ); pScene->getRenderParameter( "DO REFLECTION LAYER",sizeof(byte), &doReflectionPass ); pScene->getToneMapping( monitorGamma, burn ); // Simulens bool diffEnabled; real diffIntensity, diffFreq; const char* diffAperture = NULL; const char* diffObstacle = NULL; pScene->getDiffraction( diffEnabled, diffIntensity, diffFreq, &diffAperture, &diffObstacle ); if( diffEnabled ) renderOptns->diffractionCheck->setChecked( true ); if( diffAperture != NULL ) renderOptns->aperturePath->setPath( diffAperture ); if( diffObstacle != NULL ) renderOptns->obstaclePath->setPath( diffObstacle ); byte doScatt, doVignett; real scattering, vignetting; pScene->getRenderParameter ( "DO SCATTERING_LENS", sizeof( byte ), &doScatt ); pScene->getRenderParameter ( "SCATTERING_LENS", sizeof( real ), &scattering ); pScene->getRenderParameter ( "DO DEVIGNETTING", sizeof( byte ), &doVignett ); pScene->getRenderParameter ( "DEVIGNETTING", sizeof( real ), &vignetting ); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void MxsReader::readCameras( void ) { Cmaxwell::Ccamera::Citerator itcam; Cmaxwell::Ccamera curCamera = itcam.first( pScene ); while ( !curCamera.isNull() ) { Cpoint maxorigin, maxto; Cvector maxup; real maxfl, maxft, maxshut, maxfilw, maxfilh, maxiso, maxangle, maxpixelaspect, zClipMin, zClipMax, shiftLensX, shiftLensY; const char* maxdiaph; dword nSteps, maxblades, maxfps, maxxres, maxyres; bool zClipEnabled; QString candidateCamName = curCamera.getValues( nSteps, maxshut, maxfilw, maxfilh, maxiso, &maxdiaph, maxangle, maxblades, maxfps, maxxres, maxyres, maxpixelaspect ); curCamera.getStep( 0, maxorigin, maxto, maxup, maxfl, maxft ); real focalDistance( maxorigin.distance( maxto ) ); real correctedFocalLength = 1.0 / ( 1.0 / maxfl - 1.0 / focalDistance ); curCamera.getCutPlanes( zClipMin, zClipMax, zClipEnabled ); curCamera.getShiftLens( shiftLensX, shiftLensY ); bool isCamHidden = false; curCamera.isHide( isCamHidden ); // Set the active camera if ( pScene->getActiveCamera().getPointer() == curCamera.getPointer() ) { // This camera is the active one } curCamera = itcam.next(); } } // End readCameras ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void MxsReader::readSky( void ) { const char* activeSky = pScene->getActiveSky(); Crgb skyColor; real radianceScalar, longitude, latitude, timeOfDay, sunRot, sunTemperature, sunPowerScaleFactor, planetReflectance; real ozone, water, angstromTurbidity, wavelengthTurbidity, aerosolAlbedo, asimmetryFactor; int sm; dword dayOfYear, sunPositionType; byte useSunInConstant, sunActive; // Now the sky type is stored in the custom data if ( activeSky != NULL ) { // SKY DOME byte isSkyDomeOk = 0; isSkyDomeOk = pScene->getSkyConstant( skyColor, radianceScalar, useSunInConstant ); if( !isSkyDomeOk ) { printMsg( "Error reading sky dome" ); } // PHYSICHAL SKY byte isPhysicalSkyOk = 0; isPhysicalSkyOk = pScene->getPhysicalSkyGeometry( longitude, latitude, sm, dayOfYear, timeOfDay, sunRot, sunPositionType ); if( isPhysicalSkyOk ) { isPhysicalSkyOk = pScene->getPhysicalSkySun( sunActive, sunTemperature, sunPowerScaleFactor, planetReflectance ); isPhysicalSkyOk = pScene->getPhysicalSkyAtmosphere( ozone, water, angstromTurbidity, wavelengthTurbidity, aerosolAlbedo, asimmetryFactor ); } if( isPhysicalSkyOk ) { //... } else { printMsg( "Error reading physical sky" ); } if ( strncmp( activeSky, "CONSTANT", 8 ) == 0 ) { // Sky constant is active } else if ( strncmp( activeSky, "PHYSICAL", 8 ) == 0 ) { // Physical sky is active } } else //-->the sky is null { } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void MxsReader::readHdr( void ) { bool isEnv = false; pScene->isEnvironmentEnabled( isEnv ); char* bkTexture = NULL; char* rflTexture = NULL; char* rfrTexture = NULL; char* illumTexture = NULL; QString bkTextureFinal, rflTextureFinal, rfrTextureFinal, illumTextureFinal; bool useActiveSky = false; bool sphMapping = true; real intensity, uTile, vTile, uOffset, vOffset; pScene->getEnvironmentLayer( "background", bkTexture, useActiveSky, sphMapping, intensity, uTile, vTile, uOffset, vOffset ); pScene->getEnvironmentLayer( "reflection", rflTexture, useActiveSky, sphMapping, intensity, uTile, vTile, uOffset, vOffset ); pScene->getEnvironmentLayer( "refraction", rfrTexture, useActiveSky, sphMapping, intensity, uTile, vTile, uOffset, vOffset ); pScene->getEnvironmentLayer( "illumination", illumTexture, useActiveSky, sphMapping, intensity, uTile, vTile, uOffset, vOffset ); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void MxsReader::readMaterials( void ) { Cmaxwell::Cmaterial::Citerator itm; Cmaxwell::Cmaterial curMat = itm.first( pScene ); while ( !curMat.isNull() ) { QString matName = curMat.getName(); //... read material parameters.... curMat = itm.next(); } // End of traversing materials } // End of Read materials /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void MxsReader::readGeometry( void ) { Cmaxwell::Cobject::Citerator it; Cmaxwell::Cobject curObj = it.first( pScene ); while ( !curObj.isNull() ) { byte bOk; curObj.isMesh( bOk ); // Look for instances if ( bOk == 0 ) { curObj.isInstance( bOk ); if ( bOk == 1 ) { readInstance( curObj ); } curObj = it.next (); continue; } char* objName = NULL; curObj.getName( &objName ); // Look for its parent Cmaxwell::Cobject parent; curObj.getParent( parent ); if( !parent.isNull() ) { char* parentNameAux = NULL; parent.getName( &parentNameAux ); } // Check if this is a null object dword nTriangulos = 0; dword nVertices = 0; dword nNormales = 0; dword nPositions = 0; isOk = curObj.getNumTriangles ( nTriangulos ); isOk = curObj.getNumVertexes ( nVertices ); isOk = curObj.getNumNormals ( nNormales ); if( nTriangulos == 0 || nVertices == 0 ) { // we have a null object or a Realflow renderkit object Cmaxwell::Cmaterial nullMat; curObj.getMaterial( nullMat ); bool isRfrk = false; pScene->isRFRK( curObj, isRfrk ); if( isRfrk ) { // Call pScene->getRFRKParameters( ... ); } readMatrixAndAttributesOfObject( curObj ); curObj = it.next(); continue; } // Read main object data readGeometryOfObject( curObj ); readMatrixAndAttributesOfObject( curObj ); readMaterialsOfObject( curObj ); curObj = it.next(); } // End traverse objects } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void MxsReader::readMatrixAndAttributesOfObject( Cmaxwell::Cobject curObj ) { // OBJECT TRANSFORMATIONS Cbase base, pivot; curObj.getBaseAndPivot( base, pivot ); bool refreshTransformValues = false; bool hasPosRotSca = false; byte isOk = curObj.isPosRotScaleInitialized( hasPosRotSca ); if( hasPosRotSca && isOk ) //We have true pos/rot/sca values ---> Cool { Cvector pos, rot, sca, pivPos, pivRot, shear; curObj.getPosition( pos ); curObj.getRotation( rot ); curObj.getScale( sca ); curObj.getPivotPosition( pivPos ); curObj.getPivotRotation( pivRot ); curObj.getShear( shear ); } // object attributtes bool attrib; curObj.getHide( attrib ); curObj.getHideToCamera( attrib ); curObj.getHideToReflectionsRefractions( attrib ); curObj.getHideToGI( attrib ); curObj.isExcludedOfCutPlanes( attrib ); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void MxsReader::readMaterialsOfObject( Cmaxwell::Cobject curObj ) { // ASSING MATERIALS TO OBJECT Cmaxwell::Cmaterial objMat; curObj.getMaterial( objMat ); if ( !objMat.isNull() ) { } else // objMat isNull() { // This object is multimaterial or has not material applied to some triangles } } // End of readMaterialsOfObject /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void MxsReader::readGeometryOfObject( Cmaxwell::Cobject curObj ) { dword nTriangulos = 0; dword nVertices = 0; dword nNormales = 0; dword nPositions = 0; curObj.getNumTriangles ( nTriangulos ); curObj.getNumVertexes ( nVertices ); curObj.getNumNormals ( nNormales ); curObj.getNumPositionsPerVertex( nPositions ); // Motion blur Cvector vecTemp; if ( nPositions <= 1 ) { // No motion blur for ( NL_UINT32 i = 0; i < nNormales; i++ ) { curObj.getNormal( i, 0, vecTemp ); } for ( NL_UINT32 i = 0; i < nVertices; i++ ) { curObj.getVertex( i, 0, vecTemp ); } } else // We have motion blur! { for ( NL_UINT32 i = 0; i < nNormales; i++ ) { curObj.getNormal( i, 0, vecTemp ); curObj.getNormal( i, 1, vecTemp ); } for ( NL_UINT32 i = 0; i < nVertices; i++ ) { curObj.getVertex( i, 0 /*MB substep*/, vecTemp ); curObj.getVertex( i, 1, vecTemp ); } } for ( NL_UINT32 i = 0; i < nTriangulos; i++ ) { dword iA, iB, iC, iG, nA, nB, nC; curObj.getTriangle( i, iA, iB, iC, nA, nB, nC ); } // Texture coordinates float* pChannelsUVW = NULL; dword nChannelsUVW = 0; curObj.getNumChannelsUVW( nChannelsUVW ); if ( nChannelsUVW > 0 ) { for ( NL_UINT32 iChannel = 0; iChannel < nChannelsUVW; iChannel++ ) { float u1, v1, w1, u2, v2, w2, u3, v3, w3; for ( NL_UINT32 it = 0; it < nTriangulos; it++ ) { curObj.getTriangleUVW( it, iChannel, u1, v1, w1, u2, v2, w2, u3, v3, w3 ); } } } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void MxsReader::readInstance( Cmaxwell::Cobject curObj ) { // Exactly as in objects char* objName = NULL; curObj.getName( &objName ); // get instance name Cmaxwell::Cobject curObjInstanced = curObj.getInstanced(); char* objNameInstanced = NULL; curObjInstanced.getName( &objNameInstanced ); //parent obj name Cbase instBase; curObj.getBase( instBase ); Cbase instPivot; curObj.getPivot( instPivot ); // Material Cmaxwell::Cmaterial instMat; curObj.getMaterial( instMat ); // Instance attributtes (the same as in objects) bool tempIsHide, tempIsHideToCamera, tempIsHideToRefAndRefr, tempIsHideToIG, tempIsExcludedFromZplanes; curObj.getHide( tempIsHide ); curObj.getHideToCamera( tempIsHideToCamera ); curObj.getHideToReflectionsRefractions( tempIsHideToRefAndRefr ); curObj.getHideToGI( tempIsHideToIG ); curObj.isExcludedOfCutPlanes( tempIsExcludedFromZplanes ); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////