From 7ed402b3f7ef211cc445ced8e827272c511da92c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 2 Jan 2017 15:30:58 +0100 Subject: [PATCH] optimize the number of nodes created in the DAG - Use new kernel functors for intersection points - Construct points from double to have only one node per point (doubles are stored in Lazy_rep_3) --- .../Corefinement/intersection_nodes.h | 131 +++++++----------- .../intersection_of_coplanar_triangles_3.h | 49 +++---- 2 files changed, 70 insertions(+), 110 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_nodes.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_nodes.h index 8c736712f61..b7c066013f8 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_nodes.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_nodes.h @@ -28,51 +28,6 @@ namespace CGAL { namespace Corefinement { -template -typename Exact_kernel::Point_3 -compute_triangle_segment_intersection_point( - typename boost::graph_traits::halfedge_descriptor hd, - typename boost::graph_traits::face_descriptor fd, - const Exact_kernel& ek, - const TriangleMesh& tm_h, - const TriangleMesh& tm_f, - const VertexPointMap& vpm_h, - const VertexPointMap& vpm_f) -{ - typedef typename Kernel_traits< - typename boost::property_traits::value_type - >::Kernel Input_kernel; - typedef boost::graph_traits GT; - typedef typename GT::vertex_descriptor vertex_descriptor; - typedef typename GT::halfedge_descriptor halfedge_descriptor; - typedef typename Exact_kernel::Line_3 Line_3; - typedef typename Exact_kernel::Plane_3 Plane_3; - - CGAL::Cartesian_converter to_exact; - halfedge_descriptor hdf=halfedge(fd,tm_f); - vertex_descriptor vf1=source(hdf,tm_f), - vf2=target(hdf,tm_f), - vf3=target(next(hdf,tm_f),tm_f), - vh1=source(hd,tm_h), - vh2=target(hd,tm_h); - - Plane_3 plane(to_exact( get(vpm_f, vf1) ), - to_exact( get(vpm_f, vf2) ), - to_exact( get(vpm_f, vf3) ) ); - - Line_3 line( to_exact( get(vpm_h, vh1) ), to_exact( get(vpm_h, vh2) ) ); - - typename cpp11::result_of::type - res = ek.intersect_3_object()(plane,line); - CGAL_assertion(res!=boost::none); - const typename Exact_kernel::Point_3* e_pt = - boost::get(&(*res)); - CGAL_assertion(e_pt!=NULL); - return *e_pt; -} - // A class responsible for storing the intersection nodes of the intersection // polylines. Different specializations are available depending whether // predicates on constructions are needed. @@ -98,7 +53,6 @@ class Intersection_nodes typedef std::vector Nodes_vector; typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_kernel; typedef CGAL::Cartesian_converter Exact_to_double; - // typedef CGAL::Interval_nt::Protector Protector; typedef boost::graph_traits GT; typedef typename GT::halfedge_descriptor halfedge_descriptor; typedef typename GT::face_descriptor face_descriptor; @@ -107,6 +61,13 @@ class Intersection_nodes Nodes_vector nodes; Exact_kernel ek; Exact_to_double exact_to_double; + + typename Exact_kernel::Point_3 + to_exact(const typename Input_kernel::Point_3& p) const + { + return typename Exact_kernel::Point_3(p.x(), p.y(), p.z()); + } + public: const TriangleMesh &tm1, &tm2; VertexPointMap vpm1, vpm2; @@ -125,11 +86,6 @@ public: return nodes[i]; } - // const Point_3& exact_node(std::size_t i) const {return nodes[i];} - // const Point_3& interval_node(std::size_t i) const {return nodes[i];} - // const Point_3& to_exact(const typename Kernel::Point_3& p) const {return p;} - // const Point_3& to_interval(const typename Kernel::Point_3& p) const {return p;} - size_t size() const {return nodes.size();} void add_new_node(const Point_3& p) @@ -144,13 +100,6 @@ public: //add a new node in the final graph. //it is the intersection of the triangle with the segment - void add_new_node(halfedge_descriptor edge_1, face_descriptor face_2) - { - add_new_node( - compute_triangle_segment_intersection_point(edge_1, face_2, ek, tm1, tm2, vpm1, vpm2) - ); - } - void add_new_node(halfedge_descriptor h_a, face_descriptor f_b, const TriangleMesh& tm_a, @@ -158,9 +107,19 @@ public: const VertexPointMap vpm_a, const VertexPointMap& vpm_b) { - add_new_node( - compute_triangle_segment_intersection_point(h_a, f_b, ek, tm_a, tm_b, vpm_a, vpm_b) - ); + halfedge_descriptor h_b = halfedge(f_b, tm_b); + add_new_node( + typename Exact_kernel::Construct_plane_line_intersection_point_3()( + to_exact( get(vpm_b, source(h_b,tm_b)) ), + to_exact( get(vpm_b, target(h_b,tm_b)) ), + to_exact( get(vpm_b, target(next(h_b,tm_b),tm_b)) ), + to_exact( get(vpm_a, source(h_a,tm_a)) ), + to_exact( get(vpm_a, target(h_a,tm_a)) ) ) ); + } + + void add_new_node(halfedge_descriptor edge_1, face_descriptor face_2) + { + add_new_node(edge_1, face_2, tm1, tm2, vpm1, vpm2); } }; // end specialization @@ -246,7 +205,7 @@ public: Exact_kernel::Point_3 to_exact(const Point_3& p) const { - return double_to_exact(p); + return typename Exact_kernel::Point_3(p.x(), p.y(), p.z()); } size_t size() const {return enodes.size();} @@ -268,13 +227,6 @@ public: //add a new node in the final graph. //it is the intersection of the triangle with the segment - void add_new_node(halfedge_descriptor edge_1, face_descriptor face_2) - { - add_new_node( - compute_triangle_segment_intersection_point(edge_1, face_2, ek, tm1, tm2, vpm1, vpm2) - ); - } - void add_new_node(halfedge_descriptor h_a, face_descriptor f_b, const TriangleMesh& tm_a, @@ -282,9 +234,19 @@ public: const VertexPointMap vpm_a, const VertexPointMap& vpm_b) { - add_new_node( - compute_triangle_segment_intersection_point(h_a, f_b, ek, tm_a, tm_b, vpm_a, vpm_b) - ); + halfedge_descriptor h_b = halfedge(f_b, tm_b); + add_new_node( + typename Exact_kernel::Construct_plane_line_intersection_point_3()( + to_exact( get(vpm_b, source(h_b,tm_b)) ), + to_exact( get(vpm_b, target(h_b,tm_b)) ), + to_exact( get(vpm_b, target(next(h_b,tm_b),tm_b)) ), + to_exact( get(vpm_a, source(h_a,tm_a)) ), + to_exact( get(vpm_a, target(h_a,tm_a)) ) ) ); + } + + void add_new_node(halfedge_descriptor edge_1, face_descriptor face_2) + { + add_new_node(edge_1, face_2, tm1, tm2, vpm1, vpm2); } //the point is an input @@ -340,13 +302,6 @@ public: //add a new node in the final graph. //it is the intersection of the triangle with the segment - void add_new_node(halfedge_descriptor edge_1, face_descriptor face_2) - { - add_new_node( - compute_triangle_segment_intersection_point(edge_1, face_2, k, tm1, tm2, vpm1, vpm2) - ); - } - void add_new_node(halfedge_descriptor h_a, face_descriptor f_b, const TriangleMesh& tm_a, @@ -354,11 +309,23 @@ public: const VertexPointMap vpm_a, const VertexPointMap& vpm_b) { - add_new_node( - compute_triangle_segment_intersection_point(h_a, f_b, k, tm_a, tm_b, vpm_a, vpm_b) - ); + halfedge_descriptor h_b=halfedge(f_b,tm_b); + + add_new_node( + typename Exact_kernel::Construct_plane_line_intersection_point_3()( + get(vpm_b, source(h_b,tm_b)), + get(vpm_b, target(h_b,tm_b)), + get(vpm_b, target(next(h_b,tm_b),tm_b)), + get(vpm_a, source(h_a,tm_a)), + get(vpm_a, target(h_a,tm_a)) ) ); } + void add_new_node(halfedge_descriptor edge_1, face_descriptor face_2) + { + add_new_node(edge_1, face_2, tm1, tm2, vpm1, vpm2); + } + + void add_new_node(const Point_3& p) { nodes.push_back(p); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_of_coplanar_triangles_3.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_of_coplanar_triangles_3.h index 70d2a5f1e57..400255022b5 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_of_coplanar_triangles_3.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_of_coplanar_triangles_3.h @@ -23,7 +23,6 @@ #include #include -#include #include #include @@ -38,14 +37,12 @@ struct Intersect_coplanar_faces_3{ typedef typename boost::property_traits::value_type Point; typedef typename CGAL::Kernel_traits::Kernel Input_kernel; typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_kernel; - typedef CGAL::Cartesian_converter Converter; typedef boost::graph_traits GT; typedef typename GT::halfedge_descriptor halfedge_descriptor; typedef Coplanar_intersection Inter_pt_info; // data members - Converter converter; const TriangleMesh &tm1, &tm2; const VertexPointMap &vpm1, &vpm2; // constructor @@ -56,6 +53,12 @@ struct Intersect_coplanar_faces_3{ : tm1(tm1_), tm2(tm2_), vpm1(vpm1_), vpm2(vpm2_) {} + typename Exact_kernel::Point_3 + to_exact(const Point& p) + { + return typename Exact_kernel::Point_3(p.x(), p.y(), p.z()); + } + // function construction Inter_pt_info objects //build the intersection point as the target vertex of h1 in the face of h2 Inter_pt_info operator()(halfedge_descriptor h1,halfedge_descriptor h2) @@ -65,7 +68,7 @@ struct Intersect_coplanar_faces_3{ res.type_2=ON_FACE; res.info_1=h1, res.info_2=h2; - res.point=converter(get(vpm1,target(h1,tm1))); + res.point=to_exact(get(vpm1,target(h1,tm1))); return res; } @@ -120,11 +123,11 @@ struct Intersect_coplanar_faces_3{ //this is used to select the correct endpoint of the edge of the second facet typename Exact_kernel::Collinear_3 is_collinear = Exact_kernel().collinear_3_object(); - if ( !is_collinear(ipt_prev.point,ipt_curr.point,converter(get(vpm2,target(res.info_2,tm2)) ) ) ){ + if ( !is_collinear(ipt_prev.point,ipt_curr.point,to_exact(get(vpm2,target(res.info_2,tm2)) ) ) ){ res.info_2=prev(res.info_2,tm2); - CGAL_assertion( is_collinear(ipt_prev.point,ipt_curr.point,converter(get(vpm2,target(res.info_2,tm2))) ) ); + CGAL_assertion( is_collinear(ipt_prev.point,ipt_curr.point,to_exact(get(vpm2,target(res.info_2,tm2))) ) ); } - res.point = converter( get(vpm2, target(res.info_2,tm2)) ); + res.point = to_exact( get(vpm2, target(res.info_2,tm2)) ); return res; } } @@ -138,38 +141,28 @@ struct Intersect_coplanar_faces_3{ typename Exact_kernel::Collinear_3 is_collinear = Exact_kernel().collinear_3_object(); if ( is_collinear(ipt_prev.point, ipt_curr.point, - converter(get(vpm2, source(res.info_2,tm2))) ) ) + to_exact(get(vpm2, source(res.info_2,tm2))) ) ) { res.info_2=prev(res.info_2,tm2); res.type_2=ON_VERTEX; - res.point = converter( get(vpm2, target(res.info_2,tm2)) ); + res.point = to_exact( get(vpm2, target(res.info_2,tm2)) ); return res; } if ( is_collinear(ipt_prev.point, ipt_curr.point, - converter(get(vpm2, target(res.info_2,tm2)) ) ) ) + to_exact(get(vpm2, target(res.info_2,tm2)) ) ) ) { res.type_2=ON_VERTEX; - res.point = converter( get(vpm2, target(res.info_2,tm2)) ); + res.point = to_exact( get(vpm2, target(res.info_2,tm2)) ); return res; } } //handle regular intersection of two edges - typedef typename Exact_kernel::Line_3 Line_3; - typename Exact_kernel::Construct_line_3 line_3=Exact_kernel().construct_line_3_object(); - Line_3 l1=line_3(converter(get(vpm2, target(res.info_2,tm2))), - converter(get(vpm2, source(res.info_2,tm2)))); - Line_3 l2=line_3(ipt_prev.point,ipt_curr.point); - - typename cpp11::result_of::type - inter_res=Exact_kernel().intersect_3_object()(l1,l2); - CGAL_assertion(inter_res!=boost::none); - const typename Exact_kernel::Point_3* ptptr = - boost::get(&(*inter_res)); - CGAL_assertion(ptptr!=NULL); - res.point=*ptptr; - + typename Exact_kernel::Construct_line_line_intersection_point_3 intersect; + res.point = intersect(to_exact(get(vpm2, target(res.info_2,tm2))), + to_exact(get(vpm2, source(res.info_2,tm2))), + ipt_prev.point, ipt_curr.point ); return res; } @@ -180,9 +173,9 @@ struct Intersect_coplanar_faces_3{ typename Exact_kernel::Coplanar_orientation_3 orient= Exact_kernel().coplanar_orientation_3_object(); - Orientation res = orient(converter(get(vpm2,source(h2,tm2))), - converter(get(vpm2,target(h2,tm2))), - converter(get(vpm2,target(next(h2,tm2),tm2))), + Orientation res = orient(to_exact(get(vpm2,source(h2,tm2))), + to_exact(get(vpm2,target(h2,tm2))), + to_exact(get(vpm2,target(next(h2,tm2),tm2))), ipt.point); if ( (ipt.type_1==ON_VERTEX || ipt.type_1==ON_EDGE) && res==COLLINEAR){