From: Yoann Audouin Date: Tue, 13 Sep 2022 14:46:00 +0000 (+0200) Subject: Renaming functions and files + minor corrections in runner_main to detect what to do X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=01afecee316c9fd4759eb1175be12740d196fc9b;p=plugins%2Fnetgenplugin.git Renaming functions and files + minor corrections in runner_main to detect what to do --- diff --git a/src/NETGENPlugin/CMakeLists.txt b/src/NETGENPlugin/CMakeLists.txt index e2c27db..7a57bb0 100644 --- a/src/NETGENPlugin/CMakeLists.txt +++ b/src/NETGENPlugin/CMakeLists.txt @@ -93,9 +93,8 @@ SET(NETGENEngine_HEADERS NETGENPlugin_Mesher.hxx NETGENPlugin_Remesher_2D.hxx NETGENPlugin_Defs.hxx - NETGENPlugin_Provider.hxx - netgen_param.hxx - netgen_mesher.hxx + NETGENPlugin_DriverParam.hxx + NETGENPlugin_Runner.hxx ) # --- sources --- @@ -123,12 +122,12 @@ SET(NETGENEngine_SOURCES NETGENPlugin_SimpleHypothesis_3D_i.cxx NETGENPlugin_Remesher_2D.cxx NETGENPlugin_i.cxx - netgen_mesher.cxx - netgen_param.cxx + NETGENPlugin_Runner.cxx + NETGENPlugin_DriverParam.cxx ) -SET(Run_Mesher_SOURCES - run_mesher.cxx +SET(NetgenRunner_SOURCES + NETGENPlugin_Runner_main.cxx ) # --- scripts --- @@ -145,9 +144,9 @@ ADD_LIBRARY(NETGENEngine ${NETGENEngine_SOURCES}) TARGET_LINK_LIBRARIES(NETGENEngine ${_link_LIBRARIES} ) INSTALL(TARGETS NETGENEngine EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS}) -ADD_EXECUTABLE(run_mesher ${Run_Mesher_SOURCES}) -TARGET_LINK_LIBRARIES(run_mesher ${_link_LIBRARIES} NETGENEngine ) -INSTALL(TARGETS run_mesher EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_BINS}) +ADD_EXECUTABLE(NETGENPlugin_Runner ${NetgenRunner_SOURCES}) +TARGET_LINK_LIBRARIES(NETGENPlugin_Runner ${_link_LIBRARIES} NETGENEngine ) +INSTALL(TARGETS NETGENPlugin_Runner EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_BINS}) INSTALL(FILES ${NETGENEngine_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS}) diff --git a/src/NETGENPlugin/NETGENPlugin_DriverParam.cxx b/src/NETGENPlugin/NETGENPlugin_DriverParam.cxx new file mode 100644 index 0000000..2ddf398 --- /dev/null +++ b/src/NETGENPlugin/NETGENPlugin_DriverParam.cxx @@ -0,0 +1,214 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : NETGENPlugin_DriverParam.hxx +// Author : Yoann AUDOUIN, EDF +// Module : NETGEN +// +#include "NETGENPlugin_DriverParam.hxx" + +#include +#include +#include +#include + + +// TODO: Error handling of read/write + +/** + * @brief Print content of a netgen_params + * + * @param aParams The object to display + */ +void printNetgenParams(netgen_params& aParams){ + // TODO: prettier print + // TODO: Add call to print in log + std::cout << "has_netgen_param: " << aParams.has_netgen_param << std::endl; + std::cout << "maxh: " << aParams.maxh << std::endl; + std::cout << "minh: " << aParams.minh << std::endl; + std::cout << "segmentsperedge: " << aParams.segmentsperedge << std::endl; + std::cout << "grading: " << aParams.grading << std::endl; + std::cout << "curvaturesafety: " << aParams.curvaturesafety << std::endl; + std::cout << "secondorder: " << aParams.secondorder << std::endl; + std::cout << "quad: " << aParams.quad << std::endl; + std::cout << "optimize: " << aParams.optimize << std::endl; + std::cout << "fineness: " << aParams.fineness << std::endl; + std::cout << "uselocalh: " << aParams.uselocalh << std::endl; + std::cout << "merge_solids: " << aParams.merge_solids << std::endl; + std::cout << "chordalError: " << aParams.chordalError << std::endl; + std::cout << "optsteps2d: " << aParams.optsteps2d << std::endl; + std::cout << "optsteps3d: " << aParams.optsteps3d << std::endl; + std::cout << "elsizeweight: " << aParams.elsizeweight << std::endl; + std::cout << "opterrpow: " << aParams.opterrpow << std::endl; + std::cout << "delaunay: " << aParams.delaunay << std::endl; + std::cout << "checkoverlap: " << aParams.checkoverlap << std::endl; + std::cout << "checkchartboundary: " << aParams.checkchartboundary << std::endl; + std::cout << "closeedgefac: " << aParams.closeedgefac << std::endl; + std::cout << "has_local_size: " << aParams.has_local_size << std::endl; + std::cout << "meshsizefilename: " << aParams.meshsizefilename << std::endl; + std::cout << "has_maxelementvolume_hyp: " << aParams.has_maxelementvolume_hyp << std::endl; + std::cout << "maxElementVolume: " << aParams.maxElementVolume << std::endl; + std::cout << "has_LengthFromEdges_hyp: " << aParams.has_LengthFromEdges_hyp << std::endl; +} + +/** + * @brief Import a param_file into a netgen_params structure + * + * @param param_file Name of the file + * @param aParams Structure to fill + */ +void importNetgenParams(const std::string param_file, netgen_params& aParams){ + std::ifstream myfile(param_file); + std::string line; + + std::getline(myfile, line); + aParams.has_netgen_param = std::stoi(line); + std::getline(myfile, line); + aParams.maxh = std::stod(line); + std::getline(myfile, line); + aParams.minh = std::stod(line); + std::getline(myfile, line); + aParams.segmentsperedge = std::stod(line); + std::getline(myfile, line); + aParams.grading = std::stod(line); + std::getline(myfile, line); + aParams.curvaturesafety = std::stod(line); + std::getline(myfile, line); + aParams.secondorder = std::stoi(line); + std::getline(myfile, line); + aParams.quad = std::stoi(line); + std::getline(myfile, line); + aParams.optimize = std::stoi(line); + std::getline(myfile, line); + aParams.fineness = std::stoi(line); + std::getline(myfile, line); + aParams.uselocalh = std::stoi(line); + std::getline(myfile, line); + aParams.merge_solids = std::stoi(line); + std::getline(myfile, line); + aParams.chordalError = std::stod(line); + std::getline(myfile, line); + aParams.optsteps2d = std::stoi(line); + std::getline(myfile, line); + aParams.optsteps3d = std::stoi(line); + std::getline(myfile, line); + aParams.elsizeweight = std::stod(line); + std::getline(myfile, line); + aParams.opterrpow = std::stoi(line); + std::getline(myfile, line); + aParams.delaunay = std::stoi(line); + std::getline(myfile, line); + aParams.checkoverlap = std::stoi(line); + std::getline(myfile, line); + aParams.checkchartboundary = std::stoi(line); + std::getline(myfile, line); + aParams.closeedgefac = std::stoi(line); + std::getline(myfile, line); + aParams.has_local_size = std::stoi(line); + std::getline(myfile, line); + aParams.meshsizefilename = line; + std::getline(myfile, line); + aParams.has_maxelementvolume_hyp = std::stoi(line); + std::getline(myfile, line); + aParams.maxElementVolume = std::stod(line); + std::getline(myfile, line); + aParams.maxElementVolume = std::stoi(line); + + myfile.close(); +}; + +/** + * @brief Writes the content of a netgen_param into a file + * + * @param param_file the file + * @param aParams the object + */ +void exportNetgenParams(const std::string param_file, netgen_params& aParams){ + std::ofstream myfile(param_file); + myfile << aParams.has_netgen_param << std::endl; + myfile << aParams.maxh << std::endl; + myfile << aParams.minh << std::endl; + myfile << aParams.segmentsperedge << std::endl; + myfile << aParams.grading << std::endl; + myfile << aParams.curvaturesafety << std::endl; + myfile << aParams.secondorder << std::endl; + myfile << aParams.quad << std::endl; + myfile << aParams.optimize << std::endl; + myfile << aParams.fineness << std::endl; + myfile << aParams.uselocalh << std::endl; + myfile << aParams.merge_solids << std::endl; + myfile << aParams.chordalError << std::endl; + myfile << aParams.optsteps2d << std::endl; + myfile << aParams.optsteps3d << std::endl; + myfile << aParams.elsizeweight << std::endl; + myfile << aParams.opterrpow << std::endl; + myfile << aParams.delaunay << std::endl; + myfile << aParams.checkoverlap << std::endl; + myfile << aParams.checkchartboundary << std::endl; + myfile << aParams.closeedgefac << std::endl; + myfile << aParams.has_local_size << std::endl; + myfile << aParams.meshsizefilename << std::endl; + myfile << aParams.has_maxelementvolume_hyp << std::endl; + myfile << aParams.maxElementVolume << std::endl; + myfile << aParams.has_LengthFromEdges_hyp << std::endl; + + myfile.close(); +}; + +/** + * @brief Compares two netgen_parms object + * + * @param params1 Object 1 + * @param params2 Object 2 + + * @return true if the two object are identical + */ +bool diffNetgenParams(netgen_params params1, netgen_params params2){ + bool ret = true; + ret &= params1.maxh == params2.maxh; + ret &= params1.minh == params2.minh; + ret &= params1.segmentsperedge == params2.segmentsperedge; + ret &= params1.grading == params2.grading; + ret &= params1.curvaturesafety == params2.curvaturesafety; + ret &= params1.secondorder == params2.secondorder; + ret &= params1.quad == params2.quad; + ret &= params1.optimize == params2.optimize; + ret &= params1.fineness == params2.fineness; + ret &= params1.uselocalh == params2.uselocalh; + ret &= params1.merge_solids == params2.merge_solids; + ret &= params1.chordalError == params2.chordalError; + ret &= params1.optsteps2d == params2.optsteps2d; + ret &= params1.optsteps3d == params2.optsteps3d; + ret &= params1.elsizeweight == params2.elsizeweight; + ret &= params1.opterrpow == params2.opterrpow; + ret &= params1.delaunay == params2.delaunay; + ret &= params1.checkoverlap == params2.checkoverlap; + ret &= params1.checkchartboundary == params2.checkchartboundary; + ret &= params1.closeedgefac == params2.closeedgefac; + ret &= params1.has_local_size == params2.has_local_size; + ret &= params1.meshsizefilename == params2.meshsizefilename; + ret &= params1.has_maxelementvolume_hyp == params2.has_maxelementvolume_hyp; + ret &= params1.maxElementVolume == params2.maxElementVolume; + ret &= params1.has_LengthFromEdges_hyp == params2.has_LengthFromEdges_hyp; + + return ret; +} diff --git a/src/NETGENPlugin/NETGENPlugin_DriverParam.hxx b/src/NETGENPlugin/NETGENPlugin_DriverParam.hxx new file mode 100644 index 0000000..0f53512 --- /dev/null +++ b/src/NETGENPlugin/NETGENPlugin_DriverParam.hxx @@ -0,0 +1,96 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : NETGENPlugin_DriverParam.hxx +// Author : Yoann AUDOUIN, EDF +// Module : NETGEN +// + +#ifndef _NETGENPLUGIN_DRIVERPARAM_HXX_ +#define _NETGENPLUGIN_DRIVERPARAM_HXX_ + +#include + +class NETGENPlugin_Hypothesis; +class StdMeshers_MaxElementVolume; +class StdMeshers_ViscousLayers; + +struct netgen_params{ + // Params from NETGENPlugin_Mesher + // True if _hypParameters is not null + bool has_netgen_param=true; + double maxh; + double minh; + double segmentsperedge; + double grading; + double curvaturesafety; + int secondorder; + int quad; + bool optimize; + int fineness; + bool uselocalh; + bool merge_solids; + double chordalError; + int optsteps2d; + int optsteps3d; + double elsizeweight; + int opterrpow; + bool delaunay; + bool checkoverlap; + bool checkchartboundary; + int closeedgefac; + + + // TODO: add localsize (pass through local size file ?) + // True if we have a mesh size file or local size info + bool has_local_size = false; + std::string meshsizefilename; + + // Params from NETGEN3D + // True if _hypMaxElementVolume is not null + bool has_maxelementvolume_hyp=false; + double maxElementVolume=0.0; + + // to replace + //NETGENPlugin_Hypothesis * _hypParameters=nullptr; + // to remove ? + StdMeshers_MaxElementVolume* _hypMaxElementVolume=nullptr; + // to remove ? + StdMeshers_ViscousLayers* _viscousLayersHyp=nullptr; + //double _progressByTic; + bool _quadraticMesh=false; + + // Params from NETGEN2D + bool has_LengthFromEdges_hyp=false; + + // Number of threads for the mesher + int nbThreads; +}; + +void printNetgenParams(netgen_params& aParams); + +void importNetgenParams(const std::string param_file, netgen_params& aParams); +void exportNetgenParams(const std::string param_file, netgen_params& aParams); + +bool diffNetgenParams(netgen_params params1, netgen_params params2); + +#endif \ No newline at end of file diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx index a5b7765..d8db3de 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx @@ -1,4 +1,3 @@ -// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -25,8 +24,7 @@ #include "NETGENPlugin_Mesher.hxx" #include "NETGENPlugin_Hypothesis_2D.hxx" -#include "NETGENPlugin_Provider.hxx" -#include "netgen_param.hxx" +#include "NETGENPlugin_DriverParam.hxx" #include #include @@ -41,8 +39,8 @@ #include #include #include -#include "DriverStep.hxx" -#include "DriverMesh.hxx" +#include "SMESH_DriverStep.hxx" +#include "SMESH_DriverMesh.hxx" #include @@ -324,17 +322,17 @@ bool NETGENPlugin_NETGEN_2D_ONLY::RemoteCompute(SMESH_Mesh& aMesh, 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"); + fs::path log_file=tmp_folder / fs::path("run.log"); //TODO: Handle variable mesh_name std::string mesh_name = "Maillage_1"; //Writing Shape - export_shape(shape_file.string(), aShape); + exportShape(shape_file.string(), aShape); //Writing hypo netgen_params aParams; FillParameters(_hypParameters, aParams); - export_netgen_params(param_file.string(), aParams); + exportNetgenParams(param_file.string(), aParams); // Exporting element orientation exportElementOrientation(aMesh, aShape, aParams, element_orientation_file.string()); @@ -347,7 +345,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::RemoteCompute(SMESH_Mesh& aMesh, fs::path(std::getenv("NETGENPLUGIN_ROOT_DIR"))/ fs::path("bin")/ fs::path("salome")/ - fs::path("run_mesher"); + fs::path("NETGENPlugin_Runner"); cmd = run_mesher_exe.string() + " NETGEN2D " + mesh_file.string() + " " + shape_file.string() + " " diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index b3d624f..f08232e 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -32,9 +32,7 @@ #include "NETGENPlugin_Hypothesis.hxx" -#include "DriverStep.hxx" -#include "DriverMesh.hxx" -#include "netgen_param.hxx" +#include "NETGENPlugin_DriverParam.hxx" #include #include @@ -50,6 +48,9 @@ #include #include #include +#include +#include + #include #include @@ -196,7 +197,7 @@ bool NETGENPlugin_NETGEN_3D::CheckHypothesis (SMESH_Mesh& aMesh, } -void NETGENPlugin_NETGEN_3D::FillParameters(const NETGENPlugin_Hypothesis* hyp, netgen_params &aParams) +void NETGENPlugin_NETGEN_3D::fillParameters(const NETGENPlugin_Hypothesis* hyp, netgen_params &aParams) { aParams.maxh = hyp->GetMaxSize(); aParams.minh = hyp->GetMinSize(); @@ -315,21 +316,21 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, 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("netgen3d_param.txt"); - fs::path log_file=tmp_folder / fs::path("run_mesher.log"); + fs::path log_file=tmp_folder / fs::path("run.log"); //TODO: Handle variable mesh_name std::string mesh_name = "Maillage_1"; //Writing Shape - export_shape(shape_file.string(), aShape); + exportShape(shape_file.string(), aShape); auto time2 = std::chrono::high_resolution_clock::now(); elapsed = std::chrono::duration_cast(time2-time1); - std::cout << "Time for export_shape: " << elapsed.count() * 1e-9 << std::endl; + std::cout << "Time for exportShape: " << elapsed.count() * 1e-9 << std::endl; //Writing hypo netgen_params aParams; - FillParameters(_hypParameters, aParams); + fillParameters(_hypParameters, aParams); - export_netgen_params(param_file.string(), aParams); + exportNetgenParams(param_file.string(), aParams); auto time3 = std::chrono::high_resolution_clock::now(); elapsed = std::chrono::duration_cast(time3-time2); std::cout << "Time for fill+export param: " << elapsed.count() * 1e-9 << std::endl; @@ -338,7 +339,7 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, exportElementOrientation(aMesh, aShape, aParams, element_orientation_file.string()); auto time4 = std::chrono::high_resolution_clock::now(); elapsed = std::chrono::duration_cast(time4-time3); - std::cout << "Time for exportElemnOrient: " << elapsed.count() * 1e-9 << std::endl; + std::cout << "Time for exportElemOrient: " << elapsed.count() * 1e-9 << std::endl; aMesh.Unlock(); // Calling run_mesher @@ -348,7 +349,7 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, fs::path(std::getenv("NETGENPLUGIN_ROOT_DIR"))/ fs::path("bin")/ fs::path("salome")/ - fs::path("run_mesher"); + fs::path("NETGENPlugin_Runner"); cmd = run_mesher_exe.string() + " NETGEN3D " + mesh_file.string() + " " + shape_file.string() + " " @@ -356,8 +357,7 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, + element_orientation_file.string() + " " + std::to_string(aMesh.GetMesherNbThreads()) + " " + new_element_file.string() + " " - + std::to_string(0) + " " - + output_mesh_file.string() + + + "NONE" + " >> " + log_file.string(); //std::cout << "Running command: " << std::endl; diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx index bff3634..0fa04a0 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx @@ -31,7 +31,6 @@ #ifndef _NETGENPlugin_NETGEN_3D_HXX_ #define _NETGENPlugin_NETGEN_3D_HXX_ -#include "NETGENPlugin_Provider.hxx" #include "NETGENPlugin_Defs.hxx" #include "NETGENPlugin_Mesher.hxx" @@ -75,7 +74,7 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D: public SMESH_3D_Algo netgen_params& aParams, const std::string output_file); - void FillParameters(const NETGENPlugin_Hypothesis* hyp, + void fillParameters(const NETGENPlugin_Hypothesis* hyp, netgen_params &aParams); int RemoteCompute(SMESH_Mesh& aMesh, diff --git a/src/NETGENPlugin/NETGENPlugin_Provider.hxx b/src/NETGENPlugin/NETGENPlugin_Provider.hxx deleted file mode 100644 index d262789..0000000 --- a/src/NETGENPlugin/NETGENPlugin_Provider.hxx +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : NETGENPlugin_Provider.hxx -// Author : Yoann AUDOUIN (EDF) -// Project : SALOME -// -#ifndef _NETGENPlugin_Provider_HXX_ -#define _NETGENPlugin_Provider_HXX_ - -#include -#include -#include -#include -#include -#include - -namespace nglib { -#include -} -#ifndef OCCGEOMETRY -#define OCCGEOMETRY -#endif -#include -#include - -template -class ProviderPtr{ - public: - - ProviderPtr(){ - for(int i=0;i_mydata[i] = nullptr; - this->_useddata[i] = false; - } - } - - int take(T** data){ - - this->_mymutex.lock(); - *data = nullptr; - for(int i=0;i_useddata[i]){ - if (this->_mydata[i] == nullptr) - this->_mydata[i] = new T(); - this->_useddata[i] = true; - *data = this->_mydata[i]; - this->_mymutex.unlock(); - return i; - } - } - this->_mymutex.unlock(); - return -1; - }; - - - bool release(int i, bool clean){ - - this->_mymutex.lock(); - - if(clean){ - delete this->_mydata[i]; - this->_mydata[i] = nullptr; - } - - this->_useddata[i] = false; - - this->_mymutex.unlock(); - - return true; - }; - - void dump(){ - std::cout << "Dumping provider:" << std::endl; - for(int i=0;i_useddata[i] << std::endl; - std::cout << " - adress: " << this->_mydata[i] << std::endl; - if (this->_mydata[i] != nullptr) - std::cout << " - i: " << this->_mydata[i]->i << " d: " << this->_mydata[i]->d << std::endl; - } - }; - - private: - std::array _mydata; - std::array _useddata; - std::mutex _mymutex; - -}; - -template -class Provider{ - public: - - Provider() = default; - - int take(T& data){ - - this->_mymutex.lock(); - for(int i=0;i_useddata[i]){ - this->_useddata[i] = true; - data = this->_mydata[i]; - this->_mymutex.unlock(); - return i; - } - } - this->_mymutex.unlock(); - return -1; - }; - - - bool release(int i){ - - this->_mymutex.lock(); - this->_useddata[i] = false; - this->_mymutex.unlock(); - - return true; - }; - - void dump(){ - std::cout << "Dumping provider:" << std::endl; - for(int i=0;i_useddata[i] << std::endl; - std::cout << " - i: " << this->_mydata[i].i << " d: " << this->_mydata[i].d << std::endl; - } - }; - - private: - std::array _mydata; - std::array _useddata; - std::mutex _mymutex; - -}; - -#endif \ No newline at end of file diff --git a/src/NETGENPlugin/NETGENPlugin_Runner.cxx b/src/NETGENPlugin/NETGENPlugin_Runner.cxx new file mode 100644 index 0000000..e69dcd5 --- /dev/null +++ b/src/NETGENPlugin/NETGENPlugin_Runner.cxx @@ -0,0 +1,1051 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : NETGENPlugin_Runner.cxx +// Author : Yoann AUDOUIN, EDF +// Module : SMESH +// + +#include "NETGENPlugin_Runner.hxx" + + +#include "NETGENPlugin_DriverParam.hxx" + +#include +#include +#include +namespace fs = boost::filesystem; +#include + +// SMESH include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +// NETGENPlugin +// #include +// #include +#include "NETGENPlugin_Mesher.hxx" +#include "NETGENPlugin_Hypothesis.hxx" + + +// OCC include +#include +#include +#include +#include + +#include +#include +/* + Netgen include files +*/ + +#ifndef OCCGEOMETRY +#define OCCGEOMETRY +#endif +#include +#include + +#ifdef NETGEN_V5 +#include +#endif +#ifdef NETGEN_V6 +#include +#endif + +namespace nglib { +#include +} +namespace netgen { + + NETGENPLUGIN_DLL_HEADER + extern MeshingParameters mparam; + + NETGENPLUGIN_DLL_HEADER + extern volatile multithreadt multithread; + + NETGENPLUGIN_DLL_HEADER + extern bool merge_solids; + +#ifdef NETGEN_V5 + extern void OCCSetLocalMeshSize(OCCGeometry & geom, Mesh & mesh); +#endif +} +using namespace nglib; + +int error(int error_type, std::string msg) +{ + std::cerr << msg << std::endl; + return error_type; +}; + +int error(const SMESH_Comment& comment) +{ + return error(1, "SMESH_Comment error: "+comment); +}; + +/** + * @brief Set the netgen parameters + * + * @param aParams Internal structure of parameters + * @param mparams Netgen strcuture of parameters + */ +void set_netgen_parameters(netgen_params& aParams) +{ + + // Default parameters +#ifdef NETGEN_V6 + + //netgen::mparam.nthreads = std::thread::hardware_concurrency(); + netgen::mparam.nthreads = aParams.nbThreads; + netgen::mparam.parallel_meshing = aParams.nbThreads > 1; + + + if ( getenv( "SALOME_NETGEN_DISABLE_MULTITHREADING" )) + { + netgen::mparam.nthreads = 1; + netgen::mparam.parallel_meshing = false; + } + +#endif + + // Initialize global NETGEN parameters: + netgen::mparam.maxh = aParams.maxh; + netgen::mparam.minh = aParams.minh; + netgen::mparam.segmentsperedge = aParams.segmentsperedge; + netgen::mparam.grading = aParams.grading; + netgen::mparam.curvaturesafety = aParams.curvaturesafety; + netgen::mparam.secondorder = aParams.secondorder; + netgen::mparam.quad = aParams.quad; + netgen::mparam.uselocalh = aParams.uselocalh; + netgen::merge_solids = aParams.merge_solids; + netgen::mparam.optsteps2d = aParams.optsteps2d; + netgen::mparam.optsteps3d = aParams.optsteps3d; + netgen::mparam.elsizeweight = aParams.elsizeweight; + netgen::mparam.opterrpow = aParams.opterrpow; + netgen::mparam.delaunay = aParams.delaunay; + netgen::mparam.checkoverlap = aParams.checkoverlap; + netgen::mparam.checkchartboundary = aParams.checkchartboundary; +#ifdef NETGEN_V6 + // std::string + netgen::mparam.meshsizefilename = aParams.meshsizefilename; + netgen::mparam.closeedgefac = aParams.closeedgefac; + +#else + // const char* + netgen::mparam.meshsizefilename= aParams.meshsizefilename.empty() ? 0 : aParams.meshsizefilename.c_str(); +#endif +} + +/** + * @brief compute mesh with netgen3d + * + * @param input_mesh_file Input Mesh file + * @param shape_file Shape file + * @param hypo_file Parameter file + * @param new_element_file Binary file containing new nodes and new element info + * @param output_mesh If true will export mesh into output_mesh_file + * @param output_mesh_file Output Mesh file + * + * @return error code + */ +int netgen3d(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) +{ + auto time0 = std::chrono::high_resolution_clock::now(); + // Importing mesh + SMESH_Gen gen; + + SMESH_Mesh *myMesh = gen.CreateMesh(false); + //TODO: To define + std::string mesh_name = "Maillage_1"; + + importMesh(input_mesh_file, *myMesh, mesh_name); + auto time1 = std::chrono::high_resolution_clock::now(); + auto elapsed = std::chrono::duration_cast(time1-time0); + std::cout << "Time for importMesh: " << elapsed.count() * 1e-9 << std::endl; + + // Importing shape + TopoDS_Shape myShape; + importShape(shape_file, myShape); + auto time2 = std::chrono::high_resolution_clock::now(); + elapsed = std::chrono::duration_cast(time2-time1); + std::cout << "Time for importShape: " << elapsed.count() * 1e-9 << std::endl; + + // Importing hypothesis + netgen_params myParams; + + importNetgenParams(hypo_file, myParams); + auto time3 = std::chrono::high_resolution_clock::now(); + elapsed = std::chrono::duration_cast(time3-time2); + std::cout << "Time for import_netgen_param: " << elapsed.count() * 1e-9 << std::endl; + // Setting number of threads for netgen + myParams.nbThreads = nbThreads; + + std::cout << "Meshing with netgen3d" << std::endl; + int ret = netgen3dInternal(myShape, *myMesh, myParams, + new_element_file, element_orientation_file, + !output_mesh_file.empty()); + + + if(!ret){ + std::cout << "Meshing failed" << std::endl; + return ret; + } + + if(!output_mesh_file.empty()){ + auto time4 = std::chrono::high_resolution_clock::now(); + exportMesh(output_mesh_file, *myMesh, mesh_name); + auto time5 = std::chrono::high_resolution_clock::now(); + elapsed = std::chrono::duration_cast(time5-time4); + std::cout << "Time for exportMesh: " << elapsed.count() * 1e-9 << std::endl; + } + + return ret; +} + +/** + * @brief Compute aShape within aMesh using netgen3d + * + * @param aShape the shape + * @param aMesh the mesh + * @param aParams the netgen parameters + * @param new_element_file file containing data on the new point/tetra added by netgen + * @param element_orientation_file file containing data on the orientation of each element to add to netgen + * @param output_mesh if true add element created by netgen into aMesh + * + * @return error code + */ +int netgen3dInternal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, + std::string new_element_file, std::string element_orientation_file, + bool output_mesh) +{ + + auto time0 = std::chrono::high_resolution_clock::now(); + + netgen::multithread.terminate = 0; + netgen::multithread.task = "Volume meshing"; + + SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); + + SMESH_MesherHelper helper(aMesh); + aParams._quadraticMesh = helper.IsQuadraticSubMesh(aShape); + helper.SetElementsOnShape( true ); + + int Netgen_NbOfNodes = 0; + double Netgen_point[3]; + int Netgen_triangle[3]; + + NETGENPlugin_NetgenLibWrapper ngLib; + Ng_Mesh * Netgen_mesh = (Ng_Mesh*)ngLib._ngMesh; + + // vector of nodes in which node index == netgen ID + vector< const SMDS_MeshNode* > nodeVec; + { + const int invalid_ID = -1; + + SMESH::Controls::Area areaControl; + SMESH::Controls::TSequenceOfXYZ nodesCoords; + + // maps nodes to ng ID + typedef map< const SMDS_MeshNode*, int, TIDCompare > TNodeToIDMap; + typedef TNodeToIDMap::value_type TN2ID; + TNodeToIDMap nodeToNetgenID; + + // find internal shapes + NETGENPlugin_Internals internals( aMesh, aShape, /*is3D=*/true ); + + // --------------------------------- + // Feed the Netgen with surface mesh + // --------------------------------- + + TopAbs_ShapeEnum mainType = aMesh.GetShapeToMesh().ShapeType(); + bool checkReverse = ( mainType == TopAbs_COMPOUND || mainType == TopAbs_COMPSOLID ); + + SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( aMesh )); + if ( aParams._viscousLayersHyp ) + { + netgen::multithread.percent = 3; + proxyMesh = aParams._viscousLayersHyp->Compute( aMesh, aShape ); + if ( !proxyMesh ) + return false; + } + if ( aMesh.NbQuadrangles() > 0 ) + { + netgen::multithread.percent = 6; + StdMeshers_QuadToTriaAdaptor* Adaptor = new StdMeshers_QuadToTriaAdaptor; + Adaptor->Compute(aMesh,aShape,proxyMesh.get()); + proxyMesh.reset( Adaptor ); + } + + // Get list of elements + their orientation from element_orientation file + std::map elemOrientation; + { + // Setting all element orientation to false if there no element orientation file + if(element_orientation_file.empty()){ + SMDS_ElemIteratorPtr iteratorElem = meshDS->elementsIterator(SMDSAbs_Face); + while ( iteratorElem->more() ) // loop on elements on a geom face + { + // check mesh face + const SMDS_MeshElement* elem = iteratorElem->next(); + elemOrientation[elem->GetID()] = false; + } + } else { + std::ifstream df(element_orientation_file, ios::binary|ios::in); + int nbElement; + bool orient; + + // Warning of the use of vtkIdType (I had issue when run_mesher was compiled with internal vtk) and salome not + // Sizeof was the same but how he othered the type was different + // Maybe using another type (uint64_t) instead would be better + vtkIdType id; + df.read((char*)&nbElement, sizeof(int)); + + for(int ielem=0;ielemelementsIterator(SMDSAbs_Face); + bool isRev; + bool isInternalFace = false; + + bool isIn; + + while ( iteratorElem->more() ) // loop on elements on a geom face + { + // check mesh face + const SMDS_MeshElement* elem = iteratorElem->next(); + if ( !elem ) + return error( COMPERR_BAD_INPUT_MESH, "Null element encounters"); + if ( elem->NbCornerNodes() != 3 ) + 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; + + if(!isIn) + continue; + + // Get orientation + // Netgen requires that all the triangle point outside + isRev = elemOrientation[elem->GetID()]; + + // Add nodes of triangles and triangles them-selves to netgen mesh + + // add three nodes of triangle + bool hasDegen = false; + for ( int iN = 0; iN < 3; ++iN ) + { + const SMDS_MeshNode* node = elem->GetNode( iN ); + const int shapeID = node->getshapeId(); + if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE && + helper.IsDegenShape( shapeID )) + { + // ignore all nodes on degeneraged edge and use node on its vertex instead + TopoDS_Shape vertex = TopoDS_Iterator( meshDS->IndexToShape( shapeID )).Value(); + node = SMESH_Algo::VertexNode( TopoDS::Vertex( vertex ), meshDS ); + hasDegen = true; + } + int& ngID = nodeToNetgenID.insert(TN2ID( node, invalid_ID )).first->second; + if ( ngID == invalid_ID ) + { + ngID = ++Netgen_NbOfNodes; + Netgen_point [ 0 ] = node->X(); + Netgen_point [ 1 ] = node->Y(); + Netgen_point [ 2 ] = node->Z(); + Ng_AddPoint(Netgen_mesh, Netgen_point); + } + + Netgen_triangle[ isRev ? 2-iN : iN ] = ngID; + } + // add triangle + if ( hasDegen && (Netgen_triangle[0] == Netgen_triangle[1] || + Netgen_triangle[0] == Netgen_triangle[2] || + Netgen_triangle[2] == Netgen_triangle[1] )) + continue; + + Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); + + // TODO: Handle that case (quadrangle 2D) (isInternal is set to false) + if ( isInternalFace && !proxyMesh->IsTemporary( elem )) + { + swap( Netgen_triangle[1], Netgen_triangle[2] ); + Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); + } + } + + // insert old nodes into nodeVec + nodeVec.resize( nodeToNetgenID.size() + 1, 0 ); + TNodeToIDMap::iterator n_id = nodeToNetgenID.begin(); + for ( ; n_id != nodeToNetgenID.end(); ++n_id ) + nodeVec[ n_id->second ] = n_id->first; + nodeToNetgenID.clear(); + + // TODO: Handle internal vertex + //if ( internals.hasInternalVertexInSolid() ) + //{ + // netgen::OCCGeometry occgeo; + // NETGENPlugin_Mesher::AddIntVerticesInSolids( occgeo, + // (netgen::Mesh&) *Netgen_mesh, + // nodeVec, + // internals); + //} + } + auto time1 = std::chrono::high_resolution_clock::now(); + auto elapsed = std::chrono::duration_cast(time1-time0); + std::cout << "Time for fill_in_ngmesh: " << elapsed.count() * 1e-9 << std::endl; + + // ------------------------- + // Generate the volume mesh + // ------------------------- + netgen::multithread.terminate = 0; + + netgen::Mesh* ngMesh = ngLib._ngMesh; + Netgen_mesh = ngLib.ngMesh(); + Netgen_NbOfNodes = Ng_GetNP( Netgen_mesh ); + + + int startWith = netgen::MESHCONST_MESHVOLUME; + int endWith = netgen::MESHCONST_OPTVOLUME; + int err = 1; + + NETGENPlugin_Mesher aMesher( &aMesh, helper.GetSubShape(), /*isVolume=*/true ); + netgen::OCCGeometry occgeo; + set_netgen_parameters(aParams); + + if ( aParams.has_netgen_param ) + { + if ( aParams.has_local_size) + { + if ( ! &ngMesh->LocalHFunction() ) + { + netgen::Point3d pmin, pmax; + ngMesh->GetBox( pmin, pmax, 0 ); + ngMesh->SetLocalH( pmin, pmax, aParams.grading ); + } + aMesher.SetLocalSize( occgeo, *ngMesh ); + + try { + ngMesh->LoadLocalMeshSize( netgen::mparam.meshsizefilename ); + } catch (netgen::NgException & ex) { + return error( COMPERR_BAD_PARMETERS, ex.What() ); + } + } + if ( !aParams.optimize ) + endWith = netgen::MESHCONST_MESHVOLUME; + } + else if ( aParams.has_maxelementvolume_hyp ) + { + netgen::mparam.maxh = pow( 72, 1/6. ) * pow( aParams.maxElementVolume, 1/3. ); + // limitVolumeSize( ngMesh, netgen::mparam.maxh ); // result is unpredictable + } + else if ( aMesh.HasShapeToMesh() ) + { + aMesher.PrepareOCCgeometry( occgeo, helper.GetSubShape(), aMesh ); + netgen::mparam.maxh = occgeo.GetBoundingBox().Diam()/2; + } + else + { + netgen::Point3d pmin, pmax; + ngMesh->GetBox (pmin, pmax); + netgen::mparam.maxh = Dist(pmin, pmax)/2; + } + + if ( !aParams.has_netgen_param && aMesh.HasShapeToMesh() ) + { + netgen::mparam.minh = aMesher.GetDefaultMinSize( helper.GetSubShape(), netgen::mparam.maxh ); + } + + try + { + OCC_CATCH_SIGNALS; + + ngLib.CalcLocalH(ngMesh); + err = ngLib.GenerateMesh(occgeo, startWith, endWith, ngMesh); + + if(netgen::multithread.terminate) + return false; + if ( err ) + return error(SMESH_Comment("Error in netgen::OCCGenerateMesh() at ") << netgen::multithread.task); + } + catch (Standard_Failure& ex) + { + SMESH_Comment str("Exception in netgen::OCCGenerateMesh()"); + str << " at " << netgen::multithread.task + << ": " << ex.DynamicType()->Name(); + if ( ex.GetMessageString() && strlen( ex.GetMessageString() )) + str << ": " << ex.GetMessageString(); + return error(str); + } + catch (netgen::NgException& exc) + { + SMESH_Comment str("NgException"); + if ( strlen( netgen::multithread.task ) > 0 ) + str << " at " << netgen::multithread.task; + str << ": " << exc.What(); + return error(str); + } + catch (...) + { + SMESH_Comment str("Exception in netgen::OCCGenerateMesh()"); + if ( strlen( netgen::multithread.task ) > 0 ) + str << " at " << netgen::multithread.task; + return error(str); + } + + int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh); + int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh); + + // ------------------------------------------------------------------- + // Feed back the SMESHDS with the generated Nodes and Volume Elements + // ------------------------------------------------------------------- + + if ( err ) + { + SMESH_ComputeErrorPtr ce = NETGENPlugin_Mesher::ReadErrors(nodeVec); + if ( ce && ce->HasBadElems() ) + return error( ce ); + } + auto time2 = std::chrono::high_resolution_clock::now(); + elapsed = std::chrono::duration_cast(time2-time1); + std::cout << "Time for netgen_compute: " << elapsed.count() * 1e-9 << std::endl; + + bool isOK = ( /*status == NG_OK &&*/ Netgen_NbOfTetra > 0 );// get whatever built + if ( isOK && !new_element_file.empty() ) + { + std::ofstream df(new_element_file, ios::out|ios::binary); + + double Netgen_point[3]; + int Netgen_tetrahedron[4]; + + // Writing nodevec (correspondence netgen numbering mesh numbering) + // Number of nodes + df.write((char*) &Netgen_NbOfNodes, sizeof(int)); + df.write((char*) &Netgen_NbOfNodesNew, sizeof(int)); + for (int nodeIndex = 1 ; nodeIndex <= Netgen_NbOfNodes; ++nodeIndex ) + { + //Id of the point + int id = nodeVec.at(nodeIndex)->GetID(); + df.write((char*) &id, sizeof(int)); + } + + // Writing info on new points + for (int nodeIndex = Netgen_NbOfNodes +1 ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) + { + Ng_GetPoint(Netgen_mesh, nodeIndex, Netgen_point ); + // Coordinates of the point + df.write((char *) &Netgen_point, sizeof(double)*3); + } + + // create tetrahedrons + df.write((char*) &Netgen_NbOfTetra, sizeof(int)); + for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) + { + Ng_GetVolumeElement(Netgen_mesh, elemIndex, Netgen_tetrahedron); + df.write((char*) &Netgen_tetrahedron, sizeof(int)*4); + } + } + auto time3 = std::chrono::high_resolution_clock::now(); + elapsed = std::chrono::duration_cast(time3-time2); + std::cout << "Time for write_new_elem: " << elapsed.count() * 1e-9 << std::endl; + + + // Adding new elements in aMesh as well + if ( output_mesh ) + { + double Netgen_point[3]; + int Netgen_tetrahedron[4]; + + // create and insert new nodes into nodeVec + nodeVec.resize( Netgen_NbOfNodesNew + 1, 0 ); + int nodeIndex = Netgen_NbOfNodes + 1; + for ( ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) + { + Ng_GetPoint( Netgen_mesh, nodeIndex, Netgen_point ); + nodeVec.at(nodeIndex) = helper.AddNode(Netgen_point[0], + Netgen_point[1], + Netgen_point[2]); + } + + // create tetrahedrons + for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) + { + Ng_GetVolumeElement(Netgen_mesh, elemIndex, Netgen_tetrahedron); + try + { + helper.AddVolume (nodeVec.at( Netgen_tetrahedron[0] ), + nodeVec.at( Netgen_tetrahedron[1] ), + nodeVec.at( Netgen_tetrahedron[2] ), + nodeVec.at( Netgen_tetrahedron[3] )); + } + catch (...) + { + } + } + auto time4 = std::chrono::high_resolution_clock::now(); + elapsed = std::chrono::duration_cast(time4-time3); + std::cout << "Time for add_element_to_smesh: " << elapsed.count() * 1e-9 << std::endl; + + } + + return !err; +} + +/** + * @brief compute mesh with netgen2d + * + * @param input_mesh_file Input Mesh file + * @param shape_file Shape file + * @param hypo_file Parameter file + * @param new_element_file Binary file containing new nodes and new element info + * @param output_mesh If true will export mesh into output_mesh_file + * @param output_mesh_file Output Mesh file + * + * @return error code + */ +int netgen2d(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) +{ + + // Importing mesh + SMESH_Gen gen; + + SMESH_Mesh *myMesh = gen.CreateMesh(false); + //TODO: To define + std::string mesh_name = "Maillage_1"; + + importMesh(input_mesh_file, *myMesh, mesh_name); + + // Importing shape + TopoDS_Shape myShape; + importShape(shape_file, myShape); + + // Importing hypothesis + netgen_params myParams; + + importNetgenParams(hypo_file, myParams); + + std::cout << "Meshing with netgen3d" << std::endl; + int ret = netgen2dInternal(myShape, *myMesh, myParams, + new_element_file, element_orientation_file, + !output_mesh_file.empty()); + + if(!ret){ + std::cout << "Meshing failed" << std::endl; + return ret; + } + + if(!output_mesh_file.empty()) + exportMesh(output_mesh_file, *myMesh, mesh_name); + + return ret; +} + + +// TODO: Not working properly +/** + * @brief Compute aShape within aMesh using netgen2d + * + * @param aShape the shape + * @param aMesh the mesh + * @param aParams the netgen parameters + * @param new_element_file file containing data on the new point/tetra added by netgen + * + * @return error code + */ +int netgen2dInternal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, + std::string new_element_file, std::string element_orientation_file, + bool output_mesh) +{ + netgen::multithread.terminate = 0; + netgen::multithread.task = "Surface meshing"; + + SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); + SMESH_MesherHelper helper(aMesh); + helper.SetElementsOnShape( true ); + + NETGENPlugin_NetgenLibWrapper ngLib; + ngLib._isComputeOk = false; + + netgen::Mesh ngMeshNoLocSize; + netgen::Mesh * ngMeshes[2] = { (netgen::Mesh*) ngLib._ngMesh, & ngMeshNoLocSize }; + netgen::OCCGeometry occgeoComm; + + std::map elemOrientation; + + typedef map< const SMDS_MeshNode*, int, TIDCompare > TNodeToIDMap; + typedef TNodeToIDMap::value_type TN2ID; + const int invalid_ID = -1; + int Netgen_NbOfNodes=0; + double Netgen_point[3]; + int Netgen_segment[2]; + int Netgen_triangle[3]; + + // min / max sizes are set as follows: + // if ( _hypParameters ) + // min and max are defined by the user + // else if ( aParams.has_LengthFromEdges_hyp ) + // min = aMesher.GetDefaultMinSize() + // max = average segment len of a FACE + // else if ( _hypMaxElementArea ) + // min = aMesher.GetDefaultMinSize() + // max = f( _hypMaxElementArea ) + // else + // min = aMesher.GetDefaultMinSize() + // max = max segment len of a FACE + NETGENPlugin_Mesher aMesher( &aMesh, aShape, /*isVolume=*/false); + set_netgen_parameters( aParams ); + const bool toOptimize = aParams.optimize; + if ( aParams.has_maxelementvolume_hyp ) + { + netgen::mparam.maxh = sqrt( 2. * aParams.maxElementVolume / sqrt(3.0) ); + } + netgen::mparam.quad = aParams.quad; + + // local size is common for all FACEs in aShape? + const bool isCommonLocalSize = ( !aParams.has_LengthFromEdges_hyp && !aParams.has_maxelementvolume_hyp && netgen::mparam.uselocalh ); + const bool isDefaultHyp = ( !aParams.has_LengthFromEdges_hyp && !aParams.has_maxelementvolume_hyp && !aParams.has_netgen_param ); + + + 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 ); + + // local size set at MESHCONST_ANALYSE step depends on + // minh, face_maxh, grading and curvaturesafety; find minh if not set by the user + if ( !aParams.has_netgen_param || netgen::mparam.minh < DBL_MIN ) + { + if ( !aParams.has_netgen_param ) + 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 + const double factor = 2; //netgen::occparam.resthcloseedgefac; +#else + const double factor = netgen::occparam.resthcloseedgefac; + netgen::occparam.resthcloseedgeenable = false; + netgen::occparam.resthcloseedgefac = 1.0 + netgen::mparam.grading; +#endif + occgeoComm.face_maxh = netgen::mparam.maxh; +#ifdef NETGEN_V6 + netgen::OCCParameters occparam; + netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0], netgen::mparam, occparam ); +#else + netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0] ); +#endif + occgeoComm.emap.Clear(); + occgeoComm.vmap.Clear(); + + // Reading list of element to integrate into netgen mesh + { + std::ifstream df(element_orientation_file, ios::in|ios::binary); + int nbElement; + vtkIdType id; + bool orient; + df.read((char*)&nbElement, sizeof(int)); + + for(int ielem=0;ielemelementsIterator(SMDSAbs_Edge); + while ( iteratorElem->more() ) // loop on elements on a geom face + { + const SMDS_MeshElement* seg = iteratorElem->next(); + // Keeping only element that are in the element orientation file + isIn = elemOrientation.count(seg->GetID())==1; + + if(!isIn) + continue; + + SMESH_TNodeXYZ n1 = seg->GetNode(0); + SMESH_TNodeXYZ n2 = seg->GetNode(1); + gp_XYZ p = 0.5 * ( n1 + n2 ); + netgen::Point3d pi(p.X(), p.Y(), p.Z()); + ngMeshes[0]->RestrictLocalH( pi, factor * ( n1 - n2 ).Modulus() ); + } + + // set local size defined on shapes + aMesher.SetLocalSize( occgeoComm, *ngMeshes[0] ); + aMesher.SetLocalSizeForChordalError( occgeoComm, *ngMeshes[0] ); + try { + ngMeshes[0]->LoadLocalMeshSize( netgen::mparam.meshsizefilename ); + } catch (netgen::NgException & ex) { + return error( COMPERR_BAD_PARMETERS, ex.What() ); + } + } + netgen::mparam.uselocalh = toOptimize; // restore as it is used at surface optimization + // ================== + // Loop on all FACEs + // ================== + + vector< const SMDS_MeshNode* > nodeVec; + + // prepare occgeom + netgen::OCCGeometry occgeom; + occgeom.shape = aShape; + occgeom.fmap.Add( aShape ); + 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 + // ------------------------- + // maps nodes to ng ID + + + // MESHCONST_ANALYSE step may lead to a failure, so we make an attempt + // w/o MESHCONST_ANALYSE at the second loop + int err = 0; + enum { LOC_SIZE, NO_LOC_SIZE }; + int iLoop = isCommonLocalSize ? 0 : 1; + int faceID = occgeom.fmap.FindIndex(aShape); + int solidID = 0; + for ( ; iLoop < 2; iLoop++ ) + { + //bool isMESHCONST_ANALYSE = false; + //TODO: check how to replace that + //InitComputeError(); + + netgen::Mesh * ngMesh = ngMeshes[ iLoop ]; + ngMesh->DeleteMesh(); + + if ( iLoop == NO_LOC_SIZE ) + { + ngMesh->SetGlobalH ( netgen::mparam.maxh ); + ngMesh->SetMinimalH( netgen::mparam.minh ); + netgen::Box<3> bb = occgeom.GetBoundingBox(); + bb.Increase (bb.Diam()/10); + ngMesh->SetLocalH (bb.PMin(), bb.PMax(), netgen::mparam.grading); + aMesher.SetLocalSize( occgeom, *ngMesh ); + aMesher.SetLocalSizeForChordalError( occgeoComm, *ngMesh ); + try { + ngMesh->LoadLocalMeshSize( netgen::mparam.meshsizefilename ); + } catch (netgen::NgException & ex) { + return error( COMPERR_BAD_PARMETERS, ex.What() ); + } + } + + TNodeToIDMap nodeToNetgenID; + + nodeVec.clear(); + ngMesh->AddFaceDescriptor( netgen::FaceDescriptor( faceID, solidID, solidID, 0 )); + // set local size according to size of existing segments + SMDS_ElemIteratorPtr iteratorElem = meshDS->elementsIterator(SMDSAbs_Edge); + while ( iteratorElem->more() ) // loop on elements on a geom face + { + const SMDS_MeshElement* elem = iteratorElem->next(); + // Keeping only element that are in the element orientation file + bool isIn = elemOrientation.count(elem->GetID())==1; + + if(!isIn) + continue; + + bool isRev = elemOrientation[elem->GetID()]; + std::cerr << isRev; + + + + for ( int iN = 0; iN < 2; ++iN ) + { + const SMDS_MeshNode* node = elem->GetNode( iN ); + const int shapeID = node->getshapeId(); + int& ngID = nodeToNetgenID.insert(TN2ID( node, invalid_ID )).first->second; + if ( ngID == invalid_ID ) + { + ngID = ++Netgen_NbOfNodes; + Netgen_point [ 0 ] = node->X(); + Netgen_point [ 1 ] = node->Y(); + Netgen_point [ 2 ] = node->Z(); + netgen::MeshPoint mp( netgen::Point<3> (node->X(), node->Y(), node->Z()) ); + ngMesh->AddPoint ( mp, 1, netgen::EDGEPOINT ); + } + Netgen_segment[ isRev ? 1-iN : iN ] = ngID; + } + // add segment + + netgen::Segment seg; + seg[0] = Netgen_segment[0]; + seg[1] = Netgen_segment[1]; + seg.edgenr = ngMesh->GetNSeg() +1; + seg.si = faceID; + + ngMesh->AddSegment(seg); + } + int nbNodes2 = ngMesh->GetNP(); + int nseg = ngMesh->GetNSeg(); + + // insert old nodes into nodeVec + nodeVec.resize( nodeToNetgenID.size() + 1, 0 ); + TNodeToIDMap::iterator n_id = nodeToNetgenID.begin(); + for ( ; n_id != nodeToNetgenID.end(); ++n_id ) + nodeVec[ n_id->second ] = n_id->first; + nodeToNetgenID.clear(); + + + //if ( !isCommonLocalSize ) + //limitSize( ngMesh, mparam.maxh * 0.8); + + // ------------------------- + // Generate surface mesh + // ------------------------- + + const int startWith = netgen::MESHCONST_MESHSURFACE; + const int endWith = toOptimize ? netgen::MESHCONST_OPTSURFACE : netgen::MESHCONST_MESHSURFACE; + + SMESH_Comment str; + try { + OCC_CATCH_SIGNALS; + err = ngLib.GenerateMesh(occgeom, startWith, endWith, ngMesh); + if ( netgen::multithread.terminate ) + return false; + if ( err ) + str << "Error in netgen::OCCGenerateMesh() at " << netgen::multithread.task; + } + catch (Standard_Failure& ex) + { + err = 1; + str << "Exception in netgen::OCCGenerateMesh()" + << " at " << netgen::multithread.task + << ": " << ex.DynamicType()->Name(); + if ( ex.GetMessageString() && strlen( ex.GetMessageString() )) + str << ": " << ex.GetMessageString(); + } + catch (...) { + err = 1; + str << "Exception in netgen::OCCGenerateMesh()" + << " at " << netgen::multithread.task; + } + if ( err ) + { + if ( iLoop == LOC_SIZE ) + { + std::cout << "Need second run" << std::endl; + /*netgen::mparam.minh = netgen::mparam.maxh; + netgen::mparam.maxh = 0; + for ( size_t iW = 0; iW < wires.size(); ++iW ) + { + StdMeshers_FaceSidePtr wire = wires[ iW ]; + const vector& uvPtVec = wire->GetUVPtStruct(); + for ( size_t iP = 1; iP < uvPtVec.size(); ++iP ) + { + SMESH_TNodeXYZ p( uvPtVec[ iP ].node ); + netgen::Point3d np( p.X(),p.Y(),p.Z()); + double segLen = p.Distance( uvPtVec[ iP-1 ].node ); + double size = ngMesh->GetH( np ); + netgen::mparam.minh = Min( netgen::mparam.minh, size ); + netgen::mparam.maxh = Max( netgen::mparam.maxh, segLen ); + } + } + //cerr << "min " << mparam.minh << " max " << mparam.maxh << endl; + netgen::mparam.minh *= 0.9; + netgen::mparam.maxh *= 1.1; + */ + continue; + } + else + { + //faceErr.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED, str )); + } + } + + // ---------------------------------------------------- + // Fill the SMESHDS with the generated nodes and faces + // ---------------------------------------------------- + + if(output_mesh) + { + int nbNodes = ngMesh->GetNP(); + int nbFaces = ngMesh->GetNSE(); + std::cout << nbFaces << " " << nbNodes << std::endl; + + int nbInputNodes = (int) nodeVec.size()-1; + nodeVec.resize( nbNodes+1, 0 ); + + // add nodes + for ( int ngID = nbInputNodes + 1; ngID <= nbNodes; ++ngID ) + { + const netgen::MeshPoint& ngPoint = ngMesh->Point( ngID ); + SMDS_MeshNode * node = meshDS->AddNode(ngPoint(0), ngPoint(1), ngPoint(2)); + nodeVec[ ngID ] = node; + } + + // create faces + int i,j; + for ( i = 1; i <= nbFaces ; ++i ) + { + Ng_GetVolumeElement(ngLib.ngMesh(), i, Netgen_triangle); + + helper.AddFace (nodeVec.at( Netgen_triangle[0] ), + nodeVec.at( Netgen_triangle[1] ), + nodeVec.at( Netgen_triangle[2] )); + + } + } // output_mesh + + break; + } // two attempts + //} // loop on FACEs + + return true; + +} diff --git a/src/NETGENPlugin/NETGENPlugin_Runner.hxx b/src/NETGENPlugin/NETGENPlugin_Runner.hxx new file mode 100644 index 0000000..fe4d6c9 --- /dev/null +++ b/src/NETGENPlugin/NETGENPlugin_Runner.hxx @@ -0,0 +1,70 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : NETGENPlugin_Runner.hxx +// Author : Yoann AUDOUIN, EDF +// Module : NETGEN +// + +#ifndef _NETGENPLUGIN_RUNNER_HXX_ +#define _NETGENPLUGIN_RUNNER_HXX_ + +#include +#include + +class TopoDS_Shape; +class SMESH_Mesh; +class SMESH_Comment; +class netgen_params; + +int netgen2dInternal(TopoDS_Shape &aShape, + SMESH_Mesh& aMesh, + netgen_params& aParams, + std::string new_element_file, + std::string element_orientation_file, + bool output_mesh); +int netgen2d(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 netgen3dInternal(TopoDS_Shape &aShape, + SMESH_Mesh& aMesh, + netgen_params& aParams, + std::string new_element_file, + std::string element_orientation_file, + bool output_mesh); +int netgen3d(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); + +//TODO: Tmp function replace by real error handling +int error(int error_type, std::string msg); +int error(const SMESH_Comment& comment); + +#endif \ No newline at end of file diff --git a/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx b/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx new file mode 100644 index 0000000..709e118 --- /dev/null +++ b/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx @@ -0,0 +1,105 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : NETGENplugin_Runnner_main.cxx +// Author : Yoann AUDOUIN, EDF +// Module : NETGEN +// + + +#include "NETGENPlugin_Runner.hxx" + +#include +#include +#include +#include + +/** + * @brief Main function + * + * @param argc Number of arguments + * @param argv Arguments + * + * @return error code + */ +int main(int argc, char *argv[]){ + + if(argc!=9||(argc==2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help")==0))){ + std::cout << "Error in number of arguments "<< argc<<" given expected 8" <(end - begin); + std::cout << "Time elapsed: " << elapsed.count()*1e-9 << std::endl; + } else if (mesher=="NETGEN2D"){ + netgen2d(input_mesh_file, + shape_file, + hypo_file, + element_orientation_file, + new_element_file, + output_mesh_file); + } else { + std::cerr << "Unknown mesher:" << mesher << std::endl; + } + return 0; +} diff --git a/src/NETGENPlugin/netgen_mesher.cxx b/src/NETGENPlugin/netgen_mesher.cxx deleted file mode 100644 index d867f3b..0000000 --- a/src/NETGENPlugin/netgen_mesher.cxx +++ /dev/null @@ -1,1040 +0,0 @@ -// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : netgen_mesher.cxx -// Author : Yoann AUDOUIN, EDF -// Module : SMESH -// - -#include "netgen_mesher.hxx" - -#include "DriverStep.hxx" -#include "DriverMesh.hxx" -#include "netgen_param.hxx" - -#include -#include -#include -namespace fs = std::filesystem; -#include - -// SMESH include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -// NETGENPlugin -// #include -// #include -#include "NETGENPlugin_Mesher.hxx" -#include "NETGENPlugin_Hypothesis.hxx" - - -// OCC include -#include -#include -#include -#include - -#include -#include -/* - Netgen include files -*/ - -#ifndef OCCGEOMETRY -#define OCCGEOMETRY -#endif -#include -#include - -#ifdef NETGEN_V5 -#include -#endif -#ifdef NETGEN_V6 -#include -#endif - -namespace nglib { -#include -} -namespace netgen { - - NETGENPLUGIN_DLL_HEADER - extern MeshingParameters mparam; - - NETGENPLUGIN_DLL_HEADER - extern volatile multithreadt multithread; - - NETGENPLUGIN_DLL_HEADER - extern bool merge_solids; - -#ifdef NETGEN_V5 - extern void OCCSetLocalMeshSize(OCCGeometry & geom, Mesh & mesh); -#endif -} -using namespace nglib; - -int error(int error_type, std::string msg) -{ - std::cerr << msg << std::endl; - return error_type; -}; - -int error(const SMESH_Comment& comment) -{ - return error(1, "SMESH_Comment error: "+comment); -}; - -/** - * @brief Set the netgen parameters - * - * @param aParams Internal structure of parameters - * @param mparams Netgen strcuture of parameters - */ -void set_netgen_parameters(netgen_params& aParams) -{ - - // Default parameters -#ifdef NETGEN_V6 - - //netgen::mparam.nthreads = std::thread::hardware_concurrency(); - netgen::mparam.nthreads = aParams.nbThreads; - netgen::mparam.parallel_meshing = aParams.nbThreads > 1; - - - if ( getenv( "SALOME_NETGEN_DISABLE_MULTITHREADING" )) - { - netgen::mparam.nthreads = 1; - netgen::mparam.parallel_meshing = false; - } - -#endif - - // Initialize global NETGEN parameters: - netgen::mparam.maxh = aParams.maxh; - netgen::mparam.minh = aParams.minh; - netgen::mparam.segmentsperedge = aParams.segmentsperedge; - netgen::mparam.grading = aParams.grading; - netgen::mparam.curvaturesafety = aParams.curvaturesafety; - netgen::mparam.secondorder = aParams.secondorder; - netgen::mparam.quad = aParams.quad; - netgen::mparam.uselocalh = aParams.uselocalh; - netgen::merge_solids = aParams.merge_solids; - netgen::mparam.optsteps2d = aParams.optsteps2d; - netgen::mparam.optsteps3d = aParams.optsteps3d; - netgen::mparam.elsizeweight = aParams.elsizeweight; - netgen::mparam.opterrpow = aParams.opterrpow; - netgen::mparam.delaunay = aParams.delaunay; - netgen::mparam.checkoverlap = aParams.checkoverlap; - netgen::mparam.checkchartboundary = aParams.checkchartboundary; -#ifdef NETGEN_V6 - // std::string - netgen::mparam.meshsizefilename = aParams.meshsizefilename; - netgen::mparam.closeedgefac = aParams.closeedgefac; - -#else - // const char* - netgen::mparam.meshsizefilename= aParams.meshsizefilename.empty() ? 0 : aParams.meshsizefilename.c_str(); -#endif -} - -/** - * @brief compute mesh with netgen3d - * - * @param input_mesh_file Input Mesh file - * @param shape_file Shape file - * @param hypo_file Parameter file - * @param new_element_file Binary file containing new nodes and new element info - * @param output_mesh If true will export mesh into output_mesh_file - * @param output_mesh_file Output Mesh file - * - * @return error code - */ -int netgen3d(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, - bool output_mesh, - const std::string output_mesh_file, - int nbThreads) -{ - auto time0 = std::chrono::high_resolution_clock::now(); - // Importing mesh - SMESH_Gen gen; - - SMESH_Mesh *myMesh = gen.CreateMesh(false); - //TODO: To define - std::string mesh_name = "Maillage_1"; - - import_mesh(input_mesh_file, *myMesh, mesh_name); - auto time1 = std::chrono::high_resolution_clock::now(); - auto elapsed = std::chrono::duration_cast(time1-time0); - std::cout << "Time for import_mesh: " << elapsed.count() * 1e-9 << std::endl; - - // Importing shape - TopoDS_Shape myShape; - import_shape(shape_file, myShape); - auto time2 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time2-time1); - std::cout << "Time for import_shape: " << elapsed.count() * 1e-9 << std::endl; - - // Importing hypothesis - netgen_params myParams; - - import_netgen_params(hypo_file, myParams); - auto time3 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time3-time2); - std::cout << "Time for import_netgen_param: " << elapsed.count() * 1e-9 << std::endl; - // Setting number of threads for netgen - myParams.nbThreads = nbThreads; - - std::cout << "Meshing with netgen3d" << std::endl; - int ret = netgen3d_internal(myShape, *myMesh, myParams, - new_element_file, element_orientation_file, - output_mesh); - - - if(!ret){ - std::cout << "Meshing failed" << std::endl; - return ret; - } - - if(output_mesh){ - auto time4 = std::chrono::high_resolution_clock::now(); - export_mesh(output_mesh_file, *myMesh, mesh_name); - auto time5 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time5-time4); - std::cout << "Time for export_mesh: " << elapsed.count() * 1e-9 << std::endl; - } - - return ret; -} - -/** - * @brief Compute aShape within aMesh using netgen3d - * - * @param aShape the shape - * @param aMesh the mesh - * @param aParams the netgen parameters - * @param new_element_file file containing data on the new point/tetra added by netgen - * - * @return error code - */ -int netgen3d_internal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, - std::string new_element_file, std::string element_orientation_file, - bool output_mesh) -{ - - auto time0 = std::chrono::high_resolution_clock::now(); - - netgen::multithread.terminate = 0; - netgen::multithread.task = "Volume meshing"; - - SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); - - SMESH_MesherHelper helper(aMesh); - aParams._quadraticMesh = helper.IsQuadraticSubMesh(aShape); - helper.SetElementsOnShape( true ); - - int Netgen_NbOfNodes = 0; - double Netgen_point[3]; - int Netgen_triangle[3]; - - NETGENPlugin_NetgenLibWrapper ngLib; - Ng_Mesh * Netgen_mesh = (Ng_Mesh*)ngLib._ngMesh; - - // vector of nodes in which node index == netgen ID - vector< const SMDS_MeshNode* > nodeVec; - { - const int invalid_ID = -1; - - SMESH::Controls::Area areaControl; - SMESH::Controls::TSequenceOfXYZ nodesCoords; - - // maps nodes to ng ID - typedef map< const SMDS_MeshNode*, int, TIDCompare > TNodeToIDMap; - typedef TNodeToIDMap::value_type TN2ID; - TNodeToIDMap nodeToNetgenID; - - // find internal shapes - NETGENPlugin_Internals internals( aMesh, aShape, /*is3D=*/true ); - - // --------------------------------- - // Feed the Netgen with surface mesh - // --------------------------------- - - TopAbs_ShapeEnum mainType = aMesh.GetShapeToMesh().ShapeType(); - bool checkReverse = ( mainType == TopAbs_COMPOUND || mainType == TopAbs_COMPSOLID ); - - SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( aMesh )); - if ( aParams._viscousLayersHyp ) - { - netgen::multithread.percent = 3; - proxyMesh = aParams._viscousLayersHyp->Compute( aMesh, aShape ); - if ( !proxyMesh ) - return false; - } - if ( aMesh.NbQuadrangles() > 0 ) - { - netgen::multithread.percent = 6; - StdMeshers_QuadToTriaAdaptor* Adaptor = new StdMeshers_QuadToTriaAdaptor; - Adaptor->Compute(aMesh,aShape,proxyMesh.get()); - proxyMesh.reset( Adaptor ); - } - - // Get list of elements + their orientation from element_orientation file - std::map elemOrientation; - { - std::ifstream df(element_orientation_file, ios::binary|ios::in); - int nbElement; - bool orient; - - // Warning of the use of vtkIdType (I had issue when run_mesher was compiled with internal vtk) and salome not - // Sizeof was the same but how he othered the type was different - // Maybe using another type (uint64_t) instead would be better - vtkIdType id; - df.read((char*)&nbElement, sizeof(int)); - - for(int ielem=0;ielemelementsIterator(SMDSAbs_Face); - bool isRev; - bool isInternalFace = false; - - bool isIn; - - while ( iteratorElem->more() ) // loop on elements on a geom face - { - // check mesh face - const SMDS_MeshElement* elem = iteratorElem->next(); - if ( !elem ) - return error( COMPERR_BAD_INPUT_MESH, "Null element encounters"); - if ( elem->NbCornerNodes() != 3 ) - 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; - - if(!isIn) - continue; - - - // Get orientation - // Netgen requires that all the triangle point outside - isRev = elemOrientation[elem->GetID()]; - - // Add nodes of triangles and triangles them-selves to netgen mesh - - // add three nodes of triangle - bool hasDegen = false; - for ( int iN = 0; iN < 3; ++iN ) - { - const SMDS_MeshNode* node = elem->GetNode( iN ); - const int shapeID = node->getshapeId(); - if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE && - helper.IsDegenShape( shapeID )) - { - // ignore all nodes on degeneraged edge and use node on its vertex instead - TopoDS_Shape vertex = TopoDS_Iterator( meshDS->IndexToShape( shapeID )).Value(); - node = SMESH_Algo::VertexNode( TopoDS::Vertex( vertex ), meshDS ); - hasDegen = true; - } - int& ngID = nodeToNetgenID.insert(TN2ID( node, invalid_ID )).first->second; - if ( ngID == invalid_ID ) - { - ngID = ++Netgen_NbOfNodes; - Netgen_point [ 0 ] = node->X(); - Netgen_point [ 1 ] = node->Y(); - Netgen_point [ 2 ] = node->Z(); - Ng_AddPoint(Netgen_mesh, Netgen_point); - } - - Netgen_triangle[ isRev ? 2-iN : iN ] = ngID; - } - // add triangle - if ( hasDegen && (Netgen_triangle[0] == Netgen_triangle[1] || - Netgen_triangle[0] == Netgen_triangle[2] || - Netgen_triangle[2] == Netgen_triangle[1] )) - continue; - - Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); - - // TODO: Handle that case (quadrangle 2D) (isInternal is set to false) - if ( isInternalFace && !proxyMesh->IsTemporary( elem )) - { - swap( Netgen_triangle[1], Netgen_triangle[2] ); - Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); - } - } - - // insert old nodes into nodeVec - nodeVec.resize( nodeToNetgenID.size() + 1, 0 ); - TNodeToIDMap::iterator n_id = nodeToNetgenID.begin(); - for ( ; n_id != nodeToNetgenID.end(); ++n_id ) - nodeVec[ n_id->second ] = n_id->first; - nodeToNetgenID.clear(); - - // TODO: Handle internal vertex - //if ( internals.hasInternalVertexInSolid() ) - //{ - // netgen::OCCGeometry occgeo; - // NETGENPlugin_Mesher::AddIntVerticesInSolids( occgeo, - // (netgen::Mesh&) *Netgen_mesh, - // nodeVec, - // internals); - //} - } - auto time1 = std::chrono::high_resolution_clock::now(); - auto elapsed = std::chrono::duration_cast(time1-time0); - std::cout << "Time for fill_in_ngmesh: " << elapsed.count() * 1e-9 << std::endl; - - // ------------------------- - // Generate the volume mesh - // ------------------------- - netgen::multithread.terminate = 0; - - netgen::Mesh* ngMesh = ngLib._ngMesh; - Netgen_mesh = ngLib.ngMesh(); - Netgen_NbOfNodes = Ng_GetNP( Netgen_mesh ); - - - int startWith = netgen::MESHCONST_MESHVOLUME; - int endWith = netgen::MESHCONST_OPTVOLUME; - int err = 1; - - NETGENPlugin_Mesher aMesher( &aMesh, helper.GetSubShape(), /*isVolume=*/true ); - netgen::OCCGeometry occgeo; - set_netgen_parameters(aParams); - - if ( aParams.has_netgen_param ) - { - if ( aParams.has_local_size) - { - if ( ! &ngMesh->LocalHFunction() ) - { - netgen::Point3d pmin, pmax; - ngMesh->GetBox( pmin, pmax, 0 ); - ngMesh->SetLocalH( pmin, pmax, aParams.grading ); - } - aMesher.SetLocalSize( occgeo, *ngMesh ); - - try { - ngMesh->LoadLocalMeshSize( netgen::mparam.meshsizefilename ); - } catch (netgen::NgException & ex) { - return error( COMPERR_BAD_PARMETERS, ex.What() ); - } - } - if ( !aParams.optimize ) - endWith = netgen::MESHCONST_MESHVOLUME; - } - else if ( aParams.has_maxelementvolume_hyp ) - { - netgen::mparam.maxh = pow( 72, 1/6. ) * pow( aParams.maxElementVolume, 1/3. ); - // limitVolumeSize( ngMesh, netgen::mparam.maxh ); // result is unpredictable - } - else if ( aMesh.HasShapeToMesh() ) - { - aMesher.PrepareOCCgeometry( occgeo, helper.GetSubShape(), aMesh ); - netgen::mparam.maxh = occgeo.GetBoundingBox().Diam()/2; - } - else - { - netgen::Point3d pmin, pmax; - ngMesh->GetBox (pmin, pmax); - netgen::mparam.maxh = Dist(pmin, pmax)/2; - } - - if ( !aParams.has_netgen_param && aMesh.HasShapeToMesh() ) - { - netgen::mparam.minh = aMesher.GetDefaultMinSize( helper.GetSubShape(), netgen::mparam.maxh ); - } - - try - { - OCC_CATCH_SIGNALS; - - ngLib.CalcLocalH(ngMesh); - err = ngLib.GenerateMesh(occgeo, startWith, endWith, ngMesh); - - if(netgen::multithread.terminate) - return false; - if ( err ) - return error(SMESH_Comment("Error in netgen::OCCGenerateMesh() at ") << netgen::multithread.task); - } - catch (Standard_Failure& ex) - { - SMESH_Comment str("Exception in netgen::OCCGenerateMesh()"); - str << " at " << netgen::multithread.task - << ": " << ex.DynamicType()->Name(); - if ( ex.GetMessageString() && strlen( ex.GetMessageString() )) - str << ": " << ex.GetMessageString(); - return error(str); - } - catch (netgen::NgException& exc) - { - SMESH_Comment str("NgException"); - if ( strlen( netgen::multithread.task ) > 0 ) - str << " at " << netgen::multithread.task; - str << ": " << exc.What(); - return error(str); - } - catch (...) - { - SMESH_Comment str("Exception in netgen::OCCGenerateMesh()"); - if ( strlen( netgen::multithread.task ) > 0 ) - str << " at " << netgen::multithread.task; - return error(str); - } - - int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh); - int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh); - - // ------------------------------------------------------------------- - // Feed back the SMESHDS with the generated Nodes and Volume Elements - // ------------------------------------------------------------------- - - if ( err ) - { - SMESH_ComputeErrorPtr ce = NETGENPlugin_Mesher::ReadErrors(nodeVec); - if ( ce && ce->HasBadElems() ) - return error( ce ); - } - auto time2 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time2-time1); - std::cout << "Time for netgen_compute: " << elapsed.count() * 1e-9 << std::endl; - - bool isOK = ( /*status == NG_OK &&*/ Netgen_NbOfTetra > 0 );// get whatever built - if ( isOK ) - { - std::ofstream df(new_element_file, ios::out|ios::binary); - - double Netgen_point[3]; - int Netgen_tetrahedron[4]; - - // Writing nodevec (correspondence netgen numbering mesh numbering) - // Number of nodes - df.write((char*) &Netgen_NbOfNodes, sizeof(int)); - df.write((char*) &Netgen_NbOfNodesNew, sizeof(int)); - for (int nodeIndex = 1 ; nodeIndex <= Netgen_NbOfNodes; ++nodeIndex ) - { - //Id of the point - int id = nodeVec.at(nodeIndex)->GetID(); - df.write((char*) &id, sizeof(int)); - } - - // Writing info on new points - for (int nodeIndex = Netgen_NbOfNodes +1 ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) - { - Ng_GetPoint(Netgen_mesh, nodeIndex, Netgen_point ); - // Coordinates of the point - df.write((char *) &Netgen_point, sizeof(double)*3); - } - - // create tetrahedrons - df.write((char*) &Netgen_NbOfTetra, sizeof(int)); - for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) - { - Ng_GetVolumeElement(Netgen_mesh, elemIndex, Netgen_tetrahedron); - df.write((char*) &Netgen_tetrahedron, sizeof(int)*4); - } - } - auto time3 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time3-time2); - std::cout << "Time for write_new_elem: " << elapsed.count() * 1e-9 << std::endl; - - - // Adding new files in aMesh as well - if ( output_mesh ) - { - double Netgen_point[3]; - int Netgen_tetrahedron[4]; - - // create and insert new nodes into nodeVec - nodeVec.resize( Netgen_NbOfNodesNew + 1, 0 ); - int nodeIndex = Netgen_NbOfNodes + 1; - for ( ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) - { - Ng_GetPoint( Netgen_mesh, nodeIndex, Netgen_point ); - nodeVec.at(nodeIndex) = helper.AddNode(Netgen_point[0], - Netgen_point[1], - Netgen_point[2]); - } - - // create tetrahedrons - for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) - { - Ng_GetVolumeElement(Netgen_mesh, elemIndex, Netgen_tetrahedron); - try - { - helper.AddVolume (nodeVec.at( Netgen_tetrahedron[0] ), - nodeVec.at( Netgen_tetrahedron[1] ), - nodeVec.at( Netgen_tetrahedron[2] ), - nodeVec.at( Netgen_tetrahedron[3] )); - } - catch (...) - { - } - } - auto time4 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time4-time3); - std::cout << "Time for add_element_to_smesh: " << elapsed.count() * 1e-9 << std::endl; - - } - - return !err; -} - -/** - * @brief compute mesh with netgen2d - * - * @param input_mesh_file Input Mesh file - * @param shape_file Shape file - * @param hypo_file Parameter file - * @param new_element_file Binary file containing new nodes and new element info - * @param output_mesh If true will export mesh into output_mesh_file - * @param output_mesh_file Output Mesh file - * - * @return error code - */ -int netgen2d(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, - bool output_mesh, - const std::string output_mesh_file) -{ - - // Importing mesh - SMESH_Gen gen; - - SMESH_Mesh *myMesh = gen.CreateMesh(false); - //TODO: To define - std::string mesh_name = "Maillage_1"; - - import_mesh(input_mesh_file, *myMesh, mesh_name); - - // Importing shape - TopoDS_Shape myShape; - import_shape(shape_file, myShape); - - // Importing hypothesis - netgen_params myParams; - - import_netgen_params(hypo_file, myParams); - - std::cout << "Meshing with netgen3d" << std::endl; - int ret = netgen2d_internal(myShape, *myMesh, myParams, - new_element_file, element_orientation_file, - output_mesh); - - if(!ret){ - std::cout << "Meshing failed" << std::endl; - return ret; - } - - if(output_mesh) - export_mesh(output_mesh_file, *myMesh, mesh_name); - - return ret; -} - - -// TODO: Not working properly -/** - * @brief Compute aShape within aMesh using netgen2d - * - * @param aShape the shape - * @param aMesh the mesh - * @param aParams the netgen parameters - * @param new_element_file file containing data on the new point/tetra added by netgen - * - * @return error code - */ -int netgen2d_internal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, - std::string new_element_file, std::string element_orientation_file, - bool output_mesh) -{ - netgen::multithread.terminate = 0; - netgen::multithread.task = "Surface meshing"; - - SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); - SMESH_MesherHelper helper(aMesh); - helper.SetElementsOnShape( true ); - - NETGENPlugin_NetgenLibWrapper ngLib; - ngLib._isComputeOk = false; - - netgen::Mesh ngMeshNoLocSize; - netgen::Mesh * ngMeshes[2] = { (netgen::Mesh*) ngLib._ngMesh, & ngMeshNoLocSize }; - netgen::OCCGeometry occgeoComm; - - std::map elemOrientation; - - typedef map< const SMDS_MeshNode*, int, TIDCompare > TNodeToIDMap; - typedef TNodeToIDMap::value_type TN2ID; - const int invalid_ID = -1; - int Netgen_NbOfNodes=0; - double Netgen_point[3]; - int Netgen_segment[2]; - int Netgen_triangle[3]; - - // min / max sizes are set as follows: - // if ( _hypParameters ) - // min and max are defined by the user - // else if ( aParams.has_LengthFromEdges_hyp ) - // min = aMesher.GetDefaultMinSize() - // max = average segment len of a FACE - // else if ( _hypMaxElementArea ) - // min = aMesher.GetDefaultMinSize() - // max = f( _hypMaxElementArea ) - // else - // min = aMesher.GetDefaultMinSize() - // max = max segment len of a FACE - NETGENPlugin_Mesher aMesher( &aMesh, aShape, /*isVolume=*/false); - set_netgen_parameters( aParams ); - const bool toOptimize = aParams.optimize; - if ( aParams.has_maxelementvolume_hyp ) - { - netgen::mparam.maxh = sqrt( 2. * aParams.maxElementVolume / sqrt(3.0) ); - } - netgen::mparam.quad = aParams.quad; - - // local size is common for all FACEs in aShape? - const bool isCommonLocalSize = ( !aParams.has_LengthFromEdges_hyp && !aParams.has_maxelementvolume_hyp && netgen::mparam.uselocalh ); - const bool isDefaultHyp = ( !aParams.has_LengthFromEdges_hyp && !aParams.has_maxelementvolume_hyp && !aParams.has_netgen_param ); - - - 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 ); - - // local size set at MESHCONST_ANALYSE step depends on - // minh, face_maxh, grading and curvaturesafety; find minh if not set by the user - if ( !aParams.has_netgen_param || netgen::mparam.minh < DBL_MIN ) - { - if ( !aParams.has_netgen_param ) - 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 - const double factor = 2; //netgen::occparam.resthcloseedgefac; -#else - const double factor = netgen::occparam.resthcloseedgefac; - netgen::occparam.resthcloseedgeenable = false; - netgen::occparam.resthcloseedgefac = 1.0 + netgen::mparam.grading; -#endif - occgeoComm.face_maxh = netgen::mparam.maxh; -#ifdef NETGEN_V6 - netgen::OCCParameters occparam; - netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0], netgen::mparam, occparam ); -#else - netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0] ); -#endif - occgeoComm.emap.Clear(); - occgeoComm.vmap.Clear(); - - // Reading list of element to integrate into netgen mesh - { - std::ifstream df(element_orientation_file, ios::in|ios::binary); - int nbElement; - vtkIdType id; - bool orient; - df.read((char*)&nbElement, sizeof(int)); - - for(int ielem=0;ielemelementsIterator(SMDSAbs_Edge); - while ( iteratorElem->more() ) // loop on elements on a geom face - { - const SMDS_MeshElement* seg = iteratorElem->next(); - // Keeping only element that are in the element orientation file - isIn = elemOrientation.count(seg->GetID())==1; - - if(!isIn) - continue; - - SMESH_TNodeXYZ n1 = seg->GetNode(0); - SMESH_TNodeXYZ n2 = seg->GetNode(1); - gp_XYZ p = 0.5 * ( n1 + n2 ); - netgen::Point3d pi(p.X(), p.Y(), p.Z()); - ngMeshes[0]->RestrictLocalH( pi, factor * ( n1 - n2 ).Modulus() ); - } - - // set local size defined on shapes - aMesher.SetLocalSize( occgeoComm, *ngMeshes[0] ); - aMesher.SetLocalSizeForChordalError( occgeoComm, *ngMeshes[0] ); - try { - ngMeshes[0]->LoadLocalMeshSize( netgen::mparam.meshsizefilename ); - } catch (netgen::NgException & ex) { - return error( COMPERR_BAD_PARMETERS, ex.What() ); - } - } - netgen::mparam.uselocalh = toOptimize; // restore as it is used at surface optimization - // ================== - // Loop on all FACEs - // ================== - - vector< const SMDS_MeshNode* > nodeVec; - - // prepare occgeom - netgen::OCCGeometry occgeom; - occgeom.shape = aShape; - occgeom.fmap.Add( aShape ); - 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 - // ------------------------- - // maps nodes to ng ID - - - // MESHCONST_ANALYSE step may lead to a failure, so we make an attempt - // w/o MESHCONST_ANALYSE at the second loop - int err = 0; - enum { LOC_SIZE, NO_LOC_SIZE }; - int iLoop = isCommonLocalSize ? 0 : 1; - int faceID = occgeom.fmap.FindIndex(aShape); - int solidID = 0; - for ( ; iLoop < 2; iLoop++ ) - { - //bool isMESHCONST_ANALYSE = false; - //TODO: check how to replace that - //InitComputeError(); - - netgen::Mesh * ngMesh = ngMeshes[ iLoop ]; - ngMesh->DeleteMesh(); - - if ( iLoop == NO_LOC_SIZE ) - { - ngMesh->SetGlobalH ( netgen::mparam.maxh ); - ngMesh->SetMinimalH( netgen::mparam.minh ); - netgen::Box<3> bb = occgeom.GetBoundingBox(); - bb.Increase (bb.Diam()/10); - ngMesh->SetLocalH (bb.PMin(), bb.PMax(), netgen::mparam.grading); - aMesher.SetLocalSize( occgeom, *ngMesh ); - aMesher.SetLocalSizeForChordalError( occgeoComm, *ngMesh ); - try { - ngMesh->LoadLocalMeshSize( netgen::mparam.meshsizefilename ); - } catch (netgen::NgException & ex) { - return error( COMPERR_BAD_PARMETERS, ex.What() ); - } - } - - TNodeToIDMap nodeToNetgenID; - - nodeVec.clear(); - ngMesh->AddFaceDescriptor( netgen::FaceDescriptor( faceID, solidID, solidID, 0 )); - // set local size according to size of existing segments - SMDS_ElemIteratorPtr iteratorElem = meshDS->elementsIterator(SMDSAbs_Edge); - while ( iteratorElem->more() ) // loop on elements on a geom face - { - const SMDS_MeshElement* elem = iteratorElem->next(); - // Keeping only element that are in the element orientation file - bool isIn = elemOrientation.count(elem->GetID())==1; - - if(!isIn) - continue; - - bool isRev = elemOrientation[elem->GetID()]; - std::cerr << isRev; - - - - for ( int iN = 0; iN < 2; ++iN ) - { - const SMDS_MeshNode* node = elem->GetNode( iN ); - const int shapeID = node->getshapeId(); - int& ngID = nodeToNetgenID.insert(TN2ID( node, invalid_ID )).first->second; - if ( ngID == invalid_ID ) - { - ngID = ++Netgen_NbOfNodes; - Netgen_point [ 0 ] = node->X(); - Netgen_point [ 1 ] = node->Y(); - Netgen_point [ 2 ] = node->Z(); - netgen::MeshPoint mp( netgen::Point<3> (node->X(), node->Y(), node->Z()) ); - ngMesh->AddPoint ( mp, 1, netgen::EDGEPOINT ); - } - Netgen_segment[ isRev ? 1-iN : iN ] = ngID; - } - // add segment - - netgen::Segment seg; - seg[0] = Netgen_segment[0]; - seg[1] = Netgen_segment[1]; - seg.edgenr = ngMesh->GetNSeg() +1; - seg.si = faceID; - - ngMesh->AddSegment(seg); - } - int nbNodes2 = ngMesh->GetNP(); - int nseg = ngMesh->GetNSeg(); - - // insert old nodes into nodeVec - nodeVec.resize( nodeToNetgenID.size() + 1, 0 ); - TNodeToIDMap::iterator n_id = nodeToNetgenID.begin(); - for ( ; n_id != nodeToNetgenID.end(); ++n_id ) - nodeVec[ n_id->second ] = n_id->first; - nodeToNetgenID.clear(); - - - //if ( !isCommonLocalSize ) - //limitSize( ngMesh, mparam.maxh * 0.8); - - // ------------------------- - // Generate surface mesh - // ------------------------- - - const int startWith = netgen::MESHCONST_MESHSURFACE; - const int endWith = toOptimize ? netgen::MESHCONST_OPTSURFACE : netgen::MESHCONST_MESHSURFACE; - - SMESH_Comment str; - try { - OCC_CATCH_SIGNALS; - err = ngLib.GenerateMesh(occgeom, startWith, endWith, ngMesh); - if ( netgen::multithread.terminate ) - return false; - if ( err ) - str << "Error in netgen::OCCGenerateMesh() at " << netgen::multithread.task; - } - catch (Standard_Failure& ex) - { - err = 1; - str << "Exception in netgen::OCCGenerateMesh()" - << " at " << netgen::multithread.task - << ": " << ex.DynamicType()->Name(); - if ( ex.GetMessageString() && strlen( ex.GetMessageString() )) - str << ": " << ex.GetMessageString(); - } - catch (...) { - err = 1; - str << "Exception in netgen::OCCGenerateMesh()" - << " at " << netgen::multithread.task; - } - if ( err ) - { - if ( iLoop == LOC_SIZE ) - { - std::cout << "Need second run" << std::endl; - /*netgen::mparam.minh = netgen::mparam.maxh; - netgen::mparam.maxh = 0; - for ( size_t iW = 0; iW < wires.size(); ++iW ) - { - StdMeshers_FaceSidePtr wire = wires[ iW ]; - const vector& uvPtVec = wire->GetUVPtStruct(); - for ( size_t iP = 1; iP < uvPtVec.size(); ++iP ) - { - SMESH_TNodeXYZ p( uvPtVec[ iP ].node ); - netgen::Point3d np( p.X(),p.Y(),p.Z()); - double segLen = p.Distance( uvPtVec[ iP-1 ].node ); - double size = ngMesh->GetH( np ); - netgen::mparam.minh = Min( netgen::mparam.minh, size ); - netgen::mparam.maxh = Max( netgen::mparam.maxh, segLen ); - } - } - //cerr << "min " << mparam.minh << " max " << mparam.maxh << endl; - netgen::mparam.minh *= 0.9; - netgen::mparam.maxh *= 1.1; - */ - continue; - } - else - { - //faceErr.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED, str )); - } - } - - // ---------------------------------------------------- - // Fill the SMESHDS with the generated nodes and faces - // ---------------------------------------------------- - - if(output_mesh) - { - int nbNodes = ngMesh->GetNP(); - int nbFaces = ngMesh->GetNSE(); - std::cout << nbFaces << " " << nbNodes << std::endl; - - int nbInputNodes = (int) nodeVec.size()-1; - nodeVec.resize( nbNodes+1, 0 ); - - // add nodes - for ( int ngID = nbInputNodes + 1; ngID <= nbNodes; ++ngID ) - { - const netgen::MeshPoint& ngPoint = ngMesh->Point( ngID ); - SMDS_MeshNode * node = meshDS->AddNode(ngPoint(0), ngPoint(1), ngPoint(2)); - nodeVec[ ngID ] = node; - } - - // create faces - int i,j; - for ( i = 1; i <= nbFaces ; ++i ) - { - Ng_GetVolumeElement(ngLib.ngMesh(), i, Netgen_triangle); - - helper.AddFace (nodeVec.at( Netgen_triangle[0] ), - nodeVec.at( Netgen_triangle[1] ), - nodeVec.at( Netgen_triangle[2] )); - - } - } // output_mesh - - break; - } // two attempts - //} // loop on FACEs - - return true; - -} diff --git a/src/NETGENPlugin/netgen_mesher.hxx b/src/NETGENPlugin/netgen_mesher.hxx deleted file mode 100644 index 996b1ac..0000000 --- a/src/NETGENPlugin/netgen_mesher.hxx +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : netgen_mesher.hxx -// Author : Yoann AUDOUIN, EDF -// Module : SMESH -// - -#ifndef _NETGEN_MESHER_HXX_ -#define _NETGEN_MESHER_HXX_ - -#include -#include - -class TopoDS_Shape; -class SMESH_Mesh; -class SMESH_Comment; -class netgen_params; - -int netgen2d_internal(TopoDS_Shape &aShape, - SMESH_Mesh& aMesh, - netgen_params& aParams, - std::string new_element_file, - std::string element_orientation_file, - bool output_mesh); -int netgen2d(const std::string input_mesh_file, - const std::string shape_file, - const std::string hypo_file, - const std::string element_orienation_file, - const std::string new_element_file, - bool output_mesh, - const std::string output_mesh_file); - -int netgen3d_internal(TopoDS_Shape &aShape, - SMESH_Mesh& aMesh, - netgen_params& aParams, - std::string new_element_file, - std::string element_orientation_file, - bool output_mesh); -int netgen3d(const std::string input_mesh_file, - const std::string shape_file, - const std::string hypo_file, - const std::string element_orienation_file, - const std::string new_element_file, - bool output_mesh, - const std::string output_mesh_file, - int nbThreads); - -//TODO: Tmp function replace by real error handling -int error(int error_type, std::string msg); -int error(const SMESH_Comment& comment); - -#endif \ No newline at end of file diff --git a/src/NETGENPlugin/netgen_param.cxx b/src/NETGENPlugin/netgen_param.cxx deleted file mode 100644 index 0c69081..0000000 --- a/src/NETGENPlugin/netgen_param.cxx +++ /dev/null @@ -1,214 +0,0 @@ -// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : netgen_param.hxx -// Author : Yoann AUDOUIN, EDF -// Module : SMESH -// -#include "netgen_param.hxx" - -#include -#include -#include -#include - - -// TODO: Error handling of read/write - -/** - * @brief Print content of a netgen_params - * - * @param aParams The object to display - */ -void print_netgen_params(netgen_params& aParams){ - // TODO: prettier print - // TODO: Add call to print in log - std::cout << "has_netgen_param: " << aParams.has_netgen_param << std::endl; - std::cout << "maxh: " << aParams.maxh << std::endl; - std::cout << "minh: " << aParams.minh << std::endl; - std::cout << "segmentsperedge: " << aParams.segmentsperedge << std::endl; - std::cout << "grading: " << aParams.grading << std::endl; - std::cout << "curvaturesafety: " << aParams.curvaturesafety << std::endl; - std::cout << "secondorder: " << aParams.secondorder << std::endl; - std::cout << "quad: " << aParams.quad << std::endl; - std::cout << "optimize: " << aParams.optimize << std::endl; - std::cout << "fineness: " << aParams.fineness << std::endl; - std::cout << "uselocalh: " << aParams.uselocalh << std::endl; - std::cout << "merge_solids: " << aParams.merge_solids << std::endl; - std::cout << "chordalError: " << aParams.chordalError << std::endl; - std::cout << "optsteps2d: " << aParams.optsteps2d << std::endl; - std::cout << "optsteps3d: " << aParams.optsteps3d << std::endl; - std::cout << "elsizeweight: " << aParams.elsizeweight << std::endl; - std::cout << "opterrpow: " << aParams.opterrpow << std::endl; - std::cout << "delaunay: " << aParams.delaunay << std::endl; - std::cout << "checkoverlap: " << aParams.checkoverlap << std::endl; - std::cout << "checkchartboundary: " << aParams.checkchartboundary << std::endl; - std::cout << "closeedgefac: " << aParams.closeedgefac << std::endl; - std::cout << "has_local_size: " << aParams.has_local_size << std::endl; - std::cout << "meshsizefilename: " << aParams.meshsizefilename << std::endl; - std::cout << "has_maxelementvolume_hyp: " << aParams.has_maxelementvolume_hyp << std::endl; - std::cout << "maxElementVolume: " << aParams.maxElementVolume << std::endl; - std::cout << "has_LengthFromEdges_hyp: " << aParams.has_LengthFromEdges_hyp << std::endl; -} - -/** - * @brief Import a param_file into a netgen_params structure - * - * @param param_file Name of the file - * @param aParams Structure to fill - */ -void import_netgen_params(const std::string param_file, netgen_params& aParams){ - std::ifstream myfile(param_file); - std::string line; - - std::getline(myfile, line); - aParams.has_netgen_param = std::stoi(line); - std::getline(myfile, line); - aParams.maxh = std::stod(line); - std::getline(myfile, line); - aParams.minh = std::stod(line); - std::getline(myfile, line); - aParams.segmentsperedge = std::stod(line); - std::getline(myfile, line); - aParams.grading = std::stod(line); - std::getline(myfile, line); - aParams.curvaturesafety = std::stod(line); - std::getline(myfile, line); - aParams.secondorder = std::stoi(line); - std::getline(myfile, line); - aParams.quad = std::stoi(line); - std::getline(myfile, line); - aParams.optimize = std::stoi(line); - std::getline(myfile, line); - aParams.fineness = std::stoi(line); - std::getline(myfile, line); - aParams.uselocalh = std::stoi(line); - std::getline(myfile, line); - aParams.merge_solids = std::stoi(line); - std::getline(myfile, line); - aParams.chordalError = std::stod(line); - std::getline(myfile, line); - aParams.optsteps2d = std::stoi(line); - std::getline(myfile, line); - aParams.optsteps3d = std::stoi(line); - std::getline(myfile, line); - aParams.elsizeweight = std::stod(line); - std::getline(myfile, line); - aParams.opterrpow = std::stoi(line); - std::getline(myfile, line); - aParams.delaunay = std::stoi(line); - std::getline(myfile, line); - aParams.checkoverlap = std::stoi(line); - std::getline(myfile, line); - aParams.checkchartboundary = std::stoi(line); - std::getline(myfile, line); - aParams.closeedgefac = std::stoi(line); - std::getline(myfile, line); - aParams.has_local_size = std::stoi(line); - std::getline(myfile, line); - aParams.meshsizefilename = line; - std::getline(myfile, line); - aParams.has_maxelementvolume_hyp = std::stoi(line); - std::getline(myfile, line); - aParams.maxElementVolume = std::stod(line); - std::getline(myfile, line); - aParams.maxElementVolume = std::stoi(line); - - myfile.close(); -}; - -/** - * @brief Writes the content of a netgen_param into a file - * - * @param param_file the file - * @param aParams the object - */ -void export_netgen_params(const std::string param_file, netgen_params& aParams){ - std::ofstream myfile(param_file); - myfile << aParams.has_netgen_param << std::endl; - myfile << aParams.maxh << std::endl; - myfile << aParams.minh << std::endl; - myfile << aParams.segmentsperedge << std::endl; - myfile << aParams.grading << std::endl; - myfile << aParams.curvaturesafety << std::endl; - myfile << aParams.secondorder << std::endl; - myfile << aParams.quad << std::endl; - myfile << aParams.optimize << std::endl; - myfile << aParams.fineness << std::endl; - myfile << aParams.uselocalh << std::endl; - myfile << aParams.merge_solids << std::endl; - myfile << aParams.chordalError << std::endl; - myfile << aParams.optsteps2d << std::endl; - myfile << aParams.optsteps3d << std::endl; - myfile << aParams.elsizeweight << std::endl; - myfile << aParams.opterrpow << std::endl; - myfile << aParams.delaunay << std::endl; - myfile << aParams.checkoverlap << std::endl; - myfile << aParams.checkchartboundary << std::endl; - myfile << aParams.closeedgefac << std::endl; - myfile << aParams.has_local_size << std::endl; - myfile << aParams.meshsizefilename << std::endl; - myfile << aParams.has_maxelementvolume_hyp << std::endl; - myfile << aParams.maxElementVolume << std::endl; - myfile << aParams.has_LengthFromEdges_hyp << std::endl; - - myfile.close(); -}; - -/** - * @brief Compares two netgen_parms object - * - * @param params1 Object 1 - * @param params2 Object 2 - - * @return true if the two object are identical - */ -bool diff_netgen_params(netgen_params params1, netgen_params params2){ - bool ret = true; - ret &= params1.maxh == params2.maxh; - ret &= params1.minh == params2.minh; - ret &= params1.segmentsperedge == params2.segmentsperedge; - ret &= params1.grading == params2.grading; - ret &= params1.curvaturesafety == params2.curvaturesafety; - ret &= params1.secondorder == params2.secondorder; - ret &= params1.quad == params2.quad; - ret &= params1.optimize == params2.optimize; - ret &= params1.fineness == params2.fineness; - ret &= params1.uselocalh == params2.uselocalh; - ret &= params1.merge_solids == params2.merge_solids; - ret &= params1.chordalError == params2.chordalError; - ret &= params1.optsteps2d == params2.optsteps2d; - ret &= params1.optsteps3d == params2.optsteps3d; - ret &= params1.elsizeweight == params2.elsizeweight; - ret &= params1.opterrpow == params2.opterrpow; - ret &= params1.delaunay == params2.delaunay; - ret &= params1.checkoverlap == params2.checkoverlap; - ret &= params1.checkchartboundary == params2.checkchartboundary; - ret &= params1.closeedgefac == params2.closeedgefac; - ret &= params1.has_local_size == params2.has_local_size; - ret &= params1.meshsizefilename == params2.meshsizefilename; - ret &= params1.has_maxelementvolume_hyp == params2.has_maxelementvolume_hyp; - ret &= params1.maxElementVolume == params2.maxElementVolume; - ret &= params1.has_LengthFromEdges_hyp == params2.has_LengthFromEdges_hyp; - - return ret; -} diff --git a/src/NETGENPlugin/netgen_param.hxx b/src/NETGENPlugin/netgen_param.hxx deleted file mode 100644 index 0958931..0000000 --- a/src/NETGENPlugin/netgen_param.hxx +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : netgen_param.hxx -// Author : Yoann AUDOUIN, EDF -// Module : SMESH -// - -#ifndef _NETGEN_PARAM_HXX_ -#define _NETGEN_PARAM_HXX_ - -#include - -class NETGENPlugin_Hypothesis; -class StdMeshers_MaxElementVolume; -class StdMeshers_ViscousLayers; - -struct netgen_params{ - // Params from NETGENPlugin_Mesher - // True if _hypParameters is not null - bool has_netgen_param=true; - double maxh; - double minh; - double segmentsperedge; - double grading; - double curvaturesafety; - int secondorder; - int quad; - bool optimize; - int fineness; - bool uselocalh; - bool merge_solids; - double chordalError; - int optsteps2d; - int optsteps3d; - double elsizeweight; - int opterrpow; - bool delaunay; - bool checkoverlap; - bool checkchartboundary; - int closeedgefac; - - - // TODO: add localsize (pass through local size file ?) - // True if we have a mesh size file or local size info - bool has_local_size = false; - std::string meshsizefilename; - - // Params from NETGEN3D - // True if _hypMaxElementVolume is not null - bool has_maxelementvolume_hyp=false; - double maxElementVolume=0.0; - - // to replace - //NETGENPlugin_Hypothesis * _hypParameters=nullptr; - // to remove ? - StdMeshers_MaxElementVolume* _hypMaxElementVolume=nullptr; - // to remove ? - StdMeshers_ViscousLayers* _viscousLayersHyp=nullptr; - //double _progressByTic; - bool _quadraticMesh=false; - - // Params from NETGEN2D - bool has_LengthFromEdges_hyp=false; - - // Number of threads for the mesher - int nbThreads; -}; - -void print_netgen_params(netgen_params& aParams); - -void import_netgen_params(const std::string param_file, netgen_params& aParams); -void export_netgen_params(const std::string param_file, netgen_params& aParams); - -bool diff_netgen_params(netgen_params params1, netgen_params params2); - -#endif \ No newline at end of file diff --git a/src/NETGENPlugin/run_mesher.cxx b/src/NETGENPlugin/run_mesher.cxx deleted file mode 100644 index a1a1fbc..0000000 --- a/src/NETGENPlugin/run_mesher.cxx +++ /dev/null @@ -1,242 +0,0 @@ -// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : run_mesher.cxx -// Author : Yoann AUDOUIN, EDF -// Module : SMESH -// - -#include "DriverStep.hxx" -#include "DriverMesh.hxx" -#include "netgen_param.hxx" -#include "netgen_mesher.hxx" - -#include -#include - -#include -#include - -#include - -/** - * @brief Test of shape Import/Export - * - * @param shape_file - */ -void test_shape(){ - - std::cout << "Testing Shape Import/Export" << std::endl; - std::string shape_file = "box.step"; - - TopoDS_Shape myShape; - - // Test 1 import -> export cmp files - std::string shape_file2 = "/tmp/shape.step"; - - import_shape(shape_file, myShape); - export_shape(shape_file2, myShape); - - assert(diff_step_file(shape_file, shape_file2)); - - // Test 2 import->export->import cmp TopoDS_Shape - std::string shape_file3 = "/tmp/shape2.step"; - TopoDS_Shape myShape1, myShape2; - - import_shape(shape_file, myShape1); - - export_shape(shape_file3, myShape1); - - import_shape(shape_file3, myShape2); - - // TODO: See why this does not work - // TShape seems to be different - //assert(myShape1.IsSame(myShape2)); - -} - -/** - * @brief test of mesh import/export - * - * @param mesh_file - */ -void test_mesh(){ - - std::cout << "Testing Mesh Import/Export" << std::endl; - std::string mesh_file = "box.med"; - SMESH_Gen gen; - - SMESH_Mesh *myMesh = gen.CreateMesh(false); - std::string mesh_name = "Maillage_1"; - - // Test 1 import -> export cmp files - std::string mesh_file2 = "/tmp/mesh.med"; - - import_mesh(mesh_file, *myMesh, mesh_name); - export_mesh(mesh_file2, *myMesh, mesh_name); - - assert(diff_med_file(mesh_file, mesh_file2, mesh_name)); - - // TODO: Compare the two med files via dump ? - - // Test 2 import->export->import cmp TopoDS_Shape - std::string mesh_file3 = "/tmp/mesh2.med"; - SMESH_Mesh *myMesh1 = gen.CreateMesh(false); - SMESH_Mesh *myMesh2 = gen.CreateMesh(false); - - import_mesh(mesh_file, *myMesh1, mesh_name); - - export_mesh(mesh_file3, *myMesh1, mesh_name); - - import_mesh(mesh_file3, *myMesh2, mesh_name); - - // TODO: Compare SMESH_Mesh - //assert(myMesh1==myMesh2); -} - -/** - * @brief Test of import/export of netgen param - * - */ -void test_netgen_params(){ - - std::string param_file = "/tmp/netgen_param.txt"; - netgen_params myParams, myParams2; - myParams.has_netgen_param = true; - myParams.maxh = 34.64; - myParams.minh = 0.14; - myParams.segmentsperedge = 15; - myParams.grading = 0.2; - myParams.curvaturesafety = 1.5; - myParams.secondorder = false; - myParams.quad = false; - myParams.optimize = true; - myParams.fineness = 5; - myParams.uselocalh = true; - myParams.merge_solids = true; - myParams.chordalError = -1; - myParams.optsteps2d = 3; - myParams.optsteps3d = 3; - myParams.elsizeweight = 0.2; - myParams.opterrpow = 2; - myParams.delaunay = true; - myParams.checkoverlap = true; - myParams.checkchartboundary = false; - myParams.closeedgefac = 2; - myParams.has_local_size = false; - myParams.meshsizefilename = ""; - myParams.has_maxelementvolume_hyp = false; - myParams.maxElementVolume = 0.0; - - export_netgen_params(param_file, myParams); - import_netgen_params(param_file, myParams2); - - assert(diff_netgen_params(myParams, myParams2)); - -}; - -void test_netgen3d(){ - - std::cout << "Testing NETGEN 3D mesher" << std::endl; - netgen3d("box_partial2D1D-2.med", - "box-2.step", - "box_param.txt", - "element_orient.dat", - "new_element.dat", - true, - "box_with3D.med", - 1); - - // TODO: Check result -} - -/** - * @brief Main function - * - * @param argc Number of arguments - * @param argv Arguments - * - * @return error code - */ -int main(int argc, char *argv[]){ - - if(argc!=10||(argc==2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help")==0))){ - std::cout << "Error in number of argument"<(end - begin); - std::cout << "Time elapsed: " << elapsed.count()*1e-9 << std::endl; - } else if (mesher=="NETGEN2D"){ - netgen2d(input_mesh_file, - shape_file, - hypo_file, - element_orientation_file, - new_element_file, - output_mesh, - output_mesh_file); - } else { - std::cerr << "Unknown mesher:" << mesher << std::endl; - } - return 0; -}