9 #include <unordered_map>
27 void swap(
double &a,
double &b)
35 double yRed,
double xBlue,
double yBlue)
37 size_t BIG = 1073741824;
39 for(
int i = 0; i < 16; i++) {
40 double coordRed = (x - x0) * xRed + (y - y0) * yRed;
41 double coordBlue = (x - x0) * xBlue + (y - y0) * yBlue;
46 if(coordRed <= 0 && coordBlue <= 0) {
52 else if(coordRed <= 0 && coordBlue >= 0) {
57 else if(coordRed >= 0 && coordBlue >= 0) {
62 else if(coordRed >= 0 && coordBlue <= 0) {
63 x0 += (-xBlue + xRed);
64 y0 += (-yBlue + yRed);
74 Msg::Warning(
"Hilbert failed %d %d", coordRed, coordBlue);
81 template <
class T1,
class T2>
82 std::size_t
operator()(
const std::pair<T1, T2> &pair)
const
84 return std::hash<T1>()(pair.first) ^ std::hash<T2>()(pair.second);
93 Msg::Error(
"PolyMesh2GFace cannot find surface %d", faceTag);
102 std::unordered_map<int, MVertex *> news;
103 std::unordered_map<PolyMesh::HalfEdge *, GPoint> hon;
107 auto it = hon.find(pm->
hedges[i]);
108 if(it == hon.end()) {
109 double uv[2] = {0, 0};
123 std::map<MEdge, GPoint, MEdgeLessThan> hop;
126 if(
f->data == faceTag) {
128 f->he->next->next->next->v};
131 for(
int i = 0; i < pm->
num_sides(
f->he); i++) {
132 if(v[i]->data != -1) {
133 auto it = news.find(v[i]->data);
137 v_gmsh[i] = it->second;
140 double uv[2] = {0, 0};
153 news[v[i]->
data] = v_gmsh[i];
158 MEdge l01(v_gmsh[0], v_gmsh[1]);
159 hop[l01] = hon[
f->he];
160 MEdge l12(v_gmsh[1], v_gmsh[2]);
161 hop[l12] = hon[
f->he->next];
162 MEdge l20(v_gmsh[2], v_gmsh[0]);
163 hop[l20] = hon[
f->he->next->next];
170 new MQuadrangle(v_gmsh[0], v_gmsh[1], v_gmsh[2], v_gmsh[3]));
178 for(
int i = 0; i < 3; i++) {
179 MEdge li(t->getVertex(i), t->getVertex((i + 1) % 3));
181 MVertex *vint = t->getVertex(i + 3);
201 std::unordered_map<size_t, size_t> nodeLabels;
206 std::vector<int> elementTypes;
207 std::vector<std::vector<std::size_t> > elementTags;
208 std::vector<std::vector<std::size_t> > nodeTags;
209 gmsh::model::mesh::getElements(elementTypes, elementTags, nodeTags, 2,
212 for(
size_t K = 0; K < elementTypes.size(); K++) {
213 int eT = elementTypes[K];
220 Msg::Error(
"GFace2PolyMesh only support quads (element type 3) and "
221 "triangles (element type 2)");
226 for(
size_t i = 0; i < elementTags[K].size(); i++) {
227 for(
int j = 0; j < nNod; j++) {
228 size_t nodeTag = nodeTags[K][nNod * i + j];
229 auto it = nodeLabels.find(nodeTag);
230 if(it == nodeLabels.end()) {
232 std::vector<double> coord(3), parametricCoord(3);
233 int entityDim, entityTag;
234 gmsh::model::mesh::getNode(nodeTag, coord, parametricCoord, entityDim,
237 nodeLabels[nodeTag] = (*pm)->vertices.size();
238 (*pm)->vertices.push_back(v[j]);
241 v[j] = (*pm)->vertices[it->second];
245 for(
int j = 0; j < nNod; j++) {
247 (*pm)->hedges.push_back(he[j]);
252 (*pm)->faces.push_back(ff);
254 for(
int j = 0; j < nNod; j++) {
255 he[j]->
next = he[(j + 1) % nNod];
256 he[j]->
prev = he[(j - 1 + nNod) % nNod];
273 std::sort((*pm)->hedges.begin(), (*pm)->hedges.end(),
compare);
276 for(
size_t i = 0; i < (*pm)->hedges.size() - 1; i++) {
290 if(he->
opposite ==
nullptr)
return -1;
300 return (result > 0) ? 1 : 0;
312 double q0[3] = {p0.
x(), p0.
y(), p0.
z()};
313 double q1[3] = {p1.
x(), p1.
y(), p1.
z()};
314 double q2[3] = {p2.
x(), p2.
y(), p2.
z()};
327 p2.
x(), p2.
y(), p2.
z());
364 double POS[2] = {x, y};
376 if(s0 >= 0 && s1 >= 0 && s2 >= 0) {
386 else if(s0 <= 0 && s1 >= 0 && s2 >= 0)
388 else if(s1 <= 0 && s0 >= 0 && s2 >= 0)
390 else if(s2 <= 0 && s0 >= 0 && s1 >= 0)
392 else if(s0 <= 0 && s1 <= 0)
394 else if(s0 <= 0 && s2 <= 0)
396 else if(s1 <= 0 && s2 <= 0)
399 Msg::Error(
"Could not find half-edge in walk for point %g %g on "
400 "face %g %g %g / %g %g %g / %g %g %g "
401 "(orientation tests %g %g %g)", x, y,
407 if(he ==
nullptr)
break;
423 if(s0 * s1 >= 0)
return 0;
428 if(t0 * t1 >= 0)
return 0;
436 std::list<PolyMesh::HalfEdge *> _list;
450 _list.push_back(he->
next);
454 }
while(he != v_start->
he);
456 if(_list.empty()) {
return -1; }
492 int nbIntersection = _list.size();
495 while(!_list.empty()) {
497 _list.erase(_list.begin());
507 if(still_intersect) _list.push_back(he);
512 return nbIntersection;
517 std::stack<PolyMesh::Face *> _stack;
522 while(!_stack.empty()) {
527 for(
int i = 0; i < 3; i++) {
547 std::list<PolyMesh::HalfEdge *> _list;
551 if(q < _limit && f->data == gf->
tag()) _list.push_back(
f->he);
554 while(!_list.empty()) {
556 _list.erase(_list.begin());
566 if(
f &&
f->data == (
int)faceTag) {
567 std::vector<PolyMesh::HalfEdge *> _touched;
571 if(_touched.size() == 3) {
576 std::vector<PolyMesh::Face *> _f;
577 for(
auto h : _touched)
578 if(std::find(_f.begin(), _f.end(), h->f) == _f.end())
585 if(q < _limit && pf->data == gf->
tag()) _list.push_back(pf->he);
605 if(
f->data == faceTag) {
606 size_t n0 =
f->he->v->data;
607 size_t n1 =
f->he->next->v->data;
608 size_t n2 =
f->he->next->next->v->data;
631 for(
size_t i = 0; i <
nbCopies; i++) {
632 if(fabs(
u[i] - _u) < 1.e-9 && fabs(
v[i] - _v) < 1.e-9)
return;
642 for(
size_t i = 0; i <
nbCopies; i++) {
643 double dist = sqrt((_u -
u[i]) * (_u -
u[i]) + (_v -
v[i]) * (_v -
v[i]));
656 std::unordered_map<size_t, nodeCopies> &copies)
660 edges.insert(
edges.end(), emb_edges.begin(), emb_edges.end());
661 std::set<GEdge *> touched;
667 for(
auto e :
edges) {
668 if(!e->isMeshDegenerated()) {
669 std::set<MVertex *, MVertexPtrLessThan> e_vertices;
670 for(std::size_t i = 0; i < e->lines.size(); i++) {
671 MVertex *v1 = e->lines[i]->getVertex(0);
672 MVertex *v2 = e->lines[i]->getVertex(1);
673 e_vertices.insert(v1);
674 e_vertices.insert(v2);
679 if(touched.find(e) == touched.end())
685 for(
auto v : e_vertices) {
689 if(v->onWhat()->dim() == 0)
691 else if(v->onWhat()->dim() == 1)
692 v->getParameter(0, t);
695 param = e->reparamOnFace(gf, t,
direction);
701 param =
SPoint2(v->x(), v->y());
706 std::unordered_map<size_t, nodeCopies>::iterator it =
707 copies.find(v->getNum());
708 if(it == copies.end()) {
710 copies.insert(std::make_pair(v->getNum(),
c));
713 it->second.addCopy(param.
x(), param.
y());
720 for(
auto v : emb_vertx) {
724 copies.insert(std::make_pair(v->mesh_vertices[0]->getNum(),
c));
730 const size_t N = pts.size() / 2;
731 std::vector<double> X(N), Y(N);
732 std::vector<size_t> HC(N), IND(N);
734 for(
size_t i = 0; i < N; i++) {
736 Y[i] = pts[2 * i + 1];
742 std::sort(IND.begin(), IND.end(),
743 [&](
size_t i,
size_t j) { return HC[i] < HC[j]; });
745 for(
size_t i = 0; i < N; i++) {
754 std::vector<double> *additional)
758 if(!gf)
Msg::Error(
"GFaceInitialMesh: no face with tag %d", faceTag);
762 std::unordered_map<size_t, nodeCopies> copies;
766 for(
auto c : copies) {
767 for(
size_t i = 0; i <
c.second.nbCopies; i++)
768 bb +=
SPoint3(
c.second.u[i],
c.second.v[i], 0);
774 for(std::unordered_map<size_t, nodeCopies>::iterator it = copies.begin();
775 it != copies.end(); ++it) {
776 for(
size_t i = 0; i < it->second.nbCopies; i++) {
777 double x = it->second.u[i];
778 double y = it->second.v[i];
785 it->second.id[i] = pm->
vertices.size() - 1;
795 edges.insert(
edges.end(), emb_edges.begin(), emb_edges.end());
800 for(
auto e :
edges) {
801 if(!e->isMeshDegenerated()) {
802 for(
auto l : e->lines) {
803 auto c0 = copies.find(l->getVertex(0)->getNum());
804 auto c1 = copies.find(l->getVertex(1)->getNum());
805 if(c0 == copies.end() ||
c1 == copies.end())
807 l->getVertex(0)->getNum(), l->getVertex(1)->getNum(),
808 c0 == copies.end(),
c1 == copies.end());
809 if(c0->second.nbCopies >
c1->second.nbCopies) {
814 for(
size_t j = 0; j < c0->second.nbCopies; j++) {
817 c0->second.u[j], c0->second.v[j])];
820 Msg::Warning(
"Impossible to recover edge %lu %lu (error tag %d)",
821 l->getVertex(0)->getNum(), l->getVertex(0)->getNum(),
841 other_side =
Color(other_side, faceTag);
846 while(iter++ < 100) {
848 for(
auto he : pm->
hedges) {
849 if(he->opposite && he->f->data == faceTag &&
850 he->opposite->f->data == faceTag) {
852 if(
intersect(he->v, he->next->v, he->next->next->v,
853 he->opposite->next->next->v)) {
864 if(additional)
addPoints(pm, *additional, bb);