1 //=============================================================================
2 // File : GHS3DPlugin_GHS3D.cxx
4 // Author : Edward AGAPOV
6 // Copyright : CEA 2003
8 //=============================================================================
11 #include "GHS3DPlugin_GHS3D.hxx"
12 #include "SMESH_Gen.hxx"
13 #include "SMESH_Mesh.hxx"
15 #include "SMDS_MeshElement.hxx"
16 #include "SMDS_MeshNode.hxx"
18 #include <TopExp_Explorer.hxx>
20 #include "utilities.h"
31 //=============================================================================
35 //=============================================================================
37 GHS3DPlugin_GHS3D::GHS3DPlugin_GHS3D(int hypId, int studyId, SMESH_Gen* gen)
38 : SMESH_3D_Algo(hypId, studyId, gen)
40 MESSAGE("GHS3DPlugin_GHS3D::GHS3DPlugin_GHS3D");
42 _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type
45 //=============================================================================
49 //=============================================================================
51 GHS3DPlugin_GHS3D::~GHS3DPlugin_GHS3D()
53 MESSAGE("GHS3DPlugin_GHS3D::~GHS3DPlugin_GHS3D");
56 //=============================================================================
60 //=============================================================================
62 bool GHS3DPlugin_GHS3D::CheckHypothesis
64 const TopoDS_Shape& aShape,
65 SMESH_Hypothesis::Hypothesis_Status& aStatus)
67 // MESSAGE("GHS3DPlugin_GHS3D::CheckHypothesis");
68 aStatus = SMESH_Hypothesis::HYP_OK;
72 //=======================================================================
73 //function : writeFaces
75 //=======================================================================
77 static bool writeFaces (ofstream & theFile,
78 SMESHDS_Mesh * theMesh,
79 const map <int,int> & theSmdsToGhs3dIdMap)
84 // Loop from 1 to NB_ELEMS
85 // NB_NODES NODE_NB_1 NODE_NB_2 ... (NB_NODES + 1) times: DUMMY_INT
87 int nbFaces = theMesh->NbFaces();
91 const char* space = " ";
92 const int dummyint = 0;
95 theFile << space << nbFaces << space << dummyint << endl;
97 // Loop from 1 to NB_ELEMS
98 SMDS_FaceIteratorPtr it = theMesh->facesIterator();
102 const SMDS_MeshElement* elem = it->next();
103 const int nbNodes = elem->NbNodes();
104 theFile << space << nbNodes;
106 // NODE_NB_1 NODE_NB_2 ...
107 SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
108 while ( nodeIt->more() )
111 int aSmdsID = nodeIt->next()->GetID();
112 map<int,int>::const_iterator it = theSmdsToGhs3dIdMap.find( aSmdsID );
113 ASSERT( it != theSmdsToGhs3dIdMap.end() );
114 theFile << space << (*it).second;
117 // (NB_NODES + 1) times: DUMMY_INT
118 for ( int i=0; i<=nbNodes; i++)
119 theFile << space << dummyint;
127 //=======================================================================
128 //function : writePoints
130 //=======================================================================
132 static bool writePoints (ofstream & theFile,
133 SMESHDS_Mesh * theMesh,
134 map <int,int> & theSmdsToGhs3dIdMap,
135 map <int,const SMDS_MeshNode*> & theGhs3dIdToNodeMap)
140 // Loop from 1 to NB_NODES
143 int nbNodes = theMesh->NbNodes();
147 const char* space = " ";
148 const int dummyint = 0;
151 theFile << space << nbNodes << endl;
153 // Loop from 1 to NB_NODES
155 SMDS_NodeIteratorPtr it = theMesh->nodesIterator();
158 const SMDS_MeshNode* node = it->next();
159 theSmdsToGhs3dIdMap.insert( map <int,int>::value_type( node->GetID(), aGhs3dID ));
160 theGhs3dIdToNodeMap.insert (map <int,const SMDS_MeshNode*>::value_type( aGhs3dID, node ));
165 << space << node->X()
166 << space << node->Y()
167 << space << node->Z()
168 << space << dummyint;
176 //=======================================================================
179 //=======================================================================
181 static bool getInt( int & theValue, char * & theLine )
184 theValue = strtol( theLine, &ptr, 10 );
185 if ( ptr == theLine ||
186 // there must not be neither '.' nor ',' nor 'E' ...
187 (*ptr != ' ' && *ptr != '\n' && *ptr != '\0'))
190 DUMP( " " << theValue );
195 //=======================================================================
196 //function : getDouble
198 //=======================================================================
200 static bool getDouble( double & theValue, char * & theLine )
203 theValue = strtod( theLine, &ptr );
204 if ( ptr == theLine )
207 DUMP( " " << theValue );
212 //=======================================================================
213 //function : readLine
215 //=======================================================================
217 #define GHS3DPlugin_BUFLENGTH 256
218 #define GHS3DPlugin_ReadLine(aPtr,aBuf,aFile,aLineNb) \
219 { aPtr = fgets( aBuf, GHS3DPlugin_BUFLENGTH - 2, aFile ); aLineNb++; DUMP(endl); }
221 //=======================================================================
222 //function : readResult
224 //=======================================================================
226 static bool readResult(FILE * theFile,
227 SMESHDS_Mesh * theMesh,
228 const TopoDS_Shape& theShape,
229 map <int,const SMDS_MeshNode*>& theGhs3dIdToNodeMap)
234 // NB_ELEMENTS NB_NODES NB_INPUT_NODES (14 DUMMY_INT)
236 // (NB_ELEMENTS * 4) node nbs
238 // (NB_NODES) node XYZ
240 char aBuffer[ GHS3DPlugin_BUFLENGTH ];
244 // get shell to set nodes in
245 TopExp_Explorer exp( theShape, TopAbs_SHELL );
246 TopoDS_Shell aShell = TopoDS::Shell( exp.Current() );
248 // -------------------------------------
250 // read nb generated elements and nodes
251 // -------------------------------------
252 int nbElems = 0 , nbNodes = 0, nbInputNodes = 0;
253 GHS3DPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb );
255 !getInt( nbElems, aPtr ) ||
256 !getInt( nbNodes, aPtr ) ||
257 !getInt( nbInputNodes, aPtr))
260 // -------------------------------------------
262 // read element nodes and create tetrahedrons
263 // -------------------------------------------
264 GHS3DPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb );
265 for (int iElem = 0; iElem < nbElems; iElem++)
268 const SMDS_MeshNode * node[4];
269 for (int iNode = 0; iNode < 4; iNode++)
271 // read Ghs3d node ID
273 if (!aPtr || ! getInt ( ID, aPtr ))
275 GHS3DPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb );
276 if (!aPtr || ! getInt ( ID, aPtr ))
278 MESSAGE( "Cant read " << (iNode+1) << "-th node on line " << aLineNb );
282 // find/create a node with ID
283 map <int,const SMDS_MeshNode*>::iterator IdNode = theGhs3dIdToNodeMap.find( ID );
284 if ( IdNode == theGhs3dIdToNodeMap.end())
286 // ID is not yet in theGhs3dIdToNodeMap
287 ASSERT ( ID > nbInputNodes ); // it should be a new one
288 SMDS_MeshNode * aNewNode = theMesh->AddNode( 0.,0.,0. ); // read XYZ later
289 theMesh->SetNodeInVolume( aNewNode, aShell );
290 theGhs3dIdToNodeMap.insert
291 ( map <int,const SMDS_MeshNode*>::value_type( ID, aNewNode ));
292 node[ iNode ] = aNewNode;
296 node[ iNode ] = (*IdNode).second;
299 // create a tetrahedron
300 SMDS_MeshElement* aTet = theMesh->AddVolume( node[0], node[1], node[2], node[3] );
301 theMesh->SetMeshElementOnShape( aTet, theShape );
304 // ------------------------
306 // read and set nodes' XYZ
307 // ------------------------
308 GHS3DPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb );
309 for (int iNode = 0; iNode < nbNodes; iNode++)
311 // read 3 coordinates
313 for (int iCoord = 0; iCoord < 3; iCoord++)
315 if (!aPtr || ! getDouble ( coord[ iCoord ], aPtr ))
317 GHS3DPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb );
318 if (!aPtr || ! getDouble ( coord[ iCoord ], aPtr ))
320 MESSAGE( "Cant read " << (iCoord+1) << "-th node coord on line " << aLineNb );
325 // do not move old nodes
327 if (ID <= nbInputNodes)
330 map <int,const SMDS_MeshNode*>::iterator IdNode = theGhs3dIdToNodeMap.find( ID );
331 ASSERT ( IdNode != theGhs3dIdToNodeMap.end());
332 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*> ( (*IdNode).second );
335 theMesh->MoveNode( node, coord[0], coord[1], coord[2] );
341 //=============================================================================
343 *Here we are going to use the GHS3D mesher
345 //=============================================================================
347 bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh,
348 const TopoDS_Shape& theShape)
350 MESSAGE("GHS3DPlugin_GHS3D::Compute");
353 const char* wdName = "tmp";
354 QDir wd = QDir::root(); // "/"
355 if ( !wd.cd( wdName ) ) { // "/tmp"
356 MESSAGE( "Cannot find the " << wdName << " directory" );
360 const QString aGenericName = wd.filePath( "GHS3DTMP" );
361 const QString aFacesFileName = aGenericName + ".faces";
362 const QString aPointsFileName = aGenericName + ".points";
363 const QString aResultFileName = aGenericName + ".noboite";
364 const QString aErrorFileName = aGenericName + ".error";
367 QFile( aFacesFileName ).remove();
368 QFile( aPointsFileName ).remove();
369 QFile( aResultFileName ).remove();
370 QFile( aErrorFileName ).remove();
377 ofstream aFacesFile ( aFacesFileName.latin1() , ios::out);
378 ofstream aPointsFile ( aPointsFileName.latin1() , ios::out);
379 if (!aFacesFile || !aFacesFile.rdbuf()->is_open() ||
380 !aPointsFile || !aPointsFile.rdbuf()->is_open())
382 MESSAGE( "Can't write into " << wdName << " directory");
385 SMESHDS_Mesh* meshDS = theMesh.GetMeshDS();
386 map <int,int> aSmdsToGhs3dIdMap;
387 map <int,const SMDS_MeshNode*> aGhs3dIdToNodeMap;
390 (writePoints( aPointsFile, meshDS, aSmdsToGhs3dIdMap, aGhs3dIdToNodeMap ) &&
391 writeFaces ( aFacesFile, meshDS, aSmdsToGhs3dIdMap ));
403 QString cmd = "ghs3d "
404 "-m 1000 " // memory: 1000 M
405 "-f " + aGenericName + // file to read
406 " 1>" + aErrorFileName; // dump into file
407 if (system(cmd.latin1()))
409 MESSAGE ("Failed: <" << cmd.latin1() << ">");
417 FILE * aResultFile = fopen( aResultFileName.latin1(), "r" );
420 MESSAGE( "GHS3D ERROR: see " << aErrorFileName.latin1() );
424 Ok = readResult( aResultFile, meshDS, theShape, aGhs3dIdToNodeMap );
431 //=============================================================================
435 //=============================================================================
437 ostream & GHS3DPlugin_GHS3D::SaveTo(ostream & save)
442 //=============================================================================
446 //=============================================================================
448 istream & GHS3DPlugin_GHS3D::LoadFrom(istream & load)
453 //=============================================================================
457 //=============================================================================
459 ostream & operator << (ostream & save, GHS3DPlugin_GHS3D & hyp)
461 return hyp.SaveTo( save );
464 //=============================================================================
468 //=============================================================================
470 istream & operator >> (istream & load, GHS3DPlugin_GHS3D & hyp)
472 return hyp.LoadFrom( load );