46 for (
size_t i = 0; i < bnd.size(); i += 2)
68 FILE *view_t =
nullptr;
72 sprintf(name,
"trueBoundary%d.pos", gf->
tag());
73 view_t =
Fopen(name,
"w");
75 fprintf(view_t,
"View \"True Boundary\"{\n");
77 std::vector<GEdge *> edg = gf->
edges();
78 std::set<GEdge *>
edges(edg.begin(), edg.end());
80 for (
auto it =
edges.begin(); it !=
edges.end(); ++it)
85 int NITER = ge->
isSeam(gf) ? 2 : 1;
86 for (
int i = 0; i < NITER; i++)
88 int count = NITER == 2 ? 300 : 300;
89 for (
int k = 0; k < count; k++)
91 double t = (double)k / (count - 1);
92 double xi = r.
low() + (r.
high() - r.
low()) * t;
98 fprintf(view_t,
"SL(%g,%g,%g,%g,%g,%g){%d,%d};\n", p[k - 1].x(), p[k - 1].y(), 0.0, p[k].x(),
99 p[k].y(), 0.0, ge->
tag(), ge->
tag());
101 bnd.push_back(p[k - 1]);
109 fprintf(view_t,
"};\n");
121 for (std::size_t i = 0; i < gf->
triangles.size(); i++)
127 worst = std::min(worst, q);
128 best = std::max(best, q);
138 std::map<GEdge *, std::vector<MLine *>>
_backup;
139 std::map<MEdge, MVertex *, MEdgeLessThan>
_middle;
142 std::vector<MQuadrangle *> qnew;
143 std::map<MEdge, MVertex *, MEdgeLessThan> eds;
148 for (
int j = 0; j < 3; j++)
154 auto it2 = eds.find(E);
156 if (it ==
_middle.end() && it2 == eds.end())
179 if (v[j]->getParameter(0, u) && v[j]->onWhat()->dim() == 1)
191 double XX = (v[0]->
x() + v[1]->
x() + v[2]->
x()) * (1. / 3.);
192 double YY = (v[0]->
y() + v[1]->
y() + v[2]->
y()) * (1. / 3.);
193 double ZZ = (v[0]->
z() + v[1]->
z() + v[2]->
z()) * (1. / 3.);
206 for (
int j = 0; j < 4; j++)
212 auto it2 = eds.find(E);
214 if (it ==
_middle.end() && it2 == eds.end())
237 if (v[j]->getParameter(0, u) && v[j]->onWhat()->dim() == 1)
251 double XX = 0.25 * (v[0]->
x() + v[1]->
x() + v[2]->
x() + v[3]->
x());
252 double YY = 0.25 * (v[0]->
y() + v[1]->
y() + v[2]->
y() + v[3]->
y());
253 double ZZ = 0.25 * (v[0]->
z() + v[1]->
z() + v[2]->
z() + v[3]->
z());
267 auto ite =
edges.begin();
268 while (ite !=
edges.end())
270 for (std::size_t i = 0; i < (*ite)->lines.size(); i++)
272 delete (*ite)->lines[i];
292 Msg::Error(
"Full-quad recombination not ready yet for periodic surfaces");
295 std::vector<GEdge *>
const &
edges = gf->
edges();
296 auto ite =
edges.begin();
297 while (ite !=
edges.end())
301 Msg::Warning(
"Full-quad recombination only compatible with "
302 "transfinite meshes if those are performed first");
304 if (!(*ite)->isMeshDegenerated())
306 std::vector<MLine *> temp;
307 (*ite)->mesh_vertices.clear();
308 for (std::size_t i = 0; i < (*ite)->lines.size(); i += 2)
310 if (i + 1 >= (*ite)->lines.size())
315 MVertex *v1 = (*ite)->lines[i]->getVertex(0);
316 MVertex *v2 = (*ite)->lines[i]->getVertex(1);
317 MVertex *v3 = (*ite)->lines[i + 1]->getVertex(1);
318 v2->
x() = 0.5 * (v1->
x() + v3->
x());
319 v2->
y() = 0.5 * (v1->
y() + v3->
y());
320 v2->
z() = 0.5 * (v1->
z() + v3->
z());
321 temp.push_back(
new MLine(v1, v3));
323 (*ite)->mesh_vertices.push_back(v1);
327 (*ite)->lines = temp;
353 std::map<MVertex *, MVertex *> vs2vt;
357 std::vector<GVertex *> s_vtcs = source->
vertices();
361 if ((*it)->getBeginVertex())
362 s_vtcs.push_back((*it)->getBeginVertex());
363 if ((*it)->getEndVertex())
364 s_vtcs.push_back((*it)->getEndVertex());
366 std::vector<GVertex *> t_vtcs = target->
vertices();
370 if ((*it)->getBeginVertex())
371 t_vtcs.push_back((*it)->getBeginVertex());
372 if ((*it)->getEndVertex())
373 t_vtcs.push_back((*it)->getEndVertex());
376 if (s_vtcs.size() != t_vtcs.size())
378 Msg::Info(
"Periodicity imposed on topologically incompatible surfaces"
380 s_vtcs.size(), t_vtcs.size());
383 std::set<GVertex *> checkVtcs(s_vtcs.begin(), s_vtcs.end());
385 for (
auto tvIter = t_vtcs.begin(); tvIter != t_vtcs.end(); ++tvIter)
392 Msg::Error(
"Periodic meshing of surface %d with surface %d: "
393 "point %d has no periodic counterpart",
394 target->
tag(), source->
tag(), gvt->
tag());
398 GVertex *gvs = gvsIter->second;
399 if (checkVtcs.find(gvs) == checkVtcs.end())
402 Msg::Error(
"Periodic meshing of surface %d with surface %d: "
403 "point %d has periodic counterpart %d outside of source surface",
407 Msg::Error(
"Periodic meshing of surface %d with surface %d: "
408 "point %d has no periodic counterpart",
409 target->
tag(), source->
tag(), gvt->
tag());
423 std::vector<GEdge *> s_edges = source->
edges();
425 std::vector<GEdge *> t_edges = target->
edges();
428 std::set<GEdge *> checkEdges;
429 checkEdges.insert(s_edges.begin(), s_edges.end());
431 for (
auto te_iter = t_edges.begin(); te_iter != t_edges.end(); ++te_iter)
433 GEdge *get = *te_iter;
438 Msg::Error(
"Periodic meshing of surface %d with surface %d: "
439 "curve %d has no periodic counterpart",
440 target->
tag(), source->
tag(), get->
tag());
444 GEdge *ges = gesIter->second.first;
445 if (checkEdges.find(ges) == checkEdges.end())
447 Msg::Error(
"Periodic meshing of surface %d with surface %d: "
448 "curve %d has periodic counterpart %d",
453 Msg::Error(
"Periodic meshing of surface %d with surface %d: "
454 "curve %d has %d vertices, whereas correspondant %d has %d",
458 int orientation = gesIter->second.second;
459 int is = orientation == 1 ? 0 : get->
mesh_vertices.size() - 1;
460 for (
unsigned it = 0; it < get->
mesh_vertices.size(); it++, is += orientation)
473 for (std::size_t i = 0; i < source->
mesh_vertices.size(); i++)
478 double ps[4] = {vs->
x(), vs->
y(), vs->
z(), 1.};
479 double res[4] = {0., 0., 0., 0.};
481 for (
int i = 0; i < 4; i++)
482 for (
int j = 0; j < 4; j++)
483 res[i] += tfo[idx++] * ps[j];
485 SPoint3 tp(res[0], res[1], res[2]);
496 for (
unsigned i = 0; i < source->
triangles.size(); i++)
507 Msg::Error(
"Could not find periodic counterpart of triangle nodes "
509 source->
triangles[i]->getVertex(0)->getNum(), source->
triangles[i]->getVertex(1)->getNum(),
510 source->
triangles[i]->getVertex(2)->getNum());
514 for (
unsigned i = 0; i < source->
quadrangles.size(); i++)
520 if (v1 && v2 && v3 && v4)
526 Msg::Error(
"Could not find periodic counterpart of quadrangle nodes "
535 std::set<EdgeToRecover> &edgesNotRecovered,
bool all)
539 auto itr = edgesNotRecovered.begin();
540 for (; itr != edgesNotRecovered.end(); ++itr)
542 std::vector<GFace *> l_faces = itr->ge->faces();
544 for (
auto it = l_faces.begin(); it != l_faces.end(); ++it)
546 if ((*it)->triangles.size() || (*it)->quadrangles.size())
556 int N = itr->ge->lines.size();
557 GVertex *g1 = itr->ge->getBeginVertex();
558 GVertex *g2 = itr->ge->getEndVertex();
561 std::vector<MLine *> newLines;
563 for (
int i = 0; i < N; i++)
565 MVertex *v1 = itr->ge->lines[i]->getVertex(0);
566 MVertex *v2 = itr->ge->lines[i]->getVertex(1);
568 auto itp1 = recoverMultiMapInv.lower_bound(v1);
569 auto itp2 = recoverMultiMapInv.lower_bound(v2);
571 if (itp1 != recoverMultiMapInv.end() && itp2 != recoverMultiMapInv.end())
577 if (recoverMultiMapInv.count(v1) == 2)
582 if (recoverMultiMapInv.count(v2) == 2)
588 if ((pp1->
iD == p1 && pp2->
iD == p2) || (pp1->
iD == p2 && pp2->
iD == p1) ||
589 (pp1b->
iD == p1 && pp2b->
iD == p2) || (pp1b->
iD == p2 && pp2b->
iD == p1) || all)
595 else if (v1->
onWhat() == g2)
607 else if (v2->
onWhat() == g2)
618 t1 = fabs(t2 - bb.
low()) < fabs(t2 - bb.
high()) ? bb.
low() : bb.
high();
620 t2 = fabs(t1 - bb.
low()) < fabs(t1 - bb.
high()) ? bb.
low() : bb.
high();
627 double t = 0.5 * (t2 + t1);
628 double lc = 0.5 * (lc1 + lc2);
629 GPoint V = itr->ge->point(t);
631 newLines.push_back(
new MLine(v1, newv));
632 newLines.push_back(
new MLine(newv, v2));
633 delete itr->ge->lines[i];
637 newLines.push_back(itr->ge->lines[i]);
642 newLines.push_back(itr->ge->lines[i]);
646 itr->ge->lines = newLines;
647 itr->ge->mesh_vertices.clear();
648 N = itr->ge->lines.size();
649 for (
int i = 1; i < N; i++)
651 itr->ge->mesh_vertices.push_back(itr->ge->lines[i]->getVertex(0));
657 std::set<EdgeToRecover> &edgesNotRecovered)
661 auto itr = edgesNotRecovered.begin();
662 for (; itr != edgesNotRecovered.end(); ++itr)
664 std::vector<GFace *> l_faces = itr->ge->faces();
666 for (
auto it = l_faces.begin(); it != l_faces.end(); ++it)
668 if ((*it)->triangles.size() || (*it)->quadrangles.size())
678 int N = itr->ge->lines.size();
679 GVertex *g1 = itr->ge->getBeginVertex();
680 GVertex *g2 = itr->ge->getEndVertex();
683 std::vector<MLine *> newLines;
685 for (
int i = 0; i < N; i++)
687 MVertex *v1 = itr->ge->lines[i]->getVertex(0);
688 MVertex *v2 = itr->ge->lines[i]->getVertex(1);
689 auto itp1 = recoverMapInv.find(v1);
690 auto itp2 = recoverMapInv.find(v2);
691 if (itp1 != recoverMapInv.end() && itp2 != recoverMapInv.end())
695 if ((pp1->
iD == p1 && pp2->
iD == p2) || (pp1->
iD == p2 && pp2->
iD == p1))
701 else if (v1->
onWhat() == g2)
713 else if (v2->
onWhat() == g2)
724 t1 = fabs(t2 - bb.
low()) < fabs(t2 - bb.
high()) ? bb.
low() : bb.
high();
726 t2 = fabs(t1 - bb.
low()) < fabs(t1 - bb.
high()) ? bb.
low() : bb.
high();
733 double t = 0.5 * (t2 + t1);
734 double lc = 0.5 * (lc1 + lc2);
735 GPoint V = itr->ge->point(t);
737 newLines.push_back(
new MLine(v1, newv));
738 newLines.push_back(
new MLine(newv, v2));
739 delete itr->ge->lines[i];
743 newLines.push_back(itr->ge->lines[i]);
748 newLines.push_back(itr->ge->lines[i]);
752 itr->ge->lines = newLines;
753 itr->ge->mesh_vertices.clear();
754 N = itr->ge->lines.size();
755 for (
int i = 1; i < N; i++)
757 itr->ge->mesh_vertices.push_back(itr->ge->lines[i]->getVertex(0));
780 std::set<EdgeToRecover> *e2r, std::set<EdgeToRecover> *notRecovered,
int pass)
791 for (std::size_t i = 0; i < ge->
lines.size(); i++)
795 auto itpstart = recoverMapInv.find(vstart);
796 auto itpend = recoverMapInv.find(vend);
797 if (itpstart != recoverMapInv.end() && itpend != recoverMapInv.end())
812 Msg::Error(
"Unable to recover the edge %d (%d/%d) on curve %d (on "
821 return !_fatallyFailed;
831 auto itpstart = recoverMapInv.find(vstart);
832 auto itpend = recoverMapInv.find(vend);
833 if (itpstart != recoverMapInv.end() && itpend != recoverMapInv.end())
856 std::set<MEdge, MEdgeLessThan> &removed)
859 if (removed.find(e) != removed.end())
861 auto it = bedges.find(e);
862 if (it == bedges.end())
874 std::vector<MTriangle *> &blTris, std::set<MVertex *> &verts,
bool debug)
880 std::set<MEdge, MEdgeLessThan> bedges;
881 std::set<MEdge, MEdgeLessThan> removed;
885 edges.insert(
edges.begin(), embedded_edges.begin(), embedded_edges.end());
886 auto ite =
edges.begin();
890 ff2 =
Fopen(
"tato.pos",
"w");
892 fprintf(ff2,
"View \" \"{\n");
894 std::vector<MLine *> _lines;
896 while (ite !=
edges.end())
898 for (std::size_t i = 0; i < (*ite)->lines.size(); i++)
900 _lines.push_back((*ite)->lines[i]);
901 MVertex *v1 = (*ite)->lines[i]->getVertex(0);
902 MVertex *v2 = (*ite)->lines[i]->getVertex(1);
905 for (std::size_t SIDE = 0; SIDE < _columns->
_normals.count(dv); SIDE++)
907 std::vector<MElement *> myCol;
911 int N = std::min(
c1._column.size(), c2.
_column.size());
914 for (
int l = 0; l < N; ++l)
916 MVertex *v11, *v12, *v21, *v22;
926 v11 =
c1._column[l - 1];
932 blQuads.push_back(qq);
934 fprintf(ff2,
"SQ(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g){%d,%d,%d,%d};\n", v11->
x(), v11->
y(),
935 v11->
z(), v12->
x(), v12->
y(), v12->
z(), v22->
x(), v22->
y(), v22->
z(), v21->
x(),
936 v21->
y(), v21->
z(), l + 1, l + 1, l + 1, l + 1);
938 if (
c1._column.size() != c2.
_column.size())
941 v11 =
c1._column[N - 1];
947 blTris.push_back(qq);
949 fprintf(ff2,
"ST(%g,%g,%g,%g,%g,%g,%g,%g,%g){%d,%d,%d};\n", v11->
x(), v11->
y(), v11->
z(),
950 v12->
x(), v12->
y(), v12->
z(), v->
x(), v->
y(), v->
z(), N + 1, N + 1, N + 1);
953 for (std::size_t l = 0; l < myCol.size(); l++)
954 _columns->
_toFirst[myCol[l]] = myCol[0];
961 for (
auto itf = _columns->
beginf(); itf != _columns->
endf(); ++itf)
966 for (
int i = 0; i < nbCol - 1; i++)
970 int N = std::min(
c1._column.size(), c2.
_column.size());
971 std::vector<MElement *> myCol;
972 for (
int l = 0; l < N; ++l)
974 MVertex *v11, *v12, *v21, *v22;
984 v11 =
c1._column[l - 1];
992 blQuads.push_back(qq);
994 fprintf(ff2,
"SQ(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g){%d,%d,%d,%d};\n", v11->
x(), v11->
y(),
995 v11->
z(), v12->
x(), v12->
y(), v12->
z(), v22->
x(), v22->
y(), v22->
z(), v21->
x(),
996 v21->
y(), v21->
z(), l + 1, l + 1, l + 1, l + 1);
1002 myCol.push_back(qq);
1003 blTris.push_back(qq);
1005 fprintf(ff2,
"ST(%g,%g,%g,%g,%g,%g,%g,%g,%g){%d,%d,%d};\n", v->
x(), v->
y(), v->
z(), v22->
x(),
1006 v22->
y(), v22->
z(), v21->
x(), v21->
y(), v21->
z(), l + 1, l + 1, l + 1);
1011 for (std::size_t l = 0; l < myCol.size(); l++)
1012 _columns->
_toFirst[myCol[l]] = myCol[0];
1020 fprintf(ff2,
"};\n");
1025 for (std::size_t i = 0; i < blQuads.size(); i++)
1026 blQuads[i]->setPartition(0);
1027 for (std::size_t i = 0; i < blTris.size(); i++)
1028 blTris[i]->setPartition(0);
1030 for (std::size_t i = 0; i < blQuads.size(); i++)
1032 addOrRemove(blQuads[i]->getVertex(0), blQuads[i]->getVertex(1), bedges, removed);
1033 addOrRemove(blQuads[i]->getVertex(1), blQuads[i]->getVertex(2), bedges, removed);
1034 addOrRemove(blQuads[i]->getVertex(2), blQuads[i]->getVertex(3), bedges, removed);
1035 addOrRemove(blQuads[i]->getVertex(3), blQuads[i]->getVertex(0), bedges, removed);
1036 for (
int j = 0; j < 4; j++)
1037 if (blQuads[i]->getVertex(j)->onWhat() == gf)
1038 verts.insert(blQuads[i]->getVertex(j));
1040 for (std::size_t i = 0; i < blTris.size(); i++)
1042 addOrRemove(blTris[i]->getVertex(0), blTris[i]->getVertex(1), bedges, removed);
1043 addOrRemove(blTris[i]->getVertex(1), blTris[i]->getVertex(2), bedges, removed);
1044 addOrRemove(blTris[i]->getVertex(2), blTris[i]->getVertex(0), bedges, removed);
1045 for (
int j = 0; j < 3; j++)
1046 if (blTris[i]->getVertex(j)->onWhat() == gf)
1047 verts.insert(blTris[i]->getVertex(j));
1051 std::vector<GEdge *> hop;
1052 auto it = bedges.begin();
1056 ff =
Fopen(
"toto.pos",
"w");
1058 fprintf(ff,
"View \" \"{\n");
1059 for (; it != bedges.end(); ++it)
1061 ne.
lines.push_back(
new MLine(it->getVertex(0), it->getVertex(1)));
1063 fprintf(ff,
"SL(%g,%g,%g,%g,%g,%g){1,1};\n", it->getVertex(0)->x(), it->getVertex(0)->y(),
1064 it->getVertex(0)->z(), it->getVertex(1)->x(), it->getVertex(1)->y(), it->getVertex(1)->z());
1068 fprintf(ff,
"};\n");
1095 s1 = derivatives.
first();
1096 s2 = derivatives.
second();
1104 v1 = basis_u * cos(
angle) + basis_v * sin(
angle);
1113 std::set<MVertex *> vertices;
1117 for (std::size_t j = 0; j <
element->getNumVertices(); j++)
1120 vertices.insert(vertex);
1131 for (
auto it = vertices.begin(); it != vertices.end(); it++)
1160 MVertex *v[4] = {
nullptr,
nullptr,
nullptr,
nullptr};
1161 for (
int i = 0; i < 4; i++)
1165 if (recoverMap.find(n[i]) == recoverMap.end())
1167 v[i] =
new MFaceVertex(n[i]->X, n[i]->Y, n[i]->Z, gf, n[i]->u, n[i]->v);
1168 recoverMap[n[i]] = v[i];
1172 v[i] = recoverMap[n[i]];
1178 if (v[0] != v[1] && v[0] != v[2] && v[1] != v[2])
1192 std::set<MVertex *, MVertexPtrLessThan> allverts;
1193 for (std::size_t i = 0; i < gf->
triangles.size(); i++)
1195 for (
int j = 0; j < 3; j++)
1197 if (gf->
triangles[i]->getVertex(j)->onWhat() == gf)
1198 allverts.insert(gf->
triangles[i]->getVertex(j));
1201 for (std::size_t i = 0; i < gf->
quadrangles.size(); i++)
1203 for (
int j = 0; j < 4; j++)
1205 if (gf->
quadrangles[i]->getVertex(j)->onWhat() == gf)
1206 allverts.insert(gf->
quadrangles[i]->getVertex(j));
1220 static bool meshGenerator(
GFace *gf,
int RECUR_ITER,
bool repairSelfIntersecting1dMesh,
int onlyInitialMesh,
bool debug,
1221 std::vector<GEdge *> *replacementEdges)
1233 std::map<BDS_Point *, MVertex *, PointLessThan> recoverMap;
1234 std::map<MVertex *, BDS_Point *> recoverMapInv;
1235 std::vector<GEdge *>
edges = replacementEdges ? *replacementEdges : gf->
edges();
1237 FILE *fdeb =
nullptr;
1238 if (debug && RECUR_ITER == 0)
1241 sprintf(name,
"surface%d-boundary-real.pos", gf->
tag());
1242 fdeb = fopen(name,
"w");
1243 fprintf(fdeb,
"View \"\"{\n");
1247 std::set<MVertex *, MVertexPtrLessThan> all_vertices, boundary;
1248 auto ite =
edges.begin();
1249 while (ite !=
edges.end())
1251 if ((*ite)->isSeam(gf))
1253 if (fdeb !=
nullptr)
1257 if (!(*ite)->isMeshDegenerated())
1259 for (std::size_t i = 0; i < (*ite)->lines.size(); i++)
1261 MVertex *v1 = (*ite)->lines[i]->getVertex(0);
1262 MVertex *v2 = (*ite)->lines[i]->getVertex(1);
1266 fprintf(fdeb,
"SL(%g,%g,%g,%g,%g,%g){%d,%d};\n", v1->
x(), v1->
y(), v1->
z(), v2->
x(), v2->
y(),
1267 v2->
z(), (*ite)->tag(), (*ite)->tag());
1270 all_vertices.insert(v1);
1271 all_vertices.insert(v2);
1272 if (boundary.find(v1) == boundary.end())
1273 boundary.insert(v1);
1276 if (boundary.find(v2) == boundary.end())
1277 boundary.insert(v2);
1283 Msg::Debug(
"Degenerated mesh on edge %d", (*ite)->tag());
1289 fprintf(fdeb,
"};\n");
1293 if (boundary.size())
1295 Msg::Error(
"The 1D mesh seems not to be forming a closed loop (%d boundary "
1296 "nodes are considered once)",
1298 for (
auto it = boundary.begin(); it != boundary.end(); it++)
1300 Msg::Debug(
"Remaining node %lu", (*it)->getNum());
1307 ite = emb_edges.begin();
1308 while (ite != emb_edges.end())
1310 if (!(*ite)->isMeshDegenerated())
1312 all_vertices.insert((*ite)->mesh_vertices.begin(), (*ite)->mesh_vertices.end());
1313 if ((*ite)->getBeginVertex())
1314 all_vertices.insert((*ite)->getBeginVertex()->mesh_vertices.begin(),
1315 (*ite)->getBeginVertex()->mesh_vertices.end());
1316 if ((*ite)->getEndVertex())
1317 all_vertices.insert((*ite)->getEndVertex()->mesh_vertices.begin(),
1318 (*ite)->getEndVertex()->mesh_vertices.end());
1325 auto itvx = emb_vertx.begin();
1326 while (itvx != emb_vertx.end())
1328 all_vertices.insert((*itvx)->mesh_vertices.begin(), (*itvx)->mesh_vertices.end());
1332 if (all_vertices.size() < 3)
1334 Msg::Warning(
"Mesh generation of surface %d skipped: only %d nodes on "
1336 gf->
tag(), all_vertices.size());
1340 else if (all_vertices.size() == 3)
1342 MVertex *vv[3] = {
nullptr,
nullptr,
nullptr};
1344 for (
auto it = all_vertices.begin(); it != all_vertices.end(); it++)
1357 std::vector<BDS_Point *> points(all_vertices.size());
1360 for (
auto it = all_vertices.begin(); it != all_vertices.end(); it++)
1370 recoverMap[pp] = here;
1371 recoverMapInv[here] = pp;
1373 bbox +=
SPoint3(param[0], param[1], 0);
1386 double LC2D =
norm(dd);
1388 for (std::size_t i = 0; i < points.size(); i++)
1403 double bb[4][2] = {{bbox.
min().
x(), bbox.
min().
y()},
1407 for (
int ip = 0; ip < 4; ip++)
1424 Msg::Debug(
"Meshing of the convex hull (%d points)", points.size());
1429 catch (std::runtime_error &e)
1433 Msg::Debug(
"Meshing of the convex hull (%d points) done", points.size());
1441 if (a < 0 || a >= n || b < 0 || b >= n || c < 0 || c >= n)
1459 std::vector<GEdge *> temp;
1460 if (replacementEdges)
1463 gf->
set(*replacementEdges);
1469 if (replacementEdges)
1474 std::map<int, BDS_Point *> aaa;
1475 for (
auto it = all_vertices.begin(); it != all_vertices.end(); it++)
1478 aaa[here->
getNum()] = recoverMapInv[here];
1481 for (
int ip = 0; ip < 4; ip++)
1492 for (
size_t i = 0; i < pm->
faces.size(); i++)
1495 int a = he->
v->
data;
1507 if (debug && RECUR_ITER == 0)
1510 sprintf(name,
"surface%d-initial-real.pos", gf->
tag());
1512 sprintf(name,
"surface%d-initial-param.pos", gf->
tag());
1520 std::set<EdgeToRecover> edgesToRecover;
1521 std::set<EdgeToRecover> edgesNotRecovered;
1522 ite =
edges.begin();
1523 while (ite !=
edges.end())
1525 if (!(*ite)->isMeshDegenerated())
1526 recoverEdge(m, gf, *ite, recoverMapInv, &edgesToRecover, &edgesNotRecovered, 1);
1529 ite = emb_edges.begin();
1530 while (ite != emb_edges.end())
1532 if (!(*ite)->isMeshDegenerated())
1533 recoverEdge(m, gf, *ite, recoverMapInv, &edgesToRecover, &edgesNotRecovered, 1);
1538 ite =
edges.begin();
1539 while (ite !=
edges.end())
1541 if (!(*ite)->isMeshDegenerated())
1543 if (!
recoverEdge(m, gf, *ite, recoverMapInv, &edgesToRecover, &edgesNotRecovered, 2))
1553 Msg::Debug(
"Recovering %d mesh edges (%d not recovered)", edgesToRecover.size(), edgesNotRecovered.size());
1557 std::ostringstream sstream;
1558 for (
auto itr = edgesNotRecovered.begin(); itr != edgesNotRecovered.end(); ++itr)
1559 sstream <<
" " << itr->ge->tag();
1562 Msg::Info(
"8-| Splitting all edges and trying again");
1566 Msg::Info(
":-( There are %d intersections in the 1D mesh (curves%s)", edgesNotRecovered.size(),
1567 sstream.str().c_str());
1568 if (repairSelfIntersecting1dMesh)
1569 Msg::Info(
"8-| Splitting those edges and trying again");
1574 sprintf(name,
"surface%d-not_yet_recovered-real-%d.msh", gf->
tag(), RECUR_ITER);
1578 if (repairSelfIntersecting1dMesh)
1585 auto itr = edgesNotRecovered.begin();
1587 for (; itr != edgesNotRecovered.end(); ++itr)
1591 int tag = itr->ge->tag();
1592 Msg::Error(
"Edge not recovered: %d %d %d", p1, p2, tag);
1599 if (RECUR_ITER < 10)
1601 return meshGenerator(gf, RECUR_ITER + 1, repairSelfIntersecting1dMesh, onlyInitialMesh, debug,
1608 Msg::Info(
":-) All edges recovered after %d iteration%s", RECUR_ITER, (RECUR_ITER > 1) ?
"s" :
"");
1610 Msg::Debug(
"Boundary edges recovered for surface %d", gf->
tag());
1618 (*itt)->g =
nullptr;
1628 if (n[0]->iD < 0 || n[1]->iD < 0 || n[2]->iD < 0)
1640 auto ite = m->
edges.begin();
1641 while (ite != m->
edges.end())
1646 if (e->
faces(0)->
g == &CLASS_EXTERIOR)
1651 else if (e->
faces(1)->
g == &CLASS_EXTERIOR)
1662 if ((*itt)->g == &CLASS_EXTERIOR)
1663 (*itt)->g =
nullptr;
1669 auto ite = m->
edges.begin();
1670 while (ite != m->
edges.end())
1677 if (oface[0]->iD < 0)
1682 else if (oface[1]->iD < 0)
1692 ite = emb_edges.begin();
1693 while (ite != emb_edges.end())
1695 if (!(*ite)->isMeshDegenerated())
1696 recoverEdge(m, gf, *ite, recoverMapInv, &edgesToRecover, &edgesNotRecovered, 2);
1703 Msg::Debug(
"Computing mesh size field at mesh nodes %d", edgesToRecover.size());
1704 auto it = m->
points.begin();
1705 for (; it != m->
points.end(); ++it)
1708 auto itv = recoverMap.find(pp);
1709 if (itv != recoverMap.end())
1717 else if (ge->
dim() == 1)
1742 auto ite = m->
edges.begin();
1743 while (ite != m->
edges.end())
1769 sprintf(name,
"surface%d-recovered-real.pos", gf->
tag());
1771 sprintf(name,
"surface%d-recovered-param.pos", gf->
tag());
1786 MVertex *v1 = recoverMap[n[0]];
1787 MVertex *v2 = recoverMap[n[1]];
1788 MVertex *v3 = recoverMap[n[2]];
1791 if (v1 != v2 && v1 != v3 && v2 != v3)
1796 MVertex *v4 = recoverMap[n[3]];
1812 gf->GFace::deleteMesh();
1814 Msg::Debug(
"Starting to add internal nodes");
1827 std::vector<MQuadrangle *> blQuads;
1828 std::vector<MTriangle *> blTris;
1829 std::set<MVertex *> verts;
1835 if (!onlyInitialMesh)
1845 if (!onlyInitialMesh)
1866 Msg::Error(
"ALGO_2D_PACK_PRLGRMS_CSTR deprecated");
1889 sprintf(name,
"real%d.pos", gf->
tag());
1891 sprintf(name,
"param%d.pos", gf->
tag());
1942 std::map<BDS_Point *, MVertex *, PointLessThan> &recoverMap,
int &count,
1943 int countTot,
double tol,
bool seam_the_first =
false)
1957 std::vector<GEdgeSigned> signedEdges(gel.
begin(), gel.
end());
1958 std::vector<SPoint2> coords;
1959 std::vector<MVertex *> verts;
1961 #if 0 // for debugging - don't remove
1962 printf(
"curve loop for surface %d\n", gf->
tag());
1963 for(std::size_t i = 0; i < signedEdges.size(); i++) {
1964 GEdge *ge = signedEdges[i].getEdge();
1965 bool seam = ge->
isSeam(gf);
1967 printf(
" curve %d: ", ge->
tag());
1970 printf(
"beg (%g,%g) ", p.
x(), p.
y());
1973 printf(
"beg_alt (%g,%g) ", p.
x(), p.
y());
1976 printf(
"end (%g,%g) ", p.
x(), p.
y());
1979 printf(
"end_alt (%g,%g) ", p.
x(), p.
y());
1985 for (
int initial_dir = 0; initial_dir < 2; initial_dir++)
1991 for (std::size_t i = 0; i < signedEdges.size(); i++)
1993 std::vector<SPoint2> p, p_alt, p_rev, p_alt_rev;
1994 std::vector<MVertex *> v, v_rev;
1995 GEdge *ge = signedEdges[i].getEdge();
1996 bool seam = ge->
isSeam(gf);
2027 std::reverse(p_rev.begin(), p_rev.end());
2031 std::reverse(p_alt_rev.begin(), p_alt_rev.end());
2034 std::reverse(v_rev.begin(), v_rev.end());
2039 if (initial_dir == 0)
2041 if (seam && seam_the_first)
2049 if (seam && seam_the_first)
2061 double dist1 = coords.back().distance(p.front());
2062 double dist2 = coords.back().distance(p_rev.front());
2065 if (dist1 < dist2 && dist1 < tol)
2068 coords.insert(coords.end(), p.begin(), p.end());
2070 verts.insert(verts.end(), v.begin(), v.end());
2072 else if (dist2 < dist1 && dist2 < tol)
2075 coords.insert(coords.end(), p_rev.begin(), p_rev.end());
2077 verts.insert(verts.end(), v_rev.begin(), v_rev.end());
2081 Msg::Debug(
"Distances (%g, %g) in parametric space larger than "
2082 "tolerance (%g) between end of curve %d and "
2083 "begining of curve %d...",
2084 dist1, dist2, tol, signedEdges[i - 1].getEdge()->tag(), ge->
tag());
2085 if (initial_dir == 0)
2087 Msg::Debug(
"... will try with alternate initial orientation");
2094 Msg::Debug(
"... will try with larger tolerance");
2101 double dist3 = coords.back().distance(p_alt.front());
2102 double dist4 = coords.back().distance(p_alt_rev.front());
2103 if (dist1 < dist2 && dist1 < dist3 && dist1 < dist4 && dist1 < tol)
2106 coords.insert(coords.end(), p.begin(), p.end());
2108 verts.insert(verts.end(), v.begin(), v.end());
2110 else if (dist2 < dist1 && dist2 < dist3 && dist2 < dist4 && dist2 < tol)
2113 coords.insert(coords.end(), p_rev.begin(), p_rev.end());
2115 verts.insert(verts.end(), v_rev.begin(), v_rev.end());
2117 else if (dist3 < dist1 && dist3 < dist2 && dist3 < dist4 && dist3 < tol)
2120 coords.insert(coords.end(), p_alt.begin(), p_alt.end());
2122 verts.insert(verts.end(), v.begin(), v.end());
2124 else if (dist4 < dist1 && dist4 < dist2 && dist4 < dist3 && dist4 < tol)
2127 coords.insert(coords.end(), p_alt_rev.begin(), p_alt_rev.end());
2129 verts.insert(verts.end(), v_rev.begin(), v_rev.end());
2133 Msg::Debug(
"Distances (%g, %g, %g, %g) in parametric space larger "
2134 "than tolerance (%g) between end of curve %d and "
2135 "begining of seam curve %d...",
2136 dist1, dist2, dist3, dist4, tol, signedEdges[i - 1].getEdge()->tag(), ge->
tag());
2137 if (initial_dir == 0)
2139 Msg::Debug(
"... will try with alternate initial orientation");
2146 Msg::Debug(
"... will try with larger tolerance");
2155 if (verts.size() != coords.size())
2157 Msg::Error(
"Wrong number of parametric coordinates for boundary nodes "
2167 double dist = coords.back().distance(coords.front());
2175 Msg::Debug(
"Distance %g between first and last node in 1D mesh of surface "
2176 "%d exceeds tolerance %g",
2177 dist, gf->
tag(), tol);
2181 std::map<BDS_Point *, MVertex *, PointLessThan> recoverMapLocal;
2183 for (std::size_t i = 0; i < verts.size(); i++)
2191 for (
auto it = recoverMap.begin(); it != recoverMap.end(); ++it)
2193 if (it->second == here)
2195 SPoint2 param(it->first->u, it->first->v);
2196 double dist = coords[i].distance(param);
2211 pp = m->
add_point(count + countTot, U, V, gf);
2216 else if (ge->
dim() == 1)
2233 result.push_back(pp);
2234 recoverMapLocal[pp] = here;
2238 Msg::Debug(
"Succeeded finding consecutive list of nodes on surface "
2239 "%d, with tolerance %g",
2243 recoverMap.insert(recoverMapLocal.begin(), recoverMapLocal.end());
2250 std::vector<GEdge *> e = gf->
edges();
2251 for (
size_t i = 0; i < e.size(); i++)
2254 for (
size_t j = 0; j < ge->
lines.size(); j++)
2279 std::map<BDS_Point *, MVertex *, PointLessThan> recoverMap;
2280 std::multimap<MVertex *, BDS_Point *> recoverMultiMapInv;
2282 std::vector<SPoint2> true_boundary;
2288 double du = rangeU.
high() - rangeU.
low();
2289 double dv = rangeV.
high() - rangeV.
low();
2291 const double LC2D = std::sqrt(du * du + dv * dv);
2297 std::vector<std::vector<BDS_Point *>> edgeLoops_BDS;
2299 int nbPointsTotal = 0;
2303 std::vector<BDS_Point *> edgeLoop_BDS;
2305 const double fact[5] = {1.e-12, 1.e-9, 1.e-6, 1.e-3, 1.e-1};
2307 for (
int i = 0; i < 5; i++)
2310 nbPointsTotal, fact[i] * LC2D))
2316 nbPointsTotal, fact[i] * LC2D,
true))
2325 Msg::Error(
"The 1D mesh seems not to be forming a closed loop");
2329 nbPointsTotal += nbPointsLocal;
2330 edgeLoops_BDS.push_back(edgeLoop_BDS);
2335 auto it = recoverMap.begin();
2336 std::map<MVertex *, BDS_Point *> INV;
2337 for (; it != recoverMap.end(); ++it)
2339 recoverMultiMapInv.insert(std::make_pair(it->second, it->first));
2341 auto it2 = INV.find(it->second);
2342 if (it2 != INV.end())
2344 it->first->_periodicCounterpart = it2->second;
2345 it2->second->_periodicCounterpart = it->first;
2347 INV[it->second] = it->first;
2351 if (nbPointsTotal < 3)
2353 Msg::Warning(
"Mesh generation of surface %d skipped: only %d nodes on "
2355 gf->
tag(), nbPointsTotal);
2360 else if (nbPointsTotal == 3)
2362 MVertex *vv[3] = {
nullptr,
nullptr,
nullptr};
2364 for (
auto it = recoverMap.begin(); it != recoverMap.end(); it++)
2366 vv[i++] = it->second;
2368 if (vv[0] && vv[1] && vv[2])
2378 std::vector<int> edgesEmbedded;
2386 auto itvx = emb_vertx.begin();
2388 std::map<MVertex *, std::set<BDS_Point *>> invertedRecoverMap;
2389 for (
auto it = recoverMap.begin(); it != recoverMap.end(); it++)
2391 invertedRecoverMap[it->second].insert(it->first);
2395 nbPointsTotal += emb_vertx.size();
2398 std::set<MVertex *> vs;
2399 auto ite = emb_edges.begin();
2400 while (ite != emb_edges.end())
2402 for (std::size_t i = 0; i < (*ite)->lines.size(); i++)
2404 for (std::size_t j = 0; j < 2; j++)
2406 MVertex *v = (*ite)->lines[i]->getVertex(j);
2407 if (invertedRecoverMap.find(v) == invertedRecoverMap.end() && vs.find(v) == vs.end())
2415 nbPointsTotal += vs.size();
2419 while (itvx != emb_vertx.end())
2421 MVertex *v = (*itvx)->mesh_vertices[0];
2422 double uv[2] = {0, 0};
2426 pp->
g = m->
get_geom(-(*itvx)->tag(), 0);
2441 std::set<MVertex *> vs;
2442 std::map<MVertex *, BDS_Point *> facile;
2443 auto ite = emb_edges.begin();
2444 while (ite != emb_edges.end())
2447 for (std::size_t i = 0; i < (*ite)->lines.size(); i++)
2449 for (std::size_t j = 0; j < 2; j++)
2451 MVertex *v = (*ite)->lines[i]->getVertex(j);
2453 const auto it = invertedRecoverMap.find(v);
2454 if (it != invertedRecoverMap.end())
2456 if (it->second.size() > 1)
2458 const GEdge *edge = (*ite);
2467 param = parBounds.
low();
2472 param = parBounds.
high();
2476 const std::set<BDS_Point *> &possiblePoints = it->second;
2477 for (
auto pntIt = possiblePoints.begin(); pntIt != possiblePoints.end(); ++pntIt)
2479 if (pointOnSurface.
distance(
SPoint2((*pntIt)->u, (*pntIt)->v)) < 1e-10)
2487 Msg::Error(
"Embedded edge node %d is on the seam edge of "
2488 "surface %d and no appropriate point could be "
2495 pp = *(it->second.begin());
2499 if (pp ==
nullptr && vs.find(v) == vs.end())
2502 double uv[2] = {0, 0};
2527 for (std::size_t i = 0; i < (*ite)->lines.size(); i++)
2529 BDS_Point *p0 = facile[(*ite)->lines[i]->getVertex(0)];
2530 BDS_Point *p1 = facile[(*ite)->lines[i]->getVertex(1)];
2531 edgesEmbedded.push_back(p0->
iD);
2532 edgesEmbedded.push_back(p1->
iD);
2537 for (std::size_t i = 0; i < edgeLoops_BDS.size(); i++)
2539 std::vector<BDS_Point *> &edgeLoop_BDS = edgeLoops_BDS[i];
2540 for (std::size_t j = 0; j < edgeLoop_BDS.size(); j++)
2557 if (du / dv < 1200 && dv / du < 1200)
2566 for (
int ip = 0; ip < 4; ip++)
2583 Msg::Debug(
"Meshing of the convex hull (%d nodes)", nbPointsTotal);
2589 catch (std::runtime_error &e)
2600 if (a < 0 || a >= n || b < 0 || b >= n || c < 0 || c >= n)
2621 sprintf(name,
"surface%d-initial-real.pos", gf->
tag());
2623 sprintf(name,
"surface%d-initial-param.pos", gf->
tag());
2627 bool _fatallyFailed;
2629 for (std::size_t i = 0; i < edgesEmbedded.size() / 2; i++)
2634 Msg::Error(
"Impossible to recover the edge %d %d", edgesEmbedded[2 * i], edgesEmbedded[2 * i + 1]);
2643 std::set<EdgeToRecover> edgesNotRecovered;
2646 for (std::size_t i = 0; i < edgeLoops_BDS.size(); i++)
2648 std::vector<BDS_Point *> &edgeLoop_BDS = edgeLoops_BDS[i];
2649 for (std::size_t j = 0; j < edgeLoop_BDS.size(); j++)
2651 int num1 = edgeLoop_BDS[j]->iD;
2652 int num2 = edgeLoop_BDS[(j + 1) % edgeLoop_BDS.size()]->iD;
2699 Msg::Info(
"Surface %d has self-intersections in its 1D mesh: serializing "
2707 std::ostringstream sstream;
2708 for (
auto itr = edgesNotRecovered.begin(); itr != edgesNotRecovered.end(); ++itr)
2709 sstream <<
" " << itr->ge->tag() <<
"("
2710 << (itr->ge->getBeginVertex() ? itr->ge->getBeginVertex()->tag() : -1) <<
","
2711 << (itr->ge->getEndVertex() ? itr->ge->getEndVertex()->tag() : -1) <<
")";
2712 Msg::Info(
":-( There are %d intersections in the 1D mesh (curves%s)", edgesNotRecovered.size(),
2713 sstream.str().c_str());
2715 if (repairSelfIntersecting1dMesh)
2717 Msg::Info(
"8-| Splitting those edges and trying again");
2720 std::vector<GEdge *> eds = gf->
edges();
2721 edgesNotRecovered.clear();
2722 for (
size_t i = 0; i < eds.size(); i++)
2724 const std::size_t NN = eds[i]->lines.size() ? 1 : 0;
2725 for (
size_t j = 0; j < NN; j++)
2727 MVertex *v1 = eds[i]->lines[j]->getVertex(0);
2728 MVertex *v2 = eds[i]->lines[j]->getVertex(1);
2729 auto itp1 = recoverMultiMapInv.lower_bound(v1);
2730 auto itp2 = recoverMultiMapInv.lower_bound(v2);
2731 if (itp1 != recoverMultiMapInv.end() && itp2 != recoverMultiMapInv.end())
2732 edgesNotRecovered.insert(
EdgeToRecover(itp1->second->iD, itp2->second->iD, eds[i]));
2744 sprintf(name,
"surface%d-initial-real-afterITER%d.pos", gf->
tag(), RECUR_ITER);
2746 sprintf(name,
"surface%d-initial-param-afterITER%d.pos", gf->
tag(), RECUR_ITER);
2750 if (RECUR_ITER < 10)
2758 Msg::Info(
":-) All edges recovered after %d iteration%s", RECUR_ITER, (RECUR_ITER > 1) ?
"s" :
"");
2766 (*itt)->g =
nullptr;
2783 if (n[0]->iD < 0 || n[1]->iD < 0 || n[2]->iD < 0)
2795 auto ite = m->
edges.begin();
2796 while (ite != m->
edges.end())
2801 if (edge->
faces(0)->
g == &CLASS_EXTERIOR)
2806 else if (edge->
faces(1)->
g == &CLASS_EXTERIOR)
2817 if ((*itt)->g == &CLASS_EXTERIOR)
2818 (*itt)->g =
nullptr;
2840 auto ite = m->
edges.begin();
2841 while (ite != m->
edges.end())
2851 edge->
p1->
g = edge->
g;
2853 edge->
p2->
g = edge->
g;
2867 sprintf(name,
"surface%d-recovered-real.pos", gf->
tag());
2869 sprintf(name,
"surface%d-recovered-param.pos", gf->
tag());
2893 sprintf(name,
"surface%d-phase1-real.pos", gf->
tag());
2895 sprintf(name,
"surface%d-phase1-param.pos", gf->
tag());
2901 sprintf(name,
"surface%d-phase2-real.pos", gf->
tag());
2903 sprintf(name,
"surface%d-phase2-param.pos", gf->
tag());
2910 sprintf(name,
"surface%d-phase3-real.pos", gf->
tag());
2912 sprintf(name,
"surface%d-phase3-param.pos", gf->
tag());
2918 sprintf(name,
"surface%d-phase4-real.pos", gf->
tag());
2920 sprintf(name,
"surface%d-phase4-param.pos", gf->
tag());
2930 Msg::Info(
"Serializing surface %d and refining all its bounding edges", gf->
tag());
2941 sprintf(name,
"surface%d-just-real.pos", gf->
tag());
2949 std::map<MVertex *, MVertex *> equivalence;
2953 std::map<MVertex *, BDS_Point *> invertMap;
2954 auto it = recoverMap.begin();
2955 while (it != recoverMap.end())
2960 auto invIt = invertMap.find(mv1);
2961 if (invIt != invertMap.end())
2981 equivalence[mv2] = mv1;
2983 invertMap[mv2] = bds;
2989 invertMap[mv1] = bds;
3004 sprintf(name,
"surface%d-final-real.pos", gf->
tag());
3006 sprintf(name,
"surface%d-final-param.pos", gf->
tag());
3025 if (!onlyInitialMesh)
3028 std::vector<MQuadrangle *> blQuads;
3029 std::vector<MTriangle *> blTris;
3030 std::set<MVertex *> verts;
3047 Msg::Error(
"ALGO_2D_PACK_PRLGRMS_CSTR deprecated");
3062 sprintf(name,
"real%d.pos", gf->
tag());
3064 sprintf(name,
"param%d.pos", gf->
tag());
3069 for (
auto eq : equivalence)
3137 for (
size_t i = 0; i < gf->
triangles.size(); i++)
3143 if (invalid == 0 || invalid == gf->
triangles.size())
3193 bool quadqs =
false;
3200 const char *algo =
"Unknown";
3211 algo =
"Initial Mesh Only";
3217 algo =
"Frontal-Delaunay";
3223 algo =
"Frontal-Delaunay for Quads";
3226 algo =
"Packing of Parallelograms";
3229 algo =
"Packing of Parallelograms Constrained";
3236 bool singularEdges =
false;
3237 auto ite = gf->
edges().begin();
3238 while (ite != gf->
edges().end())
3240 if ((*ite)->isSeam(gf))
3241 singularEdges =
true;
3254 Msg::Error(
"Impossible to mesh periodic surface %d", gf->
tag());
3279 Msg::Debug(
"Delaunay-based mesher failed on surface %d -> moving to MeshAdapt", gf->
tag());
3284 gf->unsetMeshingAlgo();
3336 const bool isBLEl = existBL && (blc->
_toFirst.find(e) != blc->
_toFirst.end());
3339 if ((!isBLEl && orientNonBL == 0) || (isBLEl && orientBL == 0))
3345 const int orient = (
dot(ne, nf) > 0.) ? 1 : -1;
3349 orientNonBL = orient;
3353 if ((orientNonBL != 0) && (orientBL != 0))
3394 const bool existBL = !blc->
_toFirst.empty();
3399 int orientNonBL = 0, orientBL = existBL ? 0 : 1;
3401 if ((orientNonBL == 0) || (orientBL == 0))
3405 if ((orientNonBL == 0) && (orientBL == 0))
3414 if ((orientNonBL == -1) || (orientBL == -1))
3423 if (orientNonBL == -1)
3436 if (orientNonBL == -1)