3D PLM PPR Hub Open Gateway

Product Modeler

Positioning Products in a Product Document

Modifying relative and absolute positions of product instances

Use Case

Abstract

This article discusses the CAAPstMovable use case. This use case illustrates the way to position product instances within a Product document.


What You Will Learn With This Use Case

This use case is intended to help you understand how to modify the position of products within a Product document. Basically, you will see how to:

Before getting to the use case itself, it is important to get an understanding of the Product Structure model by reading the referenced article [1].

[Top]

The CAAPstMovable Use Case

CAAPstMovable is a use case of the CAAProductStructure.edu framework that illustrates the ProductStructure framework capabilities.

[Top]

What Does CAAPstMovable Do

The goal of CAAPstMovable is to illustrate re-positioning products within a product document. It performs the following steps:

Above is an illustration of this product structure in a CATIA session after all of the re-positioning has already occurred. Note that the two parts have different positions, which is not the case initially (before any re-positioning occurs), when the two parts are superposed.

[Top]

How to Launch CAAPstMovable

To launch CAAPstMovable, you will need to set up the build time environment, then compile CAAMovable along with its prerequisites, set up the run time environment, and then execute the sample. This is fully described in the referenced article [2]. 

To launch the use case, execute the following command:

mkrun -c "CAAPstMovable input.CATPart output.CATProduct"

[Top]

Where to Find the CAAPstBrowse Code

CAAPstMovable code is located in the CAAPstMovable.m use case module of the CAAProductStructure.edu framework:

Windows InstallRootDirectory/CAAProductStructure.edu/CAAPstMovable.m
Unix InstallRootDirectory\CAAProductStructure.edu\CAAPstMovable.m

where InstallRootDirectory is the root directory of your CAA V5 installation. It is made of a unique source file named CAAPstMovable.cpp.

[Top]

Step-by-Step

There are nine logical steps in CAAPstMovable:

  1. Creating a New Product Document
  2. Retrieving the Document's Root Product
  3. Loading an Existing Part Document
  4. Adding a Product Instance of the Part to the Root Product
  5. Adding a Product Instance of the Part to a New Local Product
  6. Modifying the Position of the Local Product
  7. Modifying the Position of the Product Instance of the Part Attached to the Local Product
  8. Retrieving the New Absolute and Relative Positions of the Product Instance of the Part
  9. Saving the Product Document

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

[Top]

Creating a New Product Document

HRESULT rc = 0;
...
CATSession *pSession = NULL;
rc = ::Create_Session("CAA2_Sample_Session", pSession );

Generally, the first thing that is necessary in a batch program is the creation of a new session. This is done using the Create_Session global function. It is important not to forget to delete the session at the end of your batch program.

CATDocument *pDoc = NULL;
rc = CATDocumentServices::New("Product", Doc);

Now that we have a current session, we can create the Product document. This is done using the New method of CATDocumentServices with type "Product" as input parameter. Note that "Product" is not the extension of the document (which is "CATProduct"), but rather its type, a name which appears in the list of document types available seen in the File/New menu of an interactive session.

[Top]

Retrieving the Document's Root Product

CATIDocRoots *piDocRootsOnDoc = NULL;
rc = pDoc->QueryInterface(IID_CATIDocRoots,
                          (void**) &piDocRootsOnDoc);
...
	
// the root product is the first element of root elements
CATListValCATBaseUnknown_var *pRootProducts = piDocRootsOnDoc->GiveDocRoots();
CATIProduct_var spRootProduct = NULL_var;
if (NULL != pRootProducts && pRootProducts->Size() > 0) {  
      spRootProduct = (*pRootProducts)[1];
...
// Get CATIProduct handle on the root product.
CATIProduct *piProductOnRoot = NULL;
rc = spRootProduct->QueryInterface(IID_CATIProduct, 
                                   (void**) &piProductOnRoot);
...         

In order to work with a new product structure within the Product document, it is necessary to access the root product. This is done using the GiveDocRoots method of CATIDocRoots which returns a list of all of the roots within the document, the first one being the root product we are looking for. From this root product, we can get a CATIProduct handle which will be needed later in order to add new components.

[Top]

Loading a Part Document

CATDocument *pPartDoc = NULL;
CATIProduct *piInstanceProd1 = NULL;
...

// load of the CATPart to import
rc = CATDocumentServices::Open(argv[1], pPartDoc);

In order to add an existing external component to a product, it is necessary to first load the document into the session. This is done using CATDocumentServices::Open. The path name of the document to be loaded is passed as the first argument to this use case.

[Top]

Adding a Product Instance of the Part to the Root Product

// import the CATPart under the root.
rc = ::AddExternalComponent(piProductOnRoot, 
                            pPartDoc,
                            &piInstanceProd1);

Now that the part exists in the session, it can be added to the product structure as a product instance. First, we add it to the root product using the AddExternalComponent global function. See the referenced article [3] for a description of this function. We pass the following parameters to this function:

[Top]

Adding a Product Instance of the Part to a New Local Product

  1. Create a local product under the root product
    // creation of a local product under the root.
    CATIProduct_var spAlternateProduct = piProductOnRoot -> AddProduct ( "AlternatProd" );
    CATIProduct *piAlternateProduct = NULL;
    rc = spAlternateProduct->QueryInterface(IID_CATIProduct, 
                                            (void**) &piAlternateProduct);

    Now, we would like to add the same part to a local product. First, a new local product is created under the root product. This is done using the CATIProduct::AddProduct method which returns a CATIProduct_var handle that we need to convert to a CATIProduct handle.

  2. Import an existing external component under the local product
    // imports the same CATPart under the local product.
    CATIProduct *piInstanceProd2 = NULL;
    // imports it again
    rc = ::AddExternalComponent(piAlternateProduct,
                                pPartDoc, 
    	                   &piInstanceProd2);

    We add the same external part to the local product also using the AddExternalComponent global function as above.

    Now that the product structure is constructed, we can move the products within the product document.

[Top]

Modifying the Position of the Local Product

Initially, the axes of the root product and local product are identical. By modifying the position of the local product, these axes will be different.

  1. Get CATIMovable handles
    // Get CATIMovable handle on the instance of product in the context of the
    // reference of the local product.
    CATIProduct_var spReferenceAlternateProduct = piAlternateProduct -> GetReferenceProduct();
    ...
    CATIProduct_var spMovableInstanceInContext = piInstanceProd2 -> FindInstance(spReferenceAlternateProduct);
    ...
    CATIMovable *piMovableInContext;
    rc = spMovableInstanceInContext -> QueryInterface(IID_CATIMovable,
                                                      (void**) &piMovableInContext);
    ...
    // Get CATIMovable handle on the instance of the local product.
    CATIMovable *piMovableOnAlternate = NULL;
    rc = spAlternateProduct->QueryInterface(IID_CATIMovable,
                                            (void**) &piMovableOnAlternate);

    In order to move the part instance under the local product, it is necessary to reference it in the context of the reference of the local product and not in the context of the instance of the local product. First of all, we need to get a handle on the actual reference of the local product (GetReferenceProduct). Next, we want to get a handle on the instance of the part under the reference of the local product (FindInstance) in order to get a CATIMovable handle on it. We also get a CATIMovable handle on the local product instance.

  2. Initialize the transformation matrix
    double *aPositionAlt = new double [12];
    for (int l=0; l < 12; l++)
       aPositionAlt[l]=0.;

    We set all entries to 0.

    aPositionAlt[0] = 1.;
    aPositionAlt[4] = 1.;
    aPositionAlt[8] = 1.;
    aPositionAlt[9] = 12.;
    aPositionAlt[10] = 12.;
    aPositionAlt[11] = 12.;

    We initialize to 1 the diagonal terms of the rotation matrix and to (12,12,12) the coordinates of the new origin.

  3. Modify the position of the local product
    // applying the matrix moves the local product.
    CATMathTransformation newRefPosition(aPositionAlt);
    piMovableOnAlternate -> SetPosition(newRefPosition,
                                        NULL_var);

    And now, using the CATIMovable handle we retrieved previously, we apply the transformation to the local product using the SetPosition method. This means that the position of the local product is now different from the position of the root product.

[Top]

Modifying the Position of the Product Instance of the Part within the Local Product

To modify the position of the product instance of the part relative to the local product, we proceed in the same manner as above.

  1. Initialize the transformation matrix
    double *aPositionAxis = new double [12];
    for (int i=0; i < 12; i++)
       aPositionAxis[i]=0.;
    aPositionAxis[0] = 1.;
    aPositionAxis[4] = 1.;
    aPositionAxis[8] = 1.;
    aPositionAxis[9] = 77.;
    aPositionAxis[10] = 77.;
    aPositionAxis[11] = 77.;

    The transformation matrix is initialized in a similar way as previously.

    The coordinates of the new origin of the product instance of the part under the local product are relative to the new axis of the local product.

  2. Modify the position of the product instance of the part under the local product
    // applying the matrix moves the instance
    CATMathTransformation newPosition(aPositionAxis);
    piMovableInContext -> SetPosition(newPosition,
                                      NULL_var);

    And finally, using the CATIMovable handle we retrieved previously, we apply the transformation to the product instance of the part using the SetPosition method.

[Top]

Retrieving the Absolute and Relative Positions of the Product Instance of the Part

If we now visualized the product document, we would see that the product instance of the part under the root product has a different position from the product instance of the part under the local product. The position of the product instance of the part under the local product can either be expressed as a "relative position", i.e., with respect to the local product, or as an "absolute position", i.e., with respect to the root product.

  1. Get the absolute position
    // absolute position
    CATIMovable *piMovableOnInstance = NULL;
    rc = piInstanceProd2 -> QueryInterface (IID_CATIMovable,
                                            (void**) &piMovableOnInstance);
    ...
    
    CATMathTransformation absolutePosition;
    piMovableOnInstance -> GetAbsPosition(absolutePosition );

    In order to get the absolute position, we use the CATIMovable handle to get a CATMathTransformation object using the GetAbsPosition method.

  2. Get the absolute position matrix
    double *pAbsoluteCoeff = new double [12];
    absolutePosition.GetCoef(pAbsoluteCoeff);

    Now, using GetCoef on the CATMathTransformation object, we get the absolute position matrix of the product instance which is:

    1 0 0 89
    0 1 0 89
    0 0 1 89

    As expected in this case, the absolute coordinates of the product instance of the part axis origin are the sum of the absolute coordinates of the local product origin with the relative coordinates of the product instance of the part axis origin with respect to the local product axis.

  3. Get the relative position
    // relative position in the context of the local product.
          // no specification for the context, means default movable will be used.
          CATIMovable_var spContext = NULL_var;
          CATMathTransformation relativePositon =
          piMovableOnInstance -> GetPosition(spContext);
          double *aRelativeCoeff = new double [12];

    In order to get the relative position, we use the CATIMovable handle to get a CATMathTransformation object using the GetPosition method.

  4. Get the relative position matrix
    double *pRelativeCoeff = new double [12];
    relativePositon.GetCoef(pRelativeCoeff);
    
    ...

    As before, using GetCoef on the CATMathTransformation object, we get the relative position matrix of the product instance which is:

    1 0 0 77
    0 1 0 77
    0 0 1 77

[Top]

Saving the CATProduct Document

  1. Save the CATProduct document
    rc = CATDocumentServices::SaveAs(*pDoc, 
    		                 argv[2]);

    We save the product document using the CATDocument::SaveAs method. The product document is saved under the name specified in the second argument to this routine.

  2. Remove the CATProduct document from the session
    rc = CATDocumentServices::Remove (*pPartDoc);

    It is good practice to remove any opened documents before exiting the session. In this case, we should remove the CATPart document we loaded into the session at the beginning of the program.

  3. Delete the session
    // delete the session, removes the opened documents also.
    // never forget to delete a creating session after usage.
    rc = ::Delete_Session("CAA2_Sample_Session");

    Do not forget to delete the session before exiting using the Delete_Session global function!

[Top]


In Short

This use case has demonstrated how to position product instances within a product document. Specifically, it has illustrated:

[Top]


References

[1] The Product Structure Model
[2] Building and Launching a CAA V5 Use Case
[3] Adding Existing External Components Utility
[4] Adding New External Components Utility
[Top]

History

Version: 1.1 [Aug 2004] Document revised
Version: 1 [Mar 2000] Document created
[Top]

Copyright © 2000, Dassault Systèmes. All rights reserved.