Analysis Solution

Analysis Modeler

Creating Analysis Features - Part 2

Import an external format inside an Analysis document

Use Case

Abstract

This article accompanies the Analysis New FeatureOverview technical article.

It will focus on the implementation of an Analysis data import inside an analysis document. This step is not necessary, it can be fulfilled by using CATIA meshing and preprocessing capability. Also this scenario will propose an alternative solution for importing some external data inside the analysis document.


What You Will Learn With This Use Case

This use case is intended to help you to import a mesh and preprocessing entities inside the Analysis document.

More specifically, the CAAAniAeroDTransition.m use case shows how to:

[Top]

About Import.

All import capabilities are associated inside Analysis environment to the Links Manager object. This feature is dedicated to keep the links from the Analysis document that is used to manage the import. In order to integrate a new format, the following sequence of interfaces have to be implemented.

If a new CATISamImportDefine is implemented, by using the contextual menu on the Links manager object, user interface will looks like:

[Top]

The CAAAniAeroDTransition Use Case

CAAAniAeroDTransition is a use case of the CAAAnalysisInterfaces.edu framework that illustrates CATIA Analysis frameworks capabilities.

What Does CAAAniAeroDTransition Do

The goal of this Use Case is to implement the import capability that will produce the image seen previously.

[Top]

How to Launch CAAAniAeroDTransition

To launch CAAAniAeroTransition, you will need to set up the build time environment, then compile CAAAniAeroTransition along with its prerequisites, set up the run time environment, and then execute the use case [1].

[Top]

Where to Find the CAAAniAeroDTransition Code

The code for this use case is contained in module CAAAniAeroDTransition.m of the framework CAAAnalysisInterfaces.edu. The module generated is a shared library or DLL that contains:

We will see the different implementations and focus on the CAAAniADImport methods and internal tools.

[Top]

Step-by-Step

Implementing a transition includes six main steps:

  1. Defining a CATIPersistent Implementation of the "fif" File Format
  2. Defining a CATISamImportDefine Implementation
  3. Defining a CAAIAniAeroImport Implementation
  4. Coding the Import Method
  5. Putting in Place the Feature Structure
  6. Implementing the CATIMSHMesher Interface
  7. Adding Callbacks to be warned by the CATAnalysis Renaming or by your own document Renaming

[Top]

Defining a CATIPersistent Implementation of the "fif" File Format

CATIPersistent is implemented by the CAAAniFifFile class.

...
CATImplementClass(CAAAniFifDoc,DataExtension,CATBaseUnknown,fif);
 
// Tie the implementation to its interface
// ---------------------------------------
#include "TIE_CATIPersistent.h"
TIE_CATIPersistent(CAAAniFifDoc);

//=====================================================================
// All methods needs to be implemented with dummy software
//=====================================================================
CATBoolean CAAAniFifDoc::Dirty ()
{ return FALSE ; }
//=====================================================================
void CAAAniFifDoc::Save()
{}
//=====================================================================
void CAAAniFifDoc::SaveAs (char * storagePrintableName,CATBoolean becameCurrent)
{}
//=====================================================================
void CAAAniFifDoc::SaveAs_B (SEQUENCE(octet) storageName, CATBoolean becameCurrent)
{}
//=====================================================================
void CAAAniFifDoc::Load (char * storagePrintableName, CATBoolean readOnlyFlag)
{}
//=====================================================================
void CAAAniFifDoc::Load_B (SEQUENCE(octet) storageName, CATBoolean readOnly)
{}
...

Associated with this setup of code, the implementation must be defined inside the Object Modeler Dictionary. See CAAAnalysisInterfaces.edu.dico file defined in CAAAnalysisInterfaces.edu\CNEXT\code\dictionary. This definition line associates the implementation of CATIPersistent interface for the fif file format inside the shared library libCAAAniAeroDTransition

...
fif  CATIPersistent  libCAAAniAeroDTransition
...

[Top]

Defining a CATISamImportDefine Implementation

CATISamImportDefine is implemented by the CAAAniImportDefine class which is derivated from CATESamImportDefineAdaptor.

...
CATImplementClass(CAAAniImportDefine,DataExtension,CATBaseUnknown,AeroDynamicImport);
//-----------------------------------------------------------------------------
// CAAAniImportDefine : constructor
//-----------------------------------------------------------------------------
CAAAniImportDefine::CAAAniImportDefine():CATESamImportDefineAdaptor()
{ 
}

// Tie the implementation to its interface
// ---------------------------------------
#include "TIE_CATISamImportDefine.h"
TIE_CATISamImportDefine(CAAAniImportDefine);

//-----------------------------------------------------------------------------
// CAAAniImportDefine : GetFileTypes
//-----------------------------------------------------------------------------

HRESULT CAAAniImportDefine::GetFileTypes(CATListValCATString& oTypes)
{
  oTypes.Append(CATString("fif"));
  return S_OK;
}
//-----------------------------------------------------------------------------
// CAAAniImportDefine : GetCommentForType
//-----------------------------------------------------------------------------

HRESULT CAAAniImportDefine::GetCommentForType(const CATString       iType,
                                               CATUnicodeString& oComment)
{
  if(iType == "fif")
    oComment = "Aerodynamic Mesh File";
  else
     return E_FAIL;

  return S_OK;
}
//-----------------------------------------------------------------------------
// CAAAniImportDefine : Import 
//-----------------------------------------------------------------------------
HRESULT CAAAniImportDefine::Import (CATDocument * iImportedDoc, CATDocument * iAnalysisDoc)
{
  HRESULT HR = E_FAIL;

  CATAssert(iImportedDoc);
  CATAssert(iAnalysisDoc);

  if (iImportedDoc->GetType() == "fif") {
    CAAIAniAeroImport_var spAeroImport(iImportedDoc);
    if (!!spAeroImport)
      HR = spAeroImport->Import((iImportedDoc->StorageName()).ConvertToChar(), iAnalysisDoc);
  }
  return HR;
}

Associated with this setup of code, the implementation must be defined inside the Object Modeler Dictionary. See CAAAnalysisInterfaces.edu.dico file defined in CAAAnalysisInterfaces.edu\CNEXT\code\dictionary. This definition line associates the AeroDynamicImport implementation of CATISamImportDefine interface inside the shared library libCAAAniAeroDTransition

...
AeroDynamicImport  CATISamImportDefine  libCAAAniAeroDTransition
...

At least three methods need to be implemented:

  1. GetFileTypes that defines the list of types associated with the file for the import dialog box customization.
  2. GetCommentForType that associates a comment for the openFile box.
  3. Import that launches the execution from the input file to the current CATAnalysis document. This method has as input two CATDocument* pointers one for the imported file and the second one to the current CATAnalysis document.

In order to associate an user interface with the file import four methods have to be implemented :

  1. GetUserFrame that generates the user dialog frame.
  2. Accept that is called when the Ok button of the main panel is pressed.
  3. GetValues that fills a CATSafeArrayVariant to store wanted values for Visual Basic.
  4. SetValues that updates wanted values from a CATSafeArrayVariant for Visual Basic.

[Top]

Defining a CAAIAniAeroImport Implementation

CAAIAniAeroImport is implemented by the CAAAniImport class on the document extension fif.

...
CATImplementClass( CAAAniADImport, DataExtension, CATBaseUnknown, fif);
...
// Tie the implementation to its interface
// ----------------------------------------
#include "TIE_CAAIAniAeroImport.h"
TIE_CAAIAniAeroImport(CAAAniADImport);

Associated with this setup of code, the implementation must be defined inside the Object Modeler Dictionary. See CAAAnalysisInterfaces.edu.dico file defined in CAAAnalysisInterfaces.edu\CNEXT\code\dictionary. This definition line associates the fif implementation of CAAIAniAeroImport interface inside the shared library libCAAAniAeroDTransition

...
fif  		CAAIAniAeroImport		libCAAAniAeroDTransition
...

Three methods have to be implemented :

  1. Import that launches the execution from the input file to the current CATAnalysis document. This method has as an input a pointer to the current CATAnalysis document defined as a CATDocument*.
  2. ImportFif that will open the file and create the node and finite elements.    
  3. TranslateToFieldModel that will generate the field model associated to our imported file.          

[Top]

Coding the Import Method

The aim of this method is to import the content of the file by creating Analysis features. As seen previously, this includes:

A lot of this software is already described in the previous uses cases. Refer to them for more explanations. At the end of the import, some steps are required:

[Top]

Putting in Place the Feature Structure

...
//=================================================================================================
// Get the Analysis Container
//=================================================================================================
CATISamAccess_var  spSamAccess (idocument);
if( NULL_var == spSamAccess) return E_FAIL;
CATIContainer     *piSpecContainer=NULL;
CATISamAnalysisContainer_var spAnalysisContainer;

hr = spSamAccess -> GetSpecContainer(piSpecContainer);
CATISamAnalysisModelFactory_var spFactory;
if (piSpecContainer)
{
  spAnalysisContainer = piSpecContainer;
  spFactory           = piSpecContainer;
  piSpecContainer -> Release();
  piSpecContainer = NULL;
}
else
{
  if (piSpecContainer) piSpecContainer -> Release();
  piSpecContainer = NULL;
  return E_FAIL;
}
if (NULL_var == spAnalysisContainer) return E_FAIL;
 
//=================================================================================================
// Get the AnalysisManager
//=================================================================================================
CATISamAnalysisManager_var spAnalysisManager;
hr = spAnalysisContainer->GetAnalysisManager(spAnalysisManager);
if (FAILED(hr)) return E_FAIL;
...
...
//=================================================================================================
// Get the DocumentManager To plug the document.
//=================================================================================================
CATISamDocumentManager_var spDocManager;
hr = spAnalysisManager ->GetDocumentManager(spDocManager);
if (FAILED(hr)) return E_FAIL;
//
CATISpecObject * piLink= NULL;
// Create a link from the document manager to the external file
if (NULL_var != spDocManager)
{
  if (NULL_var != spFactory)  piLink = spFactory -> CreateAnalysisLink("fif");
  CATDocument * pDocToLink = (CATDocument*) (this);
  if (NULL != pDocToLink)
    spDocManager ->InsertDocument(pDocToLink,"fif",piLink);
}
...
...
//=================================================================================================
 
CATIMSHMeshManager * piManager  = NULL;
CATISpecObject* piAnalysisModel = NULL;
// Retrieve the AnalysisModel
hr = spAnalysisManager ->GetCurrentModel(piAnalysisModel);
if (NULL != piAnalysisModel)
{
  CATISamExplicit *piExplicitFeat = NULL;
  // Retrieve the AnalysisModel Field model Object
  piAnalysisModel -> QueryInterface(IID_CATISamExplicit,(void**)&piExplicitFeat);
  if (NULL!= piExplicitFeat)
  {
    piExplicitFeat-> GetExplicitObject(MeshSet);
    piExplicitFeat -> Release();
  }
  CATISamAnalysisModel *piAnalysisMod = NULL ;
  piAnalysisModel -> QueryInterface(IID_CATISamAnalysisModel,(void**)&piAnalysisMod);
  if (NULL != piAnalysisMod)
  {
    // Retrieve the Case created in the transition and its field modele version
    CATISamAnalysisCase* piFoundCase = NULL;
    piAnalysisMod->GetNamedCase("Aero Case",piFoundCase);
    if (piFoundCase)
    {
      piExplicitFeat = NULL;
      piFoundCase -> QueryInterface(IID_CATISamExplicit,(void**)&piExplicitFeat);
      if (NULL!= piExplicitFeat)
      {
        piExplicitFeat -> GetExplicitObject(ExpCase);
        piExplicitFeat -> Release();
      }
      spScan = piFoundCase;
      piFoundCase-> Release();
      piFoundCase=NULL;
    }
    // Retrieve the CATIMSHMeshManager associated to the Analysis Model.
    CATBaseUnknown* piBaseMesh=NULL;
    piAnalysisMod->GetMesh(piBaseMesh);
    if (piBaseMesh!= NULL)
    {
      piBaseMesh -> QueryInterface(IID_CATIMSHMeshManager,(void**)&piManager);
      piBaseMesh -> Release();
      piBaseMesh =  NULL;
    }
    piAnalysisMod -> Release();
    piAnalysisMod =  NULL;
  }
  piAnalysisModel-> Release();
  piAnalysisModel=NULL;
}
//
if (piManager == NULL || MeshSet == NULL_exp  || ExpCase == NULL_exp )
  return E_NOINTERFACE;
//==========================================================================
// Catalog For Meshing at the level of the container of the manager
CATISpecObject* piMshMESH = NULL;
piManager -> QueryInterface(IID_CATISpecObject,(void**)&piMshMESH);
if (piMshMESH != NULL)
{
  CATIContainer_var spMCont = piMshMESH -> GetFeatContainer();
  piMshMESH -> Release ();
  piMshMESH=NULL;
  CATICatalogManager_var spCataManager = spMCont;
  if (NULL_var !=  spCataManager)
  {
    CATICatalog * pcatalog = NULL;
    CATUnicodeString CataName ("CAAAniCatalog.CATfct");
    CATUnicodeString CataId   ("CAAAniCatalog");

    AccessCatalog(&CataName,&CataId,spMCont,&pcatalog);
    if (pcatalog)   pcatalog   -> Release();
    pcatalog = NULL;
  }
}
...
...
// Create the MeshPart associated with the import.
CATIMSHMeshPart* piMshPart = piManager -> CreateMeshPart("AeroMeshPart");
if (piMshPart && piLink)
{
  CATILinkableObject * piLinkable= NULL;
  piLink -> QueryInterface (IID_CATILinkableObject,(void **)&piLinkable);
  if (piLinkable)
  {
     piMshPart -> SetSupport (NULL,piLinkable);
     piLinkable -> Release();
  }
/*CATISpecObject* piMPObject = NULL;
  piMshPart -> QueryInterface (IID_CATISpecObject,(void **)&piMPObject);
  if (piMPObject)
  {
    piMPObject -> Update();
    piMPObject -> Release();
  } */
}
if (NULL != piMshPart) piMshPart -> Release();
if (NULL != piLink)    piLink -> Release();
 //=================================================================================================
if (piManager) piManager -> Release(); piManager = NULL;
...

At this step, the global structure of the specification is set-up.

[Top]

Implementing the CATIMSHMesher Interface

CATIMSHMesher is implemented by the CAAAniAeroMesher class. Note that the Mesher identifier is build automatically by the software as the late type of the feature plus "_mesher" string.

...
CATImplementClass(CAAAniAeroMesher,DataExtension,CATBaseUnknown,AeroMeshPart_mesher);

// Tie the implementation to its interface
// ---------------------------------------
#include "TIE_CATIMSHMesher.h"
TIE_CATIMSHMesher(CAAAniAeroMesher);
...

Associated with this setup of code, the implementation must be defined inside the Object Modeler Dictionary. See CAAAnalysisInterfaces.edu.dico file defined in CAAAnalysisInterfaces.edu\CNEXT\code\dictionary. This definition line associates the AeroMeshPart_mesher implementation of CATIMSHMesher interface inside the shared library libCAAAniAeroDTransition.

...
AeroMeshPart_mesher  CATIMSHMesher  libCAAAniAeroDTransition
...

Now the implementation of the methods:

IsOfType is a Query the mesher about its type. The String representing the query made to the mesher. The Legal values can be:

The result of the query may be set to 1 if the answer is yes, else set it to 0. In our case, this is always 0.

...
int CAAAniAeroMesher::IsOfType (const CATUnicodeString &iType)
{
  if ( Type == "Other" ) return 1;
  return 0;
}
...

CheckSuppport allows the mesher to validate the support assigned to the mesh part. In our scenario, this is the link to the file.

...
HRESULT CAAAniAeroMesher::CheckSupport(CATIMSHMeshPart*       MeshPart,
                                       int &              NbParents,
                                       CATIMSHMeshPart** &ParentMeshParts)
{
  HRESULT hr = S_OK;

  NbParents = 0;
  ParentMeshParts = NULL;

  CATDocument* pBaseDoc  = NULL;
  hr = GetLinkedDoc (MeshPart,pBaseDoc);
  if (!SUCCEEDED(hr)) return E_FAIL;
  if (NULL == pBaseDoc) return E_FAIL;

  return hr;
}
...

[Top]

Mesh will effectively launch the meshing algorithm. The generated Finite Elements will be automatically  associated to a domain. This domain is identified by an integer. The created elements method is working in the current opened domain or open a new one if no one is open. The mesher has to create a new domain in which each finite element will be created. To do so, use the method of the CATIMSHMesh interface to create a new domain. Several domains can be created if the elements have to be grouped in several areas. In our case we choose to have only one domain. At the opening of a new domain, the previous one will be automatically closed.

...
HRESULT CAAAniAeroMesher::Mesh (CATIMSHMeshPart* iMeshPart)
{
  // Initialize Output Data
  HRESULT hr =S_OK;
  NbDomains = 0;
  Domains   = NULL;
  CATUnicodeString ifile_name;
  //=================================================================================================<
  // Check Input Argument
  //=================================================================================================
  if (NULL == MeshPart) return E_FAIL;
  CATIMSHMeshManager *piManager = MeshPart -> GetMeshManager ();
  if (NULL == piManager) return E_FAIL;
  CATIMSHMesh * pimesh = piManager -> GetMesh ();
  if (NULL == pimesh) return E_FAIL;
  //=================================================================================================
  // Retrieve the support  for the name of file
  //=================================================================================================
  CATDocument* pBaseDoc  = NULL;
  hr = GetLinkedDoc (MeshPart,pBaseDoc);
  if (!SUCCEEDED(hr) || NULL == pBaseDoc) return E_FAIL;
  ifile_name = pBaseDoc ->StorageName();
  //=================================================================================================
  // Retrieve the current document
  //=================================================================================================
  CATILinkableObject *piLinkable= NULL;
  hr = MeshPart -> QueryInterface(IID_CATILinkableObject,(void **)&piLinkable);
  if (NULL == piLinkable) return E_NOINTERFACE;
  CATDocument  *pCurrDoc = piLinkable-> GetDocument();
  piLinkable -> Release();piLinkable=NULL;
  //=================================================================================================
  // Get the CATAnalysisExplicitModel
  //=================================================================================================
  CATAnalysisExplicitModel* modelExpli = NULL;
  modelExpli = CATAnalysisExplicitModel::GetDocumentModel(pCurrDoc);
  //=================================================================================================
  // Get the Analysis Model
  //=================================================================================================
  CATISamAnalysisSet* piSet = NULL;
  CATAnalysisExplicitSet MeshSet,ExpCase;
  hr = MeshPart -> QueryInterface(IID_CATISamAnalysisSet,(void **)&piSet);
  if (NULL == piSet) return E_NOINTERFACE;
  CATISamAnalysisModel* piFEMModel = NULL;
  piSet -> GetFEMModel(piFEMModel);
  if (piFEMModel)
  {
    CATISamExplicit *piExplicitFeat = NULL;
    // Retrieve the AnalysisModel Field modele Object
    piFEMModel -> QueryInterface(IID_CATISamExplicit,(void**)&piExplicitFeat);
    if (NULL != piExplicitFeat)
    {
      piExplicitFeat-> GetExplicitObject(MeshSet);
      piExplicitFeat -> Release();
    }
    //=================================================================================================
    // Retrieve the Case created in the transition and its field model version
    //=================================================================================================
    CATISamAnalysisCase* piFoundCase = NULL;
    piFEMModel->GetNamedCase("Aero Case",piFoundCase);
    if (piFoundCase)
    {
      piExplicitFeat = NULL;
      piFoundCase -> QueryInterface(IID_CATISamExplicit,(void**)&piExplicitFeat);
      if (NULL!= piExplicitFeat)
      {
        piExplicitFeat -> GetExplicitObject(ExpCase);
        piExplicitFeat -> Release();
      }
      piFoundCase-> Release();
      piFoundCase=NULL;
    }
    piFEMModel -> Release();
  }
  piSet -> Release();
  //=================================================================================================
  // Start Meshing
  //=================================================================================================
  hr = ImportFif (ifile_name.ConvertToChar(),piManager,modelExpli,MeshSet,ExpCase);
  if (pimesh) pimesh-> Release();
  if (piManager) piManager -> Release();
  return hr;
}...

[Top]

ImportFif will open the file and create the nodes and finite elements. According to nodes and elements information ridden from the file, the corresponding entities have to be created inside the analysis Document. For this, we have to create the nodes and elements inside the meshing container by using the services on the CATIMSHMesh interface and reference the meshing information inside the field model. For this, use the CATAnalysisExplicitNode and CATAnalysisExplicitElement Objects. Because no specific properties are declared in the input file, some generic behavior for triangles and quadrangles will be chosen.

For Nodes:

...
//===================================================================================
// Node Creation inside the Mesh container
CATMSHNode ** m_nodes = new CATMSHNode * [nbnode];
CATAnalysisExplicitNode Node = NULL_exp;;
mesh -> CreateNodes (xyz,nbnode,m_nodes);
//===================================================================================
// Node as explicit entity creation:
for (int iele = 0 ; iele < nbnode; iele ++)
{
  Node.CreateNode(nodes,m_nodes[iele],NODE);
}
...

For Elements:

...
//===================================================================================
// Retrieve the Basic Shell Physical Type
modelExpli->GetPhysicalTypeNumber("ELEMENT_DRAWING_QUAD4",QD4);
char *connec = "QD4";
CATAnalysisExplicitElement Element = NULL_exp;

if (nbelemQD4)
{
  // Elements Creation inside the Mesh contenair
  mesh -> CreateElements(connec,4,linkednodesQD4,nbelemQD4,m_elem);
  for (j= 0 ; j < nbelemQD4 ; j++)
    Element.CreateElement(elements,m_elem[j],QD4);
}
...

[Top]

Adding Callbacks to be warned by the CATAnalysis Renaming or by your own document Renaming

Callback on the CATAnalysis

You want to be warned when the Analysis document is renamed, add a callback where idocument is the Analysis document and OnRenameCB is the method that will be called at each modification of the Analysis document's name.

...
CATCallback RenameCB = ::AddCallback ( this , idocument , "CATSamDocNotification" ,
(CATSubscriberMethod)&CAAAniADImport::OnRenameCB );
...

Callback on your own document

You want to be warned when your document is renamed, add a callback thanks to CATSamDocumentTools::AddRenameCB where pDocToLinkis your own document, idocument is the Analysis document and OnRenameCB2 is the method that will be called at each modification of your document's name.

...
CATCallback RenameCB2 = CATSamDocumentTools::AddRenameCB(pDocToLink, idocument, (CATSubscriberMethod)&CAAAniADImport::OnRenameCB2);
...

Implementation of the call method

You have to implement the method on which you will be call to make some treatments if needed. Below you will find some example about how to retrieve the old and new name of the document thanks to the notification.

void CAAAniADImport::OnRenameCB(CATCallbackEvent,void*,CATNotification *notif, CATSubscriberData,CATCallback)
{ 
   CATSamDocNotification * pNotif = (CATSamDocNotification *) notif;
   if ( !pNotif ) return;
   CATSamDocActionType type = pNotif -> GetActionType ();
   if (type != SamRename) return;

   cout<<"GiveOldName " <<(pNotif->GiveOldName()).ConvertToChar() <<endl;
   cout<<"GiveNewName " <<(pNotif->GiveNewName()).ConvertToChar() <<endl;
 
   return;
}

[Top]


In Short

This use case has demonstrated how to import some external data inside the CATAnalysis.

[Top]


References

[1] Building and Launching a CAA V5 Use Case
[2] Feature Modeler documentation
[3] Analysis Modeler Overview
[4] Integrate new Feature inside Analysis.

[Top]


History
Version: 1 [Mar 2000] Document created
Version: 2 [Jun 2004] Document modified
Version: 3 [Feb 2007] Document modified

[Top]


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