Salome HOME
Merge branch 'master' of https://codev-tuleap.cea.fr/plugins/git/salome/smesh
[modules/smesh.git] / src / DriverMED / DriverMED_W_SMESHDS_Mesh.cxx
index f31f262c03438b16bd4bcd561a227484f13ab973..a1902daac8aafe9f4cfc43d9c83906a2e769242f 100644 (file)
 #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.h>
+
 #include <BRep_Tool.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
@@ -52,7 +52,6 @@ using namespace MED;
 
 
 DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh():
-  myMedVersion(MED::eV2_2),
   myAllSubMeshes (false),
   myDoGroupOfNodes (false),
   myDoGroupOfEdges (false),
@@ -61,34 +60,40 @@ DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh():
   myDoGroupOf0DElems(false),
   myDoGroupOfBalls(false),
   myAutoDimension(false),
-  myAddODOnVertices(false)
+  myAddODOnVertices(false),
+  myDoAllInGroups(false)
 {}
 
-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 theMinor)
 {
+  myMinor = theMinor;
   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 theVersion, 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 (theVersion < 0)
+    imposedMineur = mineur;
+  else if (theVersion > MED_MINOR_NUM)
+    imposedMineur = mineur;
+  else
+    imposedMineur = theVersion;
+
   ostringstream name;
   if ( theNbDigits > 0 )
     name << majeur;
   if ( theNbDigits > 1 )
-    name << "." << mineur;
+    name << "." << imposedMineur;
   if ( theNbDigits > 2 )
     name << "." << release;
   return name.str();
@@ -129,6 +134,32 @@ void DriverMED_W_SMESHDS_Mesh::AddGroupOfVolumes()
   myDoGroupOfVolumes = true;
 }
 
+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;
+}
+
+
 namespace
 {
   typedef double (SMDS_MeshNode::* TGetCoord)() const;
@@ -312,10 +343,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);
 
@@ -360,7 +387,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());
 
@@ -406,7 +433,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));
@@ -429,8 +456,8 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
         break;
       }
     }
-    
-    MED::PWrapper myMed = CrWrapper(myFile,myMedVersion);
+
+    MED::PWrapper myMed = CrWrapperW(myFile, myMinor);
     PMeshInfo aMeshInfo = myMed->CrMeshInfo(aMeshDimension,aSpaceDimension,aMeshName);
     //MESSAGE("Add - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
     myMed->SetMeshInfo(aMeshInfo);
@@ -449,12 +476,20 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
     int nbEdges      = myMesh->NbEdges();
     int nbFaces      = myMesh->NbFaces();
     int nbVolumes    = myMesh->NbVolumes();
-    if (myDoGroupOfNodes && nbNodes) myNodesDefaultFamilyId = REST_NODES_FAMILY;
-    if (myDoGroupOfEdges && nbEdges) myEdgesDefaultFamilyId = REST_EDGES_FAMILY;
-    if (myDoGroupOfFaces && nbFaces) myFacesDefaultFamilyId = REST_FACES_FAMILY;
-    if (myDoGroupOfVolumes && nbVolumes) myVolumesDefaultFamilyId = REST_VOLUMES_FAMILY;
-    if (myDoGroupOf0DElems && nb0DElements) my0DElementsDefaultFamilyId = REST_0DELEM_FAMILY;
-    if (myDoGroupOfBalls && nbBalls) myBallsDefaultFamilyId = REST_BALL_FAMILY;
+    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    ;
+    }
 
     //MESSAGE("Perform - aFamilyInfo");
     list<DriverMED_FamilyPtr> aFamilies;
@@ -466,7 +501,8 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
          myDoGroupOfFaces   && nbFaces,
          myDoGroupOfVolumes && nbVolumes,
          myDoGroupOf0DElems && nb0DElements,
-         myDoGroupOfBalls   && nbBalls);
+         myDoGroupOfBalls   && nbBalls,
+         myDoAllInGroups);
     }
     else {
       aFamilies = DriverMED_Family::MakeFamilies
@@ -476,7 +512,8 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
          myDoGroupOfFaces   && nbFaces,
          myDoGroupOfVolumes && nbVolumes,
          myDoGroupOf0DElems && nb0DElements,
-         myDoGroupOfBalls   && nbBalls);
+         myDoGroupOfBalls   && nbBalls,
+         myDoAllInGroups);
     }
     list<DriverMED_FamilyPtr>::iterator aFamsIter;
     for (aFamsIter = aFamilies.begin(); aFamsIter != aFamilies.end(); aFamsIter++)
@@ -666,7 +703,11 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
                                              SMDSAbs_Volume));
     aTElemTypeDatas.push_back( TElemTypeData(anEntity,
                                              ePENTA15,
-                                             nbElemInfo.NbPrisms( ORDER_QUADRATIC ),
+                                             nbElemInfo.NbQuadPrisms(),
+                                             SMDSAbs_Volume));
+    aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+                                             ePENTA18,
+                                             nbElemInfo.NbBiQuadPrisms(),
                                              SMDSAbs_Volume));
     aTElemTypeDatas.push_back( TElemTypeData(anEntity,
                                              eHEXA8,
@@ -718,6 +759,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;
@@ -788,18 +836,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;
           }
@@ -824,8 +870,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();
@@ -868,13 +914,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() )
         {
@@ -906,7 +945,6 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
       {
         // Treat standard types
         // ---------------------
-
         // allocate data arrays
         PCellInfo aCellInfo = myMed->CrCellInfo( aMeshInfo,
                                                  aElemTypeData->_entity,
@@ -915,13 +953,6 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
                                                  theConnMode,
                                                  theIsElemNum,
                                                  theIsElemNames);
-        // build map of family numbers for this type
-        if ( !isElemFamMapBuilt[ aElemTypeData->_smdsType ])
-        {
-          //cout << " fillElemFamilyMap()" << endl;
-          fillElemFamilyMap( anElemFamMap, aFamilies, aElemTypeData->_smdsType );
-          isElemFamMapBuilt[ aElemTypeData->_smdsType ] = true;
-        }
 
         TInt aNbNodes = MED::GetNbNodes(aElemTypeData->_geomType);
         elemIterator = myMesh->elementsIterator( aElemTypeData->_smdsType );
@@ -956,10 +987,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
         // 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());