location: CGAL\boost\graph\Euler_operations.h
http://doc.cgal.org/latest/BGL/group__PkgBGLEulerOperations.html#gacfae7ff8e782da55b941e4487e86c738
/** * removes the incident face of `h` and changes all halfedges incident to the face into border halfedges * or removes them from the graph if they were already border halfedges. * * If this creates isolated vertices they get removed as well. * * \image html remove_face.svg * \image html remove_face_and_vertex.svg * * \tparam Graph must be a model of `MutableFaceGraph` * * \pre `h` is not a border halfedge * * \sa `make_hole()` for a more specialized variant. */ template< typename Graph > void remove_face(typename boost::graph_traits<Graph>::halfedge_descriptor h, Graph& g) { typedef typename boost::graph_traits<Graph> Traits; typedef typename Traits::halfedge_descriptor halfedge_descriptor; typedef typename Traits::face_descriptor face_descriptor; CGAL_precondition(! is_border(h,g)); face_descriptor f = face(h, g); halfedge_descriptor end = h; do { internal::set_border(h,g); halfedge_descriptor nh = next(h, g); bool h_border = is_border(opposite(h, g),g); bool nh_bborder = is_border(opposite(nh, g),g); if(h_border && nh_bborder && next(opposite(nh, g), g) == opposite(h, g)) { remove_vertex(target(h, g), g); if(h != end) remove_edge(edge(h, g), g); } else { if(nh_bborder) { internal::set_vertex_halfedge(opposite(next(opposite(nh, g), g), g), g); internal::remove_tip(h, g); //internal::set_constant_vertex_is_border(g, target(h, g)); } if(h_border) { internal::set_vertex_halfedge(opposite(next(h, g), g), g); internal::remove_tip(prev(opposite(h, g), g), g); //internal::set_constant_vertex_is_border(g, target(prev(opposite(h, g), g), g)); if(h != end) remove_edge(edge(h, g), g); } } h = nh; } while(h != end); remove_face(f, g); if(is_border(opposite(h, g),g)) remove_edge(edge(h, g), g); }
this function is used to remove the face f, then do some fix work.
there are four cases, let us explain one by one.
CGAL_precondition(! is_border(h,g));
1.left-upper corner
In first iteration, h_border is false, nh_bborder is true.
Then we will execute this part
if(nh_bborder) { internal::set_vertex_halfedge(opposite(next(opposite(nh, g), g), g), g); internal::remove_tip(h, g); //internal::set_constant_vertex_is_border(g, target(h, g)); }
remove_tip line sets the next halfedge of AB to be BC.
Next, we go to the second iteration.
now BD is h, DA is nh, h_border is true, nh_bborder is true, and the first condition holds, thus the first if sentence is executed:
if(h_border && nh_bborder && next(opposite(nh, g), g) == opposite(h, g)) { remove_vertex(target(h, g), g); if(h != end) remove_edge(edge(h, g), g); }
let us keep going to the third iteration.
now, h is DA, nh = AB, h_border is true, nh_bborder is false. the second if condition will be run:
if(h_border) { internal::set_vertex_halfedge(opposite(next(h, g), g), g); internal::remove_tip(prev(opposite(h, g), g), g); //internal::set_constant_vertex_is_border(g, target(prev(opposite(h, g), g), g)); if(h != end) remove_edge(edge(h, g), g); }
After all the iterations fininsing, we jump out of the while loop, then remove face f. the edge AB will be kept because its opposite halfedge is not a border edge.
2.right-upper case
Because the face f is an interior face no edges are going to be removed. In this case, the function is just to dig a hole within the graph.
3,4. the left-lower case and right-lower case have been illustrated in the website http://doc.cgal.org/latest/BGL/group__PkgBGLEulerOperations.html#gacfae7ff8e782da55b941e4487e86c738.
for the sake of time-saving, we will leave the analysis of these two cases to the readers.