3D PLM PPR Hub Open Gateway |
Feature Modeler |
Working with FeaturesAdding simple attributes to features |
Use Case |
AbstractThis article discusses the CAAOsmSimpleAttr use case. This use case explains how to load an existing catalog containing StartUps, how to create a document to contain new features, how to create new features by instantiating StartUps and existing features, how to add simple attributes to features and how to save the new document. |
This use case is intended to help you understand the basics of working with features. Its main intent is to explain how to create new features from StartUps or from existing features by instantiation and how to work with simple feature attributes. Through this use case, you will also learn some important aspects recommended when programming with features. Specifically, you will learn how to:
Before getting to the use case itself, it is important to get an understanding of what a feature object is and how it is created [1].
[Top]
CAAOsmSimpleAttr is a use case of the CAAObjectSpecsModeler.edu framework that illustrates CATIA ObjectSpecsModeler framework capabilities.
[Top]
The goal of CAAOsmSimpleAttr is to illustrate the basics of working with features. It uses the catalog defined in the CAAOsmCatalogSU use case [2] which contains StartUps based on the "book" example. This article describes how a new feature, "CAAOsmNovel1" is instantiated from the "CAAOsmNovel" StartUp, how its attributes are valuated, how new attributes are added to it and how it itself is instantiated to create another new feature.
A "CAAOsmNovel" has two attributes inherited from its "supertype" ("CAAOsmBook") which are "Title" and "BookPublisher". It has two other attributes of its own which are "Author" and "NovelChapter". Since this article deals with simple attributes, only "Title" and "Author" will be valuated. The CAAOsmReferencedAttr [3] and CAAOsmAggregatedAttr [4] use cases will show you how to work with referenced and aggregated attributes respectively.
[Top]
To launch CAAOsmSimpleAttr, you will need to set up the build time environment, then compile CAAOsmSimpleAttr along with its prerequisites, set up the run time environment, and then execute the sample.
mkrun -c "CAAOsmSimpleAttr CAAOsmCatalogSU.CATfct CatalogStoragePathNameOut"
This is fully described in the referenced article [5]. When launching the use case, you must pass the following arguments:
[Top]
CAAOsmSimpleAttr code is located in the CAAOsmSimpleAttr.m use case module of the CAAObjectSpecsModeler.edu framework:
Windows | InstallRootDirectory\CAAObjectSpecsModeler.edu\CAAOsmSimpleAttr.m |
Unix | InstallRootDirectory/CAAObjectSpecsModeler.edu/CAAOsmSimpleAttr.m |
where InstallRootDirectory
is the root directory of your CAA V5
installation. It is made of a unique source file named CAAOsmSimpleAttr.cpp.
[Top]
There are eight logical steps in CAAOsmSimpleAttr:
We will now comment each of those sections by looking at the code.
[Top]
See the referenced article [6] for a detailed description of the steps to go through when creating a new document.
In this use case, we create a new "Part" document: CATDocument
*pDoc
, and retrieve its root container: CATIContainer *piRootContainer
.
[Top]
Loading the catalog means opening the catalog document and getting a CATICatalog handle that will be needed in order to retrieve StartUps from the catalog.
CATUnicodeString stgName = argv[1]; CATICatalog *piCatalog; CATUnicodeString clientId("CAAOsmClientId"); rc = ::AccessCatalog (&stgName, &clientId, piRootContainer, &piCatalog); if (SUCCEEDED(rc)) cout << "Catalog accessed OK" << endl << flush; else { cout << "ERROR on AccessCatalog" << endl << flush; piRootContainer -> Release(); return 5; } |
To open a catalog, use the AccessCatalog
global function that
takes the following arguments:
stgName
- the name of the catalog without the storage path
and with the .CATfct extension. The catalog must be found under the
"WS" + "OS" + resources + graphic directory.clientId
- the client id defined on the catalog at the time
of its creation.piRootContainer
- a CATIContainer pointer to the
container in which StartUps from the catalog will be instantiated.piCatalog
- a CATICatalog pointer to the StartUps
catalog that has been opened.[Top]
CATBaseUnknown *pNovelSU = NULL; CATUnicodeString novelSUType("CAAOsmNovel"); rc = piCatalogOnContainer -> RetrieveSU(&pNovelSU, &novelSUType, "CATISpecObject"); if (NULL != pNovelSU) cout << "CAAOsmNovel StartUp retrieved OK" << endl << flush; else { (Process ERROR: Release pointers and return.) } // Get a CATISpecObject handle on the CAAOsmNovel StartUp CATISpecObject *piNovelSU = (CATISpecObject*) pNovelSU; |
A StartUp is retrieved from the catalog using the CATICatalog::RetrieveSU
method. This method returns a CATBaseUnknown pointer in pNovelSU
which is directly cast into a CATISpecObject pointer (piNovelSU
).
The CATBaseUnknown pNovelSU
pointer must be released
when no longer needed.
// Retrieve the attribute key to some of the CAAOsmNovel StartUp's attributes CATISpecAttrAccess *piSpecAttrAccessOnNovelSU = NULL; rc = piNovelSU -> QueryInterface(IID_CATISpecAttrAccess, (void**) &piSpecAttrAccessOnNovelSU); if (FAILED(rc)) { (Process ERROR: Release pointers and return.) } |
Once the StartUp has been retrieved, it is a good idea to immediately get the attribute keys that will be needed later on. These attribute keys remain globally available once they have been accessed. This means that valuating the attributes of any number instances of this StartUp will be more direct since there will be no need to access the attribute again before valuating it. In order to get the StartUp's attribute keys, we first get a CATISpecAttrAccess handle.
CATISpecAttrKey *piKeyTitle = piSpecAttrAccessOnNovelSU -> GetAttrKey("Title"); if (NULL == piKeyTitle) { (Process ERROR: Release pointers and return.) } CATISpecAttrKey *piKeyAuthor = piSpecAttrAccessOnNovelSU -> GetAttrKey("Author"); if (NULL == piKeyAuthor) { (Process ERROR: Release pointers and return.) } piSpecAttrAccessOnNovelSU -> Release(); |
Using CATISpecAttrAccess::GetAttrKey
, we get a CATISpecAttrKey
handle to each attribute that will be valuated.
[Top]
CATISpecObject *piNovelInst1 = piNovelSU -> Instanciate(CATUnicodeString("CAAOsmNovel1"), piRootContainer); pNovelSU -> Release(); if (NULL != piNovelInst1) cout << "CAAOsmNovel SU instance 1 created OK" << endl << flush; else { (Process ERROR: Release pointers and return.) } |
A new feature is created by instantiating a StartUp that has been retrieved
from the catalog. This is done using the Instanciate
method of CATISpecObject.
This method needs to know the new feature's name and the container in which it
will be created.
[Top]
In order to valuate the attributes of the new feature instance "CAAOsmNovel1", we use the different "Set" methods found in the CATISpecAttrAccess interface. As you have seen above, the attribute keys have already been retrieved on the "CAAOsmNovel" StartUp. What we need to do now, is to use these keys in order to valuate the attributes of the feature instance.
CATISpecAttrAccess *piSpecAttrAccessOnNovelInst = NULL; rc = piNovelInst1 -> QueryInterface(IID_CATISpecAttrAccess, (void**) &piSpecAttrAccessOnNovelInst); if (FAILED(rc)) { (Process ERROR: Release pointers and return.) } |
First of all, we get a CATISpecAttrAccess handle on the actual feature whose attributes we want to valuate.
piSpecAttrAccessOnNovelInst -> SetString(piKeyTitle, "The Three Musketeers"); piSpecAttrAccessOnNovelInst -> SetString(piKeyAuthor, "Alexandre Dumas"); piKeyTitle -> Release(); piKeyAuthor -> Release(); |
Then, we use SetString
to valuate the tk_string
attributes.
Note that the pointers acquired from GetAttrKey
must be
released.
[Top]
CATISpecAttribute *piVolumeNumber = piNovelInst1 -> AddAttribute(CATUnicodeString("Volume"), tk_integer); if (NULL != piVolumeNumber) piVolumeNumber -> Release(); CATISpecAttrKey *piKeyVolume = piSpecAttrAccessOnNovelInst -> GetAttrKey("Volume"); if (NULL == piKeyVolume) { (Process ERROR: Release pointers and return.) } piSpecAttrAccessOnNovelInst -> SetInteger(piKeyVolume, 1); piKeyVolume -> Release(); CATISpecAttribute *piTranslator = piNovelInst1 -> AddAttribute(CATUnicodeString("Translator"), tk_string); CATISpecAttrKey *piKeyTrans = piSpecAttrAccessOnNovelInst -> GetAttrKey("Translator"); if (NULL != piTranslator) piTranslator -> Release(); if (NULL == piKeyTrans) { (Process ERROR: Release pointers and return.) } piSpecAttrAccessOnNovelInst -> SetString(piKeyTrans, "John D. Smith"); piKeyTrans -> Release(); piSpecAttrAccessOnNovelInst -> Release(); |
To add new attributes to existing features, use the AddAttribute
method of CATISpecObject and then proceed as before to valuate them.
[Top]
CATISpecObject *piNovelInst2 = piNovelInst1 -> Instanciate(CATUnicodeString("CAAOsmNovel2"), piRootContainer); piNovelInst1 -> Release(); if (NULL != piNovelInst2) cout << "New instance of NovelInst1 created OK" << endl << flush; else { (Process ERROR: Release pointers and return.) } |
A new feature object can also be created based on an existing feature object by instantiating the latter. This means that the new feature instance inherits all of the attributes and their values of the feature it has been instantiated from. The new "CAAOsmNovel2" feature, for example, will inherit the new attributes "Volume" and "Translator" that were added to "CAAOsmNovel1" and which were not initially defined for the StartUp "Novel".
rc = piNovelInst2 -> QueryInterface(IID_CATISpecAttrAccess, (void**) &piSpecAttrAccessOnNovelInst); piNovelInst2 -> Release(); if (FAILED(rc)) { (Process ERROR: Release pointers and return.) } CATISpecAttrKey *piKeyVolume2 = piSpecAttrAccessOnNovelInst -> GetAttrKey("Volume"); if (NULL == piKeyVolume2) { (Process ERROR: Release pointers and return.) } piSpecAttrAccessOnNovelInst -> SetInteger(piKeyVolume2, 2); piKeyVolume2 -> Release(); piSpecAttrAccessOnNovelInst -> Release(); |
If we wanted to change the value of one of the new feature's attributes
that do not exist on the StartUp, it would be necessary to re-access the
attribute key since the acquisition of the key on the instantiating
feature's attribute does not remain global. So, we need to get a new CATISpecAttrAccess
handle on the new feature instance, access the attribute using GetAttrKey
and the set the value using a "Set..." method of CATISpecAttrAccess,
in this case, SetInteger
.
[Top]
piRootContainer -> Release(); piCatalogOnContainer -> Release(); |
Before proceeding to save the document, be sure to release any remaining pointers that will no longer be used.
See the referenced article [6] for a detailed description of the steps to go through when saving a document.
Note that the catalog document does not need to be removed from the session.
[Top]
This use case has demonstrated how to use the StartUps already defined in a catalog in order to create new feature objects within a new document and how to valuate and add attributes to these new features. Specifically, it has illustrated:
AccessCatalog
global functionRetrieveSU
method of CATICatalogGetAttrKey
of CATISpecAttrAccessInstanciate
method of CATISpecObject"Set..."
methods of CATISpecAttrAccessAddAttribute
method of CATISpecObject.This use case deals solely with simple attributes. Two other use cases, CAAOsmReferencedAttr [3] and CAAOsmAggregatedAttr [4], explain how to work with feature attributes.
[Top]
Version: 1 [Feb 2000] | Document created |
Version: 2 [Nov 2000] | Document modified |
[Top] |
Copyright © 2000, Dassault Systèmes. All rights reserved.