-// SMESH DriverMED : driver to read and write 'med' files
+// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
+// SMESH DriverMED : driver to read and write 'med' files
// File : DriverMED_W_SMESHDS_Mesh.cxx
// Module : SMESH
+//
-using namespace std;
#include "DriverMED_W_SMESHDS_Mesh.h"
-#include "DriverMED_W_SMDS_Mesh.h"
-#include "SMDS_MeshElement.hxx"
+#include "DriverMED_Family.h"
+#include "MED_Factory.hxx"
+#include "MED_Utilities.hxx"
+#include "SMDS_IteratorOnIterators.hxx"
#include "SMDS_MeshNode.hxx"
-#include "SMDS_MeshFacesIterator.hxx"
-#include "SMDS_MeshEdgesIterator.hxx"
-#include "SMDS_MeshNodesIterator.hxx"
-#include "SMDS_MeshVolumesIterator.hxx"
-#include "SMESHDS_SubMesh.hxx"
-#include "SMDS_MapIteratorOfExtendedMap.hxx"
-#include "SMDS_MapOfMeshElement.hxx"
-#include "SMDS_Position.hxx"
-
-#include <TopExp.hxx>
+#include "SMDS_SetIterator.hxx"
+#include "SMESHDS_Mesh.hxx"
+
+#include <BRep_Tool.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
-#include <TopoDS_Iterator.hxx>
-#include <TopoDS_Compound.hxx>
-#include <TopoDS_CompSolid.hxx>
-#include <TopoDS_Solid.hxx>
-#include <TopoDS_Shell.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Wire.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <TopoDS_Shape.hxx>
-#include <TopTools_MapOfShape.hxx>
-#include <TColStd_ListIteratorOfListOfInteger.hxx>
-
-
-#include <map>
-#include <set>
-#include <vector>
-#include "utilities.h"
-
-DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh() {
- ;
-}
-DriverMED_W_SMESHDS_Mesh::~DriverMED_W_SMESHDS_Mesh() {
- ;
-}
+#include <utilities.h>
-void DriverMED_W_SMESHDS_Mesh::SetMesh(Handle(SMDS_Mesh)& aMesh) {
- myMesh = aMesh;
+
+#define _EDF_NODE_IDS_
+//#define _ELEMENTS_BY_DIM_
+
+using namespace std;
+using namespace MED;
+
+
+DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh():
+ myAllSubMeshes (false),
+ myDoGroupOfNodes (false),
+ myDoGroupOfEdges (false),
+ myDoGroupOfFaces (false),
+ myDoGroupOfVolumes (false),
+ myDoGroupOf0DElems(false),
+ myDoGroupOfBalls(false),
+ myAutoDimension(false),
+ myAddODOnVertices(false),
+ myDoAllInGroups(false)
+{}
+
+void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName)
+{
+ Driver_SMESHDS_Mesh::SetFile(theFileName);
}
-void DriverMED_W_SMESHDS_Mesh::SetFile(string aFile) {
- myFile = aFile;
+void DriverMED_W_SMESHDS_Mesh::AddGroup(SMESHDS_GroupBase* theGroup)
+{
+ myGroups.push_back(theGroup);
}
-void DriverMED_W_SMESHDS_Mesh::SetFileId(med_idt aFileId) {
- myFileId = aFileId;
+void DriverMED_W_SMESHDS_Mesh::AddAllSubMeshes()
+{
+ myAllSubMeshes = true;
}
-void DriverMED_W_SMESHDS_Mesh::SetMeshId(int aMeshId) {
- myMeshId = aMeshId;
+void DriverMED_W_SMESHDS_Mesh::AddSubMesh(SMESHDS_SubMesh* theSubMesh, int theID)
+{
+ mySubMeshes.push_back( theSubMesh );
}
-void DriverMED_W_SMESHDS_Mesh::Write() {
+void DriverMED_W_SMESHDS_Mesh::AddGroupOfNodes()
+{
+ myDoGroupOfNodes = true;
+}
- string myClass = string("SMDS_Mesh");
- string myExtension = string("MED");
+void DriverMED_W_SMESHDS_Mesh::AddGroupOfEdges()
+{
+ myDoGroupOfEdges = true;
+}
- DriverMED_W_SMDS_Mesh* myWriter = new DriverMED_W_SMDS_Mesh;
+void DriverMED_W_SMESHDS_Mesh::AddGroupOfFaces()
+{
+ myDoGroupOfFaces = true;
+}
- myWriter->SetMesh(myMesh);
- // myWriter->SetFile(myFile);
- myWriter->SetMeshId(myMeshId);
- myWriter->SetFileId(myFileId);
+void DriverMED_W_SMESHDS_Mesh::AddGroupOfVolumes()
+{
+ myDoGroupOfVolumes = true;
+}
- myWriter->Write();
+void DriverMED_W_SMESHDS_Mesh::AddGroupOf0DElems()
+{
+ myDoGroupOf0DElems = true;
+}
+void DriverMED_W_SMESHDS_Mesh::AddGroupOfBalls()
+{
+ myDoGroupOfBalls = true;
+}
+//================================================================================
+/*!
+ * \brief Set up a flag to add all elements not belonging to any group to
+ * some auxiliary group. This is needed for SMESH -> SAUVE -> SMESH conversion,
+ * which since PAL0023285 reads only SAUVE elements belonging to any group,
+ * and hence can lose some elements. That auxiliary group is ignored while
+ * reading a MED file.
+ */
+//================================================================================
+
+void DriverMED_W_SMESHDS_Mesh::AddAllToGroup()
+{
+ myDoAllInGroups = true;
}
-void DriverMED_W_SMESHDS_Mesh::Add() {
-
- med_err ret = 0;
- int i,j,k,l;
- int numero;
- char message[200];
- Standard_Boolean ok;
- /* nombre d'objets MED */
- char nom_universel[MED_TAILLE_LNOM+1];
- med_int long_fichier_en_tete;
- char *fichier_en_tete;
- char version_hdf[10];
- char version_med[10];
- med_int nmaa,mdim,nnoe;
- med_int nmai[MED_NBR_GEOMETRIE_MAILLE],nfac[MED_NBR_GEOMETRIE_FACE];
- med_int nare[MED_NBR_GEOMETRIE_ARETE];
- /* nom du maillage */
- char nommaa[MED_TAILLE_NOM+1];
- /* noeuds */
- med_float *coo;
- // PN : Initilialisation de nomcoo et unicoo pour lisibilite du maillage
- char nomcoo[3*MED_TAILLE_PNOM+1]="x y z ";
- char unicoo[3*MED_TAILLE_PNOM+1]="m m m ";
- char *nomnoe;
- med_int *numnoe;
- med_int *nufano;
- med_repere rep;
- med_booleen inonoe,inunoe;
- med_mode_switch mode_coo;
- char str[MED_TAILLE_PNOM+1];
- med_int nbNodes;
- /* elements */
- med_int nsup;
- med_int edim;
- med_int taille;
- med_int elem_id,myId;
- med_int *connectivite;
- char *nomele;
- med_int *numele;
- med_int *nufael;
- med_booleen inoele, inuele;
- med_connectivite typ_con;
- med_geometrie_element typgeo;
- med_geometrie_element typmai[MED_NBR_GEOMETRIE_MAILLE] = {MED_POINT1,MED_SEG2,
- MED_SEG3,MED_TRIA3,
- MED_TRIA6,MED_QUAD4,
- MED_QUAD8,MED_TETRA4,
- MED_TETRA10,MED_HEXA8,
- MED_HEXA20,MED_PENTA6,
- MED_PENTA15,MED_PYRA5,
- MED_PYRA13};
- med_int desmai[MED_NBR_GEOMETRIE_MAILLE] = {0,2,3,3,3,4,4,4,4,6,6,5,5,5,5};
- med_int nmailles[MED_NBR_GEOMETRIE_MAILLE];
- char nommai[MED_NBR_GEOMETRIE_MAILLE] [MED_TAILLE_NOM+1] = {"MED_POINT1",
- "MED_SEG2",
- "MED_SEG3",
- "MED_TRIA3",
- "MED_TRIA6",
- "MED_QUAD4",
- "MED_QUAD8",
- "MED_TETRA4",
- "MED_TETRA10",
- "MED_HEXA8",
- "MED_HEXA20",
- "MED_PENTA6",
- "MED_PENTA15",
- "MED_PYRA5",
- "MED_PYRA13"};
- med_geometrie_element typfac[MED_NBR_GEOMETRIE_FACE] = {MED_TRIA3,MED_TRIA6,
- MED_QUAD4,MED_QUAD8};
- med_int desfac[MED_NBR_GEOMETRIE_FACE] = {3,3,4,4};
- med_int nfaces[MED_NBR_GEOMETRIE_FACE];
- char nomfac[MED_NBR_GEOMETRIE_FACE][MED_TAILLE_NOM+1] = {"MED_TRIA3","MED_TRIA6",
- "MED_QUAD4","MED_QUAD8"};
- med_geometrie_element typare[MED_NBR_GEOMETRIE_ARETE] = {MED_SEG2,MED_SEG3};
- med_int desare[MED_NBR_GEOMETRIE_ARETE] = {2,3};
- med_int naretes[MED_NBR_GEOMETRIE_ARETE];
- char nomare[MED_NBR_GEOMETRIE_ARETE] [MED_TAILLE_NOM+1] = {"MED_SEG2","MED_SEG3"};
-
- typ_con = MED_NOD;
- mode_coo = MED_FULL_INTERLACE;
- numero = myMeshId;
-
- //---- provisoire : switch pour ecrire les familles de mailles
- int besoinfamilledemaille=1;
- //---- provisoire : switch pour ecrire les familles de mailles
-
- /****************************************************************************
- * OUVERTURE DU FICHIER EN ECRITURE *
- ****************************************************************************/
- char* file2Read = (char*)myFile.c_str();
-
- MESSAGE ( " file2Read " << file2Read )
-
- myFileId = MEDouvrir(file2Read,MED_REMP);
- if (myFileId < 0)
- {
- fprintf(stderr,">> ERREUR : ouverture du fichier %s \n",file2Read);
- exit(EXIT_FAILURE);
- }
- /****************************************************************************
- * NOMBRES D'OBJETS MED *
- ****************************************************************************/
- MESSAGE("(****************************)");
- MESSAGE("(* INFORMATIONS GENERALES : *)");
- MESSAGE("(****************************)");
-
- /* calcul de la dimension */
- mdim=2;
- double epsilon=0.00001;
- double nodeRefX;
- double nodeRefY;
- double nodeRefZ;
-
- bool dimX = true;
- bool dimY = true;
- bool dimZ = true;
-
- SMDS_MeshNodesIterator myItNodes(myMesh);
- int inode = 0;
- for (;myItNodes.More();myItNodes.Next()) {
- const Handle(SMDS_MeshElement)& elem = myItNodes.Value();
- const Handle(SMDS_MeshNode)& node = myMesh->GetNode(1,elem);
- if ( inode == 0 ) {
- nodeRefX = fabs(node->X());
- nodeRefY = fabs(node->Y());
- nodeRefZ = fabs(node->Z());
+namespace
+{
+ typedef double (SMDS_MeshNode::* TGetCoord)() const;
+ typedef const char* TName;
+ typedef const char* TUnit;
+
+ // name length in a mesh must be equal to 16 :
+ // 1234567890123456
+ TName M = "m ";
+ TName X = "x ";
+ TName Y = "y ";
+ TName Z = "z ";
+
+ TUnit aUnit[3] = {M,M,M};
+
+ // 3 dim
+ TGetCoord aXYZGetCoord[3] = {
+ &SMDS_MeshNode::X,
+ &SMDS_MeshNode::Y,
+ &SMDS_MeshNode::Z
+ };
+ TName aXYZName[3] = {X,Y,Z};
+
+ // 2 dim
+ TGetCoord aXYGetCoord[2] = {
+ &SMDS_MeshNode::X,
+ &SMDS_MeshNode::Y
+ };
+ TName aXYName[2] = {X,Y};
+
+ TGetCoord aYZGetCoord[2] = {
+ &SMDS_MeshNode::Y,
+ &SMDS_MeshNode::Z
+ };
+ TName aYZName[2] = {Y,Z};
+
+ TGetCoord aXZGetCoord[2] = {
+ &SMDS_MeshNode::X,
+ &SMDS_MeshNode::Z
+ };
+ TName aXZName[2] = {X,Z};
+
+ // 1 dim
+ TGetCoord aXGetCoord[1] = {
+ &SMDS_MeshNode::X
+ };
+ TName aXName[1] = {X};
+
+ TGetCoord aYGetCoord[1] = {
+ &SMDS_MeshNode::Y
+ };
+ TName aYName[1] = {Y};
+
+ TGetCoord aZGetCoord[1] = {
+ &SMDS_MeshNode::Z
+ };
+ TName aZName[1] = {Z};
+
+
+ class TCoordHelper{
+ SMDS_NodeIteratorPtr myNodeIter;
+ const SMDS_MeshNode* myCurrentNode;
+ TGetCoord* myGetCoord;
+ TName* myName;
+ TUnit* myUnit;
+ public:
+ TCoordHelper(const SMDS_NodeIteratorPtr& theNodeIter,
+ TGetCoord* theGetCoord,
+ TName* theName,
+ TUnit* theUnit = aUnit):
+ myNodeIter(theNodeIter),
+ myGetCoord(theGetCoord),
+ myName(theName),
+ myUnit(theUnit)
+ {}
+ virtual ~TCoordHelper(){}
+ bool Next(){
+ return myNodeIter->more() &&
+ (myCurrentNode = myNodeIter->next());
}
- SCRUTE( inode );
- SCRUTE( nodeRefX );
- SCRUTE( nodeRefY );
- SCRUTE( nodeRefZ );
-
- if ( inode !=0 ) {
- if ( (fabs(fabs(node->X()) - nodeRefX) > epsilon ) && dimX )
- dimX = false;
- if ( (fabs(fabs(node->Y()) - nodeRefY) > epsilon ) && dimY )
- dimY = false;
- if ( (fabs(fabs(node->Z()) - nodeRefZ) > epsilon ) && dimZ )
- dimZ = false;
+ const SMDS_MeshNode* GetNode(){
+ return myCurrentNode;
}
- if ( !dimX && !dimY && !dimZ ) {
- mdim = 3;
- break;
+ MED::TIntVector::value_type GetID(){
+ return myCurrentNode->GetID();
}
- inode++;
- }
-
- if ( mdim != 3 ) {
- if ( dimX && dimY && dimZ )
- mdim = 0;
- else if ( !dimX ) {
- if ( dimY && dimZ )
- mdim = 1;
- else if (( dimY && !dimZ ) || ( !dimY && dimZ ) )
- mdim = 2;
- } else if ( !dimY ) {
- if ( dimX && dimZ )
- mdim = 1;
- else if (( dimX && !dimZ ) || ( !dimX && dimZ ) )
- mdim = 2;
- } else if ( !dimZ ) {
- if ( dimY && dimX )
- mdim = 1;
- else if (( dimY && !dimX ) || ( !dimY && dimX ) )
- mdim = 2;
+ MED::TFloatVector::value_type GetCoord(TInt theCoodId){
+ return (myCurrentNode->*myGetCoord[theCoodId])();
+ }
+ MED::TStringVector::value_type GetName(TInt theDimId){
+ return myName[theDimId];
+ }
+ MED::TStringVector::value_type GetUnit(TInt theDimId){
+ return myUnit[theDimId];
+ }
+ };
+ typedef boost::shared_ptr<TCoordHelper> TCoordHelperPtr;
+
+ //-------------------------------------------------------
+ /*!
+ * \brief Structure describing element type
+ */
+ //-------------------------------------------------------
+ struct TElemTypeData
+ {
+ EEntiteMaillage _entity;
+ EGeometrieElement _geomType;
+ TInt _nbElems;
+ SMDSAbs_ElementType _smdsType;
+
+ TElemTypeData (EEntiteMaillage entity, EGeometrieElement geom, TInt nb, SMDSAbs_ElementType type)
+ : _entity(entity), _geomType(geom), _nbElems( nb ), _smdsType( type ) {}
+ };
+
+
+ typedef NCollection_DataMap< Standard_Address, int > TElemFamilyMap;
+
+ //================================================================================
+ /*!
+ * \brief Fills element to famaly ID map for element type.
+ * Removes all families of anElemType
+ */
+ //================================================================================
+
+ void fillElemFamilyMap( TElemFamilyMap & anElemFamMap,
+ list<DriverMED_FamilyPtr> & aFamilies,
+ const SMDSAbs_ElementType anElemType)
+ {
+ anElemFamMap.Clear();
+ list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
+ while ( aFamsIter != aFamilies.end() )
+ {
+ if ((*aFamsIter)->GetType() != anElemType) {
+ aFamsIter++;
+ }
+ else {
+ int aFamId = (*aFamsIter)->GetId();
+ const ElementsSet& anElems = (*aFamsIter)->GetElements();
+ ElementsSet::const_iterator anElemsIter = anElems.begin();
+ for (; anElemsIter != anElems.end(); anElemsIter++)
+ {
+ anElemFamMap.Bind( (Standard_Address)*anElemsIter, aFamId );
+ }
+ // remove a family from the list
+ aFamilies.erase( aFamsIter++ );
+ }
}
}
- MESSAGE ( " mdim " << mdim );
+ //================================================================================
+ /*!
+ * \brief For an element, return family ID found in the map or a default one
+ */
+ //================================================================================
- /* creation du maillage */
- //mdim=3;
- sprintf(nommaa,"Mesh %d",numero);
- SCRUTE(nommaa);
- ret = MEDmaaCr(myFileId,nommaa,mdim);
+ int getFamilyId( const TElemFamilyMap & anElemFamMap,
+ const SMDS_MeshElement* anElement,
+ const int aDefaultFamilyId)
+ {
+ if ( anElemFamMap.IsBound( (Standard_Address) anElement ))
+ return anElemFamMap( (Standard_Address) anElement );
- ASSERT(ret == 0);
- SCRUTE( ret );
-
- /* Combien de noeuds ? */
- nnoe = myMesh->NbNodes();
- //SCRUTE(nnoe);
- /* Combien de mailles, faces ou aretes ? */
- for (i=0;i<MED_NBR_GEOMETRIE_MAILLE;i++)
- nmailles[i]=0;
-
- Standard_Integer nb_of_nodes, nb_of_faces, nb_of_edges;
- vector<int> elem_Id[MED_NBR_GEOMETRIE_MAILLE];
-
- SMDS_MeshEdgesIterator itEdges(myMesh);
- nb_of_edges = myMesh->NbEdges();
- for (;itEdges.More();itEdges.Next()) {
- const Handle(SMDS_MeshElement)& elem = itEdges.Value();
+ return aDefaultFamilyId;
+ }
- nb_of_nodes = elem->NbNodes();
+ //================================================================================
+ /*!
+ * \brief Returns iterator on sub-meshes
+ */
+ //================================================================================
+
+ SMESHDS_SubMeshIteratorPtr getIterator( std::vector<SMESHDS_SubMesh*>& mySubMeshes )
+ {
+ return SMESHDS_SubMeshIteratorPtr
+ ( new SMDS_SetIterator
+ < const SMESHDS_SubMesh*, std::vector< SMESHDS_SubMesh* >::iterator >( mySubMeshes.begin(),
+ mySubMeshes.end() ));
+ }
+}
- switch (nb_of_nodes) {
- case 2 : {
- elem_Id[1].push_back(elem->GetID());
- nmailles[1]++;
- break;
- }
- case 3 : {
- elem_Id[2].push_back(elem->GetID());
- nmailles[2]++;
- break;
+Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
+{
+ Status aResult = DRS_OK;
+ try {
+ //MESSAGE("Perform - myFile : "<<myFile);
+
+ // Creating the MED mesh for corresponding SMDS structure
+ //-------------------------------------------------------
+ string aMeshName;
+ if (myMeshId != -1) {
+ ostringstream aMeshNameStr;
+ aMeshNameStr<<myMeshId;
+ aMeshName = aMeshNameStr.str();
+ } else {
+ aMeshName = myMeshName;
}
- }
- }
+ // Mesh dimension definition
- SMDS_MeshFacesIterator itFaces(myMesh);
- nb_of_faces = myMesh->NbFaces();
- for (;itFaces.More();itFaces.Next()) {
- const Handle(SMDS_MeshElement)& elem = itFaces.Value();
+ TInt aMeshDimension = 0;
+ if ( myMesh->NbEdges() > 0 )
+ aMeshDimension = 1;
+ if ( myMesh->NbFaces() > 0 )
+ aMeshDimension = 2;
+ if ( myMesh->NbVolumes() > 0 )
+ aMeshDimension = 3;
- nb_of_nodes = elem->NbNodes();
+ TInt aSpaceDimension = 3;
+ TCoordHelperPtr aCoordHelperPtr;
+ {
+ bool anIsXDimension = false;
+ bool anIsYDimension = false;
+ bool anIsZDimension = false;
+ if ( myAutoDimension && aMeshDimension < 3 )
+ {
+ SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator();
+ double aBounds[6];
+ if(aNodesIter->more()){
+ const SMDS_MeshNode* aNode = aNodesIter->next();
+ aBounds[0] = aBounds[1] = aNode->X();
+ aBounds[2] = aBounds[3] = aNode->Y();
+ aBounds[4] = aBounds[5] = aNode->Z();
+ }
+ while(aNodesIter->more()){
+ const SMDS_MeshNode* aNode = aNodesIter->next();
+ aBounds[0] = min(aBounds[0],aNode->X());
+ aBounds[1] = max(aBounds[1],aNode->X());
+
+ aBounds[2] = min(aBounds[2],aNode->Y());
+ aBounds[3] = max(aBounds[3],aNode->Y());
+
+ aBounds[4] = min(aBounds[4],aNode->Z());
+ aBounds[5] = max(aBounds[5],aNode->Z());
+ }
+
+ double EPS = 1.0E-7;
+ TopoDS_Shape mainShape = myMesh->ShapeToMesh();
+ bool hasShapeToMesh = ( myMesh->SubMeshIndices().size() > 1 );
+ if ( !mainShape.IsNull() && hasShapeToMesh )
+ {
+ // define EPS by max tolerance of the mainShape (IPAL53097)
+ TopExp_Explorer subShape;
+ for ( subShape.Init( mainShape, TopAbs_FACE ); subShape.More(); subShape.Next() ) {
+ EPS = Max( EPS, BRep_Tool::Tolerance( TopoDS::Face( subShape.Current() )));
+ }
+ for ( subShape.Init( mainShape, TopAbs_EDGE ); subShape.More(); subShape.Next() ) {
+ EPS = Max( EPS, BRep_Tool::Tolerance( TopoDS::Edge( subShape.Current() )));
+ }
+ for ( subShape.Init( mainShape, TopAbs_VERTEX ); subShape.More(); subShape.Next() ) {
+ EPS = Max( EPS, BRep_Tool::Tolerance( TopoDS::Vertex( subShape.Current() )));
+ }
+ EPS *= 2.;
+ }
+ anIsXDimension = (aBounds[1] - aBounds[0]) + abs(aBounds[1]) + abs(aBounds[0]) > EPS;
+ anIsYDimension = (aBounds[3] - aBounds[2]) + abs(aBounds[3]) + abs(aBounds[2]) > EPS;
+ anIsZDimension = (aBounds[5] - aBounds[4]) + abs(aBounds[5]) + abs(aBounds[4]) > EPS;
+ aSpaceDimension = Max( aMeshDimension, anIsXDimension + anIsYDimension + anIsZDimension );
+ if ( !aSpaceDimension )
+ aSpaceDimension = 3;
+ // PAL16857(SMESH not conform to the MED convention):
+ if ( aSpaceDimension == 2 && anIsZDimension ) // 2D only if mesh is in XOY plane
+ aSpaceDimension = 3;
+ // PAL18941(a saved study with a mesh belong Z is opened and the mesh is belong X)
+ if ( aSpaceDimension == 1 && !anIsXDimension ) {// 1D only if mesh is along OX
+ if ( anIsYDimension ) {
+ aSpaceDimension = 2;
+ anIsXDimension = true;
+ } else {
+ aSpaceDimension = 3;
+ }
+ }
+ }
- switch (nb_of_nodes) {
- case 3 : {
- elem_Id[3].push_back(elem->GetID());
- nmailles[3]++;
- break;
- }
- case 4 : {
- elem_Id[5].push_back(elem->GetID());
- nmailles[5]++;
- break;
- }
- case 6 : {
- elem_Id[4].push_back(elem->GetID());
- nmailles[4]++;
- break;
- }
+ SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator();
+ switch ( aSpaceDimension ) {
+ case 3:
+ aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYZGetCoord,aXYZName));
+ break;
+ case 2:
+ if(anIsXDimension && anIsYDimension)
+ aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYGetCoord,aXYName));
+ if(anIsYDimension && anIsZDimension)
+ aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aYZGetCoord,aYZName));
+ if(anIsXDimension && anIsZDimension)
+ aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXZGetCoord,aXZName));
+ break;
+ case 1:
+ if(anIsXDimension)
+ aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXGetCoord,aXName));
+ if(anIsYDimension)
+ aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aYGetCoord,aYName));
+ if(anIsZDimension)
+ aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aZGetCoord,aZName));
+ break;
+ }
}
- }
-
- SMDS_MeshVolumesIterator itVolumes(myMesh);
- for (;itVolumes.More();itVolumes.Next()) {
- const Handle(SMDS_MeshElement)& elem = itVolumes.Value();
+ MED::PWrapper myMed = CrWrapperW(myFile);
+ PMeshInfo aMeshInfo = myMed->CrMeshInfo(aMeshDimension,aSpaceDimension,aMeshName);
+ //MESSAGE("Add - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
+ myMed->SetMeshInfo(aMeshInfo);
+
+ // Storing SMDS groups and sub-meshes as med families
+ //----------------------------------------------------
+ int myNodesDefaultFamilyId = 0;
+ int my0DElementsDefaultFamilyId = 0;
+ int myBallsDefaultFamilyId = 0;
+ int myEdgesDefaultFamilyId = 0;
+ int myFacesDefaultFamilyId = 0;
+ int myVolumesDefaultFamilyId = 0;
+ int nbNodes = myMesh->NbNodes();
+ int nb0DElements = myMesh->Nb0DElements();
+ int nbBalls = myMesh->NbBalls();
+ int nbEdges = myMesh->NbEdges();
+ int nbFaces = myMesh->NbFaces();
+ int nbVolumes = myMesh->NbVolumes();
+ if (myDoGroupOfNodes) myNodesDefaultFamilyId = REST_NODES_FAMILY;
+ if (myDoGroupOfEdges) myEdgesDefaultFamilyId = REST_EDGES_FAMILY;
+ if (myDoGroupOfFaces) myFacesDefaultFamilyId = REST_FACES_FAMILY;
+ if (myDoGroupOfVolumes) myVolumesDefaultFamilyId = REST_VOLUMES_FAMILY;
+ if (myDoGroupOf0DElems) my0DElementsDefaultFamilyId = REST_0DELEM_FAMILY;
+ if (myDoGroupOfBalls) myBallsDefaultFamilyId = REST_BALL_FAMILY;
+ if (myDoAllInGroups )
+ {
+ if (!myDoGroupOfEdges) myEdgesDefaultFamilyId = NIG_EDGES_FAMILY ;
+ if (!myDoGroupOfFaces) myFacesDefaultFamilyId = NIG_FACES_FAMILY ;
+ if (!myDoGroupOfVolumes) myVolumesDefaultFamilyId = NIG_VOLS_FAMILY ;
+ if (!myDoGroupOf0DElems) my0DElementsDefaultFamilyId = NIG_0DELEM_FAMILY ;
+ if (!myDoGroupOfBalls) myBallsDefaultFamilyId = NIG_BALL_FAMILY ;
+ }
- nb_of_nodes = elem->NbNodes();
- switch (nb_of_nodes) {
- case 8 : {
- elem_Id[9].push_back(elem->GetID());
- nmailles[9]++;
- break;
+ //MESSAGE("Perform - aFamilyInfo");
+ list<DriverMED_FamilyPtr> aFamilies;
+ if (myAllSubMeshes) {
+ aFamilies = DriverMED_Family::MakeFamilies
+ (myMesh->SubMeshes(), myGroups,
+ myDoGroupOfNodes && nbNodes,
+ myDoGroupOfEdges && nbEdges,
+ myDoGroupOfFaces && nbFaces,
+ myDoGroupOfVolumes && nbVolumes,
+ myDoGroupOf0DElems && nb0DElements,
+ myDoGroupOfBalls && nbBalls,
+ myDoAllInGroups);
}
+ else {
+ aFamilies = DriverMED_Family::MakeFamilies
+ (getIterator( mySubMeshes ), myGroups,
+ myDoGroupOfNodes && nbNodes,
+ myDoGroupOfEdges && nbEdges,
+ myDoGroupOfFaces && nbFaces,
+ myDoGroupOfVolumes && nbVolumes,
+ myDoGroupOf0DElems && nb0DElements,
+ myDoGroupOfBalls && nbBalls,
+ myDoAllInGroups);
}
- }
-
-
-
- /****************************************************************************
- * ECRITURE DES NOEUDS *
- ****************************************************************************/
- MESSAGE("(************************)");
- MESSAGE("(* NOEUDS DU MAILLAGE : *)");
- MESSAGE("(************************)");
-
- /* Allocations memoires */
- /* table des coordonnees
- profil : (dimension * nombre de noeuds ) */
- coo = (med_float*) malloc(sizeof(med_float)*nnoe*mdim);
- /* table des numeros, des numeros de familles des noeuds
- profil : (nombre de noeuds) */
- numnoe = (med_int*) malloc(sizeof(med_int)*nnoe);
- nufano = (med_int*) malloc(sizeof(med_int)*nnoe);
- /* table des noms des noeuds
- profil : (nnoe*MED_TAILLE_PNOM+1) */
- nomnoe ="";
-
- /* PN pour aster, il faut une famille 0 pour les noeuds et une autre pour les elements*/
- /* PN : Creation de la famille 0 */
- char * nomfam="FAMILLE_0";
- char *attdes="";
- char *gro=0;
- med_int ngro=0;
- med_int natt=1;
- med_int attide = 0;
- med_int attval=0;
- med_int numfam = 0;
- med_int attvalabs=1;
- ret = MEDfamCr(myFileId,nommaa,nomfam,numfam, &attide,&attval,attdes,natt,gro,ngro);
- ASSERT(ret == 0);
-
-
- /* PN : FIN Creation de la famille 0 */
-
- map < int, int > mapNoeud;
- typedef pair<set<int>::iterator, bool> IsFamily;
- int nbFamillesNoeud;
-
-
- i = 0;
- set<int> FamilySet;
- nbFamillesNoeud = 0;
- int verifienbnoeuds = 0;
- med_int* rien=0;
-
- SMDS_MeshNodesIterator itNodes(myMesh);
- for (;itNodes.More();itNodes.Next())
+ list<DriverMED_FamilyPtr>::iterator aFamsIter;
+ for (aFamsIter = aFamilies.begin(); aFamsIter != aFamilies.end(); aFamsIter++)
{
- const Handle(SMDS_MeshElement)& elem = itNodes.Value();
- const Handle(SMDS_MeshNode)& node = myMesh->GetNode(1,elem);
-
- if(mdim==3){
- coo[i*3]=node->X();
- coo[i*3+1]=node->Y();
- coo[i*3+2]=node->Z();
- } else if(mdim==2) {
- if ( dimX ) {
- coo[i*2]=node->Y();
- coo[i*2+1]=node->Z();
- }
- if ( dimY ) {
- coo[i*2]=node->X();
- coo[i*2+1]=node->Z();
- }
- if ( dimZ ) {
- coo[i*2]=node->X();
- coo[i*2+1]=node->Y();
- }
- } else {
- if ( dimX ) {
- coo[i*2]=node->Y();
- coo[i*2+1]=node->Z();
- }
- if ( dimY ) {
- coo[i*2]=node->X();
- coo[i*2+1]=node->Z();
- }
- if ( dimZ ) {
- coo[i*2]=node->X();
- coo[i*2+1]=node->Y();
- }
- }
- mapNoeud[node->GetID()] = i+1;
-
- // renvoie 0 pour les noeuds internes du volume
- int numfamille=node->GetPosition()->GetShapeId();
- nufano[i]=numfamille;
-
- //SCRUTE(i);
- //SCRUTE(nufano[i]);
- //SCRUTE(coo[i*3]);
- //SCRUTE(coo[i*3+1]);
- //SCRUTE(coo[i*3+2]);
- if ( nufano[i] != 0 )
- {
- IsFamily deja = FamilySet.insert(nufano[i]); // insert if new, or gives existant
- if (deja.second) // actually inserted
- {
- char famille[MED_TAILLE_NOM+1];
- sprintf(famille,"F%d",nufano[i]);
- // CreateFamily(strdup(nommaa),strdup(famille),nufano[i],attvalabs++);
- attvalabs++;
- CreateFamily(strdup(nommaa),strdup(famille),nufano[i],numfamille);
- //MESSAGE("---famille-noeud--- "<<nbFamillesNoeud<<" "<<nufano[i]);
- nbFamillesNoeud++;
- }
- }
-
- i++;
- verifienbnoeuds ++;
+ PFamilyInfo aFamilyInfo = (*aFamsIter)->GetFamilyInfo(myMed,aMeshInfo);
+ myMed->SetFamilyInfo(aFamilyInfo);
}
- ret = MEDnoeudsEcr(myFileId,nommaa,mdim,coo,mode_coo,MED_CART,
- nomcoo,unicoo,nomnoe,MED_FAUX,rien,MED_FAUX,
- nufano,nnoe,MED_REMP);
- ASSERT(ret == 0);
- MESSAGE("--- Creation de " << verifienbnoeuds << " noeuds");
- ASSERT(verifienbnoeuds == nnoe);
- MESSAGE("--- Creation de " << nbFamillesNoeud << " familles de noeuds");
-
- /* liberation memoire */
- free(coo);
- free(numnoe);
- free(nufano);
-
- /****************************************************************************
- * ECRITURE DES ELEMENTS *
- ****************************************************************************/
- MESSAGE("(**************************)");
- MESSAGE("(* ELEMENTS DU MAILLAGE : *)");
- MESSAGE("(**************************)");
-
- /* Ecriture des connectivites, noms, numeros des mailles */
- if (ret == 0)
+ // Storing SMDS nodes to the MED file for the MED mesh
+ //----------------------------------------------------
+#ifdef _EDF_NODE_IDS_
+ typedef map<TInt,TInt> TNodeIdMap;
+ TNodeIdMap aNodeIdMap;
+#endif
+ const EModeSwitch theMode = eFULL_INTERLACE;
+ const ERepere theSystem = eCART;
+ const EBooleen theIsElemNum = eVRAI;
+ const EBooleen theIsElemNames = eFAUX;
+ const EConnectivite theConnMode = eNOD;
+
+ TInt aNbNodes = myMesh->NbNodes();
+ PNodeInfo aNodeInfo = myMed->CrNodeInfo(aMeshInfo, aNbNodes,
+ theMode, theSystem, theIsElemNum, theIsElemNames);
+
+ // find family numbers for nodes
+ TElemFamilyMap anElemFamMap;
+ fillElemFamilyMap( anElemFamMap, aFamilies, SMDSAbs_Node );
+
+ for (TInt iNode = 0; aCoordHelperPtr->Next(); iNode++)
{
- int nbFamillesElts =0;
- Handle(SMESHDS_Mesh) mySMESHDSMesh = Handle(SMESHDS_Mesh)::DownCast(myMesh);
- TopTools_IndexedMapOfShape myIndexToShape;
- TopExp::MapShapes(mySMESHDSMesh->ShapeToMesh(),myIndexToShape);
-
- map < int, int > mapFamille;
-
- if (besoinfamilledemaille == 1)
- {
- int t;
- for (t =1; t <= myIndexToShape.Extent(); t++)
- {
- const TopoDS_Shape S = myIndexToShape(t);
- if (mySMESHDSMesh->HasMeshElements(S))
- {
- //MESSAGE ("********* Traitement de la Famille "<<-t);
-
- Handle(SMESHDS_SubMesh) SM = mySMESHDSMesh->MeshElements(S);
- const TColStd_ListOfInteger& indElt = SM->GetIDElements();
- TColStd_ListIteratorOfListOfInteger ite(indElt);
-
- bool plein=false;
- for (; ite.More(); ite.Next())
- {
- int eltId = ite.Value();
- mapFamille [eltId] = - t;
- plein=true;
- }
- if (plein)
- {
- nbFamillesElts++;
- char famille[MED_TAILLE_NOM+1];
- sprintf(famille,"E%d",t);
- CreateFamily(strdup(nommaa),strdup(famille),-t,attvalabs++);
- }
- }
- }
- }
-
- int indice=1;
- for (i=0;i<MED_NBR_GEOMETRIE_MAILLE;i++)
- {
- if (nmailles[i] > 0 && ret == 0)
- {
- MESSAGE ( " Start "<<typmai[i]);
-
- /* dimension de la maille */
- edim = typmai[i] / 100;
- nsup = 0;
- if (mdim == 2 || mdim == 3)
- if (edim == 1) nsup = 1;
- if (mdim == 3)
- if (edim == 2) nsup = 1;
- //SCRUTE(nsup);
-
- taille = nsup+typmai[i]%100;
- //SCRUTE(taille);
-
- /* allocation memoire */
- connectivite = (med_int*)malloc(sizeof(med_int)* taille*nmailles[i]);
- nomele = (char*)malloc(sizeof(char)*MED_TAILLE_PNOM* nmailles[i]+1);
- numele = (med_int*)malloc(sizeof(med_int)* nmailles[i]);
- nufael = (med_int*)malloc(sizeof(med_int)* nmailles[i]);
- nomele="";
- nbNodes=typmai[i]%100;
-
- for (j=0;j<nmailles[i];j++)
- {
- myId = elem_Id[i][j];
- const Handle(SMDS_MeshElement)& elem = myMesh->FindElement(myId);
- //*(numele+j) = myId;
- *(numele+j) = indice ++;
-
- for (k=0; k<nbNodes; k++)
- {
- *(connectivite+j*taille+k) = mapNoeud[elem->GetConnection(k+1)];
- //SCRUTE(*(connectivite+j*taille+k));
- }
- if (nsup) *(connectivite+j*taille + nbNodes) = 0;
-
- if (besoinfamilledemaille == 1)
- {
- if (mapFamille.find(myId)!=mapFamille.end())
- {
- nufael[j]=mapFamille[myId];
- }
- else
- {
- nufael[j]=0;
- }
- }
- else
- {
- nufael[j]=0;
- }
-
- //SCRUTE(myId);
- //SCRUTE(j);
- //SCRUTE(nufael[j]);
- }
-
- /* ecriture des données */
-
- med_int* rien=0;
- ret=MEDelementsEcr( myFileId,nommaa,mdim,connectivite,mode_coo,nomele,MED_FAUX,numele,
- MED_VRAI,nufael,nmailles[i],MED_MAILLE,typmai[i],typ_con,MED_REMP);
- ASSERT(ret == 0);
- //SCRUTE(ret);
-
- if (ret < 0) MESSAGE(">> ERREUR : ecriture des mailles \n");
-
- /* liberation memoire */
- free(connectivite);
- free(numele);
- free(nufael);
- MESSAGE ( " End "<<typmai[i]);
- }
- };
- MESSAGE("--- Creation de " << nbFamillesElts << " familles d elements");
+ // coordinates
+ TCoordSlice aTCoordSlice = aNodeInfo->GetCoordSlice( iNode );
+ for(TInt iCoord = 0; iCoord < aSpaceDimension; iCoord++){
+ aTCoordSlice[iCoord] = aCoordHelperPtr->GetCoord(iCoord);
+ }
+ // node number
+ int aNodeID = aCoordHelperPtr->GetID();
+ aNodeInfo->SetElemNum( iNode, aNodeID );
+#ifdef _EDF_NODE_IDS_
+ aNodeIdMap.insert( aNodeIdMap.end(), make_pair( aNodeID, iNode+1 ));
+#endif
+ // family number
+ const SMDS_MeshNode* aNode = aCoordHelperPtr->GetNode();
+ int famNum = getFamilyId( anElemFamMap, aNode, myNodesDefaultFamilyId );
+ aNodeInfo->SetFamNum( iNode, famNum );
+ }
+ anElemFamMap.Clear();
+ // coordinate names and units
+ for (TInt iCoord = 0; iCoord < aSpaceDimension; iCoord++) {
+ aNodeInfo->SetCoordName( iCoord, aCoordHelperPtr->GetName(iCoord));
+ aNodeInfo->SetCoordUnit( iCoord, aCoordHelperPtr->GetUnit(iCoord));
}
- /****************************************************************************
- * FERMETURE DU FICHIER *
- ****************************************************************************/
+ //MESSAGE("Perform - aNodeInfo->GetNbElem() = "<<aNbNodes);
+ myMed->SetNodeInfo(aNodeInfo);
+ aNodeInfo.reset(); // free memory used for arrays
- ret = MEDfermer(myFileId);
- if (ret != 0)
- fprintf(stderr,">> ERREUR : erreur a la fermeture du fichier %s\n",file2Read);
- MESSAGE ("fichier ferme");
+ // Storing SMDS elements to the MED file for the MED mesh
+ //-------------------------------------------------------
+ // Write one element type at once in order to minimize memory usage (PAL19276)
+ const SMDS_MeshInfo& nbElemInfo = myMesh->GetMeshInfo();
-}
+ // poly elements are not supported by med-2.1
+ bool polyTypesSupported = ( myMed->CrPolygoneInfo(aMeshInfo,eMAILLE,ePOLYGONE,0,0).get() != 0 );
+ TInt nbPolygonNodes = 0, nbPolyhedronNodes = 0, nbPolyhedronFaces = 0;
-void DriverMED_W_SMESHDS_Mesh::CreateFamily(char* nommaa, char* famille, int i,med_int k) {
+ // nodes on VERTEXes where 0D elements are absent
+ std::vector<const SMDS_MeshElement*> nodesOf0D;
+ std::vector< SMDS_ElemIteratorPtr > iterVec;
+ SMDS_ElemIteratorPtr iterVecIter;
+ if ( myAddODOnVertices && getNodesOfMissing0DOnVert( myMesh, nodesOf0D ))
+ {
+ iterVec.resize(2);
+ iterVec[0] = myMesh->elementsIterator( SMDSAbs_0DElement );
+ iterVec[1] = SMDS_ElemIteratorPtr
+ ( new SMDS_ElementVectorIterator( nodesOf0D.begin(), nodesOf0D.end() ));
+
+ typedef SMDS_IteratorOnIterators
+ < const SMDS_MeshElement *, std::vector< SMDS_ElemIteratorPtr > > TItIterator;
+ iterVecIter = SMDS_ElemIteratorPtr( new TItIterator( iterVec ));
+ }
- med_int ngro=0;
- med_int natt;
+ // collect info on all geom types
+
+ list< TElemTypeData > aTElemTypeDatas;
+
+ EEntiteMaillage anEntity = eMAILLE;
+#ifdef _ELEMENTS_BY_DIM_
+ anEntity = eNOEUD_ELEMENT;
+#endif
+ aTElemTypeDatas.push_back(TElemTypeData(anEntity,
+ ePOINT1,
+ nbElemInfo.Nb0DElements() + nodesOf0D.size(),
+ SMDSAbs_0DElement));
+#ifdef _ELEMENTS_BY_DIM_
+ anEntity = eSTRUCT_ELEMENT;
+#endif
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ eBALL,
+ nbElemInfo.NbBalls(),
+ SMDSAbs_Ball));
+#ifdef _ELEMENTS_BY_DIM_
+ anEntity = eARETE;
+#endif
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ eSEG2,
+ nbElemInfo.NbEdges( ORDER_LINEAR ),
+ SMDSAbs_Edge));
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ eSEG3,
+ nbElemInfo.NbEdges( ORDER_QUADRATIC ),
+ SMDSAbs_Edge));
+#ifdef _ELEMENTS_BY_DIM_
+ anEntity = eFACE;
+#endif
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ eTRIA3,
+ nbElemInfo.NbTriangles( ORDER_LINEAR ),
+ SMDSAbs_Face));
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ eTRIA6,
+ nbElemInfo.NbTriangles( ORDER_QUADRATIC ) -
+ nbElemInfo.NbBiQuadTriangles(),
+ SMDSAbs_Face));
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ eTRIA7,
+ nbElemInfo.NbBiQuadTriangles(),
+ SMDSAbs_Face));
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ eQUAD4,
+ nbElemInfo.NbQuadrangles( ORDER_LINEAR ),
+ SMDSAbs_Face));
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ eQUAD8,
+ nbElemInfo.NbQuadrangles( ORDER_QUADRATIC ) -
+ nbElemInfo.NbBiQuadQuadrangles(),
+ SMDSAbs_Face));
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ eQUAD9,
+ nbElemInfo.NbBiQuadQuadrangles(),
+ SMDSAbs_Face));
+ if ( polyTypesSupported ) {
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ ePOLYGONE,
+ nbElemInfo.NbPolygons( ORDER_LINEAR ),
+ SMDSAbs_Face));
+ // we need one more loop on poly elements to count nb of their nodes
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ ePOLYGONE,
+ nbElemInfo.NbPolygons( ORDER_LINEAR ),
+ SMDSAbs_Face));
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ ePOLYGON2,
+ nbElemInfo.NbPolygons( ORDER_QUADRATIC ),
+ SMDSAbs_Face));
+ // we need one more loop on QUAD poly elements to count nb of their nodes
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ ePOLYGON2,
+ nbElemInfo.NbPolygons( ORDER_QUADRATIC ),
+ SMDSAbs_Face));
+ }
+#ifdef _ELEMENTS_BY_DIM_
+ anEntity = eMAILLE;
+#endif
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ eTETRA4,
+ nbElemInfo.NbTetras( ORDER_LINEAR ),
+ SMDSAbs_Volume));
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ eTETRA10,
+ nbElemInfo.NbTetras( ORDER_QUADRATIC ),
+ SMDSAbs_Volume));
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ ePYRA5,
+ nbElemInfo.NbPyramids( ORDER_LINEAR ),
+ SMDSAbs_Volume));
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ ePYRA13,
+ nbElemInfo.NbPyramids( ORDER_QUADRATIC ),
+ SMDSAbs_Volume));
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ ePENTA6,
+ nbElemInfo.NbPrisms( ORDER_LINEAR ),
+ SMDSAbs_Volume));
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ ePENTA15,
+ nbElemInfo.NbQuadPrisms(),
+ SMDSAbs_Volume));
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ ePENTA18,
+ nbElemInfo.NbBiQuadPrisms(),
+ SMDSAbs_Volume));
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ eHEXA8,
+ nbElemInfo.NbHexas( ORDER_LINEAR ),
+ SMDSAbs_Volume));
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ eHEXA20,
+ nbElemInfo.NbHexas( ORDER_QUADRATIC )-
+ nbElemInfo.NbTriQuadHexas(),
+ SMDSAbs_Volume));
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ eHEXA27,
+ nbElemInfo.NbTriQuadHexas(),
+ SMDSAbs_Volume));
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ eOCTA12,
+ nbElemInfo.NbHexPrisms(),
+ SMDSAbs_Volume));
+ if ( polyTypesSupported ) {
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ ePOLYEDRE,
+ nbElemInfo.NbPolyhedrons(),
+ SMDSAbs_Volume));
+ // we need one more loop on poly elements to count nb of their nodes
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ ePOLYEDRE,
+ nbElemInfo.NbPolyhedrons(),
+ SMDSAbs_Volume));
+ }
- natt=1;
- char attdes[MED_TAILLE_DESC+1];
- char gro[MED_TAILLE_LNOM+1];
- char fam2[MED_TAILLE_LNOM+1];
+ vector< bool > isElemFamMapBuilt( SMDSAbs_NbElementTypes, false );
- strcpy(attdes,"");
- strcpy(gro,"");
- strcpy(fam2,famille);
+ // loop on all geom types of elements
- med_int * attide=new med_int[1];
- med_int * attval=new med_int[1];
- attide[0] = k;
- attval[0] = k;
+ list< TElemTypeData >::iterator aElemTypeData = aTElemTypeDatas.begin();
+ for ( ; aElemTypeData != aTElemTypeDatas.end(); ++aElemTypeData )
+ {
+ if ( aElemTypeData->_nbElems == 0 )
+ continue;
+
+ int defaultFamilyId = 0;
+ switch ( aElemTypeData->_smdsType ) {
+ case SMDSAbs_0DElement: defaultFamilyId = my0DElementsDefaultFamilyId; break;
+ case SMDSAbs_Ball: defaultFamilyId = myBallsDefaultFamilyId; break;
+ case SMDSAbs_Edge: defaultFamilyId = myEdgesDefaultFamilyId; break;
+ case SMDSAbs_Face: defaultFamilyId = myFacesDefaultFamilyId; break;
+ case SMDSAbs_Volume: defaultFamilyId = myVolumesDefaultFamilyId; break;
+ default:
+ continue;
+ }
+ // build map of family numbers for this type
+ if ( !isElemFamMapBuilt[ aElemTypeData->_smdsType ])
+ {
+ fillElemFamilyMap( anElemFamMap, aFamilies, aElemTypeData->_smdsType );
+ isElemFamMapBuilt[ aElemTypeData->_smdsType ] = true;
+ }
- //MESSAGE("-------- Creation de la Famille : "<< famille << "numero " << i << " --------------");
- med_int ret = MEDfamCr(myFileId, nommaa, fam2, i, attide, attval, attdes, natt, gro, ngro);
- ASSERT(ret==0);
- delete [] attide;
- delete [] attval;
+ // iterator on elements of a current type
+ SMDS_ElemIteratorPtr elemIterator;
+ int iElem = 0;
+
+ // Treat POLYGONs
+ // ---------------
+ if ( aElemTypeData->_geomType == ePOLYGONE ||
+ aElemTypeData->_geomType == ePOLYGON2 )
+ {
+ if ( aElemTypeData->_geomType == ePOLYGONE )
+ elemIterator = myMesh->elementEntityIterator( SMDSEntity_Polygon );
+ else
+ elemIterator = myMesh->elementEntityIterator( SMDSEntity_Quad_Polygon );
+
+ if ( nbPolygonNodes == 0 ) {
+ // Count nb of nodes
+ while ( elemIterator->more() ) {
+ const SMDS_MeshElement* anElem = elemIterator->next();
+ nbPolygonNodes += anElem->NbNodes();
+ if ( ++iElem == aElemTypeData->_nbElems )
+ break;
+ }
+ }
+ else {
+ // Store in med file
+ PPolygoneInfo aPolygoneInfo = myMed->CrPolygoneInfo(aMeshInfo,
+ aElemTypeData->_entity,
+ aElemTypeData->_geomType,
+ aElemTypeData->_nbElems,
+ nbPolygonNodes,
+ theConnMode, theIsElemNum,
+ theIsElemNames);
+ TElemNum & index = *(aPolygoneInfo->myIndex.get());
+ index[0] = 1;
+
+ while ( elemIterator->more() )
+ {
+ const SMDS_MeshElement* anElem = elemIterator->next();
+ // index
+ TInt aNbNodes = anElem->NbNodes();
+ index[ iElem+1 ] = index[ iElem ] + aNbNodes;
+
+ // connectivity
+ TConnSlice aTConnSlice = aPolygoneInfo->GetConnSlice( iElem );
+ for(TInt iNode = 0; iNode < aNbNodes; iNode++) {
+ const SMDS_MeshElement* aNode = anElem->GetNode( iNode );
+#ifdef _EDF_NODE_IDS_
+ aTConnSlice[ iNode ] = aNodeIdMap[aNode->GetID()];
+#else
+ aTConnSlice[ iNode ] = aNode->GetID();
+#endif
+ }
+ // element number
+ aPolygoneInfo->SetElemNum( iElem, anElem->GetID() );
+
+ // family number
+ int famNum = getFamilyId( anElemFamMap, anElem, defaultFamilyId );
+ aPolygoneInfo->SetFamNum( iElem, famNum );
+
+ if ( ++iElem == aPolygoneInfo->GetNbElem() )
+ break;
+ }
+ myMed->SetPolygoneInfo(aPolygoneInfo);
+
+ nbPolygonNodes = 0; // to treat next polygon type
+ }
+ }
-}
+ // Treat POLYEDREs
+ // ----------------
+ else if ( aElemTypeData->_geomType == ePOLYEDRE )
+ {
+ elemIterator = myMesh->elementGeomIterator( SMDSGeom_POLYHEDRA );
+
+ if ( nbPolyhedronNodes == 0 ) {
+ // Count nb of nodes
+ while ( elemIterator->more() ) {
+ const SMDS_MeshElement* anElem = elemIterator->next();
+ nbPolyhedronNodes += anElem->NbNodes();
+ nbPolyhedronFaces += anElem->NbFaces();
+ if ( ++iElem == aElemTypeData->_nbElems )
+ break;
+ }
+ }
+ else {
+ // Store in med file
+ PPolyedreInfo aPolyhInfo = myMed->CrPolyedreInfo(aMeshInfo,
+ aElemTypeData->_entity,
+ aElemTypeData->_geomType,
+ aElemTypeData->_nbElems,
+ nbPolyhedronFaces+1,
+ nbPolyhedronNodes,
+ theConnMode,
+ theIsElemNum,
+ theIsElemNames);
+ TElemNum & index = *(aPolyhInfo->myIndex.get());
+ TElemNum & faces = *(aPolyhInfo->myFaces.get());
+ TElemNum & conn = *(aPolyhInfo->myConn.get());
+ index[0] = 1;
+ faces[0] = 1;
+
+ TInt iFace = 0, iNode = 0;
+ while ( elemIterator->more() )
+ {
+ const SMDS_MeshElement* anElem = elemIterator->next();
+ const SMDS_MeshVolume *aPolyedre = myMesh->DownCast< SMDS_MeshVolume >( anElem );
+ if ( !aPolyedre ) continue;
+ // index
+ TInt aNbFaces = aPolyedre->NbFaces();
+ index[ iElem+1 ] = index[ iElem ] + aNbFaces;
+
+ // face index
+ for (TInt f = 1; f <= aNbFaces; ++f, ++iFace ) {
+ int aNbFaceNodes = aPolyedre->NbFaceNodes( f );
+ faces[ iFace+1 ] = faces[ iFace ] + aNbFaceNodes;
+ }
+ // connectivity
+ SMDS_ElemIteratorPtr nodeIt = anElem->nodesIterator();
+ while ( nodeIt->more() ) {
+ const SMDS_MeshElement* aNode = nodeIt->next();
+#ifdef _EDF_NODE_IDS_
+ conn[ iNode ] = aNodeIdMap[aNode->GetID()];
+#else
+ conn[ iNode ] = aNode->GetID();
+#endif
+ ++iNode;
+ }
+ // element number
+ aPolyhInfo->SetElemNum( iElem, anElem->GetID() );
+
+ // family number
+ int famNum = getFamilyId( anElemFamMap, anElem, defaultFamilyId );
+ aPolyhInfo->SetFamNum( iElem, famNum );
+
+ if ( ++iElem == aPolyhInfo->GetNbElem() )
+ break;
+ }
+ myMed->SetPolyedreInfo(aPolyhInfo);
+ }
+ } // if (aElemTypeData->_geomType == ePOLYEDRE )
+
+ // Treat BALLs
+ // ----------------
+ else if (aElemTypeData->_geomType == eBALL )
+ {
+ // allocate data arrays
+ PBallInfo aBallInfo = myMed->CrBallInfo( aMeshInfo, aElemTypeData->_nbElems );
+
+ elemIterator = myMesh->elementsIterator( SMDSAbs_Ball );
+ while ( elemIterator->more() )
+ {
+ const SMDS_MeshElement* anElem = elemIterator->next();
+ // connectivity
+ const SMDS_MeshElement* aNode = anElem->GetNode( 0 );
+#ifdef _EDF_NODE_IDS_
+ (*aBallInfo->myConn)[ iElem ] = aNodeIdMap[aNode->GetID()];
+#else
+ (*aBallInfo->myConn)[ iElem ] = aNode->GetID();
+#endif
+ // element number
+ aBallInfo->SetElemNum( iElem, anElem->GetID() );
+
+ // diameter
+ aBallInfo->myDiameters[ iElem ] =
+ static_cast<const SMDS_BallElement*>( anElem )->GetDiameter();
+
+ // family number
+ int famNum = getFamilyId( anElemFamMap, anElem, defaultFamilyId );
+ aBallInfo->SetFamNum( iElem, famNum );
+ ++iElem;
+ }
+ // store data in a file
+ myMed->SetBallInfo(aBallInfo);
+ }
+ else
+ {
+ // Treat standard types
+ // ---------------------
+ // allocate data arrays
+ PCellInfo aCellInfo = myMed->CrCellInfo( aMeshInfo,
+ aElemTypeData->_entity,
+ aElemTypeData->_geomType,
+ aElemTypeData->_nbElems,
+ theConnMode,
+ theIsElemNum,
+ theIsElemNames);
+
+ TInt aNbNodes = MED::GetNbNodes(aElemTypeData->_geomType);
+ elemIterator = myMesh->elementsIterator( aElemTypeData->_smdsType );
+ if ( aElemTypeData->_smdsType == SMDSAbs_0DElement && ! nodesOf0D.empty() )
+ elemIterator = iterVecIter;
+ while ( elemIterator->more() )
+ {
+ const SMDS_MeshElement* anElem = elemIterator->next();
+ if ( anElem->NbNodes() != aNbNodes || anElem->IsPoly() )
+ continue; // other geometry
+
+ // connectivity
+ TConnSlice aTConnSlice = aCellInfo->GetConnSlice( iElem );
+ for (TInt iNode = 0; iNode < aNbNodes; iNode++) {
+ const SMDS_MeshElement* aNode = anElem->GetNode( iNode );
+#ifdef _EDF_NODE_IDS_
+ aTConnSlice[ iNode ] = aNodeIdMap[aNode->GetID()];
+#else
+ aTConnSlice[ iNode ] = aNode->GetID();
+#endif
+ }
+ // element number
+ aCellInfo->SetElemNum( iElem, anElem->GetID() );
+
+ // family number
+ int famNum = getFamilyId( anElemFamMap, anElem, defaultFamilyId );
+ aCellInfo->SetFamNum( iElem, famNum );
+
+ if ( ++iElem == aCellInfo->GetNbElem() )
+ break;
+ }
+ // store data in a file
+ myMed->SetCellInfo(aCellInfo);
+ }
+ } // loop on geom types
+ }
+ catch(const std::exception& exc) {
+ INFOS("The following exception was caught:\n\t"<<exc.what());
+ throw;
+ }
+ catch(...) {
+ INFOS("Unknown exception was caught !!!");
+ throw;
+ }
+ myMeshId = -1;
+ myGroups.clear();
+ mySubMeshes.clear();
+ return aResult;
+}
+//================================================================================
+/*!
+ * \brief Returns nodes on VERTEXes where 0D elements are absent
+ */
+//================================================================================
+
+bool DriverMED_W_SMESHDS_Mesh::
+getNodesOfMissing0DOnVert(SMESHDS_Mesh* meshDS,
+ std::vector<const SMDS_MeshElement*>& nodes)
+{
+ nodes.clear();
+ for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
+ {
+ if ( meshDS->IndexToShape( i ).ShapeType() != TopAbs_VERTEX )
+ continue;
+ if ( SMESHDS_SubMesh* sm = meshDS->MeshElements(i) ) {
+ SMDS_NodeIteratorPtr nIt= sm->GetNodes();
+ while (nIt->more())
+ {
+ const SMDS_MeshNode* n = nIt->next();
+ if ( n->NbInverseElements( SMDSAbs_0DElement ) == 0 )
+ nodes.push_back( n );
+ }
+ }
+ }
+ return !nodes.empty();
+}