7 #include "GmshConfig.h"
22 #if defined(HAVE_QUADTRI)
23 #include "QuadTriExtruded3D.h"
41 to->
prisms.push_back(
new MPrism(v1, v2, v3, v4, v5, v6));
54 static int warningReg = 0;
58 for(
int i = 0; i < 3; i++)
59 if(v[i] == v[i + 3]) dup[j++] = i;
62 if(dup[0] == 0 && dup[1] == 1)
64 else if(dup[0] == 1 && dup[1] == 2)
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();
89 static int errorReg = 0;
90 static int warningReg = 0;
94 for(
int i = 0; i < 4; i++)
95 if(v[i] == v[i + 4]) dup[j++] = i;
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());
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",
124 if(v1 != v2 && v1 != v3 && v1 != v4 && v2 != v3 && v2 != v4 && v3 != v4)
131 double x[8], y[8],
z[8];
133 for(
int p = 0; p < n; 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();
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]);
143 for(
int p = 0; p < 2 * n; p++) {
146 Msg::Error(
"Could not find extruded vertex (%.16g, %.16g, %.16g)", x[p],
149 verts.push_back(tmp);
163 mesh_vertices.insert(mesh_vertices.end(), embedded.begin(), embedded.end());
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());
179 mesh_vertices.insert(mesh_vertices.end(), seam.begin(), seam.end());
182 for(std::size_t i = 0; i < mesh_vertices.size(); i++) {
186 double x = v->
x(), y = v->
y(),
z = v->
z();
189 if(!pos.
find(x, y,
z)) {
199 #if defined(HAVE_QUADTRI)
201 meshQuadToTriRegion(to, pos);
209 for(std::size_t i = 0; i < from->
triangles.size(); i++) {
212 std::vector<MVertex *> verts;
221 Msg::Error(
"Cannot extrude quadrangles without Recombine");
224 for(std::size_t i = 0; i < from->
quadrangles.size(); i++) {
227 std::vector<MVertex *> verts;
243 for(
auto itf =
faces.begin(); itf !=
faces.end(); itf++) {
244 pos.
insert((*itf)->mesh_vertices);
245 std::vector<MVertex *> embedded = (*itf)->getEmbeddedMeshVertices();
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);
291 carveHole(gr, it->first, it->second.first, it->second.second);
296 std::set<std::pair<MVertex *, MVertex *> > &
edges)
298 std::pair<MVertex *, MVertex *> p(std::min(v1, v2), std::max(v1, v2));
299 return edges.count(p);
303 std::set<std::pair<MVertex *, MVertex *> > &
edges)
305 std::pair<MVertex *, MVertex *> p(std::min(v1, v2), std::max(v1, v2));
310 std::set<std::pair<MVertex *, MVertex *> > &
edges)
312 std::pair<MVertex *, MVertex *> p(std::min(v1, v2), std::max(v1, v2));
318 std::set<std::pair<MVertex *, MVertex *> > &
edges,
int ntry)
324 for(std::size_t i = 0; i < from->
triangles.size(); i++) {
327 std::vector<MVertex *> v;
335 if(v[1]->getNum() < v[0]->getNum())
339 if(v[1]->getNum() < v[2]->getNum())
343 if(v[0]->getNum() < v[2]->getNum())
356 std::set<std::pair<MVertex *, MVertex *> > &
edges,
357 std::set<std::pair<MVertex *, MVertex *> > &edges_swap,
364 for(std::size_t i = 0; i < from->
triangles.size(); i++) {
367 std::vector<MVertex *> v;
378 else if(!
edgeExists(v[4], v[2], edges_swap)) {
384 else if(!
edgeExists(v[0], v[5], edges_swap)) {
401 else if(!
edgeExists(v[1], v[5], edges_swap)) {
407 else if(!
edgeExists(v[3], v[2], edges_swap)) {
422 std::set<std::pair<MVertex *, MVertex *> > &
edges)
428 for(std::size_t i = 0; i < from->
triangles.size(); i++) {
432 std::vector<MVertex *> v;
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);
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);
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);
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);
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);
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);
485 std::vector<GRegion *> regions;
486 #if defined(HAVE_QUADTRI)
487 std::vector<GRegion *> regions_quadToTri;
495 regions.push_back(*it);
498 #if defined(HAVE_QUADTRI)
503 regions_quadToTri.push_back(*it);
508 if(regions.empty())
return 0;
512 std::set<std::pair<MVertex *, MVertex *> >
edges;
514 for(
int ntry = 1; ntry <= 2; ntry++) {
516 for(std::size_t i = 0; i < regions.size(); i++)
520 std::set<std::pair<MVertex *, MVertex *> > edges_swap;
523 for(std::size_t i = 0; i < regions.size(); i++)
528 Msg::Info(
"Subdivision failed, trying alternative split");
534 "Unable to subdivide extruded mesh: change surface mesh or "
535 "recombine extrusion instead");
545 for(std::size_t i = 0; i < regions.size(); i++) {
547 for(std::size_t i = 0; i < gr->
tetrahedra.size(); i++)
550 for(std::size_t i = 0; i < gr->
hexahedra.size(); i++)
553 for(std::size_t i = 0; i < gr->
prisms.size(); i++)
delete gr->
prisms[i];
555 for(std::size_t i = 0; i < gr->
pyramids.size(); i++)
delete gr->
pyramids[i];
561 std::set<GFace *>
faces;
562 for(std::size_t i = 0; i < regions.size(); i++) {
564 std::vector<GFace *>
f = gr->
faces();
565 for(std::size_t i = 0; i <
f.size(); i++) {
581 for(
auto it =
faces.begin(); it !=
faces.end(); it++) {
585 for(std::size_t i = 0; i < gf->
triangles.size(); i++)
588 for(std::size_t i = 0; i < gf->
quadrangles.size(); i++)
597 Msg::Warning(
"Could not remesh all subdivided surfaces");
602 #if defined(HAVE_QUADTRI)
609 for(std::size_t i = 0; i < regions_quadToTri.size(); i++) {
610 GRegion *gr = regions_quadToTri[i];
614 meshQuadToTriRegionAfterGlobalSubdivide(gr, &
edges, pos_local);
619 for(std::size_t i = 0; i < regions.size(); i++) {
624 carveHole(gr, it->first, it->second.first, it->second.second);
628 #if defined(HAVE_QUADTRI)
629 for(std::size_t i = 0; i < regions_quadToTri.size(); i++) {
630 GRegion *gr = regions_quadToTri[i];
634 carveHole(gr, it->first, it->second.first, it->second.second);