3D PLM PPR Hub Open Gateway

Process Modeler

Creating a New Process Document

Defining new activities, items and resources in a process document
Use Case

Abstract

This article accompanies the CAADmiGenerProcess use case. This use case explains how to create a new document by defining new activities, items and resources and the relationships between them.


What You Will Learn With This Use Case

This use case is intended to help you create a new process document containing activities, items and resources, ordered in a control flow. Specifically, you will learn how to:

[Top]

The CAADmiGenerProcess Use Case

CAADmiGenerProcess is a use case of the CAADMAPSInterfaces.edu framework that illustrates DMAPSInterfaces framework capabilities.

[Top]

What Does CAADmiGenerProcess Do

The goal of CAADmiGenerProcess is to illustrate the creation of a new process document. This specific process document uses activities defined in the CAADmiGenerLibrary use case [1]: "CAADmiPlace" and "CAADmiAssembly". Two "CAADmiPlace" activities and one "CAADmiAssembly" activity are instantiated in this use case. These activities are then ordered in a control flow having a beginning and an end. Next, two CATProduct documents are loaded into the session. The first contains two items, "sheet" and "screw". "Sheet" is attached to the first "CAADmiPlace" activity and to the "CAADmiAssembly" activity. "Screw" is attached to the second "CAADmiPlace" activity and to the "CAADmiAssembly" activity. The second CATProduct document contains a resource, "table" which is attached to the "CAADmiAssembly" activity.

Here is a CATIA image of the CATProduct document containing the two items, "sheet" and "screw":
Fig.1

And here is a CATIA image of the CATProduct document containing the resource "table":
Fig.2

Finally, you can see the entire process: the activity flow in the MainProcess goes from Startxxx.1 to Stopxxx.1, going through the three activities we just saw, namely the two "Place" activities called CAADmiPlaceSU1 and CAADmiPlaceSU2, and the " Assembly" activity, called Assembly, containing the table resource and the sheet + screw assembly.
Fig.3

Below is a schematic view of the flow of control between the different activities. You can also see the items and resources attached to each activity. In essence, this diagram shows that first the sheet and screw are placed on the table where they are assembled. In other terms, this means that the sheet item is attached to a "Place" activity, the screw item is attached to another "Place" activity and finally the sheet item and the screw item are assembled together and placed on the table resource defined in the "Assembly" activity.

Fig.4

[Top]

How to Launch CAADmiGenerProcess?

To launch CAADmiGenerProcess, you will need to set up the build time environment, then compile CAADmiGenerProcess 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 "CAADmiGenerProcess LibraryName.act Item.CATProduct Resource.CATProduct Process.CATProcess"

[Top]

Where to Find CAADmiGenerProcess Code?

CAADmiGenerProcess code is located in the CAADmiGenerProcess.m use case module of the CAADMAPSInterfaces.edu framework:

Windows InstallRootDirectory/CAADMAPSInterfaces.edu/CAADmiGenerProcess.m
Unix InstallRootDirectory\CAADMAPSInterfaces.edu\CAADmiGenerProcess.m

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

[Top]

Step-by-Step

There are six logical steps in CAADmiGenerProcess:

  1. Creating a New Process Document
  2. Instantiating Activities Defined in an Activity Library
  3. Ordering the Activities Using Control Flow
  4. Setting Items on Different Activities
  5. Setting a Resource on an Activity
  6. Saving the Process Document

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

[Top]

Creating a New Process Document

  1. Create session and configure library file path
    HRESULT rc = E_FAIL;
    ...
    CATSession *pSession = NULL;
    rc = ::Create_Session("CAA2_Sample_Session", pSession );
    CATListOfCATUnicodeString ActivityLibrariesList;
    ActivityLibrariesList.Append(argv[1]);
    CATISPPConfig *piConfigSession = NULL;
    rc = pSession -> QueryInterface(IID_CATISPPConfig,
                                    (void**) &piConfigSession);
    if (FAILED(rc) ) return 5;
    
    piConfigSession->SetListOfLibraryFilePath(ActivityLibrariesList);
    piConfigSession->Release();
    piConfigSession = NULL;

    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.

    In order to instantiate activities defined in the activities library, it is also necessary to configure the library file path in order for the library to be accessible. This is done by first creating a list containing the name of the activities library (passed as an argument to the use case) which is an .act file. Next, we get a CATISPPConfig handle based on the pointer to the current Session and using this handle, we perform the SetListOfLibraryFilePath method having as argument the list of libraries we have just defined.

  2. Create a new process document
    CATDocument *pNewDoc = NULL;
    rc = CATDocumentServices::New("Process", pNewDoc );
    if ( FAILED(rc) || (NULL==pNewDoc)) return 2;

    The new process document is created using CATDocumentServices::New specifying "Process" as the document type. The document type is the name that appears in the list of document types when performing a File/New during an interactive CATIA session: it is not the suffix of the document.

  3. Retrieve Process document's root container
    CATInit *piInitOnDoc = NULL;
    rc = pNewDoc -> QueryInterface(IID_CATInit,
                                   (void**) &piInitOnDoc);
    if (FAILED(rc) ) return 5;
    
    CATISPPProcessContainer *piProcessCont = (CATISPPProcessContainer* )
    	piInitOnDoc->GetRootContainer(CATISPPProcessContainer::ClassName());
    if ( NULL == piProcessCont ) return 3;
    piInitOnDoc -> Release();
    piInitOnDoc = NULL;

    First of all, the document's root container is retrieved using the GetRootContainer method of CATInit which is directly cast to a CATISPPProcessContainer handle.

  4. Get Processes
    CATLISTV(CATBaseUnknown_var)* pProcessList =
    	piProcessCont->GetAllProcess();
    if ((NULL == pProcessList) || ((*pProcessList).Size() < 1))
    { 
       cout << "** ERROR empty list of process " << endl;
       if ((*pProcessList).Size() > 0) delete pProcessList;
       return 4;
    }
    cout << " number of processes : "<< (*pProcessList).Size() << endl << flush;
    piProcessCont -> Release();
    piProcessCont = NULL;

    Using the CATISPPProcessContainer handle, we can get a list of all the processes container in the document using the GetAllProcess method.

  5. Get root activity
    // root activity is the first of the list of processes.
    CATISPPActivityRoot_var spActivityRoot = (*pProcessList)[1];
    delete pProcessList;
    pProcessList=NULL;

    The root activity is the first process in the list and we retrieve it in a CATISPPActivityRoot handle.

  6. Get CATISPPChildManagement and CATISPPAbstractActivity handles
    CATISPPChildManagement *piChildManagOnActivity = NULL;
    rc = spActivityRoot -> QueryInterface(IID_CATISPPChildManagement, 
    		                      (void**) &piChildManagOnActivity);
    if (FAILED(rc))	return 5;
    
    CATISPPAbstractActivity *piActivityOnActivity = NULL;
    rc = spActivityRoot -> QueryInterface(IID_CATISPPAbstractActivity, 
    		                      (void**) &piActivityOnActivity);
    if (FAILED(rc)) return 5;

    Using the CATISPPActivityRoot handle, we can get handles on CATISPPChildManagement and CATISPPAbstractActivity which will be needed later, as you will see in the following section.

  7. Set a label on the root activity
    piActivityOnActivity->SetLabel("MainProcess");
    piActivityOnActivity -> Release();
    piActivityOnActivity = NULL;

    We can also set a label on the root activity which will appear on the first node under "ProcessList" in the process document (see Fig.3). This is done using the SetLabel method of CATISPPAbstractActivity.

[Top]

Instantiating Activities Defined in an Activity Library

// instanciate the "CAAAssembly" process
// ( defined in the library of activities ).
CATISPPAbstractActivity_var spAssemblyProcess = 
	piChildManagOnActivity->AddChild("CAADmiAssembly");   
spAssemblyProcess->SetLabel("Assembly ( sheet + screw)");

// instanciate the "CAAPlace " process 
// ( defined in the library of activities ).
CATISPPAbstractActivity_var spPlaceActivity1 =
	piChildManagOnActivity->AddChild("CAADmiPlace");
CATISPPAbstractActivity_var spPlaceActivity2 = 
	piChildManagOnActivity->AddChild("CAADmiPlace");

The activities from the library are instantiated. This is done using the CATISPPChildManagement handle acquired in the previous section to execute the AddChild method on the name of the activity. This is how we create three activities, one based on the "CAADmiAssembly" activity and two others based on the "CAADmiPlace" activity. Remember that these activities were created in an activity file in the CAADmiGenerLibrary use case [1].

[Top]

Ordering the Activities Using Control Flow

  1. Define Start and Stop
    CATISPPFlowMgt_var spRootStartFlow = 
    	(*piChildManagOnActivity->GetChild("Start"))[1];
    CATISPPFlowMgt_var spRootStopFlow  = 
    	(*piChildManagOnActivity->GetChild("Stop"))[1];
    
    piChildManagOnActivity -> Release();
    piChildManagOnActivity = NULL;

    Ordering activities implies defining a beginning and an end. This is done by defining a CATISPPFlowMgt_var variable by executing the GetChild method of CATISPPChildManagement on the "Start" and "Stop" keywords. This creates "Start" and "Stop" nodes in the activities tree of the process document.

  2. Ordering the flow of control
    // adds a control flow between "start" activity and "Place" one.
    CATISPPFlowMgt *piRootStartOnFlow = NULL;
    rc = spRootStartFlow -> QueryInterface(IID_CATISPPFlowMgt,
    		                       (void**) &piRootStartOnFlow);
    if (FAILED(rc) ) return 5;
    piRootStartOnFlow->AddControlFlow(spPlaceActivity1);
    piRootStartOnFlow->Release();
    piRootStartOnFlow = NULL;
    
    // adds a control flow between activities "place".
    CATISPPFlowMgt *piPlaceOnFlow1 = NULL;
    rc = spPlaceActivity1 -> QueryInterface(IID_CATISPPFlowMgt,
    		                        (void**) &piPlaceOnFlow1);
    if (FAILED(rc) ) return 5;
    piPlaceOnFlow1->AddControlFlow(spPlaceActivity2);
    piPlaceOnFlow1->Release();
    piPlaceOnFlow1 = NULL;
    
    // adds a control flow between activity "place" and "assembly"
    CATISPPFlowMgt *piPlaceOnFlow2 = NULL;
    rc = spPlaceActivity2 -> QueryInterface(IID_CATISPPFlowMgt,
    		                        (void**) &piPlaceOnFlow2);
    piPlaceOnFlow2->AddControlFlow(spAssemblyProcess);
    piPlaceOnFlow2->Release();
    
    // adds a control flow between "Assembly" and "Stop" one.
    CATISPPFlowMgt *piAssemblyProcessOnFlow = NULL;
    rc = spAssemblyProcess -> QueryInterface(IID_CATISPPFlowMgt,
    		                         (void**) &piAssemblyProcessOnFlow);
    if (FAILED(rc) ) return 5;
    piAssemblyProcessOnFlow->AddControlFlow(spRootStopFlow);
    piAssemblyProcessOnFlow->Release();
    piAssemblyProcessOnFlow = NULL;

    The actual ordering of the control flow begins. First of all, we add a control flow between the "Start" activity and the first "CAADmiPlace" activity. This is done by getting a CATISPPFlowMgt handle on the "Start" activity and executing the AddControlFlow method on the first "CAADmiPlace" activity using the CATISPPAbstractActivity handle we defined when instantiating it from the activities library. We proceed in a similar manner to add the second "CAADmiPlace" activity following the first one, the "CAADmiAssembly" activity following the second "CAADmiPlace" activity and finally the "Stop" activity following the "CAADmiAssembly" activity. This creates a complete control flow of the activities we have defined in this process document. Next, we will see how we can add items and resources to these different activities in order to define a complete process.

[Top]

Setting Items on Different Activities

  1. Retrieve a CATIProduct handle
    // load product document.
    CATDocument *pItemDoc = NULL;
    rc = CATDocumentServices::Open(argv[2],pItemDoc);
    if ( FAILED(rc) || (NULL==pItemDoc)) return 6;
    cout << endl << "CAAPmiGenerProcess.m:	product document opened : " 
    	<< argv[2] << endl << flush;
    
    CATIDocRoots* piDocRootsOnDoc = NULL;
    rc = pItemDoc->QueryInterface(IID_CATIDocRoots,
    		              (void**) &piDocRootsOnDoc);
    CATListValCATBaseUnknown_var* pRootProducts = 
    		piDocRootsOnDoc->GiveDocRoots();
    CATIProduct_var spRootProduct = NULL_var;
    if (pRootProducts->Size())
    { 
       spRootProduct = (*pRootProducts)[1];
       delete pRootProducts;
       pRootProducts = NULL;
    }
    CATIProduct *piProductOnRoot = NULL;
    rc = spRootProduct->QueryInterface(IID_CATIProduct, 
    		                   (void**) &piProductOnRoot);
    if (FAILED(rc) ) return 5;

    First of all, we retrieve the items from the CATProduct document. This is done by loading the document whose pathname is defined in the second argument to this program using the Open static method of CATDocumentServices. Next, we must get a CATIProduct handle on the root product of the document because it will be needed later on, as you will see. The root product of the document is the first element in the CATListValCATBaseUnknown_var list returned from GiveDocRoots which is executed using a CATIDocRoots handle on the product document.

  2. Setting items on activities
    // get items in the product document
    // associate them to activity.
    CATListValCATBaseUnknown_var *ListItems = 
    	piProductOnRoot -> GetAllChildren();
    piProductOnRoot->Release();
    piProductOnRoot=NULL;
    
    CATIProduct_var spItem = NULL_var;
    CATUnicodeString itemName (" ");
    
    // first item associate to Place activity and to Assembly activity. 
    spItem = (*ListItems)[1];
    rc = spItem -> GetPrdInstanceName ( itemName ) ;
    
    CATISPPItemMgt *piAssemblyOnItem = NULL;
    spAssemblyProcess -> QueryInterface(IID_CATISPPItemMgt,
    		                    (void**) &piAssemblyOnItem);
    if (FAILED(rc) ) return 5;
    piAssemblyOnItem->AddItem(spItem);
    
    CATISPPItemMgt *piPlaceOnItem1 = NULL;
    spPlaceActivity1 -> QueryInterface(IID_CATISPPItemMgt,
    		                   (void**) &piPlaceOnItem1);
    if (FAILED(rc) ) return 5;
    piPlaceOnItem1->AddItem(spItem);
    piPlaceOnItem1->Release();
    piPlaceOnItem1=NULL;
    
    // second associate to Place activity and to Assembly activity. 
    spItem = (*ListItems)[2];
    rc = spItem -> GetPrdInstanceName ( itemName ) ;
    
    piAssemblyOnItem->AddItem(spItem);
    
    CATISPPItemMgt *piPlaceOnItem2 = NULL;
    spPlaceActivity2 -> QueryInterface(IID_CATISPPItemMgt,
    		                   (void**) &piPlaceOnItem2);
    piPlaceOnItem2->AddItem(spItem);
    piPlaceOnItem2->Release();
    piPlaceOnItem2 = NULL;
    
    piAssemblyOnItem->Release();
    piAssemblyOnItem = NULL;

    Using the CATIProduct handle previously retrieved, we can get a list of all of the children of the root product by executing GetAllChildren. Next, we want to associate the first item in the list, which is the "sheet", to the first "CAADmiPlace" activity as well as to the "CAADmiAssembly" activity. First of all, we get the name of the first item in the list using GetPrdInstanceName in order to print it out on the batch listing. Now, in order to actually add the item to the activity, we get a CATISPPItemMgt handle based on the CATISPPAbstractActivity handle of the "CAADmiAssembly" activity with which we can execute the AddItem method to add the "sheet" to the "CAADmiAssembly" activity. We do the same thing to add the "sheet" to the first "CAADmiPlace" activity. Then we proceed in exactly the same way for the second item in the list, the "screw", this time adding it to the "CAADmiAssembly" activity, as we did with the first item, but to the second "CAADmiPlace" activity.

[Top]

Setting a Resource on an Activity

  1. Retrieve CATIProduct handle
    // load product document.
    CATDocument* pResourceDoc = NULL;
    rc = CATDocumentServices::Open(argv[3],pResourceDoc);
    if ( FAILED(rc) || (NULL==pResourceDoc) ) return 7;
    
    CATIDocRoots* piDocRootsOnDoc2 = NULL;
    rc = pResourceDoc->QueryInterface(IID_CATIDocRoots,
    		                  (void**) &piDocRootsOnDoc2);
    if (FAILED(rc) ) return 5;
    CATListValCATBaseUnknown_var* pRoots = 
    	piDocRootsOnDoc2->GiveDocRoots();
    CATIProduct_var spRoot = NULL_var;
    if (pRoots->Size())
    { 
       spRoot = (*pRoots)[1];
       delete pRoots;
       pRoots = NULL;
    }
    CATIProduct *piProductOnRoot2 = NULL;
    rc = spRoot->QueryInterface(IID_CATIProduct,
    		            (void**) &piProductOnRoot2);
    if (FAILED(rc) ) return 5;

    In order to set a resource on an activity, we first need to retrieve the resource from the CATProduct document containing it. This is done by loading the document whose pathname is defined in the third argument to this program using the Open static method of CATDocumentServices. Next, we must get a CATIProduct handle on the root product of the document because it will be needed later on, as you will see. As we have seen in the previous section, the root product of the document is the first element in the CATListValCATBaseUnknown_var list returned from GiveDocRoots which is executed using a CATIDocRoots handle on the product document.

  2. Set a resource on an activity
    // get resources in the product document
    // associate them to activity.
    CATListValCATBaseUnknown_var *ListResources = 
    	piProductOnRoot2 -> GetAllChildren();
    
    piDocRootsOnDoc2->Release();
    piDocRootsOnDoc2=NULL;
    piProductOnRoot2->Release();
    piProductOnRoot2=NULL;
    
    CATIProduct_var spResource = NULL_var;
    CATUnicodeString resourceName (" ");
    
    spResource = (*ListResources)[1];
    rc = spResource -> GetPrdInstanceName ( resourceName ) ;
    
    CATISPPResourceManagement *piAssemblyOnResource = NULL;
    rc = spAssemblyProcess -> QueryInterface(IID_CATISPPResourceManagement, 
    		                         (void**) &piAssemblyOnResource);
    if (FAILED(rc) ) return 5;
    piAssemblyOnResource->AddResource(spResource);
    
    piAssemblyOnResource->Release();
    piAssemblyOnResource=NULL;

    Using the CATIProduct handle previously retrieved, we can get a list of all of the children of the root product by executing GetAllChildren. Next, we want to associate the first resource in the list, which is the "table", to the "CAADmiAssembly" activity. First of all, we get the name of the resource using GetPrdInstanceName in order to print it out on the batch listing. Now, in order to actually add the resource to the activity, we get a CATISPPResourceManagement handle based on the CATISPPAbstractActivity handle of the "CAADmiAssembly" activity with which we can execute the AddResource method to add the "table" to the "CAADmiAssembly" activity.

[Top]

Saving the Process Document

cout << endl << "CAAPpbGenerProcess.m: Now we can save the created and modified CATProcess in "
	<< argv[4] << endl << flush;
rc = CATDocumentServices::SaveAs(*pNewDoc, argv[4]);
if ( FAILED(rc) ) return 8;

// remove opened document
rc = CATDocumentServices::Remove (*pNewDoc);
if (!SUCCEEDED(rc)) return 9;

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

Now that our process is complete, we save the process document using the SaveAs static method of CATDocumentServices under the pathname passed as a fourth argument to this program. It is always a good habit to also remove the document from the session using the Remove static method of CATDocumentServices. And finally, the session must be deleted using the Delete_Session global function.

[Top]


In Short

In this article, you have seen how to:

[Top]


References

[1] Creating a Library of Activities
[2] Building and Launching a CAA V5 Use Case
[Top]

History

Version: 1 [Apr 2000] Document created
[Top]

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