]> SALOME platform Git repositories - plugins/hexoticplugin.git/blob - src/HexoticPlugin/HexoticPlugin_Hexotic.cxx
Salome HOME
Merge from V6_main 01/04/2013
[plugins/hexoticplugin.git] / src / HexoticPlugin / HexoticPlugin_Hexotic.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 // ---
21 // File   : HexoticPlugin_Hexotic.cxx
22 // Author : Lioka RAZAFINDRAZAKA (CEA)
23 // ---
24 //
25 #include "HexoticPlugin_Hexotic.hxx"
26 #include "HexoticPlugin_Hypothesis.hxx"
27
28 #include "utilities.h"
29
30 #ifndef WIN32
31 #include <sys/sysinfo.h>
32 #endif
33
34 #ifdef _DEBUG_
35 #define DUMP(txt) \
36 //  cout << txt
37 #else
38 #define DUMP(txt)
39 #endif
40
41 #include <SMESHDS_Mesh.hxx>
42 #include <SMESHDS_GroupBase.hxx>
43 #include <SMESH_ComputeError.hxx>
44 #include <SMESH_File.hxx>
45 #include <SMESH_Gen.hxx>
46 #include <SMESH_HypoFilter.hxx>
47 #include <SMESH_MesherHelper.hxx>
48 #include <SMESH_subMesh.hxx>
49
50 #include <list>
51 #include <cstdlib>
52 #include <iostream>
53
54 #include <Standard_ProgramError.hxx>
55
56 #include <BRep_Tool.hxx>
57 #include <BRepBndLib.hxx>
58 #include <BRepClass3d_SolidClassifier.hxx>
59 #include <BRepBuilderAPI_MakeVertex.hxx>
60 #include <BRepExtrema_DistShapeShape.hxx>
61 #include <OSD_File.hxx>
62 #include <Precision.hxx>
63 #include <TopExp_Explorer.hxx>
64 #include <TopTools_MapOfShape.hxx>
65 #include <TopoDS.hxx>
66
67 static void removeFile( const TCollection_AsciiString& fileName )
68 {
69   try {
70     OSD_File( fileName ).Remove();
71   }
72   catch ( Standard_ProgramError ) {
73     MESSAGE("Can't remove file: " << fileName.ToCString() << " ; file does not exist or permission denied");
74   }
75 }
76
77 //=============================================================================
78 /*!
79  *  
80  */
81 //=============================================================================
82
83 HexoticPlugin_Hexotic::HexoticPlugin_Hexotic(int hypId, int studyId, SMESH_Gen* gen)
84   : SMESH_3D_Algo(hypId, studyId, gen)
85 {
86   MESSAGE("HexoticPlugin_Hexotic::HexoticPlugin_Hexotic");
87   _name = "Hexotic_3D";
88   _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type
89 //   _onlyUnaryInput = false;
90   _requireShape = false;
91   _iShape=0;
92   _nbShape=0;
93   _hexoticFilesKept=false;
94   _compatibleHypothesis.push_back("Hexotic_Parameters");
95 #ifdef WITH_BLSURFPLUGIN
96   _blsurfHypo = NULL;
97 #endif
98   _compute_canceled = false;
99 }
100
101 //=============================================================================
102 /*!
103  *  
104  */
105 //=============================================================================
106
107 HexoticPlugin_Hexotic::~HexoticPlugin_Hexotic()
108 {
109   MESSAGE("HexoticPlugin_Hexotic::~HexoticPlugin_Hexotic");
110 }
111
112
113 #ifdef WITH_BLSURFPLUGIN
114 bool HexoticPlugin_Hexotic::CheckBLSURFHypothesis( SMESH_Mesh&         aMesh,
115                                                    const TopoDS_Shape& aShape )
116 {
117   // MESSAGE("HexoticPlugin_Hexotic::CheckBLSURFHypothesis");
118   _blsurfHypo = NULL;
119
120   std::list<const SMESHDS_Hypothesis*>::const_iterator itl;
121   const SMESHDS_Hypothesis* theHyp;
122
123   // If a BLSURF hypothesis is applied, get it
124   SMESH_HypoFilter blsurfFilter;
125   blsurfFilter.Init( blsurfFilter.HasName( "BLSURF_Parameters" ));
126   std::list<const SMESHDS_Hypothesis *> appliedHyps;
127   aMesh.GetHypotheses( aShape, blsurfFilter, appliedHyps, false );
128
129   if ( appliedHyps.size() > 0 ) {
130     itl = appliedHyps.begin();
131     theHyp = (*itl); // use only the first hypothesis
132     std::string hypName = theHyp->GetName();
133     if (hypName == "BLSURF_Parameters") {
134       _blsurfHypo = static_cast<const BLSURFPlugin_Hypothesis*> (theHyp);
135       ASSERT(_blsurfHypo);
136       return true;
137     }
138   }
139   return false;
140 }
141 #endif
142
143 //=============================================================================
144 /*!
145  *  
146  */
147 //=============================================================================
148
149 bool HexoticPlugin_Hexotic::CheckHypothesis( SMESH_Mesh&                          aMesh,
150                                              const TopoDS_Shape&                  aShape,
151                                              SMESH_Hypothesis::Hypothesis_Status& aStatus )
152 {
153   // MESSAGE("HexoticPlugin_Hexotic::CheckHypothesis");
154   _hypothesis = NULL;
155
156   std::list<const SMESHDS_Hypothesis*>::const_iterator itl;
157   const SMESHDS_Hypothesis* theHyp;
158
159   const std::list<const SMESHDS_Hypothesis*>& hyps = GetUsedHypothesis(aMesh, aShape, false);
160   int nbHyp = hyps.size();
161   if (!nbHyp) {
162     aStatus = SMESH_Hypothesis::HYP_OK;
163     return true;  // can work with no hypothesis
164   }
165
166   itl = hyps.begin();
167   theHyp = (*itl); // use only the first hypothesis
168
169   std::string hypName = theHyp->GetName();
170   if (hypName == "Hexotic_Parameters") {
171     _hypothesis = static_cast<const HexoticPlugin_Hypothesis*> (theHyp);
172     ASSERT(_hypothesis);
173     aStatus = SMESH_Hypothesis::HYP_OK;
174   }
175   else
176     aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
177   
178 #ifdef WITH_BLSURFPLUGIN
179   CheckBLSURFHypothesis(aMesh, aShape);
180 #endif
181   
182   return aStatus == SMESH_Hypothesis::HYP_OK;
183 }
184
185 //=======================================================================
186 //function : findShape
187 //purpose  :
188 //=======================================================================
189
190 static TopoDS_Shape findShape(SMDS_MeshNode**     t_Node,
191                               TopoDS_Shape        aShape,
192                               const TopoDS_Shape* t_Shape,
193                               double**            t_Box,
194                               const int           nShape)
195 {
196   double pntCoor[3];
197   int iShape, nbNode = 8;
198
199   for ( int i=0; i<3; i++ ) {
200     pntCoor[i] = 0;
201     for ( int j=0; j<nbNode; j++ ) {
202       if ( i == 0) pntCoor[i] += t_Node[j]->X();
203       if ( i == 1) pntCoor[i] += t_Node[j]->Y();
204       if ( i == 2) pntCoor[i] += t_Node[j]->Z();
205     }
206     pntCoor[i] /= nbNode;
207   }
208   gp_Pnt aPnt(pntCoor[0], pntCoor[1], pntCoor[2]);
209
210   if ( aShape.IsNull() ) aShape = t_Shape[0];
211   BRepClass3d_SolidClassifier SC (aShape, aPnt, Precision::Confusion());
212   if ( !(SC.State() == TopAbs_IN) ) {
213     aShape.Nullify();
214     for (iShape = 0; iShape < nShape && aShape.IsNull(); iShape++) {
215       if ( !( pntCoor[0] < t_Box[iShape][0] || t_Box[iShape][1] < pntCoor[0] ||
216               pntCoor[1] < t_Box[iShape][2] || t_Box[iShape][3] < pntCoor[1] ||
217               pntCoor[2] < t_Box[iShape][4] || t_Box[iShape][5] < pntCoor[2]) ) {
218         BRepClass3d_SolidClassifier SC (t_Shape[iShape], aPnt, Precision::Confusion());
219         if (SC.State() == TopAbs_IN)
220           aShape = t_Shape[iShape];
221       }
222     }
223   }
224   return aShape;
225 }
226
227 //=======================================================================
228 //function : findEdge
229 //purpose  :
230 //=======================================================================
231
232 static int findEdge(const SMDS_MeshNode* aNode,
233                     const SMESHDS_Mesh*  aMesh,
234                     const int            nEdge,
235                     const TopoDS_Shape*  t_Edge) {
236
237   TopoDS_Shape aPntShape, foundEdge;
238   TopoDS_Vertex aVertex;
239   gp_Pnt aPnt( aNode->X(), aNode->Y(), aNode->Z() );
240
241   int foundInd, ind;
242   double nearest = RealLast(), *t_Dist;
243   double epsilon = Precision::Confusion();
244
245   t_Dist = new double[ nEdge ];
246   aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
247   aVertex   = TopoDS::Vertex( aPntShape );
248
249   for ( ind=0; ind < nEdge; ind++ ) {
250     BRepExtrema_DistShapeShape aDistance ( aVertex, t_Edge[ind] );
251     t_Dist[ind] = aDistance.Value();
252     if ( t_Dist[ind] < nearest ) {
253       nearest   = t_Dist[ind];
254       foundEdge = t_Edge[ind];
255       foundInd  = ind;
256       if ( nearest < epsilon )
257         ind = nEdge;
258     }
259   }
260
261   delete [] t_Dist;
262   return aMesh->ShapeToIndex( foundEdge );
263 }
264
265 //=======================================================================
266 //function : getNbShape
267 //purpose  :
268 //=======================================================================
269
270 static int getNbShape(std::string aFile, std::string aString, int defaultValue=0) {
271   int number = defaultValue;
272   std::string aLine;
273   std::ifstream file(aFile.c_str());
274   while ( !file.eof() ) {
275     getline( file, aLine);
276     if ( aLine == aString ) {
277       getline( file, aLine);
278       std::istringstream stringFlux( aLine );
279       stringFlux >> number;
280       number = ( number + defaultValue + std::abs(number - defaultValue) ) / 2;
281       break;
282     }
283   }
284   file.close();
285   return number;
286 }
287
288 //=======================================================================
289 //function : countShape
290 //purpose  :
291 //=======================================================================
292
293 template < class Mesh, class Shape >
294 static int countShape( Mesh* mesh, Shape shape ) {
295   TopExp_Explorer expShape ( mesh->ShapeToMesh(), shape );
296   TopTools_MapOfShape mapShape;
297   int nbShape = 0;
298   for ( ; expShape.More(); expShape.Next() ) {
299     if (mapShape.Add(expShape.Current())) {
300       nbShape++;
301     }
302   }
303   return nbShape;
304 }
305
306 //=======================================================================
307 //function : getShape
308 //purpose  :
309 //=======================================================================
310
311 template < class Mesh, class Shape, class Tab >
312 void getShape(Mesh* mesh, Shape shape, Tab *t_Shape) {
313   TopExp_Explorer expShape ( mesh->ShapeToMesh(), shape );
314   TopTools_MapOfShape mapShape;
315   for ( int i=0; expShape.More(); expShape.Next() ) {
316     if (mapShape.Add(expShape.Current())) {
317       t_Shape[i] = expShape.Current();
318       i++;
319     }
320   }
321   return;
322 }
323
324 //=======================================================================
325 //function : printWarning
326 //purpose  :
327 //=======================================================================
328
329 static void printWarning(const int nbExpected, std::string aString, const int nbFound) {
330   cout << std::endl;
331   cout << "WARNING : " << nbExpected << " " << aString << " expected, Hexotic has found " << nbFound << std::endl;
332   cout << "=======" << std::endl;
333   cout << std::endl;
334   return;
335 }
336
337 //=======================================================================
338 //function : removeHexoticFiles
339 //purpose  :
340 //=======================================================================
341
342 static void removeHexoticFiles(TCollection_AsciiString file_In, TCollection_AsciiString file_Out) {
343   removeFile( file_In );
344   removeFile( file_Out );
345 }
346
347 //=======================================================================
348 //function : readResult
349 //purpose  : Read GMF file in case of a mesh with geometry
350 //=======================================================================
351
352 static bool readResult(std::string         theFile,
353 #ifdef WITH_SMESH_CANCEL_COMPUTE
354                        HexoticPlugin_Hexotic*  theAlgo,
355 #endif
356                        SMESHDS_Mesh*       theMesh,
357                        const int           nbShape,
358                        const TopoDS_Shape* tabShape,
359                        double**            tabBox)
360 {
361   // ---------------------------------
362   // Optimisation of the plugin ...
363   // Retrieve the correspondance edge --> shape
364   // (which is very costly) only when user
365   // has defined at least one group of edges
366   // which should be rare for a 3d mesh !
367   // ---------------------------------
368   
369   bool retrieve_edges = false;
370   const std::set<SMESHDS_GroupBase*>& aGroups = theMesh->GetGroups();
371   set<SMESHDS_GroupBase*>::const_iterator GrIt = aGroups.begin();
372   for (; GrIt != aGroups.end(); GrIt++)
373     {
374       SMESHDS_GroupBase* aGrp = *GrIt;
375       if ( !aGrp )
376         continue;
377       if ( aGrp->GetType() == SMDSAbs_Edge )
378         {
379           retrieve_edges = true;
380           break;
381         }
382     }
383   
384   // ---------------------------------
385   // Read generated elements and nodes
386   // ---------------------------------
387
388   TopoDS_Shape aShape;
389   TopoDS_Vertex aVertex;
390   std::string token;
391   int EndOfFile = 0, nbElem = 0, nField = 9, nbRef = 0;
392   int aHexoticNodeID = 0, shapeID, hexoticShapeID;
393   const int IdShapeRef = 2;
394   int *tabID, *tabRef, *nodeAssigne;
395   bool *tabDummy, hasDummy = false;
396   double epsilon = Precision::Confusion();
397   std::map <std::string,int> mapField;
398   SMDS_MeshNode** HexoticNode;
399   TopoDS_Shape *tabCorner, *tabEdge;
400
401   const int nbDomains = countShape( theMesh, TopAbs_SHELL );
402   const int holeID = -1;
403
404   // tabID    = new int[nbShape];
405   tabID    = new int[nbDomains];
406   tabRef   = new int[nField];
407   tabDummy = new bool[nField];
408
409   for (int i=0; i<nbDomains; i++)
410     tabID[i] = 0;
411   if ( nbDomains == 1 )
412     tabID[0] = theMesh->ShapeToIndex( tabShape[0] );
413
414   mapField["MeshVersionFormatted"] = 0; tabRef[0] = 0; tabDummy[0] = false;
415   mapField["Dimension"]            = 1; tabRef[1] = 0; tabDummy[1] = false;
416   mapField["Vertices"]             = 2; tabRef[2] = 3; tabDummy[2] = true;
417   mapField["Corners"]              = 3; tabRef[3] = 1; tabDummy[3] = false;
418   mapField["Edges"]                = 4; tabRef[4] = 2; tabDummy[4] = true;
419   mapField["Ridges"]               = 5; tabRef[5] = 1; tabDummy[5] = false;
420   mapField["Quadrilaterals"]       = 6; tabRef[6] = 4; tabDummy[6] = true;
421   mapField["Hexahedra"]            = 7; tabRef[7] = 8; tabDummy[7] = true;
422   mapField["End"]                  = 8; tabRef[8] = 0; tabDummy[0] = false;
423
424   SMDS_NodeIteratorPtr itOnHexoticInputNode = theMesh->nodesIterator();
425   while ( itOnHexoticInputNode->more() )
426     theMesh->RemoveNode( itOnHexoticInputNode->next() );
427
428   int nbVertices   = getNbShape(theFile, "Vertices");
429   int nbCorners    = getNbShape(theFile, "Corners", countShape( theMesh, TopAbs_VERTEX ));
430   int nbShapeEdge  = countShape( theMesh, TopAbs_EDGE );
431
432   tabCorner   = new TopoDS_Shape[ nbCorners ];
433   tabEdge     = new TopoDS_Shape[ nbShapeEdge ];
434   nodeAssigne = new int[ nbVertices + 1 ];
435   HexoticNode = new SMDS_MeshNode*[ nbVertices + 1 ];
436
437   getShape(theMesh, TopAbs_VERTEX, tabCorner);
438   getShape(theMesh, TopAbs_EDGE,   tabEdge);
439
440   MESSAGE("Read " << theFile << " file");
441   std::ifstream fileRes(theFile.c_str());
442   ASSERT(fileRes);
443
444   while ( EndOfFile == 0  ) {
445     int dummy;
446     fileRes >> token;
447
448     if (mapField.count(token)) {
449       nField   = mapField[token];
450       nbRef    = tabRef[nField];
451       hasDummy = tabDummy[nField];
452     }
453     else {
454       nField = -1;
455       nbRef = 0;
456     }
457
458     nbElem = 0;
459     if ( nField < (mapField.size() - 1) && nField >= 0 )
460       fileRes >> nbElem;
461
462     switch (nField) {
463       case 0: { // "MeshVersionFormatted"
464         MESSAGE(token << " " << nbElem);
465         break;
466       }
467       case 1: { // "Dimension"
468         MESSAGE("Mesh dimension " << nbElem << "D");
469         break;
470       }
471       case 2: { // "Vertices"
472         MESSAGE("Read " << nbElem << " " << token);
473         int aHexoticID;
474         double *coord;
475         SMDS_MeshNode * aHexoticNode;
476
477         coord = new double[nbRef];
478         for ( int iElem = 0; iElem < nbElem; iElem++ ) {
479 #ifdef WITH_SMESH_CANCEL_COMPUTE
480           if(theAlgo->computeCanceled())
481             {
482               return false;
483             }
484 #endif
485           aHexoticID = iElem + 1;
486           for ( int iCoord = 0; iCoord < 3; iCoord++ )
487             fileRes >> coord[ iCoord ];
488           fileRes >> dummy;
489           aHexoticNode = theMesh->AddNode(coord[0], coord[1], coord[2]);
490           HexoticNode[ aHexoticID ] = aHexoticNode;
491           nodeAssigne[ aHexoticID ] = 0;
492         }
493         delete [] coord;
494         break;
495       }
496       case 3: // "Corners"
497       case 4: // "Edges"
498       case 5: // "Ridges"
499       case 6: // "Quadrilaterals"
500       case 7: { // "Hexahedra"
501         MESSAGE("Read " << nbElem << " " << token);
502         SMDS_MeshNode** node;
503         int nodeDim, *nodeID;
504         SMDS_MeshElement * aHexoticElement = 0;
505
506         node   = new SMDS_MeshNode*[ nbRef ];
507         nodeID = new int[ nbRef ];
508         for ( int iElem = 0; iElem < nbElem; iElem++ ) {
509 #ifdef WITH_SMESH_CANCEL_COMPUTE
510           if(theAlgo->computeCanceled())
511             {
512               return false;
513             }
514 #endif
515           for ( int iRef = 0; iRef < nbRef; iRef++ ) {
516             fileRes >> aHexoticNodeID;                          // read nbRef aHexoticNodeID
517             node[ iRef ]   = HexoticNode[ aHexoticNodeID ];
518             nodeID[ iRef ] = aHexoticNodeID;
519           }
520           if ( hasDummy )
521             fileRes >> dummy;
522           switch (nField) {
523             case 3: { // "Corners"
524               nodeDim = 1;
525               gp_Pnt HexoticPnt ( node[0]->X(), node[0]->Y(), node[0]->Z() );
526               for ( int i=0; i<nbElem; i++ ) {
527                 aVertex = TopoDS::Vertex( tabCorner[i] );
528                 gp_Pnt aPnt = BRep_Tool::Pnt( aVertex );
529                 if ( aPnt.Distance( HexoticPnt ) < epsilon )
530                   break;
531               }
532               break;
533             }
534             case 4: { // "Edges"
535               nodeDim = 2;
536               aHexoticElement = theMesh->AddEdge( node[0], node[1] );
537               int iNode = 1;
538               if ( nodeAssigne[ nodeID[0] ] == 0 || nodeAssigne[ nodeID[0] ] == 2 )
539                 iNode = 0;
540               if(retrieve_edges)
541                 shapeID = findEdge( node[iNode], theMesh, nbShapeEdge, tabEdge );
542               else
543                 shapeID = 0;
544               break;
545             }
546             case 5: { // "Ridges"
547               break;
548             }
549             case 6: { // "Quadrilaterals"
550               nodeDim = 3;
551               aHexoticElement = theMesh->AddFace( node[0], node[1], node[2], node[3] );
552               shapeID = dummy;
553               break;
554             }
555             case 7: { // "Hexahedra"
556               nodeDim = 4;
557               if ( nbDomains > 1 ) {
558                 hexoticShapeID = dummy - IdShapeRef;
559                 if ( tabID[ hexoticShapeID ] == 0 ) {
560                   aShape = findShape(node, aShape, tabShape, tabBox, nbShape);
561                   shapeID = aShape.IsNull() ? holeID : theMesh->ShapeToIndex( aShape );
562                   tabID[ hexoticShapeID ] = shapeID;
563                 }
564                 else
565                   shapeID = tabID[ hexoticShapeID ];
566                 if ( iElem == (nbElem - 1) ) {
567                   int shapeAssociated = 0;
568                   for ( int i=0; i<nbDomains; i++ ) {
569                     if (tabID[i] > 0 )
570                       shapeAssociated += 1;
571                   }
572                   if ( shapeAssociated != nbShape )
573                     printWarning(nbShape, "domains", shapeAssociated);
574                 }
575               }
576               else {
577                 shapeID = tabID[0];
578               }
579               if ( shapeID != holeID )
580                 aHexoticElement = theMesh->AddVolume( node[0], node[3], node[2], node[1], node[4], node[7], node[6], node[5] );
581               break;
582             }
583           } // switch (nField)
584
585           if ( token != "Ridges" && ( shapeID > 0 || token == "Corners")) {
586             for ( int i=0; i<nbRef; i++ ) {
587               if ( nodeAssigne[ nodeID[i] ] == 0 ) {
588                 if      ( token == "Corners" )        theMesh->SetNodeOnVertex( node[0], aVertex );
589                 else if ( token == "Edges" )          theMesh->SetNodeOnEdge( node[i], shapeID );
590                 else if ( token == "Quadrilaterals" ) theMesh->SetNodeOnFace( node[i], shapeID );
591                 else if ( token == "Hexahedra" )      theMesh->SetNodeInVolume( node[i], shapeID );
592                 nodeAssigne[ nodeID[i] ] = nodeDim;
593               }
594             }
595             if ( token != "Corners" && aHexoticElement )
596               theMesh->SetMeshElementOnShape( aHexoticElement, shapeID );
597           }
598         }
599         delete [] node;
600         delete [] nodeID;
601         break;
602       }
603       case 8: { // "End"
604         EndOfFile = 1;
605         MESSAGE("End of " << theFile << " file");
606         break;
607       }
608       default: {
609         MESSAGE("Unknown Token: " << token);
610       }
611     }
612   }
613   cout << std::endl;
614
615   // remove nodes in holes
616   if ( nbDomains > 1 )
617   {
618     SMESHDS_SubMesh* subMesh;
619     for ( int i = 1; i <= nbVertices; ++i )
620       if ( HexoticNode[i]->NbInverseElements() == 0 )
621       {
622         subMesh =  HexoticNode[i]->getshapeId() > 0 ? theMesh->MeshElements(HexoticNode[i]->getshapeId() ) : 0;
623         theMesh->RemoveFreeNode( HexoticNode[i], subMesh, /*fromGroups=*/false );
624       }
625   }
626   delete [] tabID;
627   delete [] tabRef;
628   delete [] tabDummy;
629   delete [] tabCorner;
630   delete [] tabEdge;
631   delete [] nodeAssigne;
632   delete [] HexoticNode;
633   return true;
634 }
635
636
637 //=======================================================================
638 //function : readResult
639 //purpose  : Read GMF file in case of a mesh w/o geometry
640 //=======================================================================
641
642 static bool readResult(std::string theFile,
643 #ifdef WITH_SMESH_CANCEL_COMPUTE
644                        HexoticPlugin_Hexotic*  theAlgo,
645 #endif
646                        SMESH_MesherHelper* theHelper)
647 {
648   SMESHDS_Mesh* theMesh = theHelper->GetMeshDS();
649
650   // ---------------------------------
651   // Read generated elements and nodes
652   // ---------------------------------
653
654   std::string token;
655   const int nbField = 9;
656   int nField, EndOfFile = 0, nbElem = 0, nbRef = 0;
657   int aHexoticNodeID = 0, shapeID;
658   int tabRef[nbField], *nodeAssigne;
659   bool tabDummy[nbField], hasDummy = false;
660   std::map <std::string,int> mapField;
661   SMDS_MeshNode** HexoticNode;
662
663   mapField["MeshVersionFormatted"] = 0; tabRef[0] = 0; tabDummy[0] = false;
664   mapField["Dimension"]            = 1; tabRef[1] = 0; tabDummy[1] = false;
665   mapField["Vertices"]             = 2; tabRef[2] = 3; tabDummy[2] = true;
666   mapField["Corners"]              = 3; tabRef[3] = 1; tabDummy[3] = false;
667   mapField["Edges"]                = 4; tabRef[4] = 2; tabDummy[4] = true;
668   mapField["Ridges"]               = 5; tabRef[5] = 1; tabDummy[5] = false;
669   mapField["Quadrilaterals"]       = 6; tabRef[6] = 4; tabDummy[6] = true;
670   mapField["Hexahedra"]            = 7; tabRef[7] = 8; tabDummy[7] = true;
671   mapField["End"]                  = 8; tabRef[8] = 0; tabDummy[8] = false;
672
673   theHelper->GetMesh()->Clear();
674
675   int nbVertices = getNbShape(theFile, "Vertices");
676   HexoticNode = new SMDS_MeshNode*[ nbVertices + 1 ];
677   nodeAssigne = new int[ nbVertices + 1 ];
678
679   MESSAGE("Read " << theFile << " file");
680   std::ifstream fileRes(theFile.c_str());
681   ASSERT(fileRes);
682
683   while ( !EndOfFile  )
684   {
685     int dummy;
686     fileRes >> token;
687
688     if (mapField.count(token)) {
689       nField   = mapField[token];
690       nbRef    = tabRef[nField];
691       hasDummy = tabDummy[nField];
692     }
693     else {
694       nField = -1;
695       nbRef = 0;
696     }
697
698     nbElem = 0;
699     if ( nField < (mapField.size() - 1) && nField >= 0 )
700       fileRes >> nbElem;
701
702     switch (nField) {
703     case 0: { // "MeshVersionFormatted"
704       MESSAGE(token << " " << nbElem);
705       break;
706     }
707     case 1: { // "Dimension"
708       MESSAGE("Mesh dimension " << nbElem << "D");
709       break;
710     }
711     case 2: { // "Vertices"
712       MESSAGE("Read " << nbElem << " " << token);
713       int aHexoticID;
714       double coord[3];
715       SMDS_MeshNode * aHexoticNode;
716
717       for ( int iElem = 0; iElem < nbElem; iElem++ ) {
718 #ifdef WITH_SMESH_CANCEL_COMPUTE
719         if(theAlgo->computeCanceled())
720           {
721             return false;
722           }
723 #endif
724         aHexoticID = iElem + 1;
725         for ( int iCoord = 0; iCoord < 3; iCoord++ )
726           fileRes >> coord[ iCoord ];
727         fileRes >> dummy;
728         aHexoticNode = theMesh->AddNode(coord[0], coord[1], coord[2]);
729         HexoticNode[ aHexoticID ] = aHexoticNode;
730         nodeAssigne[ aHexoticID ] = 0;
731       }
732       break;
733     }
734     case 3: // "Corners"
735     case 4: // "Edges"
736     case 5: // "Ridges"
737     case 6: // "Quadrilaterals"
738     case 7: { // "Hexahedra"
739       MESSAGE("Read " << nbElem << " " << token);
740       std::vector< SMDS_MeshNode* > node( nbRef );
741       std::vector< int >          nodeID( nbRef );
742
743       for ( int iElem = 0; iElem < nbElem; iElem++ )
744       {
745 #ifdef WITH_SMESH_CANCEL_COMPUTE
746         if(theAlgo->computeCanceled())
747           {
748             return false;
749           }
750 #endif
751         for ( int iRef = 0; iRef < nbRef; iRef++ )
752         {
753           fileRes >> aHexoticNodeID;                          // read nbRef aHexoticNodeID
754           node  [ iRef ] = HexoticNode[ aHexoticNodeID ];
755           nodeID[ iRef ] = aHexoticNodeID;
756         }
757         if ( hasDummy )
758           fileRes >> dummy;
759         switch (nField)
760         {
761         case 4: // "Edges"
762           theHelper->AddEdge( node[0], node[1] ); break;
763         case 6:  // "Quadrilaterals"
764           theMesh->AddFace( node[0], node[1], node[2], node[3] ); break;
765         case 7: // "Hexahedra"
766           theHelper->AddVolume( node[0], node[3], node[2], node[1],
767                                 node[4], node[7], node[6], node[5] ); break;
768         default: continue;
769         }
770         if ( nField == 6 )
771           for ( int iRef = 0; iRef < nbRef; iRef++ )
772             nodeAssigne[ nodeID[ iRef ]] = 1;
773       }
774       break;
775     }
776     case 8: { // "End"
777       EndOfFile = 1;
778       MESSAGE("End of " << theFile << " file");
779       break;
780     }
781     default: {
782       MESSAGE("Unknown Token: " << token);
783     }
784     }
785   }
786   cout << std::endl;
787
788   shapeID = theHelper->GetSubShapeID();
789   for ( int i = 0; i < nbVertices; ++i )
790     if ( !nodeAssigne[ i+1 ])
791       theMesh->SetNodeInVolume( HexoticNode[ i+1 ], shapeID );
792
793   delete [] HexoticNode;
794   delete [] nodeAssigne;
795   return true;
796 }
797
798 //=============================================================================
799 /*!
800  * Pass parameters to Hexotic
801  */
802 //=============================================================================
803
804 void HexoticPlugin_Hexotic::SetParameters(const HexoticPlugin_Hypothesis* hyp) {
805
806   MESSAGE("HexoticPlugin_Hexotic::SetParameters");
807   if (hyp) {
808     _hexesMinLevel = hyp->GetHexesMinLevel();
809     _hexesMaxLevel = hyp->GetHexesMaxLevel();
810     _hexesMinSize = hyp->GetMinSize();
811     _hexesMaxSize = hyp->GetMaxSize();
812     _hexoticIgnoreRidges = hyp->GetHexoticIgnoreRidges();
813     _hexoticInvalidElements = hyp->GetHexoticInvalidElements();
814     _hexoticSharpAngleThreshold = hyp->GetHexoticSharpAngleThreshold();
815     _hexoticNbProc = hyp->GetHexoticNbProc();
816     _hexoticWorkingDirectory = hyp->GetHexoticWorkingDirectory();
817     _hexoticVerbosity = hyp->GetHexoticVerbosity();
818     _hexoticMaxMemory = hyp->GetHexoticMaxMemory();
819     _hexoticSdMode = hyp->GetHexoticSdMode();
820   }
821   else {
822     cout << std::endl;
823     cout << "WARNING : The Hexotic default parameters are taken into account" << std::endl;
824     cout << "=======" << std::endl;
825     _hexesMinLevel = hyp->GetDefaultHexesMinLevel();
826     _hexesMaxLevel = hyp->GetDefaultHexesMaxLevel();
827     _hexesMinSize = hyp->GetDefaultMinSize();
828     _hexesMaxSize = hyp->GetDefaultMaxSize();
829     _hexoticIgnoreRidges = hyp->GetDefaultHexoticIgnoreRidges();
830     _hexoticInvalidElements = hyp->GetDefaultHexoticInvalidElements();
831     _hexoticSharpAngleThreshold = hyp->GetDefaultHexoticSharpAngleThreshold();
832     _hexoticNbProc = hyp->GetDefaultHexoticNbProc();
833     _hexoticWorkingDirectory = hyp->GetDefaultHexoticWorkingDirectory();
834     _hexoticVerbosity = hyp->GetDefaultHexoticVerbosity();
835     _hexoticMaxMemory = hyp->GetDefaultHexoticMaxMemory();
836     _hexoticSdMode = hyp->GetDefaultHexoticSdMode();
837   }
838 }
839
840 //=======================================================================
841 //function : getTmpDir
842 //purpose  :
843 //=======================================================================
844
845 static TCollection_AsciiString getTmpDir()
846 {
847   TCollection_AsciiString aTmpDir;
848
849   char *Tmp_dir = getenv("SALOME_TMP_DIR");
850   if(Tmp_dir != NULL) {
851     aTmpDir = Tmp_dir;
852     #ifdef WIN32
853     if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\';
854 #else
855     if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/';
856 #endif
857   }
858   else {
859 #ifdef WIN32
860     aTmpDir = TCollection_AsciiString("C:\\");
861 #else
862     aTmpDir = TCollection_AsciiString("/tmp/");
863 #endif
864   }
865   return aTmpDir;
866 }
867
868 //================================================================================
869 /*!
870  * \brief Returns a command to run Hexotic mesher
871  */
872 //================================================================================
873
874 std::string HexoticPlugin_Hexotic::getHexoticCommand(const TCollection_AsciiString& Hexotic_In,
875                                                      const TCollection_AsciiString& Hexotic_Out) const
876 {
877   cout << std::endl;
878   cout << "Hexotic execution..." << std::endl;
879   cout << _name << " parameters :" << std::endl;
880   cout << "    " << _name << " Verbosity = " << _hexoticVerbosity << std::endl;
881   cout << "    " << _name << " Max Memory = " << _hexoticMaxMemory << std::endl;
882   cout << "    " << _name << " Segments Min Level = " << _hexesMinLevel << std::endl;
883   cout << "    " << _name << " Segments Max Level = " << _hexesMaxLevel << std::endl;
884   cout << "    " << _name << " Segments Min Size = " << _hexesMinSize << std::endl;
885   cout << "    " << _name << " Segments Max Size = " << _hexesMaxSize << std::endl;
886   cout << "    " << "Hexotic can ignore ridges : " << (_hexoticIgnoreRidges ? "yes":"no") << std::endl;
887   cout << "    " << "Hexotic authorize invalide elements : " << ( _hexoticInvalidElements ? "yes":"no") << std::endl;
888   cout << "    " << _name << " Sharp angle threshold = " << _hexoticSharpAngleThreshold << " degrees" << std::endl;
889   cout << "    " << _name << " Number of threads = " << _hexoticNbProc << std::endl;
890   cout << "    " << _name << " Working directory = \"" << _hexoticWorkingDirectory << "\"" << std::endl;
891   cout << "    " << _name << " Sub. Dom mode = " << _hexoticSdMode << std::endl;
892
893   TCollection_AsciiString run_Hexotic( "hexotic" );
894
895   TCollection_AsciiString minl = " -minl ", maxl = " -maxl ", angle = " -ra ";
896   TCollection_AsciiString mins = " -mins ", maxs = " -maxs ";
897   TCollection_AsciiString in   = " -in ",   out  = " -out ";
898   TCollection_AsciiString ignoreRidges = " -nr ", invalideElements = " -inv ";
899   TCollection_AsciiString subdom = " -sd ", sharp = " -sharp ";
900   TCollection_AsciiString proc = " -nproc ";
901   TCollection_AsciiString verb = " -v ";
902   TCollection_AsciiString maxmem = " -m ";
903
904   TCollection_AsciiString minLevel, maxLevel, minSize, maxSize, sharpAngle, mode, nbproc, verbosity, maxMemory;
905   minLevel = _hexesMinLevel;
906   maxLevel = _hexesMaxLevel;
907   minSize = _hexesMinSize;
908   maxSize = _hexesMaxSize;
909   sharpAngle = _hexoticSharpAngleThreshold;
910   mode = _hexoticSdMode;
911   nbproc = _hexoticNbProc;
912   verbosity = _hexoticVerbosity;
913   maxMemory = _hexoticMaxMemory;
914
915   if (_hexoticIgnoreRidges)
916     run_Hexotic +=  ignoreRidges;
917
918   if (_hexoticInvalidElements)
919     run_Hexotic +=  invalideElements;
920
921   if (_hexesMinSize > 0)
922     run_Hexotic +=  mins + minSize;
923
924   if (_hexesMaxSize > 0)
925     run_Hexotic +=  maxs + maxSize;
926
927   if (_hexesMinLevel > 0)
928     run_Hexotic +=  minl + minLevel;
929
930   if (_hexesMaxLevel > 0)
931     run_Hexotic +=  maxl + maxLevel;
932
933   if (_hexoticSharpAngleThreshold > 0)
934     run_Hexotic +=  angle + sharpAngle;
935
936   run_Hexotic += in + Hexotic_In + out + Hexotic_Out;
937   run_Hexotic += subdom + mode;
938   run_Hexotic += proc + nbproc;
939   run_Hexotic += verb + verbosity;
940   run_Hexotic += maxmem + maxMemory;
941
942   return run_Hexotic.ToCString();
943 }
944
945 //=============================================================================
946 /*!
947  * Here we are going to use the Hexotic mesher
948  */
949 //=============================================================================
950
951 bool HexoticPlugin_Hexotic::Compute(SMESH_Mesh&          aMesh,
952                                      const TopoDS_Shape& aShape)
953 {
954 #ifdef WITH_SMESH_CANCEL_COMPUTE
955   _compute_canceled = false;
956 #endif
957   bool Ok = true;
958   SMESHDS_Mesh* meshDS = aMesh.GetMeshDS();
959   TCollection_AsciiString hexahedraMessage;
960
961   if (_iShape == 0 && _nbShape == 0) {
962     _nbShape = countShape( meshDS, TopAbs_SOLID );  // we count the number of shapes
963   }
964
965   // to prevent from displaying error message after computing,
966   // SetIsAlwaysComputed( true ) to empty sub-meshes
967   vector< SMESH_subMesh* > subMeshesAlwaysComp;
968   for ( int i = 0; i < _nbShape; ++i )
969     if ( SMESH_subMesh* sm = aMesh.GetSubMeshContaining( aShape ))
970     {
971       SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true,
972                                                                /*complexShapeFirst=*/false);
973       while ( smIt->more() )
974       {
975         sm = smIt->next();
976         if ( !sm->IsMeshComputed() )
977         {
978           sm->SetIsAlwaysComputed( true );
979           subMeshesAlwaysComp.push_back( sm );
980         }
981       }
982     }
983
984   _iShape++;
985
986   if (_iShape == _nbShape ) {
987
988     // create bounding box for each shape of the compound
989
990     int iShape = 0;
991     TopoDS_Shape *tabShape;
992     double **tabBox;
993
994     tabShape = new TopoDS_Shape[_nbShape];
995     tabBox   = new double*[_nbShape];
996     for (int i=0; i<_nbShape; i++)
997       tabBox[i] = new double[6];
998     double Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
999
1000     TopExp_Explorer expBox (meshDS->ShapeToMesh(), TopAbs_SOLID);
1001     for (; expBox.More(); expBox.Next()) {
1002       tabShape[iShape] = expBox.Current();
1003       Bnd_Box BoundingBox;
1004       BRepBndLib::Add(expBox.Current(), BoundingBox);
1005       BoundingBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
1006       tabBox[iShape][0] = Xmin; tabBox[iShape][1] = Xmax;
1007       tabBox[iShape][2] = Ymin; tabBox[iShape][3] = Ymax;
1008       tabBox[iShape][4] = Zmin; tabBox[iShape][5] = Zmax;
1009       iShape++;
1010     }
1011
1012     SetParameters(_hypothesis);
1013
1014 //     TCollection_AsciiString aTmpDir = getTmpDir();
1015     TCollection_AsciiString aTmpDir = TCollection_AsciiString(_hexoticWorkingDirectory.c_str());
1016 #ifdef WIN32
1017     if ( aTmpDir.Value(aTmpDir.Length()) != '\\' ) aTmpDir += '\\';
1018 #else
1019     if ( aTmpDir.Value(aTmpDir.Length()) != '/' ) aTmpDir += '/';
1020 #endif
1021     TCollection_AsciiString Hexotic_In(""), Hexotic_Out;
1022     TCollection_AsciiString modeFile_In( "chmod 666 " ), modeFile_Out( "chmod 666 " );
1023     TCollection_AsciiString aLogFileName = aTmpDir + "Hexotic.log";    // log
1024
1025     std::map <int,int> aSmdsToHexoticIdMap;
1026     std::map <int,const SMDS_MeshNode*> aHexoticIdToNodeMap;
1027
1028     Hexotic_Out = aTmpDir + "Hexotic_Out.mesh";
1029 #ifdef WITH_BLSURFPLUGIN
1030     bool defaultInputFile = true;
1031     if (_blsurfHypo && !_blsurfHypo->GetQuadAllowed()) {
1032       Hexotic_In = TCollection_AsciiString(_blsurfHypo->GetGMFFile().c_str());
1033       if (Hexotic_In != "")
1034         defaultInputFile = false;
1035     }
1036     if (defaultInputFile) {
1037 #endif
1038       Hexotic_In  = aTmpDir + "Hexotic_In.mesh";
1039       removeHexoticFiles(Hexotic_In, Hexotic_Out);
1040       cout << std::endl;
1041       cout << "Creating Hexotic input mesh file : " << Hexotic_In << std::endl;
1042       aMesh.ExportGMF(Hexotic_In.ToCString(), meshDS, true);
1043 #ifdef WITH_BLSURFPLUGIN
1044     }
1045     else {
1046       removeFile( Hexotic_Out );
1047     }
1048 #endif
1049     
1050
1051     std::string run_Hexotic = getHexoticCommand(Hexotic_In, Hexotic_Out);
1052     run_Hexotic += std::string(" 1 > ") + aLogFileName.ToCString();  // dump into file
1053
1054     cout << std::endl;
1055     cout << "Hexotic command : " << run_Hexotic << std::endl;
1056
1057     modeFile_In += Hexotic_In;
1058     system( modeFile_In.ToCString() );
1059     aSmdsToHexoticIdMap.clear();
1060     aHexoticIdToNodeMap.clear();
1061
1062     MESSAGE("HexoticPlugin_Hexotic::Compute");
1063
1064     int status = system( run_Hexotic.data() );
1065
1066     // --------------
1067     // read a result
1068     // --------------
1069
1070     std::ifstream fileRes( Hexotic_Out.ToCString() );
1071     modeFile_Out += Hexotic_Out;
1072     system( modeFile_Out.ToCString() );
1073     if ( ! fileRes.fail() ) {
1074       Ok = readResult( Hexotic_Out.ToCString(),
1075 #ifdef WITH_SMESH_CANCEL_COMPUTE
1076                        this,
1077 #endif
1078                        meshDS, _nbShape, tabShape, tabBox );
1079       if(Ok)
1080 /*********************
1081 // TODO: Detect and remove elements in holes in case of sd mode = 4
1082       // Remove previous nodes and elements
1083       SMDS_ElemIteratorPtr itElement = meshDS->elementsIterator();
1084       SMDS_NodeIteratorPtr itNode = meshDS->nodesIterator();
1085     
1086       while ( itElement->more() )
1087         meshDS->RemoveElement( itElement->next() );
1088       while ( itNode->more() )
1089         meshDS->RemoveNode( itNode->next() );
1090   
1091       SMESH_ComputeErrorPtr myError = aMesh.GMFToMesh(Hexotic_Out.ToCString());
1092       if (myError)
1093 */
1094         hexahedraMessage = "success";
1095       else
1096         hexahedraMessage = "failed";
1097     }
1098     else {
1099       hexahedraMessage = "failed";
1100       cout << "Problem with Hexotic output file " << Hexotic_Out.ToCString() << std::endl;
1101       Ok = false;
1102       // analyse log file
1103       SMESH_File logFile( aLogFileName.ToCString() );
1104       if ( !logFile.eof() )
1105       {
1106         char msgLic[] = " Dlim ";
1107         const char* fileBeg = logFile.getPos(), *fileEnd = fileBeg + logFile.size();
1108         if ( std::search( fileBeg, fileEnd, msgLic, msgLic+strlen(msgLic)) != fileEnd )
1109           error("Licence problems.");
1110       }
1111       if ( status > 0 && WEXITSTATUS(status) == 127 )
1112         error("hexotic: command not found");
1113     }
1114     cout << "Hexahedra meshing " << hexahedraMessage << std::endl;
1115     cout << std::endl;
1116
1117     // restore "always computed" flag of sub-meshes (0022127)
1118     for  ( size_t iSM = 0; iSM < subMeshesAlwaysComp.size(); ++iSM )
1119       subMeshesAlwaysComp[ iSM ]->SetIsAlwaysComputed( false );
1120
1121     delete [] tabShape;
1122     for (int i=0; i<_nbShape; i++)
1123       delete [] tabBox[i];
1124     delete [] tabBox;
1125     _nbShape = 0;
1126     _iShape  = 0;
1127   }
1128 #ifdef WITH_SMESH_CANCEL_COMPUTE
1129   if(_compute_canceled)
1130     return error(SMESH_Comment("interruption initiated by user"));
1131 #endif
1132   return Ok;
1133 }
1134
1135 //=============================================================================
1136 /*!
1137  * \brief Computes mesh without geometry
1138  *  \param aMesh - the mesh
1139  *  \param aHelper - helper that must be used for adding elements to \aaMesh
1140  *  \retval bool - is a success
1141  *
1142  * The method is called if ( !aMesh->HasShapeToMesh() )
1143  */
1144 //=============================================================================
1145
1146 bool HexoticPlugin_Hexotic::Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper)
1147 {
1148 #ifdef WITH_SMESH_CANCEL_COMPUTE
1149   _compute_canceled = false;
1150 #endif
1151 /*
1152   SMESH_ComputeErrorPtr myError = SMESH_ComputeError::New();
1153 */
1154   bool Ok = true;
1155   TCollection_AsciiString hexahedraMessage;
1156
1157   SetParameters(_hypothesis);
1158
1159   TCollection_AsciiString aTmpDir = getTmpDir();
1160   TCollection_AsciiString Hexotic_In, Hexotic_Out;
1161   TCollection_AsciiString modeFile_In( "chmod 666 " ), modeFile_Out( "chmod 666 " );
1162   TCollection_AsciiString aLogFileName = aTmpDir + "Hexotic.log";    // log
1163
1164   std::map <int,int> aSmdsToHexoticIdMap;
1165   std::map <int,const SMDS_MeshNode*> aHexoticIdToNodeMap;
1166
1167   Hexotic_In  = aTmpDir + "Hexotic_In.mesh";
1168   Hexotic_Out = aTmpDir + "Hexotic_Out.mesh";
1169
1170   std::string run_Hexotic = getHexoticCommand(Hexotic_In, Hexotic_Out);
1171   run_Hexotic += std::string(" 1 > ") + aLogFileName.ToCString();  // dump into file
1172
1173   removeHexoticFiles(Hexotic_In, Hexotic_Out);
1174
1175   cout << std::endl;
1176   cout << "Creating Hexotic input mesh file : " << Hexotic_In << std::endl;
1177   aMesh.ExportGMF(Hexotic_In.ToCString(), aHelper->GetMeshDS());
1178   modeFile_In += Hexotic_In;
1179   system( modeFile_In.ToCString() );
1180   aSmdsToHexoticIdMap.clear();
1181   aHexoticIdToNodeMap.clear();
1182
1183   MESSAGE("HexoticPlugin_Hexotic::Compute");
1184
1185   cout << std::endl;
1186   cout << "Hexotic command : " << run_Hexotic << std::endl;
1187   system( run_Hexotic.data() );
1188
1189   // --------------
1190   // read a result
1191   // --------------
1192
1193   std::ifstream fileRes( Hexotic_Out.ToCString() );
1194   modeFile_Out += Hexotic_Out;
1195   system( modeFile_Out.ToCString() );
1196   if ( ! fileRes.fail() ) {
1197     Ok = readResult( Hexotic_Out.ToCString(),
1198 #ifdef WITH_SMESH_CANCEL_COMPUTE
1199                      this,
1200 #endif
1201                      aHelper );
1202     if(Ok)
1203 /*
1204     // Remove previous nodes and elements
1205     SMDS_ElemIteratorPtr itElement = aHelper->GetMeshDS()->elementsIterator();
1206     SMDS_NodeIteratorPtr itNode = aHelper->GetMeshDS()->nodesIterator();
1207     
1208     while ( itElement->more() )
1209       aHelper->GetMeshDS()->RemoveElement( itElement->next() );
1210     while ( itNode->more() )
1211       aHelper->GetMeshDS()->RemoveNode( itNode->next() );
1212
1213     // Import GMF mesh
1214     myError = aMesh.GMFToMesh(Hexotic_Out.ToCString());
1215     
1216     itElement = aHelper->GetMeshDS()->elementsIterator();
1217     itNode = aHelper->GetMeshDS()->nodesIterator();
1218
1219     // Assign nodes and elements to the pseudo shape
1220     while ( itNode->more() )
1221       aHelper->GetMeshDS()->SetNodeInVolume(itNode->next(), 1);
1222     while ( itElement->more() )
1223       aHelper->GetMeshDS()->SetMeshElementOnShape(itElement->next(), 1);
1224
1225     if(myError->IsOK())
1226 */
1227       hexahedraMessage = "success";
1228     else
1229       hexahedraMessage = "failed";
1230   }
1231   else {
1232 /*
1233     myError->myName = COMPERR_EXCEPTION;
1234 */
1235     hexahedraMessage = "failed";
1236     cout << "Problem with Hexotic output file " << Hexotic_Out << std::endl;
1237     // analyse log file
1238     SMESH_File logFile( aLogFileName.ToCString() );
1239     if ( !logFile.eof() )
1240     {
1241       char msgLic[] = " Dlim ";
1242       const char* fileBeg = logFile.getPos(), *fileEnd = fileBeg + logFile.size();
1243       if ( std::search( fileBeg, fileEnd, msgLic, msgLic+strlen(msgLic)) != fileEnd )
1244         return error("Licence problems.");
1245     }
1246     return error(SMESH_Comment("Problem with Hexotic output file ")<<Hexotic_Out);
1247   }
1248   cout << "Hexahedra meshing " << hexahedraMessage << std::endl;
1249   cout << std::endl;
1250
1251 #ifdef WITH_SMESH_CANCEL_COMPUTE
1252   if(_compute_canceled)
1253     return error(SMESH_Comment("interruption initiated by user"));
1254 #endif
1255   return Ok;
1256 /*
1257   return myError->IsOK();
1258 */
1259 }
1260
1261 //=============================================================================
1262 /*!
1263  *
1264  */
1265 //=============================================================================
1266
1267 bool HexoticPlugin_Hexotic::Evaluate(SMESH_Mesh& aMesh,
1268                                      const TopoDS_Shape& aShape,
1269                                      MapShapeNbElems& aResMap)
1270 {
1271   std::vector<int> aResVec(SMDSEntity_Last);
1272   for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
1273   SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
1274   aResMap.insert(std::make_pair(sm,aResVec));
1275
1276   SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
1277   smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Evaluation is not implemented",this));
1278
1279   return true;
1280 }
1281
1282 #ifdef WITH_SMESH_CANCEL_COMPUTE
1283 void HexoticPlugin_Hexotic::CancelCompute()
1284 {
1285   _compute_canceled = true;
1286 #ifdef WNT
1287 #else
1288   TCollection_AsciiString aTmpDir = getTmpDir();
1289   TCollection_AsciiString Hexotic_In = aTmpDir + "Hexotic_In.mesh";
1290   TCollection_AsciiString cmd = TCollection_AsciiString("ps ux | grep ") + Hexotic_In;
1291   cmd += TCollection_AsciiString(" | grep -v grep | awk '{print $2}' | xargs kill -9 > /dev/null 2>&1");
1292   system( cmd.ToCString() );
1293 #endif
1294 }
1295 #endif