ENOVIA V5 VPM

CATIA V5 ENOVIA V5 VPM Integration

API's to automate access to ENOVIA V5 VPM data from CATIA V5

Automatically load, modify and save EV5 VPM data from within CV5
Use Case

Abstract

This document is related to the use case CAAEnoviaV5SaveCmd. It describes how to automatically:

  • load data from ENOVIA V5 VPM,
  • insert file-based data into loaded data,
  • save new data with a choosen vault mode in ENOVIA V5 VPM.
This, using CAA APIs and triggering the "Save in ENOVIA V5 VPM" from within one CATIA V5 command.


What You Will Learn With This Use Case

This use case is intended to help you:

[Top]


The "CAAEnoviaV5SaveCmd" Use Case

CAAEnoviaV5SaveCmd is a use case of the CAAProductStructureE5i.edu framework that illustrates how ENOVIA V5 VPM data can be automatically manipulated from within a CATIA V5 command.

[Top]

What Does the "CAAEnoviaV5SaveCmd" Use Case Do

The CAAEnoviaV5SaveCmd use case aims at a presentation of how, from within in a CATIA V5 command, to automatically perform:

From an implementation view, this use case also deals with the following points:

  1. Using the RunObjectService() API (CATPDMCSServices.h): Retrieve the CATIPLMIdentificator-s of three EV5 VPM (assembly) Item-Instances from their name. [2]
  2. Using the LoadFromPDM() API (CATPDMInteropServices.h): Load the three EV5 VPM Item-Instances (in context) given by their CATIPLMIdentificator-s.
  3. Using the Open() API (CATDocumentServices.h): Open a file-based CATProduct document.
  4. Using the GiveDocRoots() & AddProduct() methods (CATIDocRoots.h & CATIProduct.h): Insert the file-based CATProduct under one of the loaded EV5 VPM assembly Item-Instances.
  5. Using the SetEV5PersistencyMode() API (CATPDMInteropServices.h): Define a vault-mode for the file-based CATProduct document and its children.
  6. Using the GetEditor() & CreateDefaultWindow() methods (CATIEditor.h & CATFrmEditor.h): Open the whole assembly (loaded from EV5 VPM data + inserted file-based data) in an editor.
  7. Using the CATAfrStartCommand() API (CATAfrCommandHeaderServices.h): Trigger the "Save in ENOVIA V5 VPM" command.

[Top]

How to Launch the "CAAEnoviaV5SaveCmd" Use Case

Before to launch the CAAEnoviaV5SaveCmd use case, you will need to set up the build-time environment, compile CAAEnoviaV5SaveCmd (client side) and CAAVpmPsEnovGetData (server side) along with their prerequisites, set up the run-time environment (on both client and server sides) and then execute the mandatory prerequisite steps in the following way:

  1. Run ENOVIA V5 VPM
  2. Create and Save a Product Root Class
  3. Run CATIA V5 and connect it to ENOVIA V5 VPM
  4. Send the created Product Root Class to CATIA V5
  5. Insert under the loaded PRC the file-based documents "_AutoAccessAPI_BranchOne.CATProduct" & "AutoAccessAPI_BranchTwo.CATProduct" (data located in: InstallRootDirectory\CAAProductStructureEV5.tst\FunctionTests\InputData\CAACV5AccessEV5DataAPI.rec\DATA\StartingPS\)
  6. Set the "Structure Exposed" as Storage Mode and the "ENOVIA5" as PDM destination on each inserted file-based CATDocument
  7. Save the whole assembly in ENOVIA V5 VPM and close the CATIA V5 editor.

It is mandatory to have the following assembly saved in ENOVIA V5 VPM before to go through the use case.


The use case is launched by clicking the icon below: (process: View > Toolbars> CAACV5EV5Integration, if the icon is not visible)


[Top]

Where to Find the "CAAEnoviaV5SaveCmd" Use Case Code

This use case is made of two classes:

Windows ClientInstallRootDirectory\CAAProductStructureE5i.edu\CAAEnoviaV5SaveCmd.m\
  ServerInstallRootDirectory\CAAVPMInterfaces.edu\CAAVpiServerCode.m\
Unix ClientInstallRootDirectory/CAAProductStructureE5i.edu/CAAEnoviaV5SaveCmd.m/
  ServerInstallRootDirectory/CAAVPMInterfaces.edu/CAAVpiServerCode.m/

Where ClientInstallRootDirectory is the directory of the CAA CD-ROM client side installation and ServerInstallRootDirectory the directory of the CAA CD-ROM server side installation.

[Top]


Step-by-Step

The explanations of the CAAEnoviaV5SaveCmd implementation goes through 5 main steps:

  1. Retrieve the CATIPLMIdentificator of an EV5 VPM Item-Instance knowing its "V_instance_ID"
  2. Load in context an EV5 VPM Item-Instance from its CATIPLMIdentificator
  3. Insert a file-based CATProduct under a loaded EV5 VPM assembly Item-Instance
  4. Set a Storage/Vault mode (and the ENOVIA5 PDM destination) on a file-based CATProduct and its (file-based) children
  5. Open a loaded assembly in a CV5 editor
  6. Trigger the Save in EV5 VPM of the current CV5 editor

[Top]

Retrieve the CATIPLMIdentificator of an EV5 VPM Item-Instance knowing its "V_instance_ID"

To retrieve a CATIPLMIdentificator of an EV5 VPM Item-Instance from its "V_Instance_Id", the API RunObjectService is used [2]. Giving proper arguments and a late-type this API triggers on server-side the execution of the corresponding RunObjectServiceCode (ENOVIObjectServiceCode) User-Exit implementation. [3]

The code below shows how to retrieve 3 CATIPLMIdentificators corresponding to 3 Item-Instances.

The 3 "V_Instance_Id" are given through the input string argument (ipString) of the RunObjectService API. The type "Instance" is also precised through this same input argument: the server User-Exit performs a database query to found an EV5 VPM object from its "V_Id" attribute but also from its type. (code can be found at InstallServerDirectory\CAAVPMInterfaces.edu\CAAVpiServerCode.m\src\CAAVpmPsEnovGetData.cpp)

The RunObjectServiceCode user-exit implementation latetype is given through the argument iServName

The CATIPLMIdentificator-s are returned trough the output list plmIdentificatorList. The other parameters of the API are not used here.

...

//*Step1:  Retrieve  the  PLM-Identificators  of  3  EV5  Assembly  Item  Instances  that  belong  to  the  same  PRC
//                using  CAA  API  RunObjectService().
//                (The  whole  product  structure  is  supposed  to  have  already  been  created  on  EV5  database)

//  ***  RunObjectService()  parameters

//Ouput  param:  List  supposed  to  be  filled  with  the  3  II  CATIPLMIdentificators
//Input  param:  Useless  in  this  Use-Case
CATLISTV(CATIPLMIdentificator_var)    plmIdentificatorList,  notUsedInputList;  

//Input  param:  Late-Type  of  the  RunObjectServiceCode()  Implementation                                                                                  
CATString      iServName          =  "ENOVIA5_AccessEV5Data";            

//Input  param:  String  constitute  with  the  V_ID  of  the  3  EV5  Item  Instances
const  char  *ipString            =  "Instance;AutoAccessAPI_BranchOneASMII.1;AutoAccessAPI_BranchTwoASMII.1;AutoAccessAPI_BranchThreeASMII.1";

//Ouput  param:  Useless  in  this  Use-Case
char              *notUsedString  =  NULL;

//  ***  RunObjectService()  executing
rc  =  CATPDMCSServices::RunObjectService(iServName,  notUsedInputList,  ipString,  plmIdentificatorList,  ¬UsedString);

//  ***  RunObjectService()  return  test
int  nbID  =  0;
if  (SUCCEEDED(rc))
{
    //  Trace  the  number  of  the  built  PLM-Identificators
    nbID  =  plmIdentificatorList.Size();
    cout  <<  "OnOKSelected  -  The  list  returned  by  RunObjectService()  contains  "  <<  nbID  <<  "  PLMId(s)"  <<  endl;
}
else  cout  <<  "OnOKSelected  -  **Error:  RunObjectService()  has  failed!"  <<  endl;    
...      

[Top]

Load in context an EV5 VPM Item-Instance from its CATIPLMIdentificator

This step intends to give details about the way the API LoadFromPDM() is used to load the three EV5 VPM assembly Item-Instances whose CATIPLMIdentificator-s have been previously retrieved. [Step 1]

The only thing to managed is to give in input of the API a list CATIPLMIdentificator-s, which is done in the code below through the argument plmIdentificatorList of the previous step. [Step 1] The API returns (pOpenedDocList) the list of the CATDocument-s in the CATIA V5 session that have been loaded.

...
//*Step2:  Load  in  CV5  session  the  3  EV5  Item  Instances  whose  PLM-Identificators  have  just  been  retrieved
//                using  CAA  API  LoadFromPDM().
if  (nbID  >  0)
{
    //  ***  LoadFromPDM()  parameters
    
    //  Ouput  param:  List  that  will  be  filled  with  the  CATDocuments  opened  in  CV5  session  resulting  from  Load  of  the  3  EV5  Item  Instances
    CATLISTP(CATDocument)*  pOpenedDocsList  =  NULL;
    
    //  ***  LoadFromPDM()  executing
    rc  =  LoadFromPDM(plmIdentificatorList,  pOpenedDocsList);
...
        

The "plmIdentificatorList" list contains three CATIPLMIdentificator-s standing for the three assembly terminal EV5 VPM Item-Instances of the prerequisite assembly previously created and saved into the EV5 VPM database. [How to Launch CAAEnoviaV5SaveCmd] The API LoadFromPDM() loads in context these three Item-Instances in CV5; consequently, at this step of the use case, we have got in session the complete prerequisite assembly. (...loaded, but still not open in a CV5 editor!)

It is important to notice that for each load performed, the API locks the root document of the loaded data (unless the root is already in session when the API is called); this to hold the data in session. This means, the root document will have to be unlocked before unloading data from session. As seen above, the three loaded Item-Instances belongs to the same assembly; so there will be one document to unlock: the root "CATProduct" document of this assembly. We will see later how this can be managed. [Step5]

[Top]

Insert a file-based CATProduct under a loaded EV5 VPM assembly Item-Instance

The first thing to do in this step is to catch the two documents concerned by the insert operation.

What we want is to insert the file-based CATProduct document "AutoAccessAPI_fbSubAsm.CATProduct" under the CV5 Product corresponding to the first EV5 VPM assembly Item-Instance loaded with the LoadFromPDM() API [Step 2]; i.e. under the node named "AutoAccessAPI_BranchOneASMII" in the prerequisite assembly [How to Launch CAAEnoviaV5SaveCmd]

The code below calls the API Open() to load the file-based CATProduct document into the CV5 session, whereas the document carrying the CV5 product "AutoAccessAPI_BranchOneASMII" is picked from the list of the loaded document returned by the API LoadFromPDM() [Step 2]

...

//*Step3:  Insert  a  file  based  Product  under  the  loaded  instance  BranchOneASMII.1
//                Set  VolatileExposed  Vault  Mode  on  the  Product  and  its  children
//                using  CAA  API  SetEV5PersistencyMode().
if  (SUCCEEDED(rc))
{
    //  Get  (from  the  loaded  document  list)  the  doc  hosting  the  Reference  of  Instance  BranchOneASMII.1
    CATDocument  *pBranchOneLeafDoc  =  (*pOpenedDocsList)[3];
    
    if  (SUCCEEDED(rc))
    {
        //  Open  the  file  based  document  in  session
        CATUnicodeString  docStorageName  =  "CAAProductStructureEV5.tst\\FunctionTests\\InputData\\CAACV5AccessEV5DataAPI.rec\\DATA\\VolatileExposed\\AutoAccessAPI_fbSubAsm.CATProduct";
        CATDocument  *pfileBasedDoc  =  NULL;
        rc  =  CATDocumentServices::Open(docStorageName,  pfileBasedDoc);

        if  (SUCCEEDED(rc)  &&  pfileBasedDoc)
        {
            //  Insert  file  based  document  under  Instance  document
            CATIProduct_var  hNewInst;
            rc  =  InsertDocument(pBranchOneLeafDoc,  pfileBasedDoc,  hNewInst);
            ...

Then the insert operation can be proceed; catching the Root CATIA V5 Root Product Reference of each document and aggregating the first one (the file-based document reference) under the second one (the loaded-instance document reference).

To catch the Root Product Reference of a CATDocument, the GiveDocRoots() method is used.

...
HRESULT  CAAEnoviaV5SaveCmd::GetDocumentRootProdRef(CATDocument  *ipDoc,  CATIProduct_var  &ohRefProd)
{
    cout  <<  "-->CAAEnoviaV5SaveCmd::GetDocumentRootProdRef()"  <<  endl;
    HRESULT  rc  =  S_OK;

    if  (ipDoc)
    {
        CATIDocRoots_var  hLeafDoc  =  ipDoc;

        if  (!!hLeafDoc)
        {
            //  Catch  the  Root  Product  Reference  of  the  CATDocument
            CATListValCATBaseUnknown_var  *  pRootProductsList  =  hLeafDoc->GiveDocRoots();

            if  (pRootProductsList)
            {
                if  (pRootProductsList->Size()  >  0)    //  The  returned  list  is  supposed  to  contains  only  one  element
                {
                    ohRefProd  =  (*pRootProductsList)[1];
...

To instanciate a Root Product Reference under anoher one, the AddProduct() method is used...

...
//  Get  the  Root  Reference  of  the  father  Document
CATIProduct_var  hFatherDocRootProdRef;
rc  =  GetDocumentRootProdRef(ipDocFather,  hFatherDocRootProdRef);

if  (SUCCEEDED(rc)  &&  !!hFatherDocRootProdRef)
{
    //  Get  the  Root  Reference  of  the  file  son  Document
    CATIProduct_var    hSonDocRootProdRef;
    rc  =  GetDocumentRootProdRef(ipDocSon,  hSonDocRootProdRef);

    if  (SUCCEEDED(rc)  &&  !!hSonDocRootProdRef)
    {
        //  Insert  son  Reference  Product  under  father  Reference  Product
        ohInstProd  =  hFatherDocRootProdRef->AddProduct(hSonDocRootProdRef);
...

This step is run twice to insert a second file-based document: "AutoAccessAPI_fbSubAsmBB.CATProduct", under the node "AutoAccessAPI_BranchTwoASMII" of the prerequisite assembly. [How to Launch CAAEnoviaV5SaveCmd]

[Top]

Set a Storage/Vault mode (and the ENOVIA5 PDM destination) on a file-based CATProduct and its (file-based) children

The API SetEV5PersistencyMode() is used in this use case to set a choosen vault mode and the PDM destination "ENOVIA5" on the two file-based documents inserted [Previous step] into the assembly loaded into the CV5 session. [Step 2]

The below code sample set the PermanentBlackBox vault mode (and the PDM destination "ENOVIA5") on a "pfileBasedDoc" document. The "doPropagation" parameter asks for propagation of the vault mode and the PDM destination on the document children of "pfileBasedDoc".

...
//  SetEV5PersistencyMode()  parameters

//  Input  param:  The  Vault  Mode
CATIPDMPersistency::VaultMode  vaultMode  =  CATIPDMPersistency::PermanentBlackBox;

//  Input  param:  Notification  flag  used  to  launch  propagation  of  the  Vault  Mode  on  children  documents
CATBoolean  doPropagation  =  TRUE;

//  SetEV5PersistencyMode()  executing
rc  =  SetEV5PersistencyMode(pfileBasedDoc,  vaultMode,  doPropagation);
...

This code sample is run to set (with children propagation) the "VolatileExposed" vault mode and the "PermanentBlackBox" vault mode respectively on "AutoAccessAPI_fbSubAsm.CATProduct" and "AutoAccessAPI_fbSubAsmBB.CATProduct".

[Top]

Open a loaded assembly in a CV5 editor

Before triggering the "Save in ENOVIA V5 VPM" interactiv command on an assembly, it has to be open in an editor (mandatory). The first thing to do is to catch the assembly root document.

...
//*Step5:  Edit  the  whole  assembly.  (loaded  documents  +  file  based  inserted  documents)
//                Release  the  lock  put  on  the  root  document  during  the  load  API  execution
//                Save  the  whole  modified  assembly  directly  calling  the  EV5Save  command.
if  (SUCCEEDED(rc))
{
    //  Edit  the  root  Document  of  the  whole  assembly
    //  (i.e.  the  first  document  of  the  returned  load-list  in  this  specific  scenario)
    CATDocument  *pDocToBeEdited  =  (*pOpenedDocsList)[1];
    if  (pDocToBeEdited)
    {
        rc  =  EditDocument(pDocToBeEdited);
...

Then, the steps to follow are:

HRESULT  CAAEnoviaV5SaveCmd::EditDocument(CATDocument  *pToBeEditedDoc)
{
    cout  <<  "-->CAAEnoviaV5SaveCmd::EditDocument()"  <<  endl;
    HRESULT  rc  =  S_OK;

    if  (pToBeEditedDoc)
    {
        int  nbWind  =  0;

        if  (CATFrmLayout::GetCurrentLayout())  
        {
            //  Create  Editor
            CATFrmEditor*  pEditor  =  NULL;
            CATIEditor_var  hPrdEditor(pToBeEditedDoc);
            if  (!!hPrdEditor)  pEditor  =  hPrdEditor->GetEditor();

            if  (pEditor)    //  Editor  should  now  exists
            {
                //  Intialize  the  editor
                pEditor->Init();
                ...
            
                ...
                //  Get  the  nb  of  window  attached  to  the  editor
                nbWind  =  pEditor->GetWindowCount();

                if(nbWind  ==  0)  //  No  window
                {
                    //  Create  Window
                    CATFrmWindow  *pWind  =  pEditor->CreateDefaultWindow();
                    nbWind++;
                }

                //  Get  Document  Display  Name
                CATUnicodeString  toBeEditedDocDisplayName;
                CATIDocEnvironment  *pEV5DocEnv  =  CATDocEnvManager::GetEnvironment("ENOVIA5");

                if  (pEV5DocEnv)
                {
                    //  Get  Document  Id
                    CATIDocId  *pToBeEditedDocId  =  NULL;
                    rc  =  pToBeEditedDoc->GetDocId(&pToBeEditedDocId);

                    if  (SUCCEEDED(rc)  &&  pToBeEditedDocId)
                    {
                        //  Get  Display  Name
                        rc  =  pEV5DocEnv->GetDocDisplayName(pToBeEditedDocId,  toBeEditedDocDisplayName);
                        pToBeEditedDocId->Release();
                    }
                    pEV5DocEnv->Release();
                }

                //  Set  the  window  title
                pEditor->SetWindowName(toBeEditedDocDisplayName);
            }
            ...
    cout  <<  "<--CAAEnoviaV5SaveCmd::EditDocument(),  RC  =  "  <<  rc  <<  endl;
    return  rc;
}
            

At this step of the use case, the following editor should appear in CATIA V5:


Now that it is opened, the assembly is hold in session by the editor. This means the lock performed - by the LoadFromPDM() API [Step 2] - on the root document of the assembly can be released. This can be done calling the ReleaseForLock() method of the CATDocument interface.

...
rc  =  EditDocument(pDocToBeEdited);

if  (FAILED(rc))  cout  <<  "OnOKSelected  -  **Error  :  Unable  to  edit  the  assembly!"  <<  endl;

//  Release  the  root  Document  (now  that  it's  hold  by  the  editor)
pDocToBeEdited->ReleaseForLock();
...

[Top]

Trigger the Save in EV5 VPM of the current CV5 editor

Once the assembly is opened in an editor, the "Save in ENOVIA V5 VPM" command can be triggered through the following instructions...
...
//  Launch  the  EV5  Save  interacive  command
CATCommand  *  pEV5SaveCmd  =  NULL;
rc  =  CATAfrStartCommand("EnoviaV5Save",  pEV5SaveCmd);

//  At  this  point  the  CAAEnoviaV5SaveCmd  command  is  interrupted  by  the  EnoviaV5Save  exclusive  command!
//  i.e.  After  going  out  of  this  function,  the  Cancel  method  will  be  executed  and  our  CAAEnoviaV5SaveCmd  will  end!
...      

[Top]


In Short

This use case intend to give an example of how can be used the two new API-s LoadFromPDM() and SetEV5PersistencyMode(). The both API-s are respectively alternatives for the interactive "Send To CATIA" command of ENOVIA V5 VPM and the interactive "Set PDM Properties" command of CATIA V5. It is in there also explained how the "Save In ENOVIA V5 VPM" interactive command of CATIA V5 can be triggered from a single code instruction.

The above exposed use case, is implemented to load (in context of a PRC) 3 EV5 assembly Item-Instances in CATIA V5, to insert under them two file-based CATDocument-s, and to save the whole modified assembly from within a CATIA V5 editor, in the ENOVIA V5 VPM database.

[Top]


References

[1] Building and Launching a CAA V5 Use Case
[2] Manipulating an ENOVIA Item Instance from within the ENOVIA V5 VPM Navigator environment (Client Use case)
[3] Implementing the ENOVIObjectServiceCode User-Exit (Server Use case) in Server documentation in ServerInstallRootDirectory/CAAVPMInterfacesDoc.edu/CAAVpiUseCases.doc/src/CAAVpmPsEnovGetII.htm
[Top]

History

Version: 1 [Janaury 2008] Document created
[Top]

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