Salome HOME
partial work for netgen2d in run_mesher + corrections for netgen3d nodeVec + restorin...
[plugins/netgenplugin.git] / src / NETGENPlugin / NETGENPlugin_NETGEN_2D_ONLY.cxx
index 7b08a3d29095b27c769b1f0e631c041560bb3d2e..72a2e6c56345c74e8bcfe4b0b091bca1ae411a0a 100644 (file)
@@ -26,6 +26,7 @@
 #include "NETGENPlugin_Mesher.hxx"
 #include "NETGENPlugin_Hypothesis_2D.hxx"
 #include "NETGENPlugin_Provider.hxx"
+#include "netgen_param.hxx"
 
 #include <SMDS_MeshElement.hxx>
 #include <SMDS_MeshNode.hxx>
@@ -40,6 +41,9 @@
 #include <StdMeshers_MaxElementArea.hxx>
 #include <StdMeshers_QuadranglePreference.hxx>
 #include <StdMeshers_ViscousLayers2D.hxx>
+#include "DriverStep.hxx"
+#include "DriverMesh.hxx"
+
 
 #include <Precision.hxx>
 #include <Standard_ErrorHandler.hxx>
@@ -51,6 +55,9 @@
 #include <vector>
 #include <limits>
 
+#include <cstdlib>
+#include <boost/filesystem.hpp>
+namespace fs = boost::filesystem;
 /*
   Netgen include files
 */
@@ -65,7 +72,7 @@ namespace nglib {
 //#include <meshtype.hpp>
 namespace netgen {
   NETGENPLUGIN_DLL_HEADER
-  // extern MeshingParameters mparam;
+  extern MeshingParameters mparam;
 #ifdef NETGEN_V5
   extern void OCCSetLocalMeshSize(OCCGeometry & geom, Mesh & mesh);
 #endif
@@ -220,6 +227,223 @@ bool NETGENPlugin_NETGEN_2D_ONLY::CheckHypothesis (SMESH_Mesh&         aMesh,
 //   }
 // }
 
+
+// write in a binary file the orientation for each 2D element of the mesh
+void NETGENPlugin_NETGEN_2D_ONLY::exportElementOrientation(SMESH_Mesh& aMesh,
+                                                           const TopoDS_Shape& aShape,
+                                                           netgen_params& aParams,
+                                                           const std::string output_file)
+{
+  std::map<vtkIdType, bool> elemOrientation;
+
+  SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( aMesh ));
+  for ( TopExp_Explorer exEd( aShape, TopAbs_EDGE ); exEd.More(); exEd.Next())
+  {
+    const TopoDS_Shape& aShapeEdge = exEd.Current();
+    const SMESHDS_SubMesh * aSubMeshDSEdge = proxyMesh->GetSubMesh( aShapeEdge );
+    if ( !aSubMeshDSEdge ) continue;
+
+    SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSEdge->GetElements();
+    while ( iteratorElem->more() ) // loop on elements on a geom face
+    {
+      const SMDS_MeshElement* elem = iteratorElem->next();
+      elemOrientation[elem->GetID()] = aShapeEdge.Orientation() == TopAbs_INTERNAL;
+    }
+  }
+
+  std::ofstream df(output_file, ios::out|ios::binary);
+  int size=elemOrientation.size();
+
+  df.write((char*)&size, sizeof(int));
+  for(auto const& [id, orient]:elemOrientation){
+    df.write((char*)&id, sizeof(vtkIdType));
+    df.write((char*)&orient, sizeof(bool));
+  }
+  df.close();
+}
+
+void NETGENPlugin_NETGEN_2D_ONLY::FillParameters(const NETGENPlugin_Hypothesis* hyp, netgen_params &aParams)
+{
+  //TODO: factorize code with the one from NETGEN3D
+  // Move in netgen_param ?
+  aParams.maxh               = hyp->GetMaxSize();
+  aParams.minh               = hyp->GetMinSize();
+  aParams.segmentsperedge    = hyp->GetNbSegPerEdge();
+  aParams.grading            = hyp->GetGrowthRate();
+  aParams.curvaturesafety    = hyp->GetNbSegPerRadius();
+  aParams.secondorder        = hyp->GetSecondOrder() ? 1 : 0;
+  aParams.quad               = hyp->GetQuadAllowed() ? 1 : 0;
+  aParams.optimize           = hyp->GetOptimize();
+  aParams.fineness           = hyp->GetFineness();
+  aParams.uselocalh          = hyp->GetSurfaceCurvature();
+  aParams.merge_solids       = hyp->GetFuseEdges();
+  aParams.chordalError       = hyp->GetChordalErrorEnabled() ? hyp->GetChordalError() : -1.;
+  aParams.optsteps2d         = aParams.optimize ? hyp->GetNbSurfOptSteps() : 0;
+  aParams.optsteps3d         = aParams.optimize ? hyp->GetNbVolOptSteps()  : 0;
+  aParams.elsizeweight       = hyp->GetElemSizeWeight();
+  aParams.opterrpow          = hyp->GetWorstElemMeasure();
+  aParams.delaunay           = hyp->GetUseDelauney();
+  aParams.checkoverlap       = hyp->GetCheckOverlapping();
+  aParams.checkchartboundary = hyp->GetCheckChartBoundary();
+#ifdef NETGEN_V6
+  // std::string
+  aParams.meshsizefilename = hyp->GetMeshSizeFile();
+#else
+  // const char*
+  aParams.meshsizefilename = hyp->GetMeshSizeFile().empty() ? 0 : hyp->GetMeshSizeFile().c_str();
+#endif
+#ifdef NETGEN_V6
+  aParams.closeedgefac = 2;
+#else
+  aParams.closeedgefac = 0;
+#endif
+  aParams.has_LengthFromEdges_hyp = _hypLengthFromEdges;
+}
+//=============================================================================
+/*!
+ *Here we are going to use the NETGEN mesher remotely
+ */
+//=============================================================================
+
+bool NETGENPlugin_NETGEN_2D_ONLY::RemoteCompute(SMESH_Mesh&         aMesh,
+                                                const TopoDS_Shape& aShape)
+{
+    aMesh.Lock();
+  SMESH_Hypothesis::Hypothesis_Status hypStatus;
+  CheckHypothesis(aMesh, aShape, hypStatus);
+
+  // Temporary folder for run
+  fs::path tmp_folder = aMesh.tmp_folder / fs::unique_path(fs::path("Face-%%%%-%%%%"));
+  fs::create_directories(tmp_folder);
+  // Using MESH2D generated after all triangles where created.
+  fs::path mesh_file=aMesh.tmp_folder / fs::path("Mesh1D.med");
+  fs::path element_orientation_file=tmp_folder / fs::path("element_orientation.dat");
+  fs::path new_element_file=tmp_folder / fs::path("new_elements.dat");
+  fs::path tmp_mesh_file=tmp_folder / fs::path("tmp_mesh.med");
+  // TODO: Remove that file we do not use it
+  fs::path output_mesh_file=tmp_folder / fs::path("output_mesh.med");
+  fs::path shape_file=tmp_folder / fs::path("shape.step");
+  fs::path param_file=tmp_folder / fs::path("netgen2d_param.txt");
+  fs::path log_file=tmp_folder / fs::path("run_mesher.log");
+  //TODO: Handle variable mesh_name
+  std::string mesh_name = "Maillage_1";
+
+  //Writing Shape
+  export_shape(shape_file.string(), aShape);
+  //Writing hypo
+  netgen_params aParams;
+  FillParameters(_hypParameters, aParams);
+
+  export_netgen_params(param_file.string(), aParams);
+
+  // Exporting element orientation
+  exportElementOrientation(aMesh, aShape, aParams, element_orientation_file.string());
+
+  aMesh.Unlock();
+  // Calling run_mesher
+  // TODO: check if we need to handle the .exe for windows
+  std::string cmd;
+  fs::path run_mesher_exe =
+    fs::path(std::getenv("NETGENPLUGIN_ROOT_DIR"))/
+    fs::path("bin")/
+    fs::path("salome")/
+    fs::path("run_mesher");
+  cmd = run_mesher_exe.string() +
+                  " NETGEN2D " + mesh_file.string() + " "
+                               + shape_file.string() + " "
+                               + param_file.string() + " "
+                               + element_orientation_file.string() + " "
+                               + new_element_file.string() + " "
+                               + std::to_string(0) + " "
+                               + output_mesh_file.string() +
+                               " >> " + log_file.string();
+
+  std::cout << "Running command: " << std::endl;
+  std::cout << cmd << std::endl;
+
+  // Writing command in log
+  std::ofstream flog(log_file.string());
+  flog << cmd << endl;
+  flog.close();
+
+  // TODO: Replace system by something else to handle redirection for windows
+  int ret = system(cmd.c_str());
+
+  // TODO: better error handling (display log ?)
+  if(ret != 0){
+    // Run crahed
+    //throw Exception("Meshing failed");
+    std::cerr << "Issue with command: " << std::endl;
+    std::cerr << cmd << std::endl;
+    return false;
+  }
+
+    aMesh.Lock();
+  std::ifstream df(new_element_file.string(), ios::binary);
+
+  int Netgen_NbOfNodes;
+  int Netgen_NbOfNodesNew;
+  int Netgen_NbOfTria;
+  double Netgen_point[3];
+  int    Netgen_triangle[3];
+  int nodeID;
+
+  SMESH_MesherHelper helper(aMesh);
+  // This function is necessary so that SetElementOnShape works
+  int _quadraticMesh = helper.IsQuadraticSubMesh(aShape);
+  helper.SetElementsOnShape( true );
+
+  // Number of nodes in intial mesh
+  df.read((char*) &Netgen_NbOfNodes, sizeof(int));
+  // Number of nodes added by netgen
+  df.read((char*) &Netgen_NbOfNodesNew, sizeof(int));
+
+  // Filling nodevec (correspondence netgen numbering mesh numbering)
+  vector< const SMDS_MeshNode* > nodeVec ( Netgen_NbOfNodesNew + 1 );
+  for (int nodeIndex = 1 ; nodeIndex <= Netgen_NbOfNodes; ++nodeIndex )
+  {
+    //Id of the point
+    df.read((char*) &nodeID, sizeof(int));
+    nodeVec.at(nodeIndex) = nullptr;
+    SMDS_NodeIteratorPtr iteratorNode = aMesh.GetMeshDS()->nodesIterator();
+    while(iteratorNode->more()){
+      const SMDS_MeshNode* node = iteratorNode->next();
+      if(node->GetID() == nodeID){
+        nodeVec.at(nodeIndex) = node;
+        break;
+      }
+    }
+    if(nodeVec.at(nodeIndex) == nullptr){
+      std::cout << "Error could not identify id";
+      return false;
+    }
+  }
+
+  // Add new points and update nodeVec
+  for (int nodeIndex = Netgen_NbOfNodes +1 ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex )
+  {
+    df.read((char *) &Netgen_point, sizeof(double)*3);
+
+    nodeVec.at(nodeIndex) = helper.AddNode(Netgen_point[0],
+                                           Netgen_point[1],
+                                           Netgen_point[2]);
+  }
+
+  // Add tetrahedrons
+  df.read((char*) &Netgen_NbOfTria, sizeof(int));
+  for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTria; ++elemIndex )
+  {
+    df.read((char*) &Netgen_triangle, sizeof(int)*3);
+    helper.AddFace (nodeVec.at( Netgen_triangle[0] ),
+                    nodeVec.at( Netgen_triangle[1] ),
+                    nodeVec.at( Netgen_triangle[2] ));
+  }
+  df.close();
+
+  aMesh.Unlock();
+
+  return true;
+}
 //=============================================================================
 /*!
  *Here we are going to use the NETGEN mesher
@@ -229,29 +453,23 @@ bool NETGENPlugin_NETGEN_2D_ONLY::CheckHypothesis (SMESH_Mesh&         aMesh,
 bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh&         aMesh,
                                           const TopoDS_Shape& aShape)
 {
-  aMesh.Lock();
-  SMESH_Hypothesis::Hypothesis_Status hypStatus;
-  this->CheckHypothesis(aMesh, aShape, hypStatus);
-  aMesh.Unlock();
 
-  netgen::MeshingParameters mparam;
-  int id_mparam = mparam_provider.take(mparam);
+  if(aMesh.IsParallel())
+    return RemoteCompute(aMesh, aShape);
 
   netgen::multithread.terminate = 0;
-  //netgen::multithread.task = "Surface meshing";
+  netgen::multithread.task = "Surface meshing";
 
   SMESHDS_Mesh* meshDS = aMesh.GetMeshDS();
   SMESH_MesherHelper helper(aMesh);
   helper.SetElementsOnShape( true );
 
-  NETGENPlugin_NetgenLibWrapper *ngLib;
-  int id_ngLib = nglib_provider.take(&ngLib);
-  ngLib->_isComputeOk = false;
+  NETGENPlugin_NetgenLibWrapper ngLib;
+  ngLib._isComputeOk = false;
 
   netgen::Mesh   ngMeshNoLocSize;
-  netgen::Mesh * ngMeshes[2] = { (netgen::Mesh*) ngLib->_ngMesh,  & ngMeshNoLocSize };
-  netgen::OCCGeometry *occgeoComm;
-  int id_occgeoComm = occgeom_provider.take(&occgeoComm);
+  netgen::Mesh * ngMeshes[2] = { (netgen::Mesh*) ngLib._ngMesh,  & ngMeshNoLocSize };
+  netgen::OCCGeometry occgeoComm;
 
   // min / max sizes are set as follows:
   // if ( _hypParameters )
@@ -265,21 +483,18 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh&         aMesh,
   // else
   //    min = aMesher.GetDefaultMinSize()
   //    max = max segment len of a FACE
-  aMesh.Lock();
   NETGENPlugin_Mesher aMesher( &aMesh, aShape, /*isVolume=*/false);
-  // TODO: Only valid for NETGEN2D_Only
-  aMesher.SetDefaultParameters(mparam);
-  aMesher.SetParameters( _hypParameters, mparam ); // _hypParameters -> mparam
+  aMesher.SetParameters( _hypParameters ); // _hypParameters -> netgen::mparam
   const bool toOptimize = _hypParameters ? _hypParameters->GetOptimize() : true;
   if ( _hypMaxElementArea )
   {
-    mparam.maxh = sqrt( 2. * _hypMaxElementArea->GetMaxArea() / sqrt(3.0) );
+    netgen::mparam.maxh = sqrt( 2. * _hypMaxElementArea->GetMaxArea() / sqrt(3.0) );
   }
   if ( _hypQuadranglePreference )
-    mparam.quad = true;
+    netgen::mparam.quad = true;
 
   // local size is common for all FACEs in aShape?
-  const bool isCommonLocalSize = ( !_hypLengthFromEdges && !_hypMaxElementArea && mparam.uselocalh );
+  const bool isCommonLocalSize = ( !_hypLengthFromEdges && !_hypMaxElementArea && netgen::mparam.uselocalh );
   const bool isDefaultHyp = ( !_hypLengthFromEdges && !_hypMaxElementArea && !_hypParameters );
   aMesh.Unlock();
 
@@ -287,15 +502,15 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh&         aMesh,
   if ( isCommonLocalSize ) // compute common local size in ngMeshes[0]
   {
     //list< SMESH_subMesh* > meshedSM[4]; --> all sub-shapes are added to occgeoComm
-    aMesher.PrepareOCCgeometry( *occgeoComm, aShape, aMesh );//, meshedSM );
+    aMesher.PrepareOCCgeometry( occgeoComm, aShape, aMesh );//, meshedSM );
 
     // local size set at MESHCONST_ANALYSE step depends on
     // minh, face_maxh, grading and curvaturesafety; find minh if not set by the user
-    if ( !_hypParameters || mparam.minh < DBL_MIN )
+    if ( !_hypParameters || netgen::mparam.minh < DBL_MIN )
     {
       if ( !_hypParameters )
-        mparam.maxh = occgeoComm->GetBoundingBox().Diam() / 3.;
-      mparam.minh = aMesher.GetDefaultMinSize( aShape, mparam.maxh );
+        netgen::mparam.maxh = occgeoComm.GetBoundingBox().Diam() / 3.;
+      netgen::mparam.minh = aMesher.GetDefaultMinSize( aShape, netgen::mparam.maxh );
     }
     // set local size depending on curvature and NOT closeness of EDGEs
 #ifdef NETGEN_V6
@@ -303,19 +518,19 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh&         aMesh,
 #else
     const double factor = netgen::occparam.resthcloseedgefac;
     netgen::occparam.resthcloseedgeenable = false;
-    netgen::occparam.resthcloseedgefac = 1.0 + mparam.grading;
+    netgen::occparam.resthcloseedgefac = 1.0 + netgen::mparam.grading;
 #endif
-    occgeoComm->face_maxh = mparam.maxh;
+    occgeoComm.face_maxh = netgen::mparam.maxh;
 #ifdef NETGEN_V6
     netgen::OCCParameters occparam;
-    netgen::OCCSetLocalMeshSize( *occgeoComm, *ngMeshes[0], mparam, occparam );
+    netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0], netgen::mparam, occparam );
 #else
     aMesh.Lock();
-    netgen::OCCSetLocalMeshSize( *occgeoComm, *ngMeshes[0] );
+    netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0] );
     aMesh.Unlock();
 #endif
-    occgeoComm->emap.Clear();
-    occgeoComm->vmap.Clear();
+    occgeoComm.emap.Clear();
+    occgeoComm.vmap.Clear();
 
     // set local size according to size of existing segments
     TopTools_IndexedMapOfShape edgeMap;
@@ -340,15 +555,15 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh&         aMesh,
     }
 
     // set local size defined on shapes
-    aMesher.SetLocalSize( *occgeoComm, *ngMeshes[0] );
-    aMesher.SetLocalSizeForChordalError( *occgeoComm, *ngMeshes[0] );
+    aMesher.SetLocalSize( occgeoComm, *ngMeshes[0] );
+    aMesher.SetLocalSizeForChordalError( occgeoComm, *ngMeshes[0] );
     try {
-      ngMeshes[0]->LoadLocalMeshSize( mparam.meshsizefilename );
+      ngMeshes[0]->LoadLocalMeshSize( netgen::mparam.meshsizefilename );
     } catch (NgException & ex) {
       return error( COMPERR_BAD_PARMETERS, ex.What() );
     }
   }
-  mparam.uselocalh = toOptimize; // restore as it is used at surface optimization
+  netgen::mparam.uselocalh = toOptimize; // restore as it is used at surface optimization
   // ==================
   // Loop on all FACEs
   // ==================
@@ -414,7 +629,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh&         aMesh,
         }
         if ( nbSegments )
           edgeLength /= double( nbSegments );
-        mparam.maxh = edgeLength;
+        netgen::mparam.maxh = edgeLength;
       }
       else if ( isDefaultHyp )
       {
@@ -434,29 +649,28 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh&         aMesh,
           }
         }
         edgeLength = sqrt( maxSeg2 ) * 1.05;
-        mparam.maxh = edgeLength;
+        netgen::mparam.maxh = edgeLength;
       }
-      if ( mparam.maxh < DBL_MIN )
-        mparam.maxh = occgeoComm->GetBoundingBox().Diam();
+      if ( netgen::mparam.maxh < DBL_MIN )
+        netgen::mparam.maxh = occgeoComm.GetBoundingBox().Diam();
 
       if ( !isCommonLocalSize )
       {
-        mparam.minh = aMesher.GetDefaultMinSize( F, mparam.maxh );
+        netgen::mparam.minh = aMesher.GetDefaultMinSize( F, netgen::mparam.maxh );
       }
     }
 
     // prepare occgeom
-    netgen::OCCGeometry *occgeom;
-    int id_occgeom = occgeom_provider.take(&occgeom);
-    occgeom->shape = F;
-    occgeom->fmap.Add( F );
-    occgeom->CalcBoundingBox();
-    occgeom->facemeshstatus.SetSize(1);
-    occgeom->facemeshstatus = 0;
-    occgeom->face_maxh_modified.SetSize(1);
-    occgeom->face_maxh_modified = 0;
-    occgeom->face_maxh.SetSize(1);
-    occgeom->face_maxh = mparam.maxh;
+    netgen::OCCGeometry occgeom;
+    occgeom.shape = F;
+    occgeom.fmap.Add( F );
+    occgeom.CalcBoundingBox();
+    occgeom.facemeshstatus.SetSize(1);
+    occgeom.facemeshstatus = 0;
+    occgeom.face_maxh_modified.SetSize(1);
+    occgeom.face_maxh_modified = 0;
+    occgeom.face_maxh.SetSize(1);
+    occgeom.face_maxh = netgen::mparam.maxh;
 
     // -------------------------
     // Fill netgen mesh
@@ -477,28 +691,28 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh&         aMesh,
 
       if ( iLoop == NO_LOC_SIZE )
       {
-        ngMesh->SetGlobalH ( mparam.maxh );
-        ngMesh->SetMinimalH( mparam.minh );
-        Box<3> bb = occgeom->GetBoundingBox();
+        ngMesh->SetGlobalH ( netgen::mparam.maxh );
+        ngMesh->SetMinimalH( netgen::mparam.minh );
+        Box<3> bb = occgeom.GetBoundingBox();
         bb.Increase (bb.Diam()/10);
-        ngMesh->SetLocalH (bb.PMin(), bb.PMax(), mparam.grading);
-        aMesher.SetLocalSize( *occgeom, *ngMesh );
-        aMesher.SetLocalSizeForChordalError( *occgeoComm, *ngMesh );
+        ngMesh->SetLocalH (bb.PMin(), bb.PMax(), netgen::mparam.grading);
+        aMesher.SetLocalSize( occgeom, *ngMesh );
+        aMesher.SetLocalSizeForChordalError( occgeoComm, *ngMesh );
         try {
-          ngMesh->LoadLocalMeshSize( mparam.meshsizefilename );
+          ngMesh->LoadLocalMeshSize( netgen::mparam.meshsizefilename );
         } catch (NgException & ex) {
           return error( COMPERR_BAD_PARMETERS, ex.What() );
         }
       }
 
       nodeVec.clear();
-      faceErr = aMesher.AddSegmentsToMesh( *ngMesh, *occgeom, wires, helper, nodeVec,
+      faceErr = aMesher.AddSegmentsToMesh( *ngMesh, occgeom, wires, helper, nodeVec,
                                            /*overrideMinH=*/!_hypParameters);
       if ( faceErr && !faceErr->IsOK() )
         break;
 
       //if ( !isCommonLocalSize )
-      //limitSize( ngMesh, mparam.maxh * 0.8);
+      //limitSize( ngMesh, netgen::mparam.maxh * 0.8);
 
       // -------------------------
       // Generate surface mesh
@@ -510,7 +724,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh&         aMesh,
       SMESH_Comment str;
       try {
         OCC_CATCH_SIGNALS;
-        err = ngLib->GenerateMesh(*occgeom, startWith, endWith, ngMesh, mparam);
+        err = ngLib.GenerateMesh(occgeom, startWith, endWith, ngMesh);
         if ( netgen::multithread.terminate )
           return false;
         if ( err )
@@ -532,12 +746,12 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh&         aMesh,
       }
       if ( err )
       {
-        if ( aMesher.FixFaceMesh( *occgeom, *ngMesh, 1 ))
+        if ( aMesher.FixFaceMesh( occgeom, *ngMesh, 1 ))
           break;
         if ( iLoop == LOC_SIZE )
         {
-          mparam.minh = mparam.maxh;
-          mparam.maxh = 0;
+          netgen::mparam.minh = netgen::mparam.maxh;
+          netgen::mparam.maxh = 0;
           for ( size_t iW = 0; iW < wires.size(); ++iW )
           {
             StdMeshers_FaceSidePtr wire = wires[ iW ];
@@ -548,13 +762,13 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh&         aMesh,
               netgen::Point3d np( p.X(),p.Y(),p.Z());
               double segLen = p.Distance( uvPtVec[ iP-1 ].node );
               double   size = ngMesh->GetH( np );
-              mparam.minh = Min( mparam.minh, size );
-              mparam.maxh = Max( mparam.maxh, segLen );
+              netgen::mparam.minh = Min( netgen::mparam.minh, size );
+             netgen:: mparam.maxh = Max( netgen::mparam.maxh, segLen );
             }
           }
           //cerr << "min " << mparam.minh << " max " << mparam.maxh << endl;
-          mparam.minh *= 0.9;
-          mparam.maxh *= 1.1;
+          netgen::mparam.minh *= 0.9;
+          netgen::mparam.maxh *= 1.1;
           continue;
         }
         else
@@ -563,10 +777,6 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh&         aMesh,
         }
       }
 
-      occgeom_provider.release(id_occgeoComm, true);
-      occgeom_provider.release(id_occgeom, true);
-      mparam_provider.release(id_mparam);
-      aMesh.Lock();
       // ----------------------------------------------------
       // Fill the SMESHDS with the generated nodes and faces
       // ----------------------------------------------------
@@ -616,9 +826,6 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh&         aMesh,
       break;
     } // two attempts
   } // loop on FACEs
-  aMesh.Unlock();
-  nglib_provider.release(id_ngLib, true);
-
 
   return true;
 }