move code to swap edges in a function

This commit is contained in:
Sébastien Loriot 2018-05-29 15:36:15 +02:00
parent 1f1c97050b
commit 460f49d64f
3 changed files with 100 additions and 25 deletions

View File

@ -1415,6 +1415,83 @@ void swap_vertices(
set_halfedge(q, hp, g);
}
template <class FaceGraph>
void swap_edges(
const typename boost::graph_traits<FaceGraph>::halfedge_descriptor& h1,
const typename boost::graph_traits<FaceGraph>::halfedge_descriptor& h2,
FaceGraph& g)
{
typedef typename boost::graph_traits<FaceGraph>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<FaceGraph>::face_descriptor face_descriptor;
typedef typename boost::graph_traits<FaceGraph>::vertex_descriptor vertex_descriptor;
const halfedge_descriptor oh1 = opposite(h1, g), oh2 = opposite(h2, g);
// backup vertex pointers
vertex_descriptor s1 = target(oh1, g), s2 = target(oh2, g);
vertex_descriptor t1 = target(h1, g), t2 = target(h2, g);
// backup face pointers
face_descriptor f1 = face(h1, g), f2 = face(h2, g);
face_descriptor fo1 = face(oh1, g), fo2 = face(oh2, g);
// backup next prev pointers
halfedge_descriptor nh1 = next(h1, g), nh2 = next(h2, g);
halfedge_descriptor ph1 = prev(h1, g), ph2 = prev(h2, g);
halfedge_descriptor noh1 = next(oh1, g), noh2 = next(oh2, g);
halfedge_descriptor poh1 = prev(oh1, g), poh2 = prev(oh2, g);
// handle particular cases where next/prev are halfedges to be swapt
if (nh1 == oh2) nh1 = oh1;
if (nh1 == h2) nh1 = h1;
if (nh2 == oh1) nh2 = oh2;
if (nh2 == h1) nh2 = h2;
if (ph1 == oh2) ph1 = oh1;
if (ph1 == h2) ph1 = h1;
if (ph2 == oh1) ph2 = oh2;
if (ph2 == h1) ph2 = h2;
if (noh1 == oh2) noh1 = oh1;
if (noh1 == h2) noh1 = h1;
if (noh2 == oh1) noh2 = oh2;
if (noh2 == h1) noh2 = h2;
if (poh1 == oh2) poh1 = oh1;
if (poh1 == h2) poh1 = h1;
if (poh2 == oh1) poh2 = oh2;
if (poh2 == h1) poh2 = h2;
// (1) exchange next pointers
set_next(h1, nh2, g);
set_next(h2, nh1, g);
set_next(ph1, h2, g);
set_next(ph2, h1, g);
set_next(oh1, noh2, g);
set_next(oh2, noh1, g);
set_next(poh1, oh2, g);
set_next(poh2, oh1, g);
// (2) exchange vertex-halfedge pointers
set_target(h1, t2, g);
set_target(h2, t1, g);
set_target(oh1, s2, g);
set_target(oh2, s1, g);
if (halfedge(t1, g)==h1) set_halfedge(t1, h2, g);
if (halfedge(t2, g)==h2) set_halfedge(t2, h1, g);
if (halfedge(s1, g)==oh1) set_halfedge(s1, oh2, g);
if (halfedge(s2, g)==oh2) set_halfedge(s2, oh1, g);
// (3) exchange face-halfedge pointers
set_face(h1, f2, g);
set_face(h2, f1, g);
set_face(oh1, fo2, g);
set_face(oh2, fo1, g);
face_descriptor nf = boost::graph_traits<FaceGraph>::null_face();
if (f1 != nf && halfedge(f1, g)==h1) set_halfedge(f1, h2, g);
if (f2 != nf && halfedge(f2, g)==h2) set_halfedge(f2, h1, g);
if (fo1 != nf && halfedge(fo1, g)==oh1) set_halfedge(fo1, oh2, g);
if (fo2 != nf && halfedge(fo2, g)==oh2) set_halfedge(fo2, oh1, g);
}
} //end of internal namespace
/**

View File

@ -380,7 +380,27 @@ does_satisfy_link_condition()
assert(CGAL::Euler::does_satisfy_link_condition(*edges(f.m).first,f.m));
}
template <typename Graph>
void
test_swap_edges()
{
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
std::size_t nbh=12;
Kernel::Point_3 pt(0,0,0);
// test all possible pairs of halfedges
for (std::size_t i=0; i<nbh-1; ++i)
{
for(std::size_t j=i+1; j<nbh; ++j)
{
Graph g;
CGAL::make_tetrahedron(pt,pt,pt,pt,g);
halfedge_descriptor h1 = *CGAL::cpp11::next(boost::begin(halfedges(g)), i);
halfedge_descriptor h2 = *CGAL::cpp11::next(boost::begin(halfedges(g)), j);
CGAL::internal::swap_edges(h1, h2, g);
CGAL_assertion(is_valid(g));
}
}
}
template <typename Graph>
void
@ -400,6 +420,7 @@ test_Euler_operations()
remove_center_vertex_test<Graph>();
join_split_inverse<Graph>();
does_satisfy_link_condition<Graph>();
test_swap_edges<Graph>();
}
int main()

View File

@ -732,7 +732,6 @@ namespace internal {
halfedge_descriptor epo_p = opposite(ep_p, mesh_);
halfedge_descriptor en = next(he, mesh_);
halfedge_descriptor en_p = next(he_opp, mesh_);
halfedge_descriptor eno_p = opposite(en_p, mesh_);
Halfedge_status s_ep_p = status(ep_p);
Halfedge_status s_epo_p = status(epo_p);
Halfedge_status s_ep = status(prev(he, mesh_));
@ -755,29 +754,7 @@ namespace internal {
else{
// swap edges so as to keep constained edges:
// replace en_p by epo_p and ep_p by eno_p
// (1) exchange next pointer
set_next(prev(epo_p, mesh_), en_p, mesh_);
set_next(en_p, next(epo_p, mesh_), mesh_);
set_next(prev(eno_p, mesh_), ep_p, mesh_);
set_next(ep_p, next(eno_p, mesh_), mesh_);
set_next(epo_p, eno_p, mesh_);
set_next(he_opp, epo_p, mesh_);
set_next(eno_p, he_opp, mesh_);
// (2) exchange vertex-halfedge pointer
set_target(ep_p, va, mesh_);
set_target(eno_p, vb, mesh_);
set_halfedge(va, ep_p, mesh_);
set_halfedge(vb, eno_p, mesh_);
// (3) exchange face-halfedge pointer
set_face(ep_p, face(eno_p, mesh_), mesh_);
set_face(en_p, face(epo_p, mesh_), mesh_);
set_face(epo_p, face(he_opp, mesh_), mesh_);
set_face(eno_p, face(he_opp, mesh_), mesh_);
set_halfedge(face(he_opp, mesh_), he_opp, mesh_);
if (face(ep_p, mesh_) != boost::graph_traits<PM>::null_face())
set_halfedge(face(ep_p, mesh_), ep_p, mesh_);
if (face(en_p, mesh_) != boost::graph_traits<PM>::null_face())
set_halfedge(face(en_p, mesh_), en_p, mesh_);
::CGAL::internal::swap_edges(en_p, epo_p, mesh_);
CGAL_assertion(is_valid(mesh_));
}
}