diff --git a/BGL/include/CGAL/boost/graph/helpers.h b/BGL/include/CGAL/boost/graph/helpers.h index f8a84fe11c2..f34e24b7687 100644 --- a/BGL/include/CGAL/boost/graph/helpers.h +++ b/BGL/include/CGAL/boost/graph/helpers.h @@ -1415,6 +1415,83 @@ void swap_vertices( set_halfedge(q, hp, g); } +template +void swap_edges( + const typename boost::graph_traits::halfedge_descriptor& h1, + const typename boost::graph_traits::halfedge_descriptor& h2, + FaceGraph& g) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + const halfedge_descriptor oh1 = opposite(h1, g), oh2 = opposite(h2, g); + + // backup vertex pointers + vertex_descriptor s1 = target(oh1, g), s2 = target(oh2, g); + vertex_descriptor t1 = target(h1, g), t2 = target(h2, g); + + // backup face pointers + face_descriptor f1 = face(h1, g), f2 = face(h2, g); + face_descriptor fo1 = face(oh1, g), fo2 = face(oh2, g); + + // backup next prev pointers + halfedge_descriptor nh1 = next(h1, g), nh2 = next(h2, g); + halfedge_descriptor ph1 = prev(h1, g), ph2 = prev(h2, g); + halfedge_descriptor noh1 = next(oh1, g), noh2 = next(oh2, g); + halfedge_descriptor poh1 = prev(oh1, g), poh2 = prev(oh2, g); + + // handle particular cases where next/prev are halfedges to be swapt + if (nh1 == oh2) nh1 = oh1; + if (nh1 == h2) nh1 = h1; + if (nh2 == oh1) nh2 = oh2; + if (nh2 == h1) nh2 = h2; + if (ph1 == oh2) ph1 = oh1; + if (ph1 == h2) ph1 = h1; + if (ph2 == oh1) ph2 = oh2; + if (ph2 == h1) ph2 = h2; + if (noh1 == oh2) noh1 = oh1; + if (noh1 == h2) noh1 = h1; + if (noh2 == oh1) noh2 = oh2; + if (noh2 == h1) noh2 = h2; + if (poh1 == oh2) poh1 = oh1; + if (poh1 == h2) poh1 = h1; + if (poh2 == oh1) poh2 = oh2; + if (poh2 == h1) poh2 = h2; + + // (1) exchange next pointers + set_next(h1, nh2, g); + set_next(h2, nh1, g); + set_next(ph1, h2, g); + set_next(ph2, h1, g); + set_next(oh1, noh2, g); + set_next(oh2, noh1, g); + set_next(poh1, oh2, g); + set_next(poh2, oh1, g); + + // (2) exchange vertex-halfedge pointers + set_target(h1, t2, g); + set_target(h2, t1, g); + set_target(oh1, s2, g); + set_target(oh2, s1, g); + if (halfedge(t1, g)==h1) set_halfedge(t1, h2, g); + if (halfedge(t2, g)==h2) set_halfedge(t2, h1, g); + if (halfedge(s1, g)==oh1) set_halfedge(s1, oh2, g); + if (halfedge(s2, g)==oh2) set_halfedge(s2, oh1, g); + + // (3) exchange face-halfedge pointers + set_face(h1, f2, g); + set_face(h2, f1, g); + set_face(oh1, fo2, g); + set_face(oh2, fo1, g); + + face_descriptor nf = boost::graph_traits::null_face(); + if (f1 != nf && halfedge(f1, g)==h1) set_halfedge(f1, h2, g); + if (f2 != nf && halfedge(f2, g)==h2) set_halfedge(f2, h1, g); + if (fo1 != nf && halfedge(fo1, g)==oh1) set_halfedge(fo1, oh2, g); + if (fo2 != nf && halfedge(fo2, g)==oh2) set_halfedge(fo2, oh1, g); +} + + } //end of internal namespace /** diff --git a/BGL/test/BGL/test_Euler_operations.cpp b/BGL/test/BGL/test_Euler_operations.cpp index cdf53ec5f4c..5099749380f 100644 --- a/BGL/test/BGL/test_Euler_operations.cpp +++ b/BGL/test/BGL/test_Euler_operations.cpp @@ -380,7 +380,27 @@ does_satisfy_link_condition() assert(CGAL::Euler::does_satisfy_link_condition(*edges(f.m).first,f.m)); } - +template +void +test_swap_edges() +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + std::size_t nbh=12; + Kernel::Point_3 pt(0,0,0); + // test all possible pairs of halfedges + for (std::size_t i=0; i void @@ -400,6 +420,7 @@ test_Euler_operations() remove_center_vertex_test(); join_split_inverse(); does_satisfy_link_condition(); + test_swap_edges(); } int main() diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h index 4dda66dda8e..acf556b71e3 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h @@ -732,7 +732,6 @@ namespace internal { halfedge_descriptor epo_p = opposite(ep_p, mesh_); halfedge_descriptor en = next(he, mesh_); halfedge_descriptor en_p = next(he_opp, mesh_); - halfedge_descriptor eno_p = opposite(en_p, mesh_); Halfedge_status s_ep_p = status(ep_p); Halfedge_status s_epo_p = status(epo_p); Halfedge_status s_ep = status(prev(he, mesh_)); @@ -755,29 +754,7 @@ namespace internal { else{ // swap edges so as to keep constained edges: // replace en_p by epo_p and ep_p by eno_p - // (1) exchange next pointer - set_next(prev(epo_p, mesh_), en_p, mesh_); - set_next(en_p, next(epo_p, mesh_), mesh_); - set_next(prev(eno_p, mesh_), ep_p, mesh_); - set_next(ep_p, next(eno_p, mesh_), mesh_); - set_next(epo_p, eno_p, mesh_); - set_next(he_opp, epo_p, mesh_); - set_next(eno_p, he_opp, mesh_); - // (2) exchange vertex-halfedge pointer - set_target(ep_p, va, mesh_); - set_target(eno_p, vb, mesh_); - set_halfedge(va, ep_p, mesh_); - set_halfedge(vb, eno_p, mesh_); - // (3) exchange face-halfedge pointer - set_face(ep_p, face(eno_p, mesh_), mesh_); - set_face(en_p, face(epo_p, mesh_), mesh_); - set_face(epo_p, face(he_opp, mesh_), mesh_); - set_face(eno_p, face(he_opp, mesh_), mesh_); - set_halfedge(face(he_opp, mesh_), he_opp, mesh_); - if (face(ep_p, mesh_) != boost::graph_traits::null_face()) - set_halfedge(face(ep_p, mesh_), ep_p, mesh_); - if (face(en_p, mesh_) != boost::graph_traits::null_face()) - set_halfedge(face(en_p, mesh_), en_p, mesh_); + ::CGAL::internal::swap_edges(en_p, epo_p, mesh_); CGAL_assertion(is_valid(mesh_)); } }