mirror of https://github.com/CGAL/cgal
Fix Face_filtered_graph::is_selection_valid() (master)
This commit is contained in:
parent
c8a3fdaff6
commit
ccf98605ab
|
|
@ -463,64 +463,57 @@ struct Face_filtered_graph
|
||||||
|
|
||||||
/// returns `true` if around any vertex of a selected face,
|
/// returns `true` if around any vertex of a selected face,
|
||||||
/// there is at most one connected set of selected faces.
|
/// there is at most one connected set of selected faces.
|
||||||
bool is_selection_valid()
|
bool is_selection_valid() const
|
||||||
{
|
{
|
||||||
for(vertex_descriptor vd : vertices(*this) )
|
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
||||||
{
|
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
|
||||||
face_descriptor first_selected = boost::graph_traits<Graph>::null_face();
|
|
||||||
bool first_unselected_found(false),
|
|
||||||
second_unselected_found(false);
|
|
||||||
|
|
||||||
//find an unselected face, then find the first selected face.
|
// Non-manifoldness can appear either:
|
||||||
//Find another unselected face, the next selected face must be the first;
|
// - if 'pm' is pinched at a vertex. While traversing the incoming halfedges at this vertex,
|
||||||
//else this is not valid.
|
// we will meet strictly more than one border halfedge.
|
||||||
halfedge_descriptor hd = halfedge(vd, _graph);
|
// - if there are multiple umbrellas around a vertex. In that case, we will find a non-visited
|
||||||
face_descriptor first_tested = boost::graph_traits<Graph>::null_face();
|
// halfedge that has for target a vertex that is already visited.
|
||||||
while(1) //will break if valid, return false if not valid
|
|
||||||
{
|
|
||||||
face_descriptor fd = face(hd, _graph);
|
|
||||||
|
|
||||||
if(first_tested == boost::graph_traits<Graph>::null_face())
|
boost::unordered_set<vertex_descriptor> vertices_visited;
|
||||||
first_tested = fd;
|
boost::unordered_set<halfedge_descriptor> halfedges_handled;
|
||||||
else if(fd == first_tested )
|
|
||||||
|
for(halfedge_descriptor hd : halfedges(*this))
|
||||||
{
|
{
|
||||||
//if there is no unselected face, break
|
CGAL_assertion(is_in_cc(hd));
|
||||||
if(selected_faces[get(fimap, fd)] && !first_unselected_found)
|
|
||||||
break;
|
if(!halfedges_handled.insert(hd).second) // already treated this halfedge
|
||||||
//if there is no selected face, break
|
continue;
|
||||||
else if(!selected_faces[get(fimap, fd)] &&
|
|
||||||
first_selected == boost::graph_traits<Graph>::null_face())
|
vertex_descriptor vd = target(hd, *this);
|
||||||
break;
|
CGAL_assertion(is_in_cc(vd));
|
||||||
|
|
||||||
|
// Check if we have already met this vertex before (necessarily in a different umbrella
|
||||||
|
// since we have never treated the halfedge 'hd')
|
||||||
|
if(!vertices_visited.insert(vd).second)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::size_t border_halfedge_counter = 0;
|
||||||
|
|
||||||
|
// Can't simply call halfedges_around_target(vd, *this) because 'halfedge(vd)' is not necessarily 'hd'
|
||||||
|
halfedge_descriptor ihd = hd;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
halfedges_handled.insert(ihd);
|
||||||
|
if(is_border(ihd, *this))
|
||||||
|
++border_halfedge_counter;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ihd = prev(opposite(ihd, _graph), _graph);
|
||||||
}
|
}
|
||||||
|
while(!is_in_cc(ihd) && ihd != hd);
|
||||||
if(fd != boost::graph_traits<Graph>::null_face())
|
|
||||||
{
|
|
||||||
if(selected_faces[get(fimap, fd)])
|
|
||||||
{
|
|
||||||
if(first_unselected_found &&
|
|
||||||
first_selected == boost::graph_traits<Graph>::null_face())
|
|
||||||
{
|
|
||||||
first_selected = fd;
|
|
||||||
}
|
}
|
||||||
else if(second_unselected_found)
|
while(ihd != hd);
|
||||||
{
|
|
||||||
if(fd == first_selected)
|
if(border_halfedge_counter > 1)
|
||||||
break;
|
|
||||||
else
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(first_selected == boost::graph_traits<Graph>::null_face())
|
|
||||||
first_unselected_found = true;
|
|
||||||
else
|
|
||||||
second_unselected_found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hd = next(opposite(hd, _graph), _graph);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue