====== Example: Materials Only ====== This is a straightforward example that focuses on pulling material definitions only. It does not query any geometry. Most queries are set up similarly to this example. The general set up is: - Make sure the callbacks are set (done once per application lifetime). - Allocate a new **SSteEngine** object. - Load the SpeedTree Model file ([[input|STE or SPM]]). - Create, init, and set the query options using **SSteGeometryOptions**. - Create and init the **SSteGeometry** object to hold the data. - Call **SteGetGeometry** to force a compute and population of the **SSteGeometry** object. - Pull needed data from **SSteGeometry** object. - Clean up by deleting the **SSteGeometry** and **SSteEngine** objects. #include #include "speedtree_engine.h" /////////////////////////////////////////////////////////////////////// // SpeedTree Engine API error callback static void MyEngineApiErrorCallback(const char* pError) { fprintf(stderr, " **[Error Report from SpeedTree Engine API]**: %s\n", pError); } /////////////////////////////////////////////////////////////////////// // SpeedTree Engine API message callback static void MyEngineApiMessageCallback(const char* pMessage) { fprintf(stderr, " [Message from SpeedTree Engine API]: %s\n", pMessage); } /////////////////////////////////////////////////////////////////////// // Example_MaterialsOnly bool Example_MaterialsOnly(const char* pModelFilename) { bool bSuccess = false; // register callback message functions; when api calls fail, messages will be sent here SteSetErrorFunction(MyEngineApiErrorCallback); SteSetMessageFunction(MyEngineApiMessageCallback); // uses a C interface -- objects are created and initialized through function calls SSteEngine* pEngine = SteNew( ); if (pEngine) { // this causes the model file to be loaded and parsed, but nothing is computed yet if (SteLoadSpeedTreeFile(pEngine, pModelFilename) == STE_SUCCESS) { // 'geometry' is used in a lot of these function names, but the materials are // the only part we're interested in in this example // use SSteGeometryOptions to isolate just materials SSteGeometryOptions sQueryOptions; SteInitGeometryOptions(pEngine, &sQueryOptions); // rely on mostly default values, but let's set a few specific to our needs sQueryOptions.m_bExport3dGeometry = false; sQueryOptions.m_eResolution = STE_RESOLUTION_DRAFT; // don't need detail // init structure to hold the materials SSteGeometry sGeometry; SteInitGeometry(&sGeometry); // causes a tree compute to make the data avaialble if (SteGetGeometry(pEngine, &sQueryOptions, &sGeometry) == STE_SUCCESS) { // report a few things about the materials now that have them printf("# of material: %d\n\n", sGeometry.m_nNumMaterials); for (int i = 0; i < sGeometry.m_nNumMaterials; ++i) { printf("material %d is called '%s' and has normal texture: [%s]\n", i, sGeometry.m_pMaterials[i].m_szName, sGeometry.m_pMaterials[i].m_aMaps[STE_MAP_NORMAL].m_szFilename); } // using C, so no destructors SteDeleteGeometry(&sGeometry); bSuccess = true; } else { // if there's a failure, a message will be sent via the callback } } else { // if there's a failure, a message will be sent via the callback } // using C, so no destructors SteDelete(pEngine); } return bSuccess; }