Branch data Line data Source code
1 : :
2 : : #include "MKVersion.h"
3 : : #include "meshkit/MeshImprove.hpp"
4 : : #include <iostream>
5 : : #include <math.h>
6 : : #include <map>
7 : :
8 : : //#include "SweepWrapper.hpp"
9 : : #include "moab/mesquite/UntangleWrapper.hpp"
10 : : #include "moab/mesquite/ShapeImprover.hpp"
11 : : #include "moab/mesquite/SmartLaplacianSmoother.hpp"
12 : : #include "SweepWrapper.hpp"
13 : : #include "SmartLaplaceWrapper.hpp"
14 : : #include "moab/mesquite/ShapeImprovementWrapper.hpp"
15 : :
16 : : #include "moab/mesquite/IdealWeightInverseMeanRatio.hpp"
17 : : #include "moab/mesquite/QualityAssessor.hpp"
18 : : #include "moab/mesquite/InstructionQueue.hpp"
19 : : #include "moab/mesquite/TerminationCriterion.hpp"
20 : :
21 : : #include "moab/mesquite/LaplaceWrapper.hpp"
22 : : #include "moab/mesquite/SizeAdaptShapeWrapper.hpp"
23 : : #include "moab/mesquite/PaverMinEdgeLengthWrapper.hpp"
24 : : #include "moab/mesquite/DeformingDomainWrapper.hpp"
25 : : #include <moab/mesquite/MsqError.hpp>
26 : : #include <moab/mesquite/ShapeImprovementWrapper.hpp>
27 : : #include "moab/mesquite/MsqIMesh.hpp"
28 : : #include "moab/mesquite/MsqIGeom.hpp"
29 : : #ifdef HAVE_FBIGEOM
30 : : #include "meshkit/MsqFBiGeom.hpp"
31 : : #endif
32 : : using namespace MESQUITE_NS;
33 : :
34 : : namespace MeshKit {
35 : :
36 : 12 : MeshImprove::MeshImprove(MKCore* core, bool isLaplacian, bool isUntangle,
37 : : bool isShapeImprove, bool isSizeAdapt, iGeom * ig_inst)
38 : : {
39 : 12 : mk_core = core;
40 : 12 : IsLaplacian = isLaplacian;
41 : 12 : IsUntangle = isUntangle;
42 : 12 : IsShapeImprove = isShapeImprove;
43 : 12 : IsSizeAdapt = isSizeAdapt;
44 [ + - ]: 12 : if (ig_inst)
45 : 12 : igeom_inst = ig_inst;
46 : : else
47 : 0 : igeom_inst = mk_core->igeom_instance();// it will pick the first one
48 : 12 : }
49 : :
50 : 12 : void MeshImprove::SurfMeshImprove(iBase_EntityHandle surface,
51 : : iBase_EntitySetHandle surfMesh, iBase_EntityType entity_type)
52 : : {
53 : :
54 [ + - ]: 12 : MsqError mError;
55 : 12 : const char* VERTEX_FIXED_TAG_NAME = "MesquiteVertexFixed";
56 : :
57 : 12 : iBase_TagHandle fixed_tag = 0;
58 [ + - ]: 12 : iMesh::Error m_err = mk_core->imesh_instance()->getTagHandle(
59 [ + - ]: 12 : VERTEX_FIXED_TAG_NAME, fixed_tag);
60 [ + + ]: 12 : if (m_err) {
61 [ + - ]: 3 : m_err = mk_core->imesh_instance()->createTag(VERTEX_FIXED_TAG_NAME, 1,
62 [ + - ]: 3 : iBase_INTEGER, fixed_tag);
63 [ + - ]: 3 : IBERRCHK(m_err, "Trouble create the tag handle.");
64 : : }
65 : :
66 [ + - ]: 12 : MsqIMesh mesh_adapter(mk_core->imesh_instance()->instance(), surfMesh,
67 [ + - ][ + - ]: 24 : entity_type, mError, &fixed_tag);
68 [ + - ][ + - ]: 12 : cout << "error =" << mError << endl;
[ + - ]
69 [ + - ][ - + ]: 12 : if (mError)
70 [ # # ]: 0 : throw mError;
71 : :
72 : : //get all the vertices in surface mesh: entity_handles_out---quads adj_entity_handles_out---vertices
73 [ + - ][ + - ]: 24 : std::vector<iBase_EntityHandle> entity_handles_out, adj_entity_handles_out;
74 [ + - ][ + - ]: 24 : std::vector<int> offsets_out, adj_entity_indices_out;
75 : :
76 : : m_err = mk_core->imesh_instance()->getAdjEntIndices(surfMesh, entity_type,
77 : : iMesh_ALL_TOPOLOGIES, iBase_VERTEX, entity_handles_out,
78 [ + - ][ + - ]: 12 : adj_entity_handles_out, adj_entity_indices_out, offsets_out);
79 [ + - ]: 12 : IBERRCHK(m_err, "Trouble get the adjacent entity indices.");
80 : :
81 [ + - ][ + - ]: 12 : cout << "number of faces is " << entity_handles_out.size() << endl;
[ + - ]
82 [ + - ][ + - ]: 12 : cout << "number of vertices is " << adj_entity_handles_out.size() << endl;
[ + - ]
83 : :
84 : : //set fixed flag on all vertices
85 [ + - ]: 24 : std::vector<int> tag_data(adj_entity_handles_out.size(), 1);
86 [ + - ][ + - ]: 12 : m_err = mk_core->imesh_instance()->setIntArrData(&adj_entity_handles_out[0],
87 [ + - ][ + - ]: 24 : adj_entity_handles_out.size(), fixed_tag, &tag_data[0]);
88 [ + - ]: 12 : IBERRCHK(m_err, "Trouble set an array of int data for a list of vertices.");
89 : :
90 : : //clear fixed flag for vertices contained directly in set
91 : 12 : int count = -1;
92 : : m_err
93 [ + - ][ + - ]: 12 : = mk_core->imesh_instance()->getNumOfType(surfMesh, iBase_VERTEX, count);
94 [ + - ]: 12 : IBERRCHK(m_err, "Trouble get the number of vertices in the set.");
95 : :
96 : 12 : adj_entity_handles_out.clear();
97 : :
98 [ + - ][ + - ]: 12 : cout << "Num of Vertices on the target surface is " << count << endl;
[ + - ]
99 : :
100 : : m_err = mk_core->imesh_instance()->getEntities(surfMesh, iBase_VERTEX,
101 [ + - ][ + - ]: 12 : iMesh_ALL_TOPOLOGIES, adj_entity_handles_out);
102 [ + - ]: 12 : IBERRCHK(m_err, "Trouble get the nodes from the mesh entity set.");
103 : :
104 : 12 : tag_data.clear();
105 [ + - ]: 12 : tag_data.resize(adj_entity_handles_out.size(), 0);
106 : :
107 [ + - ][ + - ]: 12 : m_err = mk_core->imesh_instance()->setIntArrData(&adj_entity_handles_out[0],
108 [ + - ][ + - ]: 24 : adj_entity_handles_out.size(), fixed_tag, &tag_data[0]);
109 [ + - ]: 12 : IBERRCHK(m_err, "Trouble set an array of int data for mesh nodes.");
110 : :
111 : : //Finally smooth the mesh
112 : :
113 : : //SweepWrapper smoother( 1e-6, "COORDINATES_MAP");
114 [ + + ]: 12 : if (IsUntangle) {
115 [ + - ]: 6 : UntangleWrapper smoother;
116 : : //smoother.set_cpu_time_limit(300);
117 [ + - ]: 6 : smoother.set_vertex_movement_limit_factor(0.001);
118 : :
119 [ + - ]: 6 : if (surface) {
120 : : #ifdef HAVE_FBIGEOM
121 [ + - ][ + + ]: 6 : if (this->igeom_inst->isFBiGeom())
122 : : {
123 [ + - ]: 1 : MsqFBiGeom fbgeom_adapter((FBiGeom *)igeom_inst, surface);
124 [ + - ]: 2 : MeshDomainAssoc mesh_and_domain(&mesh_adapter, &fbgeom_adapter);
125 [ + - ]: 1 : smoother.run_instructions(&mesh_and_domain, mError);
126 [ + - ][ + - ]: 2 : cout << "Mesquite error in fb surface mesh smoothing=" << mError << endl;
[ + - ]
127 : : }
128 : : else
129 : : {
130 : : #endif
131 [ + - ][ + - ]: 5 : MsqIGeom geom_adapter(mk_core->igeom_instance()->instance(), surface);
[ + - ]
132 [ + - ]: 10 : MeshDomainAssoc mesh_and_domain(&mesh_adapter, &geom_adapter);
133 [ + - ]: 5 : smoother.run_instructions(&mesh_and_domain, mError);
134 [ + - ][ + - ]: 11 : cout << "Mesquite error in surface mesh smoothing=" << mError << endl;
[ + - ]
135 : : #ifdef HAVE_FBIGEOM
136 : : }
137 : : #endif
138 : : } else {
139 [ # # ]: 0 : smoother.run_instructions(&mesh_adapter, mError);
140 [ # # ][ # # ]: 0 : cout << "Mesquite error in surface mesh smoothing=" << mError << endl;
[ # # ]
141 : 6 : }
142 : : }
143 : :
144 : : //use the SmartLaplaceWrapper class the smooth the target surface mesh
145 [ - + ]: 12 : if (IsLaplacian) {
146 [ # # ]: 0 : LaplaceWrapper sl_smooth;
147 [ # # ][ # # ]: 0 : TerminationCriterion terminate;
148 [ # # ]: 0 : terminate.write_iterations("mesquite.gpt", mError);
149 [ # # ]: 0 : if (surface) {
150 : : #ifdef HAVE_FBIGEOM
151 [ # # ][ # # ]: 0 : if (this->igeom_inst->isFBiGeom())
152 : : {
153 [ # # ]: 0 : MsqFBiGeom fbgeom_adapter((FBiGeom *)igeom_inst, surface);
154 [ # # ]: 0 : MeshDomainAssoc mesh_and_domain(&mesh_adapter, &fbgeom_adapter);
155 [ # # ]: 0 : sl_smooth.run_instructions(&mesh_and_domain, mError);
156 [ # # ][ # # ]: 0 : cout << "Mesquite error in fb smart Laplacian surface mesh smoothing with the geometry domain=" << mError << endl;
[ # # ]
157 : : }
158 : : else
159 : : {
160 : : #endif
161 [ # # ][ # # ]: 0 : MsqIGeom geom_adapter(mk_core->igeom_instance()->instance(), surface);
[ # # ]
162 [ # # ]: 0 : MeshDomainAssoc mesh_and_domain(&mesh_adapter, &geom_adapter);
163 [ # # ]: 0 : sl_smooth.run_instructions(&mesh_and_domain, mError);
164 : : cout
165 [ # # ]: 0 : << "Mesquite error in the smart Laplacian surface mesh smoothing with the geometry domain="
166 [ # # ][ # # ]: 0 : << mError << endl;
167 : : #ifdef HAVE_FBIGEOM
168 : : }
169 : : #endif
170 : : } else {
171 [ # # ]: 0 : MeshDomainAssoc mesh_and_domain(&mesh_adapter, 0);
172 [ # # ]: 0 : sl_smooth.run_instructions(&mesh_and_domain, mError);
173 : : cout
174 [ # # ]: 0 : << "Mesquite error in the smart Laplacian surface mesh smoothing without the geometry domain="
175 [ # # ][ # # ]: 0 : << mError << endl;
176 : 0 : }
177 : : }
178 : :
179 : : //use the ShapeImprover class to smooth the target surface mesh
180 [ + - ]: 12 : if (IsShapeImprove) {
181 [ + - ]: 12 : IdealWeightInverseMeanRatio extra_metric;
182 [ + - ]: 24 : ShapeImprovementWrapper smoother1;
183 [ + - ][ + - ]: 12 : smoother1.quality_assessor().add_quality_assessment(&extra_metric);
184 : : //smoother1.set_vertex_movement_limit_factor(0.01);
185 : : //smoother1.set_cpu_time_limit(300);
186 [ + - ]: 12 : if (surface) {
187 : : #ifdef HAVE_FBIGEOM
188 [ + - ][ + + ]: 12 : if (this->igeom_inst->isFBiGeom())
189 : : {
190 [ + - ]: 1 : MsqFBiGeom fbgeom_adapter((FBiGeom *)igeom_inst, surface);
191 [ + - ]: 2 : MeshDomainAssoc mesh_and_domain(&mesh_adapter, &fbgeom_adapter);
192 [ + - ]: 1 : smoother1.run_instructions(&mesh_and_domain, mError);
193 [ + - ][ + - ]: 2 : cout << "Mesquite error in ShapeImprover fb surface mesh smoothing=" << mError << endl;
[ + - ]
194 : : }
195 : : else
196 : : {
197 : : #endif
198 [ + - ][ + - ]: 11 : MsqIGeom geom_adapter(mk_core->igeom_instance()->instance(), surface);
[ + - ]
199 [ + - ]: 22 : MeshDomainAssoc mesh_and_domain(&mesh_adapter, &geom_adapter);
200 [ + - ]: 11 : smoother1.run_instructions(&mesh_and_domain, mError);
201 [ + - ]: 11 : cout << "Mesquite error in the ShapeImprover surface mesh smoothing="
202 [ + - ][ + - ]: 23 : << mError << endl;
203 : : #ifdef HAVE_FBIGEOM
204 : : }
205 : : #endif
206 : : } else {
207 [ # # ]: 0 : MeshDomainAssoc mesh_and_domain(&mesh_adapter, 0);
208 [ # # ]: 0 : smoother1.run_instructions(&mesh_and_domain, mError);
209 [ # # ]: 0 : cout << "Mesquite error in the ShapeImprover surface mesh smoothing="
210 [ # # ][ # # ]: 0 : << mError << endl;
211 : 12 : }
212 : : }
213 : :
214 : : //Use the Minimum Edge-Length Improvement
215 : :
216 [ + + ]: 12 : if (IsSizeAdapt) {
217 [ + - ]: 6 : SizeAdaptShapeWrapper Smooth_SizeAdapt(1.0e-2);
218 [ + - ]: 6 : if (surface) {
219 : : #ifdef HAVE_FBIGEOM
220 [ + - ][ + + ]: 6 : if (this->igeom_inst->isFBiGeom())
221 : : {
222 [ + - ]: 1 : MsqFBiGeom fbgeom_adapter((FBiGeom *)igeom_inst, surface);
223 [ + - ]: 2 : MeshDomainAssoc mesh_and_domain(&mesh_adapter, &fbgeom_adapter);
224 [ + - ]: 1 : Smooth_SizeAdapt.run_instructions(&mesh_and_domain, mError);
225 [ + - ][ + - ]: 2 : cout << "Mesquite error in SizeAdaptShape fb surface mesh smoothing=" << mError << endl;
[ + - ]
226 : : }
227 : : else
228 : : {
229 : : #endif
230 [ + - ][ + - ]: 5 : MsqIGeom geom_adapter(mk_core->igeom_instance()->instance(), surface);
[ + - ]
231 [ + - ]: 10 : MeshDomainAssoc mesh_and_domain(&mesh_adapter, &geom_adapter);
232 [ + - ]: 5 : Smooth_SizeAdapt.run_instructions(&mesh_and_domain, mError);
233 [ + - ]: 5 : cout << "Mesquite error in the SizeAdaptShape surface mesh smoothing="
234 [ + - ][ + - ]: 11 : << mError << endl;
235 : : #ifdef HAVE_FBIGEOM
236 : : }
237 : : #endif
238 : :
239 : : } else {
240 [ # # ]: 0 : Smooth_SizeAdapt.run_instructions(&mesh_adapter, mError);
241 [ # # ]: 0 : cout << "Mesquite error in the SizeAdaptShape surface mesh smoothing="
242 [ # # ][ # # ]: 0 : << mError << endl;
243 : 6 : }
244 : 12 : }
245 : :
246 : 12 : }
247 : :
248 : 0 : void MeshImprove::VolumeMeshImprove(iBase_EntitySetHandle volMesh,
249 : : iBase_EntityType entity_type)
250 : : {
251 : :
252 [ # # ][ # # ]: 0 : cout << "Volume smoothing is starting..." << endl;
253 : :
254 [ # # ]: 0 : MsqError mError;
255 : 0 : const char* VERTEX_FIXED_TAG_NAME = "MesquiteVertexFixed";
256 : :
257 : 0 : iBase_TagHandle fixed_tag = 0;
258 : :
259 [ # # ]: 0 : iMesh::Error m_err = mk_core->imesh_instance()->getTagHandle(
260 [ # # ]: 0 : VERTEX_FIXED_TAG_NAME, fixed_tag);
261 [ # # ]: 0 : if (m_err) {
262 [ # # ]: 0 : m_err = mk_core->imesh_instance()->createTag(VERTEX_FIXED_TAG_NAME, 1,
263 [ # # ]: 0 : iBase_INTEGER, fixed_tag);
264 [ # # ]: 0 : IBERRCHK(m_err, "Trouble create a taghandle.");
265 : : }
266 : :
267 [ # # ]: 0 : MsqIMesh mesh_adapter(mk_core->imesh_instance()->instance(), volMesh,
268 [ # # ][ # # ]: 0 : entity_type, mError, &fixed_tag);
269 [ # # ][ # # ]: 0 : cout << "error =" << mError << endl;
[ # # ]
270 [ # # ][ # # ]: 0 : if (mError)
271 [ # # ]: 0 : throw mError;
272 : :
273 : : //get all the vertices in volume mesh
274 : : int num_vtx, count;
275 [ # # ][ # # ]: 0 : std::vector<iBase_EntityHandle> faces, verts;
276 [ # # ][ # # ]: 0 : std::vector<int> indices, offsets;
277 : :
278 : : m_err = mk_core->imesh_instance()->getAdjEntIndices(volMesh, entity_type,
279 [ # # ][ # # ]: 0 : iMesh_ALL_TOPOLOGIES, iBase_VERTEX, faces, verts, indices, offsets);
280 [ # # ]: 0 : IBERRCHK(m_err, "Trouble get the quads and nodes on the target surface.");
281 : 0 : num_vtx = verts.size();
282 : :
283 [ # # ][ # # ]: 0 : cout << "number of faces is " << faces.size() << endl;
[ # # ]
284 [ # # ][ # # ]: 0 : cout << "number of vertices is " << verts.size() << endl;
[ # # ]
285 : :
286 : : //set fixed flag on all vertices
287 [ # # ]: 0 : vector<int> tag_data(num_vtx, 1);
288 [ # # ][ # # ]: 0 : m_err = mk_core->imesh_instance()->setIntArrData(&verts[0], verts.size(),
289 [ # # ][ # # ]: 0 : fixed_tag, &tag_data[0]);
290 [ # # ]: 0 : IBERRCHK(m_err, "Trouble set an array of int data for nodes on the target surface.");
291 : :
292 : : //clear fixed flag for vertices contained directly in set
293 [ # # ][ # # ]: 0 : m_err = mk_core->imesh_instance()->getNumOfType(volMesh, iBase_VERTEX, count);
294 [ # # ]: 0 : IBERRCHK(m_err, "Trouble get the number of interior nodes on the target surface.");
295 : :
296 : : //get the interior mesh nodes on the target surface
297 : 0 : verts.clear();
298 [ # # ][ # # ]: 0 : cout << "Num of Vertices on the target surface is " << count << endl;
[ # # ]
299 : :
300 : : m_err = mk_core->imesh_instance()->getEntities(volMesh, iBase_VERTEX,
301 [ # # ][ # # ]: 0 : iMesh_ALL_TOPOLOGIES, verts);
302 [ # # ]: 0 : IBERRCHK(m_err, "Trouble get the number of interior nodes on the target surface.");
303 : :
304 : 0 : tag_data.clear();
305 [ # # ]: 0 : tag_data.resize(verts.size(), 0);
306 [ # # ][ # # ]: 0 : m_err = mk_core->imesh_instance()->setIntArrData(&verts[0], verts.size(),
307 [ # # ][ # # ]: 0 : fixed_tag, &tag_data[0]);
308 [ # # ]: 0 : IBERRCHK(m_err, "Trouble set the int data for interior nodes on the target surface.");
309 : :
310 : : //using the UntangleWrapper class to smooth the mesh with the inverted elements.
311 [ # # ]: 0 : UntangleWrapper smoother1;
312 : :
313 [ # # ]: 0 : smoother1.set_cpu_time_limit(1000);
314 [ # # ]: 0 : smoother1.set_vertex_movement_limit_factor(0.001);
315 : :
316 [ # # ]: 0 : smoother1.run_instructions(&mesh_adapter, mError);
317 : :
318 : : //Finally smooth the mesh
319 : : //Use the ShapeImprover class to smooth the target surface mesh
320 [ # # ]: 0 : ShapeImprover smoother2;
321 [ # # ]: 0 : smoother2.set_cpu_time_limit(1000);
322 [ # # ]: 0 : smoother2.set_vertex_movement_limit_factor(0.001);
323 [ # # ]: 0 : smoother2.run_instructions(&mesh_adapter, mError);
324 [ # # ][ # # ]: 0 : if (mError)
325 [ # # ][ # # ]: 0 : cout << "Mesquite error in volume mesh smoothing is as follows\n" << mError
326 [ # # ]: 0 : << std::endl;
327 : : /*
328 : :
329 : : SweepWrapper smoother3( 1e-6, "COORDINATES_MAP");
330 : : ShapeImprovementWrapper smoother2(mError);
331 : :
332 : :
333 : : smoother2.run_instructions(&mesh_adapter, mError);
334 : :
335 : : if (mError)
336 : : cout << "Mesquite error in volume mesh smoothing=" << mError << endl;
337 : : */
338 : :
339 : 0 : }
340 : :
341 : 12 : MeshImprove::~MeshImprove()
342 : : {
343 : 12 : cout << "It is over now in smoothing" << endl;
344 : 12 : }
345 : :
346 [ + - ][ + - ]: 156 : }
|