31 #ifndef MILENA_APPS_MESH_SEGM_SKEL_MISC_HH
32 # define MILENA_APPS_MESH_SEGM_SKEL_MISC_HH
37 # include <mln/algebra/vec.hh>
38 # include <mln/algebra/mat.hh>
40 # include <mln/norm/l2.hh>
42 # include <mln/data/fill.hh>
53 # if !defined(__GNUC__) || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
54 # define likely(x) (x)
55 # define unlikely(x) (x)
57 # define likely(x) (__builtin_expect((x), 1))
58 # define unlikely(x) (__builtin_expect((x), 0))
77 template <
unsigned N,
typename T>
83 for (
unsigned i = 0; i < N; ++i)
85 for (
unsigned k = 0; k < i; ++k)
86 v[k] = A(i, k) * rdiag[k];
87 for (
unsigned j = i; j < N; ++j)
90 for (
unsigned k = 0; k < i; k++)
91 sum -= v[k] * A(j, k);
94 if (unlikely(sum <=
T(0)))
96 rdiag[i] =
T(1) /
sum;
110 template <
unsigned N,
typename T>
116 for (
unsigned i = 0; i < N; ++i)
119 for (
unsigned k = 0; k < i; ++k)
120 sum -= A(i, k) * x[k];
121 x[i] = sum * rdiag[i];
123 for (
int i = N - 1; i >= 0; --i)
126 for (
unsigned k = i + 1; k < N; ++k)
127 sum += A(k, i) * x[k];
128 x[i] -= sum * rdiag[i];
165 static const unsigned D = 2;
170 normal_t normal(mesh);
177 adj_vertices_nbh_t adj_vertices_nbh;
178 mln_niter_(adj_vertices_nbh_t) adj_v(adj_vertices_nbh, f);
183 adj_v.iter().set_m(0);
189 std::vector<mln_psite_(normal_t)>
p;
194 mln_assertion(p.size() == 3);
204 p[0].to_site().front().to_vec() - p[1].to_site().front().to_vec();
206 p[1].to_site().front().to_vec() - p[2].to_site().front().to_vec();
208 p[2].to_site().front().to_vec() - p[0].to_site().front().to_vec();
216 normal(p[0]) += face_normal * (1.0f / (l2a * l2c));
217 normal(p[1]) += face_normal * (1.0f / (l2b * l2a));
218 normal(p[2]) += face_normal * (1.0f / (l2c * l2b));
225 normal(v).normalize();
253 static const unsigned D = 2;
262 typedef std::pair<corner_area_t, point_area_t> output_t;
265 output_t output(mesh, mesh);
266 corner_area_t& corner_area = output.first;
267 point_area_t& point_area = output.second;
275 adj_vertices_nbh_t adj_vertices_nbh;
276 mln_niter_(adj_vertices_nbh_t) adj_v(adj_vertices_nbh, f);
281 adj_v.iter().set_m(0);
286 std::vector<mln_psite_(corner_area_t)>
p;
291 mln_assertion(p.size() == 3);
297 (p[2].to_site().front().to_vec() - p[1].to_site().front().to_vec(),
298 p[0].to_site().front().to_vec() - p[2].to_site().front().to_vec(),
299 p[1].to_site().front().to_vec() - p[0].to_site().front().to_vec());
309 (sqr_norm[0] * (sqr_norm[1] + sqr_norm[2] - sqr_norm[0]),
310 sqr_norm[1] * (sqr_norm[2] + sqr_norm[0] - sqr_norm[1]),
311 sqr_norm[2] * (sqr_norm[0] + sqr_norm[1] - sqr_norm[2]));
313 if (edge_weight[0] <= 0.0f)
315 corner_area(f)[1] = -0.25f * sqr_norm[2] * area / (e[0] * e[2]);
316 corner_area(f)[2] = -0.25f * sqr_norm[1] * area / (e[0] * e[1]);
317 corner_area(f)[0] = area - corner_area(f)[1] - corner_area(f)[2];
319 else if (edge_weight[1] <= 0.0f)
321 corner_area(f)[2] = -0.25f * sqr_norm[0] * area / (e[1] * e[0]);
322 corner_area(f)[0] = -0.25f * sqr_norm[2] * area / (e[1] * e[2]);
323 corner_area(f)[1] = area - corner_area(f)[2] - corner_area(f)[0];
325 else if (edge_weight[2] <= 0.0f)
327 corner_area(f)[0] = -0.25f * sqr_norm[1] * area / (e[2] * e[1]);
328 corner_area(f)[1] = -0.25f * sqr_norm[0] * area / (e[2] * e[0]);
329 corner_area(f)[2] = area - corner_area(f)[0] - corner_area(f)[1];
334 0.5f * area / (edge_weight[0] + edge_weight[1] + edge_weight[2]);
335 for (
int i = 0; i < 3; ++i)
337 ewscale * (edge_weight[(i+1)%3] + edge_weight[(i+2)%3]);
340 for (
int i = 0; i < 3; ++i)
341 point_area(p[i]) += corner_area(f)[i];
366 static inline unsigned next(
unsigned i) {
return (i + 1) % 3; }
367 static inline unsigned prev(
unsigned i) {
return (i - 1) % 3; }
383 float ndot = old_norm * new_norm;
384 if (unlikely(ndot <= -1.0f))
392 1.0f / (1 + ndot) * (old_norm + new_norm);
393 new_u -= dperp * (new_u * perp_old);
394 new_v -= dperp * (new_v * perp_old);
407 float old_ku,
float old_kuv,
float old_kv,
410 float& new_ku,
float& new_kuv,
float& new_kv)
413 rot_coord_sys(new_u, new_v, vprod(old_u, old_v), r_new_u, r_new_v);
415 float u1 = r_new_u * old_u;
416 float v1 = r_new_u * old_v;
417 float u2 = r_new_v * old_u;
418 float v2 = r_new_v * old_v;
419 new_ku = old_ku * u1*u1 + old_kuv * (2.0f * u1*v1) + old_kv * v1*v1;
420 new_kuv = old_ku * u1*u2 + old_kuv * (u1*v2 + u2*v1) + old_kv * v1*v2;
421 new_kv = old_ku * u2*u2 + old_kuv * (2.0f * u2*v2) + old_kv * v2*v2;
431 float ku,
float kuv,
float kv,
435 float& k1,
float& k2)
440 float c = 1, s = 0, tt = 0;
441 if (likely(kuv != 0.0f))
444 float h = 0.5f * (kv - ku) / kuv;
446 1.0f / (h -
sqrt(1.0f + h*h)) :
447 1.0f / (h +
sqrt(1.0f + h*h));
448 c = 1.0f /
sqrt(1.0f + tt*tt);
455 if (fabs(k1) >= fabs(k2))
456 pdir1 = c*r_old_u - s*r_old_v;
460 pdir1 = s*r_old_u + c*r_old_v;
462 pdir2 = vprod(new_norm, pdir1);
490 static const unsigned D = 2;
505 typedef std::pair<corner_area_t, point_area_t> corner_point_area_t;
508 corner_area_t& corner_area = corner_point_area.first;
509 point_area_t& point_area = corner_point_area.second;
513 typedef std::pair<curv_t, curv_t> output_t;
514 output_t output(mesh, mesh);
515 curv_t& curv1 = output.first;
516 curv_t& curv2 = output.second;
531 adj_vertices_nbh_t adj_vertices_nbh;
532 mln_niter_(adj_vertices_nbh_t) adj_v(adj_vertices_nbh, f);
537 adj_v.iter().set_m(0);
542 std::vector<mln_psite_(curv_t)>
p;
547 mln_assertion(p.size() == 3);
551 p[1].to_site().front().to_vec() - p[0].to_site().front().to_vec();
553 p[2].to_site().front().to_vec() - p[1].to_site().front().to_vec();
555 p[0].to_site().front().to_vec() - p[2].to_site().front().to_vec();
562 pdir1(v).normalize();
572 std::vector<mln_psite_(curv_t)>
p;
576 mln_assertion(p.size() == 3);
582 (p[2].to_site().front().to_vec() - p[1].to_site().front().to_vec(),
583 p[0].to_site().front().to_vec() - p[2].to_site().front().to_vec(),
584 p[1].to_site().front().to_vec() - p[0].to_site().front().to_vec());
598 for (
int j = 0; j < 3; ++j)
613 normal(p[internal::prev(j)]) - normal(p[internal::next(j)]);
617 m[1] += dnu*v + dnv*u;
620 w(1, 1) = w(0, 0) + w(2, 2);
628 mln_assertion(ldlt_decomp_success_p);
631 (void) ldlt_decomp_success_p;
635 for (
int j = 0; j < 3; ++j)
639 pdir1(p[j]), pdir2(p[j]), c1, c12, c2);
640 float wt = corner_area(f)[j] / point_area(p[j]);
641 curv1(p[j]) += wt * c1;
642 curv12(p[j]) += wt * c12;
643 curv2(p[j]) += wt *
c2;
653 curv1(v), curv12(v), curv2(v),
654 normal(v), pdir1(v), pdir2(v),
664 #endif // ! MILENA_APPS_MESH_SEGM_SKEL_MISC_HH