30 #ifndef MILENA_APPS_MESH_SEGM_SKEL_MISC_HH
31 # define MILENA_APPS_MESH_SEGM_SKEL_MISC_HH
36 # include <mln/algebra/vec.hh>
37 # include <mln/algebra/mat.hh>
39 # include <mln/norm/l2.hh>
41 # include <mln/data/fill.hh>
52 # if !defined(__GNUC__) || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
53 # define likely(x) (x)
54 # define unlikely(x) (x)
56 # define likely(x) (__builtin_expect((x), 1))
57 # define unlikely(x) (__builtin_expect((x), 0))
76 template <
unsigned N,
typename T>
82 for (
unsigned i = 0; i < N; ++i)
84 for (
unsigned k = 0; k < i; ++k)
85 v[k] = A(i, k) * rdiag[k];
86 for (
unsigned j = i; j < N; ++j)
89 for (
unsigned k = 0; k < i; k++)
90 sum -= v[k] * A(j, k);
93 if (unlikely(sum <= T(0)))
95 rdiag[i] = T(1) / sum;
109 template <
unsigned N,
typename T>
113 const vec<N, T>& B, vec<N, T>& x)
115 for (
unsigned i = 0; i < N; ++i)
118 for (
unsigned k = 0; k < i; ++k)
119 sum -= A(i, k) * x[k];
120 x[i] = sum * rdiag[i];
122 for (
int i = N - 1; i >= 0; --i)
125 for (
unsigned k = i + 1; k < N; ++k)
126 sum += A(k, i) * x[k];
127 x[i] -= sum * rdiag[i];
164 static const unsigned D = 2;
166 typedef algebra::vec<3, float> vec3f;
169 normal_t normal(mesh);
175 typedef mln::complex_m_face_neighborhood<D, G> adj_vertices_nbh_t;
176 adj_vertices_nbh_t adj_vertices_nbh;
177 mln_niter_(adj_vertices_nbh_t) adj_v(adj_vertices_nbh, f);
182 adj_v.iter().set_m(0);
188 std::vector<mln_psite_(normal_t)> p;
193 mln_assertion(p.size() == 3);
203 p[0].to_site().front().to_vec() - p[1].to_site().front().to_vec();
205 p[1].to_site().front().to_vec() - p[2].to_site().front().to_vec();
207 p[2].to_site().front().to_vec() - p[0].to_site().front().to_vec();
215 normal(p[0]) += face_normal * (1.0f / (l2a * l2c));
216 normal(p[1]) += face_normal * (1.0f / (l2b * l2a));
217 normal(p[2]) += face_normal * (1.0f / (l2c * l2b));
224 normal(v).normalize();
252 static const unsigned D = 2;
254 typedef algebra::vec<3, float> vec3f;
261 typedef std::pair<corner_area_t, point_area_t> output_t;
264 output_t output(mesh, mesh);
265 corner_area_t& corner_area = output.first;
266 point_area_t& point_area = output.second;
273 typedef mln::complex_m_face_neighborhood<D, G> adj_vertices_nbh_t;
274 adj_vertices_nbh_t adj_vertices_nbh;
275 mln_niter_(adj_vertices_nbh_t) adj_v(adj_vertices_nbh, f);
280 adj_v.iter().set_m(0);
285 std::vector<mln_psite_(corner_area_t)> p;
290 mln_assertion(p.size() == 3);
293 algebra::vec<3, vec3f> e;
296 (p[2].to_site().front().to_vec() - p[1].to_site().front().to_vec(),
297 p[0].to_site().front().to_vec() - p[2].to_site().front().to_vec(),
298 p[1].to_site().front().to_vec() - p[0].to_site().front().to_vec());
308 (sqr_norm[0] * (sqr_norm[1] + sqr_norm[2] - sqr_norm[0]),
309 sqr_norm[1] * (sqr_norm[2] + sqr_norm[0] - sqr_norm[1]),
310 sqr_norm[2] * (sqr_norm[0] + sqr_norm[1] - sqr_norm[2]));
312 if (edge_weight[0] <= 0.0f)
314 corner_area(f)[1] = -0.25f * sqr_norm[2] * area / (e[0] * e[2]);
315 corner_area(f)[2] = -0.25f * sqr_norm[1] * area / (e[0] * e[1]);
316 corner_area(f)[0] = area - corner_area(f)[1] - corner_area(f)[2];
318 else if (edge_weight[1] <= 0.0f)
320 corner_area(f)[2] = -0.25f * sqr_norm[0] * area / (e[1] * e[0]);
321 corner_area(f)[0] = -0.25f * sqr_norm[2] * area / (e[1] * e[2]);
322 corner_area(f)[1] = area - corner_area(f)[2] - corner_area(f)[0];
324 else if (edge_weight[2] <= 0.0f)
326 corner_area(f)[0] = -0.25f * sqr_norm[1] * area / (e[2] * e[1]);
327 corner_area(f)[1] = -0.25f * sqr_norm[0] * area / (e[2] * e[0]);
328 corner_area(f)[2] = area - corner_area(f)[0] - corner_area(f)[1];
333 0.5f * area / (edge_weight[0] + edge_weight[1] + edge_weight[2]);
334 for (
int i = 0; i < 3; ++i)
336 ewscale * (edge_weight[(i+1)%3] + edge_weight[(i+2)%3]);
339 for (
int i = 0; i < 3; ++i)
340 point_area(p[i]) += corner_area(f)[i];
365 static inline unsigned next(
unsigned i) {
return (i + 1) % 3; }
366 static inline unsigned prev(
unsigned i) {
return (i - 1) % 3; }
373 rot_coord_sys(
const algebra::vec<3, float> &old_u,
374 const algebra::vec<3, float> &old_v,
375 const algebra::vec<3, float> &new_norm,
376 algebra::vec<3, float> &new_u,
377 algebra::vec<3, float> &new_v)
381 algebra::vec<3, float> old_norm =
vprod(old_u, old_v);
382 float ndot = old_norm * new_norm;
383 if (unlikely(ndot <= -1.0f))
389 algebra::vec<3, float> perp_old = new_norm - ndot * old_norm;
390 algebra::vec<3, float> dperp =
391 1.0f / (1 + ndot) * (old_norm + new_norm);
392 new_u -= dperp * (new_u * perp_old);
393 new_v -= dperp * (new_v * perp_old);
404 proj_curv(
const algebra::vec<3, float>& old_u,
405 const algebra::vec<3, float>& old_v,
406 float old_ku,
float old_kuv,
float old_kv,
407 const algebra::vec<3, float>& new_u,
408 const algebra::vec<3, float>& new_v,
409 float& new_ku,
float& new_kuv,
float& new_kv)
411 algebra::vec<3, float> r_new_u, r_new_v;
412 rot_coord_sys(new_u, new_v,
vprod(old_u, old_v), r_new_u, r_new_v);
414 float u1 = r_new_u * old_u;
415 float v1 = r_new_u * old_v;
416 float u2 = r_new_v * old_u;
417 float v2 = r_new_v * old_v;
418 new_ku = old_ku * u1*u1 + old_kuv * (2.0f * u1*v1) + old_kv * v1*v1;
419 new_kuv = old_ku * u1*u2 + old_kuv * (u1*v2 + u2*v1) + old_kv * v1*v2;
420 new_kv = old_ku * u2*u2 + old_kuv * (2.0f * u2*v2) + old_kv * v2*v2;
428 diagonalize_curv(
const algebra::vec<3, float>& old_u,
429 const algebra::vec<3, float>& old_v,
430 float ku,
float kuv,
float kv,
431 const algebra::vec<3, float>& new_norm,
432 algebra::vec<3, float>& pdir1,
433 algebra::vec<3, float>& pdir2,
434 float& k1,
float& k2)
436 algebra::vec<3, float> r_old_u, r_old_v;
437 rot_coord_sys(old_u, old_v, new_norm, r_old_u, r_old_v);
439 float c = 1, s = 0, tt = 0;
440 if (likely(kuv != 0.0f))
443 float h = 0.5f * (kv - ku) / kuv;
445 1.0f / (h - sqrt(1.0f + h*h)) :
446 1.0f / (h + sqrt(1.0f + h*h));
447 c = 1.0f / sqrt(1.0f + tt*tt);
454 if (fabs(k1) >= fabs(k2))
455 pdir1 = c*r_old_u - s*r_old_v;
459 pdir1 = s*r_old_u + c*r_old_v;
461 pdir2 =
vprod(new_norm, pdir1);
483 complex_image< 2, mln::space_2complex_geometry, float >,
484 complex_image< 2, mln::space_2complex_geometry, float >
489 static const unsigned D = 2;
491 typedef algebra::vec<3, float> vec3f;
492 typedef algebra::mat<3, 3, float> mat3f;
504 typedef std::pair<corner_area_t, point_area_t> corner_point_area_t;
507 corner_area_t& corner_area = corner_point_area.first;
508 point_area_t& point_area = corner_point_area.second;
512 typedef std::pair<curv_t, curv_t> output_t;
513 output_t output(mesh, mesh);
514 curv_t& curv1 = output.first;
515 curv_t& curv2 = output.second;
529 typedef mln::complex_m_face_neighborhood<D, G> adj_vertices_nbh_t;
530 adj_vertices_nbh_t adj_vertices_nbh;
531 mln_niter_(adj_vertices_nbh_t) adj_v(adj_vertices_nbh, f);
536 adj_v.iter().set_m(0);
541 std::vector<mln_psite_(curv_t)> p;
546 mln_assertion(p.size() == 3);
550 p[1].to_site().front().to_vec() - p[0].to_site().front().to_vec();
552 p[2].to_site().front().to_vec() - p[1].to_site().front().to_vec();
554 p[0].to_site().front().to_vec() - p[2].to_site().front().to_vec();
561 pdir1(v).normalize();
571 std::vector<mln_psite_(curv_t)> p;
575 mln_assertion(p.size() == 3);
578 algebra::vec<3, vec3f> e;
581 (p[2].to_site().front().to_vec() - p[1].to_site().front().to_vec(),
582 p[0].to_site().front().to_vec() - p[2].to_site().front().to_vec(),
583 p[1].to_site().front().to_vec() - p[0].to_site().front().to_vec());
597 for (
int j = 0; j < 3; ++j)
612 normal(p[internal::prev(j)]) - normal(p[internal::next(j)]);
616 m[1] += dnu*v + dnv*u;
619 w(1, 1) = w(0, 0) + w(2, 2);
627 mln_assertion(ldlt_decomp_sucess_p);
631 for (
int j = 0; j < 3; ++j)
634 internal::proj_curv(t, b, m[0], m[1], m[2],
635 pdir1(p[j]), pdir2(p[j]), c1, c12, c2);
636 float wt = corner_area(f)[j] / point_area(p[j]);
637 curv1(p[j]) += wt * c1;
638 curv12(p[j]) += wt * c12;
639 curv2(p[j]) += wt *
c2;
648 internal::diagonalize_curv(pdir1(v), pdir2(v),
649 curv1(v), curv12(v), curv2(v),
650 normal(v), pdir1(v), pdir2(v),
660 #endif // ! MILENA_APPS_MESH_SEGM_SKEL_MISC_HH