Product Synthesis & Knowledgeware |
DMU Kinematics Simulator |
Creating a Mechanism in a DocumentFrom geometrical lines to mechanism |
Use Case |
AbstractThis article discusses the CAAKiiCreateMechanism use case. This use case explains how to open a CATProduct document and explore its contents from a Kinematics perspective, down to the basic entities that capture the technology of a mechanism contained in the document.
|
This use case is intended to help you make your first steps in programming the CATIA Kinematics modeler. Its main intent is to introduce the API of the Kinematics modeler, and ways to use it.
The scenario is based on the creation of a simple mechanism starting from an assembly of two products which each contains a line. One will create the mechanism in the document, then create a joint on the two lines and create a command to control the mechanism. This mechanism will be movable interactively in the Kinematics workbench.
This picture represents a CATProduct document containing lines to create a mechanism.
[Top]
Before getting to the use case itself, it is important to get an understanding of some of the concepts that are at the heart of the Kinematics, since the use case basically navigates among objects that represent those concepts. They are presented in Kinematics Overview [1].
These concepts are:
[Top]
CAAKiiCreateMechanism is a use case of the CAAKinematicsInterfaces.edu framework that illustrates KinematicsInterfaces framework capabilities.
[Top]
The goal of CAAKiiCreateMechanism is to create a mechanism in an assembly using two products as links, and a cylindrical joint that enables a product to translate along a line with respect to the other product that remains fixed in the assembly, thanks to a translation command associated with the mechanism. To do this, CAAKiiCreateMechanism:
[Top]
To launch CAAKiiCreateMechanism, you will need to set up the build time environment, then compile CAAKiiCreateMechanism along with its prerequisites, set up the run time environment, and then execute the use case [2].
Launch the use case as follows:
e:> CAAKiiCreateMechanism inputDirectory inputFile.CATProduct outputDirectory |
$ CAAKiiCreateMechanism inputDirectory inputFile.CATProduct outputDirectory |
where:
inputDirectory |
The directory in which inputFile.CATProduct is located |
inputFile.CATProduct
| The file that contains the use case CATProduct document |
outputDirectory |
The directory into which inputFile.CATProduct is stored
after the mechanism is created |
[Top]
The CAAKiiCreateMechanism use case is made of a C++ main named CAAKiiCreateMechanism whose source file is located in the CAAKiiCreateMechanism.m module of the CAAKinematicsInterfaces.edu framework:
Windows | InstallRootDirectory\CAAKinematicsInterfaces.edu\CAAKiiCreateMechanism.m\ |
Unix | InstallRootDirectory/CAAKinematicsInterfaces.edu/CAAKiiCreateMechanism.m/ |
where InstallRootDirectory
is the directory where the CAA CD-ROM
is installed. The CAAKiiCreateMechanism class derives from CATInteractiveApplication.
The described code is located in the BeginApplication
method.
[Top]
You will find a CATProduct sample document in the following directory:
Windows | InstallRootDirectory\CAADoc\CAAKinematicsInterfaces.edu\CNext\resources\graphic\ |
Unix | InstallRootDirectory/CAADoc/CAAKinematicsInterfaces.edu/CNext/resources/graphic/ |
where InstallRootDirectory
is the directory where the CAA CD-ROM
is installed. The sample is called CAAKiiCreateMechanism.CATProduct
.
[Top]
We will now comment each of those sections by looking at the code.
[Top]
The use case is the CAAKiiCreateMechanism batch which runs in one shot. The described code is
located in the C++ main
method. It begins by creating a
session, and by opening the use case CATProduct document passed as an argument: pDocument
refers to it. This is the usual sequence for creating a document [3].
[Top]
The objective of this step is to retrieve the connector associated with the line in each of the two products:
... // Search all the roots of the document CATIDocRoots* piDocRootsOnDocument = NULL; HR = pDocument->QueryInterface(IID_CATIDocRoots, (void**)&piDocRootsOnDocument); if (SUCCEEDED(HR)) { CATListValCATBaseUnknown_var* pRootList = piDocRootsOnDocument->GiveDocRoots(); piDocRootsOnDocument->Release(); piDocRootsOnDocument = NULL; if (NULL != pRootList) { // Search the root product CATIProduct* piProductOnRootProduct = NULL; CATIProduct_var spRootProduct = NULL_var; for (int j = 1; j <= pRootList->Size() && NULL == piProductOnRootProduct; j++) { HR = (*pRootList)[j]->QueryInterface(IID_CATIProduct,(void**)&piProductOnRootProduct); if (SUCCEEDED(HR)) {spRootProduct = (*pRootList)[j];} } delete pRootList; pRootList = NULL; // Get all the products of the root product CATListValCATBaseUnknown_var* pProductList = piProductOnRootProduct->GetAllChildren(); int numberOfProducts = pProductList->Size(); // Search two valid lines in the products const int maximumNumberOfConnector = 2; CATLISTP(CATBaseUnknown) iConnectorList; CATIProduct* piFixedProduct = NULL; int numberOfConnector = 0; for (int i = 1; numberOfConnector < maximumNumberOfConnector && i <= numberOfProducts; i++) { // Search the product CATIProduct* piProductOnProduct = NULL; if (SUCCEEDED((*pProductList)[i]->QueryInterface(IID_CATIProduct,(void**)&piProductOnProduct))) { // retain first product to be set as fixed at the end if (i==1) { piFixedProduct = piProductOnProduct; piFixedProduct->AddRef(); } // Search the link to the shape representation associated with the product CATILinkableObject_var spLinkableOnShapeRep = NULL_var; if (SUCCEEDED(piProductOnProduct->GetShapeRep(spLinkableOnShapeRep))) { // Use the link the find the document containing the shape representation CATDocument* pShapeDocument = spLinkableOnShapeRep->GetDocument(); if (NULL != pShapeDocument) { // Find the container of the document CATIContainerOfDocument* piContainerOfDocumentOnShapeDocument = NULL; if (SUCCEEDED(pShapeDocument->QueryInterface(IID_CATIContainerOfDocument, (void**)&piContainerOfDocumentOnShapeDocument))) { // Find the container of the geometry CATIContainer* piContainer = NULL; piContainerOfDocumentOnShapeDocument->GetSpecContainer(piContainer); piContainerOfDocumentOnShapeDocument->Release(); piContainerOfDocumentOnShapeDocument = NULL; if (NULL != piContainer) { // List all geometrical entities and search the first line in the document SEQUENCE(CATBaseUnknown_ptr) memberList = piContainer->ListMembers(CATLine::ClassName()); CATBaseUnknown* papiUnknownOnLineConnector = NULL; for (int k = 0; NULL == papiUnknownOnLineConnector && k < memberList.length(); k++) { // Filter the line CATLine* piLine = NULL; if (SUCCEEDED(memberList[k]->QueryInterface(IID_CATLine,(void**)&piLine))) { CATILinkableObject_var spLinkableOnLine (memberList[k]); if (NULL_var != spLinkableOnLine) { // Get the connector associated to the line int xCreation = 0; HR = GetProductConnector(spLinkableOnLine, piProductOnProduct, piProductOnRootProduct, 0, spConnectorOnLine, xCreation); if (NULL_var != spConnectorOnLine) { // Store the connector as a CATBaseUnknown HR = spConnectorOnLine->QueryInterface(IID_CATBaseUnknown, (void**)&papiUnknownOnLineConnector); } } piLine->Release(); piLine = NULL; } } // Store the connector and the product corresponding to the line if (NULL != papiUnknownOnLineConnector) { iConnectorList.Append(papiUnknownOnLineConnector); numberOfConnector++; papiUnknownOnLineConnector->Release(); papiUnknownOnLineConnector = NULL; } piContainer->Release(); piContainer = NULL; } } } piProductOnProduct->Release(); piProductOnProduct = NULL; } } } delete pProductList; pProductList = NULL; piProductOnRootProduct->Release(); piProductOnRootProduct = NULL; ... |
A CATProduct document contains many roots accessible thru GiveDocRoots
method available on the CATIDocRoots interface of the document. The first
root which answer to the interface CATIProduct, is the root of all the
products in the document. To get all the products, the sample gets the children
of the root product. Then the sample search two lines which belong to the
products. It queries the document associated to each product as a shape
representation. Having the list of all geometries in this document, it filters
the lines and retrieves their connector. This connector and the corresponding
product are stored in papiUnknownOnConnector
and papiProduct
.
The sample has to clean the environment and release all resources. The technique
is fairly simple: all references to interfaces have to be released using CATBaseUnknown::Release()
and nullified.
[Top]
... CATIKinMechanism* piMechanism = NULL; CATIKinMechanismFactory* piDocumentAsMechanismFactory = NULL; if (SUCCEEDED(pDocument->QueryInterface(IID_CATIKinMechanismFactory, (void**)&piDocumentAsMechanismFactory))) { if (SUCCEEDED(piDocumentAsMechanismFactory->CreateInstance(&piMechanism))) { ... |
The creation of a mechanism in the document is made through the factory
method CreateInstance
.
The factory is obtained thru a QueryInterface on pDocument
.
[Top]
... if (numberOfConnector == maximumNumberOfConnector) { // Cylindrical joint from connectors CATIKinJoint* piJoint = NULL; const char* jointType = CATKinCylindricalJoint; boolean iCreateConstraintsForJoint = 1; if (SUCCEEDED(piMechanism->AddJoint(jointType,&iConnectorList, iCreateConstraintsForJoint, &piJoint))) { ... |
A cylindrical joint is created in the mechanism from the two retrieved
connectors using the AddJoint
method of the CATIKinMechanism interface, with the connectors
stored in iConnectorList
.
[Top]
... CATIKinCmd* piCmd = NULL; const char* cmdType = CATKinLengthCmd; if (SUCCEEDED(piMechanism->AddCommand(piJoint, cmdType, &piCmd))) { piCmd->Release(); piCmd = NULL; } piJoint->Release(); piJoint = NULL; } } ... |
A translation command is associated with the mechanism to apply to the joint
using AddCommand
method of the CATIKinMechanism interface.
[Top]
... boolean iCreateConstraintsForFixed = 1; HR = piMechanism->SetFixedProduct(piFixedProduct,iCreateConstraintsForFixed); piFixedProduct->Release(); piFixedProduct = NULL; ... |
To complete the mechanism, the fixed product is defined using SetFixedProduct
method of the CATIKinMechanism interface.
[Top]
... piMechanism->Release(); piMechanism = NULL; } piDocumentAsMechanismFactory->Release(); } ... |
The pointers to the mechanism and factory are released.
Then, the document is saving using CATDocumentServices::SaveAs
static method in the directory passed as the third argument when launching the
use case, and with the same name as the input document. After being saved, it is
is closed using the remove
method of its LifeCycleObject
interface. The environment is cleaned, and the session is deleted by the Delete_Session
global function, which is passed the same identifier that was used to open it.
This is the usual sequence for saving and closing a CATIA document, and for
deleting the session [3].
[Top]
More specifically, you have learn how to create:
[Top]
[1] | Kinematics Overview |
[2] | Building and Launching a CAA V5 Use Case |
[3] | Creating a New Document |
[Top] |
Version: 1 [Jan 2000] | Document created |
Version: 2 [Jan 2001] | Interface reviewed; exposing only KinematicsInterfaces |
Version: 3 [Aug 2002] | CATProduct sample document added |
[Top] |
Copyright © 2000-2001, Dassault Systèmes. All rights reserved.