From f454510de7ecffd74a720b03b9ad1076cab167e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 11 Mar 2020 10:33:40 +0100 Subject: [PATCH] if a vertex is on a border, its halfedge is not necessarily on the border --- .../CGAL/boost/graph/Euler_operations.h | 38 ++++++++++++------ BGL/test/BGL/test_Euler_operations.cpp | 39 +++++++++++++++++++ 2 files changed, 66 insertions(+), 11 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/Euler_operations.h b/BGL/include/CGAL/boost/graph/Euler_operations.h index 11dd34b1922..2e4656b691c 100644 --- a/BGL/include/CGAL/boost/graph/Euler_operations.h +++ b/BGL/include/CGAL/boost/graph/Euler_operations.h @@ -711,19 +711,35 @@ add_face(const VertexRange& vr, Graph& g) break; case 3: // both are new - if (halfedge(v, g) == boost::graph_traits::null_halfedge()) { - set_halfedge(v, outer_prev, g); - next_cache.push_back(NextCacheEntry(outer_prev, outer_next)); + // try to pick a border halfedge with v as target + halfedge_descriptor hv = halfedge(v, g); + if (hv != boost::graph_traits::null_halfedge() && !is_border(hv, g)) + { + BOOST_FOREACH(halfedge_descriptor h_around_v, halfedges_around_target(hv, g)) + if (is_border(h_around_v, g)) + { + hv = h_around_v; + break; + } + if (!is_border(hv, g)) + hv = boost::graph_traits::null_halfedge(); + } + + if (hv == boost::graph_traits::null_halfedge()) + { + set_halfedge(v, outer_prev, g); + next_cache.push_back(NextCacheEntry(outer_prev, outer_next)); + } + else + { + border_prev = hv; + border_next = next(border_prev, g); + next_cache.push_back(NextCacheEntry(border_prev, outer_next)); + next_cache.push_back(NextCacheEntry(outer_prev, border_next)); + } + break; } - else - { - border_prev = halfedge(v, g); - border_next = next(border_prev, g); - next_cache.push_back(NextCacheEntry(border_prev, outer_next)); - next_cache.push_back(NextCacheEntry(outer_prev, border_next)); - } - break; } // set inner link diff --git a/BGL/test/BGL/test_Euler_operations.cpp b/BGL/test/BGL/test_Euler_operations.cpp index 3ae73d6c38d..3f394ed85c0 100644 --- a/BGL/test/BGL/test_Euler_operations.cpp +++ b/BGL/test/BGL/test_Euler_operations.cpp @@ -402,6 +402,44 @@ test_swap_edges() } } +template +void +add_face_bug() +{ + typedef boost::graph_traits GT; + typedef typename GT::vertex_descriptor vertex_descriptor; + typedef typename GT::halfedge_descriptor halfedge_descriptor; + + T g; + + std::vector vs; + vs.push_back( add_vertex(g) ); // Kernel::Point_3(0,1,0) + vs.push_back( add_vertex(g) ); // Kernel::Point_3(4,1,0) + vs.push_back( add_vertex(g) ); // Kernel::Point_3(5,2,0) + vs.push_back( add_vertex(g) ); // Kernel::Point_3(4,0,0) + + CGAL::Euler::add_face(CGAL::make_array(vs[0], vs[1], vs[2]), g); + CGAL::Euler::add_face(CGAL::make_array(vs[1], vs[3], vs[2]), g); + + // force vertex halfedge to not be a border halfedge + BOOST_FOREACH(vertex_descriptor v, vertices(g)) + { + halfedge_descriptor h = halfedge(v, g); + if ( CGAL::is_border(h, g) ) + set_halfedge(v, prev(opposite(h, g), g), g); + assert(target(halfedge(v, g), g)==v); + } + + vs.push_back( add_vertex(g) ); // Kernel::Point_3(0,0,0) + vs.push_back( add_vertex(g) ); // Kernel::Point_3(1,0,0) + CGAL::Euler::add_face(CGAL::make_array(vs[4],vs[5],vs[0]), g); + + vs.push_back( add_vertex(g) ); // Kernel::Point_3(2,0,0) + vs.push_back( add_vertex(g) ); // Kernel::Point_3(3,0,0) + CGAL::Euler::add_face(CGAL::make_array(vs[6],vs[7],vs[1]), g); + CGAL::Euler::add_face(CGAL::make_array(vs[7],vs[3],vs[1]), g); +} + template void test_Euler_operations() @@ -421,6 +459,7 @@ test_Euler_operations() join_split_inverse(); does_satisfy_link_condition(); test_swap_edges(); + add_face_bug(); } int main()