From 658db0e840b38a39f20f06c93a53dc58ef0cd106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 9 Dec 2024 19:02:18 +0100 Subject: [PATCH] custom output for the slicer --- .../Axis_parallel_plane_traits.h | 2 + .../include/CGAL/Polygon_mesh_slicer.h | 95 ++++++++++++------- 2 files changed, 63 insertions(+), 34 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Polygon_mesh_slicer/Axis_parallel_plane_traits.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Polygon_mesh_slicer/Axis_parallel_plane_traits.h index 99483e93abc..6ac7fd22eb4 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Polygon_mesh_slicer/Axis_parallel_plane_traits.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Polygon_mesh_slicer/Axis_parallel_plane_traits.h @@ -37,7 +37,9 @@ class Axis_parallel_plane_traits const FT m_value; // indicates the value of the constant coordinate public: + typedef typename Traits::Segment_3 Segment_3; typedef typename Traits::Plane_3 Plane_3; + typedef typename Traits::Point_3 Point_3; Axis_parallel_plane_traits(int cst_coord, FT value, const Traits& traits) : m_traits(traits) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_slicer.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_slicer.h index 2edb5a70391..f6ad1322b6d 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_slicer.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_slicer.h @@ -36,6 +36,41 @@ namespace CGAL { + +template +struct Default_output_functor +{ + Default_output_functor(TriangleMesh& tmesh, VertexPointMap vpm, const typename Traits::Plane_3& plane, const Traits& traits) + : m_tmesh(tmesh) + , m_vpm(vpm) + , m_plane(plane) + , m_intersect_3( traits.intersect_3_object() ) + {} + + typedef typename Traits::Point_3 value_type; + TriangleMesh& m_tmesh; + VertexPointMap m_vpm; + const typename Traits::Plane_3& m_plane; + typename Traits::Intersect_3 m_intersect_3; + + value_type operator()(typename boost::graph_traits::vertex_descriptor v) const + { + return get(m_vpm, v); + } + + value_type operator()(typename boost::graph_traits::edge_descriptor ed) const + { + typename Traits::Segment_3 s( + get(m_vpm, source(ed, m_tmesh)), + get(m_vpm,target(ed, m_tmesh)) + ); + const auto inter = m_intersect_3(m_plane, s); + CGAL_assertion(inter.has_value()); + const value_type* pt_ptr = std::get_if(&(*inter)); + return *pt_ptr; + } +}; + /// \ingroup PkgPolygonMeshProcessingRef /// Function object that computes the intersection of a plane with /// a triangulated surface mesh. @@ -74,17 +109,10 @@ namespace CGAL { /// \todo `_object()` functions must also be provided template::type, - class AABBTree = AABB_tree< - AABB_traits_3::type >, - Default, - VertexPointMap>>>>, - bool UseParallelPlaneOptimization=true> + class VertexPointMap_ = Default, + class AABBTree_ = Default, + bool UseParallelPlaneOptimization=true, + template class OutputFunctor = Default_output_functor> class Polygon_mesh_slicer { /// Polygon_mesh typedefs @@ -100,6 +128,15 @@ class Polygon_mesh_slicer typedef typename Traits::Point_3 Point_3; typedef typename Traits::FT FT; + +// AABB-tree type + typedef typename Default::Get::type>::type VertexPointMap; + typedef typename Default::Get > > >::type AABBTree; + /// typedefs for internal graph to get connectivity of the polylines typedef std::variant AL_vertex_info; typedef boost::adjacency_list < @@ -111,6 +148,9 @@ class Polygon_mesh_slicer typedef std::pair AL_vertex_pair; typedef std::map Vertices_map; typedef std::pair Vertex_pair; + + + /// Traversal traits typedef Polygon_mesh_slicer_::Traversal_traits< AL_graph, @@ -142,14 +182,15 @@ class Polygon_mesh_slicer typedef std::map< halfedge_descriptor, AL_vertex_pair, Compare_face > AL_edge_map; - template + template struct Polyline_visitor{ AL_graph& al_graph; TriangleMesh& m_tmesh; const Plane_3& m_plane; VertexPointMap m_vpmap; - typename Traits_::Intersect_3 intersect_3; OutputIterator out; + Output_functor output_functor; + std::pair nodes_for_orient; Polyline_visitor( TriangleMesh& tmesh, @@ -162,11 +203,11 @@ class Polygon_mesh_slicer , m_tmesh(tmesh) , m_plane(plane) , m_vpmap(vpmap) - , intersect_3( traits.intersect_3_object() ) , out(out) + , output_functor(tmesh, vpmap, plane, traits) {} - std::vector< Point_3 > current_poly; + std::vector< typename Output_functor::value_type > current_poly; // returns true iff the polyline is not correctly oriented // Using the first edge is oriented such that the normal induced by the face @@ -263,23 +304,7 @@ class Polygon_mesh_slicer if (current_poly.size()==1) nodes_for_orient.second=node_id; - AL_vertex_info v = al_graph[node_id]; - if (const vertex_descriptor* vd_ptr = std::get_if(&v) ) - { - current_poly.push_back( get(m_vpmap, *vd_ptr) ); - } - else - { - edge_descriptor ed = std::get(v); - Segment_3 s( - get(m_vpmap, source(ed, m_tmesh)), - get(m_vpmap,target(ed, m_tmesh)) - ); - const auto inter = intersect_3(m_plane, s); - CGAL_assertion(inter != std::nullopt); - const Point_3* pt_ptr = std::get_if(&(*inter)); - current_poly.push_back( *pt_ptr ); - } + current_poly.push_back( std::visit(output_functor, al_graph[node_id]) ); } void end_polyline() @@ -628,16 +653,18 @@ class Polygon_mesh_slicer // putting them in the output iterator if (!UseParallelPlaneOptimization || app_info.first==-1) { - Polyline_visitor visitor(m_tmesh, al_graph, plane, m_vpmap, m_traits, out); + typedef OutputFunctor Output_functor; + Polyline_visitor visitor(m_tmesh, al_graph, plane, m_vpmap, m_traits, out); split_graph_into_polylines(al_graph, visitor); return visitor.out; } else { typedef Polygon_mesh_slicer_::Axis_parallel_plane_traits App_traits; + typedef OutputFunctor Output_functor; App_traits app_traits(app_info.first, app_info.second, m_traits); - Polyline_visitor visitor + Polyline_visitor visitor (m_tmesh, al_graph, plane, m_vpmap, app_traits, out); split_graph_into_polylines(al_graph, visitor); return visitor.out;