Salome HOME
Merge branch 'occ/shaper2smesh'
[modules/smesh.git] / src / DriverMED / DriverMED_W_SMESHDS_Mesh.cxx
index b4f49a216f74076c58631f5bc75d30f59d47b137..30f3ac4a31223b8caaadccd4bba229b0aee15e02 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2019  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
 #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 "MED_Common.hxx"
+
+#include <med.h>
 
 #include <BRep_Tool.hxx>
 #include <TopExp_Explorer.hxx>
@@ -52,7 +53,6 @@ using namespace MED;
 
 
 DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh():
-  myMedVersion(MED::eV2_2),
   myAllSubMeshes (false),
   myDoGroupOfNodes (false),
   myDoGroupOfEdges (false),
@@ -62,34 +62,41 @@ DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh():
   myDoGroupOfBalls(false),
   myAutoDimension(false),
   myAddODOnVertices(false),
-  myDoAllInGroups(false)
+  myDoAllInGroups(false),
+  myVersion(-1),
+  myZTolerance(-1.)
 {}
 
-void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName, 
-                                       MED::EVersion      theId)
-{
-  Driver_SMESHDS_Mesh::SetFile(theFileName);
-  myMedVersion = theId;
-}
-
-void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName)
+void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName, int theVersion)
 {
+  myVersion = theVersion;
   Driver_SMESHDS_Mesh::SetFile(theFileName);
 }
 
-string DriverMED_W_SMESHDS_Mesh::GetVersionString(const MED::EVersion theVersion, int theNbDigits)
+/*!
+ * MED version is either the latest available, or with an inferior minor,
+ * to ensure backward compatibility on writing med files.
+ */
+string DriverMED_W_SMESHDS_Mesh::GetVersionString(int theMinor, int theNbDigits)
 {
   TInt majeur, mineur, release;
-  majeur =  mineur = release = 0;
-//   if ( theVersion == eV2_1 )
-//     MED::GetVersionRelease<eV2_1>(majeur, mineur, release);
-//   else
-    MED::GetVersionRelease<eV2_2>(majeur, mineur, release);
+  majeur=MED_MAJOR_NUM;
+  mineur=MED_MINOR_NUM;
+  release=MED_RELEASE_NUM;
+  TInt imposedMineur = mineur;
+
+  if (theMinor < 0)
+    imposedMineur = mineur;
+  else if (theMinor > MED_MINOR_NUM)
+    imposedMineur = mineur;
+  else
+    imposedMineur = theMinor;
+
   ostringstream name;
   if ( theNbDigits > 0 )
     name << majeur;
   if ( theNbDigits > 1 )
-    name << "." << mineur;
+    name << "." << imposedMineur;
   if ( theNbDigits > 2 )
     name << "." << release;
   return name.str();
@@ -339,10 +346,6 @@ namespace
 Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
 {
   Status aResult = DRS_OK;
-  if (myMesh->hasConstructionEdges() || myMesh->hasConstructionFaces()) {
-    INFOS("SMDS_MESH with hasConstructionEdges() or hasConstructionFaces() do not supports!!!");
-    return DRS_FAIL;
-  }
   try {
     //MESSAGE("Perform - myFile : "<<myFile);
 
@@ -387,7 +390,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
           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());
 
@@ -416,6 +419,8 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
         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;
+        if ( myZTolerance > 0 && anIsZDimension )
+          anIsZDimension = (aBounds[5] > myZTolerance || aBounds[4] < -myZTolerance );
         aSpaceDimension = Max( aMeshDimension, anIsXDimension + anIsYDimension + anIsZDimension );
         if ( !aSpaceDimension )
           aSpaceDimension = 3;
@@ -433,7 +438,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
         }
       }
 
-      SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator(/*idInceasingOrder=*/true);
+      SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator();
       switch ( aSpaceDimension ) {
       case 3:
         aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYZGetCoord,aXYZName));
@@ -457,7 +462,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
       }
     }
 
-    MED::PWrapper myMed = CrWrapper(myFile,myMedVersion);
+    MED::PWrapper myMed = CrWrapperW(myFile, myVersion);
     PMeshInfo aMeshInfo = myMed->CrMeshInfo(aMeshDimension,aSpaceDimension,aMeshName);
     //MESSAGE("Add - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
     myMed->SetMeshInfo(aMeshInfo);
@@ -549,6 +554,10 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
       for(TInt iCoord = 0; iCoord < aSpaceDimension; iCoord++){
         aTCoordSlice[iCoord] = aCoordHelperPtr->GetCoord(iCoord);
       }
+      if ( aSpaceDimension == 3 &&
+           -myZTolerance < aTCoordSlice[2] && aTCoordSlice[2] < myZTolerance )
+        aTCoordSlice[2] = 0.;
+
       // node number
       int aNodeID = aCoordHelperPtr->GetID();
       aNodeInfo->SetElemNum( iNode, aNodeID );
@@ -759,6 +768,13 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
         continue;
       }
 
+      // build map of family numbers for this type
+      if ( !isElemFamMapBuilt[ aElemTypeData->_smdsType ])
+      {
+        fillElemFamilyMap( anElemFamMap, aFamilies, aElemTypeData->_smdsType );
+        isElemFamMapBuilt[ aElemTypeData->_smdsType ] = true;
+      }
+
       // iterator on elements of a current type
       SMDS_ElemIteratorPtr elemIterator;
       int iElem = 0;
@@ -829,18 +845,16 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
 
       // Treat POLYEDREs
       // ----------------
-      else if (aElemTypeData->_geomType == ePOLYEDRE )
+      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();
-            const SMDS_VtkVolume *aPolyedre = dynamic_cast<const SMDS_VtkVolume*>(anElem);
-            if ( !aPolyedre ) continue;
-            nbPolyhedronNodes += aPolyedre->NbNodes();
-            nbPolyhedronFaces += aPolyedre->NbFaces();
+            nbPolyhedronNodes += anElem->NbNodes();
+            nbPolyhedronFaces += anElem->NbFaces();
             if ( ++iElem == aElemTypeData->_nbElems )
               break;
           }
@@ -865,8 +879,8 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
           TInt iFace = 0, iNode = 0;
           while ( elemIterator->more() )
           {
-            const SMDS_MeshElement*  anElem = elemIterator->next();
-            const SMDS_VtkVolume *aPolyedre = dynamic_cast<const SMDS_VtkVolume*>(anElem);
+            const SMDS_MeshElement* anElem = elemIterator->next();
+            const SMDS_MeshVolume *aPolyedre = myMesh->DownCast< SMDS_MeshVolume >( anElem );
             if ( !aPolyedre ) continue;
             // index
             TInt aNbFaces = aPolyedre->NbFaces();
@@ -909,13 +923,6 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
         // allocate data arrays
         PBallInfo aBallInfo = myMed->CrBallInfo( aMeshInfo, aElemTypeData->_nbElems );
 
-        // build map of family numbers for this type
-        if ( !isElemFamMapBuilt[ aElemTypeData->_smdsType ])
-        {
-          fillElemFamilyMap( anElemFamMap, aFamilies, aElemTypeData->_smdsType );
-          isElemFamMapBuilt[ aElemTypeData->_smdsType ] = true;
-        }
-
         elemIterator = myMesh->elementsIterator( SMDSAbs_Ball );
         while ( elemIterator->more() )
         {
@@ -955,12 +962,6 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
                                                  theConnMode,
                                                  theIsElemNum,
                                                  theIsElemNames);
-        // build map of family numbers for this type
-        if ( !isElemFamMapBuilt[ aElemTypeData->_smdsType ])
-        {
-          fillElemFamilyMap( anElemFamMap, aFamilies, aElemTypeData->_smdsType );
-          isElemFamMapBuilt[ aElemTypeData->_smdsType ] = true;
-        }
 
         TInt aNbNodes = MED::GetNbNodes(aElemTypeData->_geomType);
         elemIterator = myMesh->elementsIterator( aElemTypeData->_smdsType );