allow to remesh a patch with boundary cycles of edges if genus is not to be preserved

This commit is contained in:
Sébastien Loriot 2021-05-06 14:32:32 +02:00
parent e7b91b92b8
commit 79057f3cdd
2 changed files with 47 additions and 25 deletions

View File

@ -1137,8 +1137,8 @@ void expand_face_selection_for_removal(const FaceRange& faces_to_be_deleted,
//todo: take non-manifold vertices into account.
template<class PolygonMesh, class FaceRange>
bool is_selection_a_topological_disk(const FaceRange& face_selection,
PolygonMesh& pm)
int euler_characteristic_of_selection(const FaceRange& face_selection,
PolygonMesh& pm)
{
typedef typename boost::graph_traits<PolygonMesh>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<PolygonMesh>::face_descriptor face_descriptor;
@ -1154,8 +1154,18 @@ bool is_selection_a_topological_disk(const FaceRange& face_selection,
sel_edges.insert(edge(h,pm));
}
}
return (sel_vertices.size() - sel_edges.size() + face_selection.size() == 1);
return static_cast<int>(sel_vertices.size())
- static_cast<int>(sel_edges.size())
+ static_cast<int>(face_selection.size());
}
template<class PolygonMesh, class FaceRange>
bool is_selection_a_topological_disk(const FaceRange& face_selection,
PolygonMesh& pm)
{
return euler_characteristic_of_selection(face_selection, pm) == 1;
}
} //end of namespace CGAL
#endif //CGAL_BOOST_GRAPH_SELECTION_H

View File

@ -1764,21 +1764,43 @@ remove_self_intersections_one_step(std::set<typename boost::graph_traits<Triangl
std::cout << " DEBUG: Trying hole-filling based approach\n";
#endif
if(!is_selection_a_topological_disk(cc_faces, tmesh))
int selection_chi = euler_characteristic_of_selection(cc_faces, tmesh);
if( selection_chi!=1 ) // not a topological disk
{
// check if the selection contains cycles of border halfedges
bool only_border_edges = true;
if (preserve_genus)
{
#ifdef CGAL_PMP_REMOVE_SELF_INTERSECTION_DEBUG
std::cout << " DEBUG: CC not handled, selection is not a topological disk (preserve_genus=true)\n";
++unsolved_self_intersections;
#endif
topology_issue = true;
continue;
}
// check if the topological issue is created by border edges
std::vector<halfedge_descriptor> mesh_non_border_hedges;
std::set<halfedge_descriptor> mesh_border_hedge;
for(halfedge_descriptor h : cc_border_hedges)
{
if(!is_border(opposite(h, tmesh), tmesh))
only_border_edges = false;
mesh_non_border_hedges.push_back(h);
else
mesh_border_hedge.insert(opposite(h, tmesh));
}
int nb_cycles = 0;
if (mesh_border_hedge.empty())
{
#ifdef CGAL_PMP_REMOVE_SELF_INTERSECTION_DEBUG
std::cout << " DEBUG: CC not handled, selection is not a topological disk (preserve_genus=false)\n";
++unsolved_self_intersections;
#endif
topology_issue = true;
continue;
}
// we look for cycles of border halfedges and update selection_chi
while(!mesh_border_hedge.empty())
{
// we must count the number of cycle of boundary edges
@ -1790,14 +1812,14 @@ remove_self_intersections_one_step(std::set<typename boost::graph_traits<Triangl
if(h == h_b)
{
// found a cycle
++nb_cycles;
selection_chi += 1;
break;
}
else
{
typename std::set<halfedge_descriptor>::iterator it = mesh_border_hedge.find(h);
if(it == mesh_border_hedge.end())
break; // not a cycle
break; // not a cycle does not count
mesh_border_hedge.erase(it);
}
@ -1805,29 +1827,19 @@ remove_self_intersections_one_step(std::set<typename boost::graph_traits<Triangl
while(true);
}
if(nb_cycles > (only_border_edges ? 1 : 0))
if(selection_chi!=1)
{
#ifdef CGAL_PMP_REMOVE_SELF_INTERSECTION_DEBUG
std::cout << " DEBUG: CC not handled due to the presence of "
<< nb_cycles << " of boundary edges\n";
++unsolved_self_intersections;
std::cout << " DEBUG: CC not handled, selection is not a topological disk even if"
<< " boundary cycles are removed: chi=" << selection_chi << "\n";
++unsolved_self_intersections;
#endif
topology_issue = true;
continue;
}
else
{
if(preserve_genus)
{
#ifdef CGAL_PMP_REMOVE_SELF_INTERSECTION_DEBUG
std::cout << " DEBUG: CC not handled because it is not a topological disk (preserve_genus=true)\n";
++unsolved_self_intersections;
#endif
all_fixed = false;
continue;
}
cc_border_hedges.swap(mesh_non_border_hedges);
// count the number of cycles of halfedges of the boundary
std::map<vertex_descriptor, vertex_descriptor> bhs;