60 static constexpr int maxTriangles{100};
63 using VectorType =
typename P::VectorType;
64 using Scalar =
typename P::Scalar;
66 template <
typename IndexRange,
typename IteratorBegin,
typename IteratorEnd,
typename NeighborFilter>
67 static FIT_RESULT generate(
const IndexRange& ids,
const IteratorBegin& begin,
const IteratorEnd& end,
68 const NeighborFilter& w, std::vector<
Triangle<P>>& triangles)
71 std::vector<int> indices;
75 if (w(*std::next(begin, index)).first == Scalar(0.))
77 indices.push_back(index);
82 const int lastIndex = int(indices.size()) - 1;
83 for (
int i = 0; i < maxTriangles; ++i)
86 int i1 = indices[Eigen::internal::random<int>(0, lastIndex)];
87 int i2 = indices[Eigen::internal::random<int>(0, lastIndex)];
88 int i3 = indices[Eigen::internal::random<int>(0, lastIndex)];
89 if (i1 == i2 || i1 == i3 || i2 == i3)
98 template <
typename IndexRange,
typename Po
intContainer,
typename NeighborFilter>
99 static FIT_RESULT generate(
const IndexRange& ids,
const PointContainer& points,
const NeighborFilter& w,
102 return generate(ids, std::begin(points), std::end(points), w, triangles);
114 static constexpr int maxTriangles{100};
117 using VectorType =
typename P::VectorType;
118 using Scalar =
typename P::Scalar;
120 template <
typename IndexRange,
typename IteratorBegin,
typename IteratorEnd,
typename NeighborFilter>
121 static FIT_RESULT generate(
const IndexRange& ids,
const IteratorBegin& begin,
const IteratorEnd& end,
122 const NeighborFilter& w, std::vector<
Triangle<P>>& triangles)
125 std::vector<int> indices;
126 for (
int index : ids)
129 if (w(*std::next(begin, index)).first == Scalar(0.))
131 indices.push_back(index);
137 std::random_device rd;
138 std::mt19937 rg(rd());
139 std::shuffle(indices.begin(), indices.end(), rg);
143 const int max_triangles = std::min(maxTriangles,
int(indices.size() / 3));
144 for (
int nb_vt = 0; nb_vt < max_triangles - 2; nb_vt++)
146 int i1 = indices[nb_vt];
147 int i2 = indices[nb_vt + 1];
148 int i3 = indices[nb_vt + 2];
155 template <
typename IndexRange,
typename Po
intContainer,
typename NeighborFilter>
156 static FIT_RESULT generate(
const IndexRange& ids,
const PointContainer& points,
const NeighborFilter& w,
159 return generate(ids, std::begin(points), std::end(points), w, triangles);
177 using VectorType =
typename P::VectorType;
178 using Scalar =
typename P::Scalar;
180 template <
typename IndexRange,
typename IteratorBegin,
typename IteratorEnd,
typename NeighborFilter>
181 static FIT_RESULT generate(
const IndexRange& ids,
const IteratorBegin& begin,
const IteratorEnd& end,
182 const NeighborFilter& w, std::vector<
Triangle<P>>& triangles)
184 PONCA_MULTIARCH_STD_MATH(abs);
186 VectorType c = w.center();
187 VectorType n = w.data();
188 VectorType a{VectorType::Zero()};
189 Scalar avg_d = Scalar(0);
191 bool isUndefined =
true;
192 int valid_points_count = 0;
193 for (
int index : ids)
195 auto p = *std::next(begin, index);
198 if (w(p).first == Scalar(0.))
201 avg_d += (p.pos() - c).norm();
204 valid_points_count++;
212 avg_d /= valid_points_count;
215 const int m = abs(n[0]) > abs(n[1]) ? (abs(n[0]) > abs(n[2]) ? 0 : 2) : (abs(n[1]) > abs(n[2]) ? 1 : 2);
217 const VectorType e = (m == 0) ? VectorType(0, 1, 0) : (m == 1) ? VectorType(0, 0, 1) : VectorType(1, 0, 0);
219 VectorType u = n.cross(e);
220 VectorType v = n.cross(u);
224 std::array<VectorType, 6> positions;
225 std::array<VectorType, 6> normals;
226 std::array<Scalar, 6> distance2;
227 std::array<VectorType, 6> targets;
229 for (
int i = 0; i < 6; i++)
231 distance2[i] = avg_d * avg_d;
232 targets[i] = avg_d * (u * cos(i * M_PI / 3.0) + v * sin(i * M_PI / 3.0));
233 positions[i] = w.center();
234 normals[i] = w.data();
238 for (
int index : ids)
240 auto pt = *std::next(begin, index);
243 if (w(pt).first == Scalar(0.))
246 VectorType p = pt.pos();
249 const VectorType d = p - c;
251 for (
int j = 0; j < 6; j++)
253 const Scalar d2 = (d - targets[j]).squaredNorm();
254 if (d2 < distance2[j])
258 normals[j] = pt.normal();
263 {normals[0], normals[2], normals[4]}));
265 {normals[1], normals[3], normals[5]}));
269 template <
typename IndexRange,
typename Po
intContainer,
typename NeighborFilter>
270 static FIT_RESULT generate(
const IndexRange& ids,
const PointContainer& points,
const NeighborFilter& w,
273 return generate(ids, std::begin(points), std::end(points), w, triangles);
284 using VectorType =
typename P::VectorType;
285 using Scalar =
typename P::Scalar;
286 template <
typename IndexRange,
typename Po
intIterator,
typename NeighborFilter>
287 static FIT_RESULT generate(
const IndexRange& ids,
const PointIterator& begin,
const PointIterator& end,
288 const NeighborFilter& w, std::vector<
Triangle<P>>& triangles)
291 VectorType c = w.center();
292 VectorType n = w.data();
293 VectorType a = VectorType::Zero();
294 Scalar avg_d = Scalar(0);
296 std::array<VectorType, 6> targets;
297 Scalar avg_normal = Scalar(0.5);
299 bool isUndefined =
true;
300 int valid_points_count = 0;
301 for (
int index : ids)
303 auto p = *std::next(begin, index);
304 if (w(p).first == Scalar(0.))
307 avg_d += (p.pos() - c).norm();
309 valid_points_count++;
317 avg_d /= valid_points_count;
320 const int m = (std::abs(n[0]) > std::abs(n[1])) ? ((std::abs(n[0])) > std::abs(n[2]) ? 0 : 2)
321 : ((std::abs(n[1])) > std::abs(n[2]) ? 1 : 2);
323 const VectorType e = (m == 0) ? VectorType(0, 1, 0) : (m == 1) ? VectorType(0, 0, 1) : VectorType(1, 0, 0);
324 VectorType u = n.cross(e);
325 VectorType v = n.cross(u);
330 std::array<VectorType, 6> array_avg_normals;
331 std::array<VectorType, 6> array_avg_pos;
332 std::array<int, 6> array_nb{};
333 for (
int i = 0; i < 6; i++)
335 targets[i] = avg_d * (u * cos(i * M_PI / 3.0) + v * sin(i * M_PI / 3.0));
336 array_avg_normals[i] = VectorType::Zero();
337 array_avg_pos[i] = VectorType::Zero();
341 for (
int index : ids)
343 auto pt = *std::next(begin, index);
344 if (w(pt).first == Scalar(0.))
346 VectorType p = pt.pos() - c;
348 Scalar best_d2 = (p - targets[0]).squaredNorm();
349 for (
int k = 1; k < 6; k++)
351 const Scalar d2 = (p - targets[k]).squaredNorm();
358 array_avg_normals[best_k] += pt.normal();
359 array_avg_pos[best_k] += pt.pos();
360 array_nb[best_k] += 1;
363 for (
int i = 0; i < 6; i++)
365 if (array_nb[i] == 0)
367 array_avg_normals[i] = w.data();
368 array_avg_pos[i] = w.center();
372 array_avg_normals[i] /= array_avg_normals[i].norm();
373 array_avg_pos[i] /= Scalar(array_nb[i]);
379 {array_avg_normals[0], array_avg_normals[2], array_avg_normals[4]}));
382 {array_avg_normals[1], array_avg_normals[3], array_avg_normals[5]}));
386 template <
typename IndexRange,
typename Po
intContainer,
typename NeighborFilter>
387 static FIT_RESULT generate(
const IndexRange& ids,
const PointContainer& points,
const NeighborFilter& w,
390 return generate(ids, std::begin(points), std::end(points), w, triangles);
451 MatrixType localT = MatrixType::Zero();
453 for (
int t = 0; t < m_nb_vt; ++t)
456 Scalar tA = m_triangles[t].mu0InterpolatedU();
460 m_H += m_triangles[t].template mu1InterpolatedU<true>();
461 m_G += m_triangles[t].template mu2InterpolatedU<true>();
462 localT += m_triangles[t].template muXYInterpolatedU<true>();
467 m_H += m_triangles[t].mu1InterpolatedU();
468 m_G += m_triangles[t].mu2InterpolatedU();
469 localT += m_triangles[t].muXYInterpolatedU();
473 m_T11 = localT(0, 0);
474 m_T12 = Scalar(0.5) * (localT(0, 1) + localT(1, 0));
475 m_T13 = Scalar(0.5) * (localT(0, 2) + localT(2, 0));
476 m_T22 = localT(1, 1);
477 m_T23 = Scalar(0.5) * (localT(1, 2) + localT(2, 1));
478 m_T33 = localT(2, 2);
481 if (m_A != Scalar(0))
483 T << m_T11, m_T12, m_T13, m_T12, m_T22, m_T23, m_T13, m_T23, m_T33;