Mechanical Modeler

Retrieving Selecting Object in Copied Feature

Using CATMmrBRepScanServices

Use Case

Abstract

This article shows how to retrieve Selecting Objects in copied geometry.


What You Will Learn With This Use Case

This use case is intended to show you how to retrieve Selecting Objects in copied geometry.

[Top]

The CAAMmrBRepScanServices Use Case

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

[Top]

What Does CAAMmrBRepScanServices Do

CAAMmrBRepScanServices begins by opening the following root Product Model (*)
Fig.1 The Opened Root Product Model

The root product, CAAMmrBRepScanServicesRoot, aggregates two instances of products : CAAMmrBRepScanServices_P1 and CAAMmrBRepScanServices_P2. In turn, these two products aggregate two Parts:

Then, the use case copies the PartBody of CAAMmrBRepScanServices_P2 inside CAAMmrBRepScanServices_P1 with the following options:

The result will be the as follow:

Fig.2 Model After the Copy

On this picture, simulated interactively, we have moved the copied PartBody (inside CAAMmrBRepScanServices_P1) to distinguish it from the original PartBody (inside CAAMmrBRepScanServices_P2).

Then, we are looking for the selecting objects associated with the  EdgeFillet.1. This picture illustrates these objects:

Fig.3 Selecting Object

Interactively, if you select EdgeFillet.1, two faces are highlighted. These two faces are selecting objects.

Finally, the use case retrieves these two faces in the copied features. These two faces are selecting objects too.

Fig.4 Selecting Object

Inside the white boxes you have the initial Selecting faces, and in the dotted white boxes you have the same one in the result of the copy.

[Top]

How to Launch CAAMmrBRepScanServices

To launch CAAMmrBRepScanServices , you will need to set up the build time environment, then compile CAAMmrBRepScanServices along with its prerequisites, set up the run time environment, and then execute the use case [1].

mkrun -c "CAAMmrBRepScanServices InputPath"

where InputPath is the directory containing the input model.

(*) The input model is the following:

Windows InstallRootDirectory\CAAMechanicalModeler.edu\InputData\CAAMmrBRepScanServicesRoot.CATProduct
Unix InstallRootDirectory/CAAMechanicalModeler.edu/InputData/CAAMmrBRepScanServicesRoot.CATProduct

[Top]

Where to Find the CAAMmrBRepScanServices Code

The CAAMmrBRepScanServices use case is made of one file, CAAMmrBRepScanServicesMain.cpp, located in the CAAMmrBRepScanServices.m module of the CAAMechanicalModeler.edu framework:

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

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

[Top]

Step-by-Step

There are eight logical steps in CAAMmrBRepScanServices:

[Top]

Opening the Input Root Product

...
CATDocument *pProductDocument = NULL;
CATString InputData = iArgv[1] ;
CATString DocumentProductName  = InputData + Slash + "CAAMmrBRepScanServicesRoot.CATProduct";

rc = CATDocumentServices::OpenDocument(DocumentProductName.CastToCharPtr(), pProductDocument);
...

[Top]

Retrieving the two Sub-Products

...
  CATIProduct * piProductOnRoot = NULL;

  CATIDocRoots * piDocRootsOnDoc = NULL;
  rc = pProductDocument->QueryInterface(IID_CATIDocRoots,(void**) &piDocRootsOnDoc);
                          
  if ( SUCCEEDED(rc) ) 
  {
     CATListValCATBaseUnknown_var* pRootProducts = piDocRootsOnDoc->GiveDocRoots();
     CATBaseUnknown_var spRootProduct = (*pRootProducts)[1];
    
     rc = spRootProduct->QueryInterface(IID_CATIProduct,(void**) &piProductOnRoot);     
 ...
  CATListValCATBaseUnknown_var * pListDirectChildren = piProductOnRoot->GetChildren(); 
  
  ...
  CATIProduct_var spComp1 = (*pListDirectChildren)[1] ;
  CATIProduct_var spComp2 = (*pListDirectChildren)[2] ;
...

[Top]

Retrieving Useful Objects for the Copy

...
  CATISpecObject_var spSpecObjectOnMechPartOfP2 ;
  rc = ::CAAMmrGetPartFromProduct( spComp2, spSpecObjectOnMechPartOfP2 );
 ...

we use a global function exported by the CAAMechanicalModeler.edu framework. CAAMmrGetPartFromProduct retrieves the Part feature [2] inside the Part.  spSpecObjectOnMechPartOfP1 is a CATISpecObject interface pointer on the Part feature of CAAMmrBRepScanServices_P1.

To retrieve a specific feature by its name we use another global function exported by the CAAMechanicalModeler.edu framework. CAAMmrGetGeometry retrieves. Here an extract to retrieve the EdgeFillet.1 of CAAMmrBRepScanServices_P2.

...
  CATBaseUnknown * pFil = NULL ;
  rc = ::CAAMmrGetGeometry( spSpecObjectOnMechPartOfP2, "EdgeFillet.1", &pFil );
  CATBaseUnknown_var spOnEdgeFilletOfP2 = pFil ;
 ...

spSpecObjectOnMechPartOfP2 is the CATISpecObject interface pointer on the Part feature of CAAMmrBRepScanServices_P2. The second argument is the name of the feature, and the last one is a CATBaseUnknown pointer on the retrieved feature.

Here an extract to retrieve the PartBody of CAAMmrBRepScanServices_P2.

...
  CATBaseUnknown * pBody = NULL ;
  rc = ::CAAMmrGetGeometry( spSpecObjectOnMechPartOfP2, "PartBody", &pBody );
  CATBaseUnknown_var spOnBodyOfP2 = pBody ;
 ...

[Top]

Copying PartBody

...
  CATMmrInterPartCopy * ptCATMmrInterPartCopy = NULL ;

  CATISpecObject_var SourceToCopy = spOnBodyOfP2 ;
  CATISpecObject_var Target       = spSpecObjectOnMechPartOfP1 ;

  ptCATMmrInterPartCopy =  new CATMmrInterPartCopy (SourceToCopy,Target) ;
                                                  
  ptCATMmrInterPartCopy ->SetLinkMode(CopyWithLink) ; 
  
  CATUnicodeString ErrorMsg ;
  rc = ptCATMmrInterPartCopy ->Run(&ErrorMsg);
  ...

  CATISpecObject_var Result ;
  rc = ptCATMmrInterPartCopy ->GetResult(Result);
  ...

The copy is made thanks the CATMmrInterPartCopy class.

The source of the copy (the feature to copy) is spOnBodyOfP2. This feature is the PartBody of the Part CAAMmrBRepScanServices_P2 . Its retrieval is described below.

The target of the copy is spSpecObjectOnMechPartOfP1 . This feature is the Part of the Part CAAMmrBRepScanServices_P1. Its retrieval is described below.

SetLinkMode with TRUE as argument creates a copy with link. It means that if the original feature is modified, the copied can be updated.

At least Run executes the copy. Result is a CATISpecObject interface pointer on the copied feature. On [Fig.2] it is Body.2.

[Top]

Getting EdgeFillet.1 Faces inside PartBody

This step consists in to retrieve the selecting object associated with the geometry of the EdgeFillet.1 feature inside the PartBody of CAAMmrBRepScanServices_P2. The two faces represented [Fig.3]

First the geometry of EdgeFillet.1 feature.

...
CATIMfGeometryAccess *pGeomAccessOnEdgeFillet = NULL ;
rc = spOnEdgeFilletOfP2-> QueryInterface(IID_CATIMfGeometryAccess,(void**)&pGeomAccessOnEdgeFillet);
CATLISTV(CATBaseUnknown_var) LBrepAccessOnCATBaseUnknown;
int n_face = pGeomAccessOnEdgeFillet->GetBReps(LBrepAccessOnCATBaseUnknown);
...

The GetBReps method of the CATIMfGeometryAccess interface retrieves the BRep objects associated with a feature. spOnEdgeFilletOfP2 is a CATBaseUnknown smart pointer on the EdgeFillet.1 of the Part CAAMmrBRepScanServices_P2. See the Retrieving Useful Objects for the Copy section.

Then, we retrieve the CATIBRepAccess interface pointer on each face of the feature;

...
CATLISTP(CATIBRepAccess) ListBreps;
for( int i_face = 1; i_face <= n_face; i_face++)
{
   CATBaseUnknown * Unk = LBrepAccessOnCATBaseUnknown[i_face];
   CATIBRepAccess * Brep = NULL;
   rc = Unk -> QueryInterface(IID_CATIBRepAccess,(void**)&Brep );
...

For each CATIBRepAccess interface pointer, we are looking for the equivalent face(s) in the result of the PartBody of CAAMmrBRepScanServices_P2.

...
    CATLISTV(CATBaseUnknown_var) ListTemp;
    ListTemp = Brep->GetBReps(spSpecObjResultPartBody2);
    for ( int k=1 ; k <= ListTemp.Size(); k++)
    {
	CATBaseUnknown_var TempVar = ListTemp[k]  ;
			   
        CATIBRepAccess * BrepTemp = NULL;
        TempVar->QueryInterface(IID_CATIBRepAccess,(void**)&BrepTemp );
        ListBreps.Append(BrepTemp);
...

The argument of the GetBReps method of CATIBRepAccess is the solid feature, the result of the PartBody [3]. spSpecObjResultPartBody2 is retrieved such as :

...
    CATIBodyRequest_var spBodyRequestOnBodyOfP2 = spOnBodyOfP2;
  
    CATLISTV(CATBaseUnknown_var) ListResult ;
    rc = spBodyRequestOnBodyOfP2->GetResults("",ListResult);
 
    CATBaseUnknown_var spResultPartBody2 = ListResult[1];
    CATISpecObject_var spSpecObjResultPartBody2 = spResultPartBody2 ;
...

The result of a PartBody is always the first element of the list.

ListBreps contains the faces of EdgeFillet.1. ( here two)

[Top]

Getting the BrepAccess within Copied PartBody

We have retrieved the list of selecting objects of the "original"  feature. This list is ListBreps .  Now we can try to retrieve the equivalent selecting objects in the result of the copy. 

...
  CATLISTP(CATIBRepAccess) ListBrepsRef;   
  CATLISTP(CATIBRepAccess) ListBrepsDual;  
 
  for( i_face = 1; i_face <= n_face; i_face++)
  {
	  
      CATISpecObject * pFeatRef = NULL;     
      CATISpecObject * pFeatImp = Result;   
      CATIBRepAccess * BrepIn   = ListBreps[i_face];  
      CATIBRepAccess * BrepOut  = NULL;

      rc = CATMmrBRepScanServices::FindDualBRepAccess( pFeatRef, pFeatImp, &BrepIn , &BrepOut ); 
      if ( FAILED(rc) || NULL == BrepOut ) continue;

      ListBrepsRef.Append(BrepIn); BrepIn->AddRef();
      ListBrepsDual.Append(BrepOut);
  }
...

We are using the FindDualBRepAccess method of the CATMmrBRepScanServices class. In this case the inputs of this method are the following:

ListBrepsDual contains the list of selecting objects inside the result. On [Fig.4] you can seen the two selecting objects in the dotted white boxes.

In another cases, ListBrepsDual can be:

Getting the BrepAccess within initial Part

For each selecting objects found in the result, you try to retrieve the selecting object in the original feature. In mathematical term we are looking for the Bi-Dual objects.

...
  CATLISTP(CATIBRepAccess) ListBrepsBiDual;  
  n_face = ListBrepsDual.Size();
  for( i_face = 1; i_face <= n_face; i_face++)
  {
	  CATISpecObject_var FeatRef = spOnBodyOfP2;
	  CATISpecObject *   pFeatRef = (CATISpecObject*) FeatRef ;
	  CATISpecObject *   pFeatImp = Result;        

	  CATIBRepAccess *   BrepIn   = NULL;
	  CATIBRepAccess *   BrepOut  = ListBrepsDual[i_face];
      
      rc = CATMmrBRepScanServices::FindDualBRepAccess( pFeatRef, pFeatImp, &BrepIn , &BrepOut ); 
      if ( FAILED(rc) || NULL == BrepIn ) continue;
      ListBrepsBiDual.Append(BrepIn);
  }
...

We are using the FindDualBRepAccess method of the CATMmrBRepScanServices class. In this case the inputs of this method are the following:

Checking Step

All the elements of ListBrepsBiDual must be one of the initial list, ListBrepsRef. Both are list containing faces of EdgeFillet.1 inside CAAMmrBRepScanServices_P2. But  ListBrepsRef can contains more elements.

...
  for( i_face = 1; i_face <= n_face; i_face++)
  {
    CATIBRepAccess * BrepIn = ListBrepsBiDual[i_face];
    if (NULL == BrepIn) continue;
    CATBoolean Found = FALSE ;
    int j = 1 ;
    while ( (Found==FALSE) && ( j<=ListBrepsRef.Size() ) )
    {
        CATIBRepAccess * BrepOut = ListBrepsRef[j] ;
	if ( BrepIn->IsSame(BrepOut) )
        {
            Found = TRUE ;
	}
	j++ ;
    }
    if ( Found == FALSE )
    {
       return 1;
    }
...

To compare two BRep object, use the IsSame method.

[Top]


In Short

The use case has shown that

These selecting object can be the target of a Publication. (Do not featurize a selecting object to be the target of a Publication)

[Top]


References

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

History

Version: 1 [Nov 2006] Document created
[Top]

Copyright © 1999-2006, Dassault Systèmes. All rights reserved.
Special Notices CAA V5 CATIA | CAA V5 DELMIA | CAA V5 ENOVIA