27 BDS_Mesh &m, std::map<BDS_Point *, MVertex *, PointLessThan> *recoverMap,
28 std::set<MVertex *, MVertexPtrLessThan> °enerated,
29 std::vector<BDS_Edge *> °enerated_edges)
33 auto it = m.
edges.begin();
35 while(it != m.
edges.end()) {
38 auto itp1 = recoverMap->find(e->
p1);
39 auto itp2 = recoverMap->find(e->
p2);
40 if(itp1 != recoverMap->end() && itp2 != recoverMap->end() &&
41 itp1->second == itp2->second) {
42 degenerated.insert(itp1->second);
43 degenerated_edges.push_back(e);
52 const double dx = p1->
X - p2->
X;
53 const double dy = p1->
Y - p2->
Y;
54 const double dz = p1->
Z - p2->
Z;
55 return std::sqrt(dx * dx + dy * dy + dz * dz);
65 const double dx1 = p1->
X - GP.
x();
66 const double dy1 = p1->
Y - GP.
y();
67 const double dz1 = p1->
Z - GP.
z();
68 const double l1 = std::sqrt(dx1 * dx1 + dy1 * dy1 + dz1 * dz1);
70 const double dx2 = p2->
X - GP.
x();
71 const double dy2 = p2->
Y - GP.
y();
72 const double dz2 = p2->
Z - GP.
z();
73 const double l2 = std::sqrt(dx2 * dx2 + dy2 * dy2 + dz2 * dz2);
96 double l = .5 * (l1 + l2);
98 const double coord = 0.5;
99 double U = coord * p1->
u + (1 - coord) * p2->
u;
100 double V = coord * p1->
v + (1 - coord) * p2->
v;
104 l = std::min(l, lmid);
108 double const lcmin = std::min(std::min(l1, l2), l3);
109 l1 = std::min(lcmin * 1.2, l1);
110 l2 = std::min(lcmin * 1.2, l2);
111 l3 = std::min(lcmin * 1.2, l3);
112 l = (l1 + l2 + l3) / 3.0;
144 const double THRESH =
153 double qa = std::min(qa1, qa2);
154 double qb = std::min(qb1, qb2);
169 auto it = p->
edges.begin();
170 auto ite = p->
edges.end();
180 int FINALIZE = 0,
double orientation = 1.0)
189 typedef std::vector<BDS_Edge *>::size_type size_type;
190 size_type origSize = m.
edges.size();
191 for(size_type index = 0; index < 2 * origSize && index < m.
edges.size();
195 if(!m.
edges.at(index)->deleted && m.
edges.at(index)->numfaces() == 2) {
209 std::set<swapquad> &configs)
215 if(e->
numfaces() != 2)
return false;
220 if(configs.find(sq) != configs.end())
return false;
223 double edgeCenter[2] = {0.5 * (e->
p1->
u + e->
p2->
u),
224 0.5 * (e->
p1->
v + e->
p2->
v)};
226 double p1[2] = {e->
p1->
u, e->
p1->
v};
227 double p2[2] = {e->
p2->
u, e->
p2->
v};
228 double p3[2] = {op[0]->
u, op[0]->
v};
229 double p4[2] = {op[1]->
u, op[1]->
v};
238 typedef std::vector<BDS_Edge *>::size_type size_type;
241 std::set<swapquad> configs;
245 for(size_type index = 0; index < m.
edges.size(); ++index) {
246 if(!m.
edges.at(index)->deleted) {
260 std::pair<double, BDS_Edge *> b)
266 if(std::abs(a.first - b.first) < 1e-10) {
267 if(a.second->p1->iD == b.second->p1->iD)
268 return (a.second->p2->iD < b.second->p2->iD);
270 return (a.second->p1->iD < b.second->p1->iD);
273 return (a.first < b.first);
278 double u1 = e->
p1->
u;
279 double u2 = e->
p2->
u;
280 double v1 = e->
p1->
v;
281 double v2 = e->
p2->
v;
282 double X1 = e->
p1->
X;
283 double X2 = e->
p2->
X;
284 double Y1 = e->
p1->
Y;
285 double Y2 = e->
p2->
Y;
286 double Z1 = e->
p1->
Z;
287 double Z2 = e->
p2->
Z;
289 SPoint3 pp(0.5 * (X1 + X2), 0.5 * (Y1 + Y2), 0.5 * (Z1 + Z2));
290 double guess[2] = {0.5 * (u1 + u2), 0.5 * (v1 + v2)};
295 SPoint3 MID = (XX1 + XX2) * 0.5;
306 double _p1[2] = {p1->
u, p1->
v};
307 double _p2[2] = {p2->
u, p2->
v};
308 double _op1[2] = {op[0]->
u, op[0]->
v};
309 double _op2[2] = {op[1]->
u, op[1]->
v};
310 double _ss[2] = {gp.
u(), gp.
v()};
315 if(oris_[0] * oris_[1] > 0 && oris_[0] * oris_[2] > 0 &&
316 oris_[0] * oris_[3] > 0 && oris_[1] * oris_[2] > 0 &&
317 oris_[1] * oris_[3] > 0 && oris_[2] * oris_[3] > 0) {
334 double l1 = std::sqrt((X - X1) * (X - X1) + (Y - Y1) * (Y - Y1) +
335 (Z - Z1) * (Z - Z1));
336 double l2 = std::sqrt((X - X2) * (X - X2) + (Y - Y2) * (Y - Y2) +
337 (Z - Z2) * (Z - Z2));
343 else if(l2 > 1.2 * l1) {
351 u = 0.5 * (e->
p1->
u + e->
p2->
u);
352 v = 0.5 * (e->
p1->
v + e->
p2->
v);
364 auto itp = m.
points.begin();
365 while(itp != m.
points.end()) {
366 if((*itp)->degenerated) deg.push_back(*itp);
373 for(
size_t i = 0; i < deg.size(); i++) deg[i]->degenerated = d;
378 std::vector<BDS_Edge *> degenerated;
379 for(
size_t i = 0; i < m.
edges.size(); i++) {
383 degenerated.push_back(e);
385 for(
size_t i = 0; i < degenerated.size(); i++) {
388 double U = 0.5 * (e->
p1->
u + e->
p2->
u);
389 double V = 0.5 * (e->
p1->
v + e->
p2->
v);
395 mid->
lc() = 0.5 * (e->
p1->
lc() + e->
p2->
lc());
406 std::vector<SPoint2> *true_boundary,
double &t)
409 std::vector<std::pair<double, BDS_Edge *> >
edges;
414 for(
auto it = m.
points.begin(); it != m.
points.end(); ++it) {
417 for(
size_t i = 0; i < p->
edges.size(); i++) {
420 for(
size_t j = 0; j < i; j++) {
425 edges.push_back(std::make_pair(-10.0, p->
edges[i]));
426 edges.push_back(std::make_pair(-10.0, p->
edges[j]));
433 auto it = m.
edges.begin();
434 while(it != m.
edges.end()) {
435 if(!(*it)->deleted && (*it)->numfaces() == 2 && (*it)->g &&
436 (*it)->g->classif_degree == 2) {
438 if(lone > MAXE_)
edges.push_back(std::make_pair(-lone, *it));
445 std::vector<BDS_Point *> mids(
edges.size());
449 for(std::size_t i = 0; i <
edges.size(); ++i) {
454 double U1 = e->
p1->
u;
455 double U2 = e->
p2->
u;
456 double V1 = e->
p1->
v;
457 double V2 = e->
p2->
v;
462 double U = 0.5 * (U1 + U2);
463 double V = 0.5 * (V1 + V2);
480 mid->
lc() = 0.5 * (e->
p1->
lc() + e->
p2->
lc());
487 for(std::size_t i = 0; i <
edges.size(); ++i) {
510 auto eit =
edges.begin();
511 while(eit !=
edges.end()) {
512 BDS_Point *newP1 =
nullptr, *newP2 =
nullptr;
513 if((*eit)->p1 == p) {
517 else if((*eit)->p2 == p) {
521 if(!newP1 || !newP2)
break;
523 maxLc = std::max(maxLc,
NewGetLc(&collapsedEdge, gf));
524 newP1->
del(&collapsedEdge);
525 newP2->del(&collapsedEdge);
533 int &nb_collaps,
double &t)
536 std::vector<std::pair<double, BDS_Edge *> >
edges;
537 auto it = m.
edges.begin();
538 while(it != m.
edges.end()) {
539 if(!(*it)->deleted && (*it)->numfaces() == 2 && (*it)->g &&
540 (*it)->g->classif_degree == 2) {
542 if(lone < MINE_)
edges.push_back(std::make_pair(lone, *it));
549 for(std::size_t i = 0; i <
edges.size(); i++) {
554 bool collapseP1Allowed =
false;
555 if(e->
p1->
iD > MAXNP) {
558 std::abs(lone1 - 1.0) < std::abs(
edges[i].first - 1.0);
562 bool collapseP2Allowed =
false;
563 if(e->
p2->
iD > MAXNP) {
566 std::abs(lone2 - 1.0) < std::abs(
edges[i].first - 1.0);
570 if(collapseP1Allowed && collapseP2Allowed) {
571 if(std::abs(lone1 - lone2) < 1e-12)
574 p = std::abs(lone1 - 1.0) < std::abs(lone2 - 1.0) ? e->
p1 : e->
p2;
576 else if(collapseP1Allowed && !collapseP2Allowed)
578 else if(collapseP2Allowed && !collapseP1Allowed)
588 double threshold,
double &t)
591 for(
int i = 0; i < 1; i++) {
592 auto itp = m.
points.begin();
593 while(itp != m.
points.end()) {
605 std::map<BDS_Point *, MVertex *, PointLessThan> *recoverMap)
607 auto itp = m.
points.begin();
608 while(itp != m.
points.end()) {
609 auto it = (*itp)->edges.begin();
610 auto ite = (*itp)->edges.end();
614 double l = (*it)->length();
615 if((*it)->g && (*it)->g->classif_degree == 1) {
616 L = ne ? std::max(L, l) : l;
621 if((*itp)->g && (*itp)->g->classif_tag > 0) {
630 auto itp = m.
points.begin();
631 while(itp != m.
points.end()) {
635 auto it = m.
edges.begin();
636 while(it != m.
edges.end()) {
637 bool degenerated =
false;
640 auto itp1 = recoverMap->find((*it)->p1);
641 auto itp2 = recoverMap->find((*it)->p2);
642 if(itp1 != recoverMap->end() && itp2 != recoverMap->end() &&
643 itp1->second == itp2->second) {
647 if(!degenerated && (*it)->g && (*it)->g->classif_degree == 1) {
648 double L = (*it)->length();
649 if((*it)->p1->lc() ==
MAX_LC)
652 (*it)->p1->lc() = std::max(L, (*it)->p1->lc());
653 if((*it)->p2->lc() ==
MAX_LC)
656 (*it)->p2->lc() = std::max(L, (*it)->p2->lc());
662 std::vector<BDS_Point *> pts;
663 while(itp != m.
points.end()) {
664 if((*itp)->lc() ==
MAX_LC) pts.push_back(*itp);
669 bool allTouched =
true;
670 for(
size_t i = 0; i < pts.size(); i++) {
671 auto it = pts[i]->edges.begin();
672 auto ite = pts[i]->edges.end();
674 BDS_Point *p = (*it)->othervertex(pts[i]);
676 if(pts[i]->lc() ==
MAX_LC)
677 pts[i]->
lc() = p->
lc();
679 pts[i]->lc() = 0.5 * (p->
lc() + pts[i]->lc());
683 if(pts[i]->lc() ==
MAX_LC) allTouched =
false;
685 if(iter++ >= 5 || allTouched)
break;
692 std::map<BDS_Point *, MVertex *, PointLessThan> *recoverMap)
694 std::set<MVertex *, MVertexPtrLessThan> degenerated;
695 std::vector<BDS_Edge *> degenerated_edges;
698 for(
auto it = recoverMap->begin(); it != recoverMap->end(); ++it) {
699 auto it2 = degenerated.find(it->second);
700 if(it2 != degenerated.end()) {
701 for(
size_t K = 0; K < degenerated_edges.size(); K++) {
702 if(degenerated_edges[K]->p1 == it->first ||
703 degenerated_edges[K]->p2 == it->first) {
704 if(std::abs(degenerated_edges[K]->p1->u -
705 degenerated_edges[K]->p2->u) < 1e-12) {
707 "Degenerated edge on u = cst axis: treated as well now!");
708 it->first->degenerated = 2;
711 it->first->degenerated = 1;
717 for(
size_t i = 0; i < degenerated_edges.size(); i++) {
720 recoverMap->erase(degenerated_edges[i]->p1);
727 const bool computeNodalSizeField,
728 std::map<MVertex *, BDS_Point *> *recoverMapInv,
729 std::map<BDS_Point *, MVertex *, PointLessThan> *recoverMap,
730 std::vector<SPoint2> *true_boundary)
744 auto itvx = emb_vertx.begin();
745 while(itvx != emb_vertx.end()) {
746 MVertex *v = *((*itvx)->mesh_vertices.begin());
747 auto itp = recoverMapInv->find(v);
748 if(itp != recoverMapInv->end()) {
760 double t_spl = 0, t_sw = 0, t_col = 0, t_sm = 0;
762 const double MINE_ = 0.7, MAXE_ = 1.4;
765 auto it = m.
edges.begin();
766 while(it != m.
edges.end()) {
767 if(!(*it)->deleted) {
768 (*it)->p1->config_modified =
true;
769 (*it)->p2->config_modified =
true;
775 std::vector<BDS_Point *> deg;
778 if(deg.size()) degType = deg[0]->degenerated;
780 if(computeNodalSizeField) {
844 printf(
"IN FULL DEBUG MODE AT ITER %d/%d : press enter\n", IT, NIT);
846 printf(
"THANKS .. continuing\n");
859 double minL = 1.e22, maxL = 0;
860 auto it = m.
edges.begin();
861 int LARGE = 0, SMALL = 0, TOTAL = 0;
862 while(it != m.
edges.end()) {
863 if(!(*it)->deleted) {
864 double lone = 2 * (*it)->length() /
866 if(lone > maxE) LARGE++;
867 if(lone < minE) SMALL++;
869 maxL = std::max(maxL, lone);
870 minL = std::min(minL, lone);
874 if((minL > MINE_ && maxL < MAXE_) || IT > (abs(NIT)))
break;
877 Msg::Debug(
" iter %3d minL %8.3f/%8.3f maxL %8.3f/%8.3f -- "
878 "Small/Large/Total (%6d/%6d/%6d): "
879 "%6d splits, %6d swaps, %6d collapses, %6d moves",
880 IT, minL, minE, maxL, maxE, SMALL, LARGE, TOTAL, nb_split,
881 nb_swap, nb_collaps, nb_smooth);
883 if(nb_split == 0 && nb_collaps == 0)
break;
887 printf(
"FULL DEBUG MODE : cleaning bad triangles\n");
897 for(
size_t i = 0; i < m.
triangles.size(); i++) {
899 invalid += val < 0 ? 1 : 0;
901 double orientation = invalid > (int)m.
triangles.size() / 2 ? -1.0 : 1.0;
904 printf(
"NOW FIXING BAD ELEMENTS\n");
910 for(
size_t i = 0; i < m.
triangles.size(); i++) {
918 for(
size_t i = 0; i < m.
triangles.size(); i++) {
923 if(!m.
triangles[i]->deleted && val <= 0) invalid++;
928 if(val < 0) { invalid++; }
933 if(invalid && !computeNodalSizeField) {
935 Msg::Warning(
"%d element%s remain invalid in surface %d", invalid,
936 (invalid > 1) ?
"s" :
"", gf->
tag());
956 double t_total = t_spl + t_sw + t_col + t_sm;
957 if(!t_total) t_total = 1.e-6;
958 Msg::Debug(
" ---------------------------------------");
960 Msg::Debug(
" ---------------------------------------");
961 Msg::Debug(
" CPU SWAP %12.5E sec (%3.0f %%)", t_sw, 100 * t_sw / t_total);
962 Msg::Debug(
" CPU SPLIT %12.5E sec (%3.0f %%) ", t_spl,
963 100 * t_spl / t_total);
964 Msg::Debug(
" CPU COLLAPS %12.5E sec (%3.0f %%) ", t_col,
965 100 * t_col / t_total);
966 Msg::Debug(
" CPU SMOOTH %12.5E sec (%3.0f %%) ", t_sm, 100 * t_sm / t_total);
967 Msg::Debug(
" ---------------------------------------");
968 Msg::Debug(
" CPU TOTAL %12.5E sec ", t_total);
969 Msg::Debug(
" ---------------------------------------");