16 #include <Eigen/Dense>
19 #include <boost/graph/graph_traits.hpp>
20 #include <boost/graph/properties.hpp>
22 #include <CGAL/boost/graph/iterator.h>
23 #include <CGAL/boost/graph/helpers.h>
38 template<
typename HalfedgeGraph,
51 template<
typename HalfedgeGraph,
59 template<
typename HalfedgeGraph,
64 const HalfedgeGraph &g,
66 typename boost::graph_traits< HalfedgeGraph >::face_descriptor fd,
67 const GeometryTraits >)
69 typedef typename boost::property_traits< PointMap >::value_type
Point3d;
72 CGAL::Halfedge_around_face_circulator< HalfedgeGraph > p_halfedge(
78 return FEVV::Operators::Geometry::triangle_area< GeometryTraits >(
85 template<
typename HalfedgeGraph,
87 typename FaceNormalMap,
89 typename GraphTraits = boost::graph_traits< HalfedgeGraph >,
94 const FaceNormalMap &f_nm,
96 double pp_matrix_sum[3][3],
97 const GeometryTraits >)
101 typedef typename GraphTraits::face_descriptor face_descriptor;
106 CGAL::Halfedge_around_target_circulator< HalfedgeGraph > p_halfedge(vd, g),
113 #if 1 // WAITING for AIF stuff - TODO : REMOVE THIS BLOC LATER...
116 Vector edge(p1[0] - p2[0], p1[1] - p2[1], p1[2] - p2[2]);
118 double len_edge = gt.length(
edge);
123 face_descriptor p_facet1 =
face(*p_halfedge, g);
124 face_descriptor p_facet2 =
face(
opposite(*p_halfedge, g), g);
125 assert(p_facet1 != p_facet2);
126 if(p_facet1 == GraphTraits::null_face() ||
127 p_facet2 == GraphTraits::null_face())
130 Vector normal1 = f_nm[p_facet1];
131 Vector normal2 = f_nm[p_facet2];
133 if(std::isnan(normal1[0]) || std::isnan(normal1[1]) ||
134 std::isnan(normal1[2]) ||
135 std::isnan(normal2[0]) || std::isnan(normal2[1]) ||
136 std::isnan(normal2[2]))
143 Vector cp(normal1[1] * normal2[2] - normal1[2] * normal2[1],
144 normal1[2] * normal2[0] - normal1[0] * normal2[2],
145 normal1[0] * normal2[1] - normal1[1] * normal2[0]);
146 double ps_cp_xedge = cp[0] *
edge[0] + cp[1] *
edge[1] + cp[2] *
edge[2];
157 double pp_matrix[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
159 p_vector_edge, pp_matrix, beta / len_edge);
161 }
while(++p_halfedge != done);
164 for(
int i = 0; i < 3; i++)
165 for(
int j = 0; j < 3; j++)
166 pp_matrix_sum[i][j] /= area;
168 std::cout <<
"Unable to compute curvature." << std::endl;
174 template<
typename HalfedgeGraph,
176 typename FaceNormalMap,
178 typename GraphTraits = boost::graph_traits< HalfedgeGraph >,
183 const FaceNormalMap &f_nm,
185 double pp_matrix_sum[3][3],
187 const GeometryTraits >)
191 typedef typename GraphTraits::face_descriptor face_descriptor;
193 std::set< VertexDescriptor >
vertices;
195 std::stack< VertexDescriptor > s;
201 VertexDescriptor v = s.top();
204 CGAL::Halfedge_around_target_circulator< HalfedgeGraph > h(v, g), done(h);
210 #if 1 // WAITING for AIF stuff - TODO : REMOVE THIS BLOC LATER...
211 Vector vec = gt.sub_p(p2, p1);
212 Vector pm_o = gt.sub_p(p, o);
215 Vector vec(p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]);
216 Vector PmO(P[0] - O[0], P[1] - O[1], P[2] - O[2]);
219 vec[0] * pm_o[0] + vec[1] * pm_o[1] + vec[2] * pm_o[2];
222 if(v == vd || ps_vx_pm_o >= 0.0)
225 bool normal1_nan =
false, normal2_nan =
false;
226 bool pt_face1_superpose =
false, pt_face2_superpose =
false;
229 o, radius, p, vec, gt);
231 if(!CGAL::is_border_edge(*h, g) && isect)
234 std::sqrt(vec[0] * vec[0] + vec[1] * vec[1] +
238 face_descriptor p_facet1 =
face(*h, g);
240 assert(p_facet1 != p_facet2);
242 std::vector< Point3d > face1_vertices;
243 BOOST_FOREACH(VertexDescriptor vi, CGAL::vertices_around_face(*h, g))
244 face1_vertices.push_back(
get(pm, vi));
246 if(face1_vertices[0][0] == face1_vertices[1][0] &&
247 face1_vertices[1][0] == face1_vertices[2][0] &&
248 face1_vertices[0][0] == face1_vertices[2][0] &&
249 face1_vertices[0][1] == face1_vertices[1][1] &&
250 face1_vertices[1][1] == face1_vertices[2][1] &&
251 face1_vertices[0][1] == face1_vertices[2][1] &&
252 face1_vertices[0][2] == face1_vertices[1][2] &&
253 face1_vertices[1][2] == face1_vertices[2][2] &&
254 face1_vertices[0][2] == face1_vertices[2][2])
255 pt_face1_superpose =
true;
257 std::vector< Point3d > face2_vertices;
258 BOOST_FOREACH(VertexDescriptor vi,
259 CGAL::vertices_around_face(
opposite(*h, g), g))
260 face2_vertices.push_back(
get(pm, vi));
262 if(face2_vertices[0][0] == face2_vertices[1][0] &&
263 face2_vertices[1][0] == face2_vertices[2][0] &&
264 face2_vertices[0][0] == face2_vertices[2][0] &&
265 face2_vertices[0][1] == face2_vertices[1][1] &&
266 face2_vertices[1][1] == face2_vertices[2][1] &&
267 face2_vertices[0][1] == face2_vertices[2][1] &&
268 face2_vertices[0][2] == face2_vertices[1][2] &&
269 face2_vertices[1][2] == face2_vertices[2][2] &&
270 face2_vertices[0][2] == face2_vertices[2][2])
271 pt_face2_superpose =
true;
273 if(p_facet1 != GraphTraits::null_face() &&
274 p_facet2 != GraphTraits::null_face())
276 Vector normal1 = f_nm[p_facet1];
277 Vector normal2 = f_nm[p_facet2];
280 if(std::isnan(normal1[0]) || std::isnan(normal1[1]) ||
281 std::isnan(normal1[2]))
283 if(std::isnan(normal2[0]) || std::isnan(normal2[1]) ||
284 std::isnan(normal2[2]))
290 if(!pt_face2_superpose && !pt_face1_superpose)
294 if(!normal1_nan && !normal2_nan)
297 double ps = normal1[0] * normal2[0] + normal1[1] * normal2[1] +
298 normal1[2] * normal2[2];
299 double acos = ps / std::sqrt((normal1[0] * normal1[0] +
300 normal1[1] * normal1[1] +
301 normal1[2] * normal1[2]) *
302 (normal2[0] * normal2[0] +
303 normal2[1] * normal2[1] +
304 normal2[2] * normal2[2]));
315 Vector cp(normal1[1] * normal2[2] - normal1[2] * normal2[1],
316 normal1[2] * normal2[0] - normal1[0] * normal2[2],
317 normal1[0] * normal2[1] - normal1[1] * normal2[0]);
319 cp[0] * vec[0] + cp[1] * vec[1] + cp[2] * vec[2];
328 else if((normal1_nan && !normal2_nan) ||
329 (normal2_nan && !normal1_nan))
335 bool found_face =
false;
337 VertexDescriptor t1 =
source(*h, g);
339 std::stack< VertexDescriptor > s2;
340 std::set< VertexDescriptor > s22;
343 while(!s2.empty() && !found_face)
345 VertexDescriptor t = s2.top();
347 CGAL::Halfedge_around_target_circulator< HalfedgeGraph > h2(
352 if(
get(pm,
source(*h2, g)) == destination)
354 face_descriptor newface2 =
face(*h2, g);
355 if(newface2 != GraphTraits::null_face())
357 normal2 = f_nm[newface2];
358 if(!std::isnan(normal2[0]) &&
359 !std::isnan(normal2[1]) &&
360 !std::isnan(normal2[2]) && newface2 != p_facet1)
362 Vector cp(normal1[1] * normal2[2] -
363 normal1[2] * normal2[1],
364 normal1[2] * normal2[0] -
365 normal1[0] * normal2[2],
366 normal1[0] * normal2[1] -
367 normal1[1] * normal2[0]);
368 double ps_cpx_v = cp[0] * vec[0] + cp[1] * vec[1] +
371 double sine = ps_cpx_v / len_edge;
376 else if(s22.find(
source(*h2, g)) == s22.end())
379 s22.insert(
source(*h2, g));
384 }
while(h2 != done2);
394 bool found_face =
false;
395 VertexDescriptor v1 =
source(*h, g);
397 std::stack< VertexDescriptor > s1;
398 std::set< VertexDescriptor > s11;
401 while(!s1.empty() && !found_face)
403 VertexDescriptor s = s1.top();
405 CGAL::Halfedge_around_target_circulator< HalfedgeGraph > h1(
410 if(
get(pm,
source(*h1, g)) == destination)
412 face_descriptor newface1 =
face(*h1, g);
413 if(newface1 != GraphTraits::null_face())
415 normal1 = f_nm[newface1];
416 if(!std::isnan(normal1[0]) &&
417 !std::isnan(normal1[1]) &&
418 !std::isnan(normal1[2]) && newface1 != p_facet2)
420 Vector cp(normal1[1] * normal2[2] -
421 normal1[2] * normal2[1],
422 normal1[2] * normal2[0] -
423 normal1[0] * normal2[2],
424 normal1[0] * normal2[1] -
425 normal1[1] * normal2[0]);
426 double ps_cpx_v = cp[0] * vec[0] + cp[1] * vec[1] +
429 double sine = ps_cpx_v / len_edge;
434 else if(s11.find(
source(*h1, g)) == s11.end())
437 s11.insert(
source(*h1, g));
442 }
while(h1 != done1);
457 double p_vector_edge[3] = {vec[0], vec[1], vec[2]};
458 double pp_matrix[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
460 p_vector_edge, pp_matrix, beta / len_edge);
468 VertexDescriptor w =
source(
471 assert(w != GraphTraits::null_vertex());
479 }
while(++h != done);
484 double area = M_PI * radius * radius;
486 for(
int i = 0; i < 3; i++)
487 for(
int j = 0; j < 3; j++)
488 pp_matrix_sum[i][j] /= area;
517 template<
typename HalfedgeGraph,
518 typename VertexCurvatureMap,
520 typename FaceNormalMap,
524 VertexCurvatureMap &v_cm,
526 const FaceNormalMap &f_nm,
529 double &min_nrm_min_curvature,
530 double &max_nrm_min_curvature,
531 double &min_nrm_max_curvature,
532 double &max_nrm_max_curvature,
533 const GeometryTraits >)
535 typedef boost::graph_traits< HalfedgeGraph > GraphTraits;
536 typedef typename GraphTraits::vertex_iterator vertex_iterator;
540 min_nrm_min_curvature = 100000;
541 max_nrm_min_curvature = -100000;
543 min_nrm_max_curvature = 100000;
544 max_nrm_max_curvature = -100000;
548 std::cout <<
"Asking to calculate curvature" << std::endl;
549 #ifdef DBG_calculate_curvature_cmdm
550 std::cout <<
"Real radius = " << radius << std::endl;
553 vertex_iterator vi = iterator_pair.first;
554 vertex_iterator vi_end = iterator_pair.second;
557 for(; vi != vi_end; ++vi)
559 bool no_val_pro =
false;
561 double pp_matrix_sum[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
571 pp_matrix_sum, radius, gt);
588 cov_mat(0, 0) = pp_matrix_sum[0][0];
589 cov_mat(0, 1) = pp_matrix_sum[0][1];
590 cov_mat(0, 2) = pp_matrix_sum[0][2];
591 cov_mat(1, 0) = pp_matrix_sum[1][0];
592 cov_mat(1, 1) = pp_matrix_sum[1][1];
593 cov_mat(1, 2) = pp_matrix_sum[1][2];
594 cov_mat(2, 0) = pp_matrix_sum[2][0];
595 cov_mat(2, 1) = pp_matrix_sum[2][1];
596 cov_mat(2, 2) = pp_matrix_sum[2][2];
598 #ifdef DBG_calculate_curvature_cmdm
599 std::cout <<
"\n\nCovMat\n\n" << CovMat << std::endl;
602 if(pp_matrix_sum[0][1] == 0 && pp_matrix_sum[0][2] == 0 &&
603 pp_matrix_sum[1][0] == 0 && pp_matrix_sum[1][2] == 0 &&
604 pp_matrix_sum[2][1] == 0 && pp_matrix_sum[2][0] == 0)
606 for(
int i = 0; i < 3; i++)
607 valpro(i) = cov_mat(i, i);
608 vect_pro = EigenMatrix::Identity();
618 #ifdef DBG_calculate_curvature_cmdm
619 std::cout <<
"\n\nValpro\n\n" << Valpro << std::endl;
620 std::cout <<
"\n\nVectPro\n\n" << VectPro << std::endl;
626 Vector v_kmax_curv(vect_pro(0, 1), vect_pro(1, 1), vect_pro(2, 1));
627 Vector v_kmin_curv(vect_pro(0, 0), vect_pro(1, 0), vect_pro(2, 0));
629 #ifdef DBG_calculate_curvature_cmdm
630 std::cout <<
"\n\nValpro sorted\n\n" << Valpro << std::endl;
631 std::cout <<
"\n\nVectPro sorted\n\n" << VectPro << std::endl;
632 std::cout <<
"\nVKmaxCurv = " << VKmaxCurv[0] <<
" " << VKmaxCurv[1]
633 <<
" " << VKmaxCurv[2] << std::endl;
634 std::cout <<
"\nVKminCurv = " << VKminCurv[0] <<
" " << VKminCurv[1]
635 <<
" " << VKminCurv[2] << std::endl;
638 v_cm[*vi].VKmaxCurv = v_kmax_curv;
639 v_cm[*vi].VKminCurv = v_kmin_curv;
643 v_cm[*vi].KmaxCurv = valpro(0);
644 v_cm[*vi].KminCurv = valpro(1);
648 v_cm[*vi].KmaxCurv = -valpro(0);
649 v_cm[*vi].KminCurv = -valpro(1);
654 v_cm[*vi].VKmaxCurv = gt.NULL_VECTOR;
655 v_cm[*vi].VKminCurv = gt.NULL_VECTOR;
656 v_cm[*vi].KmaxCurv = 0;
657 v_cm[*vi].KminCurv = 0;
660 #ifdef DBG_calculate_curvature_cmdm
661 std::cout <<
"\nv_cm[*vi].KmaxCurv = " << v_cm[*vi].KmaxCurv << std::endl;
662 std::cout <<
"\nv_cm[*vi].KminCurv = " << v_cm[*vi].KminCurv << std::endl;
665 min_nrm_min_curvature =
666 std::min< double >(min_nrm_min_curvature, v_cm[*vi].KminCurv);
667 max_nrm_min_curvature =
668 std::max< double >(max_nrm_min_curvature, v_cm[*vi].KminCurv);
670 min_nrm_max_curvature =
671 std::min< double >(min_nrm_max_curvature, v_cm[*vi].KmaxCurv);
672 max_nrm_max_curvature =
673 std::max< double >(max_nrm_max_curvature, v_cm[*vi].KmaxCurv);
715 template<
typename HalfedgeGraph,
716 typename VertexCurvatureMap,
718 typename FaceNormalMap,
722 VertexCurvatureMap &v_cm,
724 const FaceNormalMap &f_nm,
727 double &min_nrm_min_curvature,
728 double &max_nrm_min_curvature,
729 double &min_nrm_max_curvature,
730 double &max_nrm_max_curvature)
732 GeometryTraits gt(g);
743 min_nrm_min_curvature,
744 max_nrm_min_curvature,
745 min_nrm_max_curvature,
746 max_nrm_max_curvature,