update doc + apply changes to the constrained version

This commit is contained in:
Sébastien Loriot 2025-11-06 19:40:48 +01:00
parent 25005a97d8
commit 3c7d507530
1 changed files with 41 additions and 28 deletions

View File

@ -1543,10 +1543,10 @@ does_satisfy_link_condition(typename boost::graph_traits<Graph>::edge_descriptor
*
* After the collapse of edge `e` the following holds:
* - The edge `e` is no longer in `g`.
* - The faces incident to edge `e` are no longer in `g`.
* - The triangle faces incident to edge `e` are no longer in `g`.
* - `v0` is no longer in `g`.
* - If `h` is not a border halfedge, `p_h` is no longer in `g` and is replaced by `o_n_h`.
* - If the opposite of `h` is not a border halfedge, `p_o_h` is no longer in `g` and is replaced by `o_n_o_h`.
* - If `h` is part of a triangle face, `p_h` is no longer in `g` and is replaced by `o_n_h`.
* - If the opposite of `h` is part of a triangle face, `p_o_h` is no longer in `g` and is replaced by `o_n_o_h`.
* - The halfedges kept in `g` that had `v0` as target and source now have `v1` as target and source, respectively.
* - No other incidence information is changed in `g`.
*
@ -1658,7 +1658,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
* collapses an edge in a graph having non-collapsable edges.
*
* Let `h` be the halfedge of `e`, and let `v0` and `v1` be the source and target vertices of `h`.
* Collapses the edge `e` replacing it with `v1`, as described in the paragraph above
* Collapses the edge `e` replacing it with `v1`, as described in the other overload
* and guarantees that an edge `e2`, for which `get(edge_is_constrained_map, e2)==true`,
* is not removed after the collapse.
*
@ -1668,14 +1668,14 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
*
* \returns vertex `v1`.
* \pre This function requires `g` to be an oriented 2-manifold with or without boundaries.
* Furthermore, the edge `v0v1` must satisfy the link condition, which guarantees that the surface mesh is also 2-manifold after the edge collapse.
* \pre `get(edge_is_constrained_map, v0v1)==false`.
* Furthermore, the edge `e` must satisfy the link condition, which guarantees that the surface mesh is also 2-manifold after the edge collapse.
* \pre `get(edge_is_constrained_map, e)==false`.
* \pre `v0` and `v1` are not both incident to a constrained edge.
*/
template<typename Graph, typename EdgeIsConstrainedMap>
typename boost::graph_traits<Graph>::vertex_descriptor
collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
Graph& g,
EdgeIsConstrainedMap Edge_is_constrained_map)
{
@ -1683,11 +1683,11 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
typedef typename Traits::vertex_descriptor vertex_descriptor;
typedef typename Traits::halfedge_descriptor halfedge_descriptor;
CGAL_precondition(is_valid_edge_descriptor(v0v1, g));
CGAL_precondition(does_satisfy_link_condition(v0v1,g));
CGAL_precondition(!get(Edge_is_constrained_map, v0v1));
CGAL_precondition(is_valid_edge_descriptor(e, g));
CGAL_precondition(does_satisfy_link_condition(e,g));
CGAL_precondition(!get(Edge_is_constrained_map, e));
halfedge_descriptor pq = halfedge(v0v1,g);
halfedge_descriptor pq = halfedge(e,g);
halfedge_descriptor qp = opposite(pq,g);
halfedge_descriptor pt = opposite(prev(pq,g),g);
@ -1697,6 +1697,8 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
bool lTopFaceExists = ! is_border(pq,g) ;
bool lBottomFaceExists = ! is_border(qp,g) ;
bool lTopIsTriangle = lTopFaceExists && is_triangle(pq,g);
bool lBottomIsTriangle = lBottomFaceExists && is_triangle(qp,g);
vertex_descriptor q = target(pq,g);
vertex_descriptor p = source(pq,g);
@ -1707,7 +1709,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
// If the top facet exists, we need to choose one out of the two edges which one disappears:
// p-t if it is not constrained and t-q otherwise
if ( lTopFaceExists )
if ( lTopIsTriangle )
{
if ( !get(Edge_is_constrained_map,edge(pt,g)) )
{
@ -1721,7 +1723,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
// If the bottom facet exists, we need to choose one out of the two edges which one disappears:
// q-b if it is not constrained and b-p otherwise
if ( lBottomFaceExists )
if ( lBottomIsTriangle )
{
if ( !get(Edge_is_constrained_map,edge(qb,g)) )
{
@ -1732,7 +1734,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
}
}
if (lTopFaceExists && lBottomFaceExists)
if (lTopIsTriangle && lBottomIsTriangle)
{
if ( face(edges_to_erase[0],g) == face(edges_to_erase[1],g)
&& (! is_border(edges_to_erase[0],g)) )
@ -1779,7 +1781,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
}
else
{
if (lTopFaceExists)
if (lTopIsTriangle)
{
if (!(is_border(edges_to_erase[0],g))){
join_face(edges_to_erase[0],g);
@ -1794,21 +1796,32 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
remove_face(opposite(edges_to_erase[0],g),g);
return q;
}
if (! (is_border(edges_to_erase[0],g))){
// q will be removed, swap it with p
internal::swap_vertices(p, q, g);
join_face(edges_to_erase[0],g);
join_vertex(qp,g);
return q;
}
if(!is_border(opposite(next(qp,g),g),g))
else
{
// q will be removed, swap it with p
internal::swap_vertices(p, q, g);
if (lBottomIsTriangle)
{
if (! (is_border(edges_to_erase[0],g))){
// q will be removed, swap it with p
internal::swap_vertices(p, q, g);
join_face(edges_to_erase[0],g);
join_vertex(qp,g);
CGAL_assertion(source(qp,g)==p);
return q;
}
if(!is_border(opposite(next(qp,g),g),g))
{
// q will be removed, swap it with p
internal::swap_vertices(p, q, g);
}
remove_face(opposite(edges_to_erase[0],g),g);
return q;
}
else
{
join_vertex(pq,g);
return q;
}
}
remove_face(opposite(edges_to_erase[0],g),g);
return q;
}
}