1 // Copyright (C) 2007-2012 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 : HexoticPlugin_Hexotic.cxx
22 // Author : Lioka RAZAFINDRAZAKA (CEA)
25 #include "HexoticPlugin_Hexotic.hxx"
26 #include "HexoticPlugin_Hypothesis.hxx"
28 #include "SMDS_MeshElement.hxx"
29 #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 <SMESHDS_GroupBase.hxx>
49 #include <SMESHDS_Mesh.hxx>
50 #include <SMESH_ControlsDef.hxx>
51 #include <SMESH_File.hxx>
52 #include <SMESH_Gen.hxx>
53 #include <SMESH_HypoFilter.hxx>
54 #include <SMESH_MesherHelper.hxx>
55 #include <SMESH_subMesh.hxx>
61 #include <Standard_ProgramError.hxx>
63 #include <BRepClass3d_SolidClassifier.hxx>
64 #include <Bnd_Box.hxx>
65 #include <BRepBndLib.hxx>
66 #include <Precision.hxx>
68 #include <BRepBuilderAPI_MakeVertex.hxx>
69 #include <BRep_Tool.hxx>
70 #include <TopTools_MapOfShape.hxx>
71 #include <TopTools_Array1OfShape.hxx>
72 #include <BRepExtrema_DistShapeShape.hxx>
73 #include <TColStd_Array1OfReal.hxx>
74 #include <BRepExtrema_DistShapeShape.hxx>
76 static void removeFile( const TCollection_AsciiString& fileName )
79 OSD_File( fileName ).Remove();
81 catch ( Standard_ProgramError ) {
82 MESSAGE("Can't remove file: " << fileName.ToCString() << " ; file does not exist or permission denied");
86 //=============================================================================
90 //=============================================================================
92 HexoticPlugin_Hexotic::HexoticPlugin_Hexotic(int hypId, int studyId, SMESH_Gen* gen)
93 : SMESH_3D_Algo(hypId, studyId, gen)
95 MESSAGE("HexoticPlugin_Hexotic::HexoticPlugin_Hexotic");
97 _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type
98 // _onlyUnaryInput = false;
99 _requireShape = false;
102 _hexoticFilesKept=false;
103 _compatibleHypothesis.push_back("Hexotic_Parameters");
104 #ifdef WITH_BLSURFPLUGIN
107 #ifdef WITH_SMESH_CANCEL_COMPUTE
108 _compute_canceled = false;
112 //=============================================================================
116 //=============================================================================
118 HexoticPlugin_Hexotic::~HexoticPlugin_Hexotic()
120 MESSAGE("HexoticPlugin_Hexotic::~HexoticPlugin_Hexotic");
124 #ifdef WITH_BLSURFPLUGIN
125 bool HexoticPlugin_Hexotic::CheckBLSURFHypothesis( SMESH_Mesh& aMesh,
126 const TopoDS_Shape& aShape )
128 // MESSAGE("HexoticPlugin_Hexotic::CheckBLSURFHypothesis");
131 std::list<const SMESHDS_Hypothesis*>::const_iterator itl;
132 const SMESHDS_Hypothesis* theHyp;
134 // If a BLSURF hypothesis is applied, get it
135 SMESH_HypoFilter blsurfFilter;
136 blsurfFilter.Init( blsurfFilter.HasName( "BLSURF_Parameters" ));
137 std::list<const SMESHDS_Hypothesis *> appliedHyps;
138 aMesh.GetHypotheses( aShape, blsurfFilter, appliedHyps, false );
140 if ( appliedHyps.size() > 0 ) {
141 itl = appliedHyps.begin();
142 theHyp = (*itl); // use only the first hypothesis
143 std::string hypName = theHyp->GetName();
144 if (hypName == "BLSURF_Parameters") {
145 _blsurfHypo = static_cast<const BLSURFPlugin_Hypothesis*> (theHyp);
154 //=============================================================================
158 //=============================================================================
160 bool HexoticPlugin_Hexotic::CheckHypothesis( SMESH_Mesh& aMesh,
161 const TopoDS_Shape& aShape,
162 SMESH_Hypothesis::Hypothesis_Status& aStatus )
164 // MESSAGE("HexoticPlugin_Hexotic::CheckHypothesis");
167 std::list<const SMESHDS_Hypothesis*>::const_iterator itl;
168 const SMESHDS_Hypothesis* theHyp;
170 const std::list<const SMESHDS_Hypothesis*>& hyps = GetUsedHypothesis(aMesh, aShape, false);
171 int nbHyp = hyps.size();
173 aStatus = SMESH_Hypothesis::HYP_OK;
174 return true; // can work with no hypothesis
178 theHyp = (*itl); // use only the first hypothesis
180 std::string hypName = theHyp->GetName();
181 if (hypName == "Hexotic_Parameters") {
182 _hypothesis = static_cast<const HexoticPlugin_Hypothesis*> (theHyp);
184 aStatus = SMESH_Hypothesis::HYP_OK;
187 aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
189 #ifdef WITH_BLSURFPLUGIN
190 CheckBLSURFHypothesis(aMesh, aShape);
193 return aStatus == SMESH_Hypothesis::HYP_OK;
196 //=======================================================================
197 //function : findShape
199 //=======================================================================
201 static TopoDS_Shape findShape(SMDS_MeshNode** t_Node,
203 const TopoDS_Shape* t_Shape,
208 int iShape, nbNode = 8;
210 for ( int i=0; i<3; i++ ) {
212 for ( int j=0; j<nbNode; j++ ) {
213 if ( i == 0) pntCoor[i] += t_Node[j]->X();
214 if ( i == 1) pntCoor[i] += t_Node[j]->Y();
215 if ( i == 2) pntCoor[i] += t_Node[j]->Z();
217 pntCoor[i] /= nbNode;
219 gp_Pnt aPnt(pntCoor[0], pntCoor[1], pntCoor[2]);
221 if ( aShape.IsNull() ) aShape = t_Shape[0];
222 BRepClass3d_SolidClassifier SC (aShape, aPnt, Precision::Confusion());
223 if ( !(SC.State() == TopAbs_IN) ) {
225 for (iShape = 0; iShape < nShape && aShape.IsNull(); iShape++) {
226 if ( !( pntCoor[0] < t_Box[iShape][0] || t_Box[iShape][1] < pntCoor[0] ||
227 pntCoor[1] < t_Box[iShape][2] || t_Box[iShape][3] < pntCoor[1] ||
228 pntCoor[2] < t_Box[iShape][4] || t_Box[iShape][5] < pntCoor[2]) ) {
229 BRepClass3d_SolidClassifier SC (t_Shape[iShape], aPnt, Precision::Confusion());
230 if (SC.State() == TopAbs_IN)
231 aShape = t_Shape[iShape];
238 //=======================================================================
239 //function : findEdge
241 //=======================================================================
243 static int findEdge(const SMDS_MeshNode* aNode,
244 const SMESHDS_Mesh* theMesh,
246 const TopoDS_Shape* t_Edge) {
248 TopoDS_Shape aPntShape, foundEdge;
249 TopoDS_Vertex aVertex;
250 gp_Pnt aPnt( aNode->X(), aNode->Y(), aNode->Z() );
253 double nearest = RealLast(), *t_Dist;
254 double epsilon = Precision::Confusion();
256 t_Dist = new double[ nEdge ];
257 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
258 aVertex = TopoDS::Vertex( aPntShape );
260 for ( ind=0; ind < nEdge; ind++ ) {
261 BRepExtrema_DistShapeShape aDistance ( aVertex, t_Edge[ind] );
262 t_Dist[ind] = aDistance.Value();
263 if ( t_Dist[ind] < nearest ) {
264 nearest = t_Dist[ind];
265 foundEdge = t_Edge[ind];
267 if ( nearest < epsilon )
273 return theMesh->ShapeToIndex( foundEdge );
276 //=======================================================================
277 //function : getNbShape
279 //=======================================================================
281 static int getNbShape(std::string aFile, std::string aString, int defaultValue=0) {
282 int number = defaultValue;
284 std::ifstream file(aFile.c_str());
285 while ( !file.eof() ) {
286 getline( file, aLine);
287 if ( aLine == aString ) {
288 getline( file, aLine);
289 std::istringstream stringFlux( aLine );
290 stringFlux >> number;
291 number = ( number + defaultValue + std::abs(number - defaultValue) ) / 2;
299 //=======================================================================
300 //function : countShape
302 //=======================================================================
304 template < class Mesh, class Shape >
305 static int countShape( Mesh* mesh, Shape shape ) {
306 TopExp_Explorer expShape ( mesh->ShapeToMesh(), shape );
307 TopTools_MapOfShape mapShape;
309 for ( ; expShape.More(); expShape.Next() ) {
310 if (mapShape.Add(expShape.Current())) {
317 //=======================================================================
318 //function : getShape
320 //=======================================================================
322 template < class Mesh, class Shape, class Tab >
323 void getShape(Mesh* mesh, Shape shape, Tab *t_Shape) {
324 TopExp_Explorer expShape ( mesh->ShapeToMesh(), shape );
325 TopTools_MapOfShape mapShape;
326 for ( int i=0; expShape.More(); expShape.Next() ) {
327 if (mapShape.Add(expShape.Current())) {
328 t_Shape[i] = expShape.Current();
335 //=======================================================================
336 //function : printWarning
338 //=======================================================================
340 static void printWarning(const int nbExpected, std::string aString, const int nbFound) {
342 cout << "WARNING : " << nbExpected << " " << aString << " expected, Hexotic has found " << nbFound << std::endl;
343 cout << "=======" << std::endl;
348 //=======================================================================
349 //function : removeHexoticFiles
351 //=======================================================================
353 static void removeHexoticFiles(TCollection_AsciiString file_In, TCollection_AsciiString file_Out) {
354 removeFile( file_In );
355 removeFile( file_Out );
358 //=======================================================================
359 //function : writeHexoticFile
361 //=======================================================================
363 static bool writeHexoticFile (std::ofstream& theFile,
364 const SMESHDS_Mesh* theMesh,
365 std::map <int,int>& theSmdsToHexoticIdMap,
366 std::map <int,const SMDS_MeshNode*>& /*theHexoticIdToNodeMap*/,
367 const TCollection_AsciiString& Hexotic_In) {
369 cout << "Creating Hexotic processed mesh file : " << Hexotic_In << std::endl;
373 TopExp_Explorer expface(theMesh->ShapeToMesh(), TopAbs_FACE);
374 for ( ; expface.More(); expface.Next() )
379 TopoDS_Shape *tabShape, aShape;
386 const char* space = " ";
392 const SMDS_MeshNode* aNode;
393 SMDS_NodeIteratorPtr itOnNode;
395 std::list< const SMDS_MeshElement* > faces;
396 std::list< const SMDS_MeshElement* >::iterator itListFace;
397 const SMDS_MeshElement* aFace;
398 SMESHDS_SubMesh* theSubMesh;
399 std::map<int,int>::const_iterator itOnSmdsNode;
400 SMDS_ElemIteratorPtr itOnSubNode, itOnSubFace;
402 // Writing SMESH points into Hexotic File
404 nbVertices = theMesh->NbNodes();
406 theFile << "MeshVersionFormatted 2" << std::endl;
407 theFile << std::endl;
408 theFile << "Dimension" << std::endl;
409 theFile << 3 << std::endl;
410 theFile << "# Set of mesh vertices" << std::endl;
411 theFile << "Vertices" << std::endl;
412 theFile << nbVertices << std::endl;
414 tabID = new int[nbShape];
415 tabNodeId = new int[ nbVertices ];
416 tabShape = new TopoDS_Shape[nbShape];
418 itOnNode = theMesh->nodesIterator();
419 while ( itOnNode->more() ) {
420 aNode = itOnNode->next();
421 dummy_0D = aNode->getshapeId();
422 tabNodeId[ aSmdsNodeID - 1 ] = 0;
424 for ( int j=0; j< aSmdsNodeID; j++ ) {
425 if ( dummy_0D == tabNodeId[j] ) {
431 tabNodeId[ aSmdsNodeID - 1 ] = dummy_0D;
432 theSmdsToHexoticIdMap.insert(std::map <int,int>::value_type( aNode->GetID(), aSmdsNodeID ));
434 theFile << aNode->X() << space << aNode->Y() << space << aNode->Z() << space << dummy_0D << std::endl;
437 // Writing SMESH faces into Hexotic File
439 ostringstream triaOut;
443 for ( int i = 0; expface.More(); expface.Next(), i++ ) {
445 aShape = expface.Current();
446 shapeID = theMesh->ShapeToIndex( aShape );
448 for ( int j=0; j<=i; j++) {
449 if ( shapeID == tabID[j] ) {
456 tabShape[i] = aShape;
459 for ( int i=0; i<nbShape; i++ ) {
460 if ( ! (tabID[i] == 0) ) {
461 aShape = tabShape[i];
463 theSubMesh = theMesh->MeshElements( aShape );
464 itOnSubFace = theSubMesh->GetElements();
465 while ( itOnSubFace->more() ) {
466 aFace = itOnSubFace->next();
469 nbNodes = aFace->IsQuadratic() ? aFace->NbNodes()/2 : aFace->NbNodes();
470 if ( nbNodes == 3 ) // triangle
473 for ( int i = 0; i < nbNodes; ++i )
475 aSmdsNodeID = aFace->GetNode( i )->GetID();
476 itOnSmdsNode = theSmdsToHexoticIdMap.find( aSmdsNodeID );
477 ASSERT( itOnSmdsNode != theSmdsToHexoticIdMap.end() );
478 triaOut << (*itOnSmdsNode).second << space;
480 triaOut << dummy_2D << std::endl;
484 int nbTria = nbNodes - 2, n0 = theSmdsToHexoticIdMap[ aFace->GetNode(0)->GetID() ];
485 nbTriangles += nbTria;
486 for ( int i = 0; i < nbTria; ++i )
488 triaOut << n0 << space;
489 triaOut << theSmdsToHexoticIdMap[ aFace->GetNode(i+1)->GetID() ] << space;
490 triaOut << theSmdsToHexoticIdMap[ aFace->GetNode(i+2)->GetID() ] << space;
491 triaOut << dummy_2D << std::endl;
498 theFile << std::endl;
499 theFile << "# Set of mesh triangles (v1,v2,v3,tag)" << std::endl;
500 theFile << "Triangles" << std::endl;
501 theFile << nbTriangles << std::endl;
502 theFile << triaOut.str() << std::endl;
504 theFile << std::endl;
505 theFile << "End" << std::endl;
507 cout << "Processed mesh file created, it contains :" << std::endl;
508 cout << " " << nbVertices << " vertices" << std::endl;
509 cout << " " << nbTriangles << " triangles" << std::endl;
519 //=======================================================================
520 //function : writeHexoticFile
522 //=======================================================================
524 static bool writeHexoticFile (std::ofstream& theFile,
525 const SMESH_MesherHelper* theHelper,
526 std::map <int,int>& theSmdsToHexoticIdMap,
527 const TCollection_AsciiString& Hexotic_In)
530 cout << "Creating Hexotic processed mesh file : " << Hexotic_In << std::endl;
534 const char* space = " ";
539 const SMDS_MeshNode* aNode;
540 SMDS_NodeIteratorPtr itOnNode;
542 const SMDS_MeshElement* aFace;
543 std::map<int,int>::const_iterator itOnSmdsNode;
544 SMDS_ElemIteratorPtr itOnSubNode, itOnSubFace;
546 // Writing SMESH points into Hexotic File
548 nbVertices = theHelper->GetMeshDS()->NbNodes();
550 theFile << "MeshVersionFormatted 2" << std::endl;
551 theFile << std::endl;
552 theFile << "Dimension" << std::endl;
553 theFile << 3 << std::endl;
554 theFile << "# Set of mesh vertices" << std::endl;
555 theFile << "Vertices" << std::endl;
556 theFile << nbVertices << std::endl;
558 itOnNode = theHelper->GetMeshDS()->nodesIterator();
559 while ( itOnNode->more() )
561 aNode = itOnNode->next();
562 theSmdsToHexoticIdMap.insert(make_pair( aNode->GetID(), aSmdsNodeID ));
564 theFile << aNode->X() << space << aNode->Y() << space << aNode->Z() << space << dummy_0D << std::endl;
567 // Writing SMESH faces into Hexotic File
569 ostringstream triaOut;
571 itOnSubFace = theHelper->GetMeshDS()->elementsIterator(SMDSAbs_Face);
572 while ( itOnSubFace->more() )
574 aFace = itOnSubFace->next();
575 int nbNodes = aFace->IsQuadratic() ? aFace->NbNodes()/2 : aFace->NbNodes();
576 if ( nbNodes == 3 ) // triangle
579 for ( int i = 0; i < nbNodes; ++i )
581 aSmdsNodeID = aFace->GetNode( i )->GetID();
582 itOnSmdsNode = theSmdsToHexoticIdMap.find( aSmdsNodeID );
583 ASSERT( itOnSmdsNode != theSmdsToHexoticIdMap.end() );
584 triaOut << (*itOnSmdsNode).second << space;
586 triaOut << dummy_2D << std::endl;
590 int nbTria = nbNodes - 2, n0 = theSmdsToHexoticIdMap[ aFace->GetNode(0)->GetID() ];
591 nbTriangles += nbTria;
592 for ( int i = 0; i < nbTria; ++i )
594 triaOut << n0 << space;
595 triaOut << theSmdsToHexoticIdMap[ aFace->GetNode(i+1)->GetID() ] << space;
596 triaOut << theSmdsToHexoticIdMap[ aFace->GetNode(i+2)->GetID() ] << space;
597 triaOut << dummy_2D << std::endl;
602 theFile << std::endl;
603 theFile << "# Set of mesh triangles (v1,v2,v3,tag)" << std::endl;
604 theFile << "Triangles" << std::endl;
605 theFile << nbTriangles << std::endl;
606 theFile << triaOut.str() << std::endl;
608 theFile << std::endl;
609 theFile << "End" << std::endl;
611 cout << "Processed mesh file created, it contains :" << std::endl;
612 cout << " " << nbVertices << " vertices" << std::endl;
613 cout << " " << nbTriangles << " triangles" << std::endl;
619 //=======================================================================
620 //function : readResult
622 //=======================================================================
624 static bool readResult(std::string theFile,
625 #ifdef WITH_SMESH_CANCEL_COMPUTE
626 HexoticPlugin_Hexotic* theAlgo,
628 SMESHDS_Mesh* theMesh,
630 const TopoDS_Shape* tabShape,
634 // ---------------------------------
635 // Optimisation of the plugin ...
636 // Retrieve the correspondance edge --> shape
637 // (which is very costly) only when user
638 // has defined at least one group of edges
639 // which should be rare for a 3d mesh !
640 // ---------------------------------
642 bool retrieve_edges = false;
643 const std::set<SMESHDS_GroupBase*>& aGroups = theMesh->GetGroups();
644 set<SMESHDS_GroupBase*>::const_iterator GrIt = aGroups.begin();
645 for (; GrIt != aGroups.end(); GrIt++)
647 SMESHDS_GroupBase* aGrp = *GrIt;
650 if ( aGrp->GetType() == SMDSAbs_Edge )
652 retrieve_edges = true;
657 // ---------------------------------
658 // Read generated elements and nodes
659 // ---------------------------------
662 TopoDS_Vertex aVertex;
664 int EndOfFile = 0, nbElem = 0, nField = 9, nbRef = 0;
665 int aHexoticNodeID = 0, shapeID, hexoticShapeID;
666 const int IdShapeRef = 2;
667 int *tabID, *tabRef, *nodeAssigne;
668 bool *tabDummy, hasDummy = false;
669 double epsilon = Precision::Confusion();
670 std::map <std::string,int> mapField;
671 SMDS_MeshNode** HexoticNode;
672 TopoDS_Shape *tabCorner, *tabEdge;
674 const int nbDomains = countShape( theMesh, TopAbs_SHELL );
675 MESSAGE("Nb domains in the meshed shape: " << nbDomains );
676 const int holeID = -1;
678 // tabID = new int[nbShape];
679 tabID = new int[nbDomains];
680 tabRef = new int[nField];
681 tabDummy = new bool[nField];
683 for (int i=0; i<nbDomains; i++)
685 if ( nbDomains == 1 )
686 tabID[0] = theMesh->ShapeToIndex( tabShape[0] );
688 mapField["MeshVersionFormatted"] = 0; tabRef[0] = 0; tabDummy[0] = false;
689 mapField["Dimension"] = 1; tabRef[1] = 0; tabDummy[1] = false;
690 mapField["Vertices"] = 2; tabRef[2] = 3; tabDummy[2] = true;
691 mapField["Corners"] = 3; tabRef[3] = 1; tabDummy[3] = false;
692 mapField["Edges"] = 4; tabRef[4] = 2; tabDummy[4] = true;
693 mapField["Ridges"] = 5; tabRef[5] = 1; tabDummy[5] = false;
694 mapField["Quadrilaterals"] = 6; tabRef[6] = 4; tabDummy[6] = true;
695 mapField["Hexahedra"] = 7; tabRef[7] = 8; tabDummy[7] = true;
696 mapField["End"] = 8; tabRef[8] = 0; tabDummy[0] = false;
698 SMDS_NodeIteratorPtr itOnHexoticInputNode = theMesh->nodesIterator();
699 while ( itOnHexoticInputNode->more() )
700 theMesh->RemoveNode( itOnHexoticInputNode->next() );
702 int nbVertices = getNbShape(theFile, "Vertices");
703 int nbCorners = getNbShape(theFile, "Corners", countShape( theMesh, TopAbs_VERTEX ));
704 int nbShapeEdge = countShape( theMesh, TopAbs_EDGE );
706 tabCorner = new TopoDS_Shape[ nbCorners ];
707 tabEdge = new TopoDS_Shape[ nbShapeEdge ];
708 nodeAssigne = new int[ nbVertices + 1 ];
709 HexoticNode = new SMDS_MeshNode*[ nbVertices + 1 ];
711 getShape(theMesh, TopAbs_VERTEX, tabCorner);
712 getShape(theMesh, TopAbs_EDGE, tabEdge);
714 MESSAGE("Read " << theFile << " file");
715 std::ifstream fileRes(theFile.c_str());
718 while ( EndOfFile == 0 ) {
722 if (mapField.count(token)) {
723 nField = mapField[token];
724 nbRef = tabRef[nField];
725 hasDummy = tabDummy[nField];
733 if ( nField < (mapField.size() - 1) && nField >= 0 )
737 case 0: { // "MeshVersionFormatted"
738 MESSAGE(token << " " << nbElem);
741 case 1: { // "Dimension"
742 MESSAGE("Mesh dimension " << nbElem << "D");
745 case 2: { // "Vertices"
746 MESSAGE("Read " << nbElem << " " << token);
749 SMDS_MeshNode * aHexoticNode;
751 coord = new double[nbRef];
752 for ( int iElem = 0; iElem < nbElem; iElem++ ) {
753 #ifdef WITH_SMESH_CANCEL_COMPUTE
754 if(theAlgo->computeCanceled())
759 aHexoticID = iElem + 1;
760 for ( int iCoord = 0; iCoord < 3; iCoord++ )
761 fileRes >> coord[ iCoord ];
763 aHexoticNode = theMesh->AddNode(coord[0], coord[1], coord[2]);
764 HexoticNode[ aHexoticID ] = aHexoticNode;
765 nodeAssigne[ aHexoticID ] = 0;
773 case 6: // "Quadrilaterals"
774 case 7: { // "Hexahedra"
775 MESSAGE("Read " << nbElem << " " << token);
776 SMDS_MeshNode** node;
777 int nodeDim, *nodeID;
778 SMDS_MeshElement * aHexoticElement = 0;
780 node = new SMDS_MeshNode*[ nbRef ];
781 nodeID = new int[ nbRef ];
782 for ( int iElem = 0; iElem < nbElem; iElem++ ) {
783 #ifdef WITH_SMESH_CANCEL_COMPUTE
784 if(theAlgo->computeCanceled())
789 for ( int iRef = 0; iRef < nbRef; iRef++ ) {
790 fileRes >> aHexoticNodeID; // read nbRef aHexoticNodeID
791 node[ iRef ] = HexoticNode[ aHexoticNodeID ];
792 nodeID[ iRef ] = aHexoticNodeID;
797 case 3: { // "Corners"
799 gp_Pnt HexoticPnt ( node[0]->X(), node[0]->Y(), node[0]->Z() );
800 for ( int i=0; i<nbElem; i++ ) {
801 aVertex = TopoDS::Vertex( tabCorner[i] );
802 gp_Pnt aPnt = BRep_Tool::Pnt( aVertex );
803 if ( aPnt.Distance( HexoticPnt ) < epsilon )
810 aHexoticElement = theMesh->AddEdge( node[0], node[1] );
812 if ( nodeAssigne[ nodeID[0] ] == 0 || nodeAssigne[ nodeID[0] ] == 2 )
815 shapeID = findEdge( node[iNode], theMesh, nbShapeEdge, tabEdge );
820 case 5: { // "Ridges"
823 case 6: { // "Quadrilaterals"
825 aHexoticElement = theMesh->AddFace( node[0], node[1], node[2], node[3] );
829 case 7: { // "Hexahedra"
831 if ( nbDomains > 1 ) {
832 hexoticShapeID = dummy - IdShapeRef;
833 if ( tabID[ hexoticShapeID ] == 0 ) {
834 aShape = findShape(node, aShape, tabShape, tabBox, nbShape);
835 shapeID = aShape.IsNull() ? holeID : theMesh->ShapeToIndex( aShape );
836 tabID[ hexoticShapeID ] = shapeID;
839 shapeID = tabID[ hexoticShapeID ];
840 if ( iElem == (nbElem - 1) ) {
841 int shapeAssociated = 0;
842 for ( int i=0; i<nbDomains; i++ ) {
844 shapeAssociated += 1;
846 if ( shapeAssociated != nbShape )
847 printWarning(nbShape, "domains", shapeAssociated);
853 if ( (sdMode == 4 && shapeID != holeID) || sdMode != 2 )
854 aHexoticElement = theMesh->AddVolume( node[0], node[3], node[2], node[1], node[4], node[7], node[6], node[5] );
859 if ( token != "Ridges" && ( shapeID > 0 || token == "Corners")) {
860 for ( int i=0; i<nbRef; i++ ) {
861 if ( nodeAssigne[ nodeID[i] ] == 0 ) {
862 if ( token == "Corners" ) theMesh->SetNodeOnVertex( node[0], aVertex );
863 else if ( token == "Edges" ) theMesh->SetNodeOnEdge( node[i], shapeID );
864 else if ( token == "Quadrilaterals" ) theMesh->SetNodeOnFace( node[i], shapeID );
865 else if ( token == "Hexahedra" ) theMesh->SetNodeInVolume( node[i], shapeID );
866 nodeAssigne[ nodeID[i] ] = nodeDim;
869 if ( token != "Corners" && aHexoticElement )
870 theMesh->SetMeshElementOnShape( aHexoticElement, shapeID );
879 MESSAGE("End of " << theFile << " file");
883 MESSAGE("Unknown Token: " << token);
889 // remove nodes in holes
892 SMESHDS_SubMesh* subMesh;
893 for ( int i = 1; i <= nbVertices; ++i )
894 if ( HexoticNode[i]->NbInverseElements() == 0 )
896 subMesh = HexoticNode[i]->getshapeId() > 0 ? theMesh->MeshElements(HexoticNode[i]->getshapeId() ) : 0;
897 theMesh->RemoveFreeNode( HexoticNode[i], subMesh, /*fromGroups=*/false );
905 delete [] nodeAssigne;
906 delete [] HexoticNode;
911 //=======================================================================
912 //function : readResult
914 //=======================================================================
916 static bool readResult(std::string theFile,
917 #ifdef WITH_SMESH_CANCEL_COMPUTE
918 HexoticPlugin_Hexotic* theAlgo,
920 SMESH_MesherHelper* theHelper,
923 SMESHDS_Mesh* theMesh = theHelper->GetMeshDS();
925 // ---------------------------------
926 // Read generated elements and nodes
927 // ---------------------------------
930 const int nbField = 9;
931 int nField, EndOfFile = 0, nbElem = 0, nbRef = 0;
932 int aHexoticNodeID = 0, shapeID;
933 int tabRef[nbField], *nodeAssigne;
934 bool tabDummy[nbField], hasDummy = false;
935 std::map <std::string,int> mapField;
936 SMDS_MeshNode** HexoticNode;
938 mapField["MeshVersionFormatted"] = 0; tabRef[0] = 0; tabDummy[0] = false;
939 mapField["Dimension"] = 1; tabRef[1] = 0; tabDummy[1] = false;
940 mapField["Vertices"] = 2; tabRef[2] = 3; tabDummy[2] = true;
941 mapField["Corners"] = 3; tabRef[3] = 1; tabDummy[3] = false;
942 mapField["Edges"] = 4; tabRef[4] = 2; tabDummy[4] = true;
943 mapField["Ridges"] = 5; tabRef[5] = 1; tabDummy[5] = false;
944 mapField["Quadrilaterals"] = 6; tabRef[6] = 4; tabDummy[6] = true;
945 mapField["Hexahedra"] = 7; tabRef[7] = 8; tabDummy[7] = true;
946 mapField["End"] = 8; tabRef[8] = 0; tabDummy[8] = false;
948 theHelper->GetMesh()->Clear();
950 int nbVertices = getNbShape(theFile, "Vertices");
951 HexoticNode = new SMDS_MeshNode*[ nbVertices + 1 ];
952 nodeAssigne = new int[ nbVertices + 1 ];
954 MESSAGE("Read " << theFile << " file");
955 std::ifstream fileRes(theFile.c_str());
963 if (mapField.count(token)) {
964 nField = mapField[token];
965 nbRef = tabRef[nField];
966 hasDummy = tabDummy[nField];
974 if ( nField < (mapField.size() - 1) && nField >= 0 )
978 case 0: { // "MeshVersionFormatted"
979 MESSAGE(token << " " << nbElem);
982 case 1: { // "Dimension"
983 MESSAGE("Mesh dimension " << nbElem << "D");
986 case 2: { // "Vertices"
987 MESSAGE("Read " << nbElem << " " << token);
990 SMDS_MeshNode * aHexoticNode;
992 for ( int iElem = 0; iElem < nbElem; iElem++ ) {
993 #ifdef WITH_SMESH_CANCEL_COMPUTE
994 if(theAlgo->computeCanceled())
999 aHexoticID = iElem + 1;
1000 for ( int iCoord = 0; iCoord < 3; iCoord++ )
1001 fileRes >> coord[ iCoord ];
1003 aHexoticNode = theMesh->AddNode(coord[0], coord[1], coord[2]);
1004 HexoticNode[ aHexoticID ] = aHexoticNode;
1005 nodeAssigne[ aHexoticID ] = 0;
1009 case 3: // "Corners"
1012 case 6: // "Quadrilaterals"
1013 case 7: { // "Hexahedra"
1014 MESSAGE("Read " << nbElem << " " << token);
1015 std::vector< SMDS_MeshNode* > node( nbRef );
1016 std::vector< int > nodeID( nbRef );
1018 for ( int iElem = 0; iElem < nbElem; iElem++ )
1020 #ifdef WITH_SMESH_CANCEL_COMPUTE
1021 if(theAlgo->computeCanceled())
1026 for ( int iRef = 0; iRef < nbRef; iRef++ )
1028 fileRes >> aHexoticNodeID; // read nbRef aHexoticNodeID
1029 node [ iRef ] = HexoticNode[ aHexoticNodeID ];
1030 nodeID[ iRef ] = aHexoticNodeID;
1037 theHelper->AddEdge( node[0], node[1] ); break;
1038 case 6: // "Quadrilaterals"
1039 theMesh->AddFace( node[0], node[1], node[2], node[3] ); break;
1040 case 7: // "Hexahedra"
1041 theHelper->AddVolume( node[0], node[3], node[2], node[1],
1042 node[4], node[7], node[6], node[5] ); break;
1046 for ( int iRef = 0; iRef < nbRef; iRef++ )
1047 nodeAssigne[ nodeID[ iRef ]] = 1;
1053 MESSAGE("End of " << theFile << " file");
1057 MESSAGE("Unknown Token: " << token);
1063 shapeID = theHelper->GetSubShapeID();
1064 for ( int i = 0; i < nbVertices; ++i )
1065 if ( !nodeAssigne[ i+1 ])
1066 theMesh->SetNodeInVolume( HexoticNode[ i+1 ], shapeID );
1068 delete [] HexoticNode;
1069 delete [] nodeAssigne;
1073 //=============================================================================
1075 * Pass parameters to Hexotic
1077 //=============================================================================
1079 void HexoticPlugin_Hexotic::SetParameters(const HexoticPlugin_Hypothesis* hyp) {
1081 MESSAGE("HexoticPlugin_Hexotic::SetParameters");
1083 _hexesMinLevel = hyp->GetHexesMinLevel();
1084 _hexesMaxLevel = hyp->GetHexesMaxLevel();
1085 _hexesMinSize = hyp->GetMinSize();
1086 _hexesMaxSize = hyp->GetMaxSize();
1087 _hexoticIgnoreRidges = hyp->GetHexoticIgnoreRidges();
1088 _hexoticInvalidElements = hyp->GetHexoticInvalidElements();
1089 _hexoticSharpAngleThreshold = hyp->GetHexoticSharpAngleThreshold();
1090 _hexoticNbProc = hyp->GetHexoticNbProc();
1091 _hexoticWorkingDirectory = hyp->GetHexoticWorkingDirectory();
1092 _hexoticVerbosity = hyp->GetHexoticVerbosity();
1093 _hexoticSdMode = hyp->GetHexoticSdMode();
1097 cout << "WARNING : The Hexotic default parameters are taken into account" << std::endl;
1098 cout << "=======" << std::endl;
1099 _hexesMinLevel = hyp->GetDefaultHexesMinLevel();
1100 _hexesMaxLevel = hyp->GetDefaultHexesMaxLevel();
1101 _hexesMinSize = hyp->GetDefaultMinSize();
1102 _hexesMaxSize = hyp->GetDefaultMaxSize();
1103 _hexoticIgnoreRidges = hyp->GetDefaultHexoticIgnoreRidges();
1104 _hexoticInvalidElements = hyp->GetDefaultHexoticInvalidElements();
1105 _hexoticSharpAngleThreshold = hyp->GetDefaultHexoticSharpAngleThreshold();
1106 _hexoticNbProc = hyp->GetDefaultHexoticNbProc();
1107 _hexoticWorkingDirectory = hyp->GetDefaultHexoticWorkingDirectory();
1108 _hexoticVerbosity = hyp->GetDefaultHexoticVerbosity();
1109 _hexoticSdMode = hyp->GetDefaultHexoticSdMode();
1113 //=======================================================================
1114 //function : getTmpDir
1116 //=======================================================================
1118 static TCollection_AsciiString getTmpDir()
1120 TCollection_AsciiString aTmpDir;
1122 char *Tmp_dir = getenv("SALOME_TMP_DIR");
1123 if(Tmp_dir != NULL) {
1126 if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\';
1128 if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/';
1133 aTmpDir = TCollection_AsciiString("C:\\");
1135 aTmpDir = TCollection_AsciiString("/tmp/");
1141 //================================================================================
1143 * \brief Returns a command to run Hexotic mesher
1145 //================================================================================
1147 std::string HexoticPlugin_Hexotic::getHexoticCommand(const TCollection_AsciiString& Hexotic_In,
1148 const TCollection_AsciiString& Hexotic_Out) const
1151 cout << "Hexotic execution..." << std::endl;
1152 cout << _name << " parameters :" << std::endl;
1153 cout << " " << _name << " Verbosity = " << _hexoticVerbosity << std::endl;
1154 cout << " " << _name << " Segments Min Level = " << _hexesMinLevel << std::endl;
1155 cout << " " << _name << " Segments Max Level = " << _hexesMaxLevel << std::endl;
1156 cout << " " << _name << " Segments Min Size = " << _hexesMinSize << std::endl;
1157 cout << " " << _name << " Segments Max Size = " << _hexesMaxSize << std::endl;
1158 cout << " " << "Hexotic can ignore ridges : " << (_hexoticIgnoreRidges ? "yes":"no") << std::endl;
1159 cout << " " << "Hexotic authorize invalide elements : " << ( _hexoticInvalidElements ? "yes":"no") << std::endl;
1160 cout << " " << _name << " Sharp angle threshold = " << _hexoticSharpAngleThreshold << " degrees" << std::endl;
1161 cout << " " << _name << " Number of threads = " << _hexoticNbProc << std::endl;
1162 cout << " " << _name << " Working directory = \"" << _hexoticWorkingDirectory << "\"" << std::endl;
1163 cout << " " << _name << " Sub. Dom mode = " << _hexoticSdMode << std::endl;
1165 TCollection_AsciiString run_Hexotic( "hexotic" );
1167 TCollection_AsciiString minl = " -minl ", maxl = " -maxl ", angle = " -ra ";
1168 TCollection_AsciiString mins = " -mins ", maxs = " -maxs ";
1169 TCollection_AsciiString in = " -in ", out = " -out ";
1170 TCollection_AsciiString ignoreRidges = " -nr ", invalideElements = " -inv ";
1171 TCollection_AsciiString subdom = " -sd ", sharp = " -sharp ";
1172 TCollection_AsciiString proc = " -nproc ";
1173 TCollection_AsciiString verb = " -v ";
1175 TCollection_AsciiString minLevel, maxLevel, minSize, maxSize, sharpAngle, mode, nbproc, verbosity;
1176 minLevel = _hexesMinLevel;
1177 maxLevel = _hexesMaxLevel;
1178 minSize = _hexesMinSize;
1179 maxSize = _hexesMaxSize;
1180 sharpAngle = _hexoticSharpAngleThreshold;
1181 mode = _hexoticSdMode;
1182 nbproc = _hexoticNbProc;
1183 verbosity = _hexoticVerbosity;
1185 if (_hexoticIgnoreRidges)
1186 run_Hexotic += ignoreRidges;
1188 if (_hexoticInvalidElements)
1189 run_Hexotic += invalideElements;
1191 if (_hexesMinSize > 0)
1192 run_Hexotic += mins + minSize;
1194 if (_hexesMaxSize > 0)
1195 run_Hexotic += maxs + maxSize;
1197 if (_hexesMinLevel > 0)
1198 run_Hexotic += minl + minLevel;
1200 if (_hexesMaxLevel > 0)
1201 run_Hexotic += maxl + maxLevel;
1203 if (_hexoticSharpAngleThreshold > 0)
1204 run_Hexotic += angle + sharpAngle;
1206 run_Hexotic += in + Hexotic_In + out + Hexotic_Out;
1207 run_Hexotic += subdom + mode;
1208 run_Hexotic += proc + nbproc;
1209 run_Hexotic += verb + verbosity;
1211 return run_Hexotic.ToCString();
1214 //=============================================================================
1216 * Here we are going to use the Hexotic mesher
1218 //=============================================================================
1220 bool HexoticPlugin_Hexotic::Compute(SMESH_Mesh& theMesh,
1221 const TopoDS_Shape& theShape)
1223 #ifdef WITH_SMESH_CANCEL_COMPUTE
1224 _compute_canceled = false;
1227 SMESHDS_Mesh* meshDS = theMesh.GetMeshDS();
1228 TCollection_AsciiString hexahedraMessage;
1230 if (_iShape == 0 && _nbShape == 0) {
1231 _nbShape = countShape( meshDS, TopAbs_SOLID ); // we count the number of shapes
1232 //_tabNode = new SMDS_MeshNode*[_nbShape]; // we declare the size of the node array
1235 // to prevent from displaying error message after computing,
1236 // SetIsAlwaysComputed( true ) to empty sub-meshes
1237 for ( int i = 0; i < _nbShape; ++i )
1238 if ( SMESH_subMesh* sm = theMesh.GetSubMeshContaining( theShape ))
1240 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true,
1241 /*complexShapeFirst=*/false);
1242 while ( smIt->more() )
1245 if ( !sm->IsMeshComputed() )
1246 sm->SetIsAlwaysComputed( true );
1252 if (_iShape == _nbShape ) {
1254 // for (int i=0; i<_nbShape; i++) // we destroy the (_nbShape - 1) nodes created and used
1255 // meshDS->RemoveNode( _tabNode[i] ); // to simulate successful mesh computing.
1256 // delete [] _tabNode;
1258 // create bounding box for each shape of the compound
1261 TopoDS_Shape *tabShape;
1264 tabShape = new TopoDS_Shape[_nbShape];
1265 tabBox = new double*[_nbShape];
1266 for (int i=0; i<_nbShape; i++)
1267 tabBox[i] = new double[6];
1268 double Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
1270 TopExp_Explorer expBox (meshDS->ShapeToMesh(), TopAbs_SOLID);
1271 for (; expBox.More(); expBox.Next()) {
1272 tabShape[iShape] = expBox.Current();
1273 Bnd_Box BoundingBox;
1274 BRepBndLib::Add(expBox.Current(), BoundingBox);
1275 BoundingBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
1276 tabBox[iShape][0] = Xmin; tabBox[iShape][1] = Xmax;
1277 tabBox[iShape][2] = Ymin; tabBox[iShape][3] = Ymax;
1278 tabBox[iShape][4] = Zmin; tabBox[iShape][5] = Zmax;
1282 SetParameters(_hypothesis);
1284 // TCollection_AsciiString aTmpDir = getTmpDir();
1285 TCollection_AsciiString aTmpDir = TCollection_AsciiString(_hexoticWorkingDirectory.c_str());
1287 if ( aTmpDir.Value(aTmpDir.Length()) != '\\' ) aTmpDir += '\\';
1289 if ( aTmpDir.Value(aTmpDir.Length()) != '/' ) aTmpDir += '/';
1291 TCollection_AsciiString Hexotic_In(""), Hexotic_Out;
1292 TCollection_AsciiString modeFile_In( "chmod 666 " ), modeFile_Out( "chmod 666 " );
1293 TCollection_AsciiString aLogFileName = aTmpDir + "Hexotic.log"; // log
1295 std::map <int,int> aSmdsToHexoticIdMap;
1296 std::map <int,const SMDS_MeshNode*> aHexoticIdToNodeMap;
1298 Hexotic_Out = aTmpDir + "Hexotic_Out.mesh";
1299 #ifdef WITH_BLSURFPLUGIN
1300 bool defaultInputFile = true;
1301 if (_blsurfHypo && !_blsurfHypo->GetQuadAllowed()) {
1302 Hexotic_In = TCollection_AsciiString(_blsurfHypo->GetGMFFile().c_str());
1303 if (Hexotic_In != "")
1304 defaultInputFile = false;
1306 if (defaultInputFile) {
1308 Hexotic_In = aTmpDir + "Hexotic_In.mesh";
1309 removeHexoticFiles(Hexotic_In, Hexotic_Out);
1310 std::ofstream HexoticFile (Hexotic_In.ToCString(), std::ios::out);
1311 Ok = ( writeHexoticFile(HexoticFile, meshDS, aSmdsToHexoticIdMap, aHexoticIdToNodeMap, Hexotic_In) );
1312 HexoticFile.close();
1313 #ifdef WITH_BLSURFPLUGIN
1316 removeFile( Hexotic_Out );
1321 std::string run_Hexotic = getHexoticCommand(Hexotic_In, Hexotic_Out);
1322 run_Hexotic += std::string(" 1 > ") + aLogFileName.ToCString(); // dump into file
1325 cout << "Hexotic command : " << run_Hexotic << std::endl;
1328 // removeHexoticFiles(Hexotic_In, Hexotic_Out);
1330 // std::ofstream HexoticFile (Hexotic_In.ToCString(), std::ios::out);
1332 // Ok = ( writeHexoticFile(HexoticFile, meshDS, aSmdsToHexoticIdMap, aHexoticIdToNodeMap, Hexotic_In) );
1334 // HexoticFile.close();
1335 modeFile_In += Hexotic_In;
1336 system( modeFile_In.ToCString() );
1337 aSmdsToHexoticIdMap.clear();
1338 aHexoticIdToNodeMap.clear();
1340 MESSAGE("HexoticPlugin_Hexotic::Compute");
1342 system( run_Hexotic.data() );
1348 std::ifstream fileRes( Hexotic_Out.ToCString() );
1349 modeFile_Out += Hexotic_Out;
1350 system( modeFile_Out.ToCString() );
1351 if ( ! fileRes.fail() ) {
1352 Ok = readResult( Hexotic_Out.ToCString(),
1353 #ifdef WITH_SMESH_CANCEL_COMPUTE
1356 meshDS, _nbShape, tabShape, tabBox, _hexoticSdMode );
1358 hexahedraMessage = "success";
1360 hexahedraMessage = "failed";
1363 hexahedraMessage = "failed";
1364 cout << "Problem with Hexotic output file " << Hexotic_Out.ToCString() << std::endl;
1367 SMESH_File logFile( aLogFileName.ToCString() );
1368 if ( !logFile.eof() )
1370 char msgLic[] = " Dlim ";
1371 const char* fileBeg = logFile.getPos(), *fileEnd = fileBeg + logFile.size();
1372 if ( std::search( fileBeg, fileEnd, msgLic, msgLic+strlen(msgLic)) != fileEnd )
1373 error("Licence problems.");
1376 cout << "Hexahedra meshing " << hexahedraMessage << std::endl;
1380 for (int i=0; i<_nbShape; i++)
1381 delete [] tabBox[i];
1386 #ifdef WITH_SMESH_CANCEL_COMPUTE
1387 if(_compute_canceled)
1388 return error(SMESH_Comment("interruption initiated by user"));
1393 //=============================================================================
1395 * \brief Computes mesh without geometry
1396 * \param aMesh - the mesh
1397 * \param aHelper - helper that must be used for adding elements to \aaMesh
1398 * \retval bool - is a success
1400 * The method is called if ( !aMesh->HasShapeToMesh() )
1402 //=============================================================================
1404 bool HexoticPlugin_Hexotic::Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper)
1406 #ifdef WITH_SMESH_CANCEL_COMPUTE
1407 _compute_canceled = false;
1410 TCollection_AsciiString hexahedraMessage;
1412 SetParameters(_hypothesis);
1414 TCollection_AsciiString aTmpDir = getTmpDir();
1415 TCollection_AsciiString Hexotic_In, Hexotic_Out;
1416 TCollection_AsciiString modeFile_In( "chmod 666 " ), modeFile_Out( "chmod 666 " );
1417 TCollection_AsciiString aLogFileName = aTmpDir + "Hexotic.log"; // log
1419 std::map <int,int> aSmdsToHexoticIdMap;
1420 std::map <int,const SMDS_MeshNode*> aHexoticIdToNodeMap;
1422 Hexotic_In = aTmpDir + "Hexotic_In.mesh";
1423 Hexotic_Out = aTmpDir + "Hexotic_Out.mesh";
1425 std::string run_Hexotic = getHexoticCommand(Hexotic_In, Hexotic_Out);
1426 run_Hexotic += std::string(" 1 > ") + aLogFileName.ToCString(); // dump into file
1429 cout << "Hexotic command : " << run_Hexotic << std::endl;
1431 removeHexoticFiles(Hexotic_In, Hexotic_Out);
1433 std::ofstream HexoticFile (Hexotic_In.ToCString(), std::ios::out);
1435 Ok = ( writeHexoticFile(HexoticFile, aHelper, aSmdsToHexoticIdMap, Hexotic_In) );
1437 HexoticFile.close();
1438 modeFile_In += Hexotic_In;
1439 system( modeFile_In.ToCString() );
1440 aSmdsToHexoticIdMap.clear();
1441 aHexoticIdToNodeMap.clear();
1443 MESSAGE("HexoticPlugin_Hexotic::Compute");
1445 system( run_Hexotic.data() );
1451 std::ifstream fileRes( Hexotic_Out.ToCString() );
1452 modeFile_Out += Hexotic_Out;
1453 system( modeFile_Out.ToCString() );
1454 if ( ! fileRes.fail() ) {
1455 Ok = readResult( Hexotic_Out.ToCString(),
1456 #ifdef WITH_SMESH_CANCEL_COMPUTE
1459 aHelper, _hexoticSdMode );
1461 hexahedraMessage = "success";
1463 hexahedraMessage = "failed";
1466 hexahedraMessage = "failed";
1467 cout << "Problem with Hexotic output file " << Hexotic_Out << std::endl;
1469 SMESH_File logFile( aLogFileName.ToCString() );
1470 if ( !logFile.eof() )
1472 char msgLic[] = " Dlim ";
1473 const char* fileBeg = logFile.getPos(), *fileEnd = fileBeg + logFile.size();
1474 if ( std::search( fileBeg, fileEnd, msgLic, msgLic+strlen(msgLic)) != fileEnd )
1475 return error("Licence problems.");
1477 return error(SMESH_Comment("Problem with Hexotic output file ")<<Hexotic_Out);
1479 cout << "Hexahedra meshing " << hexahedraMessage << std::endl;
1482 #ifdef WITH_SMESH_CANCEL_COMPUTE
1483 if(_compute_canceled)
1484 return error(SMESH_Comment("interruption initiated by user"));
1489 //=============================================================================
1493 //=============================================================================
1495 bool HexoticPlugin_Hexotic::Evaluate(SMESH_Mesh& aMesh,
1496 const TopoDS_Shape& aShape,
1497 MapShapeNbElems& aResMap)
1499 std::vector<int> aResVec(SMDSEntity_Last);
1500 for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
1501 SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
1502 aResMap.insert(std::make_pair(sm,aResVec));
1504 SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
1505 smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Evaluation is not implemented",this));
1510 #ifdef WITH_SMESH_CANCEL_COMPUTE
1511 void HexoticPlugin_Hexotic::CancelCompute()
1513 _compute_canceled = true;
1516 TCollection_AsciiString aTmpDir = getTmpDir();
1517 TCollection_AsciiString Hexotic_In = aTmpDir + "Hexotic_In.mesh";
1518 TCollection_AsciiString cmd = TCollection_AsciiString("ps ux | grep ") + Hexotic_In;
1519 cmd += TCollection_AsciiString(" | grep -v grep | awk '{print $2}' | xargs kill -9 > /dev/null 2>&1");
1520 system( cmd.ToCString() );