Mechanical Modeler

Instantiating Interactively a User Feature Reference

Using CATIUdfFactory, CATIUdfInstantiate
Use Case

Abstract

This article shows how to instantiate a User Feature in an interactive command.


What You Will Learn With This Use Case

This use case describes how to instantiate a User Feature named "CAAUserFeatureSample" in an interactive command. Two other use cases are related to this one. The first, "Creating a User Feature Reference" use case [1] shows how to create this User Feature reference. The second, "Instantiating an User Feature Reference" use case [2] details how to instantiate it by a batch.

Before getting to the use case itself, it is important to already be familiar with the basic notions of User Features. See the referenced article [3] for a detailed overview.

[Top]

The CAAMcaUdfAddin Use Case

CAAMcaUdfAddin is a use case of the CAAMechanicalCommands.edu framework that illustrates MechanicalCommands framework capabilities.

[Top]

What Does CAAMcaUdfAddin Do

A new interactive command, called "Create a CAAUdfLoft User Feature", is created and included in an addin of the "Generative Shape Design" workbench which contains one toolbar, the "User Feature Creation" Toolbar:

Fig.1: The "Create a CAAUdfLoft user feature" Command in the "User Feature Creation Toolbar

This command creates an instance of the "CAAUserFeatureSample" User Feature reference in the current Part document [Fig. 2].

Fig.2: The "CAAUserFeatureSample" User Feature Reference

The User Feature reference has two inputs, which are two points. The new CATStateCommand created in this sue case allows the end user to select these points in order to create a new instance.

Fig.3: Creation Command

Here is an example of a new User Feature instance, "CAAUserFeatureSample.1", during the process of its creation. The first input has been selected (Point.1). When the end user will have selected the second point, the OK button will be selectable and the creation can be ended.

The interactive command itself is an instance of the CAAMcaUdfLoftEditCreateCmd class. This class can be used in edition mode, when you double click on an instance of the User Feature reference, or in creation mode as shown above. The "CATIEdit For a User Feature" use case [4] describes this class in used edition mode. In this article you will see how to slightly modify this class in order to have a command that can be used in creation mode.

[Top]

How to Launch CAAMcaUdfAddin

To launch the use case, you will need to set up the build time environment, then compile CAAMcaUdfAddin and CAAMcaUdfEdit along with their prerequisites, set up the run time environment, and then execute the use case [5].

Before launching CATIA:

Execute the use case by going through the following scenario:

Launch CATIA. When the application is ready:

[Top]

Where to Find the CAAMcaUdfAddin Code

The CAAMcaUdfAddin use case is made of several classes located in the CAAMcaUdfAddin.m module (for the addin) and in the CAAMcaUdfEdit.m (for the command) of the CAAMechanicalCommands.edu framework:

Windows InstallRootDirectory\CAAMechanicalCommands.edu\CAAMcaUdfAddin.m\
InstallRootDirectory\CAAMechanicalCommands.edu\CAAMcaUdfEdit.m\
Unix InstallRootDirectory/CAAMechanicalCommands.edu/CAAMcaUdfAddin.m/
InstallRootDirectory/CAAMechanicalCommands.edu/CAAMcaUdfEdit.m/

where InstallRootDirectory is the directory where the CAA CD-ROM is installed.

[Top]

Step-by-Step

This section extracts certains methods from the CAAMcaUdfLoftCreateCmd class as well as the code from the beginning of the BuildGraph method needed to create the User Feature instance. In each method, we only explain the specific code for the creation. Refer to the "CATIEdit For a User Feature" use case [4] for more complete details.

  1. Coding a Default Constructor
  2. Modifying the BuildGraph Method
  3. Coding the CreateFeature Method
  4. Coding the RetrieveTheUFRef Method
  5. Coding the InstantiateTheUFRef Method

[Top]

Coding a Default Constructor

...
#include "CATCreateExternalObject.h"
CATCreateClass(CAAMcaUdfLoftEditCreateCmd);

CAAMcaUdfLoftEditCreateCmd::CAAMcaUdfLoftEditCreateCmd():
CATPrtPanelStateCmd ("CAAMcaUdfLoftEditCreateCmd", 
                             CATDlgEngOneShot, 
                             CATCommandModeExclusive,1),
_pInputDialogBox(NULL),_pAgentErrorDialogBox(NULL),_pFeatureAgent(NULL),_ErrorKey("NoError"),
_pErrorDialogBox(NULL),_pFirstPoint(NULL),_pSecondPoint(NULL),_pSelectedPath(NULL)
{
   HRESULT rc = InitCommand();
   if (FAILED(rc) )
   {
       _ErrorKey = "InternalError";
   }
}

This class without arguments will be instantiated by the CATStateCommand class by its name.This is possible thanks to the CATCreateClass macro.

The CAAMcaUdfLoftEditCreateCmd class derives from the CATPrtPanelStateCmd. The last argument is the mode of the command: 0 for an edition and 1 for a creation.

The InitCommand creates the "CAAUdfLoft Definition" Dialog Box [Fig.3] used to display the selected inputs.

Modifying the BuildGraph Method

void CAAMcaUdfLoftEditCreateCmd::BuildGraph()
{
 
    if ( 1 == GetMode() && ( CATString("NoError")  == _ErrorKey ) )
    {
        CreateFeature();
    }
    ...
}    

Before creating the state chart, the user feature must be created ( CreateFeature ) in creation mode.

GetMode(), is a method of the CATMMUIPanelStateCmd class, which is the parent class of the current command. It returns the mode (creation or edition) set in the constructor.

[Top]

Creating the CreateFeature Method

HRESULT CAAMcaUdfLoftEditCreateCmd::CreateFeature()
{
    HRESULT rc = E_FAIL ;

    char * pCAAUdfLoftFile = NULL ;
    CATLibStatus result = ::CATGetEnvValue("CAAMcaUdfLoftFile",&pCAAUdfLoftFile);  
    if ( (CATLibError == result) || ( NULL == pCAAUdfLoftFile) )
    {
       _ErrorKey = "EnvVarNotSet";
    }else 
    {
       CATDocument * pUdfDocument = NULL ;
       CATUnicodeString UdfDocumentName = pCAAUdfLoftFile ;

       free (pCAAUdfLoftFile) ;
       pCAAUdfLoftFile = NULL ;

       HRESULT rc = CATDocumentServices::Open(UdfDocumentName,pUdfDocument);
 
       if ( SUCCEEDED(rc) )
       {
          ::CATLockDocument(*pUdfDocument);
          
          CATIUdfInstantiate * pIUdf = NULL ;
          rc = RetrieveTheUFRef(pUdfDocument, &pIUdf);                                
          if ( SUCCEEDED(rc) )
          {
             rc = InstantiateTheUFRef(pIUdf);
             if (FAILED(rc) )
             {
                _ErrorKey = "InternalError";
             }
             pIUdf->Release();
             pIUdf = NULL ;
          } 
          else _ErrorKey = "UserFeatureReferenceNotFound";
    
          rc = ::CATUnLockDocument(*pUdfDocument) ;
          pUdfDocument = NULL ;
          if ( FAILED(rc) ) _ErrorKey = "InternalError";

       }else _ErrorKey = "FileNoFound";

    }
   
    return rc ;
}

The User Feature reference to be instantiate is saved in the CAAMcaUdfLoftFile environment variable. In an industrial case, you can retrieve the reference from a catalog or thanks to the Open Dialog Box.

The Part document which contains the reference, referenced by the pUdfDocument CATDocument pointer, is opened by the Open function and immediately locked. It will be unlocked after the instantiation has finished, in other words, after the call to the InstantiateTheUFRef method.

Note: The document which contains an instance of a User Feature reference, referred to as the "Destination" document, keeps a link on the document containing the User Feature reference., named "Reference" document. When the "Destination" document is closed, if you have not locked the "Reference" document, it will be also closed. However in this particular case, the lock is not mandatory, since the "Destination" document is the active document which has a longer life than the command; this is safer.

The RetrieveTheUFRef method enables the retrieval of the "CAAUserFeatureSample" User Feature reference from pUdfDocument.

[Top]

Coding the RetrieveTheUFRef Method

HRESULT CAAMcaUdfLoftEditCreateCmd::RetrieveTheUFRef(CATDocument * iUFRefDocument, CATIUdfInstantiate ** oIUdf)
{
    HRESULT rc = E_FAIL ;

    CATInit *pInitOnDoc = NULL ;
    rc = iUFRefDocument->QueryInterface(IID_CATInit,(void **) &pInitOnDoc);
    if ( SUCCEEDED(rc) )
    {
        CATIPrtContainer * pIPrtCont = NULL ;
        pIPrtCont = (CATIPrtContainer*)pInitOnDoc->GetRootContainer("CATIPrtContainer");

        if ( NULL != pIPrtCont )
        {
           CATIUdfFactory *pIUdfFactory = NULL ;
           rc = pIPrtCont->QueryInterface(IID_CATIUdfFactory,(void **) &pIUdfFactory);
           if ( SUCCEEDED(rc) )
           {
              CATListValCATISpecObject_var * pListUserFeature = NULL ;
              pListUserFeature = pIUdfFactory->GetUserFeatureList();

              if ( NULL != pListUserFeature )
              {
                 int i= 1 ;
                 int nb = pListUserFeature->Size();
                 CATBoolean found = FALSE ;

                 rc = E_FAIL ;
                 while ( (i<= nb) && ( FALSE == found ) )
                 {
                    CATISpecObject_var spCurrentUserFeature = (*pListUserFeature)[i] ;
                    if ( NULL_var != spCurrentUserFeature )
                    {
                       rc = CheckUserFeatureType(spCurrentUserFeature);
 
                       if ( SUCCEEDED(rc) )
                       {
                          found = TRUE;
                          rc = spCurrentUserFeature->QueryInterface(IID_CATIUdfInstantiate,
                                                          (void **)oIUdf);
                       }
                    }
                    i++ ;
                 }

              }else rc = E_FAIL ;
              
              pIUdfFactory->Release();
              pIUdfFactory = NULL ;
           }
           pIPrtCont->Release();
           pIPrtCont = NULL ;
        }else rc = E_FAIL;

        pInitOnDoc->Release();
        pInitOnDoc = NULL ;
    }
 
    return rc ;
}

The list of the User Feature references is given by the CATIUdfFactory Interface. This interface is implemented on the CATPrtContainer container, pIPrtCont, which is the root container of the Part document. In the technical article about User Feature [3], the structure of a Part document is described.

This list is returned by the GetUserFeatureList method. The code loops for as long as the reference has not be found. The CheckUserFeatureType method, used to recognized the reference, is described in the edition use case [4]

[Top]

Coding the InstantiateTheUFRef Method

HRESULT CAAMcaUdfLoftEditCreateCmd::InstantiateTheUFRef(CATIUdfInstantiate * iIUdf)
{
    HRESULT rc = E_FAIL ;
                  
    CATBaseUnknown * pBkunOnMechanicalPart = NULL ;

    CATIPrtPart_var spIPrtPartOnMechanicalPart = GetPart();
    if ( NULL_var != spIPrtPartOnMechanicalPart )
    {
       CATBaseUnknown_var spBkunOnMechanicalPart = spIPrtPartOnMechanicalPart ; 
       if ( NULL_var !=  spBkunOnMechanicalPart )
       {
          pBkunOnMechanicalPart = (CATBaseUnknown *) spBkunOnMechanicalPart ;
       }
    }
   
    if ( NULL !=  pBkunOnMechanicalPart )
    {
       CATPathElement PathInstantiate(pBkunOnMechanicalPart); 
       CATPathElement * FirstUIactiveObject1 = NULL ;
       CATBaseUnknown_var FirstDest1 = NULL_var ; 

       rc = iIUdf->SetDestinationPath(&PathInstantiate,
                                  FirstUIactiveObject1,
                                  FirstDest1);
 
       if ( SUCCEEDED(rc) )
       {
          rc = iIUdf->Instantiate(NULL_var);

          if ( SUCCEEDED(rc) )
          {
             CATBaseUnknown_var spInstance = NULL_var ;
             spInstance = iIUdf->GetInstantiated(iIUdf);

             if ( NULL_var != spInstance )
             { 
                 rc = iIUdf->EndInstantiate();

                 if ( SUCCEEDED(rc) )
                 {
                    _MyFeature = spInstance ;
                 }
             } else rc = E_FAIL ;
          }
       }
    } 
            
    return rc ;
}

The new instantiation will be done in the current Part. The MechanicalPart feature of this Part is returned by the GetPart method. This method is found in the CATMMUIStateCommand parent of the current class. The MechanicalPart implements the CATIUdfInstantiate interface. See the "Instantiating a User Feature Reference" use case [2] or the "How to Use the Interfaces" section of the technical article [3] in order to have a description of the main calls for an instantiation:

Notice that, contrary to the use case [2] and the technical article [3], the inputs are not valuated. This will be done when the end user will have selected two points and clicked on the Ok Button of the "CAAUdfLoft Definition" Dialog box [Fig.3]. This valuation will be done through the CATIUdfFeatureInstance interface.

[Top]


In Short

This use case has demonstrated how to instantiate a User Feature reference in an interactive command.

[Top]


References

[1] Creating a User Feature Reference
[2] Instantiating a User Feature Reference
[3] Power Copy and User Feature Overview
[4] CATIEdit For an User Feature
[5] Building and Launching a CAA V5 Use Case
[Top]

History

Version: 1 Mar 2002] Document created
[Top]

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