22 #if defined(HAVE_EIGEN) && defined(HAVE_GEOMETRYCENTRAL)
24 #include <Eigen/Dense>
25 #include "geometrycentral/surface/signpost_intrinsic_triangulation.h"
26 #include "geometrycentral/surface/vertex_position_geometry.h"
38 for(
auto p : rtree3dData)
delete p;
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());
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;
84 for(
size_t i = 0; i < t2d.size(); i++) {
85 for(
int j = 0; j < 3; j++) {
87 MVertex *v = t2d[i].getVertex(j);
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());
117 double xy[3] = {par1, par2, 0};
130 double M[2][2], R[2];
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];
152 double xy[3] = {par1, par2, 0};
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++) {
170 return GPoint(X, Y, Z,
this, xy);
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);
203 wrapper->
_t3d = t->first;
204 wrapper->
_t2d = t->second;
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};
228 }
while(!wrapper.
_t3d);
253 double U = 1 - uvw[0] - 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());
262 return GPoint(pp3.
x(), pp3.
y(), pp3.
z(),
this, pp);
266 const double initialGuess[2])
const
272 bool convTestXYZ)
const
305 Msg::Info(
"Triangle not found at uv=(%g,%g) on discrete surface %d",
330 return std::max(
c, C);
335 double &curvMin)
const
342 Msg::Info(
"Triangle not found for curvatures at uv=(%g,%g) on "
343 "discrete surface %d",
357 curvMax = c0max.
norm();
358 curvMin = c0min.
norm();
372 Msg::Info(
"Triangle not found for first derivative at uv=(%g,%g) on "
373 "discrete surface %d",
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()}};
392 double M2D[2][2] = {{(v3->
y() - v1->
y()), -(v3->
x() - v1->
x())},
393 {-(v2->
y() - v1->
y()), (v2->
x() - v1->
x())}};
395 double det = 1. / (M2D[0][0] * M2D[1][1] - M2D[1][0] * M2D[0][1]);
399 for(
int i = 0; i < 3; i++) {
400 for(
int j = 0; j < 2; j++) {
402 for(
int k = 0; k < 2; k++) { dxdu[i][j] += det * M3D[i][k] * M2D[k][j]; }
407 SVector3(dxdu[0][1], dxdu[1][1], dxdu[2][1]));
419 sprintf(tmp,
"discrete_param_%d.pos",
tag());
420 FILE *fp = fopen(tmp,
"w");
422 fprintf(fp,
"View \"uv\" {\n");
434 for(
int j = 0; j < 2; j++) {
439 xyz0[2] = xyz1[2] = xyz2[2] = 0;
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(),
453 #if defined(HAVE_EIGEN) && defined(HAVE_GEOMETRYCENTRAL)
456 sprintf(name,
"intrinsic%d.pos",
df->tag());
457 FILE *ff = fopen(name,
"w");
458 fprintf(ff,
"View \"\"{\n");
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);
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++);
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;
486 for(
auto t :
df->triangles) {
487 for(
int i = 0; i < 3; i++) triangles(T, i) = t->getVertex(i)->getIndex();
490 geometrycentral::surface::ManifoldSurfaceMesh msm(triangles);
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());
498 geometrycentral::surface::VertexPositionGeometry vpg(msm, positions);
500 geometrycentral::surface::SignpostIntrinsicTriangulation signpostTri(msm,
503 signpostTri.flipToDelaunay();
505 signpostTri.delaunayRefine();
506 printf(
"-->nVertices %lu %lu\n", signpostTri.intrinsicMesh->nVertices(),
507 signpostTri.mesh.nVertices());
509 signpostTri.requireVertexIndices();
511 size_t nV = signpostTri.mesh.nVertices();
512 size_t nF = signpostTri.mesh.nFaces();
514 Eigen::MatrixXd vertexPositions(nV, 3);
515 Eigen::MatrixXi faceInds(nF, 3);
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;
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;
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());
568 for(
auto t :
triangles) minq = std::min(minq, t->gammaShapeMeasure());
570 Msg::Warning(
"Poor input mesh quality (min gamma = %g) for computing "
574 std::vector<MVertex *> nodes;
578 if(
model()->getCurvatures().size()) {
580 for(std::size_t i = 0; i < nodes.size(); i++) {
582 if(it ==
model()->getCurvatures().end()) {
583 Msg::Error(
"Curvature not found for node %d", nodes[i]->getNum());
607 for(std::size_t i = 0; i < T; i++) {
659 Msg::Info(
"Discrete surface %d is planar, simplifying parametrization",
662 std::vector<MElement *> temp;
663 for(
size_t j = 0; j <
_param.
t2d.size(); j++) {
671 for(
int k = 1; k < 3; k++) {
702 int position = (int)(t2d - &
_param.
t2d[0]);
712 for(
int i = start; i < N; i++) {
734 if(d.
norm() < 1.e-12)
continue;
736 double rhs[2] = {
dot(n, p),
dot(v0, t)};
744 if(fabs(
det2x2(m)) > 1.e-12) {
753 if(fabs(
det2x2(m)) > 1.e-12) {
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;
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);
788 if(uv[0] >= -1.e-6 && uv[1] >= -1.e-6 && 1. - uv[0] - uv[1] >= -1.e-6) {
790 v0_2d * (1. - uv[0] - uv[1]) + v1_2d * uv[0] + v2_2d * uv[1];
793 return GPoint(s[IT].x(), s[IT].y(), s[IT].
z(),
this, uv);
809 std::vector<double> d(11 * N, 0.);
810 for(std::size_t i = 0; i < N; i++) {
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);
832 fprintf(fp,
"%lu %lu\n", N, T);
833 for(std::size_t i = 0; i < N; i++)
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++) {
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; }
861 if(fscanf(fp,
"%lu %lu", &N, &T) != 2) {
return false; }
863 std::vector<double> d(11 * N);
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) {
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) {
884 for(std::size_t i = 0; i < T; i++) {
892 for(std::size_t i = 0; i < N; i++) {
896 SVector3(d[11 * i + 5], d[11 * i + 6], d[11 * i + 7]);
898 SVector3(d[11 * i + 8], d[11 * i + 9], d[11 * i + 10]);
928 Msg::Error(
"Unknown point %d in transfinite attributes", corn->
Num);