diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index 5787fc1441b..9f489c2e1f8 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -20,6 +20,7 @@ A comprehensive list of the supported file formats is available in the Stream_su is within a polyhedral envelope around a set of triangles. It is based on the work of Bolun Wang, Teseo Schneider, Yixin Hu, Marco Attene, and Daniele Panozzo. "Exact and efficient polyhedral envelope containment check." (ACM Trans. Graph., 39-4, July 2020). +- Added more functions in the visitor of the corefinement based methods to track all edge creations. ### [Surface Mesh Simplification](https://doc.cgal.org/5.3/Manual/packages.html#PkgSurfaceMeshSimplification) - Added a filtering mechanism so that costly tests get only applied to the next candidate for the edge collapse. diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPCorefinementVisitor.h b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPCorefinementVisitor.h index cd2e6ebf2eb..450596ed64d 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPCorefinementVisitor.h +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPCorefinementVisitor.h @@ -24,37 +24,59 @@ typedef unspecified_type halfedge_descriptor; /// `before_subface_created()`/`after_subface_created()` will correspond to /// the creation of a new face of the triangulation of `f_split`. void before_subface_creations(face_descriptor f_split, Triangle_mesh& tm); - /// called when the triangulation of a face in `tm` is finished + /// called when the triangulation of a face in `tm` is finished. void after_subface_creations(Triangle_mesh& tm); - /// called before creating a new triangle face in `tm` to triangulate the face passed to `before_subface_creations()` + /// called before creating a new triangle face in `tm` to triangulate the face passed to `before_subface_creations()`. void before_subface_created(Triangle_mesh& tm); /// called after creating a new triangle face `f_new` in `tm` to triangulate the face passed to `before_subface_creations()`. /// Note that the call is placed just after a call to `add_face()` so the halfedge pointer is not set yet. void after_subface_created(face_descriptor f_new, Triangle_mesh& tm); /// @} -/// @name Functions used by corefine() when edges are split +/// @name Functions used by corefine() when edges are split or created /// @{ /// called before the edge of `h` in `tm` is split. Each subsequent call to /// `edge_split()` until the call to `after_edge_split()` will correspond to /// the split of that edge. If `edge_split(h_i, tm)` is called for `i=1` to `n`, /// `h_1`, `h_2`, ... ,`h_n`, `h` is the sequence of halfedges representing the - /// edge split (with the same initial orientation) + /// edge split (with the same initial orientation). There is only one call per edge. void before_edge_split(halfedge_descriptor h, TriangleMesh& tm); - /// called when a new split is done. The target of `hnew` is a new split vertex. + /// called when a new split is done. The target of `hnew` is a new split vertex. There is only one call per edge. void edge_split(halfedge_descriptor hnew, TriangleMesh& tm); /// called when the split of the halfedge `h` passed at the later call to `before_edge_split()` is finished. void after_edge_split(); + /// called when a new edge has been added to triangulate a face. The face triangulated is `f_split` + /// in the last call to `before_subface_creations(f_split, tm)`. There is only one call per edge. + void add_retriangulation_edge(halfedge_descriptor h, TriangleMesh& tm); /// @} /// @name Functions used by Boolean operations functions using corefinement. /// These functions are not needed if you only call `corefine()`. /// @{ /// called before importing the face `f_src` of `tm_src` in `tm_tgt` - void before_face_copy(face_descriptor f_src, Triangle_mesh& tm_src, Triangle_mesh& tm_tgt); + void before_face_copy(face_descriptor f_src, const Triangle_mesh& tm_src, Triangle_mesh& tm_tgt); /// called after importing the face `f_src` of `tm_src` in `tm_tgt`. The new face is `f_tgt`. /// Note that the call is placed just after a call to `add_face()` so the halfedge pointer is not set yet. - void after_face_copy(face_descriptor f_src, Triangle_mesh& tm_src, + void after_face_copy(face_descriptor f_src, const Triangle_mesh& tm_src, face_descriptor f_tgt, Triangle_mesh& tm_tgt); + /// called before importing the edge of `h_src` of `tm_src` in `tm_tgt`. There is one call per edge. + void before_edge_copy(halfedge_descriptor h_src/, const TriangleMesh& tm_src, TriangleMesh& tm_tgt){} + /// called after importing the edge of `h_src` of `tm_src` in `tm_tgt`. The corresponding new halfedge is `h_tgt`. + /// There is only one call per edge. + void after_edge_copy(halfedge_descriptor h_src, const TriangleMesh& tm_src, + halfedge_descriptor h_tgt, TriangleMesh& tm_tgt); + /// called before a patch boundary edge is duplicated to disconnect patches of `tm` + /// (When an in-place operation and an out-of-place are both requested). + void before_edge_duplicated(halfedge_descriptor h, TriangleMesh& tm); + /// called when the edge of `h_src` has been duplicated into `h_new` in `tm` + /// (When an in-place operation and an out-of-place are both requested). + void after_edge_duplicated(halfedge_descriptor h_src, + halfedge_descriptor h_new, TriangleMesh& tm); + /// called when an intersection edge (represented in input meshes `tm_src1` and `tm_src2` by `h_src1` and `h_src2`, + /// respectively) is imported in `tm_tgt` as `h_tgt`. There is only one call per edge. + /// (Called only when an out-of-place operation is requested) + void intersection_edge_copy(halfedge_descriptor h_src1, const TriangleMesh& tm_src1, + halfedge_descriptor h_src2, const TriangleMesh& tm_src2, + halfedge_descriptor h_tgt, TriangleMesh& tm_tgt); /// @} }; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h index e34a519869f..78986f2a3c9 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h @@ -417,18 +417,34 @@ struct Default_visitor{ typedef boost::graph_traits GT; typedef typename GT::face_descriptor face_descriptor; typedef typename GT::halfedge_descriptor halfedge_descriptor; - +// face visitor functions void before_subface_creations(face_descriptor /*f_old*/,TriangleMesh&){} void after_subface_creations(TriangleMesh&){} void before_subface_created(TriangleMesh&){} void after_subface_created(face_descriptor /*f_new*/,TriangleMesh&){} - void before_face_copy(face_descriptor /*f_old*/, TriangleMesh&, TriangleMesh&){} - void after_face_copy(face_descriptor /*f_old*/, TriangleMesh&, + void before_face_copy(face_descriptor /*f_old*/, const TriangleMesh&, TriangleMesh&){} + void after_face_copy(face_descriptor /*f_old*/, const TriangleMesh&, face_descriptor /* f_new */, TriangleMesh&){} - void before_edge_split(halfedge_descriptor /* h */, const TriangleMesh& /* tm */){} - void edge_split(halfedge_descriptor /* hnew */, const TriangleMesh& /* tm */){} +// edge visitor functions + void before_edge_split(halfedge_descriptor /* h */, TriangleMesh& /* tm */){} + void edge_split(halfedge_descriptor /* hnew */, TriangleMesh& /* tm */){} void after_edge_split(){} + void add_retriangulation_edge(halfedge_descriptor /* h */ , TriangleMesh& /* tm */) {} // edges added during split face retriangulation + + void before_edge_copy(halfedge_descriptor /*h_old*/, const TriangleMesh&, TriangleMesh&){} + void after_edge_copy(halfedge_descriptor /*h_old*/, const TriangleMesh&, + halfedge_descriptor /* f_new */, TriangleMesh&){} + + void before_edge_duplicated(halfedge_descriptor /*h_old*/, TriangleMesh&){} // called before a patch border edge is duplicated + void after_edge_duplicated(halfedge_descriptor /*h_old*/, + halfedge_descriptor /* f_new */, TriangleMesh&){} // called after a patch border edge is duplicated + + void intersection_edge_copy(halfedge_descriptor /* h_old1 */, const TriangleMesh& /* tm1 */, + halfedge_descriptor /* h_old2 */, const TriangleMesh& /* tm2 */, + halfedge_descriptor /* h_new */, TriangleMesh& /* tm_new */){} + + // calls commented in the code and probably incomplete due to the migration // see NODE_VISITOR_TAG /* @@ -512,6 +528,7 @@ triangulate_a_face( !cdt.is_infinite(cdt.mirror_vertex(it->first,it->second)) ) { edge_descriptor e=add_edge(tm); + user_visitor.add_retriangulation_edge(halfedge(e, tm), tm); halfedge_descriptor h=halfedge(e,tm), h_opp=opposite(h,tm); Node_id i0=cdt_v0->info(), i1=cdt_v1->info(); @@ -809,7 +826,8 @@ template + class IntersectionEdgeMap, + class UserVisitor> void import_polyline( PolygonMesh& output, typename boost::graph_traits::halfedge_descriptor h1, @@ -826,7 +844,8 @@ void import_polyline( const VertexPointMap2& /*vpm2*/, const VertexPointMapOut& vpm_out, std::vector - ::edge_descriptor>& output_shared_edges) + ::edge_descriptor>& output_shared_edges, + UserVisitor& user_visitor) { typedef boost::graph_traits GT; typedef typename GT::halfedge_descriptor halfedge_descriptor; @@ -886,6 +905,8 @@ void import_polyline( pm2_to_output_edges.insert( std::make_pair(edge(prev2, pm2), edge(prev_out, output)) ); + user_visitor.intersection_edge_copy(prev1, pm1, prev2, pm2, h_out, output); + src=tgt; for (std::size_t i=1; i(ed, new_edge, @@ -1285,7 +1311,8 @@ void fill_new_triangle_mesh( tm1_to_output_vertices, intersection_edges1, intersection_edges2, vpm1, vpm2, vpm_out, - output_shared_edges); + output_shared_edges, + user_visitor); //import patches of tm1 if (reverse_orientation_of_patches_from_tm1) @@ -1334,13 +1361,15 @@ void fill_new_triangle_mesh( template + class EdgeMap, + class UserVisitor> void disconnect_patches( TriangleMesh& tm1, const boost::dynamic_bitset<>& patches_to_remove, PatchContainer& patches_of_tm1, const EdgeMap& tm1_edge_to_tm2_edge, //map intersection edges of tm1 to the equivalent in tm2 - EdgeMap& new_tm1_edge_to_tm2_edge) //map the new intersection edges of tm1 to the equivalent in tm2 + EdgeMap& new_tm1_edge_to_tm2_edge, //map the new intersection edges of tm1 to the equivalent in tm2 + UserVisitor& user_visitor) { typedef boost::graph_traits GT; typedef typename GT::halfedge_descriptor halfedge_descriptor; @@ -1396,7 +1425,9 @@ void disconnect_patches( for(std::size_t k=0; k