How-To: Use HOOPS Exchange with LibConverter for Stream Cache export

How-To: Use HOOPS Exchange with LibConverter for Stream Cache export

If you are using HOOPS Communicator, you may want to take advantage of HOOPS Exchange’s advanced functions and conversion options before generating a Stream Cache model.

How-To

As you may know, LibConverter is a simple API included in the HOOPS Communicator package. converter.exe is actually using this API.
The project mini_converter is a good start point to use this API: HOOPS_Communicator\authoring\converter\example\sample_projects\mini_converter

  • The workflow you want to implement is:

CAD File -> [HOOPS Exchange C API] -> PRC ModelFile -> [LibConverter] -> SCS file

The most important API to know to implement this workflow is in LibConvert: bool Communicator::Importer::Load (void * modelFile )

Implementation

This is what you are going to do:

  • Initialize HOOPS Exchange C API

  • Import the CAD file using HOOPS Exchange in a PRC buffer A3DAsmModelFile*

  • Do whatever you want to A3DAsmModelFile* using HOOPS Exchange

  • Initialize LibConverter

  • Import the PRC buffer A3DAsmModelFile*

  • Export it to SCS

To initialize and use HOOPS Exchange, you can review the sample ImportExport from the HOOPS Exchange package.
The class A3DSDKHOOPSExchangeLoader makes it easier to use the API, and we show how to use it in our programming guide.

A3DSDKHOOPSExchangeLoader sHoopsExchangeLoader(_T(HOOPS_BINARY_DIRECTORY)); A3DImport sImport(acSrcFileName); // see A3DSDKInternalConvert.hxx for import and export detailed parameters CHECK_RET(sHoopsExchangeLoader.Import(sImport));

After you call the Import function, the PRC buffer will be in sHoopsExchangeLoader.m_psModelFile
So you can use later LibConverter like this:

SC_Import_Options importOptions; importer.Load(sHoopsExchangeLoader.m_psModelFile); SC_Export_Options exportOptions; // Export SSC exporter.WriteSC(nullptr, output.c_str(), exportOptions);

Sample

I don’t like using A3DSDKHOOPSExchangeLoader because this structure hides the actual call to the API. It makes it simpler, but it requires more includes that if you just do the direct calls. I think it makes the sample easier to read.

Here is a sample to demonstrate the implementation described above. To use it:

  • Replace the code from HOOPS_Communicator_2022_XX\authoring\converter\example\sample_projects\mini_converter\mini.cpp

  • Add in additional include directories the path to HOOPS_Exchange_Publish_2022_XX\include

  • Replace the path in the code (Commented with TODO when there is something to change )

#include "libconverter.h" using namespace Communicator; ///TODO: Add the Additional include directory = "[...]/HOOPS_Exchange_Publish_2022_XX\include" #define INITIALIZE_A3D_API #include <A3DSDKIncludes.h> #include <string> using namespace std; int main(int argc, char* argv[]) { ///TODO: the license variable is not used, you may pass "" as the first argument. ///USAGE: ./mini_converter "" "CAD/FILE/INPUT.CAD" "PATH/TO/SCS.SCS" string input, output; // Obtain the input and output filenames size_t n = 1; // Skip verb if (n < argc) input = argv[n++]; if (n < argc) output = argv[n++]; // Initiliaze HOOPS Exchange ///TODO: REPLACE THE PATH TO BIN\\WIN64_VC140 A3DStatus iRet; if (!A3DSDKLoadLibrary("HOOPS_Exchange_Publish_2022_SP1_U1\\bin\\win64_v140")) return A3D_ERROR; ///TODO: I'm using directly the HOOPS_LICENSE variable defined in hoops_license.h. The license you generate on our developer zone is unified, //that means it works with HOOPS COmmunicator, HOOPS Exchange, LibConverter, etc... A3DLicPutUnifiedLicense(HOOPS_LICENSE); A3DInt32 iMajorVersion = 0, iMinorVersion = 0; iRet = A3DDllGetVersion(&iMajorVersion, &iMinorVersion); if (iRet != A3D_SUCCESS) return iRet; iRet = A3DDllInitialize(A3D_DLL_MAJORVERSION, A3D_DLL_MINORVERSION); if (iRet != A3D_SUCCESS) return iRet; // Import A3DAsmModelFile* m_psModelFile; A3DRWParamsLoadData m_sLoadData; A3D_INITIALIZE_DATA(A3DRWParamsLoadData, m_sLoadData); m_sLoadData.m_sGeneral.m_bReadSolids = true; m_sLoadData.m_sGeneral.m_bReadSurfaces = true; m_sLoadData.m_sGeneral.m_bReadWireframes = true; m_sLoadData.m_sGeneral.m_bReadPmis = true; m_sLoadData.m_sGeneral.m_bReadAttributes = true; m_sLoadData.m_sGeneral.m_bReadHiddenObjects = true; m_sLoadData.m_sGeneral.m_bReadConstructionAndReferences = false; m_sLoadData.m_sGeneral.m_bReadActiveFilter = true; m_sLoadData.m_sGeneral.m_eReadingMode2D3D = kA3DRead_3D; m_sLoadData.m_sGeneral.m_eReadGeomTessMode = kA3DReadGeomAndTess; m_sLoadData.m_sGeneral.m_eDefaultUnit = kA3DUnitUnknown; m_sLoadData.m_sTessellation.m_eTessellationLevelOfDetail = kA3DTessLODMedium; m_sLoadData.m_sAssembly.m_bUseRootDirectory = true; m_sLoadData.m_sMultiEntries.m_bLoadDefault = true; m_sLoadData.m_sPmi.m_bAlwaysSubstituteFont = false; m_sLoadData.m_sPmi.m_pcSubstitutionFont = (char*)"Myriad CAD"; iRet = A3DAsmModelFileLoadFromFile(input.c_str(), &m_sLoadData, &m_psModelFile); if (iRet != A3D_SUCCESS) return iRet; // HERE YOU CAN PROCESS m_psModelFile WITH HOOPS EXCHANGE ADVANCED FUNCTION Converter converter; // License Registration converter.Init(HOOPS_LICENSE); Importer importer; // Import Initialization if (!importer.Init(&converter)) return EXIT_FAILURE; //Import the PRC buffer directly SC_Import_Options importOptions; // Import if (!importer.Load(m_psModelFile)) return EXIT_FAILURE; Exporter exporter; // Export Initialization if (!exporter.Init(&importer)) return EXIT_FAILURE; SC_Export_Options exportOptions; // Export Stream Cache Model //export SCS if (!exporter.WriteSC(nullptr, output.c_str(), exportOptions)) return EXIT_FAILURE; return EXIT_SUCCESS; }

With this workflow, you have complete access to m_sLoadData (the import options). It includes more parameters than converter.exe.

You can also process the model before export (for example, Sewing to repair BRep).

To follow-up or participate in the discussion, see this article in our Community Forum : https://forum.techsoft3d.com/t/how-to-use-hoops-exchange-with-libconverter-for-stream-cache-export/1501