Salome HOME
Imported using TkCVS
[plugins/ghs3dprlplugin.git] / src / GHS3DPRLPlugin / GHS3DPRLPlugin_GHS3DPRL.cxx
1 //  GHS3DPRLPlugin : C++ implementation
2 //
3 //  Copyright (C) 2006  OPEN CASCADE, CEA/DEN, EDF R&D
4 //
5 //  This library is free software; you can redistribute it and/or
6 //  modify it under the terms of the GNU Lesser General Public
7 //  License as published by the Free Software Foundation; either
8 //  version 2.1 of the License.
9 //
10 //  This library is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 //  Lesser General Public License for more details.
14 //
15 //  You should have received a copy of the GNU Lesser General Public
16 //  License along with this library; if not, write to the Free Software
17 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 //
19 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
20 //
21 //
22 // File    : GHS3DPRLPlugin_GHS3DPRL.cxx
23 // Author  : Christian VAN WAMBEKE (CEA) (from Hexotic plugin Lioka RAZAFINDRAZAKA)
24 // Date    : 2007/02/01
25 // Project : SALOME
26 //=============================================================================
27 using namespace std;
28
29 #include "GHS3DPRLPlugin_GHS3DPRL.hxx"
30 #include "GHS3DPRLPlugin_Hypothesis.hxx"
31 // #include "GHS3DPRLPlugin_Mesher.hxx"
32
33 #include "SMDS_MeshElement.hxx"
34 #include "SMDS_MeshNode.hxx"
35
36 #include <TopExp_Explorer.hxx>
37 #include <OSD_File.hxx>
38
39 #include "utilities.h"
40
41 #ifndef WIN32
42 #include <sys/sysinfo.h>
43 #endif
44
45 #ifdef _DEBUG_
46 #define DUMP(txt) \
47 //  cout << txt
48 #else
49 #define DUMP(txt)
50 #endif
51
52 #include <SMESH_Gen.hxx>
53 #include <SMESHDS_Mesh.hxx>
54 #include <SMESH_ControlsDef.hxx>
55
56 #include <list>
57 #include <TCollection_AsciiString.hxx>
58
59 //=============================================================================
60
61 GHS3DPRLPlugin_GHS3DPRL::GHS3DPRLPlugin_GHS3DPRL(int hypId, int studyId, SMESH_Gen* gen)
62   : SMESH_3D_Algo(hypId, studyId, gen)
63 {
64   MESSAGE("GHS3DPRLPlugin_GHS3DPRL::GHS3DPRLPlugin_GHS3DPRL");
65   _name = "GHS3DPRL_3D";
66   _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type
67   _countSubMesh=0;
68   _nodeRefNumber=0;
69   _compatibleHypothesis.push_back("GHS3DPRL_Parameters");
70 }
71
72 //=============================================================================
73
74 GHS3DPRLPlugin_GHS3DPRL::~GHS3DPRLPlugin_GHS3DPRL()
75 {
76   MESSAGE("GHS3DPRLPlugin_GHS3DPRL::~GHS3DPRLPlugin_GHS3DPRL");
77 }
78
79 //=============================================================================
80
81 bool GHS3DPRLPlugin_GHS3DPRL::CheckHypothesis
82                          (SMESH_Mesh& aMesh,
83                           const TopoDS_Shape& aShape,
84                           SMESH_Hypothesis::Hypothesis_Status& aStatus)
85 {
86   MESSAGE("GHS3DPRLPlugin_GHS3DPRL::CheckHypothesis");
87
88   _hypothesis = NULL;
89
90   list<const SMESHDS_Hypothesis*>::const_iterator itl;
91   const SMESHDS_Hypothesis* theHyp;
92
93   const list<const SMESHDS_Hypothesis*>& hyps = GetUsedHypothesis(aMesh, aShape);
94   int nbHyp = hyps.size();
95   if (!nbHyp)
96   {
97     aStatus = SMESH_Hypothesis::HYP_OK;
98     return true;  // can work with no hypothesis
99   }
100
101   itl = hyps.begin();
102   theHyp = (*itl); // use only the first hypothesis
103
104   string hypName = theHyp->GetName();
105   if (hypName == "GHS3DPRL_Parameters")
106   {
107     _hypothesis = static_cast<const GHS3DPRLPlugin_Hypothesis*> (theHyp);
108     ASSERT(_hypothesis);
109     aStatus = SMESH_Hypothesis::HYP_OK;
110   }
111   else
112     aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
113
114   return aStatus == SMESH_Hypothesis::HYP_OK;
115 }
116
117 //=======================================================================
118
119 static bool writeGHS3DPRLFiles (const TCollection_AsciiString &  GHS3DPRL_In,
120                                 SMESHDS_Mesh *                   theMesh,
121                                 map <int,int> &                  theSmdsToGHS3DPRLIdMap,
122                                 map <int,const SMDS_MeshNode*> & theGHS3DPRLIdToNodeMap)
123 {
124    bool Ok;
125    TCollection_AsciiString namefile(GHS3DPRL_In);
126    namefile+=".points";
127    OSD_File(namefile).Remove();
128    ofstream theFile;
129    theFile.open(namefile.ToCString(),ios::out);
130 #ifdef WIN32
131    Ok=theFile->is_open();
132 #else
133    Ok=theFile.rdbuf()->is_open();
134 #endif
135    if (!Ok)
136    {
137       INFOS("Can't write into "<<namefile.ToCString());
138       return false;
139    }
140    cout<<endl<<"Creating GHS3DPRL processed mesh file : "<<namefile<<endl;
141
142    int nbVertices=theMesh->NbNodes();
143    int nbFaces=theMesh->NbFaces();        //triangles or quadrangles
144    const char* space="  ";
145    const int dummyint=1;                  //nrs,nsd,refnum=1 (for wrap)
146
147    // Writing SMESH points into GHS3DPRL File.points
148    theFile<<nbVertices<<endl;
149
150    int aSmdsNodeID = 1;
151    const SMDS_MeshNode* node_2;
152    SMDS_NodeIteratorPtr itOnNode = theMesh->nodesIterator();
153    while (itOnNode->more())
154    {
155       node_2 = itOnNode->next();
156       theSmdsToGHS3DPRLIdMap.insert(map <int,int>::value_type(node_2->GetID(),aSmdsNodeID));
157       theGHS3DPRLIdToNodeMap.insert(map <int,const SMDS_MeshNode*>::value_type(aSmdsNodeID,node_2));
158       aSmdsNodeID++;
159       theFile<<node_2->X()<<space<<node_2->Y()<<space<<node_2->Z()<<space<<dummyint<<endl;
160    }
161    //no specified points;
162    theFile.close();
163
164    namefile=GHS3DPRL_In+".faces";
165    OSD_File(namefile).Remove();
166    theFile.open(namefile.ToCString(),ios::out);
167 #ifdef WIN32
168    Ok=theFile->is_open();
169 #else
170    Ok=theFile.rdbuf()->is_open();
171 #endif
172    if (!Ok)
173    {
174       INFOS("Can't write into "<<namefile.ToCString());
175       return false;
176    }
177    cout<<endl<<"Creating GHS3DPRL processed mesh file : "<<namefile<<endl;
178
179    // Writing SMESH faces into GHS3DPRL File.faces
180    theFile<<nbFaces<<" 0"<<endl;   //NB_ELEMS DUMMY_INT
181                                    //" 0" is a reserved parameter
182
183    const SMDS_MeshElement* aFace;
184    map<int,int>::const_iterator itOnSmdsNode;
185    SMDS_ElemIteratorPtr itOnFaceNode;
186    SMDS_FaceIteratorPtr itOnSmdsFace = theMesh->facesIterator();
187    long nbNoTriangles=0;
188    while (itOnSmdsFace->more())
189    {
190       aFace=itOnSmdsFace->next();
191       itOnFaceNode=aFace->nodesIterator();
192       const int nbNodes=aFace->NbNodes();
193       if (nbNodes!=3) nbNoTriangles++;
194       theFile<<nbNodes<<space;        // NB_NODES
195       while (itOnFaceNode->more())
196       {
197           aSmdsNodeID=itOnFaceNode->next()->GetID();
198           itOnSmdsNode=theSmdsToGHS3DPRLIdMap.find(aSmdsNodeID);
199           ASSERT(itOnSmdsNode!=theSmdsToGHS3DPRLIdMap.end());
200           theFile<<space<<(*itOnSmdsNode).second; //NODE_1 NODE_2 ...
201       }
202       //(NB_NODES+1) times: DUMMY_INT
203       for ( int i=0; i<=nbNodes; i++) theFile<<space<<dummyint;
204       theFile<<endl;
205    }
206    theFile.close();
207
208    cout<<"Processed mesh files created, they contains :\n";
209    cout<<"    "<<nbVertices<<" vertices\n";
210    if (nbNoTriangles==0)
211       cout<<"    "<<nbFaces<<" faces\n\n";
212    else
213       cout<<"    "<<nbFaces<<" faces with "<<nbNoTriangles<<"faces no triangles\n\n";
214    return true;
215 }
216
217 //=======================================================================
218
219 static bool getInt( int & theValue, char * & theLine )
220 {
221   char *ptr;
222   theValue = strtol( theLine, &ptr, 10 );
223   if ( ptr == theLine ||
224       // there must not be neither '.' nor ',' nor 'E' ...
225       (*ptr != ' ' && *ptr != '\n' && *ptr != '\0'))
226     return false;
227
228   DUMP( "  " << theValue );
229   theLine = ptr;
230   return true;
231 }
232
233 //=======================================================================
234
235 static bool getDouble( double & theValue, char * & theLine )
236 {
237   char *ptr;
238   theValue = strtod( theLine, &ptr );
239   if ( ptr == theLine )
240     return false;
241
242   DUMP( "   " << theValue );
243   theLine = ptr;
244   return true;
245 }
246
247 //=======================================================================
248
249 #define GHS3DPRLPlugin_BUFLENGTH 256
250 #define GHS3DPRLPlugin_ReadLine(aPtr,aBuf,aFile,aLineNb) \
251 {  aPtr = fgets( aBuf, GHS3DPRLPlugin_BUFLENGTH - 2, aFile ); aLineNb++; DUMP(endl); }
252
253 //=======================================================================
254
255 static bool readResult(FILE *                           theFile,
256                        SMESHDS_Mesh *                   theMesh,
257                        const TopoDS_Shape &             theShape,
258                        map <int,const SMDS_MeshNode*> & theGHS3DPRLIdToNodeMap,
259                        const TCollection_AsciiString &  GHS3DPRL_Out,
260                        int &                            nodeRefNumber)
261 {
262   // ---------------------------------
263   // Read generated elements and nodes
264   // ---------------------------------
265
266   cout << "Reading GHS3DPRL output file : " << GHS3DPRL_Out << endl;
267   cout << endl;
268
269   char aBuffer[ GHS3DPRLPlugin_BUFLENGTH ];
270   char * aPtr;
271   int aLineNb = 0;
272   int shapeID = theMesh->ShapeToIndex( theShape );
273
274   int line = 1, EndOfFile = 0, nbElem = 0, nField = 10, nbRef = 0, aGHS3DPRLNodeID = 0;
275   char * theField;
276
277   char * tabField [nField];
278   int    tabRef [nField];
279
280   tabField[0] = "MeshVersionFormatted";    tabRef[0] = 0;
281   tabField[1] = "Dimension";               tabRef[1] = 0;
282   tabField[2] = "Vertices";                tabRef[2] = 3;
283   tabField[3] = "Edges";                   tabRef[3] = 2;
284   tabField[4] = "Triangles";               tabRef[4] = 3;
285   tabField[5] = "Quadrilaterals";          tabRef[5] = 4;
286   tabField[6] = "Hexahedra";               tabRef[6] = 8;
287   tabField[7] = "Corners";                 tabRef[7] = 1;
288   tabField[8] = "Ridges";                  tabRef[0] = 1;
289   tabField[9] = "End";                     tabRef[0] = 0;
290
291   nodeRefNumber += theMesh->NbNodes();
292
293   SMDS_NodeIteratorPtr itOnGHS3DPRLInputNode = theMesh->nodesIterator();
294   while ( itOnGHS3DPRLInputNode->more() )
295       theMesh->RemoveNode( itOnGHS3DPRLInputNode->next() );
296
297   while ( EndOfFile == 0  ) {
298       GHS3DPRLPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb );
299       for ( int iField = 0; iField < nField; iField++ ) {
300           stringstream theMessage;
301           theField = tabField[iField];
302           if ( strncmp(aPtr, theField, strlen(theField)) == 0 ) {
303               if ( strcmp(theField, "End") == 0 ) {
304                   EndOfFile = 1;
305                   theMessage << "End of GHS3DPRL output file has been reached";
306               }
307               else {
308                   GHS3DPRLPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb );
309                   line++;
310                   getInt( nbElem, aPtr );
311
312                   if ( strcmp(theField, "MeshVersionFormatted") == 0 )
313                       theMessage << "GHS3DPRL mesh descriptor : " << theField << " " << nbElem;
314                   else if ( strcmp(theField, "Dimension") == 0 )
315                       theMessage << "GHS3DPRL mesh of " << nbElem << "D dimension";
316                   else if ( strcmp(theField, "Vertices")       == 0 ||
317                             strcmp(theField, "Edges")          == 0 ||
318                             strcmp(theField, "Quadrilaterals") == 0 ||
319                             strcmp(theField, "Hexahedra")      == 0 ) {
320                       nbRef = tabRef[iField];
321                       GHS3DPRLPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb );           // read blank line
322
323                       if ( strcmp(theField, "Vertices") == 0 ) {
324                           int aGHS3DPRLID;
325                           double coord[nbRef];
326                           SMDS_MeshNode * aGHS3DPRLNode;
327
328                           for ( int iElem = 0; iElem < nbElem; iElem++ ) {
329                               aGHS3DPRLID = iElem + 1 + nodeRefNumber;
330                               GHS3DPRLPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb );   // read file lines
331                               for ( int iCoord = 0; iCoord < 3; iCoord++ )
332                                   getDouble ( coord[ iCoord ], aPtr );
333                               aGHS3DPRLNode = theMesh->AddNode(coord[0], coord[1], coord[2]);
334                               theMesh->SetNodeInVolume( aGHS3DPRLNode, shapeID );
335                               theGHS3DPRLIdToNodeMap[ aGHS3DPRLID ] = aGHS3DPRLNode;
336                           }
337                       }
338                       else {
339                           const SMDS_MeshNode * node[nbRef];
340                           SMDS_MeshElement* aGHS3DPRLElement;
341                           map <int,const SMDS_MeshNode*>::iterator itOnGHS3DPRLNode;
342
343                           for ( int iElem = 0; iElem < nbElem; iElem++ ) {
344                               GHS3DPRLPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb );   // read file lines
345                               for ( int iRef = 0; iRef < nbRef; iRef++ ) {
346                                   getInt ( aGHS3DPRLNodeID, aPtr );                         // read nbRef aGHS3DPRLNodeID
347                                   aGHS3DPRLNodeID += nodeRefNumber;
348                                   itOnGHS3DPRLNode = theGHS3DPRLIdToNodeMap.find( aGHS3DPRLNodeID );
349                                   node[ iRef ] = itOnGHS3DPRLNode->second;
350                               }
351
352                               if ( strcmp(theField, "Edges") == 0 )                        // create an element
353                                   aGHS3DPRLElement = theMesh->AddEdge( node[0], node[1] );
354                               else if ( strcmp(theField, "Quadrilaterals") == 0 )
355                                   aGHS3DPRLElement = theMesh->AddFace( node[0], node[1], node[2], node[3] );
356                               else if ( strcmp(theField, "Hexahedra") == 0 )
357                                   aGHS3DPRLElement = theMesh->AddVolume( node[0], node[1], node[2], node[3], node[4], node[5], node[6], node[7] );
358
359                               theMesh->SetMeshElementOnShape( aGHS3DPRLElement, shapeID );
360                           }
361                       }
362                       theMessage << nbElem << " " << theField << " created";
363                   }
364               }
365               if ( theMessage.str().size() != 0 ) {
366                   cout << theMessage.str() << endl;
367                   break;
368               }
369           }
370       }
371   }
372   cout << endl;
373   return true;
374 }
375
376 //=============================================================================
377 // Pass parameters to GHS3DPRL
378
379 void GHS3DPRLPlugin_GHS3DPRL::SetParameters(const GHS3DPRLPlugin_Hypothesis* hyp) {
380   if (hyp) {
381     MESSAGE("GHS3DPRLPlugin_GHS3DPRL::SetParameters");
382     _MEDName = hyp->GetMEDName();  //"DOMAIN\0"
383     _NbPart = hyp->GetNbPart();
384     _KeepFiles = hyp->GetKeepFiles();
385   }
386 }
387
388 //=======================================================================
389
390 static TCollection_AsciiString getTmpDir()
391 {
392   TCollection_AsciiString aTmpDir;
393
394   char *Tmp_dir = getenv("SALOME_TMP_DIR");
395   if (Tmp_dir == NULL) Tmp_dir = getenv("TMPDIR");
396   if(Tmp_dir != NULL)
397   {
398     aTmpDir = Tmp_dir;
399 #ifdef WIN32
400       if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\';
401 #else
402       if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/';
403 #endif
404   }
405   else
406   {
407 #ifdef WIN32
408       aTmpDir = TCollection_AsciiString("C:\\");
409 #else
410       aTmpDir = TCollection_AsciiString("/export/home/");
411 #endif
412   }
413   //cout<<"getTmpDir()="<<aTmpDir<<endl;
414   return aTmpDir;
415 }
416
417 //=============================================================================
418 // Here we are going to use the GHS3DPRL mesher
419
420 bool GHS3DPRLPlugin_GHS3DPRL::Compute(SMESH_Mesh&          theMesh,
421                                      const TopoDS_Shape& theShape) {
422
423
424    bool Ok;
425    MESSAGE("GHS3DPRLPlugin_GHS3DPRL::Compute");
426
427    if (_hypothesis==NULL)
428    {
429       Ok = false;
430       cout <<"\nNo existing parameters/hypothesis for GHS3DPRL!\n\n";
431       return Ok;
432    }
433    SetParameters(_hypothesis);
434
435   cout << endl;
436   cout << _name << " parameters :" << endl;
437   cout << "     generic path/name of MED Files = " << _MEDName << endl;
438   cout << "     number of partitions = " << _NbPart << endl;
439   cout << "     keep intermediates files (from tepal) = " << _KeepFiles << endl;
440   cout << endl;
441
442   SMESHDS_Mesh* meshDS = theMesh.GetMeshDS();
443
444   if (_countSubMesh==0)
445   {
446       _countTotal=0;
447       TopExp_Explorer expf(meshDS->ShapeToMesh(), TopAbs_SOLID);
448       for ( ; expf.More(); expf.Next() )
449           _countTotal++;
450   }
451
452   _countSubMesh++;
453
454   if (_countSubMesh == _countTotal )
455   {
456       TCollection_AsciiString
457          tmpDir=getTmpDir(),
458          GHS3DPRL_In,
459          GHS3DPRL_Out,
460          NbPart,
461          run_GHS3DPRL("tepal2med "),
462          run_keep_files("rm ");
463
464       //example: tepal2med GHS3DPRL 4 12500000 4 Test noMemu LaunchTepal
465
466       TCollection_AsciiString path;
467       TCollection_AsciiString casenamemed;//_MEDName.c_str());
468       casenamemed += (char *)_MEDName.c_str();
469       int n=casenamemed.SearchFromEnd('/');
470       if (n>0)
471       {
472          path=casenamemed.SubString(1,n);
473          casenamemed=casenamemed.SubString(n+1,casenamemed.Length());
474       }
475       else
476          path=tmpDir;
477
478       if (casenamemed.Length()>20)
479       {
480          casenamemed=casenamemed.SubString(1,20);
481          cerr<<"MEDName truncated (no more 20 characters) = "<<casenamemed<<endl;
482       }
483       cout<<"path="<<path<<endl;
484       cout<<"casenamemed="<<casenamemed<<endl;
485
486       map <int,int> aSmdsToGHS3DPRLIdMap;
487       map <int,const SMDS_MeshNode*> aGHS3DPRLIdToNodeMap;
488       GHS3DPRL_In=path + "GHS3DPRL";
489       GHS3DPRL_Out=path + casenamemed;
490       NbPart=_NbPart;
491       run_GHS3DPRL += GHS3DPRL_In + " " + NbPart + " 12500000 1 Test noMemu LaunchTepal " + GHS3DPRL_Out;
492       run_keep_files += GHS3DPRL_In + ".*.*.* " + path + "tepal.out";
493       cout<<"GHS3DPRL command : "<<run_GHS3DPRL<<endl;
494
495       OSD_File( GHS3DPRL_Out ).Remove(); //only the master med file
496       Ok=writeGHS3DPRLFiles(GHS3DPRL_In, meshDS, aSmdsToGHS3DPRLIdMap, aGHS3DPRLIdToNodeMap);
497
498       if (Ok) system( run_GHS3DPRL.ToCString() );
499
500       // read a result, GHS3DPRL_Out is the name of master file (previous xml format)
501       FILE * aResultFile = fopen( GHS3DPRL_Out.ToCString(), "r" );
502       if (aResultFile)
503       {
504           //Ok = readResult( aResultFile, meshDS, theShape, aGHS3DPRLIdToNodeMap, GHS3DPRL_Out, _nodeRefNumber );
505           Ok = true;
506           fclose(aResultFile);
507           cout << "GHS3DPRL OK output file "<<GHS3DPRL_Out<<" exist !\n\n";
508           if (!_KeepFiles)
509           {
510              system( run_keep_files.ToCString() );
511           }
512       }
513       else
514       {
515           Ok = false;
516           cout << "GHS3DPRL KO output files "<<GHS3DPRL_Out<<" do not exist ! see intermediates files keeped:\n";
517           TCollection_AsciiString run_keep_files("ls -alt ");
518           run_keep_files += GHS3DPRL_Out + "* " + GHS3DPRL_In + "* " + path + "tepal.out";
519           system( run_keep_files.ToCString() );
520           cout<<endl;
521       }
522       _countSubMesh=0;
523
524   }
525   return Ok;
526 }
527
528 //=============================================================================
529
530 ostream & GHS3DPRLPlugin_GHS3DPRL::SaveTo(ostream & save)
531 {
532   return save;
533 }
534
535 //=============================================================================
536
537 istream & GHS3DPRLPlugin_GHS3DPRL::LoadFrom(istream & load)
538 {
539   return load;
540 }
541
542 //=============================================================================
543
544 ostream & operator << (ostream & save, GHS3DPRLPlugin_GHS3DPRL & hyp)
545 {
546   return hyp.SaveTo( save );
547 }
548
549 //=============================================================================
550
551 istream & operator >> (istream & load, GHS3DPRLPlugin_GHS3DPRL & hyp)
552 {
553   return hyp.LoadFrom( load );
554 }