1 // Copyright (C) 2007-2008 OPEN CASCADE, CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 // File : GHS3DPRLPlugin_GHS3DPRL.cxx
22 // Author : Christian VAN WAMBEKE (CEA) (from Hexotic plugin Lioka RAZAFINDRAZAKA)
26 #include "GHS3DPRLPlugin_GHS3DPRL.hxx"
27 #include "GHS3DPRLPlugin_Hypothesis.hxx"
29 #include "SMDS_MeshElement.hxx"
30 #include "SMDS_MeshNode.hxx"
32 #include <TopExp_Explorer.hxx>
33 #include <OSD_File.hxx>
35 #include "utilities.h"
38 #include <sys/sysinfo.h>
48 #include <SMESH_Gen.hxx>
49 #include <SMESHDS_Mesh.hxx>
50 #include <SMESH_ControlsDef.hxx>
53 #include <TCollection_AsciiString.hxx>
58 //#include <med_config.h>
59 #include <med_utils.h>
60 //#include <med_misc.h>
63 using namespace med_2_2;*/
65 //=============================================================================
66 GHS3DPRLPlugin_GHS3DPRL::GHS3DPRLPlugin_GHS3DPRL(int hypId, int studyId, SMESH_Gen* gen)
67 : SMESH_3D_Algo(hypId, studyId, gen)
69 MESSAGE("GHS3DPRLPlugin_GHS3DPRL::GHS3DPRLPlugin_GHS3DPRL");
70 _name = "GHS3DPRL_3D";
71 _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type
74 _compatibleHypothesis.push_back("GHS3DPRL_Parameters");
77 //=============================================================================
78 GHS3DPRLPlugin_GHS3DPRL::~GHS3DPRLPlugin_GHS3DPRL()
80 MESSAGE("GHS3DPRLPlugin_GHS3DPRL::~GHS3DPRLPlugin_GHS3DPRL");
83 //=============================================================================
84 bool GHS3DPRLPlugin_GHS3DPRL::CheckHypothesis
86 const TopoDS_Shape& aShape,
87 SMESH_Hypothesis::Hypothesis_Status& aStatus)
89 //MESSAGE("GHS3DPRLPlugin_GHS3DPRL::CheckHypothesis");
92 list<const SMESHDS_Hypothesis*>::const_iterator itl;
93 const SMESHDS_Hypothesis* theHyp;
95 const list<const SMESHDS_Hypothesis*>& hyps = GetUsedHypothesis(aMesh, aShape);
96 int nbHyp = hyps.size();
99 aStatus = SMESH_Hypothesis::HYP_OK;
100 return true; // can work with no hypothesis
104 theHyp = (*itl); // use only the first hypothesis
106 string hypName = theHyp->GetName();
107 if (hypName == "GHS3DPRL_Parameters")
109 _hypothesis = static_cast<const GHS3DPRLPlugin_Hypothesis*> (theHyp);
111 aStatus = SMESH_Hypothesis::HYP_OK;
114 aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
116 return aStatus == SMESH_Hypothesis::HYP_OK;
119 //=======================================================================
120 static bool writeGHS3DPRLFiles (const TCollection_AsciiString & GHS3DPRL_In,
121 SMESHDS_Mesh * theMesh,
122 map <int,int> & theSmdsToGHS3DPRLIdMap,
123 map <int,const SMDS_MeshNode*> & theGHS3DPRLIdToNodeMap)
127 TCollection_AsciiString namefile(GHS3DPRL_In);
129 OSD_File(namefile).Remove();
131 theFile.open(namefile.ToCString(),ios::out);
133 Ok=theFile->is_open();
135 Ok=theFile.rdbuf()->is_open();
139 INFOS("Can't write into "<<namefile.ToCString());
142 cout<<endl<<"writeGHS3DPRLFiles version 2.1 "<<endl;
143 cout<<endl<<"Creating GHS3DPRL processed mesh file : "<<namefile<<endl;
145 int nbVertices=theMesh->NbNodes();
146 int nbFaces=theMesh->NbFaces(); //triangles or quadrangles
147 const char* space=" ";
148 const int dummyint=1; //nrs,nsd,refnum=1 (for wrap)
150 // Writing SMESH points into GHS3DPRL File.points
151 theFile<<nbVertices<<endl;
154 const SMDS_MeshNode* node_2;
155 SMDS_NodeIteratorPtr itOnNode=theMesh->nodesIterator();
156 //int ifam=100;//test famille
157 theFile.precision(15); theFile.setf(ios::scientific,ios::floatfield);
158 //cout<<"set precision 15 on float\n";
159 while (itOnNode->more())
161 node_2 = itOnNode->next();
162 theSmdsToGHS3DPRLIdMap.insert(map <int,int>::value_type(node_2->GetID(),aSmdsNodeID));
163 theGHS3DPRLIdToNodeMap.insert(map <int,const SMDS_MeshNode*>::value_type(aSmdsNodeID,node_2));
164 theFile<<node_2->X()<<space<<node_2->Y()<<space<<node_2->Z()<<space<<ifam<<endl;
166 //if (aSmdsNodeID==11) ifam++;
168 //no specified points;
171 namefile=GHS3DPRL_In+".faces";
172 OSD_File(namefile).Remove();
173 theFile.open(namefile.ToCString(),ios::out);
175 Ok=theFile->is_open();
177 Ok=theFile.rdbuf()->is_open();
181 INFOS("Can't write into "<<namefile.ToCString());
184 cout<<endl<<"Creating GHS3DPRL processed mesh file : "<<namefile<<endl;
186 // Writing SMESH faces into GHS3DPRL File.faces
187 theFile<<nbFaces<<" 0"<<endl; //NB_ELEMS DUMMY_INT
188 //" 0" is a reserved parameter
190 const SMDS_MeshElement* aFace;
191 map<int,int>::const_iterator itOnSmdsNode;
192 SMDS_ElemIteratorPtr itOnFaceNode;
193 SMDS_FaceIteratorPtr itOnSmdsFace = theMesh->facesIterator();
194 long nbNoTriangles=0;
197 while (itOnSmdsFace->more())
199 aFace=itOnSmdsFace->next();
200 itOnFaceNode=aFace->nodesIterator();
201 const int nbNodes=aFace->NbNodes();
202 if (nbNodes!=3) nbNoTriangles++;
204 theFile<<nbNodes<<space; // NB_NODES
205 while (itOnFaceNode->more())
207 aSmdsNodeID=itOnFaceNode->next()->GetID();
208 itOnSmdsNode=theSmdsToGHS3DPRLIdMap.find(aSmdsNodeID);
209 ASSERT(itOnSmdsNode!=theSmdsToGHS3DPRLIdMap.end());
210 theFile<<space<<(*itOnSmdsNode).second; //NODE_1 NODE_2 ...
212 //(NB_NODES+1) times: DUMMY_INT
213 //if (ifaces==11) ifam++;
214 theFile<<space<<ifam;
215 for ( int i=1; i<=nbNodes; i++) theFile<<space<<200+i;
220 cout<<"Processed mesh files created, they contains :\n";
221 cout<<" "<<nbVertices<<" vertices\n";
222 if (nbNoTriangles==0)
223 cout<<" "<<nbFaces<<" faces\n\n";
225 cout<<" "<<nbFaces<<" faces with "<<nbNoTriangles<<"faces no triangles\n\n";
229 //=======================================================================
230 static bool getInt( int & theValue, char * & theLine )
233 theValue = strtol( theLine, &ptr, 10 );
234 if ( ptr == theLine ||
235 // there must not be neither '.' nor ',' nor 'E' ...
236 (*ptr != ' ' && *ptr != '\n' && *ptr != '\0'))
239 DUMP( " " << theValue );
244 //=======================================================================
245 static bool getDouble( double & theValue, char * & theLine )
248 theValue = strtod( theLine, &ptr );
249 if ( ptr == theLine )
252 DUMP( " " << theValue );
257 //=======================================================================
259 #define GHS3DPRLPlugin_BUFLENGTH 256
260 #define GHS3DPRLPlugin_ReadLine(aPtr,aBuf,aFile,aLineNb) \
261 { aPtr = fgets( aBuf, GHS3DPRLPlugin_BUFLENGTH - 2, aFile ); aLineNb++; DUMP(endl); }
263 //=======================================================================
264 static bool readResult(FILE * theFile,
265 SMESHDS_Mesh * theMesh,
266 const TopoDS_Shape & theShape,
267 map <int,const SMDS_MeshNode*> & theGHS3DPRLIdToNodeMap,
268 const TCollection_AsciiString & GHS3DPRL_Out,
271 // ---------------------------------
272 // Read generated elements and nodes
273 // ---------------------------------
275 cout << "Reading GHS3DPRL output file : " << GHS3DPRL_Out << endl;
278 char aBuffer[ GHS3DPRLPlugin_BUFLENGTH ];
281 int shapeID = theMesh->ShapeToIndex( theShape );
283 int line = 1, EndOfFile = 0, nbElem = 0, nField = 10, nbRef = 0, aGHS3DPRLNodeID = 0;
286 char * tabField [nField];
289 tabField[0] = "MeshVersionFormatted"; tabRef[0] = 0;
290 tabField[1] = "Dimension"; tabRef[1] = 0;
291 tabField[2] = "Vertices"; tabRef[2] = 3;
292 tabField[3] = "Edges"; tabRef[3] = 2;
293 tabField[4] = "Triangles"; tabRef[4] = 3;
294 tabField[5] = "Quadrilaterals"; tabRef[5] = 4;
295 tabField[6] = "Hexahedra"; tabRef[6] = 8;
296 tabField[7] = "Corners"; tabRef[7] = 1;
297 tabField[8] = "Ridges"; tabRef[0] = 1;
298 tabField[9] = "End"; tabRef[0] = 0;
300 nodeRefNumber += theMesh->NbNodes();
302 SMDS_NodeIteratorPtr itOnGHS3DPRLInputNode = theMesh->nodesIterator();
303 while ( itOnGHS3DPRLInputNode->more() )
304 theMesh->RemoveNode( itOnGHS3DPRLInputNode->next() );
306 while ( EndOfFile == 0 ) {
307 GHS3DPRLPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb );
308 for ( int iField = 0; iField < nField; iField++ ) {
309 stringstream theMessage;
310 theField = tabField[iField];
311 if ( strncmp(aPtr, theField, strlen(theField)) == 0 ) {
312 if ( strcmp(theField, "End") == 0 ) {
314 theMessage << "End of GHS3DPRL output file has been reached";
317 GHS3DPRLPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb );
319 getInt( nbElem, aPtr );
321 if ( strcmp(theField, "MeshVersionFormatted") == 0 )
322 theMessage << "GHS3DPRL mesh descriptor : " << theField << " " << nbElem;
323 else if ( strcmp(theField, "Dimension") == 0 )
324 theMessage << "GHS3DPRL mesh of " << nbElem << "D dimension";
325 else if ( strcmp(theField, "Vertices") == 0 ||
326 strcmp(theField, "Edges") == 0 ||
327 strcmp(theField, "Quadrilaterals") == 0 ||
328 strcmp(theField, "Hexahedra") == 0 ) {
329 nbRef = tabRef[iField];
330 GHS3DPRLPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb ); // read blank line
332 if ( strcmp(theField, "Vertices") == 0 ) {
335 SMDS_MeshNode * aGHS3DPRLNode;
337 for ( int iElem = 0; iElem < nbElem; iElem++ ) {
338 aGHS3DPRLID = iElem + 1 + nodeRefNumber;
339 GHS3DPRLPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb ); // read file lines
340 for ( int iCoord = 0; iCoord < 3; iCoord++ )
341 getDouble ( coord[ iCoord ], aPtr );
342 aGHS3DPRLNode = theMesh->AddNode(coord[0], coord[1], coord[2]);
343 theMesh->SetNodeInVolume( aGHS3DPRLNode, shapeID );
344 theGHS3DPRLIdToNodeMap[ aGHS3DPRLID ] = aGHS3DPRLNode;
348 const SMDS_MeshNode * node[nbRef];
349 SMDS_MeshElement* aGHS3DPRLElement;
350 map <int,const SMDS_MeshNode*>::iterator itOnGHS3DPRLNode;
352 for ( int iElem = 0; iElem < nbElem; iElem++ ) {
353 GHS3DPRLPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb ); // read file lines
354 for ( int iRef = 0; iRef < nbRef; iRef++ ) {
355 getInt ( aGHS3DPRLNodeID, aPtr ); // read nbRef aGHS3DPRLNodeID
356 aGHS3DPRLNodeID += nodeRefNumber;
357 itOnGHS3DPRLNode = theGHS3DPRLIdToNodeMap.find( aGHS3DPRLNodeID );
358 node[ iRef ] = itOnGHS3DPRLNode->second;
361 if ( strcmp(theField, "Edges") == 0 ) // create an element
362 aGHS3DPRLElement = theMesh->AddEdge( node[0], node[1] );
363 else if ( strcmp(theField, "Quadrilaterals") == 0 )
364 aGHS3DPRLElement = theMesh->AddFace( node[0], node[1], node[2], node[3] );
365 else if ( strcmp(theField, "Hexahedra") == 0 )
366 aGHS3DPRLElement = theMesh->AddVolume( node[0], node[1], node[2], node[3], node[4], node[5], node[6], node[7] );
368 theMesh->SetMeshElementOnShape( aGHS3DPRLElement, shapeID );
371 theMessage << nbElem << " " << theField << " created";
374 if ( theMessage.str().size() != 0 ) {
375 cout << theMessage.str() << endl;
385 //=============================================================================
386 // Pass parameters to GHS3DPRL
387 void GHS3DPRLPlugin_GHS3DPRL::SetParameters(const GHS3DPRLPlugin_Hypothesis* hyp)
390 MESSAGE("GHS3DPRLPlugin_GHS3DPRL::SetParameters");
391 _MEDName = hyp->GetMEDName(); //"DOMAIN\0"
392 _NbPart = hyp->GetNbPart();
393 _KeepFiles = hyp->GetKeepFiles();
394 _Background = hyp->GetBackground();
395 _ToMeshHoles = hyp->GetToMeshHoles();
399 //=======================================================================
400 //before launching salome
401 //SALOME_TMP_DIR (for keep tepal intermediates files) could be set in user's directories
402 static TCollection_AsciiString getTmpDir()
404 TCollection_AsciiString aTmpDir;
405 char *Tmp_dir = getenv("SALOME_TMP_DIR");
406 if (Tmp_dir == NULL) Tmp_dir = getenv("TMP");
411 if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\';
413 if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/';
419 aTmpDir = TCollection_AsciiString("C:\\");
421 aTmpDir = TCollection_AsciiString("/tmp/");
427 //=============================================================================
428 // Here we are going to use the GHS3DPRL mesher
429 bool GHS3DPRLPlugin_GHS3DPRL::Compute(SMESH_Mesh& theMesh,
430 const TopoDS_Shape& theShape)
433 TCollection_AsciiString pluginerror("ghs3dprl: ");
434 SMESHDS_Mesh* meshDS = theMesh.GetMeshDS();
435 //cout<<"GetMeshDS done\n";
436 if (_countSubMesh==0){
437 MESSAGE("GHS3DPRLPlugin_GHS3DPRL::Compute");
439 TopExp_Explorer expf(meshDS->ShapeToMesh(), TopAbs_SOLID);
440 for ( ; expf.More(); expf.Next() ) _countTotal++;
443 //cout<<"Compute _countSubMesh "<<_countSubMesh<<endl;
444 //no stuff if multiples submesh, multiple call compute
445 //mesh all in one pass tepal (the last)
446 if (_countSubMesh != _countTotal ) return true;
449 if (_hypothesis==NULL){
450 pluginerror += "No existing parameters/hypothesis for GHS3DPRL";
451 cout <<"\n"<<pluginerror<<"\n\n";
452 error(COMPERR_ALGO_FAILED, pluginerror.ToCString() );
455 SetParameters(_hypothesis);
456 cout << "\n" << _name << " parameters :\n" << endl;
457 cout << " generic path/name of MED Files = " << _MEDName << endl;
458 cout << " number of partitions = " << _NbPart << endl;
459 cout << " mesh holes = " << _ToMeshHoles << endl;
460 cout << " keep intermediates files (from tepal) = " << _KeepFiles << endl;
461 cout << " background (from tepal) = " << _Background << "\n\n";
463 //string tmpDir=getTmpDir_new();
464 TCollection_AsciiString
466 GHS3DPRL_In,GHS3DPRL_Out,GHS3DPRL_Outxml,
467 run_GHS3DPRL("tepal2med "),rm("rm "),run_nokeep_files,
468 NbPart,fileskinmed(""),path,casenamemed; //_MEDName.c_str());
470 casenamemed += (char *)_MEDName.c_str();
471 int n=casenamemed.SearchFromEnd('/');
473 path=casenamemed.SubString(1,n);
474 casenamemed=casenamemed.SubString(n+1,casenamemed.Length());
479 if (casenamemed.Length()>20){
480 casenamemed=casenamemed.SubString(1,20);
481 cerr<<"MEDName truncated (no more 20 characters) = "<<casenamemed<<endl;
483 cout<<"path="<<path<<endl;
484 cout<<"casenamemed="<<casenamemed<<endl;
486 map <int,int> aSmdsToGHS3DPRLIdMap;
487 map <int,const SMDS_MeshNode*> aGHS3DPRLIdToNodeMap;
488 GHS3DPRL_In = path + "GHS3DPRL";
489 GHS3DPRL_Out = path + casenamemed;
490 GHS3DPRL_Outxml = path + casenamemed + ".xml"; //master file
492 //tepal2med --casename=/home/whoami/tmp/GHS3DPRL --number=5 --medname=DOMAIN
493 // --limitswap=1000 --verbose=0 --test=no --menu=no --launchtepal=yes;
495 run_GHS3DPRL = run_GHS3DPRL +
496 " --casename=" + GHS3DPRL_In +
497 " --number=" + NbPart +
498 " --medname=" + GHS3DPRL_Out +
499 " --launchtepal=yes";
500 if (_ToMeshHoles) run_GHS3DPRL += " --meshholes=yes"; else run_GHS3DPRL += " --meshholes=no";
501 if (_Background) run_GHS3DPRL += " --background=yes"; else run_GHS3DPRL += " --background=no";
502 run_nokeep_files = rm +GHS3DPRL_In + "* " + path + "tepal.log";
503 system( run_nokeep_files.ToCString() ); //clean files
504 run_nokeep_files = rm + GHS3DPRL_In + "* ";
506 cout<<"GHS3DPRL command : "<<run_GHS3DPRL.ToCString()<<endl;
507 cout<<"Write files .faces .point ...";
508 GHS3DPRL_Out = path + casenamemed;
509 OSD_File( GHS3DPRL_Outxml ).Remove(); //only the master xml file
510 Ok=writeGHS3DPRLFiles(GHS3DPRL_In, meshDS, aSmdsToGHS3DPRLIdMap, aGHS3DPRLIdToNodeMap);
511 if (Ok) {cout<<" ...done\n";}
513 cout<<" ...NOT done\n";
514 pluginerror = pluginerror + "problem writing input tepal files " + GHS3DPRL_In + "[.faces|.points]";
517 //Ecriture dans un fichier MED ?v2.? meme si not Ok
518 //create empty file -> avoid warning message
519 //med_idt fid=MEDouvrir((const char *)fileskinmed.ToCString(),MED_CREATION);
520 //med_err ret=MEDfermer(fid);
521 //fileskinmed=fileskinmed + "cp /home/wambeke/empty.med "+ path + "GHS3DPRL_skin.med";
522 //system( fileskinmed.ToCString() );
523 fileskinmed=path + "GHS3DPRL_skin.med";
524 cout<<"Write file "<<fileskinmed<<"...";
525 theMesh.ExportMED(fileskinmed.ToCString(),"SKIN_INITIAL",true,1);
529 error(COMPERR_ALGO_FAILED, pluginerror.ToCString());
530 return false; //pb abandonne
533 //sometimes it is better to wait flushing files on slow filesystem...
535 system( run_GHS3DPRL.ToCString() );
538 //cout<<"!!!reprise plugin!!!"<<endl;
541 pluginerror = pluginerror + "backgrounding... plugin is not waiting for output files "+ casenamemed + "_*.med";
542 cout<<pluginerror<<endl;
543 error(COMPERR_ALGO_FAILED, pluginerror.ToCString());
544 return false; //but it is not a problem but if true my message is overwritten
545 //return true; //but it is not a problem,
548 // read a result, GHS3DPRL_Out is the name of master file (previous xml format)
549 FILE * aResultFile = fopen( GHS3DPRL_Outxml.ToCString(), "r" );
551 //Ok = readResult( aResultFile, meshDS, theShape, aGHS3DPRLIdToNodeMap, GHS3DPRL_Out, _nodeRefNumber );
553 Ok = false; //but it is not a problem but if true my message is overwritten
555 cout<<"GHS3DPRL OK output master file "<<casenamemed<<".xml exist !\n\n";
556 pluginerror = pluginerror + "new tetaedra not in memory, but stored in files "+ casenamemed + "_*.med";
557 cout<<pluginerror<<endl;
558 error(COMPERR_ALGO_FAILED, pluginerror.ToCString());
559 if (!_KeepFiles) system( run_nokeep_files.ToCString() );
562 Ok = false; //it is a problem AND my message is NOT overwritten
563 pluginerror = pluginerror + "output master file " + casenamemed + ".xml do not exist";
564 cout<<pluginerror<<endl;
565 error(COMPERR_ALGO_FAILED, pluginerror.ToCString() );
566 cout<<"GHS3DPRL KO output files "<<GHS3DPRL_Out<<" do not exist ! see intermediates files keeped:\n";
567 TCollection_AsciiString run_list_files("ls -alt ");
568 run_list_files += GHS3DPRL_Out + "* " + GHS3DPRL_In + "* " + path + "tepal.log";
569 system( run_list_files.ToCString() );
576 /*pid_t pid = fork();
579 cout<<"le pere est la\n";
580 system("echo le pere > lepere.tmp");
582 system("ps -edf |grep wambeke > pslepere.tmp");
583 cout<<"le pere return 0\n";
586 } else if (pid == 0) {
588 cout<<"le fils est la\n";
589 //On rend le fils indépendant de tout terminal
592 system("echo le fils > lefils.tmp");
594 system("ps -edf |grep wambeke > pslefils.tmp");
595 cout<<"le fils return 0\n";
598 //Traitement d'erreur
599 cout<<"ya probleme sur fork()\n";
604 //=============================================================================
605 ostream & GHS3DPRLPlugin_GHS3DPRL::SaveTo(ostream & save)
610 //=============================================================================
611 istream & GHS3DPRLPlugin_GHS3DPRL::LoadFrom(istream & load)
616 //=============================================================================
617 ostream & operator << (ostream & save, GHS3DPRLPlugin_GHS3DPRL & hyp)
619 return hyp.SaveTo( save );
622 //=============================================================================
623 istream & operator >> (istream & load, GHS3DPRLPlugin_GHS3DPRL & hyp)
625 return hyp.LoadFrom( load );