]> SALOME platform Git repositories - plugins/ghs3dplugin.git/blob - src/GHS3DPlugin_GHS3D.cxx
Salome HOME
NPAL16132 (GHS3D execution failed in Salome version 4.0.0)
[plugins/ghs3dplugin.git] / src / GHS3DPlugin_GHS3D.cxx
1 // Copyright (C) 2005  CEA/DEN, EDF R&D, OPEN CASCADE, PRINCIPIA R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 //=============================================================================
20 // File      : GHS3DPlugin_GHS3D.cxx
21 // Created   : 
22 // Author    : Edward AGAPOV, modified by Lioka RAZAFINDRAZAKA (CEA) 09/02/2007
23 // Project   : SALOME
24 // Copyright : CEA 2003
25 // $Header$
26 //=============================================================================
27 using namespace std;
28
29 #include "GHS3DPlugin_GHS3D.hxx"
30 #include "SMESH_Gen.hxx"
31 #include "SMESH_Mesh.hxx"
32 #include "SMESH_Comment.hxx"
33
34 #include "SMDS_MeshElement.hxx"
35 #include "SMDS_MeshNode.hxx"
36
37 #include <TopExp_Explorer.hxx>
38 #include <OSD_File.hxx>
39
40 #include "utilities.h"
41
42 #ifndef WIN32
43 #include <sys/sysinfo.h>
44 #endif
45
46 //#include <Standard_Stream.hxx>
47
48 #include <BRepGProp.hxx>
49 #include <BRepBndLib.hxx>
50 #include <BRepClass_FaceClassifier.hxx>
51 #include <BRepClass3d_SolidClassifier.hxx>
52 #include <TopAbs.hxx>
53 #include <Bnd_Box.hxx>
54 #include <GProp_GProps.hxx>
55 #include <Precision.hxx>
56
57 #define castToNode(n) static_cast<const SMDS_MeshNode *>( n );
58
59 #ifdef _DEBUG_
60 #define DUMP(txt) \
61 //  cout << txt
62 #else
63 #define DUMP(txt)
64 #endif
65
66 extern "C"
67 {
68 #ifndef WNT
69 #include <unistd.h>
70 #include <sys/mman.h>
71 #endif
72 #include <sys/stat.h>
73 #include <fcntl.h>
74 }
75
76 //=============================================================================
77 /*!
78  *  
79  */
80 //=============================================================================
81
82 GHS3DPlugin_GHS3D::GHS3DPlugin_GHS3D(int hypId, int studyId, SMESH_Gen* gen)
83   : SMESH_3D_Algo(hypId, studyId, gen)
84 {
85   MESSAGE("GHS3DPlugin_GHS3D::GHS3DPlugin_GHS3D");
86   _name = "GHS3D_3D";
87   _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type
88   _onlyUnaryInput = false; // Compute() will be called on a compound of solids
89 //   _iShape=0;
90 //   _nbShape=0;
91 }
92
93 //=============================================================================
94 /*!
95  *  
96  */
97 //=============================================================================
98
99 GHS3DPlugin_GHS3D::~GHS3DPlugin_GHS3D()
100 {
101   MESSAGE("GHS3DPlugin_GHS3D::~GHS3DPlugin_GHS3D");
102 }
103
104 //=============================================================================
105 /*!
106  *  
107  */
108 //=============================================================================
109
110 bool GHS3DPlugin_GHS3D::CheckHypothesis ( SMESH_Mesh&                          aMesh,
111                                           const TopoDS_Shape&                  aShape,
112                                           SMESH_Hypothesis::Hypothesis_Status& aStatus )
113 {
114 //  MESSAGE("GHS3DPlugin_GHS3D::CheckHypothesis");
115   aStatus = SMESH_Hypothesis::HYP_OK;
116   return true;
117 }
118
119 //================================================================================
120 /*!
121  * \brief Write faces bounding theShape to file
122  */
123 //================================================================================
124
125 static bool writeFaces (ofstream &                      theFile,
126                         SMESHDS_Mesh *                  theMesh,
127                         const TopoDS_Shape&             theShape,
128                         vector <const SMDS_MeshNode*> & theNodeByGhs3dId)
129 {
130   // record structure:
131   //
132   // NB_ELEMS DUMMY_INT
133   // Loop from 1 to NB_ELEMS
134   // NB_NODES NODE_NB_1 NODE_NB_2 ... (NB_NODES + 1) times: DUMMY_INT
135
136   // get all faces bound to theShape
137
138   // Solids in the ShapeToMesh() can be meshed by different meshers,
139   // so we take faces only from the given shape
140   //TopoDS_Shape theShape = theMesh->ShapeToMesh();
141   int nbFaces = 0;
142   list< const SMDS_MeshElement* > faces;
143   // Use TopTools_IndexedMapOfShape in order not to take twice mesh faces from
144   // a geom face shared by two solids
145   TopTools_IndexedMapOfShape faceMap;
146   TopExp::MapShapes( theShape, TopAbs_FACE, faceMap );
147   SMESHDS_SubMesh* sm;
148   SMDS_ElemIteratorPtr eIt;
149
150   const char* space    = "  ";
151   const int   dummyint = 0;
152
153   list< const SMDS_MeshElement* >::iterator f;
154   map< const SMDS_MeshNode*,int >::iterator it;
155   SMDS_ElemIteratorPtr nodeIt;
156   const SMDS_MeshElement* elem;
157   int nbNodes;
158   //int aSmdsID;
159
160   for ( int i = 0; i < faceMap.Extent(); ++i ) {
161     sm = theMesh->MeshElements( faceMap( i+1 ) );
162     if ( sm ) {
163       eIt = sm->GetElements();
164       while ( eIt->more() ) {
165         faces.push_back( eIt->next() );
166         nbFaces++;
167       }
168     }
169   }
170
171   if ( nbFaces == 0 )
172     return false;
173
174   cout << "The initial 2D mesh contains " << nbFaces << " faces and ";
175
176   // NB_ELEMS DUMMY_INT
177   theFile << space << nbFaces << space << dummyint << endl;
178
179   // Loop from 1 to NB_ELEMS
180
181   map<const SMDS_MeshNode*,int> aNodeToGhs3dIdMap;
182   f = faces.begin();
183   for ( ; f != faces.end(); ++f )
184   {
185     // NB_NODES PER FACE
186     elem = *f;
187     nbNodes = elem->NbNodes();
188     theFile << space << nbNodes;
189
190     // NODE_NB_1 NODE_NB_2 ...
191     nodeIt = elem->nodesIterator();
192     while ( nodeIt->more() )
193     {
194       // find GHS3D ID
195       const SMDS_MeshNode* node = castToNode( nodeIt->next() );
196       int newId = aNodeToGhs3dIdMap.size() + 1; // ghs3d ids count from 1
197       it = aNodeToGhs3dIdMap.insert( make_pair( node, newId )).first;
198       theFile << space << it->second;
199     }
200
201     // (NB_NODES + 1) times: DUMMY_INT
202     for ( int i=0; i<=nbNodes; i++)
203       theFile << space << dummyint;
204
205     theFile << endl;
206   }
207
208   // put nodes to theNodeByGhs3dId vector
209   theNodeByGhs3dId.resize( aNodeToGhs3dIdMap.size() );
210   map<const SMDS_MeshNode*,int>::const_iterator n2id = aNodeToGhs3dIdMap.begin();
211   for ( ; n2id != aNodeToGhs3dIdMap.end(); ++ n2id)
212   {
213     theNodeByGhs3dId[ n2id->second - 1 ] = n2id->first; // ghs3d ids count from 1
214   }
215
216   return true;
217 }
218
219 //=======================================================================
220 //function : writePoints
221 //purpose  : 
222 //=======================================================================
223
224 static bool writePoints (ofstream &                            theFile,
225                          SMESHDS_Mesh *                        theMesh,
226                          const vector <const SMDS_MeshNode*> & theNodeByGhs3dId)
227 {
228   // record structure:
229   //
230   // NB_NODES
231   // Loop from 1 to NB_NODES
232   //   X Y Z DUMMY_INT
233
234   //int nbNodes = theMesh->NbNodes();
235   int nbNodes = theNodeByGhs3dId.size();
236   if ( nbNodes == 0 )
237     return false;
238
239   const char* space    = "  ";
240   const int   dummyint = 0;
241
242   const SMDS_MeshNode* node;
243
244   // NB_NODES
245   theFile << space << nbNodes << endl;
246   cout << nbNodes << " nodes" << endl;
247
248   // Loop from 1 to NB_NODES
249
250   vector<const SMDS_MeshNode*>::const_iterator nodeIt = theNodeByGhs3dId.begin();
251   vector<const SMDS_MeshNode*>::const_iterator after  = theNodeByGhs3dId.end();
252   for ( ; nodeIt != after; ++nodeIt )
253   {
254     node = *nodeIt;
255
256     // X Y Z DUMMY_INT
257     theFile
258       << space << node->X()
259       << space << node->Y()
260       << space << node->Z()
261       << space << dummyint;
262
263     theFile << endl;
264   }
265
266   return true;
267 }
268
269 //=======================================================================
270 //function : findSolid
271 //purpose  : 
272 //=======================================================================
273
274 static TopoDS_Shape findSolid(const SMDS_MeshNode *aNode[],
275                               TopoDS_Shape        aSolid,
276                               const TopoDS_Shape  shape[],
277                               const double        box[][6],
278                               const int           nShape) {
279
280   Standard_Real PX, PY, PZ;
281   int iShape;
282
283   PX = ( aNode[0]->X() + aNode[1]->X() + aNode[2]->X() + aNode[3]->X() ) / 4.0;
284   PY = ( aNode[0]->Y() + aNode[1]->Y() + aNode[2]->Y() + aNode[3]->Y() ) / 4.0;
285   PZ = ( aNode[0]->Z() + aNode[1]->Z() + aNode[2]->Z() + aNode[3]->Z() ) / 4.0;
286   gp_Pnt aPnt(PX, PY, PZ);
287
288   BRepClass3d_SolidClassifier SC (aSolid, aPnt, Precision::Confusion());
289   if ( not(SC.State() == TopAbs_IN) ) {
290     for (iShape = 0; iShape < nShape; iShape++) {
291       aSolid = shape[iShape];
292       if ( not( PX < box[iShape][0] || box[iShape][1] < PX ||
293                 PY < box[iShape][2] || box[iShape][3] < PY ||
294                 PZ < box[iShape][4] || box[iShape][5] < PZ) ) {
295         BRepClass3d_SolidClassifier SC (aSolid, aPnt, Precision::Confusion());
296         if (SC.State() == TopAbs_IN)
297           break;
298       }
299     }
300   }
301   return aSolid;
302 }
303
304 //=======================================================================
305 //function : readMapIntLine
306 //purpose  : 
307 //=======================================================================
308
309 static char* readMapIntLine(char* ptr, int tab[]) {
310   long int intVal;
311   cout << endl;
312
313   for ( int i=0; i<17; i++ ) {
314     intVal = strtol(ptr, &ptr, 10);
315     if ( i < 3 )
316       tab[i] = intVal;
317   }
318   return ptr;
319 }
320
321 //=======================================================================
322 //function : readLine
323 //purpose  : 
324 //=======================================================================
325
326 #define GHS3DPlugin_BUFLENGTH 256
327 #define GHS3DPlugin_ReadLine(aPtr,aBuf,aFile,aLineNb) \
328 {  aPtr = fgets( aBuf, GHS3DPlugin_BUFLENGTH - 2, aFile ); aLineNb++; DUMP(endl); }
329
330 #include <list>
331 //=======================================================================
332 //function : readResultFile
333 //purpose  : 
334 //=======================================================================
335
336 static bool readResultFile(const int                      fileOpen,
337                            SMESHDS_Mesh*                  theMeshDS,
338                            TopoDS_Shape                   tabShape[],
339                            double                         tabBox[][6],
340                            const int                      nShape,
341                            vector <const SMDS_MeshNode*>& theNodeByGhs3dId) {
342
343   struct stat  status;
344   size_t       length;
345
346   char *ptr, *mapPtr;
347   char *tetraPtr;
348   char *shapePtr;
349
350   int fileStat;
351   int nbElems, nbNodes, nbInputNodes;
352   int nodeId, triangleId;
353   int tab[3]/*, tabID[nShape]*/;
354   int nbTriangle;
355   int ID, shapeID, ghs3dShapeID;
356
357   double coord [3];
358   vector< int > tabID (nShape, 0);
359
360   TopoDS_Shape aSolid;
361   SMDS_MeshNode * aNewNode;
362   const SMDS_MeshNode * node[4];
363   map <int,const SMDS_MeshNode*>::iterator IdNode;
364   SMDS_MeshElement* aTet;
365
366 //   for (int i=0; i<nShape; i++)
367 //     tabID[i] = 0;
368
369   // Read the file state
370   fileStat = fstat(fileOpen, &status);
371   length   = status.st_size;
372
373   // Mapping the result file into memory
374   ptr = (char *) mmap(0,length,PROT_READ,MAP_PRIVATE,fileOpen,0);
375   mapPtr = ptr;
376
377   ptr      = readMapIntLine(ptr, tab);
378   tetraPtr = ptr;
379
380   nbElems      = tab[0];
381   nbNodes      = tab[1];
382   nbInputNodes = tab[2];
383
384   theNodeByGhs3dId.resize( nbNodes );
385
386   // Reading the nodeId
387   for (int i=0; i < 4*nbElems; i++)
388     nodeId = strtol(ptr, &ptr, 10);
389
390   // Reading the nodeCoor and update the nodeMap
391   for (int iNode=0; iNode < nbNodes; iNode++) {
392     for (int iCoor=0; iCoor < 3; iCoor++)
393       coord[ iCoor ] = strtod(ptr, &ptr);
394     if ((iNode+1) > nbInputNodes) {
395       aNewNode = theMeshDS->AddNode( coord[0],coord[1],coord[2] );
396       theNodeByGhs3dId[ iNode ] = aNewNode;
397     }
398   }
399
400   // Reading the triangles
401   nbTriangle = strtol(ptr, &ptr, 10);
402
403   for (int i=0; i < 3*nbTriangle; i++)
404     triangleId = strtol(ptr, &ptr, 10);
405
406   shapePtr = ptr;
407
408   // Associating the tetrahedrons to the shapes
409   for (int iElem = 0; iElem < nbElems; iElem++) {
410     for (int iNode = 0; iNode < 4; iNode++) {
411       ID = strtol(tetraPtr, &tetraPtr, 10);
412       node[ iNode ] = theNodeByGhs3dId[ ID-1 ];
413     }
414     aTet = theMeshDS->AddVolume( node[1], node[0], node[2], node[3] );
415     ghs3dShapeID = strtol(shapePtr, &shapePtr, 10);
416     if ( tabID[ ghs3dShapeID - 1 ] == 0 ) {
417       if (iElem == 0)
418         aSolid = tabShape[0];
419       aSolid = findSolid(node, aSolid, tabShape, tabBox, nShape /*nbTriangle*/);
420       shapeID = theMeshDS->ShapeToIndex( aSolid );
421       tabID[ ghs3dShapeID - 1] = shapeID;
422     }
423     else {
424       shapeID = tabID[ ghs3dShapeID - 1];
425     }
426     theMeshDS->SetMeshElementOnShape( aTet, shapeID );
427     // set new nodes on to the shape
428     SMDS_ElemIteratorPtr nodeIt = aTet->nodesIterator();
429     while ( nodeIt->more() ) {
430       const SMDS_MeshNode * n = castToNode( nodeIt->next() );
431       if ( !n->GetPosition()->GetShapeId() )
432         theMeshDS->SetNodeInVolume( n, shapeID );
433     }
434   }
435   if ( nbElems )
436     cout << nbElems << " tetrahedrons have been associated to " << nbTriangle << " shapes" << endl;
437   munmap(mapPtr, length);
438   close(fileOpen);
439   return true;
440 }
441
442 //=======================================================================
443 //function : getTmpDir
444 //purpose  : 
445 //=======================================================================
446
447 static TCollection_AsciiString getTmpDir()
448 {
449   TCollection_AsciiString aTmpDir;
450
451   char *Tmp_dir = getenv("SALOME_TMP_DIR");
452   if(Tmp_dir != NULL) {
453     aTmpDir = Tmp_dir;
454 #ifdef WIN32
455     if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\';
456 #else
457     if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/';
458 #endif      
459   }
460   else {
461 #ifdef WIN32
462     aTmpDir = TCollection_AsciiString("C:\\");
463 #else
464     aTmpDir = TCollection_AsciiString("/tmp/");
465 #endif
466   }
467   return aTmpDir;
468 }
469
470 //================================================================================
471 /*!
472  * \brief Look for a line containing a text in a file
473   * \retval bool - true if the line is found
474  */
475 //================================================================================
476
477 static bool findLineContaing(const TCollection_AsciiString& theText,
478                              const TCollection_AsciiString& theFile,
479                              TCollection_AsciiString &      theFoundLine)
480 {
481   bool found = false;
482   if ( FILE * aFile = fopen( theFile.ToCString(), "r" ))
483   {
484     char * aPtr;
485     char aBuffer[ GHS3DPlugin_BUFLENGTH ];
486     int aLineNb = 0;
487     do {
488       GHS3DPlugin_ReadLine( aPtr, aBuffer, aFile, aLineNb );
489       if ( aPtr ) {
490         theFoundLine = aPtr;
491         found = theFoundLine.Search( theText ) >= 0;
492       }
493     } while ( aPtr && !found );
494
495     fclose( aFile );
496   }
497   return found;
498 }
499
500 //================================================================================
501 /*!
502  * \brief Decrease amount of memory GHS3D may use until it can allocate it
503   * \param nbMB - memory size to adjust
504   * \param aLogFileName - file for GHS3D output
505   * \retval bool - false if GHS3D can not run for any reason
506  */
507 //================================================================================
508
509 static void adjustMemory(int & nbMB, const TCollection_AsciiString & aLogFileName)
510 {
511   // the second call to ghs3d hangs up until C-d RET typed in terminal,
512   // if SALOME was launched with args, so we check memory allocation ourself
513   try {
514     char* buf = new char[ nbMB * 1024 * 1024 ];
515     delete [] buf;
516   }
517   catch (...) {
518     nbMB = int( double(nbMB) * 0.75 );
519     adjustMemory( nbMB, aLogFileName );
520   }
521 //   TCollection_AsciiString cmd( "ghs3d -m " );
522 //   cmd += nbMB;
523 //   cmd += " 1>";
524 //   cmd += aLogFileName;
525
526 //   system( cmd.ToCString() ); // run
527
528 //   // analyse log file
529 //   TCollection_AsciiString foundLine;
530 //   if ( findLineContaing( "UNABLE TO ALLOCATE MEMORY",aLogFileName,foundLine))
531 //   {
532 //     nbMB = int( double(nbMB) * 0.75 );
533 //     adjustMemory( nbMB, aLogFileName );
534 //   }
535 }
536
537 //=============================================================================
538 /*!
539  *Here we are going to use the GHS3D mesher
540  */
541 //=============================================================================
542
543 bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
544                                 const TopoDS_Shape& theShape)
545 {
546   // theShape is a compound of solids as _onlyUnaryInput = false
547   bool Ok(false);
548   SMESHDS_Mesh* meshDS = theMesh.GetMeshDS();
549
550   int _nbShape = 0;
551   /*if (_iShape == 0 && _nbShape == 0)*/ {
552     cout << endl;
553     cout << "Ghs3d execution..." << endl;
554     cout << endl;
555     
556     //TopExp_Explorer exp (meshDS->ShapeToMesh(), TopAbs_SOLID);
557     TopExp_Explorer exp (theShape, TopAbs_SOLID);
558     for (; exp.More(); exp.Next())
559       _nbShape++;
560   }
561   
562   //_iShape++;
563
564   /*if ( _iShape == _nbShape )*/ {
565
566     // create bounding box for every shape
567
568     int iShape = 0;
569     TopoDS_Shape tabShape[_nbShape];
570     double tabBox[_nbShape][6];
571     Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
572
573     TopExp_Explorer expBox (theShape, TopAbs_SOLID);
574     for (; expBox.More(); expBox.Next()) {
575       tabShape[iShape] = expBox.Current();
576       Bnd_Box BoundingBox;
577       BRepBndLib::Add(expBox.Current(), BoundingBox);
578       BoundingBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
579       tabBox[iShape][0] = Xmin; tabBox[iShape][1] = Xmax;
580       tabBox[iShape][2] = Ymin; tabBox[iShape][3] = Ymax;
581       tabBox[iShape][4] = Zmin; tabBox[iShape][5] = Zmax;
582       iShape++;
583     }
584
585     // make a unique working file name
586     // to avoid access to the same files by eg different users
587   
588     TCollection_AsciiString aGenericName, aTmpDir = getTmpDir();
589     aGenericName = aTmpDir + "GHS3D_";
590 #ifdef WIN32
591     aGenericName += GetCurrentProcessId();
592 #else
593     aGenericName += getpid();
594 #endif
595     aGenericName += "_";
596     aGenericName += meshDS->ShapeToIndex( theShape );
597
598     TCollection_AsciiString aFacesFileName, aPointsFileName, aResultFileName;
599     TCollection_AsciiString aBadResFileName, aBbResFileName, aLogFileName;
600     aFacesFileName  = aGenericName + ".faces";  // in faces
601     aPointsFileName = aGenericName + ".points"; // in points
602     aResultFileName = aGenericName + ".noboite";// out points and volumes
603     aBadResFileName = aGenericName + ".boite";  // out bad result
604     aBbResFileName  = aGenericName + ".bb";     // out vertex stepsize
605     aLogFileName    = aGenericName + ".log";    // log
606
607     // -----------------
608     // make input files
609     // -----------------
610
611     ofstream aFacesFile  ( aFacesFileName.ToCString()  , ios::out);
612     ofstream aPointsFile ( aPointsFileName.ToCString() , ios::out);
613     // bool Ok =
614     Ok =
615 #ifdef WIN32
616       aFacesFile->is_open() && aPointsFile->is_open();
617 #else
618       aFacesFile.rdbuf()->is_open() && aPointsFile.rdbuf()->is_open();
619 #endif
620     if (!Ok)
621         return error(dfltErr(), SMESH_Comment("Can't write into ") << aTmpDir);
622
623     vector <const SMDS_MeshNode*> aNodeByGhs3dId;
624
625     Ok = ( writeFaces ( aFacesFile,  meshDS, theShape, aNodeByGhs3dId ) &&
626            writePoints( aPointsFile, meshDS, aNodeByGhs3dId ));
627
628     aFacesFile.close();
629     aPointsFile.close();
630
631     if ( ! Ok ) {
632       if ( !getenv("GHS3D_KEEP_FILES") ) {
633         OSD_File( aFacesFileName ).Remove();
634         OSD_File( aPointsFileName ).Remove();
635       }
636       return error(COMPERR_BAD_INPUT_MESH);
637     }
638
639     // -----------------
640     // run ghs3d mesher              WIN32???
641     // -----------------
642
643     // ghs3d need to know amount of memory it may use (MB).
644     // Default memory is defined at ghs3d installation but it may be not enough,
645     // so allow to use about all available memory
646
647     TCollection_AsciiString memory;
648 #ifdef WIN32
649     // ????
650 #else
651     struct sysinfo si;
652     int err = sysinfo( &si );
653     if ( !err ) {
654         int MB = ( si.freeram + si.freeswap ) * si.mem_unit / 1024 / 1024;
655         MB = int( double( MB ) * 0.9 );
656         adjustMemory( MB, aLogFileName );
657         memory = "-m ";
658         memory += MB;
659     }
660 #endif
661
662     OSD_File( aResultFileName ).Remove(); // old file prevents writing a new one
663
664     TCollection_AsciiString cmd( "ghs3d " ); // command to run
665     cmd +=
666       memory +                // memory
667       " -c 0"                 // 0 - mesh all components, 1 - keep only the main component
668       " -f " + aGenericName + // file to read
669       " 1>" + aLogFileName;   // dump into file
670
671     MESSAGE("GHS3DPlugin_GHS3D::Compute() " << cmd );
672     system( cmd.ToCString() ); // run
673
674     cout << endl;
675     cout << "End of Ghs3d execution !" << endl;
676
677     // --------------
678     // read a result
679     // --------------
680
681     // Mapping the result file
682
683     int fileOpen;
684     fileOpen = open( aResultFileName.ToCString(), O_RDONLY);
685     if ( fileOpen < 0 ) {
686       cout << endl;
687       cout << "Error when opening the " << aResultFileName.ToCString() << " file" << endl;
688       cout << endl;
689       Ok = false;
690     }
691     else {
692       Ok = readResultFile( fileOpen, meshDS, tabShape, tabBox, _nbShape, aNodeByGhs3dId );
693     }
694
695   // ---------------------
696   // remove working files
697   // ---------------------
698
699     if ( Ok )
700     {
701       OSD_File( aLogFileName ).Remove();
702     }
703     else if ( OSD_File( aLogFileName ).Size() > 0 )
704     {
705       // get problem description from the log file
706       SMESH_Comment comment;
707       TCollection_AsciiString foundLine;
708       if ( findLineContaing( "has expired",aLogFileName,foundLine) &&
709            foundLine.Search("Licence") >= 0)
710       {
711         foundLine.LeftAdjust();
712         comment << foundLine;
713       }
714       if ( findLineContaing( "%% ERROR",aLogFileName,foundLine))
715       {
716         foundLine.LeftAdjust();
717         comment << foundLine;
718       }
719       if ( findLineContaing( "%% NO SAVING OPERATION",aLogFileName,foundLine))
720       {
721         comment << "Too many elements generated for a trial version.\n";
722       }
723       if ( comment.empty() )
724         comment << "See " << aLogFileName << " for problem description";
725       else
726         comment << "See " << aLogFileName << " for more information";
727       error(COMPERR_ALGO_FAILED, comment);
728     }
729     else
730     {
731       // the log file is empty
732       OSD_File( aLogFileName ).Remove();
733       error(COMPERR_ALGO_FAILED, "ghs3d: command not found" );
734     }
735
736     if ( !getenv("GHS3D_KEEP_FILES") )
737     {
738       OSD_File( aFacesFileName ).Remove();
739       OSD_File( aPointsFileName ).Remove();
740       OSD_File( aResultFileName ).Remove();
741       OSD_File( aBadResFileName ).Remove();
742       OSD_File( aBbResFileName ).Remove();
743     }
744   }
745   
746   return Ok;
747 }