]> SALOME platform Git repositories - plugins/ghs3dplugin.git/commitdiff
Salome HOME
Still in progress ...
authorgdd <gdd>
Fri, 8 Apr 2011 15:38:23 +0000 (15:38 +0000)
committergdd <gdd>
Fri, 8 Apr 2011 15:38:23 +0000 (15:38 +0000)
src/GHS3DPlugin/GHS3DPlugin_GHS3D.cxx
src/GHS3DPlugin/GHS3DPlugin_GHS3D.hxx
src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.cxx

index 7cbfa818a08b73d8cd6beba1dddf0592e21bb005..5e5cf5324c28c0fe3f6ddbeee5d677237e1da256 100644 (file)
 //
 #include "GHS3DPlugin_GHS3D.hxx"
 #include "GHS3DPlugin_Hypothesis.hxx"
-extern "C"
-{
-  #include "libmesh5.h"
-}
 
 #include <Basics_Utils.hxx>
 
@@ -51,7 +47,9 @@ extern "C"
 
 #include <BRepAdaptor_Surface.hxx>
 #include <BRepBndLib.hxx>
+#include <BRepBuilderAPI_MakeVertex.hxx>
 #include <BRepClass3d_SolidClassifier.hxx>
+#include <BRepExtrema_DistShapeShape.hxx>
 #include <BRepTools.hxx>
 #include <BRep_Tool.hxx>
 #include <Bnd_Box.hxx>
@@ -79,6 +77,7 @@ extern "C"
 #else
 #include <sys/sysinfo.h>
 #endif
+#include <algorithm>
 
 using namespace std;
 
@@ -185,13 +184,13 @@ bool GHS3DPlugin_GHS3D::CheckHypothesis ( SMESH_Mesh&         aMesh,
   return true;
 }
 
-#if GHS3D_VERSION < 42
+#if GHS3D_VERSION < 42 || !defined GMF_HAS_SUBDOMAIN_INFO
 //=======================================================================
 //function : findShape
 //purpose  : 
 //=======================================================================
 
-static TopoDS_Shape findShape(const SMDS_MeshNode *aNode[],
+static TopoDS_Shape findShape(SMDS_MeshNode *aNode[],
                               TopoDS_Shape        aShape,
                               const TopoDS_Shape  shape[],
                               double**            box,
@@ -244,23 +243,722 @@ static char* readMapIntLine(char* ptr, int tab[]) {
   }
   return ptr;
 }
+
+//================================================================================
+/*!
+ * \brief returns true if a triangle defined by the nodes is a temporary face on a
+ * side facet of pyramid and defines sub-domian inside the pyramid
+ */
+//================================================================================
+
+static bool isTmpFace(const SMDS_MeshNode* node1,
+                      const SMDS_MeshNode* node2,
+                      const SMDS_MeshNode* node3)
+{
+  // find a pyramid sharing the 3 nodes
+  //const SMDS_MeshElement* pyram = 0;
+  SMDS_ElemIteratorPtr vIt1 = node1->GetInverseElementIterator(SMDSAbs_Volume);
+  while ( vIt1->more() )
+  {
+    const SMDS_MeshElement* pyram = vIt1->next();
+    if ( pyram->NbCornerNodes() != 5 ) continue;
+    int i2, i3;
+    if ( (i2 = pyram->GetNodeIndex( node2 )) >= 0 &&
+         (i3 = pyram->GetNodeIndex( node3 )) >= 0 )
+    {
+      // Triangle defines sub-domian inside the pyramid if it's
+      // normal points out of the pyram
+
+      // make i2 and i3 hold indices of base nodes of the pyram while
+      // keeping the nodes order in the triangle
+      const int iApex = 4;
+      if ( i2 == iApex )
+        i2 = i3, i3 = pyram->GetNodeIndex( node1 );
+      else if ( i3 == iApex )
+        i3 = i2, i2 = pyram->GetNodeIndex( node1 );
+
+      int i3base = (i2+1) % 4; // next index after i2 within the pyramid base
+      return ( i3base != i3 );
+    }
+  }
+  return false;
+}
+
+//=======================================================================
+//function : findShapeID
+//purpose  : find the solid corresponding to GHS3D sub-domain following
+//           the technique proposed in GHS3D manual (available within
+//           ghs3d installation) in chapter "B.4 Subdomain (sub-region) assignment".
+//           In brief: normal of the triangle defined by the given nodes
+//           points out of the domain it is associated to
+//=======================================================================
+
+static int findShapeID(SMESH_Mesh&          mesh,
+                       const SMDS_MeshNode* node1,
+                       const SMDS_MeshNode* node2,
+                       const SMDS_MeshNode* node3,
+                       const bool           toMeshHoles)
+{
+  const int invalidID = 0;
+  SMESHDS_Mesh* meshDS = mesh.GetMeshDS();
+
+  // face the nodes belong to
+  const SMDS_MeshElement * face = meshDS->FindFace(node1,node2,node3);
+  if ( !face )
+    return isTmpFace(node1, node2, node3) ? HOLE_ID : invalidID;
+#ifdef _DEBUG_
+  std::cout << "bnd face " << face->GetID() << " - ";
+#endif
+  // geom face the face assigned to
+  SMESH_MeshEditor editor(&mesh);
+  int geomFaceID = editor.FindShape( face );
+  if ( !geomFaceID )
+    return isTmpFace(node1, node2, node3) ? HOLE_ID : invalidID;
+  TopoDS_Shape shape = meshDS->IndexToShape( geomFaceID );
+  if ( shape.IsNull() || shape.ShapeType() != TopAbs_FACE )
+    return invalidID;
+  TopoDS_Face geomFace = TopoDS::Face( shape );
+
+  // solids bounded by geom face
+  TopTools_IndexedMapOfShape solids, shells;
+  TopTools_ListIteratorOfListOfShape ansIt = mesh.GetAncestors(geomFace);
+  for ( ; ansIt.More(); ansIt.Next() ) {
+    switch ( ansIt.Value().ShapeType() ) {
+    case TopAbs_SOLID:
+      solids.Add( ansIt.Value() ); break;
+    case TopAbs_SHELL:
+      shells.Add( ansIt.Value() ); break;
+    default:;
+    }
+  }
+  // analyse found solids
+  if ( solids.Extent() == 0 || shells.Extent() == 0)
+    return invalidID;
+
+  const TopoDS_Solid& solid1 = TopoDS::Solid( solids(1) );
+  if ( solids.Extent() == 1 )
+  {
+    if ( toMeshHoles )
+      return meshDS->ShapeToIndex( solid1 );
+
+    // - Are we at a hole boundary face?
+    if ( shells(1).IsSame( BRepTools::OuterShell( solid1 )) )
+    { // - No, but maybe a hole is bound by two shapes? Does shells(1) touches another shell?
+      bool touch = false;
+      TopExp_Explorer eExp( shells(1), TopAbs_EDGE );
+      // check if any edge of shells(1) belongs to another shell
+      for ( ; eExp.More() && !touch; eExp.Next() ) {
+        ansIt = mesh.GetAncestors( eExp.Current() );
+        for ( ; ansIt.More() && !touch; ansIt.Next() ) {
+          if ( ansIt.Value().ShapeType() == TopAbs_SHELL )
+            touch = ( !ansIt.Value().IsSame( shells(1) ));
+        }
+      }
+      if (!touch)
+        return meshDS->ShapeToIndex( solid1 );
+    }
+  }
+  // find orientation of geom face within the first solid
+  TopExp_Explorer fExp( solid1, TopAbs_FACE );
+  for ( ; fExp.More(); fExp.Next() )
+    if ( geomFace.IsSame( fExp.Current() )) {
+      geomFace = TopoDS::Face( fExp.Current() );
+      break;
+    }
+  if ( !fExp.More() )
+    return invalidID; // face not found
+
+  // normale to triangle
+  gp_Pnt node1Pnt ( node1->X(), node1->Y(), node1->Z() );
+  gp_Pnt node2Pnt ( node2->X(), node2->Y(), node2->Z() );
+  gp_Pnt node3Pnt ( node3->X(), node3->Y(), node3->Z() );
+  gp_Vec vec12( node1Pnt, node2Pnt );
+  gp_Vec vec13( node1Pnt, node3Pnt );
+  gp_Vec meshNormal = vec12 ^ vec13;
+  if ( meshNormal.SquareMagnitude() < DBL_MIN )
+    return invalidID;
+
+  // get normale to geomFace at any node
+  bool geomNormalOK = false;
+  gp_Vec geomNormal;
+  const SMDS_MeshNode* nodes[3] = { node1, node2, node3 };
+  SMESH_MesherHelper helper( mesh ); helper.SetSubShape( geomFace );
+  for ( int i = 0; !geomNormalOK && i < 3; ++i )
+  {
+    // find UV of i-th node on geomFace
+    const SMDS_MeshNode* nNotOnSeamEdge = 0;
+    if ( helper.IsSeamShape( nodes[i]->getshapeId() )) {
+      if ( helper.IsSeamShape( nodes[(i+1)%3]->getshapeId() ))
+        nNotOnSeamEdge = nodes[(i+2)%3];
+      else
+        nNotOnSeamEdge = nodes[(i+1)%3];
+    }
+    bool uvOK;
+    gp_XY uv = helper.GetNodeUV( geomFace, nodes[i], nNotOnSeamEdge, &uvOK );
+    // check that uv is correct
+    if (uvOK) {
+      double tol = 1e-6;
+      TopoDS_Shape nodeShape = helper.GetSubShapeByNode( nodes[i], meshDS );
+      if ( !nodeShape.IsNull() )
+        switch ( nodeShape.ShapeType() )
+        {
+        case TopAbs_FACE:   tol = BRep_Tool::Tolerance( TopoDS::Face( nodeShape )); break;
+        case TopAbs_EDGE:   tol = BRep_Tool::Tolerance( TopoDS::Edge( nodeShape )); break;
+        case TopAbs_VERTEX: tol = BRep_Tool::Tolerance( TopoDS::Vertex( nodeShape )); break;
+        default:;
+        }
+      gp_Pnt nodePnt ( nodes[i]->X(), nodes[i]->Y(), nodes[i]->Z() );
+      BRepAdaptor_Surface surface( geomFace );
+      uvOK = ( nodePnt.Distance( surface.Value( uv.X(), uv.Y() )) < 2 * tol );
+      if ( uvOK ) {
+        // normale to geomFace at UV
+        gp_Vec du, dv;
+        surface.D1( uv.X(), uv.Y(), nodePnt, du, dv );
+        geomNormal = du ^ dv;
+        if ( geomFace.Orientation() == TopAbs_REVERSED )
+          geomNormal.Reverse();
+        geomNormalOK = ( geomNormal.SquareMagnitude() > DBL_MIN * 1e3 );
+      }
+    }
+  }
+  if ( !geomNormalOK)
+    return invalidID;
+
+  // compare normals
+  bool isReverse = ( meshNormal * geomNormal ) < 0;
+  if ( !isReverse )
+    return meshDS->ShapeToIndex( solid1 );
+
+  if ( solids.Extent() == 1 )
+    return HOLE_ID; // we are inside a hole
+  else
+    return meshDS->ShapeToIndex( solids(2) );
+}
+#endif
+
+//=======================================================================
+//function : countShape
+//purpose  :
+//=======================================================================
+
+template < class Mesh, class Shape >
+static int countShape( Mesh* mesh, Shape shape ) {
+  TopExp_Explorer expShape ( mesh->ShapeToMesh(), shape );
+  TopTools_MapOfShape mapShape;
+  int nbShape = 0;
+  for ( ; expShape.More(); expShape.Next() ) {
+    if (mapShape.Add(expShape.Current())) {
+      nbShape++;
+    }
+  }
+  return nbShape;
+}
+
+//=======================================================================
+//function : getShape
+//purpose  :
+//=======================================================================
+
+template < class Mesh, class Shape, class Tab >
+void getShape(Mesh* mesh, Shape shape, Tab *t_Shape) {
+  TopExp_Explorer expShape ( mesh->ShapeToMesh(), shape );
+  TopTools_MapOfShape mapShape;
+  for ( int i=0; expShape.More(); expShape.Next() ) {
+    if (mapShape.Add(expShape.Current())) {
+      t_Shape[i] = expShape.Current();
+      i++;
+    }
+  }
+  return;
+}
+
+//=======================================================================
+//function : findEdgeID
+//purpose  :
+//=======================================================================
+
+static int findEdgeID(const SMDS_MeshNode* aNode,
+                      const SMESHDS_Mesh*  theMesh,
+                      const int            nEdge,
+                      const TopoDS_Shape*  t_Edge) {
+
+  TopoDS_Shape aPntShape, foundEdge;
+  TopoDS_Vertex aVertex;
+  gp_Pnt aPnt( aNode->X(), aNode->Y(), aNode->Z() );
+
+  int foundInd, ind;
+  double nearest = RealLast(), *t_Dist;
+  double epsilon = Precision::Confusion();
+
+  t_Dist = new double[ nEdge ];
+  aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
+  aVertex   = TopoDS::Vertex( aPntShape );
+
+  for ( ind=0; ind < nEdge; ind++ ) {
+    BRepExtrema_DistShapeShape aDistance ( aVertex, t_Edge[ind] );
+    t_Dist[ind] = aDistance.Value();
+    if ( t_Dist[ind] < nearest ) {
+      nearest   = t_Dist[ind];
+      foundEdge = t_Edge[ind];
+      foundInd  = ind;
+      if ( nearest < epsilon )
+        ind = nEdge;
+    }
+  }
+
+  delete [] t_Dist;
+  return theMesh->ShapeToIndex( foundEdge );
+}
+
+#if GHS3D_VERSION >= 42
+//=======================================================================
+//function : readGMFFile
+//purpose  :
+//=======================================================================
+
+static bool readGMFFile(
+#ifndef GMF_HAS_SUBDOMAIN_INFO
+                        const int                       fileOpen,
+#endif
+                        const char*                     theFileName, 
+                        SMESH_Mesh&                     theMesh,
+                        const int                       nbShape,
+                        const TopoDS_Shape*             tabShape,
+                        double**                        tabBox,
+                        map <int,const SMDS_MeshNode*>& theGhs3dIdToNodeMap,
+                        bool                            toMeshHoles,
+                        int                             nbEnforcedVertices,
+                        int                             nbEnforcedNodes,
+                        TIDSortedNodeSet &              theEnforcedNodes,
+                        TIDSortedElemSet &              theEnforcedTriangles,
+                        TIDSortedElemSet &              theEnforcedQuadrangles)
+{
+  TopoDS_Shape aShape;
+  TopoDS_Vertex aVertex;
+  SMESHDS_Mesh* theMeshDS = theMesh.GetMeshDS();
+  int nbElem = 0, nbRef = 0, IdShapeRef = 1;
+  int *tabID;
+  int aGMFNodeID = 0;
+  int compoundID =
+    nbShape ? theMeshDS->ShapeToIndex( tabShape[0] ) : theMeshDS->ShapeToIndex( theMeshDS->ShapeToMesh() );
+  int tetraShapeID = compoundID;
+  double epsilon = Precision::Confusion();
+  int *nodeAssigne, *GMFNodeAssigne;
+  SMDS_MeshNode** GMFNode;
+  TopoDS_Shape *tabCorner, *tabEdge;
+  std::map <GmfKwdCod,int> tabRef;
+  
+  
+  int ver, dim;
+  MESSAGE("Read " << theFileName << " file");
+  int InpMsh = GmfOpenMesh(theFileName, GmfRead, &ver, &dim);
+  if (!InpMsh)
+    return false;
+  
+  // ===========================
+  // Fill the tabID array: BEGIN
+  // ===========================
+  
+#ifndef GMF_HAS_SUBDOMAIN_INFO
+  /*
+  The output .mesh file does not contain yet the subdomain-info (Ghs3D 4.2)
+  */
+  Kernel_Utils::Localizer loc;
+  struct stat status;
+  size_t      length;
+
+  char *ptr, *mapPtr;
+  char *tetraPtr;
+  int *tab = new int[3];
+  
+  // Read the file state
+  fstat(fileOpen, &status);
+  length   = status.st_size;
+  
+  // Mapping the result file into memory
+#ifdef WNT
+  HANDLE fd = CreateFile(theFileName, GENERIC_READ, FILE_SHARE_READ,
+                         NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+  HANDLE hMapObject = CreateFileMapping(fd, NULL, PAGE_READONLY,
+                                        0, (DWORD)length, NULL);
+  ptr = ( char* ) MapViewOfFile(hMapObject, FILE_MAP_READ, 0, 0, 0 );
+#else
+  ptr = (char *) mmap(0,length,PROT_READ,MAP_PRIVATE,fileOpen,0);
+#endif
+  mapPtr = ptr;
+
+  ptr      = readMapIntLine(ptr, tab);
+  tetraPtr = ptr;
+
+  nbElem            = tab[0];
+  int nbNodes       = tab[1];
+  
+  for (int i=0; i < 4*nbElem; i++)
+    strtol(ptr, &ptr, 10);
+  
+  for (int iNode=1; iNode <= nbNodes; iNode++)
+    for (int iCoor=0; iCoor < 3; iCoor++)
+      strtod(ptr, &ptr);
+
+    
+  // Reading the number of triangles which corresponds to the number of sub-domains
+  int nbTriangle = strtol(ptr, &ptr, 10);
+#else
+  // The keyword does not exist yet => to update when it is created
+  int nbTriangle = GmfStatKwd(InpMsh, GmfSubdomain);
+  int id_tri[3];
+#endif
+
+  tabID = new int[nbTriangle];
+  for (int i=0; i < nbTriangle; i++) {
+    tabID[i] = 0;
+    int nodeId1, nodeId2, nodeId3;
+    // find the solid corresponding to GHS3D sub-domain following
+    // the technique proposed in GHS3D manual in chapter
+    // "B.4 Subdomain (sub-region) assignment"
+#ifndef GMF_HAS_SUBDOMAIN_INFO
+    nodeId1 = strtol(ptr, &ptr, 10);
+    nodeId2 = strtol(ptr, &ptr, 10);
+    nodeId3 = strtol(ptr, &ptr, 10);
+#else
+  // The keyword does not exist yet => to update when it is created
+    GmfGetLin(InpMsh, GmfSubdomain, &id_tri[0], &id_tri[1], &id_tri[2]);
+    nodeId1 = id_tri[0];
+    nodeId2 = id_tri[1];
+    nodeId3 = id_tri[2];
+#endif
+    if ( nbTriangle > 1 ) {
+      // get the nodes indices
+      const SMDS_MeshNode* n1 = theGhs3dIdToNodeMap[ nodeId1 ];
+      const SMDS_MeshNode* n2 = theGhs3dIdToNodeMap[ nodeId2 ];
+      const SMDS_MeshNode* n3 = theGhs3dIdToNodeMap[ nodeId3 ];
+      try {
+        OCC_CATCH_SIGNALS;
+        tabID[i] = findShapeID( theMesh, n1, n2, n3, toMeshHoles );
+        // -- 0020330: Pb with ghs3d as a submesh
+        // check that found shape is to be meshed
+        if ( tabID[i] > 0 ) {
+          const TopoDS_Shape& foundShape = theMeshDS->IndexToShape( tabID[i] );
+          bool isToBeMeshed = false;
+          for ( int iS = 0; !isToBeMeshed && iS < nbShape; ++iS )
+            isToBeMeshed = foundShape.IsSame( tabShape[ iS ]);
+          if ( !isToBeMeshed )
+            tabID[i] = HOLE_ID;
+        }
+        // END -- 0020330: Pb with ghs3d as a submesh
+#ifdef _DEBUG_
+        std::cout << i+1 << " subdomain: findShapeID() returns " << tabID[i] << std::endl;
+#endif
+      }
+      catch ( Standard_Failure & ex)
+      {
+#ifdef _DEBUG_
+        std::cout << i+1 << " subdomain: Exception caugt: " << ex.GetMessageString() << std::endl;
+#endif
+      }
+      catch (...) {
+#ifdef _DEBUG_
+        std::cout << i+1 << " subdomain: unknown exception caught " << std::endl;
+#endif
+      }
+    }
+  }
+  
+  // ===========================
+  // Fill the tabID array: END
+  // ===========================
+  
+
+  tabRef[GmfVertices]       = 3;
+  tabRef[GmfCorners]        = 1;
+  tabRef[GmfEdges]          = 2;
+  tabRef[GmfRidges]         = 1;
+  tabRef[GmfTriangles]      = 3;
+//   tabRef[GmfQuadrilaterals] = 4;
+  tabRef[GmfTetrahedra]     = 4;
+//   tabRef[GmfHexahedra]      = 8;
+  
+  SMDS_NodeIteratorPtr itOnGMFInputNode = theMeshDS->nodesIterator();
+  while ( itOnGMFInputNode->more() )
+    theMeshDS->RemoveNode( itOnGMFInputNode->next() );
+
+  
+  int nbVertices = GmfStatKwd(InpMsh, GmfVertices);
+  int nbCorners = max(countShape( theMeshDS, TopAbs_VERTEX ) , GmfStatKwd(InpMsh, GmfCorners));
+  int nbShapeEdge = countShape( theMeshDS, TopAbs_EDGE );
+
+  tabCorner       = new TopoDS_Shape[ nbCorners ];
+  tabEdge         = new TopoDS_Shape[ nbShapeEdge ];
+  nodeAssigne     = new int[ nbVertices + 1 ];
+  GMFNodeAssigne  = new int[ nbVertices + 1 ];
+  GMFNode         = new SMDS_MeshNode*[ nbVertices + 1 ];
+
+  getShape(theMeshDS, TopAbs_VERTEX, tabCorner);
+  getShape(theMeshDS, TopAbs_EDGE,   tabEdge);
+
+  std::map <GmfKwdCod,int>::const_iterator it = tabRef.begin();
+  for ( ; it != tabRef.end() ; ++it)
+  {
+//     int dummy;
+    GmfKwdCod token = it->first;
+    nbRef    = it->second;
+
+    nbElem = GmfStatKwd(InpMsh, token);
+    if (nbElem > 0) {
+      GmfGotoKwd(InpMsh, token);
+      std::cout << "Read " << nbElem;
+    }
+    else
+      continue;
+
+    int id[nbElem*tabRef[token]];
+    int ghs3dShapeID[nbElem];
+
+    if (token == GmfVertices) {
+      std::cout << " vertices" << std::endl;
+      int aGMFID;
+
+      float VerTab_f[nbElem][3];
+      double VerTab_d[nbElem][3];
+      SMDS_MeshNode * aGMFNode;
+
+      for ( int iElem = 0; iElem < nbElem; iElem++ ) {
+        aGMFID = iElem + 1;
+        if (ver == GmfFloat) {
+          GmfGetLin(InpMsh, token, &VerTab_f[nbElem][0], &VerTab_f[nbElem][1], &VerTab_f[nbElem][2], &ghs3dShapeID[iElem]);
+          aGMFNode = theMeshDS->AddNode(VerTab_f[nbElem][0], VerTab_f[nbElem][1], VerTab_f[nbElem][2]);
+        }
+        else {
+          GmfGetLin(InpMsh, token, &VerTab_d[nbElem][0], &VerTab_d[nbElem][1], &VerTab_d[nbElem][2], &ghs3dShapeID[iElem]);
+          aGMFNode = theMeshDS->AddNode(VerTab_d[nbElem][0], VerTab_d[nbElem][1], VerTab_d[nbElem][2]);
+        }
+        GMFNode[ aGMFID ] = aGMFNode;
+        nodeAssigne[ aGMFID ] = 0;
+        GMFNodeAssigne[ aGMFID ] = 0;
+      }
+    }
+    else if (token == GmfCorners && nbElem > 0) {
+      std::cout << " corners" << std::endl;
+      for ( int iElem = 0; iElem < nbElem; iElem++ )
+        GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]]);
+    }
+    else if (token == GmfRidges && nbElem > 0) {
+      std::cout << " ridges" << std::endl;
+      for ( int iElem = 0; iElem < nbElem; iElem++ )
+        GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]]);
+    }
+    else if (token == GmfEdges && nbElem > 0) {
+      std::cout << " edges" << std::endl;
+      for ( int iElem = 0; iElem < nbElem; iElem++ )
+        GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &ghs3dShapeID[iElem]);
+    }
+    else if (token == GmfTriangles && nbElem > 0) {
+      std::cout << " triangles" << std::endl;
+      for ( int iElem = 0; iElem < nbElem; iElem++ )
+        GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &ghs3dShapeID[iElem]);
+    }
+//     else if (token == GmfQuadrilaterals && nbElem > 0) {
+//       std::cout << " Quadrilaterals" << std::endl;
+//       for ( int iElem = 0; iElem < nbElem; iElem++ )
+//         GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &id[iElem*tabRef[token]+3], &ghs3dShapeID[iElem]);
+//     }
+    else if (token == GmfTetrahedra && nbElem > 0) {
+      std::cout << " Tetrahedra" << std::endl;
+      for ( int iElem = 0; iElem < nbElem; iElem++ )
+        GmfGetLin(InpMsh, token, 
+                  &id[iElem*tabRef[token]], 
+                  &id[iElem*tabRef[token]+1], 
+                  &id[iElem*tabRef[token]+2], 
+                  &id[iElem*tabRef[token]+3], 
+                  &ghs3dShapeID[iElem]);
+    }
+//     else if (token == GmfHexahedra && nbElem > 0) {
+//       std::cout << " Hexahedra" << std::endl;
+//       for ( int iElem = 0; iElem < nbElem; iElem++ )
+//         GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &id[iElem*tabRef[token]+3],
+//                   &id[iElem*tabRef[token]+4], &id[iElem*tabRef[token]+5], &id[iElem*tabRef[token]+6], &id[iElem*tabRef[token]+7], &ghs3dShapeID[iElem]);
+//     }
+
+    switch (token) {
+    case GmfCorners:
+    case GmfRidges:
+    case GmfEdges:
+    case GmfTriangles:
+//     case GmfQuadrilaterals:
+    case GmfTetrahedra:
+//     case GmfHexahedra:
+    {
+      int nodeDim, shapeID, *nodeID;
+      SMDS_MeshNode** node;
+//       std::vector< SMDS_MeshNode* > enfNode( nbRef );
+      SMDS_MeshElement * aGMFElement;
+      
+      node    = new SMDS_MeshNode*[nbRef];
+      nodeID  = new int[ nbRef ];
+
+      for ( int iElem = 0; iElem < nbElem; iElem++ )
+      {
+        for ( int iRef = 0; iRef < nbRef; iRef++ )
+        {
+          aGMFNodeID = id[iElem*tabRef[token]+iRef]; // read nbRef aGMFNodeID
+          node  [ iRef ] = GMFNode[ aGMFNodeID ];
+          nodeID[ iRef ] = aGMFNodeID;
+        }
+
+        switch (token)
+        {
+        case GmfCorners: {
+          nodeDim = 1;
+          gp_Pnt GMFPnt ( node[0]->X(), node[0]->Y(), node[0]->Z() );
+          for ( int i=0; i<nbElem; i++ ) {
+            aVertex = TopoDS::Vertex( tabCorner[i] );
+            gp_Pnt aPnt = BRep_Tool::Pnt( aVertex );
+            if ( aPnt.Distance( GMFPnt ) < epsilon )
+              break;
+          }
+          break;
+        }
+        case GmfEdges: {
+          nodeDim = 2;
+          aGMFElement = theMeshDS->AddEdge( node[0], node[1] );
+          int iNode = 1;
+          if ( GMFNodeAssigne[ nodeID[0] ] == 0 || GMFNodeAssigne[ nodeID[0] ] == 2 )
+            iNode = 0;
+          shapeID = findEdgeID( node[iNode], theMeshDS, nbShapeEdge, tabEdge );
+          break;
+        }
+        case GmfRidges:
+          break;
+        case GmfTriangles: {
+          nodeDim = 3;
+          aGMFElement = theMeshDS->AddFace( node[0], node[1], node[2]);
+          shapeID = -1;
+          break;
+        }
+//         case GmfQuadrilaterals: {
+//           nodeDim = 4;
+//           aGMFElement = theMeshDS->AddFace( node[0], node[1], node[2], node[3] );
+//           shapeID = -1;
+//           break;
+//         }
+        case GmfTetrahedra: {
+          
+          // IN WORK
+          TopoDS_Shape aSolid;
+          // We always run GHS3D with "to mesh holes"==TRUE but we must not create
+          // tetras within holes depending on hypo option,
+          // so we first check if aTet is inside a hole and then create it 
+          if ( nbTriangle > 1 ) {
+            tetraShapeID = HOLE_ID; // negative tetraShapeID means not to create tetras if !toMeshHoles
+            int aGhs3dShapeID = ghs3dShapeID[iElem] - IdShapeRef;
+            if ( tabID[ aGhs3dShapeID ] == 0 ) {
+              TopAbs_State state;
+              aSolid = findShape(node, aSolid, tabShape, tabBox, nbShape, &state);
+              if ( toMeshHoles || state == TopAbs_IN )
+                tetraShapeID = theMeshDS->ShapeToIndex( aSolid );
+              tabID[ aGhs3dShapeID ] = tetraShapeID;
+            }
+            else
+              tetraShapeID = tabID[ aGhs3dShapeID ];
+          }
+          else if ( nbShape > 1 ) {
+            // Case where nbTriangle == 1 while nbShape == 2 encountered
+            // with compound of 2 boxes and "To mesh holes"==False,
+            // so there are no subdomains specified for each tetrahedron.
+            // Try to guess a solid by a node already bound to shape
+            tetraShapeID = 0;
+            for ( int i=0; i<4 && tetraShapeID==0; i++ ) {
+              if ( nodeAssigne[ nodeID[i] ] == 1 &&
+                  node[i]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_3DSPACE &&
+                  node[i]->getshapeId() > 1 )
+              {
+                tetraShapeID = node[i]->getshapeId();
+              }
+            }
+            if ( tetraShapeID==0 ) {
+              aSolid = findShape(node, aSolid, tabShape, tabBox, nbShape);
+              tetraShapeID = theMeshDS->ShapeToIndex( aSolid );
+            }
+          }
+          // set new nodes and tetrahedron onto the shape
+          for ( int i=0; i<4; i++ ) {
+            if ( nodeAssigne[ nodeID[i] ] == 0 ) {
+              if ( tetraShapeID != HOLE_ID )
+                theMeshDS->SetNodeInVolume( node[i], tetraShapeID );
+              nodeAssigne[ nodeID[i] ] = tetraShapeID;
+            }
+          }
+          if ( toMeshHoles || tetraShapeID != HOLE_ID ) {
+            aGMFElement = theMeshDS->AddVolume( node[1], node[0], node[2], node[3] );
+            theMeshDS->SetMeshElementOnShape( aGMFElement, tetraShapeID );
+          }
+          
+          // IN WORK
+          
+          nodeDim = 5;
+          break;
+        }
+//         case GmfHexahedra: {
+//           nodeDim = 6;
+//           aGMFElement = theMeshDS->AddVolume( node[0], node[3], node[2], node[1],
+//                                             node[4], node[7], node[6], node[5] );
+//           break;
+//         }
+        default: continue;
+        }
+        if (token != GmfRidges)
+        {
+          for ( int i=0; i<nbRef; i++ ) {
+              if ( GMFNodeAssigne[ nodeID[i] ] == 0 ) {
+                if      ( token == GmfCorners )   theMeshDS->SetNodeOnVertex( node[0], aVertex );
+                else if ( token == GmfEdges )     theMeshDS->SetNodeOnEdge( node[i], shapeID );
+                else if ( token == GmfTriangles ) theMeshDS->SetNodeOnFace( node[i], shapeID );
+                GMFNodeAssigne[ nodeID[i] ] = nodeDim;
+              }
+            }
+            if ( token != "Corners" )
+              theMeshDS->SetMeshElementOnShape( aGMFElement, shapeID );
+        }
+      } // for
+      
+      if ( !toMeshHoles ) {
+        map <int,const SMDS_MeshNode*>::iterator itOnNode = theGhs3dIdToNodeMap.find( nbVertices-(nbEnforcedVertices+nbEnforcedNodes) );
+        for ( ; itOnNode != theGhs3dIdToNodeMap.end(); ++itOnNode) {
+          if ( nodeAssigne[ itOnNode->first ] == HOLE_ID )
+            theMeshDS->RemoveFreeNode( itOnNode->second, 0 );
+        }
+      }
+      
+      delete [] node;
+      delete [] nodeID;
+      break;
+      } // case GmfTetrahedra
+    } // switch(token)
+  } // for
+  cout << std::endl;
+  
+#ifndef GMF_HAS_SUBDOMAIN_INFO
+#ifdef WNT
+  UnmapViewOfFile(mapPtr);
+  CloseHandle(hMapObject);
+  CloseHandle(fd);
+#else
+  munmap(mapPtr, length);
 #endif
-//=======================================================================
-//function : countShape
-//purpose  :
-//=======================================================================
+  close(fileOpen);
+#endif
+  
+  delete [] tabID;
+  delete [] tabCorner;
+  delete [] tabEdge;
+  delete [] nodeAssigne;
+  delete [] GMFNodeAssigne;
+  delete [] GMFNode;
+  
+  return true;
+}
 
-// template < class Mesh, class Shape >
-// static int countShape( Mesh* mesh, Shape shape ) {
-//   TopExp_Explorer expShape ( mesh->ShapeToMesh(), shape );
-//   int nbShape = 0;
-//   for ( ; expShape.More(); expShape.Next() ) {
-//       nbShape++;
-//   }
-//   return nbShape;
-// }
 
-#if GHS3D_VERSION >= 42
 //=======================================================================
 //function : readGMFFile
 //purpose  :
@@ -278,15 +976,11 @@ static bool readGMFFile(const char* theFile, SMESH_MesherHelper*   theHelper,
   // Read generated elements and nodes
   // ---------------------------------
 
-//  std::string token;
   int nbElem = 0, nbRef = 0;
   int aGMFNodeID = 0, shapeID;
   int *nodeAssigne;
-  std::map <GmfKwdCod,int> tabRef;
   SMDS_MeshNode** GMFNode;
-
-//  int nbEnfTri = theEnforcedTriangles.size();
-//  int nbEnfQuad = theEnforcedQuadrangles.size();
+  std::map <GmfKwdCod,int> tabRef;
 
   tabRef[GmfVertices]       = 3;
   tabRef[GmfCorners]        = 1;
@@ -316,7 +1010,6 @@ static bool readGMFFile(const char* theFile, SMESH_MesherHelper*   theHelper,
     GmfKwdCod token = it->first;
     nbRef    = it->second;
 
-
     nbElem = GmfStatKwd(InpMsh, token);
     if (nbElem > 0) {
       GmfGotoKwd(InpMsh, token);
@@ -337,37 +1030,16 @@ static bool readGMFFile(const char* theFile, SMESH_MesherHelper*   theHelper,
 
       for ( int iElem = 0; iElem < nbElem; iElem++ ) {
         aGMFID = iElem + 1;
-//        TIDSortedNodeSet theEnforcedNodesCopy = theEnforcedNodes;
-//        SMESH_MeshEditor::TListOfListOfNodes aGroupsOfNodes;
         if (ver == GmfFloat) {
           GmfGetLin(InpMsh, token, &VerTab_f[nbElem][0], &VerTab_f[nbElem][1], &VerTab_f[nbElem][2], &dummy);
           aGMFNode = theMesh->AddNode(VerTab_f[nbElem][0], VerTab_f[nbElem][1], VerTab_f[nbElem][2]);
-//          theEnforcedNodesCopy.insert(aGMFNode);
-//          if (!theEnforcedNodesCopy.insert(aGMFNode).second)
-//            std::cout << "No added into theEnforcedNodesCopy: " << aGMFNode;
-//          SMESH_OctreeNode::FindCoincidentNodes ( theEnforcedNodesCopy, &aGroupsOfNodes, 1e-5);
         }
         else {
           GmfGetLin(InpMsh, token, &VerTab_d[nbElem][0], &VerTab_d[nbElem][1], &VerTab_d[nbElem][2], &dummy);
           aGMFNode = theMesh->AddNode(VerTab_d[nbElem][0], VerTab_d[nbElem][1], VerTab_d[nbElem][2]);
-//          theEnforcedNodesCopy.insert(aGMFNode);
-//          if (!theEnforcedNodesCopy.insert(aGMFNode).second)
-//            std::cout << "No added into theEnforcedNodesCopy: " << aGMFNode;
-//          SMESH_OctreeNode::FindCoincidentNodes ( theEnforcedNodesCopy, &aGroupsOfNodes, 1e-5);
         }
         GMFNode[ aGMFID ] = aGMFNode;
         nodeAssigne[ aGMFID ] = 0;
-//        if (aGroupsOfNodes.size()) {
-//          std::cout << "Coincident node found when adding " << aGMFNode;
-//          SMESH_MeshEditor::TListOfListOfNodes::iterator grIt = aGroupsOfNodes.begin();
-//          for ( ; grIt != aGroupsOfNodes.end(); grIt++) {
-//            list<const SMDS_MeshNode*>& nodes = *grIt;
-//            list<const SMDS_MeshNode*>::iterator nIt = nodes.begin();
-//            for ( ; nIt != nodes.end(); nIt++ )
-//              std::cout << *nIt;
-//          }
-////          theMesh->RemoveNode(aGMFNode);
-//        }
       }
     }
     else if (token == GmfCorners && nbElem > 0) {
@@ -406,6 +1078,7 @@ static bool readGMFFile(const char* theFile, SMESH_MesherHelper*   theHelper,
         GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &id[iElem*tabRef[token]+3],
                   &id[iElem*tabRef[token]+4], &id[iElem*tabRef[token]+5], &id[iElem*tabRef[token]+6], &id[iElem*tabRef[token]+7], &dummy);
     }
+    std::cout << std::endl;
 
     switch (token) {
     case GmfCorners:
@@ -434,32 +1107,10 @@ static bool readGMFFile(const char* theFile, SMESH_MesherHelper*   theHelper,
           theHelper->AddEdge( node[0], node[1] ); break;
         case GmfTriangles: {
           theMesh->AddFace( node[0], node[1], node[2]);
-          // Enforced triangles
-//          for ( int iEnfElem = nbElem; iEnfElem < nbElem+nbEnfTri; iEnfElem++ )
-//          {
-//            for ( int iRef = 0; iRef < nbRef; iRef++ )
-//            {
-//              aGMFNodeID = id[iEnfElem*tabRef[token]+iRef]; // read nbRef aGMFNodeID
-//              enfNode  [ iRef ] = GMFNode[ aGMFNodeID ];
-//              nodeAssigne[ aGMFNodeID] = 1;
-//            }
-//            theMesh->AddFace( enfNode[0], enfNode[1], enfNode[2]);
-//          }
           break;
         }
         case GmfQuadrilaterals: {
           theMesh->AddFace( node[0], node[1], node[2], node[3] );
-          // Enforced Quadrilaterals
-//          for ( int iEnfElem = nbElem+nbEnfTri; iEnfElem < nbElem+nbEnfTri+nbEnfQuad; iEnfElem++ )
-//          {
-//            for ( int iRef = 0; iRef < nbRef; iRef++ )
-//            {
-//              aGMFNodeID = id[iEnfElem*tabRef[token]+iRef]; // read nbRef aGMFNodeID
-//              enfNode  [ iRef ] = GMFNode[ aGMFNodeID ];
-//              nodeAssigne[ aGMFNodeID] = 1;
-//            }
-//            theMesh->AddFace( enfNode[0], enfNode[1], enfNode[2], enfNode[3]);
-//          }
           break;
         }
         case GmfTetrahedra:
@@ -477,7 +1128,6 @@ static bool readGMFFile(const char* theFile, SMESH_MesherHelper*   theHelper,
     }
     }
   }
-  cout << std::endl;
 
   shapeID = theHelper->GetSubShapeID();
   for ( int i = 0; i < nbVertices; ++i )
@@ -503,7 +1153,7 @@ static bool writeGMFFile(const char*   theMeshFileName,
                          TIDSortedElemSet &               theEnforcedQuadrangles,
                          GHS3DPlugin_Hypothesis::TEnforcedVertexValues & theEnforcedVertices)
 {
-  MESSAGE("writeGMFFile");
+  MESSAGE("writeGMFFile w/o geometry");
   int idx, idxRequired, idxSol;
   const int dummyint = 0;
   GHS3DPlugin_Hypothesis::TEnforcedVertexValues::const_iterator vertexIt;
@@ -979,6 +1629,7 @@ static bool writeGMFFile(const char*   theMeshFileName,
                          TIDSortedElemSet &               theEnforcedQuadrangles,
                          GHS3DPlugin_Hypothesis::TEnforcedVertexValues & theEnforcedVertices)
 {
+  MESSAGE("writeGMFFile with geometry");
   int idx, nbv, nbev, nben, aGhs3dID = 0;
   const int dummyint = 0;
   GHS3DPlugin_Hypothesis::TEnforcedVertexValues::const_iterator vertexIt;
@@ -2152,197 +2803,6 @@ static bool writePoints (ofstream &                            theFile,
   return true;
 }
 
-//================================================================================
-/*!
- * \brief returns true if a triangle defined by the nodes is a temporary face on a
- * side facet of pyramid and defines sub-domian inside the pyramid
- */
-//================================================================================
-
-static bool isTmpFace(const SMDS_MeshNode* node1,
-                      const SMDS_MeshNode* node2,
-                      const SMDS_MeshNode* node3)
-{
-  // find a pyramid sharing the 3 nodes
-  //const SMDS_MeshElement* pyram = 0;
-  SMDS_ElemIteratorPtr vIt1 = node1->GetInverseElementIterator(SMDSAbs_Volume);
-  while ( vIt1->more() )
-  {
-    const SMDS_MeshElement* pyram = vIt1->next();
-    if ( pyram->NbCornerNodes() != 5 ) continue;
-    int i2, i3;
-    if ( (i2 = pyram->GetNodeIndex( node2 )) >= 0 &&
-         (i3 = pyram->GetNodeIndex( node3 )) >= 0 )
-    {
-      // Triangle defines sub-domian inside the pyramid if it's
-      // normal points out of the pyram
-
-      // make i2 and i3 hold indices of base nodes of the pyram while
-      // keeping the nodes order in the triangle
-      const int iApex = 4;
-      if ( i2 == iApex )
-        i2 = i3, i3 = pyram->GetNodeIndex( node1 );
-      else if ( i3 == iApex )
-        i3 = i2, i2 = pyram->GetNodeIndex( node1 );
-
-      int i3base = (i2+1) % 4; // next index after i2 within the pyramid base
-      return ( i3base != i3 );
-    }
-  }
-  return false;
-}
-
-//=======================================================================
-//function : findShapeID
-//purpose  : find the solid corresponding to GHS3D sub-domain following
-//           the technique proposed in GHS3D manual (available within
-//           ghs3d installation) in chapter "B.4 Subdomain (sub-region) assignment".
-//           In brief: normal of the triangle defined by the given nodes
-//           points out of the domain it is associated to
-//=======================================================================
-
-static int findShapeID(SMESH_Mesh&          mesh,
-                       const SMDS_MeshNode* node1,
-                       const SMDS_MeshNode* node2,
-                       const SMDS_MeshNode* node3,
-                       const bool           toMeshHoles)
-{
-  const int invalidID = 0;
-  SMESHDS_Mesh* meshDS = mesh.GetMeshDS();
-
-  // face the nodes belong to
-  const SMDS_MeshElement * face = meshDS->FindFace(node1,node2,node3);
-  if ( !face )
-    return isTmpFace(node1, node2, node3) ? HOLE_ID : invalidID;
-#ifdef _DEBUG_
-  std::cout << "bnd face " << face->GetID() << " - ";
-#endif
-  // geom face the face assigned to
-  SMESH_MeshEditor editor(&mesh);
-  int geomFaceID = editor.FindShape( face );
-  if ( !geomFaceID )
-    return isTmpFace(node1, node2, node3) ? HOLE_ID : invalidID;
-  TopoDS_Shape shape = meshDS->IndexToShape( geomFaceID );
-  if ( shape.IsNull() || shape.ShapeType() != TopAbs_FACE )
-    return invalidID;
-  TopoDS_Face geomFace = TopoDS::Face( shape );
-
-  // solids bounded by geom face
-  TopTools_IndexedMapOfShape solids, shells;
-  TopTools_ListIteratorOfListOfShape ansIt = mesh.GetAncestors(geomFace);
-  for ( ; ansIt.More(); ansIt.Next() ) {
-    switch ( ansIt.Value().ShapeType() ) {
-    case TopAbs_SOLID:
-      solids.Add( ansIt.Value() ); break;
-    case TopAbs_SHELL:
-      shells.Add( ansIt.Value() ); break;
-    default:;
-    }
-  }
-  // analyse found solids
-  if ( solids.Extent() == 0 || shells.Extent() == 0)
-    return invalidID;
-
-  const TopoDS_Solid& solid1 = TopoDS::Solid( solids(1) );
-  if ( solids.Extent() == 1 )
-  {
-    if ( toMeshHoles )
-      return meshDS->ShapeToIndex( solid1 );
-
-    // - Are we at a hole boundary face?
-    if ( shells(1).IsSame( BRepTools::OuterShell( solid1 )) )
-    { // - No, but maybe a hole is bound by two shapes? Does shells(1) touches another shell?
-      bool touch = false;
-      TopExp_Explorer eExp( shells(1), TopAbs_EDGE );
-      // check if any edge of shells(1) belongs to another shell
-      for ( ; eExp.More() && !touch; eExp.Next() ) {
-        ansIt = mesh.GetAncestors( eExp.Current() );
-        for ( ; ansIt.More() && !touch; ansIt.Next() ) {
-          if ( ansIt.Value().ShapeType() == TopAbs_SHELL )
-            touch = ( !ansIt.Value().IsSame( shells(1) ));
-        }
-      }
-      if (!touch)
-        return meshDS->ShapeToIndex( solid1 );
-    }
-  }
-  // find orientation of geom face within the first solid
-  TopExp_Explorer fExp( solid1, TopAbs_FACE );
-  for ( ; fExp.More(); fExp.Next() )
-    if ( geomFace.IsSame( fExp.Current() )) {
-      geomFace = TopoDS::Face( fExp.Current() );
-      break;
-    }
-  if ( !fExp.More() )
-    return invalidID; // face not found
-
-  // normale to triangle
-  gp_Pnt node1Pnt ( node1->X(), node1->Y(), node1->Z() );
-  gp_Pnt node2Pnt ( node2->X(), node2->Y(), node2->Z() );
-  gp_Pnt node3Pnt ( node3->X(), node3->Y(), node3->Z() );
-  gp_Vec vec12( node1Pnt, node2Pnt );
-  gp_Vec vec13( node1Pnt, node3Pnt );
-  gp_Vec meshNormal = vec12 ^ vec13;
-  if ( meshNormal.SquareMagnitude() < DBL_MIN )
-    return invalidID;
-
-  // get normale to geomFace at any node
-  bool geomNormalOK = false;
-  gp_Vec geomNormal;
-  const SMDS_MeshNode* nodes[3] = { node1, node2, node3 };
-  SMESH_MesherHelper helper( mesh ); helper.SetSubShape( geomFace );
-  for ( int i = 0; !geomNormalOK && i < 3; ++i )
-  {
-    // find UV of i-th node on geomFace
-    const SMDS_MeshNode* nNotOnSeamEdge = 0;
-    if ( helper.IsSeamShape( nodes[i]->getshapeId() )) {
-      if ( helper.IsSeamShape( nodes[(i+1)%3]->getshapeId() ))
-        nNotOnSeamEdge = nodes[(i+2)%3];
-      else
-        nNotOnSeamEdge = nodes[(i+1)%3];
-    }
-    bool uvOK;
-    gp_XY uv = helper.GetNodeUV( geomFace, nodes[i], nNotOnSeamEdge, &uvOK );
-    // check that uv is correct
-    if (uvOK) {
-      double tol = 1e-6;
-      TopoDS_Shape nodeShape = helper.GetSubShapeByNode( nodes[i], meshDS );
-      if ( !nodeShape.IsNull() )
-        switch ( nodeShape.ShapeType() )
-        {
-        case TopAbs_FACE:   tol = BRep_Tool::Tolerance( TopoDS::Face( nodeShape )); break;
-        case TopAbs_EDGE:   tol = BRep_Tool::Tolerance( TopoDS::Edge( nodeShape )); break;
-        case TopAbs_VERTEX: tol = BRep_Tool::Tolerance( TopoDS::Vertex( nodeShape )); break;
-        default:;
-        }
-      gp_Pnt nodePnt ( nodes[i]->X(), nodes[i]->Y(), nodes[i]->Z() );
-      BRepAdaptor_Surface surface( geomFace );
-      uvOK = ( nodePnt.Distance( surface.Value( uv.X(), uv.Y() )) < 2 * tol );
-      if ( uvOK ) {
-        // normale to geomFace at UV
-        gp_Vec du, dv;
-        surface.D1( uv.X(), uv.Y(), nodePnt, du, dv );
-        geomNormal = du ^ dv;
-        if ( geomFace.Orientation() == TopAbs_REVERSED )
-          geomNormal.Reverse();
-        geomNormalOK = ( geomNormal.SquareMagnitude() > DBL_MIN * 1e3 );
-      }
-    }
-  }
-  if ( !geomNormalOK)
-    return invalidID;
-
-  // compare normals
-  bool isReverse = ( meshNormal * geomNormal ) < 0;
-  if ( !isReverse )
-    return meshDS->ShapeToIndex( solid1 );
-
-  if ( solids.Extent() == 1 )
-    return HOLE_ID; // we are inside a hole
-  else
-    return meshDS->ShapeToIndex( solids(2) );
-}
-
 //=======================================================================
 //function : readResultFile
 //purpose  : 
@@ -2386,13 +2846,13 @@ static bool readResultFile(const int                       fileOpen,
 
   int *tab, *tabID, *nodeID, *nodeAssigne;
   double *coord;
-  const SMDS_MeshNode **node;
+  SMDS_MeshNode **node;
 
   tab    = new int[3];
   //tabID  = new int[nbShape];
   nodeID = new int[4];
   coord  = new double[3];
-  node   = new const SMDS_MeshNode*[4];
+  node   = new SMDS_MeshNode*[4];
 
   TopoDS_Shape aSolid;
   SMDS_MeshNode * aNewNode;
@@ -2809,7 +3269,8 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
   TCollection_AsciiString aGenericName
     = (char*) GHS3DPlugin_Hypothesis::GetFileName(_hyp).c_str();
 
-  TCollection_AsciiString aLogFileName, aResultFileName;
+  TCollection_AsciiString aResultFileName;
+  TCollection_AsciiString aLogFileName    = aGenericName + ".log";    // log
 #if GHS3D_VERSION < 42
   TCollection_AsciiString aFacesFileName, aPointsFileName;
   TCollection_AsciiString aBadResFileName, aBbResFileName;
@@ -2835,14 +3296,31 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
   }
 #else
   TCollection_AsciiString aGMFFileName, aRequiredVerticesFileName, aSolFileName;
+#ifndef GMF_HAS_SUBDOMAIN_INFO
+  TCollection_AsciiString aResultGMFFileName;
+#endif
 #ifdef _DEBUG_
   aGMFFileName    = aGenericName + ".mesh"; // GMF mesh file
+#ifndef GMF_HAS_SUBDOMAIN_INFO
+  // The output .mesh file does not contain yet the subdomain-info (Ghs3D 4.2)
+  aResultGMFFileName = aGenericName + "Vol.mesh"; // GMF mesh file
+  aResultFileName = aGenericName + ".noboite";// out points and volumes
+#else
   aResultFileName = aGenericName + "Vol.mesh"; // GMF mesh file
+#endif
   aRequiredVerticesFileName    = aGenericName + "_required.mesh"; // GMF required vertices mesh file
   aSolFileName    = aGenericName + "_required.sol"; // GMF solution file
 #else
-  aGMFFileName    = aGenericName + ".meshb"; // GMF mesh file
+#ifndef GMF_HAS_SUBDOMAIN_INFO
+  // The output .mesh file does not contain yet the subdomain-info (Ghs3D 4.2)
+//   aGMFFileName    = aGenericName + ".mesh"; // GMF mesh file
+  aResultGMFFileName = aGenericName + "Vol.meshb"; // GMF mesh file
+  aResultFileName = aGenericName + ".noboite";// out points and volumes
+#else
+//   aGMFFileName    = aGenericName + ".meshb"; // GMF mesh file
   aResultFileName = aGenericName + "Vol.meshb"; // GMF mesh file
+#endif
+  aGMFFileName    = aGenericName + ".meshb"; // GMF mesh file
   aRequiredVerticesFileName    = aGenericName + "_required.meshb"; // GMF required vertices mesh file
   aSolFileName    = aGenericName + ".solb"; // GMF solution file
 #endif
@@ -2858,6 +3336,9 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
   GHS3DPlugin_Hypothesis::TID2SizeMap nodeIDToSizeMap = GHS3DPlugin_Hypothesis::GetNodeIDToSizeMap(_hyp);
 //   GHS3DPlugin_Hypothesis::TID2SizeMap elemIDToSizeMap = GHS3DPlugin_Hypothesis::GetElementIDToSizeMap(_hyp);
 
+  int nbEnforcedVertices = enforcedVertices.size();
+  int nbEnforcedNodes = enforcedNodes.size();
+  
   SMESH_MesherHelper helper( theMesh );
   helper.SetSubShape( theShape );
 
@@ -2898,8 +3379,6 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
           writeFaces ( aFacesFile, *proxyMesh, theShape, 
                        aSmdsToGhs3dIdMap, anEnforcedNodeIdToGhs3dIdMap,
                        enforcedEdges, enforcedTriangles, enforcedQuadrangles));
-    int nbEnforcedVertices = enforcedVertices.size();
-    int nbEnforcedNodes = enforcedNodes.size();
 #else
     Ok = writeGMFFile(aGMFFileName.ToCString(), aRequiredVerticesFileName.ToCString(), aSolFileName.ToCString(),
                       helper, *proxyMesh,
@@ -2936,6 +3415,10 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
 #if GHS3D_VERSION < 42
       removeFile( aFacesFileName );
       removeFile( aPointsFileName );
+#else
+      removeFile( aGMFFileName );
+      removeFile( aRequiredVerticesFileName );
+      removeFile( aSolFileName );
 #endif
       removeFile( aSmdsToGhs3dIdMapFileName );
     }
@@ -2948,12 +3431,15 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
   // -----------------
 
   TCollection_AsciiString cmd = TCollection_AsciiString((char*)GHS3DPlugin_Hypothesis::CommandToRun( _hyp ).c_str() );
-#if GHS3D_VERSION < 42
+  // The output .mesh file does not contain yet the subdomain-info (Ghs3D 4.2)
+// #if GHS3D_VERSION < 42
   cmd += TCollection_AsciiString(" -f ") + aGenericName;  // file to read
-#else
-  cmd += TCollection_AsciiString(" --in ") + aGenericName;
+// #else
+#if GHS3D_VERSION >= 42
+  cmd += TCollection_AsciiString(" -IM ");
+//   cmd += TCollection_AsciiString(" --in ") + aGenericName;
 //   cmd += TCollection_AsciiString(" --required_vertices ") + aRequiredVerticesFileName;
-  cmd += TCollection_AsciiString(" --out ") + aGenericName;
+//    cmd += TCollection_AsciiString(" --out ") + aGenericName;
 #endif
   cmd += TCollection_AsciiString(" -Om 1>" ) + aLogFileName;  // dump into file
 
@@ -2970,6 +3456,7 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
   // read a result
   // --------------
 
+  bool toMeshHoles = _hyp ? _hyp->GetToMeshHoles(true) : GHS3DPlugin_Hypothesis::DefaultMeshHoles();
 #if GHS3D_VERSION < 42
   // Mapping the result file
 
@@ -2982,8 +3469,6 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
     Ok = false;
   }
   else {
-    bool toMeshHoles =
-      _hyp ? _hyp->GetToMeshHoles(true) : GHS3DPlugin_Hypothesis::DefaultMeshHoles();
     Ok = readResultFile( fileOpen,
 #ifdef WNT
                          aResultFileName.ToCString(),
@@ -2994,8 +3479,30 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
                          enforcedEdges, enforcedTriangles, enforcedQuadrangles );
   }
 #else
-  // TODO
-//   Ok = readGMFFile(aResultFileName.ToCString(), theMesh, enforcedNodesFromEnforcedElem, enforcedTriangles, enforcedQuadrangles);
+#ifndef GMF_HAS_SUBDOMAIN_INFO
+  // The output .mesh file does not contain yet the subdomain-info (Ghs3D 4.2)
+  
+  int fileOpen = open( aResultFileName.ToCString(), O_RDONLY);
+  if ( fileOpen < 0 ) {
+    std::cout << std::endl;
+    std::cout << "Can't open the " << aResultFileName.ToCString() << " GHS3D output file" << std::endl;
+    std::cout << "Log: " << aLogFileName << std::endl;
+    Ok = false;
+  }
+  else {
+#endif
+      Ok = readGMFFile(
+#ifndef GMF_HAS_SUBDOMAIN_INFO
+                       fileOpen,
+#endif
+                       aGenericName.ToCString(), theMesh,
+                       _nbShape, tabShape, tabBox, 
+                       aGhs3dIdToNodeMap, toMeshHoles,
+                       nbEnforcedVertices, nbEnforcedNodes, 
+                       enforcedNodes, enforcedTriangles, enforcedQuadrangles);
+#ifndef GMF_HAS_SUBDOMAIN_INFO
+  }
+#endif
 #endif
 
   // ---------------------
@@ -3030,6 +3537,8 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
     removeFile( aBbResFileName );
 #endif
     removeFile( aSmdsToGhs3dIdMapFileName );
+  // The output .mesh file does not contain yet the subdomain-info (Ghs3D 4.2)
+    removeFile( aResultFileName );
   }
   std::cout << "<" << aResultFileName.ToCString() << "> GHS3D output file ";
   if ( !Ok )
@@ -3196,7 +3705,8 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
                          enforcedEdges, enforcedTriangles, enforcedQuadrangles );
   }
 #else
-  Ok = readGMFFile(aResultFileName.ToCString(), aHelper, enforcedNodesFromEnforcedElem, enforcedTriangles, enforcedQuadrangles);
+  Ok = readGMFFile(aResultFileName.ToCString(), aHelper, 
+                   enforcedNodesFromEnforcedElem, enforcedTriangles, enforcedQuadrangles);
 #endif
   
   // ---------------------
index 3378ffb71071f23824d1b7a16687a4cc8a5fab7d..7c8358fa74f6b77ee4edf5335d146fe44e544dea 100644 (file)
 #include <map>
 #include <vector>
 
-#define GMFVERSION 2
+extern "C"
+{
+  #include "libmesh5.h"
+}
+
+#ifndef GMFVERSION
+#define GMFVERSION GmfDouble
+#endif
 #define GMFDIMENSION 3
 
 class GHS3DPlugin_Hypothesis;
index f0882b6dc5d95dd1ae3f850e9ba777a09886dd40..63952ba28f41805f3a6ed2aa454802407de0d5bd 100644 (file)
@@ -482,7 +482,7 @@ void GHS3DPlugin_Hypothesis_i::SetEnforcedMesh(SMESH::SMESH_IDSource_ptr theSour
   ExDescription.text = "Bad version of GHS3D. It must >= 4.2.";
   ExDescription.type = SALOME::BAD_PARAM;
   ExDescription.sourceFile = "GHS3DPlugin_Hypothesis::SetEnforcedMesh(theSource, theType)";
-  ExDescription.lineNumber = 445;
+  ExDescription.lineNumber = 463;
   throw SALOME::SALOME_Exception(ExDescription);
 #endif
 }