Salome HOME
PAL18058 (4.x: computation of the 3D mesh (via 2D skin) by GHS3D is failed) V4_1_0rc2
authoreap <eap@opencascade.com>
Wed, 28 Nov 2007 13:11:24 +0000 (13:11 +0000)
committereap <eap@opencascade.com>
Wed, 28 Nov 2007 13:11:24 +0000 (13:11 +0000)
    partially fix regressions provided by the previous integration by RAZA

src/GHS3DPlugin_GHS3D.cxx
src/GHS3DPlugin_GHS3D.hxx

index 02437ef49d3ab7f1b6ddc9787b5e13045d42f6a7..4699432d3a812d8b4abf107a45109a1856520ea0 100644 (file)
@@ -29,10 +29,13 @@ using namespace std;
 #include "GHS3DPlugin_GHS3D.hxx"
 #include "SMESH_Gen.hxx"
 #include "SMESH_Mesh.hxx"
+#include "SMESH_Comment.hxx"
+#include "SMESH_MesherHelper.hxx"
 
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
 
+#include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <OSD_File.hxx>
 
@@ -53,6 +56,8 @@ using namespace std;
 #include <GProp_GProps.hxx>
 #include <Precision.hxx>
 
+#define castToNode(n) static_cast<const SMDS_MeshNode *>( n );
+
 #ifdef _DEBUG_
 #define DUMP(txt) \
 //  cout << txt
@@ -199,6 +204,92 @@ static bool writeFaces (ofstream &            theFile,
   return true;
 }
 
+//=======================================================================
+//function : writeFaces
+//purpose  : Write Faces in case if generate 3D mesh w/o geometry
+//=======================================================================
+
+static bool writeFaces (ofstream &            theFile,
+                        SMESHDS_Mesh *        theMesh,
+                        vector <const SMDS_MeshNode*> & theNodeByGhs3dId)
+{
+  // record structure:
+  //
+  // NB_ELEMS DUMMY_INT
+  // Loop from 1 to NB_ELEMS
+  //   NB_NODES NODE_NB_1 NODE_NB_2 ... (NB_NODES + 1) times: DUMMY_INT
+
+
+  int nbFaces = 0;
+  list< const SMDS_MeshElement* > faces;
+  list< const SMDS_MeshElement* >::iterator f;
+  map< const SMDS_MeshNode*,int >::iterator it;
+  SMDS_ElemIteratorPtr nodeIt;
+  const SMDS_MeshElement* elem;
+  int nbNodes;
+
+  const char* space    = "  ";
+  const int   dummyint = 0;
+
+  //get all faces from mesh
+  SMDS_FaceIteratorPtr eIt = theMesh->facesIterator();
+  while ( eIt->more() ) {
+    const SMDS_MeshElement* elem = eIt->next();
+    if ( !elem )
+      return false;
+    faces.push_back( elem );
+    nbFaces++;
+  }
+
+  if ( nbFaces == 0 )
+    return false;
+  
+  cout << "The initial 2D mesh contains " << nbFaces << " faces and ";
+
+  // NB_ELEMS DUMMY_INT
+  theFile << space << nbFaces << space << dummyint << endl;
+
+  // Loop from 1 to NB_ELEMS
+
+  map<const SMDS_MeshNode*,int> aNodeToGhs3dIdMap;
+  f = faces.begin();
+  for ( ; f != faces.end(); ++f )
+  {
+    // NB_NODES PER FACE
+    elem = *f;
+    nbNodes = elem->NbNodes();
+    theFile << space << nbNodes;
+
+    // NODE_NB_1 NODE_NB_2 ...
+    nodeIt = elem->nodesIterator();
+    while ( nodeIt->more() )
+    {
+      // find GHS3D ID
+      const SMDS_MeshNode* node = castToNode( nodeIt->next() );
+      int newId = aNodeToGhs3dIdMap.size() + 1; // ghs3d ids count from 1
+      it = aNodeToGhs3dIdMap.insert( make_pair( node, newId )).first;
+      theFile << space << it->second;
+    }
+
+    // (NB_NODES + 1) times: DUMMY_INT
+    for ( int i=0; i<=nbNodes; i++)
+      theFile << space << dummyint;
+
+    theFile << endl;
+  }
+
+  // put nodes to theNodeByGhs3dId vector
+  theNodeByGhs3dId.resize( aNodeToGhs3dIdMap.size() );
+  map<const SMDS_MeshNode*,int>::const_iterator n2id = aNodeToGhs3dIdMap.begin();
+  for ( ; n2id != aNodeToGhs3dIdMap.end(); ++ n2id)
+  {
+    theNodeByGhs3dId[ n2id->second - 1 ] = n2id->first; // ghs3d ids count from 1
+  }
+
+  return true;
+  
+}
+
 //=======================================================================
 //function : writePoints
 //purpose  : 
@@ -254,6 +345,56 @@ static bool writePoints (ofstream &                       theFile,
   return true;
 }
 
+//=======================================================================
+//function : writePoints
+//purpose  : 
+//=======================================================================
+
+static bool writePoints (ofstream &                            theFile,
+                         SMESHDS_Mesh *                        theMesh,
+                         const vector <const SMDS_MeshNode*> & theNodeByGhs3dId)
+{
+  // record structure:
+  //
+  // NB_NODES
+  // Loop from 1 to NB_NODES
+  //   X Y Z DUMMY_INT
+
+  //int nbNodes = theMesh->NbNodes();
+  int nbNodes = theNodeByGhs3dId.size();
+  if ( nbNodes == 0 )
+    return false;
+
+  const char* space    = "  ";
+  const int   dummyint = 0;
+
+  const SMDS_MeshNode* node;
+
+  // NB_NODES
+  theFile << space << nbNodes << endl;
+  cout << nbNodes << " nodes" << endl;
+
+  // Loop from 1 to NB_NODES
+
+  vector<const SMDS_MeshNode*>::const_iterator nodeIt = theNodeByGhs3dId.begin();
+  vector<const SMDS_MeshNode*>::const_iterator after  = theNodeByGhs3dId.end();
+  for ( ; nodeIt != after; ++nodeIt )
+  {
+    node = *nodeIt;
+
+    // X Y Z DUMMY_INT
+    theFile
+      << space << node->X()
+      << space << node->Y()
+      << space << node->Z()
+      << space << dummyint;
+
+    theFile << endl;
+  }
+
+  return true;
+}
+
 //=======================================================================
 //function : findShape
 //purpose  : 
@@ -311,6 +452,90 @@ static char* readMapIntLine(char* ptr, int tab[]) {
 //purpose  : 
 //=======================================================================
 
+static bool readResultFile(const int                      fileOpen,
+                           SMESHDS_Mesh*                  theMeshDS,
+                           TopoDS_Shape                   aSolid,
+                           vector <const SMDS_MeshNode*>& theNodeByGhs3dId) {
+
+  struct stat  status;
+  size_t       length;
+
+  char *ptr, *mapPtr;
+  char *tetraPtr;
+  char *shapePtr;
+
+  int fileStat;
+  int nbElems, nbNodes, nbInputNodes;
+  int nodeId, triangleId;
+  int tab[3];
+  int nbTriangle;
+  int ID, shapeID;
+
+  double coord [3];
+
+  SMDS_MeshNode * aNewNode;
+  const SMDS_MeshNode * node[4];
+  map <int,const SMDS_MeshNode*>::iterator IdNode;
+  SMDS_MeshElement* aTet;
+
+  // Read the file state
+  fileStat = fstat(fileOpen, &status);
+  length   = status.st_size;
+
+  // Mapping the result file into memory
+  ptr = (char *) mmap(0,length,PROT_READ,MAP_PRIVATE,fileOpen,0);
+  mapPtr = ptr;
+
+  ptr      = readMapIntLine(ptr, tab);
+  tetraPtr = ptr;
+
+  nbElems      = tab[0];
+  nbNodes      = tab[1];
+  nbInputNodes = tab[2];
+
+  theNodeByGhs3dId.resize( nbNodes );
+
+  // Reading the nodeId
+  for (int i=0; i < 4*nbElems; i++)
+    nodeId = strtol(ptr, &ptr, 10);
+
+  // Reading the nodeCoor and update the nodeMap
+  shapeID = theMeshDS->ShapeToIndex( aSolid );
+  for (int iNode=0; iNode < nbNodes; iNode++) {
+    for (int iCoor=0; iCoor < 3; iCoor++)
+      coord[ iCoor ] = strtod(ptr, &ptr);
+    if ((iNode+1) > nbInputNodes) {
+      aNewNode = theMeshDS->AddNode( coord[0],coord[1],coord[2] );
+      theMeshDS->SetNodeInVolume( aNewNode, shapeID );
+      theNodeByGhs3dId[ iNode ] = aNewNode;
+    }
+  }
+
+  // Reading the triangles
+  nbTriangle = strtol(ptr, &ptr, 10);
+
+  for (int i=0; i < 3*nbTriangle; i++)
+    triangleId = strtol(ptr, &ptr, 10);
+
+  shapePtr = ptr;
+
+  // Associating the tetrahedrons to the shapes
+  for (int iElem = 0; iElem < nbElems; iElem++) {
+    for (int iNode = 0; iNode < 4; iNode++) {
+      ID = strtol(tetraPtr, &tetraPtr, 10);
+      node[ iNode ] = theNodeByGhs3dId[ ID-1 ];
+    }
+    aTet = theMeshDS->AddVolume( node[1], node[0], node[2], node[3] );
+    shapeID = theMeshDS->ShapeToIndex( aSolid );
+    theMeshDS->SetMeshElementOnShape( aTet, shapeID );
+  }
+  if ( nbElems )
+    cout << nbElems << " tetrahedrons have been associated to " << nbTriangle << " shapes" << endl;
+  munmap(mapPtr, length);
+  close(fileOpen);
+  return true;
+}
+
 static bool readResultFile(const int                       fileOpen,
                            SMESHDS_Mesh*                   theMeshDS,
                            TopoDS_Shape                    tabShape[],
@@ -634,47 +859,140 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
   return Ok;
 }
 
-
 //=============================================================================
 /*!
- *  
+ *Here we are going to use the GHS3D mesher w/o geometry
  */
 //=============================================================================
-
-ostream & GHS3DPlugin_GHS3D::SaveTo(ostream & save)
+bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
+                                SMESH_MesherHelper* aHelper)
 {
-  return save;
-}
+  MESSAGE("GHS3DPlugin_GHS3D::Compute()");
 
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
+  SMESHDS_Mesh* meshDS = theMesh.GetMeshDS();
+  TopoDS_Shape theShape = aHelper->GetSubShape();
 
-istream & GHS3DPlugin_GHS3D::LoadFrom(istream & load)
-{
-  return load;
-}
+  // make a unique working file name
+  // to avoid access to the same files by eg different users
+  
+  TCollection_AsciiString aGenericName, aTmpDir = getTmpDir();
+  aGenericName = aTmpDir + "GHS3D_";
+#ifdef WIN32
+  aGenericName += GetCurrentProcessId();
+#else
+  aGenericName += getpid();
+#endif
+  aGenericName += "_";
+  aGenericName += meshDS->ShapeToIndex( theShape );
+
+  TCollection_AsciiString aFacesFileName, aPointsFileName, aResultFileName;
+  TCollection_AsciiString aBadResFileName, aBbResFileName, aLogFileName;
+  aFacesFileName  = aGenericName + ".faces";  // in faces
+  aPointsFileName = aGenericName + ".points"; // in points
+  aResultFileName = aGenericName + ".noboite";// out points and volumes
+  aBadResFileName = aGenericName + ".boite";  // out bad result
+  aBbResFileName  = aGenericName + ".bb";     // out vertex stepsize
+  aLogFileName    = aGenericName + ".log";    // log
+
+  // -----------------
+  // make input files
+  // -----------------
+
+  ofstream aFacesFile  ( aFacesFileName.ToCString()  , ios::out);
+  ofstream aPointsFile  ( aPointsFileName.ToCString()  , ios::out);
+  bool Ok =
+#ifdef WIN32
+    aFacesFile->is_open() && aPointsFile->is_open();
+#else
+    aFacesFile.rdbuf()->is_open() && aPointsFile.rdbuf()->is_open();
+#endif
 
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
+  if (!Ok)
+    return error( SMESH_Comment("Can't write into ") << aTmpDir.ToCString());
 
-ostream & operator << (ostream & save, GHS3DPlugin_GHS3D & hyp)
-{
-  return hyp.SaveTo( save );
-}
+  vector <const SMDS_MeshNode*> aNodeByGhs3dId;
 
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
+  Ok = (writeFaces ( aFacesFile, meshDS, aNodeByGhs3dId ) &&
+        writePoints( aPointsFile, meshDS, aNodeByGhs3dId));
+  
+  aFacesFile.close();
+  aPointsFile.close();
+  
+  if ( ! Ok ) {
+    if ( !getenv("GHS3D_KEEP_FILES") ) {
+      OSD_File( aFacesFileName ).Remove();
+      OSD_File( aPointsFileName ).Remove();
+    }
+    return error(COMPERR_BAD_INPUT_MESH);
+  }
 
-istream & operator >> (istream & load, GHS3DPlugin_GHS3D & hyp)
-{
-  return hyp.LoadFrom( load );
+  // -----------------
+  // run ghs3d mesher              WIN32???
+  // -----------------
+
+  // ghs3d need to know amount of memory it may use (MB).
+  // Default memory is defined at ghs3d installation but it may be not enough,
+  // so allow to use about all available memory
+  TCollection_AsciiString memory;
+#ifdef WIN32
+  // ????
+#else
+  struct sysinfo si;
+  int err = sysinfo( &si );
+  if ( !err ) {
+    int freeMem = si.totalram * si.mem_unit / 1024 / 1024;
+    memory = "-m ";
+    memory += int( 0.7 * freeMem );
+  }
+#endif
+  
+  TCollection_AsciiString cmd( "ghs3d " ); // command to run
+  cmd +=
+    memory +                 // memory
+    " -f " + aGenericName +  // file to read
+    " 1>" + aLogFileName;    // dump into file
+  
+  
+  
+  system( cmd.ToCString() ); // run
+
+  // --------------
+  // read a result
+  // --------------
+  int fileOpen;
+  fileOpen = open( aResultFileName.ToCString(), O_RDONLY);
+  if ( fileOpen < 0 ) {
+    cout << endl;
+    cout << "Error when opening the " << aResultFileName.ToCString() << " file" << endl;
+    cout << endl;
+    Ok = false;
+  }
+  else {
+    Ok = readResultFile( fileOpen, meshDS, theShape ,aNodeByGhs3dId );
+  }
+  
+  // ---------------------
+  // remove working files
+  // ---------------------
+
+  if ( Ok ) {
+    OSD_File( aLogFileName ).Remove();
+  }
+  else if ( OSD_File( aLogFileName ).Size() > 0 ) {
+    Ok = error( SMESH_Comment("See ")<< aLogFileName.ToCString() );
+  }
+  else {
+    OSD_File( aLogFileName ).Remove();
+  }
+
+  if ( !getenv("GHS3D_KEEP_FILES") )
+  {
+    OSD_File( aFacesFileName ).Remove();
+    OSD_File( aPointsFileName ).Remove();
+    OSD_File( aResultFileName ).Remove();
+    OSD_File( aBadResFileName ).Remove();
+    OSD_File( aBbResFileName ).Remove();
+  }
+  
+  return Ok;
 }
index 3cac48c536b7f729a6ded18b0d053c30b03b5786..e22bb3281db686a36fa0c799f593d2da576bd7be 100644 (file)
@@ -44,10 +44,8 @@ public:
   virtual bool Compute(SMESH_Mesh&         aMesh,
                       const TopoDS_Shape& aShape);
 
-  ostream & SaveTo(ostream & save);
-  istream & LoadFrom(istream & load);
-  friend ostream & operator << (ostream & save, GHS3DPlugin_GHS3D & hyp);
-  friend istream & operator >> (istream & load, GHS3DPlugin_GHS3D & hyp);
+  virtual bool Compute(SMESH_Mesh&         theMesh,
+                       SMESH_MesherHelper* aHelper);
 
 private:
   int _iShape;