1 // GHS3DPRLPlugin : C++ implementation
3 // Copyright (C) 2006 OPEN CASCADE, CEA/DEN, EDF R&D
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.
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.
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
19 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
22 // File : GHS3DPRLPlugin_GHS3DPRL.cxx
23 // Author : Christian VAN WAMBEKE (CEA) (from Hexotic plugin Lioka RAZAFINDRAZAKA)
26 //=============================================================================
29 #include "GHS3DPRLPlugin_GHS3DPRL.hxx"
30 #include "GHS3DPRLPlugin_Hypothesis.hxx"
31 // #include "GHS3DPRLPlugin_Mesher.hxx"
33 #include "SMDS_MeshElement.hxx"
34 #include "SMDS_MeshNode.hxx"
36 #include <TopExp_Explorer.hxx>
37 #include <OSD_File.hxx>
39 #include "utilities.h"
42 #include <sys/sysinfo.h>
52 #include <SMESH_Gen.hxx>
53 #include <SMESHDS_Mesh.hxx>
54 #include <SMESH_ControlsDef.hxx>
57 #include <TCollection_AsciiString.hxx>
59 //=============================================================================
61 GHS3DPRLPlugin_GHS3DPRL::GHS3DPRLPlugin_GHS3DPRL(int hypId, int studyId, SMESH_Gen* gen)
62 : SMESH_3D_Algo(hypId, studyId, gen)
64 MESSAGE("GHS3DPRLPlugin_GHS3DPRL::GHS3DPRLPlugin_GHS3DPRL");
65 _name = "GHS3DPRL_3D";
66 _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type
69 _compatibleHypothesis.push_back("GHS3DPRL_Parameters");
72 //=============================================================================
74 GHS3DPRLPlugin_GHS3DPRL::~GHS3DPRLPlugin_GHS3DPRL()
76 MESSAGE("GHS3DPRLPlugin_GHS3DPRL::~GHS3DPRLPlugin_GHS3DPRL");
79 //=============================================================================
81 bool GHS3DPRLPlugin_GHS3DPRL::CheckHypothesis
83 const TopoDS_Shape& aShape,
84 SMESH_Hypothesis::Hypothesis_Status& aStatus)
86 MESSAGE("GHS3DPRLPlugin_GHS3DPRL::CheckHypothesis");
90 list<const SMESHDS_Hypothesis*>::const_iterator itl;
91 const SMESHDS_Hypothesis* theHyp;
93 const list<const SMESHDS_Hypothesis*>& hyps = GetUsedHypothesis(aMesh, aShape);
94 int nbHyp = hyps.size();
97 aStatus = SMESH_Hypothesis::HYP_OK;
98 return true; // can work with no hypothesis
102 theHyp = (*itl); // use only the first hypothesis
104 string hypName = theHyp->GetName();
105 if (hypName == "GHS3DPRL_Parameters")
107 _hypothesis = static_cast<const GHS3DPRLPlugin_Hypothesis*> (theHyp);
109 aStatus = SMESH_Hypothesis::HYP_OK;
112 aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
114 return aStatus == SMESH_Hypothesis::HYP_OK;
117 //=======================================================================
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)
125 TCollection_AsciiString namefile(GHS3DPRL_In);
127 OSD_File(namefile).Remove();
129 theFile.open(namefile.ToCString(),ios::out);
131 Ok=theFile->is_open();
133 Ok=theFile.rdbuf()->is_open();
137 INFOS("Can't write into "<<namefile.ToCString());
140 cout<<endl<<"Creating GHS3DPRL processed mesh file : "<<namefile<<endl;
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)
147 // Writing SMESH points into GHS3DPRL File.points
148 theFile<<nbVertices<<endl;
151 const SMDS_MeshNode* node_2;
152 SMDS_NodeIteratorPtr itOnNode = theMesh->nodesIterator();
153 while (itOnNode->more())
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));
159 theFile<<node_2->X()<<space<<node_2->Y()<<space<<node_2->Z()<<space<<dummyint<<endl;
161 //no specified points;
164 namefile=GHS3DPRL_In+".faces";
165 OSD_File(namefile).Remove();
166 theFile.open(namefile.ToCString(),ios::out);
168 Ok=theFile->is_open();
170 Ok=theFile.rdbuf()->is_open();
174 INFOS("Can't write into "<<namefile.ToCString());
177 cout<<endl<<"Creating GHS3DPRL processed mesh file : "<<namefile<<endl;
179 // Writing SMESH faces into GHS3DPRL File.faces
180 theFile<<nbFaces<<" 0"<<endl; //NB_ELEMS DUMMY_INT
181 //" 0" is a reserved parameter
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())
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())
197 aSmdsNodeID=itOnFaceNode->next()->GetID();
198 itOnSmdsNode=theSmdsToGHS3DPRLIdMap.find(aSmdsNodeID);
199 ASSERT(itOnSmdsNode!=theSmdsToGHS3DPRLIdMap.end());
200 theFile<<space<<(*itOnSmdsNode).second; //NODE_1 NODE_2 ...
202 //(NB_NODES+1) times: DUMMY_INT
203 for ( int i=0; i<=nbNodes; i++) theFile<<space<<dummyint;
208 cout<<"Processed mesh files created, they contains :\n";
209 cout<<" "<<nbVertices<<" vertices\n";
210 if (nbNoTriangles==0)
211 cout<<" "<<nbFaces<<" faces\n\n";
213 cout<<" "<<nbFaces<<" faces with "<<nbNoTriangles<<"faces no triangles\n\n";
217 //=======================================================================
219 static bool getInt( int & theValue, char * & theLine )
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'))
228 DUMP( " " << theValue );
233 //=======================================================================
235 static bool getDouble( double & theValue, char * & theLine )
238 theValue = strtod( theLine, &ptr );
239 if ( ptr == theLine )
242 DUMP( " " << theValue );
247 //=======================================================================
249 #define GHS3DPRLPlugin_BUFLENGTH 256
250 #define GHS3DPRLPlugin_ReadLine(aPtr,aBuf,aFile,aLineNb) \
251 { aPtr = fgets( aBuf, GHS3DPRLPlugin_BUFLENGTH - 2, aFile ); aLineNb++; DUMP(endl); }
253 //=======================================================================
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,
262 // ---------------------------------
263 // Read generated elements and nodes
264 // ---------------------------------
266 cout << "Reading GHS3DPRL output file : " << GHS3DPRL_Out << endl;
269 char aBuffer[ GHS3DPRLPlugin_BUFLENGTH ];
272 int shapeID = theMesh->ShapeToIndex( theShape );
274 int line = 1, EndOfFile = 0, nbElem = 0, nField = 10, nbRef = 0, aGHS3DPRLNodeID = 0;
277 char * tabField [nField];
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;
291 nodeRefNumber += theMesh->NbNodes();
293 SMDS_NodeIteratorPtr itOnGHS3DPRLInputNode = theMesh->nodesIterator();
294 while ( itOnGHS3DPRLInputNode->more() )
295 theMesh->RemoveNode( itOnGHS3DPRLInputNode->next() );
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 ) {
305 theMessage << "End of GHS3DPRL output file has been reached";
308 GHS3DPRLPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb );
310 getInt( nbElem, aPtr );
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
323 if ( strcmp(theField, "Vertices") == 0 ) {
326 SMDS_MeshNode * aGHS3DPRLNode;
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;
339 const SMDS_MeshNode * node[nbRef];
340 SMDS_MeshElement* aGHS3DPRLElement;
341 map <int,const SMDS_MeshNode*>::iterator itOnGHS3DPRLNode;
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;
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] );
359 theMesh->SetMeshElementOnShape( aGHS3DPRLElement, shapeID );
362 theMessage << nbElem << " " << theField << " created";
365 if ( theMessage.str().size() != 0 ) {
366 cout << theMessage.str() << endl;
376 //=============================================================================
377 // Pass parameters to GHS3DPRL
379 void GHS3DPRLPlugin_GHS3DPRL::SetParameters(const GHS3DPRLPlugin_Hypothesis* hyp) {
381 MESSAGE("GHS3DPRLPlugin_GHS3DPRL::SetParameters");
382 _MEDName = hyp->GetMEDName(); //"DOMAIN\0"
383 _NbPart = hyp->GetNbPart();
384 _KeepFiles = hyp->GetKeepFiles();
388 //=======================================================================
390 static TCollection_AsciiString getTmpDir()
392 TCollection_AsciiString aTmpDir;
394 char *Tmp_dir = getenv("SALOME_TMP_DIR");
395 if (Tmp_dir == NULL) Tmp_dir = getenv("TMPDIR");
400 if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\';
402 if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/';
408 aTmpDir = TCollection_AsciiString("C:\\");
410 aTmpDir = TCollection_AsciiString("/export/home/");
413 //cout<<"getTmpDir()="<<aTmpDir<<endl;
417 //=============================================================================
418 // Here we are going to use the GHS3DPRL mesher
420 bool GHS3DPRLPlugin_GHS3DPRL::Compute(SMESH_Mesh& theMesh,
421 const TopoDS_Shape& theShape) {
425 MESSAGE("GHS3DPRLPlugin_GHS3DPRL::Compute");
427 if (_hypothesis==NULL)
430 cout <<"\nNo existing parameters/hypothesis for GHS3DPRL!\n\n";
433 SetParameters(_hypothesis);
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;
442 SMESHDS_Mesh* meshDS = theMesh.GetMeshDS();
444 if (_countSubMesh==0)
447 TopExp_Explorer expf(meshDS->ShapeToMesh(), TopAbs_SOLID);
448 for ( ; expf.More(); expf.Next() )
454 if (_countSubMesh == _countTotal )
456 TCollection_AsciiString
461 run_GHS3DPRL("tepal2med "),
462 run_keep_files("rm ");
464 //example: tepal2med GHS3DPRL 4 12500000 4 Test noMemu LaunchTepal
466 TCollection_AsciiString path;
467 TCollection_AsciiString casenamemed;//_MEDName.c_str());
468 casenamemed += (char *)_MEDName.c_str();
469 int n=casenamemed.SearchFromEnd('/');
472 path=casenamemed.SubString(1,n);
473 casenamemed=casenamemed.SubString(n+1,casenamemed.Length());
478 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;
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;
495 OSD_File( GHS3DPRL_Out ).Remove(); //only the master med file
496 Ok=writeGHS3DPRLFiles(GHS3DPRL_In, meshDS, aSmdsToGHS3DPRLIdMap, aGHS3DPRLIdToNodeMap);
498 if (Ok) system( run_GHS3DPRL.ToCString() );
500 // read a result, GHS3DPRL_Out is the name of master file (previous xml format)
501 FILE * aResultFile = fopen( GHS3DPRL_Out.ToCString(), "r" );
504 //Ok = readResult( aResultFile, meshDS, theShape, aGHS3DPRLIdToNodeMap, GHS3DPRL_Out, _nodeRefNumber );
507 cout << "GHS3DPRL OK output file "<<GHS3DPRL_Out<<" exist !\n\n";
510 system( run_keep_files.ToCString() );
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() );
528 //=============================================================================
530 ostream & GHS3DPRLPlugin_GHS3DPRL::SaveTo(ostream & save)
535 //=============================================================================
537 istream & GHS3DPRLPlugin_GHS3DPRL::LoadFrom(istream & load)
542 //=============================================================================
544 ostream & operator << (ostream & save, GHS3DPRLPlugin_GHS3DPRL & hyp)
546 return hyp.SaveTo( save );
549 //=============================================================================
551 istream & operator >> (istream & load, GHS3DPRLPlugin_GHS3DPRL & hyp)
553 return hyp.LoadFrom( load );