Salome HOME
ILMAB: export GEOM fields to MED file
authoreap <eap@opencascade.com>
Wed, 5 Mar 2014 15:37:55 +0000 (19:37 +0400)
committereap <eap@opencascade.com>
Wed, 5 Mar 2014 15:37:55 +0000 (19:37 +0400)
  Re-implement addition of 0D elements w/o modification of SMESHDS_Mesh

src/DriverMED/DriverMED_W_Field.cxx
src/DriverMED/DriverMED_W_Field.h
src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx
src/DriverMED/DriverMED_W_SMESHDS_Mesh.h
src/SMESH/SMESH_Mesh.cxx
src/SMESH/SMESH_Mesh.hxx
src/SMESH_I/SMESH_Mesh_i.cxx

index 721396f..9389275 100644 (file)
@@ -27,6 +27,7 @@
 #include "DriverMED_W_Field.h"
 
 #include "DriverMED.hxx"
+#include "DriverMED_W_SMESHDS_Mesh.h"
 #include "MED_Factory.hxx"
 #include "MED_Utilities.hxx"
 #include "MED_Wrapper.hxx"
@@ -108,6 +109,20 @@ bool DriverMED_W_Field::Set(SMESHDS_Mesh *      mesh,
 
       _nbElemsByGeom.push_back( make_pair( geom, nbElems + _nbElemsByGeom.back().second ));
     }
+    // add nodes of missing 0D elements on VERTEXes
+    if ( _addODOnVertices && _elemType == SMDSAbs_0DElement )
+    {
+      std::vector< const SMDS_MeshElement* >& nodes = _elemsByGeom[SMDSEntity_Node];
+      if ( nodes.empty() )
+        DriverMED_W_SMESHDS_Mesh::getNodesOfMissing0DOnVert( myMesh, nodes );
+      if ( !nodes.empty() )
+      {
+        if ( _nbElemsByGeom.size() == 1 )
+          _nbElemsByGeom.push_back( make_pair( SMDSEntity_0D, 0));
+        _nbElemsByGeom.push_back( make_pair( SMDSEntity_Node,
+                                             nodes.size() + _nbElemsByGeom.back().second ));
+      }
+    }
 
     // sort elements by their geometry
     int iGeoType, nbGeomTypes = _nbElemsByGeom.size() - 1;
@@ -119,6 +134,7 @@ bool DriverMED_W_Field::Set(SMESHDS_Mesh *      mesh,
         nbElems  = _nbElemsByGeom[iG].second - _nbElemsByGeom[iG-1].second;
         _elemsByGeom[ iGeoType ].reserve( nbElems );
       }
+      iGeoType = _nbElemsByGeom[1].first; // for missing 0D
       if ( _elemsByGeom[ iGeoType ].empty() )
       {
         nbElems = mesh->GetMeshInfo().NbElements( _elemType );
@@ -283,6 +299,14 @@ Driver_Mesh::Status DriverMED_W_Field::Perform()
   }
   medFile->SetFieldInfo( fieldInfo );
 
+  // specific treatment of added 0D elements
+  if ( _nbElemsByGeom.size()   == 3 &&
+       _nbElemsByGeom[1].first == SMDSEntity_0D )
+  {
+    _nbElemsByGeom[1].second += _nbElemsByGeom[2].second;
+    _nbElemsByGeom.resize( 2 );
+  }
+
   // create a time stamp
   MED::TGeom2Size type2nb;
   for ( size_t iG = 1; iG < _nbElemsByGeom.size(); ++iG )
index 56b907d..0749123 100644 (file)
@@ -41,6 +41,8 @@ class MESHDRIVERMED_EXPORT DriverMED_W_Field: public Driver_SMESHDS_Mesh
 
   DriverMED_W_Field();
 
+  void AddODOnVertices(bool toAdd) { _addODOnVertices = toAdd; }
+
   bool Set(SMESHDS_Mesh *      mesh,
            const std::string & fieldName,
            SMDSAbs_ElementType type,
@@ -72,6 +74,7 @@ class MESHDRIVERMED_EXPORT DriverMED_W_Field: public Driver_SMESHDS_Mesh
   std::vector< double >      _dblValues;
   std::vector< int >         _intValues;
   int                        _dt, _it;
+  bool                       _addODOnVertices;
 
   std::vector< const SMDS_MeshElement* >              _elemsByGeom[SMDSEntity_Last];
   std::vector< std::pair< SMDSAbs_EntityType, int > > _nbElemsByGeom;
index f46f225..47fa68b 100644 (file)
 #include "DriverMED_Family.h"
 #include "MED_Factory.hxx"
 #include "MED_Utilities.hxx"
+#include "SMDS_IteratorOnIterators.hxx"
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMDS_SetIterator.hxx"
 #include "SMESHDS_Mesh.hxx"
 
 #include <utilities.h>
@@ -421,7 +423,6 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
     if (myDoGroupOfBalls && nbBalls) myBallsDefaultFamilyId = REST_BALL_FAMILY;
 
     MESSAGE("Perform - aFamilyInfo");
-    //cout << " DriverMED_Family::MakeFamilies() " << endl;
     list<DriverMED_FamilyPtr> aFamilies;
     if (myAllSubMeshes) {
       aFamilies = DriverMED_Family::MakeFamilies
@@ -442,7 +443,6 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
          myDoGroupOf0DElems && nb0DElements,
          myDoGroupOfBalls   && nbBalls);
     }
-    //cout << " myMed->SetFamilyInfo() " << endl;
     list<DriverMED_FamilyPtr>::iterator aFamsIter;
     for (aFamsIter = aFamilies.begin(); aFamsIter != aFamilies.end(); aFamsIter++)
     {
@@ -463,7 +463,6 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
     const EConnectivite theConnMode    = eNOD;
 
     TInt aNbNodes = myMesh->NbNodes();
-    //cout << " myMed->CrNodeInfo() aNbNodes = " << aNbNodes << endl;
     PNodeInfo aNodeInfo = myMed->CrNodeInfo(aMeshInfo, aNbNodes,
                                             theMode, theSystem, theIsElemNum, theIsElemNames);
 
@@ -514,6 +513,22 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
     bool polyTypesSupported = myMed->CrPolygoneInfo(aMeshInfo,eMAILLE,ePOLYGONE,0,0);
     TInt nbPolygonNodes = 0, nbPolyhedronNodes = 0, nbPolyhedronFaces = 0;
 
+    // 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 ));
+    }
+
     // collect info on all geom types
 
     list< TElemTypeData > aTElemTypeDatas;
@@ -524,7 +539,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
 #endif
     aTElemTypeDatas.push_back(TElemTypeData(anEntity,
                                             ePOINT1,
-                                            nbElemInfo.Nb0DElements(),
+                                            nbElemInfo.Nb0DElements() + nodesOf0D.size(),
                                             SMDSAbs_0DElement));
 #ifdef _ELEMENTS_BY_DIM_
     anEntity = eSTRUCT_ELEMENT;
@@ -873,6 +888,8 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
 
         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();
@@ -921,3 +938,31 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
   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();
+}
index fc68df5..d817c3f 100644 (file)
@@ -35,6 +35,7 @@
 #include <string>
 #include <list>
 #include <map>
+#include <vector>
 
 class SMESHDS_Mesh;
 class SMESHDS_GroupBase;
@@ -49,10 +50,9 @@ class MESHDRIVERMED_EXPORT DriverMED_W_SMESHDS_Mesh: public Driver_SMESHDS_Mesh
   virtual void SetFile(const std::string& theFileName);
   void SetFile(const std::string& theFileName, MED::EVersion theId);
   void SetAutoDimension(bool toFindOutDimension) { myAutoDimension = toFindOutDimension; }
+
   static std::string GetVersionString(const MED::EVersion theVersion, int theNbDigits=2);
 
-  /*! sets file name; only for usage with Add(), not Write()
-   */
   void AddGroupOfNodes();
   void AddGroupOfEdges();
   void AddGroupOfFaces();
@@ -65,6 +65,10 @@ class MESHDRIVERMED_EXPORT DriverMED_W_SMESHDS_Mesh: public Driver_SMESHDS_Mesh
   void AddGroup(SMESHDS_GroupBase * theGroup);
   void AddAllSubMeshes();
   void AddSubMesh(SMESHDS_SubMesh* theSubMesh, int theID);
+  void AddODOnVertices(bool toAdd) { myAddODOnVertices = toAdd; }
+
+  static bool getNodesOfMissing0DOnVert(SMESHDS_Mesh*                         mesh,
+                                        std::vector<const SMDS_MeshElement*>& nodes);
 
   /*! add one mesh
    */
@@ -83,6 +87,7 @@ class MESHDRIVERMED_EXPORT DriverMED_W_SMESHDS_Mesh: public Driver_SMESHDS_Mesh
   bool myDoGroupOf0DElems;
   bool myDoGroupOfBalls;
   bool myAutoDimension;
+  bool myAddODOnVertices;
 };
 
 #endif
index 692940c..b3cf4df 100644 (file)
@@ -1289,7 +1289,8 @@ void SMESH_Mesh::ExportMED(const char *        file,
                            bool                theAutoGroups,
                            int                 theVersion,
                            const SMESHDS_Mesh* meshPart,
-                           bool                theAutoDimension)
+                           bool                theAutoDimension,
+                           bool                theAddODOnVertices)
   throw(SALOME_Exception)
 {
   SMESH_TRY;
@@ -1298,6 +1299,7 @@ void SMESH_Mesh::ExportMED(const char *        file,
   myWriter.SetFile         ( file, MED::EVersion(theVersion) );
   myWriter.SetMesh         ( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS   );
   myWriter.SetAutoDimension( theAutoDimension );
+  myWriter.AddODOnVertices ( theAddODOnVertices );
   if ( !theMeshName ) 
     myWriter.SetMeshId     ( _id         );
   else {
index 6c25414..1981887 100644 (file)
@@ -236,7 +236,8 @@ public:
                  bool                theAutoGroups = true, 
                  int                 theVersion = 0,
                  const SMESHDS_Mesh* theMeshPart = 0,
-                 bool                theAutoDimension = false)
+                 bool                theAutoDimension = false,
+                 bool                theAddODOnVertices = false)
     throw(SALOME_Exception);
 
   void ExportDAT(const char *        file,
index 2689dc8..0b83371 100644 (file)
@@ -2848,25 +2848,6 @@ void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
   _impl->ExportSTL(file, isascii);
 }
 
-namespace // utils used by ExportPartToMED()
-{
-  // remover of 0d elements temporary added by ExportPartToMED()
-  struct OdRemover
-  {
-    std::vector< const SMDS_MeshElement* > _0dElems;
-    SMESHDS_Mesh*                          _mesh;
-    OdRemover( SMESHDS_Mesh* mesh ): _mesh( mesh ) {}
-    ~OdRemover() {
-      for ( size_t i = 0; i < _0dElems.size(); ++i )
-        if ( _0dElems[i] )
-        {
-          SMESHDS_SubMesh* sm = _mesh->MeshElements( _0dElems[i]->getshapeId() );
-          _mesh->RemoveFreeElement( _0dElems[i], sm, false );
-        }
-    }
-  };
-}
-
 //================================================================================
 /*!
  * \brief Export a part of mesh to a med file
@@ -2921,29 +2902,6 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
 
   SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
 
-  OdRemover a0dRemover( meshDS );
-  if ( have0dField )
-  {
-    // temporary add 0D elements on all nodes on vertices
-    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 )
-          {
-            a0dRemover._0dElems.push_back( meshDS->Add0DElement( n ));
-            sm->AddElement( a0dRemover._0dElems.back() );
-          }
-        }
-      }
-    }
-  }
-
   // write mesh
 
   string aMeshName = "Mesh";
@@ -2952,8 +2910,8 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
        SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
   {
     aMeshName = prepareMeshNameAndGroups(file, overwrite);
-    _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
-
+    _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
+                      version, 0, autoDimension, have0dField);
     meshDS = _impl->GetMeshDS();
   }
   else
@@ -2972,8 +2930,8 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
       }
     }
     SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
-    _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, partDS, autoDimension );
-
+    _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
+                      version, partDS, autoDimension, have0dField);
     meshDS = tmpDSDeleter._obj = partDS;
   }
 
@@ -2984,6 +2942,7 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
     DriverMED_W_Field fieldWriter;
     fieldWriter.SetFile( file );
     fieldWriter.SetMeshName( aMeshName );
+    fieldWriter.AddODOnVertices( have0dField );
 
     exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
   }