3D PLM PPR Hub Open Gateway |
Product Modeler |
Working With Rigid/Flexible Sub-ProductsUsing the CATIBlockMovable interface |
Use Case |
AbstractThis article presents the CAAPstBlockMovable use case which illustrates how to work with flexible sub-products. |
Using the CATIBlockMovable interface, a sub-product can be made flexible or rigid.
[Top]
CAAPstBlockMovable is a use case of the CAAProductStructure.edu framework that illustrates the ProductStructure framework capabilities.
[Top]
The goal of CAAPstBlockMovable is to demonstrate the CATIBlockMovable interface. It performs the following steps:
Below is the Product document that will be loaded in the use case. It can be found in
InstallRoot/CAAProductStructure.edu/CNext/resources/graphic/CAAPstBlockMovable_document.CATProduct
If link.1 is moved (by dropping the compass on the part and then dragging it), it is the whole chain.1 that will move and not only link.1. This is because chain.1 is rigid.
The code in the use case will make chain.1 flexible and then move link.1. The resulting document will show that only link.1 has moved. Moreover, link.1 and link.2 can now be moved separately using the compass.
[Top]
To launch CAAPstBlockMovable:
- input.CATProduct - the path to the supplied document whose path is InstallRoot/CAAProductStructure.edu/CNext/resources/graphic/CAAPstBlockMovable_document.CATProduct
- output.CATProduct: the path to the resulting CATProduct document
- link.1: instance name of the part to be moved and whose parent must be made flexible beforehand
- 0 50 0: x,y,z translation vector to be applied to link.1
In the resulting document, only link.1 has moved because chain.1 has been made flexible
[Top]
CAAPstBlockMovable code is located in the CAAPstBlockMovable.m module of the CAAProductStructure.edu framework. There are two source files:
[Top]
There are six logical steps in CAAPstBlockMovable:
We will now detail each of those sections:
[Top]
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 when the
program exits. Once the session is created, a Product document can be loaded
with CATDocumentServices::Open.
// // Start session and load a Product // rc = ::Create_Session((char *) _sessionName, _pSession); ... rc = CATDocumentServices::Open(inputFilename, _pDocument); |
[Top]
In order to work with a 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 find a part.
// // Get Root Product // CATIDocRoots* piDocRootsOnDoc = NULL; rc = _pDocument->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 (pRootProducts && pRootProducts->Size()) { spRootProduct = (*pRootProducts)[1]; ... // // Get CATIProduct handle on the root product. // CATIProduct *piProductOnRoot = NULL; rc = spRootProduct->QueryInterface(IID_CATIProduct, (void**) &piProductOnRoot); |
[Top]
Finding a part with a given instance name is implemented by the FindPart method: it walks though the children list of the root product until the name matches with an instance's.
CATIProduct_var CAAPstBlockMovable::FindPart(CATUnicodeString& ipartName, CATIProduct *ipiProductOnRoot) { CATIProduct_var ospPart = NULL_var; ... CATListValCATBaseUnknown_var* childrenList = ipiProductOnRoot->GetAllChildren(); ... int childrenCount = childrenList->Size(); CATIProduct_var spChild = NULL_var; CATUnicodeString instanceName; for (int i=1; i <= childrenCount; i++) { spChild = (*childrenList)[i]; if (NULL_var == spChild) break; HRESULT rc = spChild->GetPrdInstanceName(instanceName); if (FAILED(rc)) break; if (instanceName == ipartName) { ospPart = spChild; break; } } ... return ospPart; } |
Once the part is found, getting its parent product is done by calling GetFatherProduct
// // Retrieve the part with specified name // CATIProduct_var spPart = FindPart(partName, piProductOnRoot); ... if ( NULL_var == spPart) { cout << partName.ConvertToChar() << " not found" << endl; ERROR_RETURN(S_PartNotFound); } // // Retrieve the parent product of the part // CATIProduct_var spParentProduct = spPart->GetFatherProduct(); if (NULL_var == spParentProduct) { cout << "Can't find parent product of " << partName.ConvertToChar() << endl; ERROR_RETURN(S_ParentNotFound); } |
[Top]
The next thing to do is to get the CATIBlockMovalbe interface of the parent product. Using this interface, the parent product rigidity is tested with IsSoft and is made flexible only if it is necessary with MakeSoftAssembly.
// // Get the CATIBlockMovable interface on the parent product // CATIBlockMovable *piBlockMovable = NULL; rc = spParentProduct->QueryInterface(IID_CATIBlockMovable, (void **) &piBlockMovable); ... // // Check whether the rigid/flexible modification needs to be applied to // the parent product // int isFlexibleFlag = piBlockMovable->IsSoft(); CATUnicodeString parentName; spParentProduct->GetPrdInstanceName(parentName); cout << parentName.ConvertToChar(); if (isFlexibleFlag) cout << " is already flexible" << endl; else { cout << " is rigid, making it flexible" << endl; piBlockMovable->MakeSoftAssembly(); } |
[Top]
Now that the parent product is flexible, the part can be moved using the CATIMovable interface. (see reference [3])
isFlexibleFlag = piBlockMovable->IsSoft(); ... // // If the parent product is flexible then move the part: // Get the CATIMovable Interface and move the part on the Y axis // if (isFlexibleFlag) { CATIMovable *piMovable = NULL; rc = spPart->QueryInterface(IID_CATIMovable, (void **) &piMovable); ... CATMathTransformation position; rc = piMovable->GetAbsPosition(position); ... double array[12]; position.GetCoef(array, sizeof(array)/sizeof(array[0])); // // move the part 20mm in the Y axis // array[9] += double(deltaX); array[10] += double(deltaY); array[11] += double(deltaZ); position.SetCoef(array); rc = piMovable->SetAbsPosition(position); |
[Top]
The modified document can now be saved. Finally the session is delete and the loaded Product document is removed.
// // All done. save the modified document into the specified output file // rc = CATDocumentServices::SaveAs(*_pDocument, outputFilename); ... // // Remove the opened document and close the session // CleanUp(); |
[Top]
This use case has demonstrated how to make a sub-product flexible so that one of its parts can be moved:
[Top]
[1] | The Product Structure Model |
[2] | Building and Launching a CAA V5 Use Case |
[3] | Positioning Products Use Case |
[Top] |
Version: 1.1 [Aug 2004] | Document revised |
Version: 1 [Aug 2003] | Document created |
[Top] |
Copyright © 2003, Dassault Systèmes. All rights reserved.