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.