3D PLM PPR Hub Open Gateway

CATIA V5 - ENOVIA VPM V4 Interoperability

Interactive File Based Import

Implementing the CATIPDMUECreate Interface
Use Case

Abstract

This article discusses the CAAPbiUECreate use case which illustrates how to implement the CATIPDMUECreate user exit. The attributes of parts and documents created in CATIA V5 but stored in ENOVIA VPM V4 are provided through this interface.


What You Will Learn With This Use Case

This use case is an example of how to implement the CATIPDMUECreate user exit.

[Top]

The CAAPbiUECreate Use Case

CAAPbiUECreate  is a use case of the CAAPSNInteroperability.edu framework that illustrates the CATIA PDM interoperability features.

[Top]

What Does CAAPbiUECreate Do

The goal of CAAPbiUECreate  is to provide mandatory attributes of parts and documents when they are created in CATIA V5 but stored in ENOVIA VPM V4. The following methods are called for each parts and documents:

For a part:

For a document:

[Top]

How to Launch CAAPbiUECreate

To launch CAAPbiUECreate, please follow these steps:

  1. Change the default directory to InstallRoot/CAAPSNInteroperability.edu
  2. Set up the build time environment using mkGetPreq
  3. Build the CAAPbiUECreate.m module (see Building and Launching a CAA V5 Use Case)
  4. Modify the CNEXT/code/dictionary/CAAPSNInteroperability.edu.dic dictionary by removing the leading '#' of the following line:
    #CATUEPDMCreate CATIPDMUECreate libCAAPbiUECreate
  5. Set up your CATIA run-time environment using mkrtv
  6. Start ENOVIA VPM V4 and select the correct environment (VPMENV) by clicking on the button next to "Environment:".
  7. Start CATIA V5with mkrun and create a new part.
    Next connect to ENOVIA VPM V4 using the Connect/Disconnect to/from VPM button of the ENOVIA VPM toolbar .
  8. A database connection dialog box should appear.
    Select the same database as with ENOVIA VPM, fill in all necessary login information and click on the Connect button.
  9. Once the connection to ENOVIA VPM V4 is established, click on the Set PDM Properties button on the ENOVIA VPM toolbar.
  10. The following dialog box should appear. Select the Part1 document and VPM1 as the destination PDM
  11. Now save the Part1 document by selecting Save on the File menu. The following status window should be displayed
  12. Once the save is completed, you can bring up ENOVIA VPM V4 to verify that your Part1 document has been sent from CATIA V5 with the mandatory attributes as defined in the code. First select the VPMENV by clicking on the button next to "Environment:". This the default in the code.
  13. Next make the query "Start with" CAAPart1. You should then see the attributes as defined by the sample code

[Top]

Where to Find the CAAPbiUECreate Code

CAAPbiUECreate code is located in the CAAPbiUECreate.m use case module of the CAAPSNInteroperability.edu framework:

InstallRoot/CAACATPBMBaseInterfaces.edu/CAAPbiUECreate.m

where InstallRoot is the root directory of your CAA V5 installation. There are two source files named CAAPbiUECreate.cpp and CAAPbiAttributes.cpp

[Top]

Source Code Walk Through

  1. CAAPbiAttributes.cpp: supporting class
  2. CAAPbiUECreate.cpp: implementation of the CATIPDMUECreate interface

[Top]

CAAPbiAttributes.cpp

The purpose of this class is to manipulate the output attributes list. It simplifies the code of the CAAPbiUECreate.cpp.

The constructor stores references to the output arguments (_names, _types, _values and _count) and the maximum attributes count (_maxCount)

CAAPbiAttributes::CAAPbiAttributes(CATListOfCATUnicodeString& inames,
                                   CATListOfCATUnicodeString& itypes,
                                   void**& ivalues,
                                   int& icount,
                                   int imaxCount) :
        _names(inames), // attribute names
        _types(itypes), // attribute types
        _values(ivalues), // attribute values
        _count(icount), // current count
        _maxCount(imaxCount) // maximum count
{
        // disable adding new attribute until AllocateValues is called
        _count = _maxCount;
}

 

The AllocateValues method allocates an array of pointers. Each array position will hold a pointer to an attribute value.

HRESULT CAAPbiAttributes::AllocateValues()
{
        if (NULL == _values) {
                _values = new void *[_maxCount];
                if (NULL == _values)
                        return E_FAIL;
                else
                        for (int i = 0; i < _maxCount; i++)
                                _values[i] = NULL;

        }
        _count = 0;
        return S_OK;
}

 

The AddAttribute method updates the output parameters with a new attribute.

void CAAPbiAttributes::AddAttribute(const char *iAttrName,
                                    const char *iAttrType,
                                    const void *iAttrValue)
{
        if (_count >= _maxCount)
                return;
        _names.Append(iAttrName);
        _types.Append(iAttrType);
        _values[_count] = (void*) iAttrValue;
        _count++;
}

[Top]

CAAPbiUECreate.cpp

  1. Implementation linking
  2. CAAPbiUECreate Constructur/destructor
  3. Methods for a memory based part GetProductEnvironment, GetProductAttributesValue
  4. Methods for a memory based document: GetDocumentEnvironment, GetDocumentAttributesValue
  5. Methods for file based part and document: GetDocumentEnvironment, GetDocumentAttributesValue and GetProductAttributesValue
  6. Supporting methods (not required by the interface): GetEnvironment, GetRepository, GetDocNameAndExtension and CopyUStringToChar

The implementation is linked to the interface with this code.

#include "TIE_CATIPDMUECreate.h"
TIE_CATIPDMUECreate(CAAPbiUECreate);

CATImplementClass(CAAPbiUECreate,
                  DataExtension,
                  CATBaseUnknown,
                  CATUEPDMCreate);

In addition to the code, a dictionary with the following line is required:.

CATUEPDMCreate CATIPDMUECreate libCAAPbiUECreate

The constructor initializes the cache storage for the environment name and database table name.

CAAPbiUECreate::CAAPbiUECreate():
        CATBaseUnknown()
{
        _environment = NULL;
        _repository = NULL;
}

The destructor frees the cache storage that was allocated

CCAAPbiUECreate::~CAAPbiUECreate()
{
        if (NULL != _environment) {
                free((void *) _environment);
               _environment = NULL;
        }
        if (NULL != _repository) {
               free((void *) _repository);
               _repository = NULL;
        }
}

GetProductEnvironment for a memory base part returns the part environment name (see GetEnvironment)

HRESULT CAAPbiUECreate::GetProductEnvironment (const CATBaseUnknown* iObj,
                                               CATUnicodeString& oEnv,
                                               CATUnicodeString& oType)
{
        oEnv = GetEnvironment();
        return S_OK;
}

GetProductAttributes for a memory based part returns three attributes:

S_PART_NUMBER and S_TYPE values are obtained differently depending on whether the part is a CATDocument or not.

HRESULT CAAPbiUECreate::GetProductAttributesValue (const CATBaseUnknown* iObj,
                                                   const CATUnicodeString& iType,
                                                   int& oNbAttr,
                                                   CATListOfCATUnicodeString& oAttrName,
                                                   CATListOfCATUnicodeString& oAttrType,
                                                   void**& oAttrValues,
                                                   CATBoolean& oCreateOrUpdate)
{
        if (NULL == iObj)
                return E_FAIL;

        oCreateOrUpdate = TRUE;
        CAAPbiAttributes attrs(oAttrName, oAttrType, oAttrValues, oNbAttr, 3);
        HRESULT ret = attrs.AllocateValues();
        if (FAILED(ret))
                return ret;

        if (iObj->IsAKindOf("CATDocument")) {

                //
                // S_PART_NUMBER : "Part"+document name
                // S_CHG_NUM : 0
                // S_TYPE : document extension
                //
                CATUnicodeString docName;
                CATUnicodeString docExt;
                GetDocNameAndExtension(*(CATDocument*) iObj, docName, docExt);

                CATUnicodeString partNum("Part");
                partNum += docName;
                const char *cPartNum = CopyUStringToChar(partNum, 32);
                if (NULL == cPartNum)
                        return E_FAIL;
                attrs.AddAttribute("S_PART_NUMBER", "String", cPartNum);

                CATUnicodeString chgNum("0");
                const char *cNum = CopyUStringToChar(chgNum, 0);
                attrs.AddAttribute("S_CHG_NUM", "Integer", num);

                const char *cPartType = CopyUStringToChar(docExt, 15);
                if (NULL == cPartType)
                        return E_FAIL;
                attrs.AddAttribute("S_TYPE", "String", cPartType);

        } else {

                //
                // S_PART_NUMBER : part number
                // S_CHG_NUM : 0
                // S_TYPE : part type
                //
                CATUnicodeString partNum;
                CATIProduct_var prod((CATBaseUnknown*)iObj);
                if (NULL_var != prod) {
                        partNum = prod->GetPartNumber(); 
                } else {
	                CATISpecObject_var spec((CATBaseUnknown*)iObj);
                        if (NULL_var != spec) {
                                partNum = spec->GetDisplayName();
                        }
                }
                const char *cPartNum = CopyUStringToChar(partNum, 32);
                if (NULL == cPartNum)
                        return E_FAIL;
                attrs.AddAttribute("S_PART_NUMBER", "String", cPartNum);
                
                CATUnicodeString chgNum("0");
                const char *cNum = CopyUStringToChar(chgNum, 0);
                attrs.AddAttribute("S_CHG_NUM", "Integer", num);

                CATUnicodeString partType;
                CATISpecObject_var spec((CATBaseUnknown*)iObj);
                if (NULL_var != spec) {
                        CATUnicodeString specType= spec->GetType();
                        specType = specType.Strip();
                        if (specType == "ASMPRODUCT") 
                              partType = "PART";
                        else if (specType == "DATABASEPRODUCT")
                              partType = "PART";
                        else
                              partType = specType;
                }

                const char *cPartType = CopyUStringToChar(partType, 15);
                if (NULL == cPartType)
                        return E_FAIL;
                attrs.AddAttribute("S_TYPE", "String", cPartType);

        }

        return S_OK;
}

GetDocumentEnvironment for a memory document returns the environment name (see GetEnvironment) and database table name. The database table name depends on the document type. It is "CATIA_MODEL" for "model"or "CDMAmodel". Otherwise it is "DOCUMENT".

HRESULT CAAPbiUECreate::GetDocumentEnvironment (const CATDocument* iDoc,
                                                CATUnicodeString& oEnv,
                                                CATUnicodeString& oTable)
{
        oEnv = GetEnvironment();

        const char *docNomadType = (NULL != iDoc ? iDoc->IsA() : NULL);

        oTable = (NULL != docNomadType && 
                  strcmp(docNomadType, "model") == 0 || 
                  strcmp(docNomadType, "CDMAmodel") == 0 ?
                  "CATIA_MODEL" :
                  "DOCUMENT");

        return S_OK;
}

GetDocumentAttributes for a memory based document returns five attributes:

HRESULT CAAPbiUECreate::GetDocumentAttributesValue (const CATDocument* iDoc,
                                                    int& oNbAttr,
                                                    CATListOfCATUnicodeString& oAttrName,
                                                    CATListOfCATUnicodeString& oAttrType,
                                                    void**& oAttrValues,
                                                    CATBoolean& oCreateOrUpdate)
{
        if (NULL == iDoc)
                return E_FAIL;

        oCreateOrUpdate=TRUE;
        CAAPbiAttributes attrs(oAttrName, oAttrType, oAttrValues, oNbAttr, 5); 
        HRESULT ret = attrs.AllocateValues();
        if (FAILED(ret))
                return ret;

        CATUnicodeString docName;
        CATUnicodeString docExt;
        GetDocNameAndExtension(*iDoc, docName, docExt);

        docName = "CAA" + docName;
        const char *cDocName = CopyUStringToChar(docName, 12);
        if (NULL == cDocName)
                return E_FAIL;
        attrs.AddAttribute("S_NAME", "String", cDocName);

        const char *cDocType = CopyUStringToChar(docExt, 8);
        if (NULL == cDocType)
                return E_FAIL;
        attrs.AddAttribute("S_TYPE_REP", "String", cDocType);

        CATUnicodeString userName("CAA");
        const char *cUserName = CopyUStringToChar(userName, 5);
        if (NULL == cUserName)
                return E_FAIL;
        attrs.AddAttribute("S_FORMAT", "String", cUserName);

        CATUnicodeString repository(GetRepository());
        const char *cRepository = CopyUStringToChar(repository, 0);
        if (NULL == cRepository)
                return E_FAIL;
        attrs.AddAttribute("C_LAST_REPOSITORY", "String", cRepository);

        CATUnicodeString notes("Created from CAA");
        const char *cNotes = CopyUStringToChar(notes, 0);
        if (NULL == cNotes)
                return E_FAIL;
        attrs.AddAttribute("NOTES", "String", cNotes);

        return S_OK;
}

Methods for file based parts and documents are not implemented: they all return E_NOTIMPL:

GetDocumentEnvironment for file based document:

HRESULT CAAPbiUECreate::GetDocumentEnvironment(const char* Filepath,
                                               CATUnicodeString& oEnv,
                                               CATUnicodeString& oTable)
{
        return E_NOTIMPL;
}

GetDocumentAttribusteValue for file based document

HRESULT CAAPbiUECreate::GetDocumentAttributesValue(const char* iFilepath,
                                                   int& oNbAttr,
                                                   CATListOfCATUnicodeString& oAttrName,
                                                   CATListOfCATUnicodeString& oAttrType,
                                                   void**& oAttrValues)
{
        return E_NOTIMPL;
}

GetProductAttributesValue for file base part:

HHRESULT CAAPbiUECreate::GetProductAttributesValue(const char* iFilepath, 
                                                   int& oNbAttr, 
                                                   CATListOfCATUnicodeString& oAttrName, 
                                                   CATListOfCATUnicodeString& oAttrType, 
                                                   void**& oAttrValues)
{
        return E_NOTIMPL;
}

GetEnvironment returns the value of the environment variable CV5_VPM_ENV or "VPMENV" if it is not defined. This result is cached to avoid computation during subsequent calls.

const char *CAAPbiUECreate::GetEnvironment()
{
        static const char *env = NULL;

        if (NULL == env) {
                if (CATGetEnvValue("CV5_VPM_ENV", (char **) &_environment) == 
                    CATLibSuccess) {
                        env = _environment;
                } else {
                        env = "VPMENV";
                }
        }
        return env;
}

Similar to GetEnvironment, GetRepository returns the value of the environment variable CV5_VPM_REPOSITORY or "DBLFAIX.BIN PATH $HOME/db/" if it is undefined. The result is also cached.

const char *CAAPbiUECreate::GetRepository()
{
        static const char *rep = NULL;

        if (NULL == rep) {
                if (CATGetEnvValue("CV5_VPM_REPOSITORY", (char **) &_repository)
                    == CATLibSuccess) {
                        rep = _repository;
                } else {
                        rep = "DBLFAIX.BIN PATH $HOME/db/";
                }
        }
        return rep;
}

GetDocNameAndExtension returns the storage path of a memory based CATDocument: split into two parts: the file name and the file extension.

void CAAPbiUECreate::GetDocNameAndExtension (const CATDocument& iDoc,
                                             CATUnicodeString& ioDocName,
                                             CATUnicodeString& ioDocExt)
{
        CATUnicodeString docStorageName = iDoc.StorageName();
        char docDir[CATMaxPathSize];
        char docFileName[CATMaxPathSize];
        CATSplitPath(docStorageName.ConvertToChar(), docDir, docFileName);
        char *dotpos = strrchr(docFileName, '.');
        if (NULL != dotpos) {
                *dotpos = 0;
                ioDocName = docFileName;
                dotpos++;
                ioDocExt = dotpos;
        } else {
                ioDocName = docFileName;
                ioDocExt = "";
        }
}

CopyUStringToChar converts a CATUnicodeString to an ASCII string of a given size. The resulting string is truncated or padded with spaces as necessary.

const char *CAAPbiUECreate::CopyUStringToChar (CATUnicodeString& iStr, 
                                               int iSize)
{
        int len;

        if (0 == iSize) {
                // length is null, copy whole string
                len = iStr.GetLengthInChar();
        } else {
                // only copy up to specified length
                // padding with spaces if necessary
                iStr.Resize(iSize);
                len = iSize;
        }
        char *ptr = new char [len + 1];
        if (NULL == ptr)
                return NULL;
        strcpy(ptr, iStr.ConvertToChar());
        return ptr;
}

In Short

This use case has demonstrated how to implement the CATIPDMUECreate interface.

[Top]


History

Version: 1.2 [Oct 2005] Document revised
Version: 1.1 [Sep 2003] Document revised
Version: 1 [Jul 2003] Document created
[Top]

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