1 // Copyright (C) 2007-2023 CEA, EDF, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // NETGENPlugin : C++ implementation
21 // File : NETGENPlugin_NETGEN_2D_SA.cxx
22 // Author : Cesar Conopoima (OCC)
25 //=============================================================================
27 #include "NETGENPlugin_NETGEN_2D_SA.hxx"
28 #include "NETGENPlugin_Hypothesis_2D.hxx"
29 #include "NETGENPlugin_SimpleHypothesis_2D.hxx"
30 #include "NETGENPlugin_Mesher.hxx"
32 #include <SMESHDS_Mesh.hxx>
33 #include <SMESH_ControlsDef.hxx>
34 #include <SMESH_Gen.hxx>
35 #include <SMESH_Mesh.hxx>
36 #include <SMESH_MesherHelper.hxx>
37 #include <SMESH_DriverShape.hxx>
38 #include <SMESH_DriverMesh.hxx>
39 #include <StdMeshers_LengthFromEdges.hxx>
40 #include <StdMeshers_MaxElementArea.hxx>
41 #include <utilities.h>
45 namespace fs = std::filesystem;
47 #include <boost/filesystem.hpp>
48 namespace fs = boost::filesystem;
54 #include <meshing.hpp>
56 using namespace nglib;
58 //=============================================================================
62 //=============================================================================
64 NETGENPlugin_NETGEN_2D_SA::NETGENPlugin_NETGEN_2D_SA()
65 : NETGENPlugin_NETGEN_2D_ONLY(0, new SMESH_Gen())
67 _name = "NETGEN_2D_SA";
70 //=============================================================================
74 //=============================================================================
76 NETGENPlugin_NETGEN_2D_SA::~NETGENPlugin_NETGEN_2D_SA()
81 * @brief fill plugin hypothesis from the netgen_params structure
83 * @param aParams the structure
85 void NETGENPlugin_NETGEN_2D_SA::fillHyp(const std::string param_file, netgen_params aParams)
88 if( aParams.has_netgen_param && aParams.myType == hypoType::Hypo )
90 NETGENPlugin_Hypothesis_2D * hyp = new NETGENPlugin_Hypothesis_2D(0, GetGen());
91 hyp->SetMaxSize(aParams.maxh);
92 hyp->SetMinSize(aParams.minh);
93 hyp->SetGrowthRate(aParams.grading);
94 hyp->SetQuadAllowed(aParams.quad);
95 hyp->SetFineness((NETGENPlugin_Hypothesis::Fineness)aParams.fineness);
96 hyp->SetChordalErrorEnabled(aParams.chordalError);
98 hyp->SetNbSurfOptSteps(aParams.optsteps2d);
100 _hypParameters = dynamic_cast< const NETGENPlugin_Hypothesis_2D *> (hyp);
104 NETGENPlugin_Hypothesis * hyp = new NETGENPlugin_Hypothesis(0, GetGen());
105 if (param_file.find("lenghtfromedge") != std::string::npos )
107 _hypLengthFromEdges = dynamic_cast<const StdMeshers_LengthFromEdges*> (hyp);
109 else if ( param_file.find("maxarea") != std::string::npos )
111 StdMeshers_MaxElementArea * hyp = new StdMeshers_MaxElementArea(0, GetGen());
113 std::ifstream myfile(param_file);
116 std::getline(myfile, line);
117 bool hashypothesis = std::stoi(line);
120 std::getline(myfile, line);
121 maxArea = std::stod(line);
122 hyp->SetMaxArea( maxArea );
123 _hypMaxElementArea = static_cast<const StdMeshers_MaxElementArea*> (hyp);
133 * @brief Write a binary file containing information on the elements/nodes
134 * created by the mesher
136 * @param premeshedNodes map of the premeshed nodes of 1D elements
137 * @param newNetgenCoordinates map of the coordinate of new netgen points created in the mesh
138 * @param newNetgenElements map of the element triangulation
139 * @return true if there are some error
141 bool NETGENPlugin_NETGEN_2D_SA::fillNewElementFile( std::string new_element_file,
142 const int numberOfGlobalPremeshedNodes,
143 std::map<int,const SMDS_MeshNode*>& premeshedNodes,
144 std::map<int,std::vector<double>>& newNetgenCoordinates,
145 std::map<int,std::vector<smIdType>>& newNetgenElements )
147 MESSAGE("Writting new elements")
149 int NetgenNbOfNodes = premeshedNodes.size();
150 int NetgenNbOfNodesNew = numberOfGlobalPremeshedNodes + newNetgenCoordinates.size();
151 int NetgenNbOfTriangles = newNetgenElements.size();
152 bool isOK = ( NetgenNbOfTriangles > 0 );
153 if ( isOK && !new_element_file.empty() )
155 int NetgenElement[3];
156 std::ofstream df(new_element_file, ios::out|ios::binary);
157 // Writing nodevec (correspondence netgen numbering mesh numbering)
159 df.write((char*) &numberOfGlobalPremeshedNodes, sizeof(int));
160 df.write((char*) &NetgenNbOfNodes, sizeof(int));
161 df.write((char*) &NetgenNbOfNodesNew, sizeof(int));
162 for (auto k : premeshedNodes )
163 df.write((char*) &k.first, sizeof(int));
165 // Writing info on new points
166 for (auto k : newNetgenCoordinates )
167 df.write((char*) k.second.data(), sizeof(double)*3 );
170 df.write((char*) &NetgenNbOfTriangles, sizeof(int));
171 for ( int elemIndex = 1; elemIndex <= NetgenNbOfTriangles; ++elemIndex )
173 int nodes = newNetgenElements[ elemIndex ].size();
174 for (int i = 0; i < nodes; i++)
175 NetgenElement[ i ] = (int) newNetgenElements[ elemIndex ][ i ];
177 df.write((char*) &NetgenElement, sizeof(int)* nodes );
186 * @brief Compute the mesh based on the
188 * @param input_mesh_file Mesh file (containing 2D elements)
189 * @param shape_file Shape file (BREP or STEP format)
190 * @param hypo_file Ascii file containing the netgen parameters
191 * @param element_orientation_file Binary file containing the orientation of surface elemnts
192 * @param new_element_file output file containing info the elements created by the mesher
193 * @param output_mesh_file output mesh file (if empty it will not be created)
194 * @return true, false
196 bool NETGENPlugin_NETGEN_2D_SA::Compute( SMESH_Mesh& aMesh, TopoDS_Shape &aShape, std::string new_element_file )
198 // Nodes on edge are double because each face is treat one by one, so seam edges are iterated twice
199 vector< const SMDS_MeshNode* > nodeVec;
200 NETGENPlugin_Mesher aMesher( &aMesh, aShape, false /*isVolume=*/ );
201 NETGENPlugin_NetgenLibWrapper ngLib;
202 ngLib._isComputeOk = false;
204 fs::path netgen_log_file = fs::path(new_element_file).remove_filename() / fs::path("NETGEN.out");
205 MESSAGE("netgen ouput"<<netgen_log_file.string());
206 ngLib.setOutputFile(netgen_log_file.string());
208 netgen::OCCGeometry occgeoComm;
209 NETGENPlugin_NETGEN_2D_ONLY::SetParameteres( aMesh, aShape, aMesher, ngLib._ngMesh, occgeoComm, false /*submesh is not supported*/ );
211 std::map<int,const SMDS_MeshNode*> premeshedNodes;
212 std::map<int,std::vector<double>> newNetgenCoordinates;
213 std::map<int,std::vector<smIdType>> newNetgenElements;
214 const int numberOfTotalPremeshedNodes = aMesh.NbNodes();
215 bool compute = NETGENPlugin_NETGEN_2D_ONLY::MapSegmentsToEdges( aMesh, aShape, ngLib, nodeVec,
216 premeshedNodes, newNetgenCoordinates,
219 compute = fillNewElementFile(new_element_file,
220 numberOfTotalPremeshedNodes,
222 newNetgenCoordinates,
228 * @brief Running the mesher on the given files
230 * @param input_mesh_file Mesh file (containing 2D elements)
231 * @param shape_file Shape file (BREP or STEP format)
232 * @param hypo_file Ascii file containing the netgen parameters
233 * @param element_orientation_file Binary file containing the orientation of surface elemnts
234 * @param new_element_file output file containing info the elements created by the mesher
235 * @param output_mesh_file output mesh file (if empty it will not be created)
238 int NETGENPlugin_NETGEN_2D_SA::run(const std::string input_mesh_file,
239 const std::string shape_file,
240 const std::string hypo_file,
241 const std::string element_orientation_file,
242 const std::string new_element_file,
243 const std::string output_mesh_file)
246 std::unique_ptr<SMESH_Mesh> myMesh(_gen->CreateMesh(false));
248 SMESH_DriverMesh::importMesh(input_mesh_file, *myMesh);
250 TopoDS_Shape myShape;
251 SMESH_DriverShape::importShape(shape_file, myShape);
252 // Importing hypothesis
253 netgen_params myParams;
254 importNetgenParams(hypo_file, myParams);
255 fillHyp(hypo_file,myParams);
256 MESSAGE("Meshing with netgen2d");
257 int ret = (int) Compute( *myMesh, myShape, new_element_file );
260 std::cerr << "Meshing failed" << std::endl;
264 if(!output_mesh_file.empty()){
265 std::string meshName = "MESH";
266 SMESH_DriverMesh::exportMesh(output_mesh_file, *myMesh, meshName);