mirror of https://github.com/CGAL/cgal
Merge remote-tracking branch 'cgal/5.6.x-branch' into HEAD
This commit is contained in:
commit
0eb709dd65
|
|
@ -178,6 +178,7 @@ void copy_face_graph_impl(const SourceMesh& sm, TargetMesh& tm,
|
||||||
}
|
}
|
||||||
|
|
||||||
// detect if there are some non-manifold umbrellas and fix missing halfedge target pointers
|
// detect if there are some non-manifold umbrellas and fix missing halfedge target pointers
|
||||||
|
std::map<sm_vertex_descriptor, std::vector<tm_halfedge_descriptor>> nm_umbrella_map;
|
||||||
typedef typename std::vector<tm_edge_descriptor>::iterator edge_iterator;
|
typedef typename std::vector<tm_edge_descriptor>::iterator edge_iterator;
|
||||||
for (edge_iterator it=new_edges.begin(); it!=new_edges.end(); ++it)
|
for (edge_iterator it=new_edges.begin(); it!=new_edges.end(); ++it)
|
||||||
{
|
{
|
||||||
|
|
@ -199,10 +200,19 @@ void copy_face_graph_impl(const SourceMesh& sm, TargetMesh& tm,
|
||||||
// we recover tm_v using the halfedge associated to the target vertex of
|
// we recover tm_v using the halfedge associated to the target vertex of
|
||||||
// the halfedge in sm corresponding to nh_t. This is working because we
|
// the halfedge in sm corresponding to nh_t. This is working because we
|
||||||
// set the vertex halfedge pointer to the "same" halfedges.
|
// set the vertex halfedge pointer to the "same" halfedges.
|
||||||
tm_vertex_descriptor tm_v =
|
|
||||||
target( get(hs_to_ht, halfedge(target(get(ht_to_hs, nh_t), sm), sm)), tm);
|
sm_vertex_descriptor vs = target(get(ht_to_hs, nh_t), sm);
|
||||||
for(tm_halfedge_descriptor ht : halfedges_around_target(nh_t, tm))
|
sm_halfedge_descriptor hs = halfedge(vs, sm);
|
||||||
set_target(ht, tm_v, tm);
|
if (hs == boost::graph_traits<SourceMesh>::null_halfedge())
|
||||||
|
{ // special case for Face_filtered_graph with a non-manifold input with not all umbrellas selected
|
||||||
|
nm_umbrella_map[vs].push_back(nh_t);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tm_vertex_descriptor tm_v = target( get(hs_to_ht, hs), tm);
|
||||||
|
for(tm_halfedge_descriptor ht : halfedges_around_target(nh_t, tm))
|
||||||
|
set_target(ht, tm_v, tm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
nh_t = opposite(nh_t, tm);
|
nh_t = opposite(nh_t, tm);
|
||||||
}
|
}
|
||||||
|
|
@ -210,6 +220,18 @@ void copy_face_graph_impl(const SourceMesh& sm, TargetMesh& tm,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const auto& vs_and_hts : nm_umbrella_map)
|
||||||
|
{
|
||||||
|
sm_vertex_descriptor v_sm = vs_and_hts.first;
|
||||||
|
tm_vertex_descriptor v_tm = add_vertex(tm);
|
||||||
|
*v2v++=std::make_pair(v_sm, v_tm);
|
||||||
|
set_halfedge(v_tm, vs_and_hts.second.front(), tm);
|
||||||
|
put(tm_vpm, v_tm, conv(get(sm_vpm, v_sm)));
|
||||||
|
|
||||||
|
for (tm_halfedge_descriptor h_tm : vs_and_hts.second)
|
||||||
|
set_target(h_tm, v_tm, tm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end of namespace internal
|
} // end of namespace internal
|
||||||
|
|
|
||||||
|
|
@ -579,6 +579,102 @@ void test_Polyhedron_tetrahedron()
|
||||||
test_mesh<Polyhedron, FCMap, Poly_Adapter>(poly_adapter);
|
test_mesh<Polyhedron, FCMap, Poly_Adapter>(poly_adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void non_manifoldness_test1()
|
||||||
|
{
|
||||||
|
// works out-of-the-box because Face_filtered_graph handles already non-manifold cycles
|
||||||
|
SM mesh;
|
||||||
|
SM::Vertex_index v0=add_vertex(mesh);
|
||||||
|
SM::Vertex_index v1=add_vertex(mesh);
|
||||||
|
SM::Vertex_index v2=add_vertex(mesh);
|
||||||
|
SM::Vertex_index v3=add_vertex(mesh);
|
||||||
|
SM::Vertex_index v4=add_vertex(mesh);
|
||||||
|
SM::Vertex_index v5=add_vertex(mesh);
|
||||||
|
SM::Vertex_index v6=add_vertex(mesh);
|
||||||
|
|
||||||
|
SM::Face_index f0=mesh.add_face(v0,v1,v2);
|
||||||
|
SM::Face_index f1=mesh.add_face(v0,v3,v4);
|
||||||
|
SM::Face_index f2=mesh.add_face(v0,v5,v6);
|
||||||
|
SM::Halfedge_index h = halfedge(f0,mesh);
|
||||||
|
while(target(h, mesh)!=v0)
|
||||||
|
h=next(h,mesh);
|
||||||
|
set_halfedge(v0, h, mesh);
|
||||||
|
|
||||||
|
std::vector<SM::Face_index> selection = {f1, f2};
|
||||||
|
CGAL::Face_filtered_graph<SM> ffg(mesh, selection);
|
||||||
|
|
||||||
|
SM out;
|
||||||
|
CGAL::copy_face_graph(ffg, out);
|
||||||
|
|
||||||
|
assert(vertices(out).size()==5);
|
||||||
|
assert(faces(out).size()==2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void non_manifoldness_test2()
|
||||||
|
{
|
||||||
|
SM mesh;
|
||||||
|
SM::Vertex_index v0=add_vertex(mesh);
|
||||||
|
SM::Vertex_index v0b=add_vertex(mesh);
|
||||||
|
SM::Vertex_index v0t=add_vertex(mesh);
|
||||||
|
|
||||||
|
SM::Vertex_index v1=add_vertex(mesh);
|
||||||
|
SM::Vertex_index v2=add_vertex(mesh);
|
||||||
|
SM::Vertex_index v3=add_vertex(mesh);
|
||||||
|
|
||||||
|
SM::Vertex_index v4=add_vertex(mesh);
|
||||||
|
SM::Vertex_index v5=add_vertex(mesh);
|
||||||
|
SM::Vertex_index v6=add_vertex(mesh);
|
||||||
|
|
||||||
|
SM::Vertex_index v7=add_vertex(mesh);
|
||||||
|
SM::Vertex_index v8=add_vertex(mesh);
|
||||||
|
SM::Vertex_index v9=add_vertex(mesh);
|
||||||
|
|
||||||
|
SM::Face_index f00=mesh.add_face(v1,v2,v0);
|
||||||
|
SM::Face_index f01=mesh.add_face(v2,v3,v0);
|
||||||
|
SM::Face_index f02=mesh.add_face(v3,v1,v0);
|
||||||
|
|
||||||
|
SM::Face_index f10=mesh.add_face(v4,v5,v0b);
|
||||||
|
SM::Face_index f11=mesh.add_face(v5,v6,v0b);
|
||||||
|
SM::Face_index f12=mesh.add_face(v6,v4,v0b);
|
||||||
|
|
||||||
|
SM::Face_index f20=mesh.add_face(v7,v8,v0t);
|
||||||
|
SM::Face_index f21=mesh.add_face(v8,v9,v0t);
|
||||||
|
SM::Face_index f22=mesh.add_face(v9,v7,v0t);
|
||||||
|
|
||||||
|
assert(f00!=SM::Face_index());
|
||||||
|
assert(f01!=SM::Face_index());
|
||||||
|
assert(f02!=SM::Face_index());
|
||||||
|
assert(f10!=SM::Face_index());
|
||||||
|
assert(f11!=SM::Face_index());
|
||||||
|
assert(f12!=SM::Face_index());
|
||||||
|
assert(f20!=SM::Face_index());
|
||||||
|
assert(f21!=SM::Face_index());
|
||||||
|
assert(f22!=SM::Face_index());
|
||||||
|
|
||||||
|
#define UPDATE_V(fX, vX) \
|
||||||
|
{ SM::Halfedge_index h = halfedge(fX,mesh);\
|
||||||
|
while(target(h, mesh)!=vX) h=next(h,mesh);\
|
||||||
|
set_target(h, v0, mesh); }
|
||||||
|
|
||||||
|
UPDATE_V(f10, v0b)
|
||||||
|
UPDATE_V(f11, v0b)
|
||||||
|
UPDATE_V(f12, v0b)
|
||||||
|
UPDATE_V(f20, v0t)
|
||||||
|
UPDATE_V(f21, v0t)
|
||||||
|
UPDATE_V(f22, v0t)
|
||||||
|
|
||||||
|
remove_vertex(v0b, mesh);
|
||||||
|
remove_vertex(v0t, mesh);
|
||||||
|
|
||||||
|
std::vector<SM::Face_index> selection = {f10, f11, f12, f20, f21, f22};
|
||||||
|
CGAL::Face_filtered_graph<SM> ffg(mesh, selection);
|
||||||
|
|
||||||
|
SM out;
|
||||||
|
CGAL::copy_face_graph(ffg, out);
|
||||||
|
|
||||||
|
assert(vertices(out).size()==7);
|
||||||
|
assert(faces(out).size()==6);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int, char**)
|
int main(int, char**)
|
||||||
{
|
{
|
||||||
test_graph_range(poly_data());
|
test_graph_range(poly_data());
|
||||||
|
|
@ -590,6 +686,8 @@ int main(int, char**)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
test_invalid_selections();
|
test_invalid_selections();
|
||||||
|
non_manifoldness_test1();
|
||||||
|
non_manifoldness_test2();
|
||||||
|
|
||||||
test_SM_tetrahedron();
|
test_SM_tetrahedron();
|
||||||
test_Polyhedron_tetrahedron();
|
test_Polyhedron_tetrahedron();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue