...
As you can see in the below link, in some cases parsing and interpreting the PRC structures is non-trivial.
We are providing sample source code to traverse the model file using Visitor pattern. This sample is reusable and you can port the code into your application as it is even you don’t know in details of the traversing manner.
...
Info |
---|
To run this application, it is necessary to specify source and destination CAD file names in to the Command Arguments value of Debugging page of the project property i.e.) |
...
Though you can find some sample projects including Visitor pattern, visitor pattern of the Collision sample will be the best for reuse.
Copy visitor folder from <HOOPS_Exchange_Publish SDK dir>\samples\exchange\exchangesource\Collision and past in the ImportTraverseExport folder
Back to the project of Visual Studio.
Create a new filter named “visitor” under the Header Files and add all header files in the visitor folder
Create a new filter named “visitor” under the Source Files and add all cpp files in the visitor folder
...
Thanks to the visitor pattern sample, now you can access model file from the root to leaves in correct manner. Though you can add your own retrieving and updating processes in it, we recommend you to make derived classes of A3DTreeVisitor so that you can divide code into common traverse and various use cases. You don't need to write traverse code in the each use case.
...
Create a derived class of A3DTreeVisitor
Code Block language cpp ... static MY_CHAR acLogFileName[_MAX_PATH * 2]; class myTreeVisitor: public A3DTreeVisitor { public: myTreeVisitor(A3DVisitorContainer* psContainer = NULL) : A3DTreeVisitor(psContainer) { psContainer->SetTraverseInstance(true); }; ~myTreeVisitor() {}; public: virtual A3DStatus visitEnter(const A3DProductOccurrenceConnector& sConnector) override { A3DStatus iRet = A3DTreeVisitor::visitEnter(sConnector); // My processes return iRet; } virtual A3DStatus visitLeave(const A3DProductOccurrenceConnector& sConnector) override { A3DStatus iRet = A3D_SUCCESS; // My processes iRet = A3DTreeVisitor::visitLeave(sConnector); return iRet; } }; void traverseModelFile(A3DAsmModelFile* pModelFile) ...
Use the derived myTreeVisitor class instead of A3DTessVisitor in the traverseModelFile function
Code Block ... // Prepare Tree traverse visitor and set to the container myTreeVisitor *pMyTreeVisitor = new myTreeVisitor(&sA3DVisitorContainer); sA3DVisitorContainer.push(pMyTreeVisitor); ...
Build the project
Make break points in the myTreeVisitor class and verify that the class is called
Info |
---|
In the A3DTreeVisitor, model file is traversed recursively from root (pModelFile) to leaves (Product Occurrence, Part definition, Representation Item, …). The In the above sample, you can implement your own processes when ProductOccurence Product Occurence is traversed by setting as |
...
Add code to log component names in the console
Code Block language cpp ... private: int m_iLevel = 0; public: virtual A3DStatus visitEnter(const A3DProductOccurrenceConnector& sConnector) override { A3DStatus iRet = A3DTreeVisitor::visitEnter(sConnector); // Increment level m_iLevel++; // Get the ProductOccurrence (PO) const A3DEntity* pEntity = sConnector.GetA3DEntity(); A3DAsmProductOccurrence* pOccurrence = (A3DAsmProductOccurrence*)pEntity; // Get RootBaseData of the PO A3DRootBaseData sRootBaseData; A3D_INITIALIZE_DATA(A3DRootBaseData, sRootBaseData); A3DRootBaseGet(pOccurrence, &sRootBaseData); // Get the PO name A3DUniChar acName[256]; if (sRootBaseData.m_pcName) A3DMiscUTF8ToUTF16(sRootBaseData.m_pcName, acName); else wcscpy_s(acName, _T("NO_NAME")); // Show the PO name with level for (int i = 0; i < m_iLevel; i++) _tprintf(_T("+ ")); _tprintf(_T("%s\n"), acName); return iRet; } virtual A3DStatus visitLeave(const A3DProductOccurrenceConnector& sConnector) override { A3DStatus iRet = A3D_SUCCESS; // Decrement level m_iLevel--; iRet = A3DTreeVisitor::visitLeave(sConnector); return iRet; } ...
Build the project
Verify that ProductOccurence Product Occurrence name are displayed in the condoleconsole
In the above image, we used Landing Gear model in the sample folder."$(HEXCHANGE_INSTALL_DIR)\samples\data\catiaV5\CV5_Landing Gear Model_LandingGear.CATProduct"
...
Add
CONNECT_COLORS
to the visitor containerCode Block language cpp ... #include "visitor/VisitorTree.h" #include "visitor/VisitorCascadedAttribute.h" #include "visitor/CascadedAttributeConnector.h" ... void traverseModelFile(A3DAsmModelFile* pModelFile) { // Prepare Visitor container A3DVisitorContainer sA3DVisitorContainer(CONNECT_TRANSFO | CONNECT_COLORS); sA3DVisitorContainer.SetTraverseInstance(true); ...
Add code to access visibility info
Code Block language cpp ... virtual A3DStatus visitEnter(const A3DProductOccurrenceConnector& sConnector) override { ... _tprintf(_T("%s"), acName); A3DVisitorColorMaterials *pA3DCascadedVisitor = static_cast<A3DVisitorColorMaterials*>(m_psContainer->GetVisitorByName("CascadedAttribute")); if (pA3DCascadedVisitor) { ColorMaterialsConnector sColorConnector(nullptr); pA3DCascadedVisitor->GetColorMaterialConnector(sColorConnector); if (sColorConnector.IsShow()) _tprintf(_T("\n")); else _tprintf(_T(" (Hidden)\n")); } return iRet; } ...
Build the project
Verify that
(Hidden)
is added after the ProductOccurence Product Occurence name
...
Getting instance
...
transformation
You will see in HDV that some components are used multiple times in the assembly model.
...
You will see that the visitor to get transform is already assigned to the visitor container.A3DVisitorContainer sA3DVisitorContainer(CONNECT_TRANSFO | CONNECT_COLORS);
Add override function of PartConnector A3DPartConnector and get the part transform
Code Block language cpp class myTreeVisitor: public A3DTreeVisitor { ... virtual A3DStatus visitEnter(const A3DPartConnector& sConnector) override { A3DStatus iRet = A3DTreeVisitor::visitEnter(sConnector); // Get transform connector via transform visitor A3DVisitorTransfo* psVisitorTransfo = static_cast<A3DVisitorTransfo*>(m_psContainer->GetVisitorByName("Transformation")); A3DTransfoConnector* pConnector = psVisitorTransfo->GetTransfoConnector(); A3DMatrix4x4 sTransfo; pConnector->GetGlobalTransfo(sTransfo); delete pConnector; for (unsigned int i = 0; i < m_iLevel; i++) _tprintf(_T("+ ")); _tprintf(_T(" (%.3f, %.3f, %.3f)\n"), sTransfo.m_adM[12], sTransfo.m_adM[13], sTransfo.m_adM[14]); return iRet; } ...
Build the project
Verify that part locations differ by instance
Info |
---|
You will see If you set it as false, just the first part of instances will be traversed. |
...
Info |
---|
If you refer the Collision sample, you will see a usage of Tree traverse Visitor. Hence
|