gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
meshGFaceBDS.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 <stdlib.h>
7 #include "GmshMessage.h"
8 #include "meshGFace.h"
9 #include "meshGFaceOptimize.h"
10 #include "BackgroundMesh.h"
11 #include "GVertex.h"
12 #include "GEdge.h"
13 #include "GFace.h"
14 #include "discreteFace.h"
15 #include "MVertex.h"
16 #include "MElement.h"
17 #include "Context.h"
18 #include "GPoint.h"
19 #include "GModel.h"
20 #include "Numeric.h"
21 #include "BDS.h"
22 #include "qualityMeasures.h"
23 #include "OS.h"
24 #include "robustPredicates.h"
25 
27  BDS_Mesh &m, std::map<BDS_Point *, MVertex *, PointLessThan> *recoverMap,
28  std::set<MVertex *, MVertexPtrLessThan> &degenerated,
29  std::vector<BDS_Edge *> &degenerated_edges)
30 {
31  degenerated.clear();
32 
33  auto it = m.edges.begin();
34 
35  while(it != m.edges.end()) {
36  BDS_Edge *e = *it;
37  if(!e->deleted && e->numfaces() == 1) {
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);
44  }
45  }
46  ++it;
47  }
48 }
49 
51 {
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);
56 }
57 
58 static inline double computeEdgeLinearLength(BDS_Point *p1, BDS_Point *p2,
59  GFace *f)
60 {
61  GPoint GP = f->point(SPoint2(0.5 * (p1->u + p2->u), 0.5 * (p1->v + p2->v)));
62 
63  if(!GP.succeeded()) return computeEdgeLinearLength(p1, p2);
64 
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);
69 
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);
74 
75  return l1 + l2;
76 }
77 
79 {
80  // FIXME !!!
81  return f->geomType() == GEntity::Plane ?
82  e->length() :
83  computeEdgeLinearLength(e->p1, e->p2, f);
84 }
85 
86 static double NewGetLc(BDS_Point *point, GFace *gf)
87 {
88  return Extend1dMeshIn2dSurfaces(gf) ? std::min(point->lc(), point->lcBGM()) :
89  point->lcBGM();
90 }
91 
92 static double correctLC_(BDS_Point *p1, BDS_Point *p2, GFace *f)
93 {
94  double l1 = NewGetLc(p1, f);
95  double l2 = NewGetLc(p2, f);
96  double l = .5 * (l1 + l2);
97 
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;
101 
102  GPoint gpp = f->point(U, V);
103  double lmid = BGM_MeshSize(f, U, V, gpp.x(), gpp.y(), gpp.z());
104  l = std::min(l, lmid);
105 
106  if(CTX::instance()->mesh.lcFromCurvature) {
107  double l3 = l;
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;
113  }
114  return l;
115 }
116 
117 static double NewGetLc(BDS_Edge *const edge, GFace *const face)
118 {
119  return computeEdgeLinearLength(edge, face) /
120  correctLC_(edge->p1, edge->p2, face);
121 }
122 
123 // SWAP TESTS i.e. tell if swap should be done
124 
125 static bool edgeSwapTestAngle(BDS_Edge *e, double min_cos)
126 {
127  BDS_Face *f1 = e->faces(0);
128  BDS_Face *f2 = e->faces(1);
129  BDS_Point *n1[4];
130  BDS_Point *n2[4];
131  if(!f1->getNodes(n1) || !f2->getNodes(n2)) return false;
132  double norm1[3];
133  double norm2[3];
134  normal_triangle(n1[0], n1[1], n1[2], norm1);
135  normal_triangle(n2[0], n2[1], n2[2], norm2);
136 
137  return prosca(norm1, norm2) > min_cos;
138 }
139 
140 static int edgeSwapTest(GFace *gf, BDS_Edge *e)
141 {
142  BDS_Point *op[2];
143 
144  const double THRESH =
145  cos(CTX::instance()->mesh.allowSwapEdgeAngle * M_PI / 180.);
146 
147  e->oppositeof(op);
148 
149  double qa1 = qmTriangle::gamma(e->p1, e->p2, op[0]);
150  double qa2 = qmTriangle::gamma(e->p1, e->p2, op[1]);
151  double qb1 = qmTriangle::gamma(e->p1, op[0], op[1]);
152  double qb2 = qmTriangle::gamma(e->p2, op[0], op[1]);
153  double qa = std::min(qa1, qa2);
154  double qb = std::min(qb1, qb2);
155 
156  // if(qb > 15*qa) return 1;
157 
158  if(!edgeSwapTestAngle(e, THRESH)) return -1;
159 
160  if(qb > qa)
161  return 1;
162  else
163  return -1;
164 }
165 
167 {
168  if(p->config_modified) return true;
169  auto it = p->edges.begin();
170  auto ite = p->edges.end();
171  while(it != ite) {
172  BDS_Point *o = (*it)->othervertex(p);
173  if(o->config_modified) return true;
174  ++it;
175  }
176  return false;
177 }
178 
179 static void swapEdgePass(GFace *gf, BDS_Mesh &m, int &nb_swap, double &t,
180  int FINALIZE = 0, double orientation = 1.0)
181 {
182  double t1 = Cpu();
183  BDS_SwapEdgeTest *qual;
184  if(FINALIZE && gf->getNativeType() != GEntity::GmshModel)
185  qual = new BDS_SwapEdgeTestNormals(gf, orientation);
186  else
187  qual = new BDS_SwapEdgeTestQuality(true, true);
188 
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();
192  ++index) {
193  if(neighboringModified(m.edges.at(index)->p1) ||
194  neighboringModified(m.edges.at(index)->p2)) {
195  if(!m.edges.at(index)->deleted && m.edges.at(index)->numfaces() == 2) {
196  int const result = FINALIZE ? 1 : edgeSwapTest(gf, m.edges.at(index));
197  if(result >= 0) {
198  if(m.swap_edge(m.edges.at(index), *qual)) { ++nb_swap; }
199  }
200  }
201  }
202  }
203  m.cleanup();
204  delete qual;
205  t += (Cpu() - t1);
206 }
207 
209  std::set<swapquad> &configs)
210 {
211  BDS_Point *op[2];
212 
213  if(!e->p1->config_modified && !e->p2->config_modified) return false;
214 
215  if(e->numfaces() != 2) return false;
216 
217  e->oppositeof(op);
218 
219  swapquad sq(e->p1->iD, e->p2->iD, op[0]->iD, op[1]->iD);
220  if(configs.find(sq) != configs.end()) return false;
221  configs.insert(sq);
222 
223  double edgeCenter[2] = {0.5 * (e->p1->u + e->p2->u),
224  0.5 * (e->p1->v + e->p2->v)};
225 
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};
230  double metric[3];
231  buildMetric(gf, edgeCenter, metric);
232  if(!inCircumCircleAniso(gf, p1, p2, p3, p4, metric)) { return false; }
233  return true;
234 }
235 
236 void delaunayizeBDS(GFace *gf, BDS_Mesh &m, int &nb_swap)
237 {
238  typedef std::vector<BDS_Edge *>::size_type size_type;
239 
240  nb_swap = 0;
241  std::set<swapquad> configs;
242  while(1) {
243  size_type NSW = 0;
244 
245  for(size_type index = 0; index < m.edges.size(); ++index) {
246  if(!m.edges.at(index)->deleted) {
247  if(edgeSwapTestDelaunayAniso(m.edges.at(index), gf, configs)) {
248  if(m.swap_edge(m.edges.at(index), BDS_SwapEdgeTestQuality(false))) {
249  ++NSW;
250  }
251  }
252  }
253  }
254  nb_swap += NSW;
255  if(!NSW) return;
256  }
257 }
258 
259 static bool edges_sort(std::pair<double, BDS_Edge *> a,
260  std::pair<double, BDS_Edge *> b)
261 {
262  // don't compare pointers: it leads to non-deterministic behavior
263  // if (a.first == b.first){
264  // return ((*a.second) < (*b.second));
265  // }
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);
269  else
270  return (a.second->p1->iD < b.second->p1->iD);
271  }
272  else
273  return (a.first < b.first);
274 }
275 
276 static bool middlePoint(GFace *gf, BDS_Edge *e, double &u, double &v)
277 {
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;
288 
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)};
291  GPoint gp = gf->closestPoint(pp, guess);
292  if(0 && gp.succeeded()) {
293  SPoint3 XX1(X1, Y1, Z1);
294  SPoint3 XX2(X2, Y2, Z2);
295  SPoint3 MID = (XX1 + XX2) * 0.5;
296  SPoint3 PRJ(gp.x(), gp.y(), gp.z());
297  ;
298  double d1 = PRJ.distance(MID);
299  double d2 = XX1.distance(XX2);
300  // projection is close to mid...
301  if(d1 < .3 * d2) {
302  BDS_Point *op[2];
303  BDS_Point *p1 = e->p1;
304  BDS_Point *p2 = e->p2;
305  e->oppositeof(op);
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()};
311  double oris_[4] = {robustPredicates::orient2d(_p1, _op2, _ss),
312  robustPredicates::orient2d(_op2, _p2, _ss),
313  robustPredicates::orient2d(_p2, _op1, _ss),
314  robustPredicates::orient2d(_op1, _p1, _ss)};
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) {
318  u = gp.u();
319  v = gp.v();
320  return true;
321  }
322  }
323  }
324 
325  int iter = 0;
326  while(1) {
327  u = 0.5 * (u1 + u2);
328  v = 0.5 * (v1 + v2);
329  GPoint gpp = gf->point(u, v);
330  if(gpp.succeeded()) {
331  double X = gpp.x();
332  double Y = gpp.y();
333  double Z = gpp.z();
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));
338  // 1 ------ p -- 2
339  if(l1 > 1.2 * l2) {
340  u2 = u;
341  v2 = v;
342  }
343  else if(l2 > 1.2 * l1) {
344  u1 = u;
345  v1 = v;
346  }
347  else
348  break;
349  }
350  if(iter++ > 4) {
351  u = 0.5 * (e->p1->u + e->p2->u);
352  v = 0.5 * (e->p1->v + e->p2->v);
353  return false;
354  }
355  }
356  return true;
357 }
358 
359 // create a valid initial mesh when degeneracies are present
360 
361 static void getDegeneracy(BDS_Mesh &m, std::vector<BDS_Point *> &deg)
362 {
363  deg.clear();
364  auto itp = m.points.begin();
365  while(itp != m.points.end()) {
366  if((*itp)->degenerated) deg.push_back(*itp);
367  itp++;
368  }
369 }
370 
371 static void setDegeneracy(std::vector<BDS_Point *> &deg, short d)
372 {
373  for(size_t i = 0; i < deg.size(); i++) deg[i]->degenerated = d;
374 }
375 
377 {
378  std::vector<BDS_Edge *> degenerated;
379  for(size_t i = 0; i < m.edges.size(); i++) {
380  BDS_Edge *e = m.edges[i];
381  if(!e->deleted && ((!e->p1->degenerated && e->p2->degenerated) ||
382  (e->p1->degenerated && !e->p2->degenerated)))
383  degenerated.push_back(e);
384  }
385  for(size_t i = 0; i < degenerated.size(); i++) {
386  BDS_Edge *e = degenerated[i];
387  if(!e->deleted && e->numfaces() == 2) {
388  double U = 0.5 * (e->p1->u + e->p2->u);
389  double V = 0.5 * (e->p1->v + e->p2->v);
390  GPoint gpp = gf->point(U, V);
391  BDS_Point *mid =
392  m.add_point(++m.MAXPOINTNUMBER, gpp.x(), gpp.y(), gpp.z());
393  mid->u = U;
394  mid->v = V;
395  mid->lc() = 0.5 * (e->p1->lc() + e->p2->lc());
396  // abort if one of the splits leads to an invalid mesh in the param plane
397  if(!m.split_edge(e, mid, true)) {
398  m.del_point(mid);
399  return;
400  }
401  }
402  }
403 }
404 
405 static void splitEdgePass(GFace *gf, BDS_Mesh &m, double MAXE_, int &nb_split,
406  std::vector<SPoint2> *true_boundary, double &t)
407 {
408  double t1 = Cpu();
409  std::vector<std::pair<double, BDS_Edge *> > edges;
410 
411  SPoint2 out(gf->parBounds(0).high() + 1.21982512,
412  gf->parBounds(1).high() + 1.8635436432);
413 
414  for(auto it = m.points.begin(); it != m.points.end(); ++it) {
415  BDS_Point *p = *it;
416  if(!p->_periodicCounterpart && (p->g && p->g->classif_degree == 2)) {
417  for(size_t i = 0; i < p->edges.size(); i++) {
418  BDS_Point *p1 =
419  p->edges[i]->p1 == p ? p->edges[i]->p2 : p->edges[i]->p1;
420  for(size_t j = 0; j < i; j++) {
421  BDS_Point *p2 =
422  p->edges[j]->p1 == p ? p->edges[j]->p2 : p->edges[j]->p1;
423  if(!p1->degenerated && !p2->degenerated && p1->_periodicCounterpart &&
424  p1->_periodicCounterpart == p2) {
425  edges.push_back(std::make_pair(-10.0, p->edges[i]));
426  edges.push_back(std::make_pair(-10.0, p->edges[j]));
427  }
428  }
429  }
430  }
431  }
432 
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) {
437  double lone = NewGetLc(*it, gf);
438  if(lone > MAXE_) edges.push_back(std::make_pair(-lone, *it));
439  }
440  ++it;
441  }
442 
443  std::sort(edges.begin(), edges.end(), edges_sort);
444 
445  std::vector<BDS_Point *> mids(edges.size());
446 
447  bool faceDiscrete = gf->geomType() == GEntity::DiscreteSurface;
448 
449  for(std::size_t i = 0; i < edges.size(); ++i) {
450  BDS_Edge *e = edges[i].second;
451  BDS_Point *mid = nullptr;
452  if(!e->deleted &&
454  double U1 = e->p1->u;
455  double U2 = e->p2->u;
456  double V1 = e->p1->v;
457  double V2 = e->p2->v;
458  if(e->p1->degenerated == 1) U1 = U2;
459  if(e->p2->degenerated == 1) U2 = U1;
460  if(e->p1->degenerated == 2) V1 = V2;
461  if(e->p2->degenerated == 2) V2 = V1;
462  double U = 0.5 * (U1 + U2);
463  double V = 0.5 * (V1 + V2);
464  if(faceDiscrete)
465  if(!middlePoint(gf, e, U, V)) continue;
466 
467  GPoint gpp = gf->point(U, V);
468  bool inside = true;
469  if(true_boundary) {
470  SPoint2 pp(U, V);
471  int N;
472  if(!pointInsideParametricDomain(*true_boundary, pp, out, N)) {
473  inside = false;
474  }
475  }
476  if(inside && gpp.succeeded()) {
477  mid = m.add_point(++m.MAXPOINTNUMBER, gpp.x(), gpp.y(), gpp.z());
478  mid->u = U;
479  mid->v = V;
480  mid->lc() = 0.5 * (e->p1->lc() + e->p2->lc());
481  mid->lcBGM() = BGM_MeshSize(gf, U, V, mid->X, mid->Y, mid->Z);
482  }
483  }
484  mids[i] = mid;
485  }
486 
487  for(std::size_t i = 0; i < edges.size(); ++i) {
488  BDS_Edge *e = edges[i].second;
489  if(!e->deleted) {
490  BDS_Point *mid = mids[i];
491  if(mid) {
492  if(!m.split_edge(e, mid))
493  m.del_point(mid);
494  else {
495  nb_split++;
496  }
497  }
498  }
499  }
500  t += (Cpu() - t1);
501 }
502 
504  BDS_Point *p)
505 {
506  BDS_Point *o = e->othervertex(p);
507 
508  double maxLc = 0.0;
509  std::vector<BDS_Edge *> edges(p->edges);
510  auto eit = edges.begin();
511  while(eit != edges.end()) {
512  BDS_Point *newP1 = nullptr, *newP2 = nullptr;
513  if((*eit)->p1 == p) {
514  newP1 = o;
515  newP2 = (*eit)->p2;
516  }
517  else if((*eit)->p2 == p) {
518  newP1 = (*eit)->p1;
519  newP2 = o;
520  }
521  if(!newP1 || !newP2) break; // error
522  BDS_Edge collapsedEdge = BDS_Edge(newP1, newP2);
523  maxLc = std::max(maxLc, NewGetLc(&collapsedEdge, gf));
524  newP1->del(&collapsedEdge);
525  newP2->del(&collapsedEdge);
526  ++eit;
527  }
528 
529  return maxLc;
530 }
531 
532 void collapseEdgePass(GFace *gf, BDS_Mesh &m, double MINE_, int MAXNP,
533  int &nb_collaps, double &t)
534 {
535  double t1 = Cpu();
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) {
541  double lone = NewGetLc(*it, gf);
542  if(lone < MINE_) edges.push_back(std::make_pair(lone, *it));
543  }
544  ++it;
545  }
546 
547  std::sort(edges.begin(), edges.end(), edges_sort);
548 
549  for(std::size_t i = 0; i < edges.size(); i++) {
550  BDS_Edge *e = edges[i].second;
551  if(!e->deleted &&
553  double lone1 = 0.;
554  bool collapseP1Allowed = false;
555  if(e->p1->iD > MAXNP) {
556  lone1 = getMaxLcWhenCollapsingEdge(gf, m, e, e->p1);
557  collapseP1Allowed =
558  std::abs(lone1 - 1.0) < std::abs(edges[i].first - 1.0);
559  }
560 
561  double lone2 = 0.;
562  bool collapseP2Allowed = false;
563  if(e->p2->iD > MAXNP) {
564  lone2 = getMaxLcWhenCollapsingEdge(gf, m, e, e->p2);
565  collapseP2Allowed =
566  std::abs(lone2 - 1.0) < std::abs(edges[i].first - 1.0);
567  }
568 
569  BDS_Point *p = nullptr;
570  if(collapseP1Allowed && collapseP2Allowed) {
571  if(std::abs(lone1 - lone2) < 1e-12)
572  p = e->p1->iD < e->p2->iD ? e->p1 : e->p2;
573  else
574  p = std::abs(lone1 - 1.0) < std::abs(lone2 - 1.0) ? e->p1 : e->p2;
575  }
576  else if(collapseP1Allowed && !collapseP2Allowed)
577  p = e->p1;
578  else if(collapseP2Allowed && !collapseP1Allowed)
579  p = e->p2;
580 
581  if(p && m.collapse_edge_parametric(e, p)) nb_collaps++;
582  }
583  }
584  t += (Cpu() - t1);
585 }
586 
587 void smoothVertexPass(GFace *gf, BDS_Mesh &m, int &nb_smooth, bool q,
588  double threshold, double &t)
589 {
590  double t1 = Cpu();
591  for(int i = 0; i < 1; i++) {
592  auto itp = m.points.begin();
593  while(itp != m.points.end()) {
594  if(neighboringModified(*itp)) {
595  if(m.smooth_point_centroid(*itp, gf, threshold)) nb_smooth++;
596  }
597  ++itp;
598  }
599  }
600  t += (Cpu() - t1);
601 }
602 
603 static void
605  std::map<BDS_Point *, MVertex *, PointLessThan> *recoverMap)
606 {
607  auto itp = m.points.begin();
608  while(itp != m.points.end()) {
609  auto it = (*itp)->edges.begin();
610  auto ite = (*itp)->edges.end();
611  double L = 0;
612  int ne = 0;
613  while(it != ite) {
614  double l = (*it)->length();
615  if((*it)->g && (*it)->g->classif_degree == 1) {
616  L = ne ? std::max(L, l) : l;
617  ne++;
618  }
619  ++it;
620  }
621  if((*itp)->g && (*itp)->g->classif_tag > 0) {
622  if(!ne) L = MAX_LC;
623  if(CTX::instance()->mesh.lcFromPoints) (*itp)->lc() = L;
624  (*itp)->lcBGM() = L;
625  }
626  ++itp;
627  }
628  return;
629  {
630  auto itp = m.points.begin();
631  while(itp != m.points.end()) {
632  (*itp)->lc() = MAX_LC;
633  ++itp;
634  }
635  auto it = m.edges.begin();
636  while(it != m.edges.end()) {
637  bool degenerated = false;
638 
639  if(recoverMap) {
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) {
644  degenerated = true;
645  }
646  }
647  if(!degenerated && (*it)->g && (*it)->g->classif_degree == 1) {
648  double L = (*it)->length();
649  if((*it)->p1->lc() == MAX_LC)
650  (*it)->p1->lc() = L;
651  else
652  (*it)->p1->lc() = std::max(L, (*it)->p1->lc());
653  if((*it)->p2->lc() == MAX_LC)
654  (*it)->p2->lc() = L;
655  else
656  (*it)->p2->lc() = std::max(L, (*it)->p2->lc());
657  }
658  ++it;
659  }
660 
661  itp = m.points.begin();
662  std::vector<BDS_Point *> pts;
663  while(itp != m.points.end()) {
664  if((*itp)->lc() == MAX_LC) pts.push_back(*itp);
665  ++itp;
666  }
667  int iter = 0;
668  while(1) {
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();
673  while(it != ite) {
674  BDS_Point *p = (*it)->othervertex(pts[i]);
675  if(p->lc() != MAX_LC) {
676  if(pts[i]->lc() == MAX_LC)
677  pts[i]->lc() = p->lc();
678  else
679  pts[i]->lc() = 0.5 * (p->lc() + pts[i]->lc());
680  }
681  ++it;
682  }
683  if(pts[i]->lc() == MAX_LC) allTouched = false;
684  }
685  if(iter++ >= 5 || allTouched) break;
686  }
687  }
688 }
689 
691  GFace *gf, BDS_Mesh &m,
692  std::map<BDS_Point *, MVertex *, PointLessThan> *recoverMap)
693 {
694  std::set<MVertex *, MVertexPtrLessThan> degenerated;
695  std::vector<BDS_Edge *> degenerated_edges;
696  getDegeneratedVertices(m, recoverMap, degenerated, degenerated_edges);
697 
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) {
706  Msg::Debug(
707  "Degenerated edge on u = cst axis: treated as well now!");
708  it->first->degenerated = 2;
709  }
710  else {
711  it->first->degenerated = 1;
712  }
713  }
714  }
715  }
716  }
717  for(size_t i = 0; i < degenerated_edges.size(); i++) {
718  m.collapse_edge_parametric(degenerated_edges[i], degenerated_edges[i]->p1,
719  true);
720  recoverMap->erase(degenerated_edges[i]->p1);
721  }
722 }
723 
724 //#define superdebug 1
725 
726 void refineMeshBDS(GFace *gf, BDS_Mesh &m, const int NIT,
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)
731 {
732 #ifdef superdebug
733  outputScalarField(m.triangles, "initial.pos", 1, gf);
734  getchar();
735 #endif
736 
737  int IT = 0;
738  int MAXNP = m.MAXPOINTNUMBER;
739 
740  // classify correctly the embedded vertices use a negative model
741  // face number to avoid mesh motion
742  if(recoverMapInv) {
743  std::vector<GVertex *> emb_vertx = gf->getEmbeddedVertices();
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()) {
749  BDS_Point *p = itp->second;
750  m.add_geom(-1, 2);
751  p->g = m.get_geom(-1, 2);
752  ++itvx;
753  }
754  }
755  }
756 
757  // if asked, compute nodal size field using 1D Mesh
758  if(computeNodalSizeField) computeNodalSizes(gf, m, recoverMap);
759 
760  double t_spl = 0, t_sw = 0, t_col = 0, t_sm = 0;
761 
762  const double MINE_ = 0.7, MAXE_ = 1.4;
763 
764  {
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;
770  }
771  ++it;
772  }
773  }
774 
775  std::vector<BDS_Point *> deg;
776  getDegeneracy(m, deg);
777  short degType = 1;
778  if(deg.size()) degType = deg[0]->degenerated;
779 
780  if(computeNodalSizeField) {
782 #ifdef superdebug
783  outputScalarField(m.triangles, "cut_all_degenerate.pos", 1, gf);
784  getchar();
785 #endif
786  }
787 
788  while(1) {
789  setDegeneracy(deg, degType);
790 
791  // we count the number of local mesh modifs.
792  int nb_split = 0;
793  int nb_smooth = 0;
794  int nb_collaps = 0;
795  int nb_swap = 0;
796 
797  // split long edges
798  double maxE = MAXE_;
799  double minE = MINE_;
800  splitEdgePass(gf, m, maxE, nb_split, true_boundary, t_spl);
801  if(IT == 0) {
802 #ifdef superdebug
803  outputScalarField(m.triangles, "split00.pos", 0, gf);
804  outputScalarField(m.triangles, "split01.pos", 1, gf);
805 #endif
806  splitEdgePass(gf, m, maxE, nb_split, true_boundary, t_spl);
807  }
808 #ifdef superdebug
809  outputScalarField(m.triangles, "split0.pos", 0, gf);
810  outputScalarField(m.triangles, "split1.pos", 1, gf);
811 #endif
812  smoothVertexPass(gf, m, nb_smooth, false, .5, t_sm);
813 #ifdef superdebug
814  outputScalarField(m.triangles, "splitsmooth0.pos", 0, gf);
815  outputScalarField(m.triangles, "splitsmooth1.pos", 1, gf);
816 #endif
817 
818  swapEdgePass(gf, m, nb_swap, t_sw);
819  smoothVertexPass(gf, m, nb_smooth, false, .5, t_sm);
820 
821 #ifdef superdebug
822  outputScalarField(m.triangles, "swapsmooth1.pos", 1, gf);
823  outputScalarField(m.triangles, "swapsmooth0.pos", 0, gf);
824 #endif
825 
826  collapseEdgePass(gf, m, minE, MAXNP, nb_collaps, t_col);
827 #ifdef superdebug
828  outputScalarField(m.triangles, "collapse0.pos", 0, gf);
829  outputScalarField(m.triangles, "collapse1.pos", 1, gf);
830 #endif
831  smoothVertexPass(gf, m, nb_smooth, false, .5, t_sm);
832 #ifdef superdebug
833  outputScalarField(m.triangles, "collapsemooth.pos", 1, gf);
834 #endif
835 
836  swapEdgePass(gf, m, nb_swap, t_sw);
837 #ifdef superdebug
838  outputScalarField(m.triangles, "d1.pos", 1, gf);
839 #endif
840  smoothVertexPass(gf, m, nb_smooth, false, .5, t_sm);
841 #ifdef superdebug
842  outputScalarField(m.triangles, "temp0.pos", 0, gf);
843  outputScalarField(m.triangles, "temp1.pos", 1, gf);
844  printf("IN FULL DEBUG MODE AT ITER %d/%d : press enter\n", IT, NIT);
845  getchar();
846  printf("THANKS .. continuing\n");
847 #endif
848 
849  // remove small edges
850  if(IT == abs(NIT)) {
851  collapseEdgePass(gf, m, .45, MAXNP, nb_collaps, t_col);
852  smoothVertexPass(gf, m, nb_smooth, false, .5, t_sm);
853  }
854 
855  // CHECK_STRANGE("smmooth", m);
856 
857  m.cleanup();
858 
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() /
865  (NewGetLc((*it)->p1, gf) + NewGetLc((*it)->p2, gf));
866  if(lone > maxE) LARGE++;
867  if(lone < minE) SMALL++;
868  TOTAL++;
869  maxL = std::max(maxL, lone);
870  minL = std::min(minL, lone);
871  }
872  ++it;
873  }
874  if((minL > MINE_ && maxL < MAXE_) || IT > (abs(NIT))) break;
875 
876  IT++;
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);
882  // getchar();
883  if(nb_split == 0 && nb_collaps == 0) break;
884  }
885 
886 #ifdef superdebug
887  printf("FULL DEBUG MODE : cleaning bad triangles\n");
888  outputScalarField(m.triangles, "before0.pos", 0, gf);
889  outputScalarField(m.triangles, "before1.pos", 1, gf);
890 #endif
891 
892  int ITER = 0;
893  int bad = 0;
894  int invalid = 0;
895 
896  if(gf->getNativeType() != GEntity::GmshModel) {
897  for(size_t i = 0; i < m.triangles.size(); i++) {
898  double val = BDS_Face_Validity(gf, m.triangles[i]);
899  invalid += val < 0 ? 1 : 0;
900  }
901  double orientation = invalid > (int)m.triangles.size() / 2 ? -1.0 : 1.0;
902 
903 #ifdef superdebug
904  printf("NOW FIXING BAD ELEMENTS\n");
905 #endif
906 
907  while(1) {
908  bad = 0;
909  invalid = 0;
910  for(size_t i = 0; i < m.triangles.size(); i++) {
911  BDS_Point *pts[4];
912  if(!m.triangles[i]->deleted && m.triangles[i]->getNodes(pts)) {
913  pts[0]->config_modified = false;
914  pts[1]->config_modified = false;
915  pts[2]->config_modified = false;
916  }
917  }
918  for(size_t i = 0; i < m.triangles.size(); i++) {
919  BDS_Point *pts[4];
920  if(m.triangles[i]->getNodes(pts)) {
921  double val = orientation * BDS_Face_Validity(gf, m.triangles[i]);
922  if(val <= 0.2) {
923  if(!m.triangles[i]->deleted && val <= 0) invalid++;
924  pts[0]->config_modified = true;
925  pts[1]->config_modified = true;
926  pts[2]->config_modified = true;
927  bad++;
928  if(val < 0) { invalid++; }
929  }
930  }
931  }
932  if(++ITER == 10) {
933  if(invalid && !computeNodalSizeField) {
935  Msg::Warning("%d element%s remain invalid in surface %d", invalid,
936  (invalid > 1) ? "s" : "", gf->tag());
937  }
938  break;
939  }
940 
941  if(bad != 0) {
942  int nb_swap = 0;
943  int nb_smooth = 0;
944  swapEdgePass(gf, m, nb_swap, t_sw, 1, orientation);
945  smoothVertexPass(gf, m, nb_smooth, true, .5, t_sm);
946  }
947  else {
948  // everything ok!
949  break;
950  }
951  }
952  }
953 
954  setDegeneracy(deg, degType);
955 
956  double t_total = t_spl + t_sw + t_col + t_sm;
957  if(!t_total) t_total = 1.e-6;
958  Msg::Debug(" ---------------------------------------");
959  Msg::Debug(" CPU Report ");
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(" ---------------------------------------");
970 }
neighboringModified
static bool neighboringModified(BDS_Point *p)
Definition: meshGFaceBDS.cpp:166
GPoint::succeeded
bool succeeded() const
Definition: GPoint.h:63
BDS_Mesh::smooth_point_centroid
bool smooth_point_centroid(BDS_Point *p, GFace *gf, double thresh)
Definition: BDS.cpp:1613
qualityMeasures.h
BDS_Edge::p1
BDS_Point * p1
Definition: BDS.h:160
GFace::status
GEntity::MeshGenerationStatus status
Definition: GFace.h:395
splitEdgePass
static void splitEdgePass(GFace *gf, BDS_Mesh &m, double MAXE_, int &nb_split, std::vector< SPoint2 > *true_boundary, double &t)
Definition: meshGFaceBDS.cpp:405
BDS_Edge::deleted
bool deleted
Definition: BDS.h:159
BDS_Mesh
Definition: BDS.h:339
middlePoint
static bool middlePoint(GFace *gf, BDS_Edge *e, double &u, double &v)
Definition: meshGFaceBDS.cpp:276
GPoint::y
double y() const
Definition: GPoint.h:22
GFace.h
BDS_SwapEdgeTestNormals
Definition: BDS.h:302
GFace::getEmbeddedVertices
std::vector< GVertex * > getEmbeddedVertices(bool force=false) const
Definition: GFace.cpp:355
GFace
Definition: GFace.h:33
SPoint2
Definition: SPoint2.h:12
OS.h
smoothVertexPass
void smoothVertexPass(GFace *gf, BDS_Mesh &m, int &nb_smooth, bool q, double threshold, double &t)
Definition: meshGFaceBDS.cpp:587
Msg::Debug
static void Debug(const char *fmt,...)
Definition: GmshMessage.cpp:752
robustPredicates.h
MVertex
Definition: MVertex.h:24
Msg::Warning
static void Warning(const char *fmt,...)
Definition: GmshMessage.cpp:543
BDS_Mesh::split_edge
bool split_edge(BDS_Edge *, BDS_Point *, bool check_area_param=false)
Definition: BDS.cpp:674
BackgroundMesh.h
BDS_Mesh::get_geom
BDS_GeomEntity * get_geom(int p1, int p2)
Definition: BDS.cpp:597
swapEdgePass
static void swapEdgePass(GFace *gf, BDS_Mesh &m, int &nb_swap, double &t, int FINALIZE=0, double orientation=1.0)
Definition: meshGFaceBDS.cpp:179
SPoint3
Definition: SPoint3.h:14
LegendrePolynomials::f
void f(int n, double u, double *val)
Definition: orthogonalBasis.cpp:77
swapquad
Definition: meshGFaceOptimize.h:75
GFace::point
virtual GPoint point(double par1, double par2) const =0
meshGFaceOptimize.h
NewGetLc
static double NewGetLc(BDS_Point *point, GFace *gf)
Definition: meshGFaceBDS.cpp:86
BDS_Point::g
BDS_GeomEntity * g
Definition: BDS.h:62
GEntity::getNativeType
virtual ModelType getNativeType() const
Definition: GEntity.h:268
BDS_SwapEdgeTest
Definition: BDS.h:261
BDS_Point::config_modified
bool config_modified
Definition: BDS.h:58
BDS_Mesh::triangles
std::vector< BDS_Face * > triangles
Definition: BDS.h:349
GmshMessage.h
BDS_Point::edges
std::vector< BDS_Edge * > edges
Definition: BDS.h:63
edges
static int edges[6][2]
Definition: meshGRegionLocalMeshMod.cpp:23
GEntity::GmshModel
@ GmshModel
Definition: GEntity.h:81
MAX_LC
#define MAX_LC
Definition: GEntity.h:19
BDS_GeomEntity::classif_degree
int classif_degree
Definition: BDS.h:34
BDS_SwapEdgeTestQuality
Definition: BDS.h:285
GPoint
Definition: GPoint.h:13
BDS_Point::lcBGM
double & lcBGM()
Definition: BDS.h:65
GFace::closestPoint
virtual GPoint closestPoint(const SPoint3 &queryPoint, const double initialGuess[2]) const
Definition: GFace.cpp:1323
buildMetric
void buildMetric(GFace *gf, double *uv, double *metric)
Definition: meshGFaceDelaunayInsertion.cpp:332
BDS_Mesh::collapse_edge_parametric
bool collapse_edge_parametric(BDS_Edge *, BDS_Point *, bool=false)
Definition: BDS.cpp:1074
Extend1dMeshIn2dSurfaces
bool Extend1dMeshIn2dSurfaces(GFace *gf)
Definition: BackgroundMeshTools.cpp:339
BDS_Edge::oppositeof
void oppositeof(BDS_Point *oface[2]) const
Definition: BDS.cpp:572
BDS_Edge::p2
BDS_Point * p2
Definition: BDS.h:160
GEntity::Plane
@ Plane
Definition: GEntity.h:105
GPoint::z
double z() const
Definition: GPoint.h:23
CTX::instance
static CTX * instance()
Definition: Context.cpp:122
edges_sort
static bool edges_sort(std::pair< double, BDS_Edge * > a, std::pair< double, BDS_Edge * > b)
Definition: meshGFaceBDS.cpp:259
GEdge.h
BDS_Point::X
double X
Definition: BDS.h:56
GFace::meshStatistics
struct GFace::@19 meshStatistics
GPoint::u
double u() const
Definition: GPoint.h:27
BDS_Mesh::points
std::set< BDS_Point *, PointLessThan > points
Definition: BDS.h:347
edgeSwapTestAngle
static bool edgeSwapTestAngle(BDS_Edge *e, double min_cos)
Definition: meshGFaceBDS.cpp:125
MVertex.h
BDS_Face_Validity
double BDS_Face_Validity(GFace *gf, BDS_Face *f)
Definition: BDS.cpp:33
qmTriangle::gamma
static double gamma(MTriangle *f)
Definition: qualityMeasures.cpp:146
Numeric.h
BDS_Point::v
double v
Definition: BDS.h:57
computeNodalSizes
static void computeNodalSizes(GFace *gf, BDS_Mesh &m, std::map< BDS_Point *, MVertex *, PointLessThan > *recoverMap)
Definition: meshGFaceBDS.cpp:604
Cpu
double Cpu()
Definition: OS.cpp:366
BDS_Point::degenerated
short degenerated
Definition: BDS.h:59
BGM_MeshSize
double BGM_MeshSize(GEntity *ge, double U, double V, double X, double Y, double Z)
Definition: BackgroundMeshTools.cpp:255
BDS_Mesh::cleanup
void cleanup()
Definition: BDS.cpp:642
GEntity::geomType
virtual GeomType geomType() const
Definition: GEntity.h:238
collapseEdgePass
void collapseEdgePass(GFace *gf, BDS_Mesh &m, double MINE_, int MAXNP, int &nb_collaps, double &t)
Definition: meshGFaceBDS.cpp:532
prosca
double prosca(double const a[3], double const b[3])
Definition: Numeric.h:112
getMaxLcWhenCollapsingEdge
double getMaxLcWhenCollapsingEdge(GFace *gf, BDS_Mesh &m, BDS_Edge *e, BDS_Point *p)
Definition: meshGFaceBDS.cpp:503
getDegeneracy
static void getDegeneracy(BDS_Mesh &m, std::vector< BDS_Point * > &deg)
Definition: meshGFaceBDS.cpp:361
GFace::mesh
virtual void mesh(bool verbose)
Definition: GFace.cpp:2142
BDS.h
GEntity::tag
int tag() const
Definition: GEntity.h:280
edgeSwapTest
static int edgeSwapTest(GFace *gf, BDS_Edge *e)
Definition: meshGFaceBDS.cpp:140
discreteFace.h
BDS_Point::iD
int iD
Definition: BDS.h:61
BDS_Edge::faces
BDS_Face * faces(std::size_t const i) const
Definition: BDS.h:103
norm2
double norm2(double a[3][3])
Definition: Numeric.cpp:38
normal_triangle
void normal_triangle(BDS_Point *p1, BDS_Point *p2, BDS_Point *p3, double c[3])
Definition: BDS.cpp:185
GEntity::parBounds
virtual Range< double > parBounds(int i) const
Definition: GEntity.h:259
refineMeshBDS
void refineMeshBDS(GFace *gf, BDS_Mesh &m, const int NIT, const bool computeNodalSizeField, std::map< MVertex *, BDS_Point * > *recoverMapInv, std::map< BDS_Point *, MVertex *, PointLessThan > *recoverMap, std::vector< SPoint2 > *true_boundary)
Definition: meshGFaceBDS.cpp:726
BDS_Edge::numfaces
int numfaces() const
Definition: BDS.h:110
GEntity::DiscreteSurface
@ DiscreteSurface
Definition: GEntity.h:117
BDS_Face
Definition: BDS.h:164
BDS_Mesh::add_geom
void add_geom(int degree, int tag)
Definition: BDS.cpp:539
SPoint3::distance
double distance(const SPoint3 &p) const
Definition: SPoint3.h:176
BDS_Face::getNodes
bool getNodes(BDS_Point *_n[4]) const
Definition: BDS.h:201
BDS_Edge::othervertex
BDS_Point * othervertex(const BDS_Point *p) const
Definition: BDS.h:120
meshGFace.h
outputScalarField
void outputScalarField(std::vector< BDS_Face * > &t, const char *iii, int param, GFace *gf)
Definition: BDS.cpp:46
Context.h
setDegeneracy
static void setDegeneracy(std::vector< BDS_Point * > &deg, short d)
Definition: meshGFaceBDS.cpp:371
BDS_Point::del
void del(BDS_Edge *e)
Definition: BDS.h:71
GVertex.h
pointInsideParametricDomain
bool pointInsideParametricDomain(std::vector< SPoint2 > &bnd, SPoint2 &p, SPoint2 &out, int &N)
Definition: meshGFace.cpp:43
BDS_Mesh::add_point
BDS_Point * add_point(int num, double x, double y, double z)
Definition: BDS.cpp:257
BDS_Point::Y
double Y
Definition: BDS.h:56
MElement.h
BDS_Mesh::del_point
void del_point(BDS_Point *p)
Definition: BDS.cpp:533
modifyInitialMeshToRemoveDegeneracies
void modifyInitialMeshToRemoveDegeneracies(GFace *gf, BDS_Mesh &m, std::map< BDS_Point *, MVertex *, PointLessThan > *recoverMap)
Definition: meshGFaceBDS.cpp:690
correctLC_
static double correctLC_(BDS_Point *p1, BDS_Point *p2, GFace *f)
Definition: meshGFaceBDS.cpp:92
GPoint::v
double v() const
Definition: GPoint.h:28
BDS_Edge
Definition: BDS.h:85
BDS_Point::u
double u
Definition: BDS.h:57
GPoint.h
computeEdgeLinearLength
static double computeEdgeLinearLength(BDS_Point *p1, BDS_Point *p2)
Definition: meshGFaceBDS.cpp:50
BDS_Edge::length
double length() const
Definition: BDS.h:104
GModel.h
BDS_Point
Definition: BDS.h:49
getDegeneratedVertices
static void getDegeneratedVertices(BDS_Mesh &m, std::map< BDS_Point *, MVertex *, PointLessThan > *recoverMap, std::set< MVertex *, MVertexPtrLessThan > &degenerated, std::vector< BDS_Edge * > &degenerated_edges)
Definition: meshGFaceBDS.cpp:26
BDS_Mesh::edges
std::vector< BDS_Edge * > edges
Definition: BDS.h:348
inCircumCircleAniso
int inCircumCircleAniso(GFace *gf, double *p1, double *p2, double *p3, double *uv, double *metric)
Definition: meshGFaceDelaunayInsertion.cpp:348
BDS_Point::lc
double & lc()
Definition: BDS.h:66
edgeSwapTestDelaunayAniso
static bool edgeSwapTestDelaunayAniso(BDS_Edge *e, GFace *gf, std::set< swapquad > &configs)
Definition: meshGFaceBDS.cpp:208
GEntity::FAILED
@ FAILED
Definition: GEntity.h:130
delaunayizeBDS
void delaunayizeBDS(GFace *gf, BDS_Mesh &m, int &nb_swap)
Definition: meshGFaceBDS.cpp:236
GPoint::x
double x() const
Definition: GPoint.h:21
BDS_Mesh::swap_edge
bool swap_edge(BDS_Edge *, const BDS_SwapEdgeTest &theTest, bool force=false)
Can invalidate the iterators for edge.
Definition: BDS.cpp:926
robustPredicates::orient2d
REAL orient2d(REAL *pa, REAL *pb, REAL *pc)
Definition: robustPredicates.cpp:1633
BDS_Point::_periodicCounterpart
BDS_Point * _periodicCounterpart
Definition: BDS.h:60
splitAllEdgesConnectedToSingularity
static void splitAllEdgesConnectedToSingularity(GFace *gf, BDS_Mesh &m)
Definition: meshGFaceBDS.cpp:376
BDS_Mesh::MAXPOINTNUMBER
int MAXPOINTNUMBER
Definition: BDS.h:341
BDS_Point::Z
double Z
Definition: BDS.h:56