3D PLM PPR Hub Open Gateway |
Feature Modeler |
Working with Cut, Copy and Paste OperationsPerforming CCP operations on features |
Use Case |
AbstractThis article discusses the CAAOsmCCP use case. This use case explains how to perform Cut, Copy and Paste operations on feature objects in applicative containers. |
This use case is intended to help you understand how to perform Cut, Copy and Paste operations on feature objects in applicative containers. Specifically, you will learn how to:
Paste
and Remove
methods of CATICutAndPastableBoundaryExtract
,
Extract
and Paste
methods of CATICutAndPastableBefore getting to the use case itself, you should have a good understanding of what a feature object is and how it is created [1].
[Top]
CAAOsmCCP is a use case of the CAAObjectSpecsModeler.edu framework that illustrates ObjectSpecsModeler framework capabilities.
[Top]
The goal of CAAOsmCCP is to illustrate performing CCP operations on feature objects in both batch and interactive modes. To exemplify this, it uses the "CAAOsmNovel" and "CAAOsmChapter" StartUps defined in the catalog created by the CAAOsmCatalogSU use case [2]. These StartUps are instantiated in an applicative container created in a new document. Here is an image of the initial contents of this document:
Note that two CATFeatCont containers have been created, one of which contains one instance of the "CAAOsmNovel" StartUp and three new instances of the "CAAOsmChapter" StartUp. The second CATFeatCont is initially empty.
Next, "CAAOsmChapter1" and "CAAOsmChapter2" are copied from the first container, said to be the source container, to the second, said to be the target container. "CAAOsmChapter1" is removed from the source container. This illustrates a Cut/Paste of "CAAOsmChapter1" as it is removed from the source container and pasted in the target container and a Copy/Paste of "CAAOsmChapter2" from the source container to the target container. This example is meant to show how you would program this operation in batch mode, without needing to pass through the clipboard. Here is an image of the CATPart Document after this operation has been performed:
Finally, "CAAOsmChapter3" is copied from the source container to the target container. This operation is shown as it would need to be programmed in interactive mode. In this case, it is first necessary to extract the object from the source container and store it in the clipboard. Then, it is extracted from the clipboard and pasted in the target container. Here is an image of the CATPart Document after this second operation has been performed:
[Top]
To launch CAAOsmCCP, you will need to set up the build time environment, then compile CAAOsmCCP along with its prerequisites, set up the run time environment, and then execute the sample as follows:
mkrun -c "CAAOsmCCP CAAOsmCatalogSU.CATfct DocumentStorageName.CATPart"
This step is fully described in the referenced article [3]. Following are the arguments passed when launching the use case:
[Top]
CAAOsmCCP code is located in the CAAOsmCCP.m use case module of the CAAObjectSpecsModeler.edu framework:
Windows | InstallRootDirectory\CAAObjectSpecsModeler.edu\CAAOsmCCP.m |
Unix | InstallRootDirectory/CAAObjectSpecsModeler.edu/CAAOsmCCP.m |
where InstallRootDirectory
is the root directory of your CAA V5
installation. It is made of a unique source file named CAAOsmCCP.cpp.
[Top]
There are eight logical steps in CAAOsmCCP:
We will now comment each of those sections by looking at the code.
[Top]
... // We will work with a "CATPart" document. CATDocument *pDoc = NULL; rc = CATDocumentServices::New("Part", pDoc); if (NULL != pDoc) cout << "New document created OK" << endl << flush; else { cout << "ERROR in creating New document" << endl << flush; return 2; } ... |
A new document is created simply by executing the New
method of CATDocumentServices.
CATLockDocument(*pDoc); |
In general, when working in batch with CCP operations, it is a good idea to lock
the document ahead of time in order to avoid problems when wanting to save it or
remove it from the session. This is done using the CATLockDocument
method of CATSessionServices. Remember, however, that it is extremely
important not to forget to unlock the document at the end!
// Retrieve the root container of the document CATInit *piInitOnDoc = NULL; rc = pDoc -> QueryInterface(IID_CATInit, (void**) &piInitOnDoc); if (FAILED(rc)) { cout << "ERROR in QueryInterface on CATInit for doc" << endl << flush; return 3; } const CATIdent idCATIContainer = "CATIContainer"; CATIContainer *piRootContainer = NULL; piRootContainer = (CATIContainer*) piInitOnDoc -> GetRootContainer(idCATIContainer); piInitOnDoc -> Release(); piInitOnDoc = NULL; if (NULL == piRootContainer) { cout << "ERROR in GetRootContainer" << endl << flush; return 4; } |
It is also necessary to retrieve the root container of the newly-created
document because it will be needed in order to load the catalog of StartUps. The
root container is retrieved using the GetRootContainer
method of CATInit.
[Top]
IdFormat FEATURE_FORMAT = "CATFeatCont"; const CATFormat *featFormat = ::SpecBindNativeFormat(FEATURE_FORMAT); |
Formats are used by the CCP system in order to perform specific user-defined
actions. A format type can be any user-defined string. Format types must be
defined in the CCP system before they can be used. Use SpecBindNativeFormat
to declare them. If no formats are needed, as in this use case, the container's
late type is used by default. Here we are working in a "CATFeatCont
"
container.
[Top]
CATIdent idAppliCont = "CATFeatCont"; CATUnicodeString sourceAppliContId ("CAAOsmSourceContainer"); CATBaseUnknown *pSourceContainer = NULL; rc = ::CATCreateApplicativeContainer(&pSourceContainer, // appli cont created pDoc, // document idAppliCont, // type of appli cont IID_CATIContainer, // interface type of appli cont "", // supertype of appli cont sourceAppliContId); // name of appli cont if (SUCCEEDED(rc)) cout << "Source applicative container created OK" << endl << flush; else { cout << "ERROR in creating source applicative container" << endl << flush; piRootContainer -> Release(); return 5; } |
A new applicative container is created using the CATCreateApplicativeContainer
global function. See the CAAOsmAppliCont [5] use case
for a more detailed description of this service. Above you can see how to create
the first or "Source" container. The same procedure is performed for
the second or "Target" container.
[Top]
Loading a catalog means opening the catalog document in order to allow the access to the StartUps it contains.
CATUnicodeString stgName = argv[1]; CATICatalog *piCatalog; CATUnicodeString clientId("CAAOsmClientId"); rc = ::AccessCatalog (&stgName, &clientId, piSourceContainer, &piCatalog); if (SUCCEEDED(rc)) cout << "Catalog accessed OK" << endl << flush; else { cout << "ERROR on AccessCatalog" << endl << flush; pSourceContainer -> Release(); pTargetContainer -> 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.piSourceContainer
- 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 = piCatalog -> RetrieveSU(&pNovelSU, &novelSUType, "CATISpecObject"); if (NULL != pNovelSU) cout << "CAAOsmNovel StartUp retrieved OK" << endl << flush; else { cout << "ERROR in retrieving CAAOsmNovel StartUp" << endl << flush; pSourceContainer -> Release(); pTargetContainer -> Release(); piCatalog -> Release(); return 7; } // Get a CATISpecObject handle on the CAAOsmNovel StartUp CATISpecObject *piNovelSU = (CATISpecObject*) pNovelSU; |
In order to create new feature objects in the document, it is first necessary to retrieve an existing StartUp. The example above shows how the StartUp whose type is "CAAOsmNovel" is retrieved from the catalog. The same must be done for the "CAAOsmChapter" StartUp whose type is "CAAOsmChapter".
CATISpecObject *piNovelInst1 = piNovelSU -> Instanciate(CATUnicodeString("CAAOsmNovel1"), pSourceContainer); pNovelSU -> Release(); pNovelSU = NULL; if (NULL != piNovelInst1) cout << "CAAOsmNovel instance 1 created OK" << endl << flush; else { cout << "ERROR in creating instance 1 of CAAOsmNovel SU" << endl << flush; pSourceContainer -> Release(); pTargetContainer -> Release(); piCatalog -> Release(); return 8; } piNovelInst1 -> Release(); piNovelInst1 = NULL; |
A new feature object is created in the source container by instantiating
a StartUp. Above, you can see that a new feature object
"CAAOsmNovel1" is created using the Instanciate
method of CATISpecObject. The same must be done in order to create
the other three features, "CAAOsmChapter1",
"CAAOsmChapter2" and "CAAOsmChapter3" which will be
needed in this use case. They will be handled using piChapterInst1
,
piChapterInst2
and piChapterInst3
respectively.
[Top]
This first case deals with performing CCP operations while working in batch mode. This case is simpler, since there is no need to pass through the clipboard, the CCP operations are performed directly. However for a Mechanical feature, the second methodology must be used. See CCP in Interactive Mode.
The first case directly pastes "CAAOsmChapter1" and "CAAOsmChapter2" into the target container and then deletes "CAAOsmChapter1" from the source container.
CATICutAndPastable *piCutAndPastableOnTargetCont = NULL; rc = pTargetContainer -> QueryInterface(IID_CATICutAndPastable, (void**) &piCutAndPastableOnTargetCont); pTargetContainer -> Release(); pTargetContainer = NULL; if (FAILED(rc)) { cout << "ERROR in QueryInterface on CATICutAndPastable on Target Container" << endl << flush; pSourceContainer -> Release(); piChapterInst1 -> Release(); piChapterInst2 -> Release(); piChapterInst3 -> Release(); return 3; } |
ListOfVarBaseUnknown listToPaste; listToPaste.Append(piChapterInst1); listToPaste.Append(piChapterInst2); ListOfVarBaseUnknown listPastedObjects = piCutAndPastableOnTargetCont -> Paste (listToPaste, NULL, NULL); if (listPastedObjects.Size() != 2) { cout << "ERROR in Paste of objects" << endl << flush; pSourceContainer -> Release(); piChapterInst1 -> Release(); piChapterInst2 -> Release(); piChapterInst3 -> Release(); return 9; } else cout << "Objects Pasted in Target Container from Source Container OK" << endl << flush; piChapterInst2 -> Release(); piChapterInst2 = NULL; |
A copy in batch mode is simply performed by pasting objects directly in
the target container. This is done using the Paste
method of CATICutAndPastable
which takes the following arguments:
CATICutAndPastable *piCutAndPastableOnSourceCont = NULL; rc = pSourceContainer -> QueryInterface(IID_CATICutAndPastable, (void**) &piCutAndPastableOnSourceCont); pSourceContainer -> Release(); pSourceContainer = NULL; if (FAILED(rc)) { cout << "ERROR in QueryInterface on CATICutAndPastable on Source Container" << endl << flush; piChapterInst1 -> Release(); piChapterInst3 -> Release(); piCutAndPastableOnTargetCont -> Release(); return 3; } |
ListOfVarBaseUnknown listToRemove; listToRemove.Append(piChapterInst1); piChapterInst1 -> Release(); piChapterInst1 = NULL; if (piCutAndPastableOnSourceCont -> Remove (listToRemove, NULL)) cout << "Remove of objects from Source Container succeeded" << endl << flush; else { cout << "Remove failed" << endl << flush; piCutAndPastableOnSourceCont -> Release(); piCutAndPastableOnTargetCont -> Release(); piChapterInst3 -> Release(); return 10; } |
Deleting an object in batch mode is simply performed by passing the list
of objects to be removed as input to the Remove
method of CATICutAndPastable.
Note that the second argument to this method is the format type which is not
used here.
[Top]
This second case deals with performing CCP operations while working in interactive mode. In this case, all operations need to pass through the clipboard. In other words, objects must first be extracted from the source container to the clipboard, from which they must again be extracted in order to be copied to the target container. In other words, "CAAOsmChapter3" will be extracted from the source container to the clipboard from which it will be extracted and pasted into the target container.
ListOfVarBaseUnknown newListToCopy; ListOfVarBaseUnknown listFromCopy; listFromCopy.Append(piChapterInst3); piChapterInst3 -> Release(); piChapterInst3 = NULL; int result = NULL; result = piCutAndPastableOnSourceCont -> BoundaryExtract (newListToCopy, &listFromCopy, NULL); if (NULL != result) { cout << "BoundaryExtract from Source Container succeeded" << endl << flush; cout << "Number of objects extracted = " << newListToCopy.Size() << endl << flush; } else { cout << "BoundaryExtract failed" << endl << flush; piCutAndPastableOnSourceCont -> Release(); piCutAndPastableOnTargetCont -> Release(); return 11; } VarBaseUnknown pExtractedList; pExtractedList = piCutAndPastableOnSourceCont -> Extract (newListToCopy, NULL); piCutAndPastableOnSourceCont -> Release(); piCutAndPastableOnSourceCont = NULL; |
In the above example, objects are first stored in a list using the BoundaryExtract
method of CATICutAndPastable which is useful when constructing a list
of objects. This method takes the following arguments:
Next, using the Extract
method of CATICutAndPastable, the
objects contained in the list passed into the first argument are actually
extracted and saved in the clipboard. The second argument to this method is
again the iAnImposedFormat which is not used.
pExtractedList
)
CATICutAndPastable *piCutAndPastableOnExtractedList = NULL; rc = pExtractedList -> QueryInterface(IID_CATICutAndPastable, (void**) &piCutAndPastableOnExtractedList); if (FAILED(rc)) { cout << "ERROR in QueryInterface on CATICutAndPastable on Target Container" << endl << flush; return 3; } |
In order to paste objects, they must be extracted from the clipboard.
First of all, it is necessary to get a CATICutAndPastable handle on
the container representing the clipboard. The pointer to this container was
returned by the preceding Extract
operation.
ListOfVarBaseUnknown extractedListToCopy; result = NULL; result = piCutAndPastableOnExtractedList -> BoundaryExtract (extractedListToCopy, NULL, NULL); if (NULL != result) { cout << "BoundaryExtract from Clipboard succeeded" << endl << flush; cout << "Number of objects extracted = " << extractedListToCopy.Size() << endl << flush; } else { cout << "BoundaryExtract failed" << endl << flush; piCutAndPastableOnTargetCont -> Release(); return 11; } piCutAndPastableOnExtractedList -> Release(); piCutAndPastableOnExtractedList = NULL; listPastedObjects = piCutAndPastableOnTargetCont -> Paste (extractedListToCopy, NULL, NULL); if (listPastedObjects.Size() != 1) { cout << "ERROR in Paste of objects" << endl << flush; return 9; } else cout << "Objects Pasted from Clipboard to Target Container OK" << endl << flush; piCutAndPastableOnTargetCont -> Release(); piCutAndPastableOnTargetCont = NULL; |
Next, a BoundaryExtract
is performed passing a NULL pointer
in the second argument, thus creating a list of all of the objects currently
waiting in the clipboard. Then, the Paste
method simply copies
the objects contained in this list into the target container.
[Top]
See the referenced article [4] for a detailed description of the steps to go through when saving the document. Note, however, that an unlock of the document must be performed in order to effectively release it from the session:
CATUnLockDocument(*pDoc); |
This is done using the CATUnlockDocument
method of CATSessionServices.
Note that the catalog document does not need to be removed from the session.
[Top]
This use case has demonstrated how to perform Cut, Copy and Paste operations on feature objects in applicative containers in both batch and interactive mode. Specifically, it has illustrated:
SpecBindNativeFormat
global functionCATCreateApplicativeContainer
global functionPaste
and Remove
methods of CATICutAndPastableBoundaryExtract
and Extract
methods in order to store in and retrieve objects
from the clipboard[Top]
Version: 1 [Aug 2000] | Document created |
Version: 2 [Nov 2000] | Document modified |
[Top] |
Copyright © 2000, Dassault Systèmes. All rights reserved.