gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
meshGRegionExtruded.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 #include <set>
7 #include "GmshConfig.h"
8 #include "GmshMessage.h"
9 #include "GModel.h"
10 #include "MTriangle.h"
11 #include "MQuadrangle.h"
12 #include "MTetrahedron.h"
13 #include "MHexahedron.h"
14 #include "MPrism.h"
15 #include "MPyramid.h"
16 #include "ExtrudeParams.h"
17 #include "meshGFace.h"
18 #include "meshGRegion.h"
19 #include "Context.h"
20 #include "MVertexRTree.h"
21 
22 #if defined(HAVE_QUADTRI)
23 #include "QuadTriExtruded3D.h"
24 #endif
25 
26 static void addTetrahedron(MVertex *v1, MVertex *v2, MVertex *v3, MVertex *v4,
27  GRegion *to)
28 {
29  to->tetrahedra.push_back(new MTetrahedron(v1, v2, v3, v4));
30 }
31 
32 static void addPyramid(MVertex *v1, MVertex *v2, MVertex *v3, MVertex *v4,
33  MVertex *v5, GRegion *to)
34 {
35  to->pyramids.push_back(new MPyramid(v1, v2, v3, v4, v5));
36 }
37 
38 static void addPrism(MVertex *v1, MVertex *v2, MVertex *v3, MVertex *v4,
39  MVertex *v5, MVertex *v6, GRegion *to)
40 {
41  to->prisms.push_back(new MPrism(v1, v2, v3, v4, v5, v6));
42 }
43 
44 static void addHexahedron(MVertex *v1, MVertex *v2, MVertex *v3, MVertex *v4,
45  MVertex *v5, MVertex *v6, MVertex *v7, MVertex *v8,
46  GRegion *to)
47 {
48  to->hexahedra.push_back(new MHexahedron(v1, v2, v3, v4, v5, v6, v7, v8));
49 }
50 
51 static void createPriPyrTet(std::vector<MVertex *> &v, GRegion *to,
52  MElement *source)
53 {
54  static int warningReg = 0;
55 
56  int dup[3];
57  int j = 0;
58  for(int i = 0; i < 3; i++)
59  if(v[i] == v[i + 3]) dup[j++] = i;
60 
61  if(j == 2) {
62  if(dup[0] == 0 && dup[1] == 1)
63  addTetrahedron(v[0], v[1], v[2], v[5], to);
64  else if(dup[0] == 1 && dup[1] == 2)
65  addTetrahedron(v[0], v[1], v[2], v[3], to);
66  else
67  addTetrahedron(v[0], v[1], v[2], v[4], to);
68  }
69  else if(j == 1) {
70  if(dup[0] == 0)
71  addPyramid(v[1], v[4], v[5], v[2], v[0], to);
72  else if(dup[0] == 1)
73  addPyramid(v[0], v[2], v[5], v[3], v[1], to);
74  else
75  addPyramid(v[0], v[1], v[4], v[3], v[2], to);
76  }
77  else {
78  addPrism(v[0], v[1], v[2], v[3], v[4], v[5], to);
79  if(j && warningReg != to->tag()) {
80  warningReg = to->tag();
81  Msg::Warning("Degenerated prism in extrusion of volume %d", to->tag());
82  }
83  }
84 }
85 
86 static void createHexPri(std::vector<MVertex *> &v, GRegion *to,
87  MElement *source)
88 {
89  static int errorReg = 0;
90  static int warningReg = 0;
91 
92  int dup[4];
93  int j = 0;
94  for(int i = 0; i < 4; i++)
95  if(v[i] == v[i + 4]) dup[j++] = i;
96 
97  if(j == 2) {
98  if(dup[0] == 0 && dup[1] == 1)
99  addPrism(v[0], v[3], v[7], v[1], v[2], v[6], to);
100  else if(dup[0] == 1 && dup[1] == 2)
101  addPrism(v[0], v[1], v[4], v[3], v[2], v[7], to);
102  else if(dup[0] == 2 && dup[1] == 3)
103  addPrism(v[0], v[3], v[4], v[1], v[2], v[5], to);
104  else if(dup[0] == 0 && dup[1] == 3)
105  addPrism(v[0], v[1], v[5], v[3], v[2], v[6], to);
106  else if(to->tag() != errorReg) {
107  errorReg = to->tag();
108  Msg::Error("Wrong hexahedron in extrusion of volume %d", to->tag());
109  }
110  }
111  else {
112  addHexahedron(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], to);
113  if(j && warningReg != to->tag()) {
114  warningReg = to->tag();
115  Msg::Warning("Degenerated hexahedron in extrusion of volume %d",
116  to->tag());
117  }
118  }
119 }
120 
121 static void createTet(MVertex *v1, MVertex *v2, MVertex *v3, MVertex *v4,
122  GRegion *to, MElement *source)
123 {
124  if(v1 != v2 && v1 != v3 && v1 != v4 && v2 != v3 && v2 != v4 && v3 != v4)
125  addTetrahedron(v1, v2, v3, v4, to);
126 }
127 
128 static int getExtrudedVertices(MElement *ele, ExtrudeParams *ep, int j, int k,
129  MVertexRTree &pos, std::vector<MVertex *> &verts)
130 {
131  double x[8], y[8], z[8];
132  int n = ele->getNumVertices();
133  for(int p = 0; p < n; p++) {
134  MVertex *v = ele->getVertex(p);
135  x[p] = x[p + n] = v->x();
136  y[p] = y[p + n] = v->y();
137  z[p] = z[p + n] = v->z();
138  }
139  for(int p = 0; p < n; p++) {
140  ep->Extrude(j, k, x[p], y[p], z[p]);
141  ep->Extrude(j, k + 1, x[p + n], y[p + n], z[p + n]);
142  }
143  for(int p = 0; p < 2 * n; p++) {
144  MVertex *tmp = pos.find(x[p], y[p], z[p]);
145  if(!tmp)
146  Msg::Error("Could not find extruded vertex (%.16g, %.16g, %.16g)", x[p],
147  y[p], z[p]);
148  else
149  verts.push_back(tmp);
150  }
151  return verts.size();
152 }
153 
154 static void extrudeMesh(GFace *from, GRegion *to, MVertexRTree &pos)
155 {
157 
158  // interior vertices
159  std::vector<MVertex *> mesh_vertices = from->mesh_vertices;
160 
161  // add all embedded vertices
162  std::vector<MVertex *> embedded = from->getEmbeddedMeshVertices();
163  mesh_vertices.insert(mesh_vertices.end(), embedded.begin(), embedded.end());
164 
165  // add all vertices on surface seams
166  std::set<MVertex *> seam;
167  std::vector<GEdge *> const &l_edges = from->edges();
168  for(auto it = l_edges.begin(); it != l_edges.end(); ++it) {
169  if((*it)->isSeam(from)) {
170  seam.insert((*it)->mesh_vertices.begin(), (*it)->mesh_vertices.end());
171  if((*it)->getBeginVertex())
172  seam.insert((*it)->getBeginVertex()->mesh_vertices.begin(),
173  (*it)->getBeginVertex()->mesh_vertices.end());
174  if((*it)->getEndVertex())
175  seam.insert((*it)->getEndVertex()->mesh_vertices.begin(),
176  (*it)->getEndVertex()->mesh_vertices.end());
177  }
178  }
179  mesh_vertices.insert(mesh_vertices.end(), seam.begin(), seam.end());
180 
181  // create extruded vertices
182  for(std::size_t i = 0; i < mesh_vertices.size(); i++) {
183  MVertex *v = mesh_vertices[i];
184  for(int j = 0; j < ep->mesh.NbLayer; j++) {
185  for(int k = 0; k < ep->mesh.NbElmLayer[j]; k++) {
186  double x = v->x(), y = v->y(), z = v->z();
187  ep->Extrude(j, k + 1, x, y, z);
188  if(j != ep->mesh.NbLayer - 1 || k != ep->mesh.NbElmLayer[j] - 1) {
189  if(!pos.find(x, y, z)) {
190  MVertex *newv = new MVertex(x, y, z, to);
191  to->mesh_vertices.push_back(newv);
192  pos.insert(newv);
193  }
194  }
195  }
196  }
197  }
198 
199 #if defined(HAVE_QUADTRI)
200  if(ep && ep->mesh.ExtrudeMesh && ep->mesh.QuadToTri && ep->mesh.Recombine) {
201  meshQuadToTriRegion(to, pos);
202  return;
203  }
204 #endif
205 
206  // create elements (note that it would be faster to access the *interior*
207  // nodes by direct indexing, but it's just simpler to query everything by
208  // position)
209  for(std::size_t i = 0; i < from->triangles.size(); i++) {
210  for(int j = 0; j < ep->mesh.NbLayer; j++) {
211  for(int k = 0; k < ep->mesh.NbElmLayer[j]; k++) {
212  std::vector<MVertex *> verts;
213  if(getExtrudedVertices(from->triangles[i], ep, j, k, pos, verts) == 6) {
214  createPriPyrTet(verts, to, from->triangles[i]);
215  }
216  }
217  }
218  }
219 
220  if(from->quadrangles.size() && !ep->mesh.Recombine) {
221  Msg::Error("Cannot extrude quadrangles without Recombine");
222  }
223  else {
224  for(std::size_t i = 0; i < from->quadrangles.size(); i++) {
225  for(int j = 0; j < ep->mesh.NbLayer; j++) {
226  for(int k = 0; k < ep->mesh.NbElmLayer[j]; k++) {
227  std::vector<MVertex *> verts;
228  if(getExtrudedVertices(from->quadrangles[i], ep, j, k, pos, verts) ==
229  8)
230  createHexPri(verts, to, from->quadrangles[i]);
231  }
232  }
233  }
234  }
235 }
236 
237 static void insertAllVertices(GRegion *gr, MVertexRTree &pos)
238 {
239  pos.insert(gr->mesh_vertices);
240  std::vector<MVertex *> embedded = gr->getEmbeddedMeshVertices();
241  pos.insert(embedded);
242  std::vector<GFace *> faces = gr->faces();
243  for(auto itf = faces.begin(); itf != faces.end(); itf++) {
244  pos.insert((*itf)->mesh_vertices);
245  std::vector<MVertex *> embedded = (*itf)->getEmbeddedMeshVertices();
246  pos.insert(embedded);
247  std::vector<GEdge *> const &edges = (*itf)->edges();
248  for(auto ite = edges.begin(); ite != edges.end(); ite++) {
249  pos.insert((*ite)->mesh_vertices);
250  if((*ite)->getBeginVertex())
251  pos.insert((*ite)->getBeginVertex()->mesh_vertices);
252  if((*ite)->getEndVertex())
253  pos.insert((*ite)->getEndVertex()->mesh_vertices);
254  }
255  }
256 }
257 
259 {
260  gr->model()->setCurrentMeshEntity(gr);
261 
262  if(gr->geomType() == GEntity::DiscreteVolume) return;
263 
265 
266  if(!ep || !ep->mesh.ExtrudeMesh || ep->geo.Mode != EXTRUDED_ENTITY) return;
267 
268  Msg::Info("Meshing volume %d (Extruded)", gr->tag());
269 
270  // destroy the mesh if it exists
271  deMeshGRegion dem;
272  dem(gr);
273 
274  // build an rtree with all the vertices on the boundary of gr
275  MVertexRTree pos(CTX::instance()->geom.tolerance * CTX::instance()->lc);
276  insertAllVertices(gr, pos);
277 
278  // volume is extruded from a surface
279  GFace *from = gr->model()->getFaceByTag(std::abs(ep->geo.Source));
280  if(!from) {
281  Msg::Error("Unknown source surface %d for extrusion", ep->geo.Source);
282  return;
283  }
284 
285  extrudeMesh(from, gr, pos);
286 
287  // carve holes if any (only do it now if the mesh is final, i.e., if
288  // the mesh is recombined)
289  if(ep->mesh.Holes.size() && ep->mesh.Recombine) {
290  for(auto it = ep->mesh.Holes.begin(); it != ep->mesh.Holes.end(); it++)
291  carveHole(gr, it->first, it->second.first, it->second.second);
292  }
293 }
294 
295 static int edgeExists(MVertex *v1, MVertex *v2,
296  std::set<std::pair<MVertex *, MVertex *> > &edges)
297 {
298  std::pair<MVertex *, MVertex *> p(std::min(v1, v2), std::max(v1, v2));
299  return edges.count(p);
300 }
301 
302 static void createEdge(MVertex *v1, MVertex *v2,
303  std::set<std::pair<MVertex *, MVertex *> > &edges)
304 {
305  std::pair<MVertex *, MVertex *> p(std::min(v1, v2), std::max(v1, v2));
306  edges.insert(p);
307 }
308 
309 static void deleteEdge(MVertex *v1, MVertex *v2,
310  std::set<std::pair<MVertex *, MVertex *> > &edges)
311 {
312  std::pair<MVertex *, MVertex *> p(std::min(v1, v2), std::max(v1, v2));
313  edges.erase(p);
314 }
315 
316 // subdivide the 3 lateral faces of each prism
317 static void phase1(GRegion *gr, MVertexRTree &pos,
318  std::set<std::pair<MVertex *, MVertex *> > &edges, int ntry)
319 {
321  GFace *from = gr->model()->getFaceByTag(std::abs(ep->geo.Source));
322  if(!from) return;
323 
324  for(std::size_t i = 0; i < from->triangles.size(); i++) {
325  for(int j = 0; j < ep->mesh.NbLayer; j++) {
326  for(int k = 0; k < ep->mesh.NbElmLayer[j]; k++) {
327  std::vector<MVertex *> v;
328  if(getExtrudedVertices(from->triangles[i], ep, j, k, pos, v) == 6) {
329  if(ntry == 1) {
330  if(!edgeExists(v[0], v[4], edges)) createEdge(v[1], v[3], edges);
331  if(!edgeExists(v[4], v[2], edges)) createEdge(v[1], v[5], edges);
332  if(!edgeExists(v[3], v[2], edges)) createEdge(v[0], v[5], edges);
333  }
334  else { // from Michel Benhamou
335  if(v[1]->getNum() < v[0]->getNum())
336  createEdge(v[1], v[3], edges);
337  else
338  createEdge(v[0], v[4], edges);
339  if(v[1]->getNum() < v[2]->getNum())
340  createEdge(v[1], v[5], edges);
341  else
342  createEdge(v[4], v[2], edges);
343  if(v[0]->getNum() < v[2]->getNum())
344  createEdge(v[0], v[5], edges);
345  else
346  createEdge(v[3], v[2], edges);
347  }
348  }
349  }
350  }
351  }
352 }
353 
354 // modify lateral edges to make them "tet-compatible"
355 static void phase2(GRegion *gr, MVertexRTree &pos,
356  std::set<std::pair<MVertex *, MVertex *> > &edges,
357  std::set<std::pair<MVertex *, MVertex *> > &edges_swap,
358  int &swap)
359 {
361  GFace *from = gr->model()->getFaceByTag(std::abs(ep->geo.Source));
362  if(!from) return;
363 
364  for(std::size_t i = 0; i < from->triangles.size(); i++) {
365  for(int j = 0; j < ep->mesh.NbLayer; j++) {
366  for(int k = 0; k < ep->mesh.NbElmLayer[j]; k++) {
367  std::vector<MVertex *> v;
368  if(getExtrudedVertices(from->triangles[i], ep, j, k, pos, v) == 6) {
369  if(edgeExists(v[3], v[1], edges) && edgeExists(v[4], v[2], edges) &&
370  edgeExists(v[0], v[5], edges)) {
371  swap++;
372  if(!edgeExists(v[3], v[1], edges_swap)) {
373  deleteEdge(v[3], v[1], edges);
374  createEdge(v[0], v[4], edges);
375  createEdge(v[3], v[1], edges_swap);
376  createEdge(v[0], v[4], edges_swap);
377  }
378  else if(!edgeExists(v[4], v[2], edges_swap)) {
379  deleteEdge(v[4], v[2], edges);
380  createEdge(v[1], v[5], edges);
381  createEdge(v[4], v[2], edges_swap);
382  createEdge(v[1], v[5], edges_swap);
383  }
384  else if(!edgeExists(v[0], v[5], edges_swap)) {
385  deleteEdge(v[0], v[5], edges);
386  createEdge(v[3], v[2], edges);
387  createEdge(v[0], v[5], edges_swap);
388  createEdge(v[3], v[2], edges_swap);
389  }
390  }
391  else if(edgeExists(v[0], v[4], edges) &&
392  edgeExists(v[1], v[5], edges) &&
393  edgeExists(v[3], v[2], edges)) {
394  swap++;
395  if(!edgeExists(v[0], v[4], edges_swap)) {
396  deleteEdge(v[0], v[4], edges);
397  createEdge(v[3], v[1], edges);
398  createEdge(v[0], v[4], edges_swap);
399  createEdge(v[3], v[1], edges_swap);
400  }
401  else if(!edgeExists(v[1], v[5], edges_swap)) {
402  deleteEdge(v[1], v[5], edges);
403  createEdge(v[4], v[2], edges);
404  createEdge(v[1], v[5], edges_swap);
405  createEdge(v[4], v[2], edges_swap);
406  }
407  else if(!edgeExists(v[3], v[2], edges_swap)) {
408  deleteEdge(v[3], v[2], edges);
409  createEdge(v[0], v[5], edges);
410  createEdge(v[3], v[2], edges_swap);
411  createEdge(v[0], v[5], edges_swap);
412  }
413  }
414  }
415  }
416  }
417  }
418 }
419 
420 // create tets
421 static void phase3(GRegion *gr, MVertexRTree &pos,
422  std::set<std::pair<MVertex *, MVertex *> > &edges)
423 {
425  GFace *from = gr->model()->getFaceByTag(std::abs(ep->geo.Source));
426  if(!from) return;
427 
428  for(std::size_t i = 0; i < from->triangles.size(); i++) {
429  MTriangle *tri = from->triangles[i];
430  for(int j = 0; j < ep->mesh.NbLayer; j++) {
431  for(int k = 0; k < ep->mesh.NbElmLayer[j]; k++) {
432  std::vector<MVertex *> v;
433  if(getExtrudedVertices(tri, ep, j, k, pos, v) == 6) {
434  if(edgeExists(v[3], v[1], edges) && edgeExists(v[4], v[2], edges) &&
435  edgeExists(v[3], v[2], edges)) {
436  createTet(v[0], v[1], v[2], v[3], gr, tri);
437  createTet(v[3], v[4], v[5], v[2], gr, tri);
438  createTet(v[1], v[3], v[4], v[2], gr, tri);
439  }
440  else if(edgeExists(v[3], v[1], edges) &&
441  edgeExists(v[1], v[5], edges) &&
442  edgeExists(v[3], v[2], edges)) {
443  createTet(v[0], v[1], v[2], v[3], gr, tri);
444  createTet(v[3], v[4], v[5], v[1], gr, tri);
445  createTet(v[3], v[1], v[5], v[2], gr, tri);
446  }
447  else if(edgeExists(v[3], v[1], edges) &&
448  edgeExists(v[1], v[5], edges) &&
449  edgeExists(v[5], v[0], edges)) {
450  createTet(v[0], v[1], v[2], v[5], gr, tri);
451  createTet(v[3], v[4], v[5], v[1], gr, tri);
452  createTet(v[1], v[3], v[5], v[0], gr, tri);
453  }
454  else if(edgeExists(v[4], v[0], edges) &&
455  edgeExists(v[4], v[2], edges) &&
456  edgeExists(v[3], v[2], edges)) {
457  createTet(v[0], v[1], v[2], v[4], gr, tri);
458  createTet(v[3], v[4], v[5], v[2], gr, tri);
459  createTet(v[0], v[3], v[4], v[2], gr, tri);
460  }
461  else if(edgeExists(v[4], v[0], edges) &&
462  edgeExists(v[4], v[2], edges) &&
463  edgeExists(v[5], v[0], edges)) {
464  createTet(v[0], v[1], v[2], v[4], gr, tri);
465  createTet(v[3], v[4], v[5], v[0], gr, tri);
466  createTet(v[0], v[2], v[4], v[5], gr, tri);
467  }
468  else if(edgeExists(v[4], v[0], edges) &&
469  edgeExists(v[1], v[5], edges) &&
470  edgeExists(v[5], v[0], edges)) {
471  createTet(v[0], v[1], v[2], v[5], gr, tri);
472  createTet(v[3], v[4], v[5], v[0], gr, tri);
473  createTet(v[0], v[1], v[4], v[5], gr, tri);
474  }
475  }
476  }
477  }
478  }
479 }
480 
482 {
483  // get all non-recombined extruded regions and vertices; also, create a vector
484  // of quadToTri regions that have NOT been meshed yet
485  std::vector<GRegion *> regions;
486 #if defined(HAVE_QUADTRI)
487  std::vector<GRegion *> regions_quadToTri;
488 #endif
489 
490  MVertexRTree pos(CTX::instance()->geom.tolerance * CTX::instance()->lc);
491  for(auto it = m->firstRegion(); it != m->lastRegion(); it++) {
492  ExtrudeParams *ep = (*it)->meshAttributes.extrude;
493  if(ep && ep->mesh.ExtrudeMesh && ep->geo.Mode == EXTRUDED_ENTITY &&
494  !ep->mesh.Recombine) {
495  regions.push_back(*it);
496  insertAllVertices(*it, pos);
497  }
498 #if defined(HAVE_QUADTRI)
499  // create vector of valid quadToTri regions...not all will necessarily be
500  // meshed here.
501  if(ep && ep->mesh.ExtrudeMesh && ep->geo.Mode == EXTRUDED_ENTITY &&
502  ep->mesh.Recombine && ep->mesh.QuadToTri) {
503  regions_quadToTri.push_back(*it);
504  }
505 #endif
506  }
507 
508  if(regions.empty()) return 0;
509 
510  Msg::Info("Subdividing extruded mesh");
511 
512  std::set<std::pair<MVertex *, MVertex *> > edges;
513 
514  for(int ntry = 1; ntry <= 2; ntry++) {
515  // create edges on lateral sides of "prisms"
516  for(std::size_t i = 0; i < regions.size(); i++)
517  phase1(regions[i], pos, edges, ntry);
518  // swap lateral edges to make them "tet-compatible"
519  int j = 0, swap;
520  std::set<std::pair<MVertex *, MVertex *> > edges_swap;
521  do {
522  swap = 0;
523  for(std::size_t i = 0; i < regions.size(); i++)
524  phase2(regions[i], pos, edges, edges_swap, swap);
525  Msg::Info("Swapping %d", swap);
526  if(j && j == swap) {
527  if(ntry == 1) {
528  Msg::Info("Subdivision failed, trying alternative split");
529  edges.clear();
530  break;
531  }
532  else {
533  Msg::Error(
534  "Unable to subdivide extruded mesh: change surface mesh or "
535  "recombine extrusion instead");
536  return -1;
537  }
538  }
539  j = swap;
540  } while(swap);
541  if(!swap) break;
542  }
543 
544  // delete volume elements and create tetrahedra instead
545  for(std::size_t i = 0; i < regions.size(); i++) {
546  GRegion *gr = regions[i];
547  for(std::size_t i = 0; i < gr->tetrahedra.size(); i++)
548  delete gr->tetrahedra[i];
549  gr->tetrahedra.clear();
550  for(std::size_t i = 0; i < gr->hexahedra.size(); i++)
551  delete gr->hexahedra[i];
552  gr->hexahedra.clear();
553  for(std::size_t i = 0; i < gr->prisms.size(); i++) delete gr->prisms[i];
554  gr->prisms.clear();
555  for(std::size_t i = 0; i < gr->pyramids.size(); i++) delete gr->pyramids[i];
556  gr->pyramids.clear();
557  phase3(gr, pos, edges);
558  }
559 
560  // remesh bounding surfaces, to make them compatible with the volume mesh
561  std::set<GFace *> faces;
562  for(std::size_t i = 0; i < regions.size(); i++) {
563  GRegion *gr = regions[i];
564  std::vector<GFace *> f = gr->faces();
565  for(std::size_t i = 0; i < f.size(); i++) {
566  ExtrudeParams *ep = f[i]->meshAttributes.extrude;
567  // TODO: this does not yet handle swapping of edges in COPIED_ENTITY
568  // surfaces, whose mesh is copied during extrusion (the "top"
569  // surface). PS: we will need to distinguish the old boundary layer case
570  // if we include these "copied" meshes
571  if(ep && ep->mesh.ExtrudeMesh && ep->geo.Mode == EXTRUDED_ENTITY &&
572  !ep->mesh.Recombine) {
573  f[i]->meshStatistics.status = GFace::PENDING;
574  faces.insert(f[i]);
575  }
576  }
577  }
578  int nIter = 0;
579  while(1) {
580  int nPending = 0;
581  for(auto it = faces.begin(); it != faces.end(); it++) {
582  GFace *gf = *it;
584  Msg::Info("Remeshing surface %d", gf->tag());
585  for(std::size_t i = 0; i < gf->triangles.size(); i++)
586  delete gf->triangles[i];
587  gf->triangles.clear();
588  for(std::size_t i = 0; i < gf->quadrangles.size(); i++)
589  delete gf->quadrangles[i];
590  gf->quadrangles.clear();
592  nPending++;
593  }
594  }
595  if(!nPending) break;
596  if(nIter++ > 10) {
597  Msg::Warning("Could not remesh all subdivided surfaces");
598  break;
599  }
600  }
601 
602 #if defined(HAVE_QUADTRI)
603  // now mesh the QuadToTri regions. Everything can be done locally for each
604  // quadToTri region, but still use edge set from above just to make sure
605  // laterals get remeshed properly ( QuadToTriEdgeGenerator detects if the
606  // neighbor has been meshed or if a lateral surface should remain static for
607  // any other reason). If this function detects allNonGlobalSharedLaterals, it
608  // won't mesh the region (should already be done in ExtrudeMesh).
609  for(std::size_t i = 0; i < regions_quadToTri.size(); i++) {
610  GRegion *gr = regions_quadToTri[i];
611  MVertexRTree pos_local(CTX::instance()->geom.tolerance *
612  CTX::instance()->lc);
613  insertAllVertices(gr, pos_local);
614  meshQuadToTriRegionAfterGlobalSubdivide(gr, &edges, pos_local);
615  }
616 #endif
617 
618  // carve holes if any (TODO: update extrusion information)
619  for(std::size_t i = 0; i < regions.size(); i++) {
620  GRegion *gr = regions[i];
622  if(ep->mesh.Holes.size()) {
623  for(auto it = ep->mesh.Holes.begin(); it != ep->mesh.Holes.end(); it++)
624  carveHole(gr, it->first, it->second.first, it->second.second);
625  }
626  }
627 
628 #if defined(HAVE_QUADTRI)
629  for(std::size_t i = 0; i < regions_quadToTri.size(); i++) {
630  GRegion *gr = regions_quadToTri[i];
632  if(ep->mesh.Holes.size()) {
633  for(auto it = ep->mesh.Holes.begin(); it != ep->mesh.Holes.end(); it++)
634  carveHole(gr, it->first, it->second.first, it->second.second);
635  }
636  }
637 #endif
638 
639  return 1;
640 }
MTriangle.h
GFace::edges
virtual std::vector< GEdge * > const & edges() const
Definition: GFace.h:121
GFace::status
GEntity::MeshGenerationStatus status
Definition: GFace.h:395
deleteEdge
static void deleteEdge(MVertex *v1, MVertex *v2, std::set< std::pair< MVertex *, MVertex * > > &edges)
Definition: meshGRegionExtruded.cpp:309
extrudeMesh
static void extrudeMesh(GFace *from, GRegion *to, MVertexRTree &pos)
Definition: meshGRegionExtruded.cpp:154
meshGRegionExtruded::operator()
void operator()(GRegion *)
Definition: meshGRegionExtruded.cpp:258
MTetrahedron
Definition: MTetrahedron.h:34
GFace
Definition: GFace.h:33
GFace::triangles
std::vector< MTriangle * > triangles
Definition: GFace.h:428
Msg::Info
static void Info(const char *fmt,...)
Definition: GmshMessage.cpp:587
GEntity::model
GModel * model() const
Definition: GEntity.h:277
phase1
static void phase1(GRegion *gr, MVertexRTree &pos, std::set< std::pair< MVertex *, MVertex * > > &edges, int ntry)
Definition: meshGRegionExtruded.cpp:317
MVertex
Definition: MVertex.h:24
Msg::Warning
static void Warning(const char *fmt,...)
Definition: GmshMessage.cpp:543
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
MVertex::z
double z() const
Definition: MVertex.h:62
LegendrePolynomials::f
void f(int n, double u, double *val)
Definition: orthogonalBasis.cpp:77
GModel::getFaceByTag
GFace * getFaceByTag(int n) const
Definition: GModel.cpp:326
phase3
static void phase3(GRegion *gr, MVertexRTree &pos, std::set< std::pair< MVertex *, MVertex * > > &edges)
Definition: meshGRegionExtruded.cpp:421
phase2
static void phase2(GRegion *gr, MVertexRTree &pos, std::set< std::pair< MVertex *, MVertex * > > &edges, std::set< std::pair< MVertex *, MVertex * > > &edges_swap, int &swap)
Definition: meshGRegionExtruded.cpp:355
MPyramid
Definition: MPyramid.h:32
MPrism
Definition: MPrism.h:34
GmshMessage.h
edges
static int edges[6][2]
Definition: meshGRegionLocalMeshMod.cpp:23
ExtrudeParams::geo
struct ExtrudeParams::@15 geo
addHexahedron
static void addHexahedron(MVertex *v1, MVertex *v2, MVertex *v3, MVertex *v4, MVertex *v5, MVertex *v6, MVertex *v7, MVertex *v8, GRegion *to)
Definition: meshGRegionExtruded.cpp:44
addTetrahedron
static void addTetrahedron(MVertex *v1, MVertex *v2, MVertex *v3, MVertex *v4, GRegion *to)
Definition: meshGRegionExtruded.cpp:26
MElement::getNumVertices
virtual std::size_t getNumVertices() const =0
GFace::quadrangles
std::vector< MQuadrangle * > quadrangles
Definition: GFace.h:429
ExtrudeParams::QuadToTri
int QuadToTri
Definition: ExtrudeParams.h:38
deMeshGRegion
Definition: meshGRegion.h:48
getExtrudedVertices
static int getExtrudedVertices(MElement *ele, ExtrudeParams *ep, int j, int k, MVertexRTree &pos, std::vector< MVertex * > &verts)
Definition: meshGRegionExtruded.cpp:128
CTX::instance
static CTX * instance()
Definition: Context.cpp:122
MElement::getVertex
virtual const MVertex * getVertex(int num) const =0
GRegion::faces
virtual std::vector< GFace * > faces() const
Definition: GRegion.h:64
GRegion::hexahedra
std::vector< MHexahedron * > hexahedra
Definition: GRegion.h:164
GRegion::extrude
ExtrudeParams * extrude
Definition: GRegion.h:148
addPrism
static void addPrism(MVertex *v1, MVertex *v2, MVertex *v3, MVertex *v4, MVertex *v5, MVertex *v6, GRegion *to)
Definition: meshGRegionExtruded.cpp:38
ExtrudeParams::mesh
struct ExtrudeParams::@14 mesh
GFace::meshStatistics
struct GFace::@19 meshStatistics
GEntity::mesh_vertices
std::vector< MVertex * > mesh_vertices
Definition: GEntity.h:56
MHexahedron.h
EXTRUDED_ENTITY
#define EXTRUDED_ENTITY
Definition: ExtrudeParams.h:17
MVertexRTree::insert
MVertex * insert(MVertex *v, bool warnIfExists=false, std::set< MVertex *, MVertexPtrLessThan > *duplicates=nullptr)
Definition: MVertexRTree.h:38
CTX::lc
double lc
Definition: Context.h:234
createHexPri
static void createHexPri(std::vector< MVertex * > &v, GRegion *to, MElement *source)
Definition: meshGRegionExtruded.cpp:86
swap
void swap(double &a, double &b)
Definition: meshTriangulation.cpp:27
GRegion::getEmbeddedMeshVertices
std::vector< MVertex * > getEmbeddedMeshVertices() const
Definition: GRegion.cpp:571
GEntity::DiscreteVolume
@ DiscreteVolume
Definition: GEntity.h:120
GModel
Definition: GModel.h:44
addPyramid
static void addPyramid(MVertex *v1, MVertex *v2, MVertex *v3, MVertex *v4, MVertex *v5, GRegion *to)
Definition: meshGRegionExtruded.cpp:32
ExtrudeParams::NbLayer
int NbLayer
Definition: ExtrudeParams.h:39
ExtrudeParams.h
MPyramid.h
GEntity::geomType
virtual GeomType geomType() const
Definition: GEntity.h:238
SubdivideExtrudedMesh
int SubdivideExtrudedMesh(GModel *m)
Definition: meshGRegionExtruded.cpp:481
ExtrudeParams::Holes
std::map< int, std::pair< double, std::vector< int > > > Holes
Definition: ExtrudeParams.h:45
ExtrudeParams::Recombine
bool Recombine
Definition: ExtrudeParams.h:37
MHexahedron
Definition: MHexahedron.h:28
ExtrudeParams::Mode
int Mode
Definition: ExtrudeParams.h:49
MElement
Definition: MElement.h:30
ExtrudeParams::NbElmLayer
std::vector< int > NbElmLayer
Definition: ExtrudeParams.h:40
GEntity::tag
int tag() const
Definition: GEntity.h:280
MVertexRTree.h
ExtrudeParams::Extrude
void Extrude(int iLayer, int iElemLayer, double &dx, double &dy, double &dz)
Definition: ExtrudeParams.cpp:51
GRegion
Definition: GRegion.h:28
ExtrudeParams::ExtrudeMesh
bool ExtrudeMesh
Definition: ExtrudeParams.h:36
GRegion::prisms
std::vector< MPrism * > prisms
Definition: GRegion.h:165
MTriangle
Definition: MTriangle.h:26
ExtrudeParams::Source
int Source
Definition: ExtrudeParams.h:51
createEdge
static void createEdge(MVertex *v1, MVertex *v2, std::set< std::pair< MVertex *, MVertex * > > &edges)
Definition: meshGRegionExtruded.cpp:302
GRegion::pyramids
std::vector< MPyramid * > pyramids
Definition: GRegion.h:166
GModel::firstRegion
riter firstRegion()
Definition: GModel.h:354
GModel::lastRegion
riter lastRegion()
Definition: GModel.h:358
meshGFace.h
Context.h
MTetrahedron.h
MVertexRTree::find
MVertex * find(double x, double y, double z)
Definition: MVertexRTree.h:70
z
const double z
Definition: GaussQuadratureQuad.cpp:56
MQuadrangle.h
GRegion::meshAttributes
struct GRegion::@20 meshAttributes
MPrism.h
edgeExists
static int edgeExists(MVertex *v1, MVertex *v2, std::set< std::pair< MVertex *, MVertex * > > &edges)
Definition: meshGRegionExtruded.cpp:295
createPriPyrTet
static void createPriPyrTet(std::vector< MVertex * > &v, GRegion *to, MElement *source)
Definition: meshGRegionExtruded.cpp:51
createTet
static void createTet(MVertex *v1, MVertex *v2, MVertex *v3, MVertex *v4, GRegion *to, MElement *source)
Definition: meshGRegionExtruded.cpp:121
meshGRegion.h
MVertexRTree
Definition: MVertexRTree.h:16
GModel.h
MVertex::y
double y() const
Definition: MVertex.h:61
GFace::getEmbeddedMeshVertices
std::vector< MVertex * > getEmbeddedMeshVertices(bool force=false) const
Definition: GFace.cpp:369
ExtrudeParams
Definition: ExtrudeParams.h:26
GEntity::PENDING
@ PENDING
Definition: GEntity.h:130
MeshExtrudedSurface
int MeshExtrudedSurface(GFace *gf, std::set< std::pair< MVertex *, MVertex * > > *constrainedEdges=nullptr)
Definition: meshGFaceExtruded.cpp:291
carveHole
void carveHole(GRegion *gr, int num, double distance, std::vector< int > &surfaces)
Definition: meshGRegionCarveHole.cpp:19
insertAllVertices
static void insertAllVertices(GRegion *gr, MVertexRTree &pos)
Definition: meshGRegionExtruded.cpp:237
GModel::setCurrentMeshEntity
void setCurrentMeshEntity(GEntity *e)
Definition: GModel.cpp:2202
GRegion::tetrahedra
std::vector< MTetrahedron * > tetrahedra
Definition: GRegion.h:163
MVertex::x
double x() const
Definition: MVertex.h:60
faces
static int faces[4][3]
Definition: meshGRegionDelaunayInsertion.cpp:165