27 using vec2 = std::array<double, 2>;
28 using vec3 = std::array<double, 3>;
31 return {{a[0] - b[0], a[1] - b[1], a[2] - b[2]}};
35 return {{a[0] + b[0], a[1] + b[1], a[2] + b[2]}};
39 return {{a * b[0], a * b[1], a * b[2]}};
43 return {{a[0] * b, a[1] * b, a[2] * b}};
47 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
50 inline double maxAbs(
double x,
double y,
double z)
52 return std::max(std::abs(x), std::max(std::abs(y), std::abs(
z)));
57 a = 1. / std::sqrt(
length2(a)) * a;
62 if(amp == 0.) {
return; }
72 double t =
dot(query - a, b - a);
73 if(t <= 0. || l2 == 0.) {
84 proj = lambda * a + (1. - lambda) * b;
92 vec3 &proj,
double lambda[3])
94 vec3 diff = p1 - query;
98 double a01 =
dot(edge0, edge1);
100 double b0 =
dot(diff, edge0);
101 double b1 =
dot(diff, edge1);
103 double det = ::fabs(a00 * a11 - a01 * a01);
104 double s = a01 *
b1 - a11 * b0;
105 double t = a01 * b0 - a00 *
b1;
118 lambda[1] = 1. - cur_l1;
121 if(cur_dist < result) {
125 lambda[2] = 1. - cur_l1;
129 if(cur_dist < result) {
133 lambda[2] = 1. - cur_l1;
146 sqrDistance = a00 + 2.0 * b0 +
c;
150 sqrDistance = b0 * s +
c;
159 else if(-
b1 >= a11) {
161 sqrDistance = a11 + 2.0 *
b1 +
c;
165 sqrDistance =
b1 * t +
c;
175 else if(-
b1 >= a11) {
177 sqrDistance = a11 + 2.0 *
b1 +
c;
181 sqrDistance =
b1 * t +
c;
191 else if(-b0 >= a00) {
193 sqrDistance = a00 + 2.0 * b0 +
c;
197 sqrDistance = b0 * s +
c;
202 double invDet = double(1.0) / det;
205 sqrDistance = s * (a00 * s + a01 * t + 2.0 * b0) +
206 t * (a01 * s + a11 * t + 2.0 *
b1) +
c;
210 double tmp0, tmp1, numer, denom;
217 denom = a00 - 2.0 * a01 + a11;
221 sqrDistance = a00 + 2.0 * b0 +
c;
226 sqrDistance = s * (a00 * s + a01 * t + 2.0 * b0) +
227 t * (a01 * s + a11 * t + 2.0 *
b1) +
c;
234 sqrDistance = a11 + 2.0 *
b1 +
c;
242 sqrDistance =
b1 * t +
c;
251 denom = a00 - 2.0 * a01 + a11;
255 sqrDistance = a11 + 2.0 *
b1 +
c;
260 sqrDistance = s * (a00 * s + a01 * t + 2.0 * b0) +
261 t * (a01 * s + a11 * t + 2.0 *
b1) +
c;
268 sqrDistance = a00 + 2.0 * b0 +
c;
276 sqrDistance = b0 * s +
c;
281 numer = a11 +
b1 - a01 - b0;
285 sqrDistance = a11 + 2.0 *
b1 +
c;
288 denom = a00 - 2.0 * a01 + a11;
292 sqrDistance = a00 + 2.0 * b0 +
c;
297 sqrDistance = s * (a00 * s + a01 * t + 2.0 * b0) +
298 t * (a01 * s + a11 * t + 2.0 *
b1) +
c;
305 if(sqrDistance < 0.0) { sqrDistance = 0.0; }
307 proj = p1 + s * edge0 + t * edge1;
308 lambda[0] = 1.0 - s - t;
321 Msg::Error(
"SurfaceProjector: quads not implemented yet, should create "
322 "fake MTriangle* just for initialize()");
326 if(!ok) {
Msg::Error(
"failed to initialize SurfaceProjector"); }
345 if(
gf->
geomType() == GFace::GeomType::Sphere) {
360 "Surface projector: analytical formula for given shape not supported");
365 const std::vector<MTriangle *> &gfTriangles,
371 const int BasIdx = 1;
376 for (
size_t i = 0; i < this->
points.size(); ++i) {
384 for (
size_t i = 0; i < this->
triangles.size(); ++i) {
391 for (
size_t i = 0; i < this->
triangle_uvs.size(); ++i) {
404 Msg::Warning(
"SurfaceProjector initialize: failed to build STL triangulation");
409 bool disableParamPer =
false;
411 disableParamPer =
true;
418 points.reserve(gfTriangles.size());
424 std::array<int32_t, 3> tri_pts;
425 std::array<vec2, 3> tri_uvs;
426 bool check_periodicity =
false;
427 bool no_eval =
false;
428 for(
size_t lv = 0; lv <
f->getNumVertices(); ++lv) {
430 auto it = old2new.
find(v);
431 if(it == old2new.
end()) {
433 tri_pts[lv] = count + BasIdx;
438 tri_pts[lv] = it->second + BasIdx;
448 check_periodicity =
true;
453 if(check_periodicity) {
455 for(
size_t lv = 0; lv < 3; ++lv) {
459 MVertex *v2 =
f->getVertex((lv + 1) % 3);
460 MVertex *v3 =
f->getVertex((lv + 2) % 3);
466 tri_uvs[(lv + 0) % 3] = {{param1.
x(), param1.
y()}};
467 tri_uvs[(lv + 1) % 3] = {{param2.
x(), param2.
y()}};
468 tri_uvs[(lv + 2) % 3] = {{param3.
x(), param3.
y()}};
478 double initialGuess[2] = {0., 0.};
492 tri_uvs[0] = {{param1.
x(), param1.
y()}};
493 tri_uvs[1] = {{param2.
x(), param2.
y()}};
494 tri_uvs[2] = {{param3.
x(), param3.
y()}};
498 tri_uvs[0] = {{0., 0.}};
499 tri_uvs[1] = {{0., 0.}};
500 tri_uvs[2] = {{0., 0.}};
507 if(paramAvailable && disableParamPer)
528 int32_t NmbVer = (int32_t)
points.size();
529 double *VerTab1 =
points[0].data();
530 double *VerTab2 =
points[1].data();
532 int32_t NmbTri = (int32_t)
triangles.size();
536 Msg::Debug(
"create libOL octree (%i vertices and %i triangles)", NmbVer,
539 TriTab1, TriTab2, 0, NULL, NULL, 0, NULL, NULL, 0, NULL,
540 NULL, 0, NULL, NULL, 0, NULL, NULL, BasIdx, 1);
547 GPoint fail(DBL_MAX, DBL_MAX, DBL_MAX, NULL);
553 const std::array<double, 10> &analyticalParameters)
555 vec3 dir = {{query[0] - analyticalParameters[0],
556 query[1] - analyticalParameters[1],
557 query[2] - analyticalParameters[2]}};
560 const vec3 newPos = {{
561 analyticalParameters[0] + analyticalParameters[3] * dir[0],
562 analyticalParameters[1] + analyticalParameters[3] * dir[1],
563 analyticalParameters[2] + analyticalParameters[3] * dir[2]}};
564 return GPoint(newPos[0], newPos[1], newPos[2], gf);
568 bool projectOnCAD)
const
576 "SurfaceProjector::closestPoint(): no analytical formula for shape");
582 Msg::Error(
"SurfaceProjector::closestPoint(): no octree (face %i, %li "
583 "points, %li triangles)",
588 const int BasIdx = 1;
591 double crd[3] = {query[0], query[1], query[2]};
592 double dis = DBL_MAX;
595 Msg::Warning(
"SurfaceProjector::closestPoint(): no closest triangle found "
596 "(face %i, %li triangles)",
600 size_t tri = idx - 1;
603 const vec3 queryv3 = {{query[0], query[1], query[2]}};
619 double uv[2] = {0., 0.};
627 SPoint3 queryp3(query[0], query[1], query[2]);
629 if(cadProj.
succeeded()) { proj = cadProj; }
634 SPoint3 queryp3(query[0], query[1], query[2]);
636 if(cadProj.
succeeded()) { proj = cadProj; }
639 proj =
gf->
point(uv[0], uv[1]);
643 proj =
GPoint(cproj[0], cproj[1], cproj[2],
gf, uv[0], uv[1]);
647 proj =
GPoint(cproj[0], cproj[1], cproj[2],
gf);
654 const std::vector<std::array<double,3> >& _points,
655 const std::vector<std::array<int32_t,2> >& _edges,
656 const std::vector<std::array<int32_t,3> >& _triangles,
657 const std::vector<std::array<int32_t,4> >& _quads,
658 const std::vector<std::array<int32_t,4> >& _tetrahedra,
659 const std::vector<std::array<int32_t,5> >& _pyramids,
660 const std::vector<std::array<int32_t,6> >& _prisms,
661 const std::vector<std::array<int32_t,8> >& _hexahedra):
662 points(_points),
edges(_edges), triangles(_triangles), quads(_quads),
663 tetrahedra(_tetrahedra), pyramids(_pyramids), prisms(_prisms),
664 hexahedra(_hexahedra)
666 const int BasIdx = 1;
667 for (
size_t i = 0; i <
edges.size(); ++i)
for (
size_t j = 0; j <
edges[0].size(); ++j)
edges[i][j] += BasIdx;
669 for (
size_t i = 0; i <
quads.size(); ++i)
for (
size_t j = 0; j <
quads[0].size(); ++j)
quads[i][j] += BasIdx;
671 for (
size_t i = 0; i <
pyramids.size(); ++i)
for (
size_t j = 0; j <
pyramids[0].size(); ++j)
pyramids[i][j] += BasIdx;
672 for (
size_t i = 0; i <
prisms.size(); ++i)
for (
size_t j = 0; j <
prisms[0].size(); ++j)
prisms[i][j] += BasIdx;
700 double* bboxMin,
double* bboxMax,
701 std::vector<int32_t>& elements) {
703 const int BufSiz = 1e5;
707 elements.resize(NmbItm);
708 for (
int i = 0; i < NmbItm; ++i) {
709 elements[i] = buf[i]-1;