Salome HOME
IPAL53097: At med export "Automatically define space dimension" does not work
[modules/smesh.git] / src / DriverMED / DriverMED_W_SMESHDS_Mesh.cxx
index b4ab8dbe401b4a8caf9d5649d61359ea9f110ea3..1b3c26bac11ab5e2120c601832686403dc5b2792 100644 (file)
 #include "SMDS_SetIterator.hxx"
 #include "SMESHDS_Mesh.hxx"
 
+#include <BRep_Tool.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+
 #include <utilities.h>
 
 
@@ -254,7 +258,6 @@ namespace
                           const SMDSAbs_ElementType   anElemType)
   {
     anElemFamMap.Clear();
-    //anElemFamMap.clear();
     list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
     while ( aFamsIter != aFamilies.end() )
     {
@@ -263,12 +266,11 @@ namespace
       }
       else {
         int aFamId = (*aFamsIter)->GetId();
-        const set<const SMDS_MeshElement *>& anElems = (*aFamsIter)->GetElements();
-        set<const SMDS_MeshElement *>::const_iterator anElemsIter = anElems.begin();
+        const ElementsSet&              anElems = (*aFamsIter)->GetElements();
+        ElementsSet::const_iterator anElemsIter = anElems.begin();
         for (; anElemsIter != anElems.end(); anElemsIter++)
         {
           anElemFamMap.Bind( (Standard_Address)*anElemsIter, aFamId );
-          //anElemFamMap[*anElemsIter] = aFamId;
         }
         // remove a family from the list
         aFamilies.erase( aFamsIter++ );
@@ -288,9 +290,7 @@ namespace
   {
     if ( anElemFamMap.IsBound( (Standard_Address) anElement ))
       return anElemFamMap( (Standard_Address) anElement );
-//     TElemFamilyMap::iterator elem_famNum = anElemFamMap.find( anElement );
-//     if ( elem_famNum != anElemFamMap.end() )
-//       return elem_famNum->second;
+
     return aDefaultFamilyId;
   }
 
@@ -354,17 +354,34 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
           
           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 = anIsXDimension + anIsYDimension + anIsZDimension;
-        if(!aSpaceDimension)
+        if ( !aSpaceDimension )
           aSpaceDimension = 3;
         // PAL16857(SMESH not conform to the MED convention):
         if ( aSpaceDimension == 2 && anIsZDimension ) // 2D only if mesh is in XOY plane
@@ -381,7 +398,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
       }
 
       SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator(/*idInceasingOrder=*/true);
-      switch(aSpaceDimension){
+      switch ( aSpaceDimension ) {
       case 3:
         aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYZGetCoord,aXYZName));
         break;
@@ -448,7 +465,8 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
          myDoGroupOfVolumes && nbVolumes,
          myDoGroupOf0DElems && nb0DElements,
          myDoGroupOfBalls   && nbBalls);
-    } else {
+    }
+    else {
       aFamilies = DriverMED_Family::MakeFamilies
         (getIterator( mySubMeshes ), myGroups,
          myDoGroupOfNodes   && nbNodes,
@@ -481,7 +499,6 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
     PNodeInfo aNodeInfo = myMed->CrNodeInfo(aMeshInfo, aNbNodes,
                                             theMode, theSystem, theIsElemNum, theIsElemNames);
 
-    //cout << " fillElemFamilyMap( SMDSAbs_Node )" << endl;
     // find family numbers for nodes
     TElemFamilyMap anElemFamMap;
     fillElemFamilyMap( anElemFamMap, aFamilies, SMDSAbs_Node );
@@ -525,7 +542,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
     const SMDS_MeshInfo& nbElemInfo = myMesh->GetMeshInfo();
 
     // poly elements are not supported by med-2.1
-    bool polyTypesSupported = myMed->CrPolygoneInfo(aMeshInfo,eMAILLE,ePOLYGONE,0,0);
+    bool polyTypesSupported = ( myMed->CrPolygoneInfo(aMeshInfo,eMAILLE,ePOLYGONE,0,0).get() != 0 );
     TInt nbPolygonNodes = 0, nbPolyhedronNodes = 0, nbPolyhedronFaces = 0;
 
     // nodes on VERTEXes where 0D elements are absent
@@ -691,21 +708,11 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
 
       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;
+      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;
       }
@@ -787,7 +794,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
         if ( nbPolyhedronNodes == 0 ) {
           // Count nb of nodes
           while ( elemIterator->more() ) {
-            const SMDS_MeshElement* anElem = elemIterator->next();
+            const SMDS_MeshElement*  anElem = elemIterator->next();
             const SMDS_VtkVolume *aPolyedre = dynamic_cast<const SMDS_VtkVolume*>(anElem);
             if ( !aPolyedre ) continue;
             nbPolyhedronNodes += aPolyedre->NbNodes();
@@ -816,7 +823,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
           TInt iFace = 0, iNode = 0;
           while ( elemIterator->more() )
           {
-            const SMDS_MeshElement* anElem = elemIterator->next();
+            const SMDS_MeshElement*  anElem = elemIterator->next();
             const SMDS_VtkVolume *aPolyedre = dynamic_cast<const SMDS_VtkVolume*>(anElem);
             if ( !aPolyedre ) continue;
             // index
@@ -858,8 +865,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
       else if (aElemTypeData->_geomType == eBALL )
       {
         // allocate data arrays
-        PBallInfo aBallInfo = myMed->CrBallInfo( aMeshInfo,
-                                                 aElemTypeData->_nbElems );
+        PBallInfo aBallInfo = myMed->CrBallInfo( aMeshInfo, aElemTypeData->_nbElems );
 
         // build map of family numbers for this type
         if ( !isElemFamMapBuilt[ aElemTypeData->_smdsType ])