From e2a80611ce629737f3ff54958ae27c58f36b2c3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 24 Feb 2021 16:52:16 +0100 Subject: [PATCH 1/5] complete the visitor for edge creation/copies --- .../Concepts/PMPCorefinementVisitor.h | 31 +++++++++-- .../internal/Corefinement/face_graph_utils.h | 53 +++++++++++++++---- 2 files changed, 68 insertions(+), 16 deletions(-) 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..3dcd162f0de 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPCorefinementVisitor.h +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPCorefinementVisitor.h @@ -33,28 +33,49 @@ typedef unspecified_type halfedge_descriptor; 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 after edge is 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. + 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 6c85bd8d8da..1e284c670d9 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 @@ -216,18 +216,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 /* @@ -311,6 +327,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(); @@ -610,7 +627,8 @@ template + class IntersectionEdgeMap, + class UserVisitor> void import_polyline( PolygonMesh& output, typename boost::graph_traits::halfedge_descriptor h1, @@ -627,7 +645,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; @@ -687,6 +706,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, @@ -1086,7 +1112,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) @@ -1135,13 +1162,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; @@ -1197,7 +1226,9 @@ void disconnect_patches( for(std::size_t k=0; k Date: Wed, 24 Feb 2021 16:57:21 +0100 Subject: [PATCH 2/5] update changes --- Installation/CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index ed91c406088..eb9992c4696 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. From c0a90c101b546d8fe3502afd1a4cab169e31d10b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 24 Feb 2021 17:05:58 +0100 Subject: [PATCH 3/5] doc update + missing renaming --- .../Polygon_mesh_processing/Concepts/PMPCorefinementVisitor.h | 1 + .../internal/Corefinement/face_graph_utils.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) 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 3dcd162f0de..eddb57b7bb2 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPCorefinementVisitor.h +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPCorefinementVisitor.h @@ -74,6 +74,7 @@ typedef unspecified_type halfedge_descriptor; 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 1e284c670d9..f221e09efc8 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 @@ -718,7 +718,7 @@ void import_polyline( h1 = next_marked_halfedge_around_target_vertex(prev1, pm1, intersection_edges1); h2 = next_marked_halfedge_around_target_vertex(prev2, pm2, intersection_edges2); - user_visitor.edge_copy(h1, pm1, h2, pm2, h_out, output); + user_visitor.intersection_edge_copy(h1, pm1, h2, pm2, h_out, output); //if this is the final segment, only create a target vertex if it does not exist if (i+1!=nb_segments) From 2864f62ade7c81fdea871b333691083bfe686473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 1 Mar 2021 19:47:21 +0100 Subject: [PATCH 4/5] fixes after review --- .../Concepts/PMPCorefinementVisitor.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 eddb57b7bb2..b6f59c84eb2 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPCorefinementVisitor.h +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPCorefinementVisitor.h @@ -45,7 +45,7 @@ typedef unspecified_type halfedge_descriptor; 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 after edge is added to triangulate a face. The face triangulated is `f_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); /// @} @@ -59,7 +59,7 @@ typedef unspecified_type halfedge_descriptor; /// 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, 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 + /// 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. @@ -72,7 +72,7 @@ typedef unspecified_type halfedge_descriptor; /// (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` + /// 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, From 909b3a15f4a2df9cde7c89cfe229a3a044e7ec73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 1 Mar 2021 20:02:07 +0100 Subject: [PATCH 5/5] missing dots --- .../Concepts/PMPCorefinementVisitor.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 b6f59c84eb2..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,9 +24,9 @@ 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. @@ -66,10 +66,10 @@ typedef unspecified_type halfedge_descriptor; 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) + /// (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) + /// (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`,