46 static constexpr int maxTriangles {100};
48 using VectorType =
typename P::VectorType;
49 using Scalar =
typename P::Scalar;
51 template <
typename IndexRange,
typename Po
intContainer,
typename NeighborFilter>
53 const IndexRange& ids,
54 const PointContainer& points,
55 const NeighborFilter& w,
59 std::vector<int> indices;
60 for (
int index : ids ) {
62 if (w(points[ index ]).first == Scalar(0.))
64 indices.push_back(index);
69 const int lastIndex = int(indices.size()) - 1;
70 for (
int i = 0; i < maxTriangles; ++i) {
72 int i1 = indices[Eigen::internal::random<int>(0, lastIndex)];
73 int i2 = indices[Eigen::internal::random<int>(0, lastIndex)];
74 int i3 = indices[Eigen::internal::random<int>(0, lastIndex)];
75 if (i1 == i2 || i1 == i3 || i2 == i3)
continue;
90 static constexpr int maxTriangles {100};
92 using VectorType =
typename P::VectorType;
93 using Scalar =
typename P::Scalar;
95 template <
typename IndexRange,
typename Po
intContainer,
typename NeighborFilter>
97 const IndexRange& ids,
98 const PointContainer& points,
99 const NeighborFilter& w,
103 std::vector<int> indices;
104 for (
int index : ids ) {
106 if (w(points[ index ]).first == Scalar(0.))
108 indices.push_back(index);
114 std::random_device rd;
115 std::mt19937 rg(rd());
116 std::shuffle(indices.begin(), indices.end(), rg);
120 const int max_triangles = std::min(maxTriangles,
int(ids.size() / 3));
121 for (
int nb_vt = 0; nb_vt < max_triangles-2; nb_vt++) {
122 int i1 = indices[nb_vt];
123 int i2 = indices[nb_vt+1];
124 int i3 = indices[nb_vt+2];
144 using VectorType =
typename P::VectorType;
145 using Scalar =
typename P::Scalar;
147 template <
typename IndexRange,
typename Po
intContainer,
typename NeighborFilter>
149 const IndexRange& ids,
150 const PointContainer& points,
151 const NeighborFilter& w,
154 PONCA_MULTIARCH_STD_MATH(abs);
156 VectorType c = w.evalPos();
157 VectorType n = w.evalNormal();
158 VectorType a {VectorType::Zero()};
159 Scalar avg_d = Scalar(0);
161 bool isUndefined =
true;
162 int valid_points_count = 0;
163 for (
int index : ids ) {
165 if (w(points[ index ]).first == Scalar(0.))
167 auto p = points[ index ];
168 avg_d += ( p.pos() - c ).norm();
171 valid_points_count ++;
179 avg_d /= valid_points_count;
182 const int m = abs( n[0] ) > abs( n[1] )
183 ? ( abs( n[0] ) > abs( n[2] ) ? 0 : 2 )
184 : ( abs( n[1] ) > abs( n[2] ) ? 1 : 2 ) ;
187 ( m == 0 ) ? VectorType( 0, 1, 0 ) :
188 ( m == 1 ) ? VectorType( 0, 0, 1 ) :
189 VectorType( 1, 0, 0 ) ;
191 VectorType u = n.cross( e );
192 VectorType v = n.cross( u );
196 std::array<VectorType , 6> positions ;
197 std::array<VectorType , 6> normals ;
198 std::array< Scalar , 6 > distance2;
199 std::array< VectorType, 6 > targets;
201 for (
int i = 0 ; i < 6 ; i++ ) {
202 distance2[ i ] = avg_d * avg_d;
203 targets [ i ] = avg_d * ( u * cos(i * M_PI / 3.0) + v * sin(i * M_PI / 3.0) );
204 positions[ i ] = w.evalPos();
205 normals [ i ] = w.evalNormal();
209 for (
int index : ids ) {
211 if (w(points[ index ]).first == Scalar(0.))
214 VectorType p = points[ index ].pos();
215 if ( p == c )
continue;
216 const VectorType d = p - c;
218 for (
int j = 0 ; j < 6 ; j++ ) {
219 const Scalar d2 = ( d - targets[ j ]).squaredNorm();
220 if ( d2 < distance2[ j ] ) {
223 normals [ j ] = points[ index ].normal();
227 triangles.push_back(
internal::Triangle<P>({positions[0] , positions[2] , positions[4]}, {normals[0] , normals[2], normals[4]}));
228 triangles.push_back(
internal::Triangle<P>({positions[1] , positions[3] , positions[5]}, {normals[1] , normals[3], normals[5]}));
240 using VectorType =
typename P::VectorType;
241 using Scalar =
typename P::Scalar;
243 template <
typename IndexRange,
typename Po
intContainer,
typename NeighborFilter>
245 const IndexRange& ids,
246 const PointContainer& points,
247 const NeighborFilter& w,
251 VectorType c = w.evalPos();
252 VectorType n = w.evalNormal();
253 VectorType a = VectorType::Zero();
254 Scalar avg_d = Scalar(0);
256 std::array< VectorType, 6 > targets;
257 Scalar avg_normal = Scalar(0.5);
259 bool isUndefined =
true;
260 int valid_points_count = 0;
261 for (
int index : ids ) {
262 if (w(points[ index ]).first == Scalar(0.))
264 a += points[ index ].normal();
265 avg_d += ( points[ index ].pos() - c ).norm();
267 valid_points_count ++;
275 avg_d /= valid_points_count;
278 const int m = ( std::abs( n[0] ) > std::abs ( n[1] ))
279 ? ( ( std::abs( n[0] ) ) > std::abs( n[2] ) ? 0 : 2 )
280 : ( ( std::abs( n[1] ) ) > std::abs( n[2] ) ? 1 : 2 );
282 const VectorType e = ( m == 0 ) ? VectorType( 0, 1, 0 ) :
283 ( m == 1 ) ? VectorType( 0, 0, 1 ) :
284 VectorType( 1, 0, 0 ) ;
285 VectorType u = n.cross( e );
286 VectorType v = n.cross( u );
291 std::array< VectorType, 6 > array_avg_normals;
292 std::array< VectorType, 6 > array_avg_pos;
293 std::array< int, 6 > array_nb {};
294 for (
int i = 0 ; i < 6 ; i++ ) {
295 targets[ i ] = avg_d * ( u * cos(i * M_PI / 3.0) + v * sin(i * M_PI / 3.0) );
296 array_avg_normals[ i ] = VectorType::Zero();
297 array_avg_pos [ i ] = VectorType::Zero();
301 for (
int index : ids) {
302 if (w(points[ index ]).first == Scalar(0.))
304 VectorType p = points[ index ].pos() - c;
306 Scalar best_d2 = ( p - targets[ 0 ] ).squaredNorm();
307 for (
int k = 1 ; k < 6 ; k++) {
308 const Scalar d2 = ( p - targets[ k ] ).squaredNorm();
309 if ( d2 < best_d2 ) {
314 array_avg_normals[ best_k ] += points[ index ].normal();
315 array_avg_pos [ best_k ] += points[ index ].pos();
316 array_nb[ best_k ] += 1;
319 for (
int i = 0 ; i < 6 ; i++) {
320 if ( array_nb[ i ] == 0 ) {
321 array_avg_normals[ i ] = w.evalNormal();
322 array_avg_pos [ i ] = w.evalPos();
324 array_avg_normals[ i ] /= array_avg_normals[ i ].norm();
325 array_avg_pos [ i ] /= array_nb[ i ];
330 { array_avg_pos[0] , array_avg_pos[2] , array_avg_pos[4] },
331 { array_avg_normals[0], array_avg_normals[2], array_avg_normals[4] }
334 { array_avg_pos[1] , array_avg_pos[3] , array_avg_pos[5] },
335 { array_avg_normals[1], array_avg_normals[3], array_avg_normals[5] }
372 MatrixType localT = MatrixType::Zero();
374 for (
int t = 0; t < m_nb_vt; ++t) {
376 Scalar tA = m_triangles[t].mu0InterpolatedU();
379 m_H += m_triangles[t].template mu1InterpolatedU<true>();
380 m_G += m_triangles[t].template mu2InterpolatedU<true>();
381 localT += m_triangles[t].template muXYInterpolatedU<true>();
384 m_H += m_triangles[t].mu1InterpolatedU();
385 m_G += m_triangles[t].mu2InterpolatedU();
386 localT += m_triangles[t].muXYInterpolatedU();
391 m_T12 = 0.5 * (localT(0,1) + localT(1,0));
392 m_T13 = 0.5 * (localT(0,2) + localT(2,0));
394 m_T23 = 0.5 * (localT(1,2) + localT(2,1));
398 if (m_A != Scalar(0)) {
399 T << m_T11, m_T12, m_T13,
static std::tuple< Scalar, Scalar, VectorType, VectorType > curvaturesFromTensor(const MatrixType &tensor, const Scalar area, const VectorType &N)
Computing principal curvatures k1 and k2 from tensor.