gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
discreteFace.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 <queue>
8 #include "GmshMessage.h"
9 #include "discreteEdge.h"
10 #include "discreteFace.h"
11 #include "GModelIO_GEO.h"
12 #include "Geo.h"
13 #include "Context.h"
14 #include "MPoint.h"
15 #include "MElementOctree.h"
16 #include "Octree.h"
17 #include "Context.h"
18 #include "GEdgeLoop.h"
19 #include "MEdge.h"
20 #include "GModelParametrize.h"
21 
22 #if defined(HAVE_EIGEN) && defined(HAVE_GEOMETRYCENTRAL)
23 #include <Eigen/Core>
24 #include <Eigen/Dense>
25 #include "geometrycentral/surface/signpost_intrinsic_triangulation.h"
26 #include "geometrycentral/surface/vertex_position_geometry.h"
27 #endif
28 
30 {
31  clear();
32 }
33 
35 {
36  if(oct) delete oct;
37  rtree3d.RemoveAll();
38  for(auto p : rtree3dData) delete p;
39  rtree3dData.clear();
40  v2d.clear();
41  v3d.clear();
42  bbox = SBoundingBox3d();
43  t2d.clear();
44  t3d.clear();
45  CURV.clear();
46 }
47 
49 {
50  SBoundingBox3d bb;
51  mean_plane mp;
52  std::vector<SPoint3> v, vp;
53  for(size_t i = 0; i < t3d.size(); i++) {
54  for(int j = 0; j < 3; j++) {
55  SPoint3 p(t3d[i].getVertex(j)->x(), t3d[i].getVertex(j)->y(),
56  t3d[i].getVertex(j)->z());
57  bb += p;
58  v.push_back(p);
59  }
60  }
61 
63  projectPointsToPlane(v, vp, mp);
64  for(size_t i = 0; i < v.size(); i++) {
65  double F = mp.a * v[i].x() + mp.b * v[i].y() + mp.c * v[i].z() - mp.d;
66  // this is maybe a bit strict, but it's better this way: wrongly identifying
67  // a very thin (but curved) surface as plane will lead to complete meshing
68  // failure (see e.g. mmbendo.stl in #641)
69  if(fabs(F) > CTX::instance()->geom.matchMeshTolerance * bb.diag()) {
70  return false;
71  }
72  }
73 
74  SVector3 VX(mp.plan[0][0], mp.plan[0][1], mp.plan[0][2]);
75  SVector3 VY(mp.plan[1][0], mp.plan[1][1], mp.plan[1][2]);
76  SPoint3 XP(mp.x, mp.y, mp.z);
77 
78  umin = 1e200;
79  vmin = 1e200;
80  umax = -1e200;
81  vmax = -1e200;
82 
83  int count = 0;
84  for(size_t i = 0; i < t2d.size(); i++) {
85  for(int j = 0; j < 3; j++) {
86  SVector3 DX = vp[count++] - XP;
87  MVertex *v = t2d[i].getVertex(j);
88  v->x() = dot(DX, VX);
89  v->y() = dot(DX, VY);
90  umin = std::min(umin, v->x());
91  vmin = std::min(vmin, v->y());
92  umax = std::max(umax, v->x());
93  vmax = std::max(vmax, v->y());
94  }
95  }
96  return true;
97 }
98 
100 {
103  meshStatistics.status = GFace::DONE;
104 }
105 
107 {
108  // used for temporary discrete faces, that should not lead to the creation of
109  // the corresponding entity in GEO internals
110 }
111 
112 int discreteFace::trianglePosition(double par1, double par2, double &u,
113  double &v) const
114 {
115  if(_param.empty()) return 0;
116 
117  double xy[3] = {par1, par2, 0};
118  double uv[3];
119  const MElement *e = _param.oct->find(par1, par2, 0.0, -1, true);
120  if(!e) return -1;
121  e->xyz2uvw(xy, uv);
122  int position = (int)((MTriangle *)e - &_param.t2d[0]);
123  u = uv[0];
124  v = uv[1];
125  return position;
126 }
127 
128 static void MYxyz2uvw(const MElement *t, double xyz[3], double uvw[3])
129 {
130  double M[2][2], R[2];
131  const SPoint2 p0(t->getVertex(0)->x(), t->getVertex(0)->y());
132  const SPoint2 p1(t->getVertex(1)->x(), t->getVertex(1)->y());
133  const SPoint2 p2(t->getVertex(2)->x(), t->getVertex(2)->y());
134  M[0][0] = p1.x() - p0.x();
135  M[0][1] = p2.x() - p0.x();
136  M[1][0] = p1.y() - p0.y();
137  M[1][1] = p2.y() - p0.y();
138  R[0] = (xyz[0] - p0.x());
139  R[1] = (xyz[1] - p0.y());
140  double const det = M[0][0] * M[1][1] - M[1][0] * M[0][1];
141  uvw[0] = R[0] * M[1][1] - M[0][1] * R[1];
142  uvw[1] = M[0][0] * R[1] - M[1][0] * R[0];
143  uvw[0] /= det;
144  uvw[1] /= det;
145  return;
146 }
147 
148 GPoint discreteFace::point(double par1, double par2) const
149 {
150  if(_param.empty()) return GPoint();
151 
152  double xy[3] = {par1, par2, 0};
153  double uv[3];
154  const MElement *e = _param.oct->find(par1, par2, 0.0, -1, true);
155  if(!e) {
156  GPoint gp = GPoint(1.e21, 1.e21, 1.e21, this, xy);
157  gp.setNoSuccess();
158  return gp;
159  }
160  MYxyz2uvw(e, xy, uv);
161  int position = (int)((MTriangle *)e - &_param.t2d[0]);
162  const MTriangle &t3d = _param.t3d[position];
163  double X = 0, Y = 0, Z = 0;
164  double eval[3] = {1. - uv[0] - uv[1], uv[0], uv[1]};
165  for(int io = 0; io < 3; io++) {
166  X += t3d.getVertex(io)->x() * eval[io];
167  Y += t3d.getVertex(io)->y() * eval[io];
168  Z += t3d.getVertex(io)->z() * eval[io];
169  }
170  return GPoint(X, Y, Z, this, xy);
171 }
172 
173 class dfWrapper {
174 public:
176  double _distance;
179  dfWrapper(const SPoint3 &p)
180  : _p(p), _distance(1.e22), _t3d(nullptr), _t2d(nullptr)
181  {
182  }
183 };
184 
185 bool discreteFace_rtree_callback(std::pair<MTriangle *, MTriangle *> *t,
186  void *w)
187 {
188  dfWrapper *wrapper = static_cast<dfWrapper *>(w);
189 
190  SPoint3 closePt;
191  double d;
193  SPoint3(t->first->getVertex(0)->x(), t->first->getVertex(0)->y(),
194  t->first->getVertex(0)->z()),
195  SPoint3(t->first->getVertex(1)->x(), t->first->getVertex(1)->y(),
196  t->first->getVertex(1)->z()),
197  SPoint3(t->first->getVertex(2)->x(), t->first->getVertex(2)->y(),
198  t->first->getVertex(2)->z()),
199  wrapper->_p, d, closePt);
200  if(fabs(d) < wrapper->_distance) {
201  wrapper->_distance = fabs(d);
202  wrapper->_closestPoint = closePt;
203  wrapper->_t3d = t->first;
204  wrapper->_t2d = t->second;
205  }
206 
207  return true;
208 }
209 
210 GPoint discreteFace::closestPoint(const SPoint3 &queryPoint, double maxDistance,
211  SVector3 *normal) const
212 {
213  if(_param.empty()) {
214  auto pp = GPoint();
215  pp.setNoSuccess();
216  return pp;
217  }
218 
219  dfWrapper wrapper(queryPoint);
220  do {
221  wrapper._distance = 1.e22;
222  double MIN[3] = {queryPoint.x() - maxDistance, queryPoint.y() - maxDistance,
223  queryPoint.z() - maxDistance};
224  double MAX[3] = {queryPoint.x() + maxDistance, queryPoint.y() + maxDistance,
225  queryPoint.z() + maxDistance};
227  maxDistance *= 2.0;
228  } while(!wrapper._t3d);
229 
230  if(normal) {
231  SVector3 t1(
232  wrapper._t3d->getVertex(1)->x() - wrapper._t3d->getVertex(0)->x(),
233  wrapper._t3d->getVertex(1)->y() - wrapper._t3d->getVertex(0)->y(),
234  wrapper._t3d->getVertex(1)->z() - wrapper._t3d->getVertex(0)->z());
235  SVector3 t2(
236  wrapper._t3d->getVertex(2)->x() - wrapper._t3d->getVertex(0)->x(),
237  wrapper._t3d->getVertex(2)->y() - wrapper._t3d->getVertex(0)->y(),
238  wrapper._t3d->getVertex(2)->z() - wrapper._t3d->getVertex(0)->z());
239  *normal = crossprod(t1, t2);
240  normal->normalize();
241  }
242 
243  double xyz[3] = {wrapper._closestPoint.x(), wrapper._closestPoint.y(),
244  wrapper._closestPoint.z()};
245  double uvw[3];
246  wrapper._t3d->xyz2uvw(xyz, uvw);
247  const MVertex *v0 = wrapper._t2d->getVertex(0);
248  const MVertex *v1 = wrapper._t2d->getVertex(1);
249  const MVertex *v2 = wrapper._t2d->getVertex(2);
250  const MVertex *v03 = wrapper._t3d->getVertex(0);
251  const MVertex *v13 = wrapper._t3d->getVertex(1);
252  const MVertex *v23 = wrapper._t3d->getVertex(2);
253  double U = 1 - uvw[0] - uvw[1];
254  double V = uvw[0];
255  double W = uvw[1];
256  SPoint2 pp(U * v0->x() + V * v1->x() + W * v2->x(),
257  U * v0->y() + V * v1->y() + W * v2->y());
258  SPoint3 pp3(U * v03->x() + V * v13->x() + W * v23->x(),
259  U * v03->y() + V * v13->y() + W * v23->y(),
260  U * v03->z() + V * v13->z() + W * v23->z());
261 
262  return GPoint(pp3.x(), pp3.y(), pp3.z(), this, pp);
263 }
264 
266  const double initialGuess[2]) const
267 {
268  return closestPoint(queryPoint, 1e-1);
269 }
270 
271 SPoint2 discreteFace::parFromPoint(const SPoint3 &p, bool onSurface,
272  bool convTestXYZ) const
273 {
274  GPoint gp = closestPoint(p, 1e-6);
275  return SPoint2(gp.u(), gp.v());
276 }
277 
279 {
280  if(i == 0)
282  else
284 }
285 
287 {
288  if(_param.empty()) return false;
289  if(_param.oct->find(pt.x(), pt.y(), 0.0, -1, true)) return true;
290  return false;
291 }
292 
294 {
295  if(_param.empty()) return GFace::bounds(fast);
296  return _param.bbox;
297 }
298 
300 {
301  if(_param.empty()) return SVector3();
302 
303  MElement *e = _param.oct->find(param.x(), param.y(), 0.0, -1, true);
304  if(!e) {
305  Msg::Info("Triangle not found at uv=(%g,%g) on discrete surface %d",
306  param.x(), param.y(), tag());
307  return SVector3(0, 0, 1);
308  }
309  int position = (int)((MTriangle *)e - &_param.t2d[0]);
310  const MTriangle &t3d = _param.t3d[position];
311  SVector3 v31(t3d.getVertex(2)->x() - t3d.getVertex(0)->x(),
312  t3d.getVertex(2)->y() - t3d.getVertex(0)->y(),
313  t3d.getVertex(2)->z() - t3d.getVertex(0)->z());
314  SVector3 v21(t3d.getVertex(1)->x() - t3d.getVertex(0)->x(),
315  t3d.getVertex(1)->y() - t3d.getVertex(0)->y(),
316  t3d.getVertex(1)->z() - t3d.getVertex(0)->z());
317  SVector3 n = crossprod(v21, v31);
318  n.normalize();
319  return n;
320 }
321 
323 {
324  if(_param.empty()) return 0.;
325 
326  SVector3 dirMax, dirMin;
327  double c, C;
328  if(_param.CURV.empty()) return 0.0;
329  curvatures(param, dirMax, dirMin, C, c);
330  return std::max(c, C);
331 }
332 
334  SVector3 &dirMin, double &curvMax,
335  double &curvMin) const
336 {
337  if(_param.empty()) return 0.;
338  if(_param.CURV.empty()) return 0.0;
339 
340  MElement *e = _param.oct->find(param.x(), param.y(), 0.0, -1, true);
341  if(!e) {
342  Msg::Info("Triangle not found for curvatures at uv=(%g,%g) on "
343  "discrete surface %d",
344  param.x(), param.y(), tag());
345  return 0.0;
346  }
347 
348  int position = (int)((MTriangle *)e - &_param.t2d[0]);
349 
350  SVector3 c0max = _param.CURV[6 * position + 0];
351  SVector3 c1max = _param.CURV[6 * position + 1];
352  SVector3 c2max = _param.CURV[6 * position + 2];
353  SVector3 c0min = _param.CURV[6 * position + 3];
354  SVector3 c1min = _param.CURV[6 * position + 4];
355  SVector3 c2min = _param.CURV[6 * position + 5];
356 
357  curvMax = c0max.norm();
358  curvMin = c0min.norm();
359 
360  dirMax = c0max.normalize();
361  dirMin = c0min.normalize();
362 
363  return false;
364 }
365 
367 {
369 
370  MElement *e = _param.oct->find(param.x(), param.y(), 0.0, -1, true);
371  if(!e) {
372  Msg::Info("Triangle not found for first derivative at uv=(%g,%g) on "
373  "discrete surface %d",
374  param.x(), param.y(), tag());
375  return Pair<SVector3, SVector3>(SVector3(1, 0, 0), SVector3(0, 1, 0));
376  }
377 
378  int position = (int)((MTriangle *)e - &_param.t2d[0]);
379 
380  const MTriangle &t3d = _param.t3d[position];
381  const MVertex *v1 = t3d.getVertex(0);
382  const MVertex *v2 = t3d.getVertex(1);
383  const MVertex *v3 = t3d.getVertex(2);
384 
385  double M3D[3][2] = {{v2->x() - v1->x(), v3->x() - v1->x()},
386  {v2->y() - v1->y(), v3->y() - v1->y()},
387  {v2->z() - v1->z(), v3->z() - v1->z()}};
388  v1 = e->getVertex(0);
389  v2 = e->getVertex(1);
390  v3 = e->getVertex(2);
391 
392  double M2D[2][2] = {{(v3->y() - v1->y()), -(v3->x() - v1->x())},
393  {-(v2->y() - v1->y()), (v2->x() - v1->x())}};
394 
395  double det = 1. / (M2D[0][0] * M2D[1][1] - M2D[1][0] * M2D[0][1]);
396 
397  double dxdu[3][2];
398 
399  for(int i = 0; i < 3; i++) {
400  for(int j = 0; j < 2; j++) {
401  dxdu[i][j] = 0.;
402  for(int k = 0; k < 2; k++) { dxdu[i][j] += det * M3D[i][k] * M2D[k][j]; }
403  }
404  }
405 
406  return Pair<SVector3, SVector3>(SVector3(dxdu[0][0], dxdu[1][0], dxdu[2][0]),
407  SVector3(dxdu[0][1], dxdu[1][1], dxdu[2][1]));
408 }
409 
411  SVector3 &dvdv, SVector3 &dudv) const
412 {
413  return;
414 }
415 
417 {
418  char tmp[256];
419  sprintf(tmp, "discrete_param_%d.pos", tag());
420  FILE *fp = fopen(tmp, "w");
421  if(fp) {
422  fprintf(fp, "View \"uv\" {\n");
423  for(std::size_t i = 0; i < stl_triangles.size(); i += 3) {
424  int i0 = stl_triangles[i + 0];
425  int i1 = stl_triangles[i + 1];
426  int i2 = stl_triangles[i + 2];
427  SPoint3 xyz0 = stl_vertices_xyz[i0];
428  SPoint3 xyz1 = stl_vertices_xyz[i1];
429  SPoint3 xyz2 = stl_vertices_xyz[i2];
430  SPoint2 uv0 = stl_vertices_uv[i0];
431  SPoint2 uv1 = stl_vertices_uv[i1];
432  SPoint2 uv2 = stl_vertices_uv[i2];
433  if(uv) {
434  for(int j = 0; j < 2; j++) {
435  xyz0[j] = uv0[j];
436  xyz1[j] = uv1[j];
437  xyz2[j] = uv2[j];
438  }
439  xyz0[2] = xyz1[2] = xyz2[2] = 0;
440  }
441  fprintf(fp, "ST(%g,%g,%g, %g,%g,%g, %g,%g,%g){%g,%g,%g, %g,%g,%g};\n",
442  xyz0.x(), xyz0.y(), xyz0.z(), xyz1.x(), xyz1.y(), xyz1.z(),
443  xyz2.x(), xyz2.y(), xyz2.z(), uv0.x(), uv1.x(), uv2.x(), uv0.y(),
444  uv1.y(), uv2.y());
445  }
446  fprintf(fp, "};\n");
447  fclose(fp);
448  }
449 }
450 
452 {
453 #if defined(HAVE_EIGEN) && defined(HAVE_GEOMETRYCENTRAL)
454 
455  char name[245];
456  sprintf(name, "intrinsic%d.pos", df->tag());
457  FILE *ff = fopen(name, "w");
458  fprintf(ff, "View \"\"{\n");
459 
460  Eigen::MatrixXi triangles(df->triangles.size(), 3);
461  std::vector<geometrycentral::Vector3> vertexCoordinates;
462  for(auto t : df->triangles) {
463  t->getVertex(0)->setIndex(-1);
464  t->getVertex(1)->setIndex(-1);
465  t->getVertex(2)->setIndex(-1);
466  }
467  int index = 0;
468  for(auto t : df->triangles) {
469  for(int i = 0; i < 3; i++) {
470  if(t->getVertex(i)->getIndex() == -1) {
471  geometrycentral::Vector3 p = {
472  t->getVertex(i)->x(), t->getVertex(i)->y(), t->getVertex(i)->z()};
473  vertexCoordinates.push_back(p);
474  t->getVertex(i)->setIndex(index++);
475  }
476  }
477  }
478  Eigen::MatrixXd positions(vertexCoordinates.size(), 3);
479  for(size_t i = 0; i < vertexCoordinates.size(); i++) {
480  positions(i, 0) = vertexCoordinates[i].x;
481  positions(i, 1) = vertexCoordinates[i].y;
482  positions(i, 2) = vertexCoordinates[i].z;
483  }
484 
485  int T = 0;
486  for(auto t : df->triangles) {
487  for(int i = 0; i < 3; i++) triangles(T, i) = t->getVertex(i)->getIndex();
488  T++;
489  }
490  geometrycentral::surface::ManifoldSurfaceMesh msm(triangles);
491 
492  printf("isManifold %d\n", msm.isManifold());
493  printf("isOriented %d\n", msm.isOriented());
494  printf("nVertices %lu\n", msm.nVertices());
495  printf("nCorners %lu\n", msm.nCorners());
496  printf("nInteriorVertices %lu\n", msm.nInteriorVertices());
497 
498  geometrycentral::surface::VertexPositionGeometry vpg(msm, positions);
499 
500  geometrycentral::surface::SignpostIntrinsicTriangulation signpostTri(msm,
501  vpg);
502 
503  signpostTri.flipToDelaunay();
504 
505  signpostTri.delaunayRefine();
506  printf("-->nVertices %lu %lu\n", signpostTri.intrinsicMesh->nVertices(),
507  signpostTri.mesh.nVertices());
508 
509  signpostTri.requireVertexIndices();
510 
511  size_t nV = signpostTri.mesh.nVertices();
512  size_t nF = signpostTri.mesh.nFaces();
513 
514  Eigen::MatrixXd vertexPositions(nV, 3);
515  Eigen::MatrixXi faceInds(nF, 3);
516 
517  size_t iF = 0;
518  for(geometrycentral::surface::Face f : signpostTri.mesh.faces()) {
519  geometrycentral::surface::Halfedge he = f.halfedge();
520  for(int v = 0; v < 3; v++) {
521  geometrycentral::surface::Vertex vA = he.vertex();
522  size_t indA = signpostTri.vertexIndices[vA];
523  faceInds(iF, v) = indA;
524  he = he.next();
525  }
526  iF++;
527  }
528 
529  size_t iV = 0;
530  for(geometrycentral::surface::Vertex v : signpostTri.mesh.vertices()) {
531  geometrycentral::Vector3 pos =
532  signpostTri.vertexLocations[v].interpolate(vpg.inputVertexPositions);
533  vertexPositions(iV, 0) = pos.x;
534  vertexPositions(iV, 1) = pos.y;
535  vertexPositions(iV, 2) = pos.z;
536  iV++;
537  }
538 
539  for(int i = 0; i < nF; i++) {
540  int id0 = faceInds(i, 0);
541  int id1 = faceInds(i, 1);
542  int id2 = faceInds(i, 2);
543  fprintf(ff, "ST(%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg){%d,%d,%d};\n",
544  vertexPositions(id0, 0), vertexPositions(id0, 1),
545  vertexPositions(id0, 2), vertexPositions(id1, 0),
546  vertexPositions(id1, 1), vertexPositions(id1, 2),
547  vertexPositions(id2, 0), vertexPositions(id2, 1),
548  vertexPositions(id2, 2), df->tag(), df->tag(), df->tag());
549  }
550 
551  fprintf(ff, "};\n");
552  fclose(ff);
553 
554 #endif
555 }
556 
558 {
559  stl_vertices_uv.clear();
560  stl_vertices_xyz.clear();
561  stl_curvatures.clear();
562  stl_triangles.clear();
563  if(triangles.empty()) return 0;
564 
565  // intrinsicDelaunayize(this);
566 
567  double minq = 1.;
568  for(auto t : triangles) minq = std::min(minq, t->gammaShapeMeasure());
569  if(minq < 1e-3)
570  Msg::Warning("Poor input mesh quality (min gamma = %g) for computing "
571  "parametrization",
572  minq);
573 
574  std::vector<MVertex *> nodes;
576  stl_triangles);
577 
578  if(model()->getCurvatures().size()) {
579  stl_curvatures.resize(2 * nodes.size());
580  for(std::size_t i = 0; i < nodes.size(); i++) {
581  auto it = model()->getCurvatures().find(nodes[i]);
582  if(it == model()->getCurvatures().end()) {
583  Msg::Error("Curvature not found for node %d", nodes[i]->getNum());
584  }
585  else {
586  stl_curvatures[2 * i] = it->second.first;
587  stl_curvatures[2 * i + 1] = it->second.second;
588  }
589  }
590  }
591 
594 
595  //_debugParametrization(false);
596 
597  return 0;
598 }
599 
601 {
602  stl_normals.clear();
603  std::size_t T = stl_triangles.size() / 3;
604  std::size_t N = stl_vertices_xyz.size();
605  if(!N || !T) return;
606  stl_normals.resize(N);
607  for(std::size_t i = 0; i < T; i++) {
608  int a = stl_triangles[3 * i + 0];
609  int b = stl_triangles[3 * i + 1];
610  int c = stl_triangles[3 * i + 2];
611  SPoint3 pa(stl_vertices_xyz[a]);
612  SPoint3 pb(stl_vertices_xyz[b]);
614  SVector3 vba = pb - pa;
615  SVector3 vca = pc - pa;
616  SVector3 n = crossprod(vba, vca);
617  stl_normals[a] += n;
618  stl_normals[b] += n;
619  stl_normals[c] += n;
620  }
621  for(std::size_t i = 0; i < N; i++) stl_normals[i].normalize();
622 }
623 
625 {
626  if(stl_triangles.empty() || stl_vertices_uv.empty() ||
627  stl_vertices_xyz.empty())
628  return;
629 
630  _param.clear();
631 
632  for(size_t i = 0; i < stl_vertices_uv.size(); i++) {
633  _param.v2d.push_back(
634  MVertex(stl_vertices_uv[i].x(), stl_vertices_uv[i].y(), 0.0));
635  _param.v3d.push_back(MVertex(stl_vertices_xyz[i].x(),
636  stl_vertices_xyz[i].y(),
637  stl_vertices_xyz[i].z()));
638  _param.bbox += _param.v3d.back().point();
639  }
640 
641  for(size_t i = 0; i < stl_triangles.size() / 3; i++) {
642  int a = stl_triangles[3 * i];
643  int b = stl_triangles[3 * i + 1];
644  int c = stl_triangles[3 * i + 2];
645  _param.t2d.push_back(
646  MTriangle(&_param.v2d[a], &_param.v2d[b], &_param.v2d[c]));
647  _param.t3d.push_back(
648  MTriangle(&_param.v3d[a], &_param.v3d[b], &_param.v3d[c]));
649  if(!stl_curvatures.empty()) {
650  _param.CURV.push_back(stl_curvatures[2 * a]);
651  _param.CURV.push_back(stl_curvatures[2 * a + 1]);
652  _param.CURV.push_back(stl_curvatures[2 * b]);
653  _param.CURV.push_back(stl_curvatures[2 * b + 1]);
654  _param.CURV.push_back(stl_curvatures[2 * c]);
655  _param.CURV.push_back(stl_curvatures[2 * c + 1]);
656  }
657  }
658  if(_param.checkPlanar())
659  Msg::Info("Discrete surface %d is planar, simplifying parametrization",
660  tag());
661 
662  std::vector<MElement *> temp;
663  for(size_t j = 0; j < _param.t2d.size(); j++) {
664  temp.push_back(&_param.t2d[j]);
665  double MIN[3] = {_param.t3d[j].getVertex(0)->x(),
666  _param.t3d[j].getVertex(0)->y(),
667  _param.t3d[j].getVertex(0)->z()};
668  double MAX[3] = {_param.t3d[j].getVertex(0)->x(),
669  _param.t3d[j].getVertex(0)->y(),
670  _param.t3d[j].getVertex(0)->z()};
671  for(int k = 1; k < 3; k++) {
672  MAX[0] = std::max(MAX[0], _param.t3d[j].getVertex(k)->x());
673  MIN[0] = std::min(MIN[0], _param.t3d[j].getVertex(k)->x());
674  MAX[1] = std::max(MAX[1], _param.t3d[j].getVertex(k)->y());
675  MIN[1] = std::min(MIN[1], _param.t3d[j].getVertex(k)->y());
676  MAX[2] = std::max(MAX[2], _param.t3d[j].getVertex(k)->z());
677  MIN[2] = std::min(MIN[2], _param.t3d[j].getVertex(k)->z());
678  }
679  _param.rtree3dData.push_back
680  (new std::pair<MTriangle *, MTriangle *>(&_param.t3d[j], &_param.t2d[j]));
682  }
683  _param.oct = new MElementOctree(temp);
684 }
685 
686 void discreteFace::mesh(bool verbose)
687 {
688  if(_param.empty()) return;
689  GFace::mesh(verbose);
690 }
691 
693  const SVector3 &n2,
694  const SVector3 &p, const double &R,
695  double uv[2])
696 {
697  if(_param.empty()) return 0.;
698 
699  MTriangle *t2d = (MTriangle *)_param.oct->find(uv[0], uv[1], 0.0, -1, true);
700  MTriangle *t3d = nullptr;
701  if(t2d) {
702  int position = (int)(t2d - &_param.t2d[0]);
703  t3d = &_param.t3d[position];
704  }
705 
706  SVector3 n = crossprod(n1, n2);
707  n.normalize();
708 
709  int N = _param.t3d.size();
710  int start = 0;
711  if(t2d) start = -1;
712  for(int i = start; i < N; i++) {
713  if(i >= 0) {
714  t2d = &_param.t2d[i];
715  t3d = &_param.t3d[i];
716  }
717  SVector3 v0(t3d->getVertex(0)->x(), t3d->getVertex(0)->y(),
718  t3d->getVertex(0)->z());
719  SVector3 v1(t3d->getVertex(1)->x(), t3d->getVertex(1)->y(),
720  t3d->getVertex(1)->z());
721  SVector3 v2(t3d->getVertex(2)->x(), t3d->getVertex(2)->y(),
722  t3d->getVertex(2)->z());
723  SVector3 v0_2d(t2d->getVertex(0)->x(), t2d->getVertex(0)->y(),
724  t2d->getVertex(0)->z());
725  SVector3 v1_2d(t2d->getVertex(1)->x(), t2d->getVertex(1)->y(),
726  t2d->getVertex(1)->z());
727  SVector3 v2_2d(t2d->getVertex(2)->x(), t2d->getVertex(2)->y(),
728  t2d->getVertex(2)->z());
729  SVector3 t1 = v1 - v0;
730  SVector3 t2 = v2 - v0;
731  SVector3 t = crossprod(t1, t2);
732  t.normalize();
733  SVector3 d = crossprod(n, t);
734  if(d.norm() < 1.e-12) continue;
735  d.normalize();
736  double rhs[2] = {dot(n, p), dot(v0, t)};
737  double r[2];
738  double m[2][2];
739  SVector3 x0(0, 0, 0);
740  m[0][0] = n.y();
741  m[0][1] = n.z();
742  m[1][0] = t.y();
743  m[1][1] = t.z();
744  if(fabs(det2x2(m)) > 1.e-12) {
745  sys2x2(m, rhs, r);
746  x0 = SVector3(0, r[0], r[1]);
747  }
748  else {
749  m[0][0] = n.x();
750  m[0][1] = n.z();
751  m[1][0] = t.x();
752  m[1][1] = t.z();
753  if(fabs(det2x2(m)) > 1.e-12) {
754  sys2x2(m, rhs, r);
755  x0 = SVector3(r[0], 0, r[1]);
756  }
757  else {
758  m[0][0] = n.x();
759  m[0][1] = n.y();
760  m[1][0] = t.x();
761  m[1][1] = t.y();
762  if(sys2x2(m, rhs, r)) { x0 = SVector3(r[0], r[1], 0); }
763  else {
764  // printf("mauvaise pioche\n");
765  continue;
766  }
767  }
768  }
769 
770  const double a = 1.0;
771  const double b = -2 * dot(d, p - x0);
772  const double c = dot(p - x0, p - x0) - R * R;
773  const double delta = b * b - 4 * a * c;
774  if(delta >= 0) {
775  double sign = (dot(n2, d) > 0) ? 1.0 : -1.0;
776  const double ta = (-b + sign * sqrt(delta)) / (2. * a);
777  const double tb = (-b - sign * sqrt(delta)) / (2. * a);
778  SVector3 s[2] = {x0 + d * ta, x0 + d * tb};
779  for(int IT = 0; IT < 2; IT++) {
780  double mat[2][2], b[2], uv[2];
781  mat[0][0] = dot(t1, t1);
782  mat[1][1] = dot(t2, t2);
783  mat[0][1] = mat[1][0] = dot(t1, t2);
784  b[0] = dot(s[IT] - v0, t1);
785  b[1] = dot(s[IT] - v0, t2);
786  sys2x2(mat, b, uv);
787  // check now if the point is inside the triangle
788  if(uv[0] >= -1.e-6 && uv[1] >= -1.e-6 && 1. - uv[0] - uv[1] >= -1.e-6) {
789  SVector3 pp =
790  v0_2d * (1. - uv[0] - uv[1]) + v1_2d * uv[0] + v2_2d * uv[1];
791  uv[0] = pp.x();
792  uv[1] = pp.y();
793  return GPoint(s[IT].x(), s[IT].y(), s[IT].z(), this, uv);
794  }
795  }
796  }
797  }
798 
799  GPoint pp(0);
800  pp.setNoSuccess();
801  // Msg::Warning("Could not intersect with circle");
802  return pp;
803 }
804 
805 bool discreteFace::writeParametrization(FILE *fp, bool binary)
806 {
807  std::size_t N = stl_vertices_uv.size();
808  std::size_t T = stl_triangles.size() / 3;
809  std::vector<double> d(11 * N, 0.);
810  for(std::size_t i = 0; i < N; i++) {
811  d[11 * i + 0] = stl_vertices_xyz[i].x();
812  d[11 * i + 1] = stl_vertices_xyz[i].y();
813  d[11 * i + 2] = stl_vertices_xyz[i].z();
814  d[11 * i + 3] = stl_vertices_uv[i].x();
815  d[11 * i + 4] = stl_vertices_uv[i].y();
816  if(stl_curvatures.size() == 2 * stl_vertices_uv.size()) {
817  d[11 * i + 5] = stl_curvatures[2 * i].x();
818  d[11 * i + 6] = stl_curvatures[2 * i].y();
819  d[11 * i + 7] = stl_curvatures[2 * i].z();
820  d[11 * i + 8] = stl_curvatures[2 * i + 1].x();
821  d[11 * i + 9] = stl_curvatures[2 * i + 1].y();
822  d[11 * i + 10] = stl_curvatures[2 * i + 1].z();
823  }
824  }
825  if(binary) {
826  fwrite(&N, sizeof(std::size_t), 1, fp);
827  fwrite(&T, sizeof(std::size_t), 1, fp);
828  fwrite(&d[0], sizeof(double), d.size(), fp);
829  fwrite(&stl_triangles[0], sizeof(int), stl_triangles.size(), fp);
830  }
831  else {
832  fprintf(fp, "%lu %lu\n", N, T);
833  for(std::size_t i = 0; i < N; i++)
834  fprintf(fp,
835  "%.16g %.16g %.16g %.16g %.16g %.16g %.16g "
836  "%.16g %.16g %.16g %.16g\n",
837  d[11 * i + 0], d[11 * i + 1], d[11 * i + 2], d[11 * i + 3],
838  d[11 * i + 4], d[11 * i + 5], d[11 * i + 6], d[11 * i + 7],
839  d[11 * i + 8], d[11 * i + 9], d[11 * i + 10]);
840  for(std::size_t i = 0; i < T; i++) {
841  fprintf(fp, "%d %d %d\n", stl_triangles[3 * i + 0],
842  stl_triangles[3 * i + 1], stl_triangles[3 * i + 2]);
843  }
844  }
845  return true;
846 }
847 
848 bool discreteFace::readParametrization(FILE *fp, bool binary)
849 {
850  stl_vertices_xyz.clear();
851  stl_vertices_uv.clear();
852  stl_curvatures.clear();
853  stl_triangles.clear();
854 
855  std::size_t N, T;
856  if(binary) {
857  if(fread(&N, sizeof(std::size_t), 1, fp) != 1) { return false; }
858  if(fread(&T, sizeof(std::size_t), 1, fp) != 1) { return false; }
859  }
860  else {
861  if(fscanf(fp, "%lu %lu", &N, &T) != 2) { return false; }
862  }
863  std::vector<double> d(11 * N);
864  stl_vertices_xyz.resize(N);
865  stl_vertices_uv.resize(N);
866  stl_curvatures.resize(2 * N);
867  stl_triangles.resize(3 * T);
868 
869  if(binary) {
870  if(fread(&d[0], sizeof(double), 11 * N, fp) != 11 * N) { return false; }
871  if(fread(&stl_triangles[0], sizeof(int), 3 * T, fp) != 3 * T) {
872  return false;
873  }
874  }
875  else {
876  for(std::size_t i = 0; i < N; i++) {
877  if(fscanf(fp, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
878  &d[11 * i + 0], &d[11 * i + 1], &d[11 * i + 2], &d[11 * i + 3],
879  &d[11 * i + 4], &d[11 * i + 5], &d[11 * i + 6], &d[11 * i + 7],
880  &d[11 * i + 8], &d[11 * i + 9], &d[11 * i + 10]) != 11) {
881  return false;
882  }
883  }
884  for(std::size_t i = 0; i < T; i++) {
885  if(fscanf(fp, "%d %d %d", &stl_triangles[3 * i + 0],
886  &stl_triangles[3 * i + 1], &stl_triangles[3 * i + 2]) != 3) {
887  return false;
888  }
889  }
890  }
891 
892  for(std::size_t i = 0; i < N; i++) {
893  stl_vertices_xyz[i] = SPoint3(d[11 * i + 0], d[11 * i + 1], d[11 * i + 2]);
894  stl_vertices_uv[i] = SPoint2(d[11 * i + 3], d[11 * i + 4]);
895  stl_curvatures[2 * i + 0] =
896  SVector3(d[11 * i + 5], d[11 * i + 6], d[11 * i + 7]);
897  stl_curvatures[2 * i + 1] =
898  SVector3(d[11 * i + 8], d[11 * i + 9], d[11 * i + 10]);
899  }
900 
903  return true;
904 }
905 
907 {
908  Surface *_s = FindSurface(tag());
909  if(!_s) {
911  return;
912  }
913  meshAttributes.recombine = _s->Recombine;
914  meshAttributes.recombineAngle = _s->RecombineAngle;
915  meshAttributes.method = _s->Method;
916  meshAttributes.extrude = _s->Extrude;
917  if(meshAttributes.method == MESH_TRANSFINITE) {
918  meshAttributes.transfiniteArrangement = _s->Recombine_Dir;
919  meshAttributes.transfiniteSmoothing = _s->TransfiniteSmoothing;
920  meshAttributes.corners.clear();
921  for(int i = 0; i < List_Nbr(_s->TrsfPoints); i++) {
922  Vertex *corn;
923  List_Read(_s->TrsfPoints, i, &corn);
924  GVertex *gv = model()->getVertexByTag(corn->Num);
925  if(gv)
926  meshAttributes.corners.push_back(gv);
927  else
928  Msg::Error("Unknown point %d in transfinite attributes", corn->Num);
929  }
930  }
931  meshAttributes.reverseMesh = _s->ReverseMesh;
932  meshAttributes.algorithm = _s->MeshAlgorithm;
933  meshAttributes.meshSizeFromBoundary = _s->MeshSizeFromBoundary;
934  meshAttributes.transfinite3 = false;
935 }
discreteFace::trianglePosition
int trianglePosition(double par1, double par2, double &u, double &v) const
Definition: discreteFace.cpp:112
crossprod
SVector3 crossprod(const SVector3 &a, const SVector3 &b)
Definition: SVector3.h:150
Surface::TrsfPoints
List_T * TrsfPoints
Definition: Geo.h:122
MElement::xyz2uvw
virtual void xyz2uvw(double xyz[3], double uvw[3]) const
Definition: MElement.cpp:1128
Geo.h
computeParametrization
bool computeParametrization(const std::vector< MTriangle * > &triangles, std::vector< MVertex * > &nodes, std::vector< SPoint2 > &stl_vertices_uv, std::vector< SPoint3 > &stl_vertices_xyz, std::vector< int > &stl_triangles)
Definition: GModelParametrize.cpp:495
SBoundingBox3d::diag
double diag() const
Definition: SBoundingBox3d.h:93
mean_plane::d
double d
Definition: Numeric.h:35
dot
double dot(const SVector3 &a, const SMetric3 &m, const SVector3 &b)
Definition: STensor3.h:71
discreteFace::secondDer
virtual void secondDer(const SPoint2 &param, SVector3 &dudu, SVector3 &dvdv, SVector3 &dudv) const
Definition: discreteFace.cpp:410
discreteFace::curvatures
double curvatures(const SPoint2 &param, SVector3 &dirMax, SVector3 &dirMin, double &curvMax, double &curvMin) const
Definition: discreteFace.cpp:333
GModel::getCurvatures
std::map< MVertex *, std::pair< SVector3, SVector3 > > & getCurvatures()
Definition: GModel.h:719
mean_plane::c
double c
Definition: Numeric.h:35
dfWrapper::_closestPoint
SPoint3 _closestPoint
Definition: discreteFace.cpp:177
mean_plane::x
double x
Definition: Numeric.h:36
dfWrapper
Definition: discreteFace.cpp:173
MTriangle::xyz2uvw
virtual void xyz2uvw(double xyz[3], double uvw[3]) const
Definition: MTriangle.cpp:124
GFace
Definition: GFace.h:33
GFace::triangles
std::vector< MTriangle * > triangles
Definition: GFace.h:428
Msg::Info
static void Info(const char *fmt,...)
Definition: GmshMessage.cpp:587
GEntity::model
GModel * model() const
Definition: GEntity.h:277
F
#define F
Definition: DefaultOptions.h:23
SPoint2
Definition: SPoint2.h:12
discreteFace::discreteFace
discreteFace(GModel *model, int num)
Definition: discreteFace.cpp:99
MAX
#define MAX(a, b)
Definition: libol1.c:81
c
static double c(int i, int j, fullMatrix< double > &CA, const std::vector< SPoint3 > &P, const std::vector< SPoint3 > &Q)
Definition: discreteFrechetDistance.cpp:15
MESH_TRANSFINITE
#define MESH_TRANSFINITE
Definition: GmshDefines.h:259
delta
int delta(int i, int j)
Definition: terms.h:32
Octree.h
discreteFace::param::rtree3dData
std::vector< std::pair< MTriangle *, MTriangle * > * > rtree3dData
Definition: discreteFace.h:24
MVertex
Definition: MVertex.h:24
MElementOctree.h
Msg::Warning
static void Warning(const char *fmt,...)
Definition: GmshMessage.cpp:543
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
discreteFace::param::CURV
std::vector< SVector3 > CURV
Definition: discreteFace.h:29
discreteFace::_param
param _param
Definition: discreteFace.h:38
MVertex::z
double z() const
Definition: MVertex.h:62
SPoint3
Definition: SPoint3.h:14
LegendrePolynomials::f
void f(int n, double u, double *val)
Definition: orthogonalBasis.cpp:77
intrinsicDelaunayize
void intrinsicDelaunayize(discreteFace *df)
Definition: discreteFace.cpp:451
List_Nbr
int List_Nbr(List_T *liste)
Definition: ListUtils.cpp:106
Vertex
Definition: Geo.h:29
discreteFace::param::clear
void clear()
Definition: discreteFace.cpp:34
GModelParametrize.h
GFace::meshAttributes
struct GFace::@18 meshAttributes
discreteFace::param::umax
double umax
Definition: discreteFace.h:30
SVector3
Definition: SVector3.h:16
discreteFace::createGeometry
int createGeometry()
Definition: discreteFace.cpp:557
discreteFace::curvatureMax
double curvatureMax(const SPoint2 &param) const
Definition: discreteFace.cpp:322
GEdgeLoop.h
GModelIO_GEO.h
Surface::MeshSizeFromBoundary
int MeshSizeFromBoundary
Definition: Geo.h:130
MTriangle::getVertex
virtual MVertex * getVertex(int num)
Definition: MTriangle.h:62
MPoint.h
discreteFace::containsParam
bool containsParam(const SPoint2 &pt)
Definition: discreteFace.cpp:286
mean_plane::b
double b
Definition: Numeric.h:35
GmshMessage.h
mean_plane
Definition: Numeric.h:33
GPoint
Definition: GPoint.h:13
discreteFace::mesh
virtual void mesh(bool verbose)
Definition: discreteFace.cpp:686
discreteFace::closestPoint
GPoint closestPoint(const SPoint3 &queryPoint, double maxDistance, SVector3 *normal=nullptr) const
Definition: discreteFace.cpp:210
discreteFace::param::oct
MElementOctree * oct
Definition: discreteFace.h:22
discreteFace::_debugParametrization
void _debugParametrization(bool uv)
Definition: discreteFace.cpp:416
discreteFace::resetMeshAttributes
virtual void resetMeshAttributes()
Definition: discreteFace.cpp:906
CreateSurface
Surface * CreateSurface(int Num, int Typ)
Definition: Geo.cpp:579
Vertex::Num
int Num
Definition: Geo.h:31
GFace::stl_curvatures
std::vector< SVector3 > stl_curvatures
Definition: GFace.h:411
CTX::instance
static CTX * instance()
Definition: Context.cpp:122
MElement::getVertex
virtual const MVertex * getVertex(int num) const =0
GFace::stl_vertices_xyz
std::vector< SPoint3 > stl_vertices_xyz
Definition: GFace.h:409
SPoint3::x
double x(void) const
Definition: SPoint3.h:125
Range
Definition: Range.h:10
GFace::meshStatistics
struct GFace::@19 meshStatistics
discreteFace::param::~param
~param()
Definition: discreteFace.cpp:29
GPoint::u
double u() const
Definition: GPoint.h:27
det2x2
double det2x2(double mat[2][2])
Definition: Numeric.cpp:199
Surface::Extrude
ExtrudeParams * Extrude
Definition: Geo.h:124
signedDistancePointTriangle
void signedDistancePointTriangle(const SPoint3 &p1, const SPoint3 &p2, const SPoint3 &p3, const SPoint3 &p, double &d, SPoint3 &closePt)
Definition: Numeric.cpp:758
discreteFace::writeParametrization
bool writeParametrization(FILE *fp, bool binary)
Definition: discreteFace.cpp:805
GEO_Internals::Surfaces
Tree_T * Surfaces
Definition: GModelIO_GEO.h:18
GVertex
Definition: GVertex.h:23
discreteFace::param::checkPlanar
bool checkPlanar()
Definition: discreteFace.cpp:48
discreteFace::param::v2d
std::vector< MVertex > v2d
Definition: discreteFace.h:25
discreteFace::param::v3d
std::vector< MVertex > v3d
Definition: discreteFace.h:26
Tree_Add
void * Tree_Add(Tree_T *tree, void *data)
Definition: TreeUtils.cpp:37
discreteFace::point
GPoint point(double par1, double par2) const
Definition: discreteFace.cpp:148
GModel
Definition: GModel.h:44
GEntity::DONE
@ DONE
Definition: GEntity.h:130
discreteFace::intersectionWithCircle
GPoint intersectionWithCircle(const SVector3 &n1, const SVector3 &n2, const SVector3 &p, const double &R, double uv[2])
Definition: discreteFace.cpp:692
GFace::stl_normals
std::vector< SVector3 > stl_normals
Definition: GFace.h:410
discreteFace_rtree_callback
bool discreteFace_rtree_callback(std::pair< MTriangle *, MTriangle * > *t, void *w)
Definition: discreteFace.cpp:185
Surface
Definition: Geo.h:111
MSH_SURF_DISCRETE
#define MSH_SURF_DISCRETE
Definition: GeoDefines.h:38
MElementOctree
Definition: MElementOctree.h:15
mean_plane::a
double a
Definition: Numeric.h:35
mean_plane::z
double z
Definition: Numeric.h:36
dfWrapper::_t3d
MTriangle * _t3d
Definition: discreteFace.cpp:178
dfWrapper::_distance
double _distance
Definition: discreteFace.cpp:176
SVector3::norm
double norm() const
Definition: SVector3.h:33
SPoint3::y
double y(void) const
Definition: SPoint3.h:127
discreteFace::param::t2d
std::vector< MTriangle > t2d
Definition: discreteFace.h:27
dfWrapper::_t2d
MTriangle * _t2d
Definition: discreteFace.cpp:178
discreteFace::param::umin
double umin
Definition: discreteFace.h:30
discreteFace::parFromPoint
SPoint2 parFromPoint(const SPoint3 &p, bool onSurface=true, bool convTestXYZ=false) const
Definition: discreteFace.cpp:271
GFace::resetMeshAttributes
virtual void resetMeshAttributes()
Definition: GFace.cpp:257
MElement
Definition: MElement.h:30
GFace::mesh
virtual void mesh(bool verbose)
Definition: GFace.cpp:2142
GFace::stl_triangles
std::vector< int > stl_triangles
Definition: GFace.h:412
GFace::bounds
virtual SBoundingBox3d bounds(bool fast=false)
Definition: GFace.cpp:273
GEntity::tag
int tag() const
Definition: GEntity.h:280
discreteFace.h
discreteFace::param::empty
bool empty() const
Definition: discreteFace.h:34
SVector3::x
double x(void) const
Definition: SVector3.h:30
dfWrapper::_p
SPoint3 _p
Definition: discreteFace.cpp:175
RTree::Insert
void Insert(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], const DATATYPE &a_dataId)
MElementOctree::find
MElement * find(double x, double y, double z, int dim=-1, bool strict=false) const
Definition: MElementOctree.cpp:205
MTriangle
Definition: MTriangle.h:26
LegendrePolynomials::df
void df(int n, double u, double *val)
Definition: orthogonalBasis.cpp:103
Surface::MeshAlgorithm
int MeshAlgorithm
Definition: Geo.h:130
mean_plane::y
double y
Definition: Numeric.h:36
discreteFace::parBounds
Range< double > parBounds(int i) const
Definition: discreteFace.cpp:278
discreteFace::param::t3d
std::vector< MTriangle > t3d
Definition: discreteFace.h:28
Surface::TransfiniteSmoothing
int TransfiniteSmoothing
Definition: Geo.h:119
discreteFace::_createGeometryFromSTL
void _createGeometryFromSTL()
Definition: discreteFace.cpp:624
GPoint::setNoSuccess
bool setNoSuccess()
Definition: GPoint.h:64
MEdge.h
SPoint2::x
double x(void) const
Definition: SPoint2.h:86
projectPointsToPlane
void projectPointsToPlane(const std::vector< SPoint3 > &pts, std::vector< SPoint3 > &ptsProj, const mean_plane &meanPlane)
Definition: Numeric.cpp:1514
discreteEdge.h
Surface::RecombineAngle
double RecombineAngle
Definition: Geo.h:118
Surface::Recombine
int Recombine
Definition: Geo.h:116
Context.h
sys2x2
int sys2x2(double mat[2][2], double b[2], double res[2])
Definition: Numeric.cpp:101
mean_plane::plan
double plan[3][3]
Definition: Numeric.h:34
RTree::Search
int Search(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], bool a_resultCallback(DATATYPE a_data, void *a_context), void *a_context)
SVector3::y
double y(void) const
Definition: SVector3.h:31
z
const double z
Definition: GaussQuadratureQuad.cpp:56
discreteFace::readParametrization
bool readParametrization(FILE *fp, bool binary)
Definition: discreteFace.cpp:848
discreteFace::param::vmin
double vmin
Definition: discreteFace.h:30
Pair
Definition: Pair.h:10
SVector3::z
double z(void) const
Definition: SVector3.h:32
MYxyz2uvw
static void MYxyz2uvw(const MElement *t, double xyz[3], double uvw[3])
Definition: discreteFace.cpp:128
GFace::stl_vertices_uv
std::vector< SPoint2 > stl_vertices_uv
Definition: GFace.h:408
discreteFace::normal
SVector3 normal(const SPoint2 &param) const
Definition: discreteFace.cpp:299
SPoint3::z
double z(void) const
Definition: SPoint3.h:129
normalize
void normalize(Quaternion &q)
Definition: Camera.cpp:370
discreteFace::param::vmax
double vmax
Definition: discreteFace.h:30
GPoint::v
double v() const
Definition: GPoint.h:28
MIN
#define MIN(a, b)
Definition: libol1.c:80
MVertex::y
double y() const
Definition: MVertex.h:61
Surface::Recombine_Dir
int Recombine_Dir
Definition: Geo.h:117
Surface::ReverseMesh
int ReverseMesh
Definition: Geo.h:130
GModel::getVertexByTag
GVertex * getVertexByTag(int n) const
Definition: GModel.cpp:346
GModel::getGEOInternals
GEO_Internals * getGEOInternals()
Definition: GModel.h:315
discreteFace::param::bbox
SBoundingBox3d bbox
Definition: discreteFace.h:31
discreteFace::bounds
SBoundingBox3d bounds(bool fast=false)
Definition: discreteFace.cpp:293
SBoundingBox3d
Definition: SBoundingBox3d.h:21
List_Read
void List_Read(List_T *liste, int index, void *data)
Definition: ListUtils.cpp:111
discreteFace::param::rtree3d
RTree< std::pair< MTriangle *, MTriangle * > *, double, 3 > rtree3d
Definition: discreteFace.h:23
FindSurface
static Surface * FindSurface(int inum, Tree_T *t)
Definition: Geo.cpp:708
discreteFace::firstDer
virtual Pair< SVector3, SVector3 > firstDer(const SPoint2 &param) const
Definition: discreteFace.cpp:366
computeMeanPlaneSimple
void computeMeanPlaneSimple(const std::vector< SPoint3 > &points, mean_plane &meanPlane)
Definition: Numeric.cpp:1438
discreteFace::param
Definition: discreteFace.h:20
discreteFace::_computeSTLNormals
void _computeSTLNormals()
Definition: discreteFace.cpp:600
MVertex::x
double x() const
Definition: MVertex.h:60
SVector3::normalize
double normalize()
Definition: SVector3.h:38
Surface::Method
int Method
Definition: Geo.h:115
discreteFace
Definition: discreteFace.h:18
SPoint2::y
double y(void) const
Definition: SPoint2.h:88
dfWrapper::dfWrapper
dfWrapper(const SPoint3 &p)
Definition: discreteFace.cpp:179