Mechanical Modeler

Navigating a Part Document

Exploring mechanical entities down to topological entities
Use Case

Abstract

This article discusses the CAAMmrPartBodyRequest use case. This use case explains how to open a Part document and explore its content from a mechanical modeler perspective, down to the topological entities that capture the shape of the mechanical entities contained in the document.


What You Will Learn With This Use Case

This use case is intended to help you make your first steps in programming the Mechanical Modeler. Its main intent is to introduce important concepts about the underlying data structure of the mechanical modeler, and ways to navigate it. More specifically, you will learn how to:

In bracket, we have referenced technical articles which describe in details the concepts in relationship with this use case.  

[Top]

The CAAMmrPartBodyRequest Use Case

CAAMmrPartBodyRequest is a use case of the CAAMechanicalModeler.edu framework that illustrates MechanicalModeler framework capabilities.

[Top]

What Does CAAMmrPartBodyRequest Do

The goal of CAAMmrPartBodyRequest is to open a Part document and navigate data structure in it that represents the concepts presented in the referenced technical articles. Namely, it:

Here is an sample, with the CAAMmrPartBodyRequest Part document (see the How to Launch CAAMmrPartBodyRequest section for its location). 

The output traces for this Part are the following:

The CAAMmrPartBodyRequest use case begins
   The document CAAMechanicalModeler.edu\InputData\CAAMmrPartBodyRequest.CATPart is opened
   
Using CATIDescendants

   The list of Body Features: , has 3 element(s)
      Body.3 E_FAIL for GetResult
      PartBody
         Count of elements in the result list=5
            Solid.1, its topological result is with the following tag : 474
            Sketch.1, its topological result is with the following tag : 263
            Point.5, its topological result is with the following tag : 10351
            Sketch.3, its topological result is with the following tag : 10507
            Solid.1, its topological result is with the following tag : 10543
      Body.2 
         Count of elements in the result list=0
         
   The list of Ordered Geometrical Set: , has 4 element(s)
      Ordered Geometrical Set.1 E_FAIL for GetResult
      Ordered Geometrical Set.3 E_FAIL for GetResult
      Ordered Geometrical Set.6
         Count of elements in the result list=2
            Point.3, its topological result is with the following tag : 627
            Point.4, its topological result is with the following tag : 633
      Ordered Geometrical Set.5
         Count of elements in the result list=2
            Sketch.2, its topological result is with the following tag : 9026
            Split.1, its topological result is with the following tag : 9915

   The list of Geometrical Set: , has 2 element(s)
      Geometrical Set.2
         Count of elements in the result list=0
      Geometrical Set.4
         Count of elements in the result list=2
            Point.6, its topological result is with the following tag : 10714
            Plane.1, its topological result is with the following tag : 11178

Using CATIPartRequest

   The list of Body Features: , has 2 element(s)
      PartBody
         Count of elements in the result list=5
            Solid.1, its topological result is with the following tag : 474
            Sketch.1, its topological result is with the following tag : 263
            Point.5, its topological result is with the following tag : 10351
            Sketch.3, its topological result is with the following tag : 10507
            Solid.1, its topological result is with the following tag : 10543
      Body.2  
         Count of elements in the result list=0
         
   The list of Surfacic Sets: , has 4 element(s)
      Geometrical Set.2
         Count of elements in the result list=0
      Ordered Geometrical Set.6
         Count of elements in the result list=2
            Point.3, its topological result is with the following tag : 627
            Point.4, its topological result is with the following tag : 633
      Geometrical Set.4
         Count of elements in the result list=2
            Point.6, its topological result is with the following tag : 10714
            Plane.1, its topological result is with the following tag : 11178
      Ordered Geometrical Set.5
         Count of elements in the result list=2
            Sketch.2, its topological result is with the following tag : 9026
            Split.1, its topological result is with the following tag : 9915
 
The CAAMmrPartBodyRequest use case is ended

You can note that :

[Top]

How to Launch CAAMmrPartBodyRequest

To launch CAAMmrPartBodyRequest, you will need to set up the build time environment, then compile CAAMmrPartBodyRequest along with its prerequisites, set up the run time environment, and then execute the use case [3]. To launch the use case, execute the following command:

mkrun -c "CAAMmrPartBodyRequest Filename "

where Filename is  the complete path of a Part document. You can use the CAAMmrPartBodyRequest.CATPart located:

[Top]

Where to Find the CAAMmrPartBodyRequest Code

The CAAMmrPartBodyRequest use case is made of a single source file named CAAMmrPartBodyRequest.cpp located in the CAAMmrPartBodyRequest.m module of the CAAMechanicalModeler.edu framework:

Windows InstallRootDirectory\CAAMechanicalModeler.edu\CAAMmrPartBodyRequest.m\
Unix InstallRootDirectory/CAAMechanicalModeler.edu/CAAMmrPartBodyRequest.m/

where InstallRootDirectory is the directory where the CAA CD-ROM is installed.

[Top]

Step-by-Step

There are seven logical steps in CAAMmrPartBodyRequest:

  1. Opening the Session
  2. Reading the Part Document from Disk and Preparing It for Parsing
  3. Getting Access to the Part Feature
  4. Getting Geometrical Features Sets thanks to CATIPartRequest
  5. Getting Geometrical Features Sets thanks to CATIDescendants
  6. Getting the Geometrical Features Set Result
  7. Closing the Session and Exiting.

We will now comment each of those sections by looking at the code.

[Top]

Opening the Session

int main(int    iArgc,   // Number of arguments (1) 
         char **iArgv)   // Path to an existing Part document
{
  ...
  char *pSessionName = "SampleSession";
  CATSession *pSession = 0;
  HRESULT rc = ::Create_Session(pSessionName, pSession) ;
... 

The use case is a main (batch) program that takes a single argument - the path to an existing Part document. This first section opens a session to read the document in memory.

[Top]

Reading the Part Document From Disk and Preparing It For Parsing

...
    CATDocument *pDoc = 0;
    if( SUCCEEDED(CATDocumentServices::OpenDocument(iArgv[1], pDoc)) )
    {
        CATInit *pDocAsInit = 0;
        if( SUCCEEDED(pDoc->QueryInterface(IID_CATInit, (void**)&pDocAsInit)) )
        {
         
           CATIPrtContainer *pSpecContainer = 
             (CATIPrtContainer*)pDocAsInit->GetRootContainer("CATIPrtContainer");
           pDocAsInit->Release();
...

The CATDocumentServices::OpenDocument static method opens the document from its disk location and returns it as a CATDocument. This is the implementation for all of the interfaces that a document must implement.

Documents are internally divided in containers [4]. If you think of a document as an apartment, then the containers are its rooms. Like the rooms in an apartment, containers are specialized. Each contains a specific set of data that represent some aspect of the overall document.

The first container found in a document is a high-level container that basically give access to all the other, more specialized containers in the document, although it may contain other data as well. Along our apartment metaphor, it is similar to the lobby in which you enter first, and which provides access to the other rooms in the apartment. This container is called the root container.

The first interface that we use on that document is CATInit. Through its GetRootContainer method, we can access the document's root container.

In a Part document, the root container is the container that contains the features-based definition of the part being modeled. Such structure can be explored through a dedicated interface, CATIPrtContainer, that is of course implemented by the root container. By giving this interface name as argument to GetRootContainer, the root container is returned cast to this interface type, which makes it ready for being parsed as a Part.

[Top]

Getting Access to the Part Feature

...
          CATIPrtPart_var spPart( pSpecContainer->GetPart() );
          pSpecContainer->Release();
...

We readily use the CATIPrtContainer to access the Part feature [5]. The GetPart method returns a CATIPrtPart interface pointer on this feature. We will then use a navigation facet, namely the CATIPartRequest interface, onto the Part feature in order to discover its structure.

[Top]

Getting Geometrical Features Sets thanks to CATIDescendants

...
  cout <<"Using CATIDescendants" << endl <<endl;
  CATIDescendants *pPartAsDescendants = 0;
  rc = spPart->QueryInterface(IID_CATIDescendants, (void**)&pPartAsDescendants) ;
  ...
  	  
  // 6-1 Extracts the lists of its Body Features
  CATLISTV(CATISpecObject_var) BodyListDesc;  
  pPartAsDescendants->GetAllChildren("CATIMechanicalTool", BodyListDesc);
  cout <<"   The list of Body Features:" ;
  PrintGeometricalFeaturesSetsResult2(BodyListDesc);

  // 6-2 Extracts the lists of its OGS
  CATLISTV(CATISpecObject_var) OGSList;  
  pPartAsDescendants->GetAllChildren("CATIMmiOrderedGeometricalSet",OGSList);
  cout <<"   The list of Ordered Geometrical Set:"  ;
  PrintGeometricalFeaturesSetsResult2(OGSList);

  // 6-3 Extracts the lists of its GS
  CATLISTV(CATISpecObject_var) GSList;  
  pPartAsDescendants->GetAllChildren("CATIMmiNonOrderedGeometricalSet",GSList);
  cout <<"   The list of Geometrical Set:"  ;
  PrintGeometricalFeaturesSetsResult2(GSList);

  pPartAsDescendants->Release();
  pPartAsDescendants = NULL ;
...

Using specific interfaces you retrieve all the geometrical features set into the Part document:

The result of the CATIBodyRequest interface and the final extraction of the topological bodies from the set is delegated to a dedicated function: PrintGeometricalFeaturesSetsResult. The PrintGeometricalFeaturesSetsResult2 method being just an encapsulation of the PrintGeometricalFeaturesSetsResult method to convert a list of CATISpecObject into a list of CATBaseUnknown

[Top]

Getting Geometrical Features Sets thanks to CATIPartRequest

...
  cout <<"Using CATIPartRequest" << endl <<endl;
  CATIPartRequest *pPartAsRequest = 0;
  rc = spPart->QueryInterface(IID_CATIPartRequest, (void**)&pPartAsRequest) ;
  ...
   
  const CATUnicodeString stdContext(" ");  
  	  
  // 7-1 Extracts the lists of its Body Features
  CATLISTV(CATBaseUnknown_var) BodyList;  
  pPartAsRequest->GetSolidBodies(stdContext, BodyList);
  cout <<"   The list of Body Features:" ;
  PrintGeometricalFeaturesSetsResult(BodyList);

  // 7-2 Extracts the lists of its surfacic sets
  CATLISTV(CATBaseUnknown_var) SurfacicSetList;  
  pPartAsRequest->GetSurfBodies(stdContext, SurfacicSetList);
  cout <<"   The list of Surfacic Sets:"  ;
  PrintGeometricalFeaturesSetsResult(SurfacicSetList);

  pPartAsRequest->Release();
  pPartAsRequest = NULL ;
...

We saw earlier that specifying a context was necessary to choose among the potentially many topological bodies associated to one geometrical features set. This is what the stdContext variable does here. The blank value is the one that retrieve standard topological bodies. In case others set of topological bodies are associated to the geometrical features set by some application, then an application specific string can be passed to filter them out. For instance, the Mechanical Modeler maintains additional topological bodies for sheet metal applications that represent the parts in their unfolded configuration. Those topological bodies can be accessed through the string "Unfolded".

The CATIPartRequest interface offers a direct access to geometrical features sets that are associated to the Part, thanks to two dedicated methods, GetSolidBodies and GetSurfBodies. What is returned are :

The result of the CATIBodyRequest interface and the final extraction of the topological bodies from the set is delegated to a dedicated function: PrintGeometricalFeaturesSetsResult. 

[Top]

Getting the Geometrical Features Set Result

void PrintGeometricalFeaturesSetsResult(const CATLISTV(CATBaseUnknown_var) &iSet) 
{
  const CATUnicodeString stdContext(""); 

  cout <<" , has " << iSet.Size() << " element(s)" << endl;

  for(int curSetIdx=1; curSetIdx<=iSet.Size(); curSetIdx++)
  {
      CATBaseUnknown_var CurrentSet = iSet[curSetIdx] ;
      if ( NULL_var == CurrentSet ) break ;

      CATIAlias_var aliasOnCurrentSet = CurrentSet ;
      
      cout << "      " << aliasOnCurrentSet->GetAlias().ConvertToChar() ;
      
      CATLISTV(CATBaseUnknown_var) pListResult;

      CATIBodyRequest *pBodyRequestOnCurrentSet = NULL;
      HRESULT rc = CurrentSet->QueryInterface(IID_CATIBodyRequest, (void**)&pBodyRequestOnCurrentSet);
      if ( SUCCEEDED(rc) )
      {  
         rc = pBodyRequestOnCurrentSet->GetResults(stdContext, pListResult);

This function takes as input a collection of set, and displays the values returned by the CATIBodyRequest interface. Its unique method, GetResults, returns a list of features holding a topological result. The GetResults method requires the context of construction. For the default context, you can use the empty string or "MfDefault3DView". 

...
         for(int curFeatIdx=1; curFeatIdx<=SizeList; curFeatIdx++)
         { 
            CATBaseUnknown_var CurrentFeat = pListResult[curFeatIdx] ;
            ...
            CATIAlias_var aliasOnCurElt = CurrentFeat ;
            
            cout << "            " << aliasOnCurElt->GetAlias().ConvertToChar() ;
            
            CATIGeometricalElement *pCurFeatOnGeomElt = NULL ;
            rc = CurrentFeat->QueryInterface(IID_CATIGeometricalElement, 
                                                                 (void**)&pCurFeatOnGeomElt);
            if( SUCCEEDED(rc) )
            {       
                  CATBody_var ResultBody = pCurFeatOnGeomElt->GetBodyResult();
                  
                  if ( NULL_var != ResultBody )
                  {
                     CATICGMObject *pCurTopo = 0;
                     rc=ResultBody->QueryInterface(IID_CATICGMObject,(void**)&pCurTopo);
                               
                         unsigned long curResultTag = pCurTopo->GetPersistentTag();
                         cout <<"  ,Its contains a topological result with the following tag : " ;
                         cout << curResultTag << endl;

For each element of the list returned by the GetResults method, its associated topological body is retrieved. It is possible thanks to the CATIGeometricalElement interface. The GetBodyResult method retrieves the CATBody associated with the feature.

[Top]

Closing the Session and Exiting

...
  CATDocumentServices::Remove(*pDoc);
  ... 
  ::Delete_Session("SampleSession");
...

After the job is finished, a proper cleanup of document and session is necessary before ending. To do this, the CATDocumentServices::Remove static method and the Delete Session global function are used, as counterpart of CATDocumentServices::Open and Create Session that were used in the beginning of the use case.

[Top]


In Short

This use case has demonstrated the way to programmatically navigate a Part document, form the document itself down to the entities that hold the topology associated with the mechanical bodies of its part.

[Top]


References

[1] The Contents of the Specification Container- Geometrical Features Sets
[2] Specification/Result Mechanism Applied to Mechanical Features
[3] Building and Launching a CAA V5 Use Case
[4] The Structure of a Part Document
[5] The Contents of the Specification Container- The Part Feature
[Top]

History

Version: 1 [Jan 2000] Document created
Version: 2 [Dec 2003] Document updated
Version: 3 [Jun 2004] Document updated to take R13/R14 novelties into account
[Top]

Copyright © 2000, Dassault Systemes. All rights reserved.