diff --git a/BGL/include/CGAL/boost/graph/Euler_operations.h b/BGL/include/CGAL/boost/graph/Euler_operations.h index f8c79165bc5..4ca35144f8a 100644 --- a/BGL/include/CGAL/boost/graph/Euler_operations.h +++ b/BGL/include/CGAL/boost/graph/Euler_operations.h @@ -12,10 +12,6 @@ #ifndef CGAL_EULER_OPERATIONS_H #define CGAL_EULER_OPERATIONS_H -#include -#include -#include - #include #include @@ -27,6 +23,10 @@ #include +#include +#include +#include + namespace CGAL { /// \cond SKIP_IN_MANUAL @@ -1866,10 +1866,72 @@ bool satisfies_link_condition(typename boost::graph_traits::edge_descript } /// \endcond #endif + +/// removes the target vertex of `h`, merging its incident edges into a single edge. +/// \pre `degree(target(h, g), g) == 2`. +/// \pre there is no pre-existing edge between source(h, g) and target(next(h, g), g) +template +typename boost::graph_traits::halfedge_descriptor +remove_degree_2_vertex(const typename boost::graph_traits::halfedge_descriptor h, + Graph& g) +{ + typedef boost::graph_traits Traits; + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::halfedge_descriptor halfedge_descriptor; + typedef typename Traits::face_descriptor face_descriptor; + + CGAL_precondition(degree(target(h, g), g) == 2); + + vertex_descriptor v = target(h, g); + halfedge_descriptor h1 = h; + halfedge_descriptor h2 = opposite(next(h1, g), g); + + if(is_border(h1, g)) + std::swap(h1, h2); + + vertex_descriptor v1 = source(h1, g); + vertex_descriptor v2 = source(h2, g); + + bool exists; + halfedge_descriptor huv; + std::tie(huv, exists) = halfedge(v1, v2, g); + if(exists) + return boost::graph_traits::null_halfedge(); + + if(is_border(h2, g)) + { + CGAL_assertion(!is_border(h1, g)); + + halfedge_descriptor oh1 = opposite(h1, g); + halfedge_descriptor nnh1 = next(next(h1, g), g); + halfedge_descriptor ph2 = prev(h2, g); + face_descriptor f1 = face(h1, g); + + set_target(h1, v2, g); + set_halfedge(v2, ph2, g); + set_next(h1, nnh1, g); + set_next(ph2, oh1, g); + set_halfedge(f1, h1, g); // in case it was nh1 + + remove_edge(edge(h2, g), g); + remove_vertex(v, g); + + return h1; + } + else + { + CGAL_assertion(!is_border(h1, g) && !is_border(h2, g)); + + halfedge_descriptor ph1 = prev(h1, g); + halfedge_descriptor ph2 = prev(h2, g); + Euler::remove_center_vertex(h, g); + return Euler::split_face(ph1, ph2, g); + } +} + /// @} } // namespace Euler - } // namespace CGAL #endif /* CGAL_EULER_OPERATIONS_H */