Salome HOME
updated copyright message
[plugins/netgenplugin.git] / src / NETGENPlugin / NETGENPlugin_NETGEN_3D_SA.cxx
index da003456f41fa340c5c733f53721899af3de8bc6..b12edb756f0cffecbe1d29095544dfd006cfcfca 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2021  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2023  CEA, EDF, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -32,6 +32,7 @@
 
 #include "NETGENPlugin_DriverParam.hxx"
 #include "NETGENPlugin_Hypothesis.hxx"
+#include "StdMeshers_MaxElementVolume.hxx"
 
 #include <SMESH_Gen.hxx>
 #include <SMESH_Mesh.hxx>
 #include <SMESHDS_Mesh.hxx>
 
 
+#ifdef WIN32
+#include <filesystem>
+namespace fs = std::filesystem;
+#else
 #include <boost/filesystem.hpp>
 namespace fs = boost::filesystem;
+#endif
 
 /*
   Netgen include files
@@ -75,19 +81,19 @@ using namespace nglib;
 
 //=============================================================================
 /*!
- *
+ * Constructor
  */
 //=============================================================================
 
 NETGENPlugin_NETGEN_3D_SA::NETGENPlugin_NETGEN_3D_SA()
-  : NETGENPlugin_NETGEN_3D(0, _gen=new SMESH_Gen())
+  :  NETGENPlugin_NETGEN_3D(0, new SMESH_Gen())
 {
   _name = "NETGEN_3D_SA";
 }
 
 //=============================================================================
 /*!
- *
+ * Destructor
  */
 //=============================================================================
 
@@ -97,7 +103,59 @@ NETGENPlugin_NETGEN_3D_SA::~NETGENPlugin_NETGEN_3D_SA()
     delete _gen;
 }
 
+/**
+ * @brief fill plugin hypothesis from the netgen_params structure
+ *
+ * @param aParams the structure
+ * @param gen SMESH_Gen associate with the SA
+ */
+void NETGENPlugin_NETGEN_3D_SA::fillHyp(netgen_params aParams)
+{
+  if(aParams.has_netgen_param){
+    NETGENPlugin_Hypothesis * hypParameters = new NETGENPlugin_Hypothesis(0, GetGen());
+
+    hypParameters->SetMaxSize(aParams.maxh);
+    hypParameters->SetMinSize(aParams.minh);
+    hypParameters->SetNbSegPerEdge(aParams.segmentsperedge);
+    hypParameters->SetGrowthRate(aParams.grading);
+    hypParameters->SetNbSegPerRadius(aParams.curvaturesafety);
+    hypParameters->SetSecondOrder(aParams.secondorder);
+    hypParameters->SetQuadAllowed(aParams.quad);
+    hypParameters->SetOptimize(aParams.optimize);
+    hypParameters->SetFineness((NETGENPlugin_Hypothesis::Fineness)aParams.fineness);
+    hypParameters->SetSurfaceCurvature(aParams.uselocalh);
+    hypParameters->SetFuseEdges(aParams.merge_solids);
+    hypParameters->SetChordalErrorEnabled(aParams.chordalError);
+    if(aParams.optimize){
+      hypParameters->SetNbSurfOptSteps(aParams.optsteps2d);
+      hypParameters->SetNbVolOptSteps(aParams.optsteps3d);
+    }
+    hypParameters->SetElemSizeWeight(aParams.elsizeweight);
+    hypParameters->SetWorstElemMeasure(aParams.opterrpow);
+    hypParameters->SetUseDelauney(aParams.delaunay);
+    hypParameters->SetCheckOverlapping(aParams.checkoverlap);
+    hypParameters->SetCheckChartBoundary(aParams.checkchartboundary);
+    hypParameters->SetMeshSizeFile(aParams.meshsizefilename);
+
+    _hypParameters = dynamic_cast< const NETGENPlugin_Hypothesis *> (hypParameters);
+  }
+  if(aParams.has_maxelementvolume_hyp){
+    _hypMaxElementVolume = new StdMeshers_MaxElementVolume(1, GetGen());
+    _maxElementVolume = aParams.maxElementVolume;
+  }
+  // TODO: Handle viscous layer
+}
 
+/**
+ * @brief Write a binary file containing information on the elements/nodes
+ *        created by the mesher
+ *
+ * @param nodeVec mapping between the mesh id and the netgen structure id
+ * @param ngLib Wrapper on netgen library
+ * @param new_element_file Name of the output file
+ * @param Netgen_NbOfNodes Number of nodes in the netgen structure
+ * @return true if there are some error
+ */
 bool NETGENPlugin_NETGEN_3D_SA::computeFillNewElementFile(
     std::vector< const SMDS_MeshNode* > &nodeVec,
     NETGENPlugin_NetgenLibWrapper &ngLib,
@@ -148,10 +206,22 @@ bool NETGENPlugin_NETGEN_3D_SA::computeFillNewElementFile(
   return false;
 }
 
-
-bool NETGENPlugin_NETGEN_3D_SA::Compute(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams,
-                     std::string new_element_file, std::string element_orientation_file,
-                     bool output_mesh)
+/**
+ * @brief Compute mesh associated to shape
+ *
+ * @param aShape the shape
+ * @param aMesh the mesh
+ * @param aParams netgen_params structure
+ * @param new_element_file Name of the file containing new element
+ * @param output_mesh Name of the output mesh (if empty it will not be written)
+ * @return true if there are some error
+ */
+bool NETGENPlugin_NETGEN_3D_SA::Compute(
+        TopoDS_Shape &aShape,
+        SMESH_Mesh& aMesh,
+        netgen_params& aParams,
+        std::string new_element_file,
+        bool output_mesh)
 {
   // vector of nodes in which node index == netgen ID
   vector< const SMDS_MeshNode* > nodeVec;
@@ -161,22 +231,17 @@ bool NETGENPlugin_NETGEN_3D_SA::Compute(TopoDS_Shape &aShape, SMESH_Mesh& aMesh,
   int endWith   = netgen::MESHCONST_OPTVOLUME;
   int Netgen_NbOfNodes=0;
 
-  bool ret;
-  ret = NETGENPlugin_NETGEN_3D::computeFillNgMesh(aMesh, aShape, nodeVec, ngLib, helper, aParams, Netgen_NbOfNodes);
-  if(ret)
-    return error( aParams._error, aParams._comment);
+  // Changing netgen log_file putting it next to new_element_file
+  fs::path netgen_log_file = fs::path(new_element_file).remove_filename() / fs::path("NETGEN.out");
 
-  netgen::OCCGeometry occgeo;
-  NETGENPlugin_NETGEN_3D::computePrepareParam(aMesh, ngLib, occgeo, helper, aParams, endWith);
+  ngLib.setOutputFile(netgen_log_file.string());
 
-  ret = NETGENPlugin_NETGEN_3D::computeRunMesher(occgeo, nodeVec, ngLib._ngMesh, ngLib, aParams, startWith, endWith);
-  if(ret){
-    if(aParams._error)
-      return error(aParams._error, aParams._comment);
+  NETGENPlugin_NETGEN_3D::computeFillNgMesh(aMesh, aShape, nodeVec, ngLib, helper, Netgen_NbOfNodes);
 
-    error(aParams._comment);
-    return true;
-  }
+  netgen::OCCGeometry occgeo;
+  NETGENPlugin_NETGEN_3D::computePrepareParam(aMesh, ngLib, occgeo, helper, endWith);
+
+  NETGENPlugin_NETGEN_3D::computeRunMesher(occgeo, nodeVec, ngLib._ngMesh, ngLib, startWith, endWith);
 
   computeFillNewElementFile(nodeVec, ngLib, new_element_file, Netgen_NbOfNodes);
 
@@ -186,63 +251,88 @@ bool NETGENPlugin_NETGEN_3D_SA::Compute(TopoDS_Shape &aShape, SMESH_Mesh& aMesh,
   return false;
 }
 
+
+/**
+ * @brief Running the mesher on the given files
+ *
+ * @param input_mesh_file Mesh file (containing 2D elements)
+ * @param shape_file Shape file (BREP or STEP format)
+ * @param hypo_file Ascii file containing the netgen parameters
+ * @param element_orientation_file Binary file containing the orientation of surface elemnts
+ * @param new_element_file output file containing info the elements created by the mesher
+ * @param output_mesh_file output mesh file (if empty it will not be created)
+ * @return int
+ */
 int NETGENPlugin_NETGEN_3D_SA::run(const std::string input_mesh_file,
           const std::string shape_file,
           const std::string hypo_file,
           const std::string element_orientation_file,
           const std::string new_element_file,
-          const std::string output_mesh_file,
-          int nbThreads)
+          const std::string output_mesh_file)
 {
 
   _element_orientation_file = element_orientation_file;
-  // Importing mesh
-  SMESH_Gen gen;
 
-  std::unique_ptr<SMESH_Mesh> myMesh(gen.CreateMesh(false));
+  std::unique_ptr<SMESH_Mesh> myMesh(_gen->CreateMesh(false));
 
-  importMesh(input_mesh_file, *myMesh);
+  SMESH_DriverMesh::importMesh(input_mesh_file, *myMesh);
 
   // Importing shape
   TopoDS_Shape myShape;
-  importShape(shape_file, myShape);
+  SMESH_DriverShape::importShape(shape_file, myShape);
 
   // Importing hypothesis
   netgen_params myParams;
 
-  importNetgenParams(hypo_file, myParams, &gen);
-  // Setting number of threads for netgen
-  myParams.nbThreads = nbThreads;
+  importNetgenParams(hypo_file, myParams);
+  fillHyp(myParams);
 
-  std::cout << "Meshing with netgen3d" << std::endl;
+  MESSAGE("Meshing with netgen3d");
   int ret = Compute(myShape, *myMesh, myParams,
-                      new_element_file, element_orientation_file,
+                      new_element_file,
                       !output_mesh_file.empty());
 
 
   if(ret){
-    std::cout << "Meshing failed" << std::endl;
+    std::cerr << "Meshing failed" << std::endl;
     return ret;
   }
 
   if(!output_mesh_file.empty()){
-    exportMesh(output_mesh_file, *myMesh, mesh_name);
+    std::string meshName = "MESH";
+    SMESH_DriverMesh::exportMesh(output_mesh_file, *myMesh, meshName);
   }
 
   return ret;
 }
 
-
+/**
+ * @brief Compute the list of already meshed Surface elements and info
+ *        on their orientation and if they are internal
+ *
+ * @param aMesh Global Mesh
+ * @param aShape Shape associated to the mesh
+ * @param proxyMesh pointer to mesh used fo find the elements
+ * @param internals information on internal sub shapes
+ * @param helper helper associated to the mesh
+ * @param listElements map of surface element associated with
+ *                     their orientation and internal status
+ * @return true if their was some error
+ */
 bool NETGENPlugin_NETGEN_3D_SA::getSurfaceElements(
     SMESH_Mesh&         aMesh,
     const TopoDS_Shape& aShape,
     SMESH_ProxyMesh::Ptr proxyMesh,
     NETGENPlugin_Internals &internals,
     SMESH_MesherHelper &helper,
-    netgen_params &aParams,
-    std::map<const SMDS_MeshElement*, tuple<bool, bool>>& listElements
+    std::map<const SMDS_MeshElement*, tuple<bool, bool>, TIDCompare>& listElements
     )
 {
+  // To remove compilation warnings
+  (void) aShape;
+  (void) proxyMesh;
+  (void) internals;
+  (void) helper;
   SMESHDS_Mesh* meshDS = aMesh.GetMeshDS();
 
   // Get list of elements + their orientation from element_orientation file
@@ -250,7 +340,7 @@ bool NETGENPlugin_NETGEN_3D_SA::getSurfaceElements(
   {
     // Setting all element orientation to false if there no element orientation file
     if(_element_orientation_file.empty()){
-      std::cout << "No element orientation file" << std::endl;
+      MESSAGE("No element orientation file");
 
       SMDS_ElemIteratorPtr iteratorElem = meshDS->elementsIterator(SMDSAbs_Face);
       while ( iteratorElem->more() ) // loop on elements on a geom face
@@ -260,7 +350,7 @@ bool NETGENPlugin_NETGEN_3D_SA::getSurfaceElements(
           elemOrientation[elem->GetID()] = false;
         }
     } else {
-      std::cout << "Reading from elements from file: " << _element_orientation_file << std::endl;
+      MESSAGE("Reading from elements from file: " << _element_orientation_file);
       std::ifstream df(_element_orientation_file, ios::binary|ios::in);
       int nbElement;
       bool orient;
@@ -282,7 +372,6 @@ bool NETGENPlugin_NETGEN_3D_SA::getSurfaceElements(
   // Adding elements from Mesh
   SMDS_ElemIteratorPtr iteratorElem = meshDS->elementsIterator(SMDSAbs_Face);
   bool isRev;
-  bool isInternalFace = false;
 
   bool isIn;
 
@@ -291,14 +380,10 @@ bool NETGENPlugin_NETGEN_3D_SA::getSurfaceElements(
     // check mesh face
     const SMDS_MeshElement* elem = iteratorElem->next();
     if ( !elem ){
-      aParams._error = COMPERR_BAD_INPUT_MESH;
-      aParams._comment = "Null element encounters";
-      return true;
+      return error( COMPERR_BAD_INPUT_MESH, "Null element encounters");
     }
     if ( elem->NbCornerNodes() != 3 ){
-      aParams._error = COMPERR_BAD_INPUT_MESH;
-      aParams._comment = "Not triangle element encounters";
-      return true;
+      return error( COMPERR_BAD_INPUT_MESH, "Not triangle element encounters");
     }
     // Keeping only element that are in the element orientation file
     isIn = elemOrientation.count(elem->GetID())==1;