From ae60ff2d15008cf5fab20eb28f7d28fa46d1c314 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 26 Aug 2019 13:05:27 +0200 Subject: [PATCH] Robustification of most visible vertex normal computation --- .../Polygon_mesh_processing/compute_normal.h | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/compute_normal.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/compute_normal.h index 3e528a44408..3e454068c90 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/compute_normal.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/compute_normal.h @@ -297,17 +297,21 @@ typename GT::Vector_3 compute_normals_bisector(const typename GT::Vector_3& ni, return traits.construct_sum_of_vectors_3_object()(ni, nj); // not normalized } -// @FIXME Handle the case of ni, nj and nk giving 3 points on a great circle template typename GT::Vector_3 compute_normals_bisector(const typename GT::Vector_3& ni, const typename GT::Vector_3& nj, const typename GT::Vector_3& nk, const GT& traits) { + typedef typename GT::FT FT; typedef typename GT::Point_3 Point_3; typedef typename GT::Vector_3 Vector_3; - Vector_3 nb = traits.construct_vector_3_object()(CGAL::NULL_VECTOR); + typename GT::Construct_scaled_vector_3 cslv_3 = traits.construct_scaled_vector_3_object(); + typename GT::Construct_sum_of_vectors_3 csv_3 = traits.construct_sum_of_vectors_3_object(); + typename GT::Construct_vector_3 cv_3 = traits.construct_vector_3_object(); + + Vector_3 nb = cv_3(CGAL::NULL_VECTOR); if(almost_equal(ni, nj, traits)) { @@ -329,27 +333,28 @@ typename GT::Vector_3 compute_normals_bisector(const typename GT::Vector_3& ni, CGAL_assertion(ni != nj); CGAL_assertion(ni != nk); CGAL_assertion(nj != nk); - CGAL_assertion(!traits.collinear_3_object()(CGAL::ORIGIN + ni, - CGAL::ORIGIN + nj, - CGAL::ORIGIN + nk)); + CGAL_assertion(!traits.collinear_3_object()(CGAL::ORIGIN + ni, CGAL::ORIGIN + nj, CGAL::ORIGIN + nk)); #ifdef CGAL_PMP_COMPUTE_NORMAL_DEBUG_PP std::cout << "Triplet: ni[" << ni << "] nj[" << nj << "] nk[" << nk << "]" << std::endl; #endif - const Point_3 c = traits.construct_circumcenter_3_object()(CGAL::ORIGIN + ni, - CGAL::ORIGIN + nj, - CGAL::ORIGIN + nk); - CGAL_assertion(c != CGAL::ORIGIN); + const Point_3 c = traits.construct_circumcenter_3_object()(CGAL::ORIGIN + ni, CGAL::ORIGIN + nj, CGAL::ORIGIN + nk); + if(c == CGAL::ORIGIN) + { + // will happen if the three vectors live in the same plan, return some weighted sum + const FT third = FT(1)/FT(3); + return csv_3(csv_3(cslv_3(ni, third), cslv_3(nj, third)), cslv_3(nk, third)); + } - nb = traits.construct_vector_3_object()(CGAL::ORIGIN, c); // note that this isn't normalized + nb = cv_3(CGAL::ORIGIN, c); // note that this isn't normalized } return nb; } template -std::pair +typename GT::Vector_3 compute_most_visible_normal_2_points(std::vector::face_descriptor>& incident_faces, const FaceNormalVector& face_normals, const GT& traits) @@ -358,14 +363,15 @@ compute_most_visible_normal_2_points(std::vector::reference Vector_ref; - typename GT::Compute_scalar_product_3 sp = traits.compute_scalar_product_3_object(); + typename GT::Compute_scalar_product_3 sp_3 = traits.compute_scalar_product_3_object(); + typename GT::Construct_vector_3 cv_3 = traits.construct_vector_3_object(); #ifdef CGAL_PMP_COMPUTE_NORMAL_DEBUG_PP std::cout << "Trying to find enclosing normal with 2 normals" << std::endl; #endif FT min_sp = -1; - Vector_3 n = traits.construct_vector_3_object()(CGAL::NULL_VECTOR); + Vector_3 n = cv_3(CGAL::NULL_VECTOR); const std::size_t nif = incident_faces.size(); for(int i=0; i= 0); if(sp_bi <= min_sp) @@ -396,8 +401,7 @@ compute_most_visible_normal_2_points(std::vector @@ -410,9 +414,6 @@ compute_most_visible_normal_3_points(const std::vector::reference Vector_ref; - typename GT::Compute_scalar_product_3 sp = traits.compute_scalar_product_3_object(); - typename GT::Construct_sum_of_vectors_3 csv = traits.construct_sum_of_vectors_3_object(); - #ifdef CGAL_PMP_COMPUTE_NORMAL_DEBUG_PP std::cout << "Trying to find enclosing normal with 3 normals" << std::endl; #endif @@ -437,7 +438,7 @@ compute_most_visible_normal_3_points(const std::vector res = compute_most_visible_normal_2_points(incident_faces, face_normals, traits); + Vector_3 res = compute_most_visible_normal_2_points(incident_faces, face_normals, traits); - if(!res.second || // won't be able to find a most visible normal - (res.second && res.first != CGAL::NULL_VECTOR)) // found a valid normal through 2 point min circle - return res.first; + if(res != CGAL::NULL_VECTOR) // found a valid normal through 2 point min circle + return res; CGAL_assertion(incident_faces.size() > 2);