CGAL remove_face source code analysis

来源:互联网 发布:青岛知行国际要交费吗 编辑:程序博客网 时间:2024/05/20 04:13


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));

this line ensure the halfedge h is not a border, or the incident face of h are gonna be null_face.


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));      }

set_vertex_halfedge line sets the incident halfedge of vertex B to CB

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);    }

first, it removes the vertex D, after that, it removes the edge BD. 

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);      }

first set the incident halfedge of vertex  A to BA, followed by setting the next halfedge of CA to be AB, then remove edge DA

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.



0 0