Analysis Solution |
Analysis Modeler |
Creating Analysis Features - Part 2Import an external format inside an Analysis document |
Use Case |
AbstractThis 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.
|
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]
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]
CAAAniAeroDTransition is a use case of the CAAAnalysisInterfaces.edu framework that illustrates CATIA Analysis frameworks capabilities.
The goal of this Use Case is to implement the import capability that will produce the image seen previously.
[Top]
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]
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]
Implementing a transition includes six main steps:
[Top]
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]
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:
GetFileTypes
that defines the list of types associated
with the file for the import dialog box customization.GetCommentForType
that associates a comment for the
openFile box.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 :
GetUserFrame
that generates the
user dialog frame.Accept
that is called when the Ok button of the main panel is pressed.GetValues
that fills a CATSafeArrayVariant to
store wanted values for Visual Basic. SetValues
that updates wanted values from a
CATSafeArrayVariant for Visual Basic.[Top]
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 :
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*.ImportFif
that will open the file and create the node and finite elements.
TranslateToFieldModel
that will
generate the field model associated to our imported file.
[Top]
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]
... //================================================================================================= // 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]
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]
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]
This use case has demonstrated how to import some external data inside the CATAnalysis.
[Top]
[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.