Salome HOME
Copyright update 2021
[plugins/hexoticplugin.git] / src / HexoticPlugin / HexoticPlugin_Hexotic.cxx
index d08466c54fcd71d08b9e40d046a0320aee6b56fe..806747783571238042c6950dc6544df95da16933 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2021  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 
 #include "utilities.h"
 
+#ifdef WIN32
+#include <process.h>
+#endif
+
 #ifdef _DEBUG_
 #define DUMP(txt) \
-//  cout << txt
+//  std::cout << txt
 #else
 #define DUMP(txt)
 #endif
 #include <SMESH_HypoFilter.hxx>
 #include <SMESH_MesherHelper.hxx>
 #include <SMESH_subMesh.hxx>
+#include <SMESH_MeshEditor.hxx>
+#include <SMESH_ControlPnt.hxx>
 
 #include <list>
 #include <cstdlib>
-#include <iostream>
 
 #include <Standard_ProgramError.hxx>
 
 #include <BRepBndLib.hxx>
 #include <BRepClass3d_SolidClassifier.hxx>
-#include <BRepMesh_IncrementalMesh.hxx>
 #include <BRep_Tool.hxx>
-#include <GCPnts_UniformAbscissa.hxx>
-#include <GeomAdaptor_Curve.hxx>
-#include <IntCurvesFace_Intersector.hxx>
+#include <Bnd_Box.hxx>
 #include <OSD_File.hxx>
-#include <Poly_Triangulation.hxx>
 #include <Precision.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <TopoDS.hxx>
-#include <gp_Ax3.hxx>
-#include <gp_Lin.hxx>
+#include <TopoDS_Vertex.hxx>
 #include <gp_Pnt.hxx>
 
 #include <Basics_Utils.hxx>
 #define GMFVERSION GmfDouble
 #define GMFDIMENSION 3
 
+using SMESHUtils::ControlPnt;
+
 static void removeFile( const TCollection_AsciiString& fileName )
 {
   try {
     OSD_File( fileName ).Remove();
   }
-  catch ( Standard_ProgramError ) {
+  catch ( Standard_ProgramError& ) {
     MESSAGE("Can't remove file: " << fileName.ToCString() << " ; file does not exist or permission denied");
   }
 }
@@ -90,10 +92,9 @@ static void removeFile( const TCollection_AsciiString& fileName )
  */
 //=============================================================================
 
-HexoticPlugin_Hexotic::HexoticPlugin_Hexotic(int hypId, int studyId, SMESH_Gen* gen)
-  : SMESH_3D_Algo(hypId, studyId, gen)
+HexoticPlugin_Hexotic::HexoticPlugin_Hexotic(int hypId, SMESH_Gen* gen)
+  : SMESH_3D_Algo(hypId, gen)
 {
-  MESSAGE("HexoticPlugin_Hexotic::HexoticPlugin_Hexotic");
   _name = "MG-Hexa";
   _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type
   _onlyUnaryInput = false;
@@ -107,15 +108,6 @@ HexoticPlugin_Hexotic::HexoticPlugin_Hexotic(int hypId, int studyId, SMESH_Gen*
 #endif
   _computeCanceled = false;
   
-  // Copy of what is done in BLSURFPLugin TODO : share the code
-  smeshGen_i = SMESH_Gen_i::GetSMESHGen();
-  CORBA::Object_var anObject = smeshGen_i->GetNS()->Resolve("/myStudyManager");
-  SALOMEDS::StudyManager_var aStudyMgr = SALOMEDS::StudyManager::_narrow(anObject);
-  
-  myStudy = NULL;
-  myStudy = aStudyMgr->GetStudyByID(_studyId);
-  if ( !myStudy->_is_nil() )
-    MESSAGE("myStudy->StudyId() = " << myStudy->StudyId());
 }
 
 //=============================================================================
@@ -126,7 +118,6 @@ HexoticPlugin_Hexotic::HexoticPlugin_Hexotic(int hypId, int studyId, SMESH_Gen*
 
 HexoticPlugin_Hexotic::~HexoticPlugin_Hexotic()
 {
-  MESSAGE("HexoticPlugin_Hexotic::~HexoticPlugin_Hexotic");
 }
 
 
@@ -134,7 +125,6 @@ HexoticPlugin_Hexotic::~HexoticPlugin_Hexotic()
 bool HexoticPlugin_Hexotic::CheckBLSURFHypothesis( SMESH_Mesh&         aMesh,
                                                    const TopoDS_Shape& aShape )
 {
-  // MESSAGE("HexoticPlugin_Hexotic::CheckBLSURFHypothesis");
   _blsurfHypo = NULL;
 
   std::list<const SMESHDS_Hypothesis*>::const_iterator itl;
@@ -142,7 +132,8 @@ bool HexoticPlugin_Hexotic::CheckBLSURFHypothesis( SMESH_Mesh&         aMesh,
 
   // If a BLSURF hypothesis is applied, get it
   SMESH_HypoFilter blsurfFilter;
-  blsurfFilter.Init( blsurfFilter.HasName( BLSURFPlugin_Hypothesis::GetHypType() ));
+  blsurfFilter.Init( blsurfFilter.HasName( BLSURFPlugin_Hypothesis::GetHypType(true) ));
+  blsurfFilter.Or  ( blsurfFilter.HasName( BLSURFPlugin_Hypothesis::GetHypType(false)));
   std::list<const SMESHDS_Hypothesis *> appliedHyps;
   aMesh.GetHypotheses( aShape, blsurfFilter, appliedHyps, false );
 
@@ -150,7 +141,9 @@ bool HexoticPlugin_Hexotic::CheckBLSURFHypothesis( SMESH_Mesh&         aMesh,
     itl = appliedHyps.begin();
     theHyp = (*itl); // use only the first hypothesis
     std::string hypName = theHyp->GetName();
-    if (hypName == BLSURFPlugin_Hypothesis::GetHypType()) {
+    if (hypName == BLSURFPlugin_Hypothesis::GetHypType(true) ||
+        hypName == BLSURFPlugin_Hypothesis::GetHypType(false) )
+    {
       _blsurfHypo = static_cast<const BLSURFPlugin_Hypothesis*> (theHyp);
       ASSERT(_blsurfHypo);
       return true;
@@ -170,7 +163,6 @@ bool HexoticPlugin_Hexotic::CheckHypothesis( SMESH_Mesh&
                                              const TopoDS_Shape&                  aShape,
                                              SMESH_Hypothesis::Hypothesis_Status& aStatus )
 {
-  // MESSAGE("HexoticPlugin_Hexotic::CheckHypothesis");
   _hypothesis = NULL;
 
   std::list<const SMESHDS_Hypothesis*>::const_iterator itl;
@@ -179,6 +171,10 @@ bool HexoticPlugin_Hexotic::CheckHypothesis( SMESH_Mesh&
   const std::list<const SMESHDS_Hypothesis*>& hyps = GetUsedHypothesis(aMesh, aShape, false);
   int nbHyp = hyps.size();
   if (!nbHyp) {
+    // retrieve BLSURF hypothesis if no hexotic hypothesis has been set
+#ifdef WITH_BLSURFPLUGIN
+    CheckBLSURFHypothesis(aMesh, aShape);
+#endif
     aStatus = SMESH_Hypothesis::HYP_OK;
     return true;  // can work with no hypothesis
   }
@@ -254,23 +250,12 @@ static int getNbShape(MG_Hexotic_API* hexaOutput, int iMesh, GmfKwdCod what, int
   int number = hexaOutput->GmfStatKwd( iMesh, what );
   if ( number > 0 )
   {
-  // std::string aLine;
-  // std::ifstream file(aFile.c_str());
-  // while ( !file.eof() ) {
-  //   getline( file, aLine);
-  //   if ( aLine == aString ) {
-  //     getline( file, aLine);
-  //     std::istringstream stringFlux( aLine );
-  //     stringFlux >> number;
-      number = ( number + defaultValue + std::abs(number - defaultValue) ) / 2;
-    //   break;
-    // }
+    number = ( number + defaultValue + std::abs(number - defaultValue) ) / 2;
   }
   else
   {
     number = defaultValue;
   }
-  //file.close();
   return number;
 }
 
@@ -319,10 +304,10 @@ void getShape(Mesh* mesh, Shape shape, Tab *t_Shape)
 //=======================================================================
 
 static void printWarning(const int nbExpected, std::string aString, const int nbFound) {
-  cout << std::endl;
-  cout << "WARNING : " << nbExpected << " " << aString << " expected, MG-Hexa has found " << nbFound << std::endl;
-  cout << "=======" << std::endl;
-  cout << std::endl;
+  std::cout << std::endl;
+  std::cout << "WARNING : " << nbExpected << " " << aString << " expected, MG-Hexa has found " << nbFound << std::endl;
+  std::cout << "=======" << std::endl;
+  std::cout << std::endl;
   return;
 }
 
@@ -331,7 +316,8 @@ static void printWarning(const int nbExpected, std::string aString, const int nb
 //purpose  :
 //=======================================================================
 
-static void removeHexoticFiles(TCollection_AsciiString file_In, TCollection_AsciiString file_Out) {
+static void removeHexoticFiles(TCollection_AsciiString file_In, TCollection_AsciiString file_Out)
+{
   removeFile( file_In );
   removeFile( file_Out );
 }
@@ -437,24 +423,25 @@ static bool readResult(MG_Hexotic_API*       theHexaOutput,
   std::string token;
   int shapeID, hexoticShapeID;
   const int IdShapeRef = 2;
-  int *tabID;
+  std::vector< int > tabID;
   double epsilon = Precision::Confusion();
   std::map <std::string,int> mapField;
-  SMDS_MeshNode** HexoticNode;
-  TopoDS_Shape *tabCorner;
+  std::vector< SMDS_MeshNode*> HexoticNode;
+  std::vector< TopoDS_Shape > tabCorner;
 
   const int nbDomains = countShape( theMesh, TopAbs_SHELL );
   const int holeID = -1;
 
   if ( nbDomains > 0 )
   {
-    tabID    = new int[nbDomains];
-
-    for (int i=0; i<nbDomains; i++)
-      tabID[i] = 0;
+    tabID.resize( nbDomains, 0 );
     if ( nbDomains == 1 )
       tabID[0] = theMeshDS->ShapeToIndex( tabShape[0] );
   }
+  else
+  {
+    tabID.resize( 1, 1 );
+  }
 
   SMDS_ElemIteratorPtr eIt = theMeshDS->elementsIterator();
   while( eIt->more() )
@@ -463,18 +450,23 @@ static bool readResult(MG_Hexotic_API*       theHexaOutput,
   while ( nIt->more() )
     theMeshDS->RemoveFreeNode( nIt->next(), /*sm=*/0 );
 
+  theHelper->SetElementsOnShape( false );
+
   int ver, dim;
   int meshID = theHexaOutput->GmfOpenMesh( theFile, GmfRead, &ver, &dim );
 
+  int nbVerticesInShape = countShape( theMesh, TopAbs_VERTEX );
   int nbVertices  = getNbShape(theHexaOutput, meshID, GmfVertices );
-  int nbCorners   = getNbShape(theHexaOutput, meshID, GmfCorners, countShape( theMesh, TopAbs_VERTEX ));
+  int nbCorners   = getNbShape(theHexaOutput, meshID, GmfCorners, nbVerticesInShape);
   if ( nbVertices == 0 )
     return false;
 
-  tabCorner   = new TopoDS_Shape[ nbCorners ];
-  HexoticNode = new SMDS_MeshNode*[ nbVertices + 1 ];
+  tabCorner.resize( nbCorners );
+  HexoticNode.resize( nbVertices + 1 );
 
-  getShape(theMeshDS, TopAbs_VERTEX, tabCorner);
+  // get the shape vertices if the mesh lies on a shape (and this shape has corners)
+  if ( nbCorners > 0 && nbVerticesInShape > 0 )
+    getShape( theMeshDS, TopAbs_VERTEX, tabCorner.data() );
 
   int nbNodes = theHexaOutput->GmfStatKwd( meshID, GmfVertices );
   if ( nbNodes > 0 )
@@ -530,11 +522,11 @@ static bool readResult(MG_Hexotic_API*       theHexaOutput,
       for ( int i = 0; i < 2; ++i )
       {
         node[i] = HexoticNode[ nodeID[i]];
-        if ( node[i]->getshapeId() < 1 )
+        if ( shapeID > 0 && node[i]->getshapeId() < 1 )
           theMeshDS->SetNodeOnEdge( node[i], shapeID );
       }
       aHexoticElement = theHelper->AddEdge( node[0], node[1] );
-      if ( aHexoticElement->getshapeId() < 1 )
+      if ( shapeID > 0 && aHexoticElement->getshapeId() < 1 )
         theMeshDS->SetMeshElementOnShape( aHexoticElement, shapeID );
     }
   }
@@ -605,7 +597,7 @@ static bool readResult(MG_Hexotic_API*       theHexaOutput,
       {
         for ( int i = 0; i < 8; ++i )
         {
-          if ( node[i]->getshapeId() < 1 )
+          if ( node[i]->NbInverseElements( SMDSAbs_Face ) == 0 )
             theMeshDS->SetNodeInVolume( node[i], shapeID );
         }
         aHexoticElement = theHelper->AddVolume( node[0], node[3], node[2], node[1],
@@ -615,7 +607,7 @@ static bool readResult(MG_Hexotic_API*       theHexaOutput,
       }
     }
   }
-  cout << std::endl;
+  std::cout << std::endl;
 
   // remove nodes in holes
   if ( nbDomains > 1 )
@@ -627,9 +619,20 @@ static bool readResult(MG_Hexotic_API*       theHexaOutput,
         theMeshDS->RemoveFreeNode( HexoticNode[i], subMesh, /*fromGroups=*/false );
       }
   }
-  delete [] tabID;
-  delete [] tabCorner;
-  delete [] HexoticNode;
+
+  // avoid "Error: No mesh on sub-shape"
+  if ( theMesh->NbVolumes() > 0 )
+  {
+    SMESH_subMesh*         smMain = theMesh->GetSubMesh( theMesh->GetShapeToMesh() );
+    SMESH_subMeshIteratorPtr smIt = smMain->getDependsOnIterator( /*includeSelf=*/true );
+    while ( smIt->more() )
+    {
+      SMESH_subMesh* sm = smIt->next();
+      if ( !sm->IsMeshComputed() )
+        sm->SetIsAlwaysComputed( true );
+    }
+  }
+
   return true;
 }
 
@@ -639,14 +642,14 @@ static bool readResult(MG_Hexotic_API*       theHexaOutput,
  */
 //=============================================================================
 
-void HexoticPlugin_Hexotic::SetParameters(const HexoticPlugin_Hypothesis* hyp) {
-
-  MESSAGE("HexoticPlugin_Hexotic::SetParameters");
+void HexoticPlugin_Hexotic::SetParameters(const HexoticPlugin_Hypothesis* hyp)
+{
   if (hyp) {
     _hexesMinLevel = hyp->GetHexesMinLevel();
     _hexesMaxLevel = hyp->GetHexesMaxLevel();
     _hexesMinSize = hyp->GetMinSize();
     _hexesMaxSize = hyp->GetMaxSize();
+    _approxAngle = hyp->GetGeomApproxAngle();
     _hexoticIgnoreRidges = hyp->GetHexoticIgnoreRidges();
     _hexoticInvalidElements = hyp->GetHexoticInvalidElements();
     _hexoticSharpAngleThreshold = hyp->GetHexoticSharpAngleThreshold();
@@ -663,15 +666,19 @@ void HexoticPlugin_Hexotic::SetParameters(const HexoticPlugin_Hypothesis* hyp) {
     _growth = hyp->GetGrowth();
     _facesWithLayers = hyp->GetFacesWithLayers();
     _imprintedFaces = hyp->GetImprintedFaces();
+    _keepFiles = hyp->GetKeepFiles();
+    _removeLogOnSuccess = hyp->GetRemoveLogOnSuccess();
+    _logInStandardOutput = hyp->GetStandardOutputLog();
   }
   else {
-    cout << std::endl;
-    cout << "WARNING : The MG-Hexa default parameters are taken into account" << std::endl;
-    cout << "=======" << std::endl;
+    std::cout << std::endl;
+    std::cout << "WARNING : The MG-Hexa default parameters are taken into account" << std::endl;
+    std::cout << "=======" << std::endl;
     _hexesMinLevel = hyp->GetDefaultHexesMinLevel();
     _hexesMaxLevel = hyp->GetDefaultHexesMaxLevel();
     _hexesMinSize = hyp->GetDefaultMinSize();
     _hexesMaxSize = hyp->GetDefaultMaxSize();
+    _approxAngle = hyp->GetDefaultGeomApproxAngle();
     _hexoticIgnoreRidges = hyp->GetDefaultHexoticIgnoreRidges();
     _hexoticInvalidElements = hyp->GetDefaultHexoticInvalidElements();
     _hexoticSharpAngleThreshold = hyp->GetDefaultHexoticSharpAngleThreshold();
@@ -688,6 +695,9 @@ void HexoticPlugin_Hexotic::SetParameters(const HexoticPlugin_Hypothesis* hyp) {
     _growth = hyp->GetDefaultGrowth();
     _facesWithLayers = hyp->GetDefaultFacesWithLayers();
     _imprintedFaces = hyp->GetDefaultImprintedFaces();
+    _keepFiles = hyp->GetDefaultKeepFiles();
+    _removeLogOnSuccess = hyp->GetDefaultRemoveLogOnSuccess();
+    _logInStandardOutput = hyp->GetDefaultStandardOutputLog();
   }
 }
 
@@ -725,79 +735,80 @@ static TCollection_AsciiString getSuffix()
  */
 //================================================================================
 
-std::string HexoticPlugin_Hexotic::getHexoticCommand(const TCollection_AsciiString& Hexotic_In,
-                                                     const TCollection_AsciiString& Hexotic_Out,
-                                                     const TCollection_AsciiString& Hexotic_SizeMap_Prefix,
-                                                     const bool                     forExecutable) const
+std::string
+HexoticPlugin_Hexotic::getHexoticCommand(const TCollection_AsciiString& Hexotic_In,
+                                         const TCollection_AsciiString& Hexotic_Out,
+                                         const TCollection_AsciiString& Hexotic_SizeMap_Prefix,
+                                         const bool                     forExecutable) const
 {
-  cout << std::endl;
-  cout << "MG-Hexa execution..." << std::endl;
-  cout << _name << " parameters :" << std::endl;
-  cout << "    " << _name << " Verbosity = " << _hexoticVerbosity << std::endl;
-  cout << "    " << _name << " Max Memory = " << _hexoticMaxMemory << std::endl;
-  cout << "    " << _name << " Segments Min Level = " << _hexesMinLevel << std::endl;
-  cout << "    " << _name << " Segments Max Level = " << _hexesMaxLevel << std::endl;
-  cout << "    " << _name << " Segments Min Size = " << _hexesMinSize << std::endl;
-  cout << "    " << _name << " Segments Max Size = " << _hexesMaxSize << std::endl;
-  cout << "    " << "MG-Hexa can ignore ridges : " << (_hexoticIgnoreRidges ? "yes":"no") << std::endl;
-  cout << "    " << "MG-Hexa authorize invalide elements : " << ( _hexoticInvalidElements ? "yes":"no") << std::endl;
-  cout << "    " << _name << " Sharp angle threshold = " << _hexoticSharpAngleThreshold << " degrees" << std::endl;
-  cout << "    " << _name << " Number of threads = " << _hexoticNbProc << std::endl;
-  cout << "    " << _name << " Working directory = \"" << _hexoticWorkingDirectory << "\"" << std::endl;
-  cout << "    " << _name << " Sub. Dom mode = " << _hexoticSdMode << std::endl;
-  cout << "    " << _name << " Text options = \"" << _textOptions << "\"" << std::endl;
-  cout << "    " << _name << " Number of layers = " << _nbLayers << std::endl;
-  cout << "    " << _name << " Size of the first layer  = " << _firstLayerSize << std::endl;
-  cout << "    " << _name << " Direction of the layers = " << ( _direction ? "Inward" : "Outward" ) << std::endl;
-  cout << "    " << _name << " Growth = " << _growth << std::endl;
+  std::cout << std::endl;
+  std::cout << "MG-Hexa execution..." << std::endl;
+  std::cout << _name << " parameters :" << std::endl;
+  std::cout << "    " << _name << " Verbosity = " << _hexoticVerbosity << std::endl;
+  std::cout << "    " << _name << " Max Memory = " << _hexoticMaxMemory << std::endl;
+  std::cout << "    " << _name << " Segments Min Level = " << _hexesMinLevel << std::endl;
+  std::cout << "    " << _name << " Segments Max Level = " << _hexesMaxLevel << std::endl;
+  std::cout << "    " << _name << " Segments Min Size = " << _hexesMinSize << std::endl;
+  std::cout << "    " << _name << " Segments Max Size = " << _hexesMaxSize << std::endl;
+  std::cout << "    " << "MG-Hexa can ignore ridges : " << (_hexoticIgnoreRidges ? "yes":"no") << std::endl;
+  std::cout << "    " << "MG-Hexa authorize invalide elements : " << ( _hexoticInvalidElements ? "yes":"no") << std::endl;
+  std::cout << "    " << _name << " Sharp angle threshold = " << _hexoticSharpAngleThreshold << " degrees" << std::endl;
+  std::cout << "    " << _name << " Number of threads = " << _hexoticNbProc << std::endl;
+  std::cout << "    " << _name << " Working directory = \"" << _hexoticWorkingDirectory << "\"" << std::endl;
+  std::cout << "    " << _name << " Sub. Dom mode = " << _hexoticSdMode << std::endl;
+  std::cout << "    " << _name << " Text options = \"" << _textOptions << "\"" << std::endl;
+  std::cout << "    " << _name << " Number of layers = " << _nbLayers << std::endl;
+  std::cout << "    " << _name << " Size of the first layer  = " << _firstLayerSize << std::endl;
+  std::cout << "    " << _name << " Direction of the layers = " << ( _direction ? "Inward" : "Outward" ) << std::endl;
+  std::cout << "    " << _name << " Growth = " << _growth << std::endl;
   if (!_facesWithLayers.empty()) {
-    cout << "    " << _name << " Faces with layers = ";
+    std::cout << "    " << _name << " Faces with layers = ";
     for (size_t i = 0; i < _facesWithLayers.size(); i++)
     {
-      cout << _facesWithLayers.at(i);
+      std::cout << _facesWithLayers.at(i);
       if ((i + 1) != _facesWithLayers.size())
-        cout << ", ";
+        std::cout << ", ";
     }
-    cout << std::endl;
+    std::cout << std::endl;
   }
   if (!_imprintedFaces.empty()) {
-    cout << "    " << _name << " Imprinted faces = ";
+    std::cout << "    " << _name << " Imprinted faces = ";
     for (size_t i = 0; i < _imprintedFaces.size(); i++)
     {
-      cout << _imprintedFaces.at(i);
+      std::cout << _imprintedFaces.at(i);
       if ((i + 1) != _imprintedFaces.size())
-        cout << ", ";
+        std::cout << ", ";
     }
-    cout << std::endl;
+    std::cout << std::endl;
   }
 
   TCollection_AsciiString run_Hexotic("mg-hexa.exe");
 
-  TCollection_AsciiString minl = " --min_level ", maxl = " --max_level ", angle = " --ridge_angle ";
-  TCollection_AsciiString mins = " --min_size ", maxs = " --max_size ";
-  TCollection_AsciiString in   = " --in ",   out  = " --out ";
-  TCollection_AsciiString sizeMap = " --read_sizemap ";
+  TCollection_AsciiString minl         = " --min_level ", maxl = " --max_level ", angle = " --ridge_angle ";
+  TCollection_AsciiString mins         = " --min_size ", maxs = " --max_size ";
+  TCollection_AsciiString in           = " --in ",   out  = " --out ";
+  TCollection_AsciiString sizeMap      = " --read_sizemap ";
   TCollection_AsciiString ignoreRidges = " --compute_ridges no ", invalideElements = " --allow_invalid_elements yes ";
-  TCollection_AsciiString subdom = " --components ";
+  TCollection_AsciiString subdom       = " --components ";
 #ifndef WIN32
-  TCollection_AsciiString proc = " --max_number_of_threads ";
+  TCollection_AsciiString proc         = " --max_number_of_threads ";
 #endif
-  TCollection_AsciiString verb = " --verbose ";
-  TCollection_AsciiString maxmem = " --max_memory ";
+  TCollection_AsciiString verb         = " --verbose ";
+  TCollection_AsciiString maxmem       = " --max_memory ";
 
-  TCollection_AsciiString comNbLayers = " --number_of_boundary_layers ";
-  TCollection_AsciiString comFirstLayerSize = " --height_of_the_first_layer ";
-  TCollection_AsciiString comDirection = " --boundary_layers_subdomain_direction ";
-  TCollection_AsciiString comGrowth = " --boundary_layers_geometric_progression ";
+  TCollection_AsciiString comNbLayers        = " --number_of_boundary_layers ";
+  TCollection_AsciiString comFirstLayerSize  = " --height_of_the_first_layer ";
+  TCollection_AsciiString comDirection       = " --boundary_layers_subdomain_direction ";
+  TCollection_AsciiString comGrowth          = " --boundary_layers_geometric_progression ";
   TCollection_AsciiString comFacesWithLayers = " --boundary_layers_surface_ids ";
-  TCollection_AsciiString comImptintedFaces = " --imprinted_surface_ids ";
+  TCollection_AsciiString comImptintedFaces  = " --imprinted_surface_ids ";
 
   TCollection_AsciiString minLevel, maxLevel, minSize, maxSize, sharpAngle, mode, nbproc, verbosity, maxMemory,
                           textOptions, nbLayers, firstLayerSize, direction, growth, facesWithLayers, imprintedFaces;
-  minLevel = _hexesMinLevel;
-  maxLevel = _hexesMaxLevel;
-  minSize = _hexesMinSize;
-  maxSize = _hexesMaxSize;
+  minLevel   = _hexesMinLevel;
+  maxLevel   = _hexesMaxLevel;
+  minSize    = _hexesMinSize;
+  maxSize    = _hexesMaxSize;
   sharpAngle = _hexoticSharpAngleThreshold;
   // Mode translation for mg-tetra 1.1
   switch ( _hexoticSdMode )
@@ -815,14 +826,14 @@ std::string HexoticPlugin_Hexotic::getHexoticCommand(const TCollection_AsciiStri
       mode = "all --manifold_geometry no";
       break;
   }
-  nbproc = _hexoticNbProc;
-  verbosity = _hexoticVerbosity;
-  maxMemory = _hexoticMaxMemory;
-  textOptions = (" " + _textOptions + " ").c_str();
-  nbLayers = _nbLayers;
+  nbproc         = _hexoticNbProc;
+  verbosity      = _hexoticVerbosity;
+  maxMemory      = _hexoticMaxMemory;
+  textOptions    = (" " + _textOptions + " ").c_str();
+  nbLayers       = _nbLayers;
   firstLayerSize = _firstLayerSize;
-  direction = _direction ? "1" : "-1";
-  growth = _growth;
+  direction      = _direction ? "1" : "-1";
+  growth         = _growth;
   for (size_t i = 0; i < _facesWithLayers.size(); i++)
   {
     facesWithLayers += _facesWithLayers[i];
@@ -892,19 +903,16 @@ std::string HexoticPlugin_Hexotic::getHexoticCommand(const TCollection_AsciiStri
 // way to share it
 TopoDS_Shape HexoticPlugin_Hexotic::entryToShape(std::string entry)
 {
-  MESSAGE("HexoticPlugin_Hexotic::entryToShape "<<entry );
-  if ( myStudy->_is_nil() )
-    throw SALOME_Exception("MG-Hexa plugin can't work w/o publishing in the study");
   GEOM::GEOM_Object_var aGeomObj;
   TopoDS_Shape S = TopoDS_Shape();
-  SALOMEDS::SObject_var aSObj = myStudy->FindObjectID( entry.c_str() );
+  SALOMEDS::SObject_var aSObj = SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindObjectID( entry.c_str() );
   if (!aSObj->_is_nil()) {
     CORBA::Object_var obj = aSObj->GetObject();
     aGeomObj = GEOM::GEOM_Object::_narrow(obj);
     aSObj->UnRegister();
   }
   if ( !aGeomObj->_is_nil() )
-    S = smeshGen_i->GeomObjectToShape( aGeomObj.in() );
+    S = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( aGeomObj.in() );
   return S;
 }
 
@@ -913,12 +921,13 @@ TopoDS_Shape HexoticPlugin_Hexotic::entryToShape(std::string entry)
  * \brief Produces a .mesh file with the size maps informations to give to Hexotic
  */
 //================================================================================
-std::vector<std::string> HexoticPlugin_Hexotic::writeSizeMapFile( MG_Hexotic_API* mgOutput,
+
+std::vector<std::string> HexoticPlugin_Hexotic::writeSizeMapFile( MG_Hexotic_API* mgInput,
                                                                   std::string     sizeMapPrefix )
 {
   HexoticPlugin_Hypothesis::THexoticSizeMaps::iterator it;
-  
-  std::vector<Control_Pnt> points;
+
+  std::vector<ControlPnt> points;
   // Iterate on the size maps
   for (it=_sizeMaps.begin(); it!=_sizeMaps.end(); it++)
   {
@@ -939,31 +948,31 @@ std::vector<std::string> HexoticPlugin_Hexotic::writeSizeMapFile( MG_Hexotic_API
   
   // Open files
   int verticesFileID =
-    mgOutput->GmfOpenMesh( myVerticesFile.c_str(), GmfWrite, GMFVERSION, GMFDIMENSION );  
+    mgInput->GmfOpenMesh( myVerticesFile.c_str(), GmfWrite, GMFVERSION, GMFDIMENSION );  
   int solFileID =
-    mgOutput->GmfOpenMesh( mySolFile.c_str(), GmfWrite, GMFVERSION, GMFDIMENSION );
+    mgInput->GmfOpenMesh( mySolFile.c_str(), GmfWrite, GMFVERSION, GMFDIMENSION );
   
   int pointsNumber = points.size();
   
   // Vertices Keyword
-  mgOutput->GmfSetKwd( verticesFileID, GmfVertices, pointsNumber );
+  mgInput->GmfSetKwd( verticesFileID, GmfVertices, pointsNumber );
   // SolAtVertices Keyword
   int TypTab[] = {GmfSca};
-  mgOutput->GmfSetKwd(solFileID, GmfSolAtVertices, pointsNumber, 1, TypTab);
+  mgInput->GmfSetKwd(solFileID, GmfSolAtVertices, pointsNumber, 1, TypTab);
   
   // Read the control points information from the vector and write it into the files
   double ValTab[1];
-  std::vector<Control_Pnt>::const_iterator points_it;
+  std::vector<ControlPnt>::const_iterator points_it;
   for (points_it = points.begin(); points_it != points.end(); points_it++ )
   {
-    mgOutput->GmfSetLin( verticesFileID, GmfVertices, points_it->X(), points_it->Y(), points_it->Z(), 0 );
+    mgInput->GmfSetLin( verticesFileID, GmfVertices, points_it->X(), points_it->Y(), points_it->Z(), 0 );
     ValTab[0] = points_it->Size();
-    mgOutput->GmfSetLin( solFileID, GmfSolAtVertices, ValTab);
+    mgInput->GmfSetLin( solFileID, GmfSolAtVertices, ValTab);
   }
 
   // Close Files
-  mgOutput->GmfCloseMesh( verticesFileID );
-  mgOutput->GmfCloseMesh( solFileID );
+  mgInput->GmfCloseMesh( verticesFileID );
+  mgInput->GmfCloseMesh( solFileID );
 
   std::vector<std::string> fileNames(2);
   fileNames[0] = myVerticesFile;
@@ -972,345 +981,6 @@ std::vector<std::string> HexoticPlugin_Hexotic::writeSizeMapFile( MG_Hexotic_API
   return fileNames;
 }
 
-//================================================================================
-/*!
- * \brief Fills a vector of points from which a size map input file can be written
- */
-//================================================================================
-void HexoticPlugin_Hexotic::createControlPoints( const TopoDS_Shape& aShape, 
-                                                 const double& theSize, 
-                                                 std::vector<Control_Pnt>& thePoints )
-{ 
-  if ( aShape.ShapeType() == TopAbs_VERTEX )
-  {
-    gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex(aShape) );
-    Control_Pnt aControl_Pnt( aPnt, theSize );
-    thePoints.push_back( aControl_Pnt );
-  }
-  if ( aShape.ShapeType() == TopAbs_EDGE )
-  {
-    createPointsSampleFromEdge( aShape, theSize, thePoints );  
-  }
-  else if ( aShape.ShapeType() == TopAbs_WIRE )
-  {
-    TopExp_Explorer Ex;
-    for (Ex.Init(aShape,TopAbs_EDGE); Ex.More(); Ex.Next()) 
-    {
-      createPointsSampleFromEdge( Ex.Current(), theSize, thePoints );
-    } 
-  }
-  else if ( aShape.ShapeType() ==  TopAbs_FACE )
-  {
-    createPointsSampleFromFace( aShape, theSize, thePoints ); 
-  }
-  else if ( aShape.ShapeType() ==  TopAbs_SOLID )
-  {
-    createPointsSampleFromSolid( aShape, theSize, thePoints ); 
-  }
-  else if ( aShape.ShapeType() == TopAbs_COMPOUND )
-  {
-    TopoDS_Iterator it( aShape );
-    for(; it.More(); it.Next())
-    {
-      createControlPoints( it.Value(), theSize, thePoints );
-    }
-  }
-}
-
-//================================================================================
-/*!
- * \brief Fills a vector of points with point samples approximately 
- * \brief spaced with a given size
- */
-//================================================================================
-void HexoticPlugin_Hexotic::createPointsSampleFromEdge( const TopoDS_Shape& aShape, 
-                                                        const double& theSize, 
-                                                        std::vector<Control_Pnt>& thePoints )
-{
-  double step = theSize;
-  double first, last;  
-  Handle( Geom_Curve ) aCurve = BRep_Tool::Curve( TopoDS::Edge( aShape ), first, last );
-  GeomAdaptor_Curve C ( aCurve );
-  GCPnts_UniformAbscissa DiscretisationAlgo(C, step , first, last, Precision::Confusion());
-  int nbPoints = DiscretisationAlgo.NbPoints();
-  
-  for ( int i = 1; i <= nbPoints; i++ )
-  {
-    double param = DiscretisationAlgo.Parameter( i );
-    Control_Pnt aPnt;
-    aCurve->D0( param, aPnt );
-    aPnt.SetSize(theSize);
-    thePoints.push_back( aPnt );
-  }  
-}
-
-//================================================================================
-/*!
- * \brief Fills a vector of points with point samples approximately 
- * \brief spaced with a given size
- */
-//================================================================================
-void HexoticPlugin_Hexotic::createPointsSampleFromFace( const TopoDS_Shape& aShape, 
-                                                        const double& theSize, 
-                                                        std::vector<Control_Pnt>& thePoints )
-{
-  BRepMesh_IncrementalMesh M(aShape, 0.01, Standard_True);
-  TopLoc_Location aLocation;
-  TopoDS_Face aFace = TopoDS::Face(aShape);
-
-  // Triangulate the face
-  Handle(Poly_Triangulation) aTri = BRep_Tool::Triangulation (aFace, aLocation);
-  
-  // Get the transformation associated to the face location
-  gp_Trsf aTrsf = aLocation.Transformation();
-  
-  // Get triangles
-  int nbTriangles = aTri->NbTriangles();
-  Poly_Array1OfTriangle triangles(1,nbTriangles);
-  triangles=aTri->Triangles();
-  
-  // GetNodes
-  int nbNodes = aTri->NbNodes();
-  TColgp_Array1OfPnt nodes(1,nbNodes);
-  nodes = aTri->Nodes();
-
-  // Iterate on triangles and subdivide them
-  for(int i=1; i<=nbTriangles; i++)
-  {
-     Poly_Triangle aTriangle = triangles.Value(i);
-     gp_Pnt p1 = nodes.Value(aTriangle.Value(1));
-     gp_Pnt p2 = nodes.Value(aTriangle.Value(2));
-     gp_Pnt p3 = nodes.Value(aTriangle.Value(3));
-     
-     p1.Transform(aTrsf);
-     p2.Transform(aTrsf);
-     p3.Transform(aTrsf);
-     
-     subdivideTriangle(p1, p2, p3, theSize, thePoints);  
-  }
-}
-
-//================================================================================
-/*!
- * \brief Fills a vector of points with point samples approximately 
- * \brief spaced with a given size
- */
-//================================================================================
-void HexoticPlugin_Hexotic::createPointsSampleFromSolid( const TopoDS_Shape& aShape, 
-                                                         const double& theSize, 
-                                                         std::vector<Control_Pnt>& thePoints )
-{
-  // Compute the bounding box
-  double Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
-  Bnd_Box B;               
-  BRepBndLib::Add(aShape, B);
-  B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
-  
-  // Create the points
-  double step = theSize;
-  
-  for ( double x=Xmin; x-Xmax<Precision::Confusion(); x=x+step )
-  {
-    for ( double y=Ymin; y-Ymax<Precision::Confusion(); y=y+step )
-    {
-      // Step1 : generate the Zmin -> Zmax line
-      gp_Pnt startPnt(x, y, Zmin);
-      gp_Pnt endPnt(x, y, Zmax);
-      gp_Vec aVec(startPnt, endPnt);
-      gp_Lin aLine(startPnt, aVec);
-      double endParam = Zmax - Zmin;
-      
-      // Step2 : for each face of aShape:
-      std::set<double> intersections;
-      std::set<double>::iterator it = intersections.begin();
-      
-      TopExp_Explorer Ex;
-      for (Ex.Init(aShape,TopAbs_FACE); Ex.More(); Ex.Next()) 
-      { 
-        // check if there is an intersection
-        IntCurvesFace_Intersector anIntersector(TopoDS::Face(Ex.Current()), Precision::Confusion());
-        anIntersector.Perform(aLine, 0, endParam);
-        
-        // get the intersection's parameter and store it
-        int nbPoints = anIntersector.NbPnt();
-        for(int i = 0 ; i < nbPoints ; i++ )
-        {
-          it = intersections.insert( it, anIntersector.WParameter(i+1) );
-        }
-      }
-      // Step3 : go through the line chunk by chunk 
-      if ( intersections.begin() != intersections.end() )
-      {
-        std::set<double>::iterator intersectionsIterator=intersections.begin();
-        double first = *intersectionsIterator;
-        intersectionsIterator++;
-        bool innerPoints = true; 
-        for ( ; intersectionsIterator!=intersections.end() ; intersectionsIterator++ )
-        {
-          double second = *intersectionsIterator;
-          if ( innerPoints )
-          {
-            // If the last chunk was outside of the shape or this is the first chunk
-            // add the points in the range [first, second] to the points vector
-            double localStep = (second -first) / ceil( (second - first) / step );
-            for ( double z = Zmin + first; z < Zmin + second; z = z + localStep )
-            {
-              thePoints.push_back(Control_Pnt( x, y, z, theSize ));
-            }
-            thePoints.push_back(Control_Pnt( x, y, Zmin + second, theSize ));
-          }
-          first = second;
-          innerPoints = !innerPoints;
-        }
-      }
-    }
-  }
-}
-
-//================================================================================
-/*!
- * \brief Subdivides a triangle until it reaches a certain size (recursive function)
- */
-//================================================================================
-void HexoticPlugin_Hexotic::subdivideTriangle( const gp_Pnt& p1, 
-                                               const gp_Pnt& p2, 
-                                               const gp_Pnt& p3, 
-                                               const double& theSize, 
-                                               std::vector<Control_Pnt>& thePoints)
-{
-  // Size threshold to stop subdividing
-  // This value ensures that two control points are distant no more than 2*theSize
-  // as shown below
-  //
-  // The greater distance D of the mass center M to each Edge is 1/3 * Median 
-  // and Median < sqrt(3/4) * a  where a is the greater side (by using Apollonius' thorem). 
-  // So D < 1/3 * sqrt(3/4) * a and if a < sqrt(3) * S then D < S/2
-  // and the distance between two mass centers of two neighbouring triangles 
-  // sharing an edge is < 2 * 1/2 * S = S
-  // If the traingles share a Vertex and no Edge the distance of the mass centers 
-  // to the Vertices is 2*D < S so the mass centers are distant of less than 2*S 
-  
-  double threshold = sqrt( 3. ) * theSize;
-  
-  if ( (p1.Distance(p2) > threshold ||
-        p2.Distance(p3) > threshold ||
-        p3.Distance(p1) > threshold))
-  { 
-    std::vector<gp_Pnt> midPoints = computePointsForSplitting(p1, p2, p3);
-    subdivideTriangle( midPoints[0], midPoints[1], midPoints[2], theSize, thePoints );
-    subdivideTriangle( midPoints[0], p2, midPoints[1], theSize, thePoints );
-    subdivideTriangle( midPoints[2], midPoints[1], p3, theSize, thePoints );
-    subdivideTriangle( p1, midPoints[0], midPoints[2], theSize, thePoints );
-  }
-  else
-  {
-    double x = (p1.X() + p2.X() + p3.X()) / 3 ;
-    double y = (p1.Y() + p2.Y() + p3.Y()) / 3 ;
-    double z = (p1.Z() + p2.Z() + p3.Z()) / 3 ;
-    
-    Control_Pnt massCenter( x ,y ,z, theSize );
-    thePoints.push_back( massCenter );
-  }
-}
-
-//================================================================================
-/*!
- * \brief Returns the appropriate points for splitting a triangle
- * \brief the tangency points of the incircle are used in order to have mostly
- * \brief well-shaped sub-triangles
- */
-//================================================================================
-std::vector<gp_Pnt> HexoticPlugin_Hexotic::computePointsForSplitting( const gp_Pnt& p1, 
-                                                                      const gp_Pnt& p2, 
-                                                                      const gp_Pnt& p3 )
-{
-  std::vector<gp_Pnt> midPoints;
-  //Change coordinates
-  gp_Trsf Trsf_1;            // Identity transformation
-  gp_Ax3 reference_system(gp::Origin(), gp::DZ(), gp::DX());   // OXY
-  gp_Vec Vx(p1, p3);
-  gp_Vec Vaux(p1, p2);
-  gp_Dir Dx(Vx);
-  gp_Dir Daux(Vaux);
-  gp_Dir Dz = Dx.Crossed(Daux);
-  gp_Ax3 current_system(p1, Dz, Dx);
-  
-  Trsf_1.SetTransformation( reference_system, current_system );
-  
-  gp_Pnt A = p1.Transformed(Trsf_1);
-  gp_Pnt B = p2.Transformed(Trsf_1);
-  gp_Pnt C = p3.Transformed(Trsf_1);
-  
-  double a =  B.Distance(C) ;
-  double b =  A.Distance(C) ;
-  double c =  B.Distance(A) ;
-  
-  // Incenter coordinates
-  // see http://mathworld.wolfram.com/Incenter.html
-  double Xi = ( b*B.X() + c*C.X() ) / ( a + b + c );
-  double Yi = ( b*B.Y() ) / ( a + b + c );
-  gp_Pnt Center(Xi, Yi, 0);
-  
-  // Calculate the tangency points of the incircle
-  gp_Pnt T1 = tangencyPoint( A, B, Center);
-  gp_Pnt T2 = tangencyPoint( B, C, Center);
-  gp_Pnt T3 = tangencyPoint( C, A, Center);
-  
-  gp_Pnt p1_2 = T1.Transformed(Trsf_1.Inverted());
-  gp_Pnt p2_3 = T2.Transformed(Trsf_1.Inverted());
-  gp_Pnt p3_1 = T3.Transformed(Trsf_1.Inverted());
-
-  midPoints.push_back(p1_2);
-  midPoints.push_back(p2_3);
-  midPoints.push_back(p3_1);
-  
-  return midPoints;
-}
-
-//================================================================================
-/*!
- * \brief Computes the tangency points of the circle of center Center with
- * \brief the straight line (p1 p2)
- */
-//================================================================================
-gp_Pnt HexoticPlugin_Hexotic::tangencyPoint(const gp_Pnt& p1,
-                                            const gp_Pnt& p2,
-                                            const gp_Pnt& Center)
-{
-  double Xt = 0;
-  double Yt = 0;
-  
-  // The tangency point is the intersection of the straight line (p1 p2)
-  // and the straight line (Center T) which is orthogonal to (p1 p2)
-  if ( fabs(p1.X() - p2.X()) <= Precision::Confusion() )
-  {
-    Xt=p1.X();     // T is on (p1 p2)
-    Yt=Center.Y(); // (Center T) is orthogonal to (p1 p2)
-  }
-  else if ( fabs(p1.Y() - p2.Y()) <= Precision::Confusion() )
-  {
-    Yt=p1.Y();     // T is on (p1 p2) 
-    Xt=Center.X(); // (Center T) is orthogonal to (p1 p2)
-  }
-  else
-  {
-    // First straight line coefficients (equation y=a*x+b)
-    double a = (p2.Y() - p1.Y()) / (p2.X() - p1.X())  ;
-    double b = p1.Y() - a*p1.X();         // p1 is on this straight line
-    
-    // Second straight line coefficients (equation y=c*x+d)
-    double c = -1 / a;                    // The 2 lines are orthogonal
-    double d = Center.Y() - c*Center.X(); // Center is on this straight line
-    
-    Xt = (d - b) / (a - c);
-    Yt = a*Xt + b;
-  }
-  
-  return gp_Pnt( Xt, Yt, 0 );
-}
-
 //=============================================================================
 /*!
  * Here we are going to use the MG-Hexa mesher
@@ -1318,7 +988,7 @@ gp_Pnt HexoticPlugin_Hexotic::tangencyPoint(const gp_Pnt& p1,
 //=============================================================================
 
 bool HexoticPlugin_Hexotic::Compute(SMESH_Mesh&          aMesh,
-                                    const TopoDS_Shape& aShape)
+                                    const TopoDS_Shape& /*aShape*/)
 {
   _computeCanceled = false;
   bool Ok = true;
@@ -1374,11 +1044,12 @@ bool HexoticPlugin_Hexotic::Compute(SMESH_Mesh&          aMesh,
     Hexotic_Out = aTmpDir + "Hexotic"+getSuffix()+"_Out.mesh";
 #ifdef WITH_BLSURFPLUGIN
     bool defaultInputFile = true;
-    if (_blsurfHypo && !_blsurfHypo->GetQuadAllowed()) {
+    if (_blsurfHypo && _blsurfHypo->GetElementType() == BLSURFPlugin_Hypothesis::Triangles ) {
       Hexotic_In = _blsurfHypo->GetGMFFile().c_str();
       if ( !Hexotic_In.IsEmpty() &&
            SMESH_File( _blsurfHypo->GetGMFFile() ).exists() )
       {
+        MESSAGE("Use output file from blsurf as input file from hexotic: " << Hexotic_In);
         mgHexa.SetUseExecutable();
         defaultInputFile = false;
       }
@@ -1390,8 +1061,8 @@ bool HexoticPlugin_Hexotic::Compute(SMESH_Mesh&          aMesh,
       splitQuads(aMesh); // quadrangles are no longer acceptable as input
       if ( mgHexa.IsExecutable() )
       {
-        cout << std::endl;
-        cout << "Creating MG-Hexa input mesh file : " << Hexotic_In << std::endl;
+        std::cout << std::endl;
+        std::cout << "Creating MG-Hexa input mesh file : " << Hexotic_In << std::endl;
       }
       writeInput( &mgHexa, Hexotic_In.ToCString(), meshDS );
 #ifdef WITH_BLSURFPLUGIN
@@ -1407,10 +1078,10 @@ bool HexoticPlugin_Hexotic::Compute(SMESH_Mesh&          aMesh,
     std::string run_Hexotic = getHexoticCommand(aQuote + Hexotic_In + aQuote, aQuote + Hexotic_Out + aQuote, Hexotic_SizeMap_Prefix, mgHexa.IsExecutable() );
     run_Hexotic += std::string(" 1> ") + aQuote.ToCString() + aLogFileName.ToCString() + aQuote.ToCString();  // dump into file
     mgHexa.SetLogFile( aLogFileName.ToCString() );
-    cout << "Creating MG-Hexa log file : " << aLogFileName << std::endl;
+    std::cout << "Creating MG-Hexa log file : " << aLogFileName << std::endl;
 
-    cout << std::endl;
-    cout << "MG-Hexa command : " << run_Hexotic << std::endl;
+    std::cout << std::endl;
+    std::cout << "MG-Hexa command : " << run_Hexotic << std::endl;
 
     if ( mgHexa.IsExecutable() )
     {
@@ -1433,7 +1104,7 @@ bool HexoticPlugin_Hexotic::Compute(SMESH_Mesh&          aMesh,
     // read a result
     // --------------
 
-    if ( mgHexa.IsExecutable() )
+    if ( mgHexa.IsExecutable() && SMESH_File( Hexotic_Out.ToCString() ).exists() )
     {
 #ifndef WIN32
       modeFile_Out += Hexotic_Out;
@@ -1447,38 +1118,48 @@ bool HexoticPlugin_Hexotic::Compute(SMESH_Mesh&          aMesh,
                      &aHelper, _nbShape, tabShape, tabBox );
 
     std::string log = mgHexa.GetLog();
+    hexahedraMessage = "failed";
     if ( Ok )
     {
       hexahedraMessage = "success";
-#ifndef _DEBUG_
-      removeFile(Hexotic_Out);
-      removeFile(Hexotic_In);
-      //removeFile(aLogFileName);
-      for( size_t i=0; i<sizeMapFiles.size(); i++)
-      {
-        removeFile( TCollection_AsciiString( sizeMapFiles[i].c_str() ) );
-      }
-#endif
+      if ( _removeLogOnSuccess )
+        removeFile( aLogFileName );
     }
-    else
+    else if ( !log.empty() )
     {
-      hexahedraMessage = "failed";
-      if ( mgHexa.IsExecutable() )
-        cout << "Problem with MG-Hexa output file " << Hexotic_Out.ToCString() << std::endl;
-      // analyse log file
-      if ( !log.empty() )
+      if( _computeCanceled )
+        error( "interruption initiated by user" );
+      else
       {
+        // get problem description from the log file
         char msgLic[] = " Dlim ";
-        std::string log = mgHexa.GetLog();
         const char* fileBeg = &log[0], *fileEnd = fileBeg + log.size();
         if ( std::search( fileBeg, fileEnd, msgLic, msgLic+strlen(msgLic)) != fileEnd )
           error("Licence problems.");
       }
-      if ( !errStr.empty() )
-        error(errStr);
     }
-    cout << "Hexahedra meshing " << hexahedraMessage << std::endl;
-    cout << std::endl;
+    else if ( !errStr.empty() )
+    {
+      // the log file is empty
+      removeFile( aLogFileName );
+      INFOS( "MG-Hexa Error, " << errStr);
+      error(COMPERR_ALGO_FAILED, errStr);
+    }
+
+    if ( !Ok && mgHexa.IsExecutable() )
+      std::cout << "Problem with MG-Hexa output file " << Hexotic_Out.ToCString() << std::endl;
+
+    if ( !_keepFiles )
+    {
+      if (! Ok && _computeCanceled )
+        removeFile( aLogFileName );
+      removeFile(Hexotic_Out);
+      removeFile(Hexotic_In);
+      for ( size_t i = 0; i < sizeMapFiles.size(); i++ )
+        removeFile( sizeMapFiles[i].c_str() );
+    }
+    std::cout << "Hexahedra meshing " << hexahedraMessage << std::endl;
+    std::cout << std::endl;
 
     delete [] tabShape;
     for (int i=0; i<_nbShape; i++)
@@ -1488,9 +1169,6 @@ bool HexoticPlugin_Hexotic::Compute(SMESH_Mesh&          aMesh,
     _iShape  = 0;
   }
 
-  if(_computeCanceled)
-    return error(SMESH_Comment("interruption initiated by user"));
-
   return Ok;
 }
 
@@ -1508,14 +1186,12 @@ bool HexoticPlugin_Hexotic::Compute(SMESH_Mesh&          aMesh,
 bool HexoticPlugin_Hexotic::Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper)
 {
   _computeCanceled = false;
-/*
-  SMESH_ComputeErrorPtr myError = SMESH_ComputeError::New();
-*/
+
   bool Ok = true;
   TCollection_AsciiString hexahedraMessage;
   TCollection_AsciiString aQuote("");
 #ifdef WIN32
-    aQuote = "\"";
+  aQuote = "\"";
 #endif
   SetParameters(_hypothesis);
 
@@ -1530,7 +1206,7 @@ bool HexoticPlugin_Hexotic::Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHel
   Hexotic_In  = aTmpDir + "Hexotic"+getSuffix()+"_In.mesh";
   Hexotic_Out = aTmpDir + "Hexotic"+getSuffix()+"_Out.mesh";
   Hexotic_SizeMap_Prefix = aTmpDir + "Hexotic_SizeMap";
+
   MG_Hexotic_API mgHexa( _computeCanceled, _progress );
 
   std::vector<std::string> sizeMapFiles = writeSizeMapFile( &mgHexa, Hexotic_SizeMap_Prefix.ToCString() );
@@ -1538,14 +1214,14 @@ bool HexoticPlugin_Hexotic::Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHel
   std::string run_Hexotic = getHexoticCommand(aQuote + Hexotic_In + aQuote, aQuote + Hexotic_Out + aQuote, Hexotic_SizeMap_Prefix, mgHexa.IsExecutable());
   run_Hexotic += std::string(" 1> ") + aQuote.ToCString() + aLogFileName.ToCString() + aQuote.ToCString();  // dump into file
   mgHexa.SetLogFile( aLogFileName.ToCString() );
-  cout << "Creating MG-Hexa log file : " << aLogFileName << std::endl;
+  std::cout << "Creating MG-Hexa log file : " << aLogFileName << std::endl;
 
   removeHexoticFiles(Hexotic_In, Hexotic_Out);
 
   splitQuads(aMesh); // quadrangles are no longer acceptable as input
 
-  cout << std::endl;
-  cout << "Creating MG-Hexa input mesh file : " << Hexotic_In << std::endl;
+  std::cout << std::endl;
+  std::cout << "Creating MG-Hexa input mesh file : " << Hexotic_In << std::endl;
   writeInput( &mgHexa, Hexotic_In.ToCString(), aHelper->GetMeshDS() );
   if ( mgHexa.IsExecutable() )
   {
@@ -1559,8 +1235,8 @@ bool HexoticPlugin_Hexotic::Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHel
 
   MESSAGE("HexoticPlugin_Hexotic::Compute");
 
-  cout << std::endl;
-  cout << "MG-Hexa command : " << run_Hexotic << std::endl;
+  std::cout << std::endl;
+  std::cout << "MG-Hexa command : " << run_Hexotic << std::endl;
 
   std::string errStr;
   Ok = mgHexa.Compute( run_Hexotic, errStr ); // run
@@ -1569,15 +1245,13 @@ bool HexoticPlugin_Hexotic::Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHel
   // read a result
   // --------------
 
-  if ( mgHexa.IsExecutable() )
+  if ( mgHexa.IsExecutable() && SMESH_File( Hexotic_Out.ToCString() ).exists() )
   {
     modeFile_Out += Hexotic_Out;
     system( modeFile_Out.ToCString() );
   }
 
-  Ok = readResult( &mgHexa, Hexotic_Out.ToCString(),
-                   this,
-                   aHelper );
+  Ok = Ok && readResult( &mgHexa, Hexotic_Out.ToCString(), this, aHelper );
 
   std::string log = mgHexa.GetLog();
   if ( Ok )
@@ -1588,26 +1262,24 @@ bool HexoticPlugin_Hexotic::Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHel
   {
     hexahedraMessage = "failed";
     if ( mgHexa.IsExecutable() )
-      cout << "Problem with MG-Hexa output file " << Hexotic_Out << std::endl;
-    // analyse log file
-    if ( !log.empty() )
-    {
-      char msgLic[] = " Dlim ";
-      const char* fileBeg = &log[0], *fileEnd = fileBeg + log.size();
-      if ( std::search( fileBeg, fileEnd, msgLic, msgLic+strlen(msgLic)) != fileEnd )
-        error("Licence problems.");
-    }
+      std::cout << "Problem with MG-Hexa output file " << Hexotic_Out << std::endl;
+
+    if ( log.find( " license " ) != std::string::npos ||
+         log.find( " Dlim "    ) != std::string::npos )
+      error("License problems.");
+
     if ( !errStr.empty() )
       error(errStr);
   }
-  cout << "Hexahedra meshing " << hexahedraMessage << std::endl;
-  cout << std::endl;
+  std::cout << "Hexahedra meshing " << hexahedraMessage << std::endl;
+  std::cout << std::endl;
 
   if(_computeCanceled)
     return error(SMESH_Comment("interruption initiated by user"));
   removeFile(Hexotic_Out);
   removeFile(Hexotic_In);
-  removeFile(aLogFileName);
+  if ( Ok )
+    removeFile(aLogFileName);
   for( size_t i=0; i<sizeMapFiles.size(); i++)
   {
     removeFile( TCollection_AsciiString(sizeMapFiles[i].c_str()) );