mirror of https://github.com/CGAL/cgal
Merge pull request #2350 from sloriot/SMS-fix_link_computation
Fix the link computation for edges on the border
This commit is contained in:
commit
dfa7481b76
|
|
@ -152,7 +152,7 @@ template<class VertexIdxMap
|
|||
|
||||
// counterclockwise around v0
|
||||
halfedge_descriptor e02 = opposite(prev(v0_v1(),surface_mesh()), surface_mesh());
|
||||
vertex_descriptor v, v2 =target(e02,surface_mesh());
|
||||
vertex_descriptor v=target(e02,surface_mesh()), v2=v;
|
||||
while(e02 != endleft) {
|
||||
#ifdef CGAL_SMS_EDGE_PROFILE_ALWAYS_NEED_UNIQUE_VERTEX_IN_LINK
|
||||
if (vertex_already_inserted.insert(v2).second)
|
||||
|
|
@ -161,12 +161,14 @@ template<class VertexIdxMap
|
|||
bool is_b = is_border(e02);
|
||||
e02 = opposite(prev(e02,surface_mesh()), surface_mesh());
|
||||
v = target(e02,surface_mesh());
|
||||
if(! is_b){
|
||||
if( !is_b )
|
||||
mTriangles.push_back(Triangle(v,v0(),v2) ) ;
|
||||
}
|
||||
v2 = v;
|
||||
}
|
||||
if(v != vR() && (v!= vertex_descriptor())){
|
||||
|
||||
e02 = opposite(prev(v1_v0(),surface_mesh()), surface_mesh());
|
||||
if(target(e02, surface_mesh())!=v ) // add the vertex if it is not added in the following loop
|
||||
{
|
||||
#ifdef CGAL_SMS_EDGE_PROFILE_ALWAYS_NEED_UNIQUE_VERTEX_IN_LINK
|
||||
if (vertex_already_inserted.insert(v).second)
|
||||
#endif
|
||||
|
|
@ -174,8 +176,8 @@ template<class VertexIdxMap
|
|||
}
|
||||
|
||||
// counterclockwise around v1
|
||||
e02 = opposite(prev(v1_v0(),surface_mesh()), surface_mesh());
|
||||
v2 = target(e02,surface_mesh());
|
||||
v = v2;
|
||||
while(e02 != endright) {
|
||||
#ifdef CGAL_SMS_EDGE_PROFILE_ALWAYS_NEED_UNIQUE_VERTEX_IN_LINK
|
||||
if (vertex_already_inserted.insert(v2).second)
|
||||
|
|
@ -184,18 +186,22 @@ template<class VertexIdxMap
|
|||
bool is_b = is_border(e02);
|
||||
e02 = opposite(prev(e02,surface_mesh()), surface_mesh());
|
||||
v = target(e02,surface_mesh());
|
||||
if(! is_b){
|
||||
if( !is_b ){
|
||||
mTriangles.push_back(Triangle(v,v1(),v2) ) ;
|
||||
}
|
||||
v2 = v;
|
||||
}
|
||||
if(v != vL() && (v!= vertex_descriptor())){
|
||||
|
||||
if(mLink.empty() || //handle link of an isolated triangle
|
||||
target(opposite(prev(v0_v1(),surface_mesh()), surface_mesh()), surface_mesh())!=v)
|
||||
{
|
||||
#ifdef CGAL_SMS_EDGE_PROFILE_ALWAYS_NEED_UNIQUE_VERTEX_IN_LINK
|
||||
if (vertex_already_inserted.insert(v).second)
|
||||
#endif
|
||||
mLink.push_back(v);
|
||||
}
|
||||
|
||||
|
||||
CGAL_assertion(!mLink.empty());
|
||||
}
|
||||
|
||||
} // namespace Surface_mesh_simplification
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
OFF
|
||||
16 18 0
|
||||
|
||||
-12 -8 0
|
||||
-9 -11 0
|
||||
-10 -7 0
|
||||
-10 -17 0
|
||||
-9 -14 0
|
||||
-12 -15 0
|
||||
-3 -7 0
|
||||
-6 -6 0
|
||||
-5 -10 0
|
||||
-13 -14 0
|
||||
-8 -19 0
|
||||
-6 -15 0
|
||||
-2 -17 0
|
||||
-4 -20 0
|
||||
-2 -10 0
|
||||
-9 -6 0
|
||||
3 0 1 2
|
||||
3 3 4 5
|
||||
3 6 7 8
|
||||
3 5 4 9
|
||||
3 9 1 0
|
||||
3 10 11 4
|
||||
3 12 11 13
|
||||
3 10 4 3
|
||||
3 7 1 8
|
||||
3 8 11 14
|
||||
3 2 1 15
|
||||
3 11 8 4
|
||||
3 11 12 14
|
||||
3 14 6 8
|
||||
3 4 8 1
|
||||
3 10 13 11
|
||||
3 9 4 1
|
||||
3 15 1 7
|
||||
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
OFF
|
||||
16 17 0
|
||||
|
||||
-12 -8 0
|
||||
-9 -11 0
|
||||
-10 -7 0
|
||||
-10 -17 0
|
||||
-9 -14 0
|
||||
-12 -15 0
|
||||
-3 -7 0
|
||||
-6 -6 0
|
||||
-5 -10 0
|
||||
-13 -14 0
|
||||
-8 -19 0
|
||||
-6 -15 0
|
||||
-2 -17 0
|
||||
-4 -20 0
|
||||
-2 -10 0
|
||||
-9 -6 0
|
||||
3 0 1 2
|
||||
3 3 4 5
|
||||
3 6 7 8
|
||||
3 9 1 0
|
||||
3 10 11 4
|
||||
3 12 11 13
|
||||
3 10 4 3
|
||||
3 7 1 8
|
||||
3 8 11 14
|
||||
3 2 1 15
|
||||
3 11 8 4
|
||||
3 11 12 14
|
||||
3 14 6 8
|
||||
3 4 8 1
|
||||
3 10 13 11
|
||||
3 9 4 1
|
||||
3 15 1 7
|
||||
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
OFF
|
||||
16 16 0
|
||||
|
||||
-12 -8 0
|
||||
-9 -11 0
|
||||
-10 -7 0
|
||||
-10 -17 0
|
||||
-9 -14 0
|
||||
-12 -15 0
|
||||
-3 -7 0
|
||||
-6 -6 0
|
||||
-5 -10 0
|
||||
-13 -14 0
|
||||
-8 -19 0
|
||||
-6 -15 0
|
||||
-2 -17 0
|
||||
-4 -20 0
|
||||
-2 -10 0
|
||||
-9 -6 0
|
||||
3 0 1 2
|
||||
3 3 4 5
|
||||
3 6 7 8
|
||||
3 9 1 0
|
||||
3 10 11 4
|
||||
3 12 11 13
|
||||
3 10 4 3
|
||||
3 7 1 8
|
||||
3 8 11 14
|
||||
3 2 1 15
|
||||
3 11 8 4
|
||||
3 11 12 14
|
||||
3 14 6 8
|
||||
3 4 8 1
|
||||
3 10 13 11
|
||||
3 15 1 7
|
||||
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
OFF
|
||||
14 13 0
|
||||
|
||||
-12 -8 0
|
||||
-9 -11 0
|
||||
-10 -7 0
|
||||
-9 -14 0
|
||||
-3 -7 0
|
||||
-6 -6 0
|
||||
-5 -10 0
|
||||
-13 -14 0
|
||||
-8 -19 0
|
||||
-6 -15 0
|
||||
-2 -17 0
|
||||
-4 -20 0
|
||||
-2 -10 0
|
||||
-9 -6 0
|
||||
3 0 1 2
|
||||
3 4 5 6
|
||||
3 7 1 0
|
||||
3 10 9 11
|
||||
3 5 1 6
|
||||
3 6 9 12
|
||||
3 2 1 13
|
||||
3 9 6 3
|
||||
3 9 10 12
|
||||
3 12 4 6
|
||||
3 3 6 1
|
||||
3 8 11 9
|
||||
3 13 1 5
|
||||
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
OFF
|
||||
16 16 0
|
||||
|
||||
-12 -8 0
|
||||
-9 -11 0
|
||||
-10 -7 0
|
||||
-10 -17 0
|
||||
-9 -14 0
|
||||
-12 -15 0
|
||||
-3 -7 0
|
||||
-6 -6 0
|
||||
-5 -10 0
|
||||
-13 -14 0
|
||||
-8 -19 0
|
||||
-6 -15 0
|
||||
-2 -17 0
|
||||
-4 -20 0
|
||||
-2 -10 0
|
||||
-9 -6 0
|
||||
3 0 1 2
|
||||
3 3 4 5
|
||||
3 6 7 8
|
||||
3 9 1 0
|
||||
3 10 11 4
|
||||
3 12 11 13
|
||||
3 10 4 3
|
||||
3 7 1 8
|
||||
3 8 11 14
|
||||
3 2 1 15
|
||||
3 11 8 4
|
||||
3 11 12 14
|
||||
3 4 8 1
|
||||
3 10 13 11
|
||||
3 9 4 1
|
||||
3 15 1 7
|
||||
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
OFF
|
||||
16 14 0
|
||||
|
||||
-12 -8 0
|
||||
-9 -11 0
|
||||
-10 -7 0
|
||||
-10 -17 0
|
||||
-9 -14 0
|
||||
-12 -15 0
|
||||
-3 -7 0
|
||||
-6 -6 0
|
||||
-5 -10 0
|
||||
-13 -14 0
|
||||
-8 -19 0
|
||||
-6 -15 0
|
||||
-2 -17 0
|
||||
-4 -20 0
|
||||
-2 -10 0
|
||||
-9 -6 0
|
||||
3 0 1 2
|
||||
3 3 4 5
|
||||
3 6 7 8
|
||||
3 9 1 0
|
||||
3 10 11 4
|
||||
3 12 11 13
|
||||
3 10 4 3
|
||||
3 7 1 8
|
||||
3 2 1 15
|
||||
3 11 8 4
|
||||
3 11 12 14
|
||||
3 4 8 1
|
||||
3 10 13 11
|
||||
3 15 1 7
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
OFF
|
||||
10 9 0
|
||||
|
||||
-9 -11 0
|
||||
-10 -17 0
|
||||
-9 -14 0
|
||||
-12 -15 0
|
||||
-5 -10 0
|
||||
-8 -19 0
|
||||
-6 -15 0
|
||||
-2 -17 0
|
||||
-4 -20 0
|
||||
-2 -10 0
|
||||
3 1 2 3
|
||||
3 5 6 2
|
||||
3 7 6 8
|
||||
3 5 2 1
|
||||
3 4 6 9
|
||||
3 6 4 2
|
||||
3 6 7 9
|
||||
3 2 4 0
|
||||
3 5 8 6
|
||||
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
OFF
|
||||
13 11 0
|
||||
|
||||
-12 -8 0
|
||||
-9 -11 0
|
||||
-10 -7 0
|
||||
-9 -14 0
|
||||
-6 -6 0
|
||||
-5 -10 0
|
||||
-13 -14 0
|
||||
-8 -19 0
|
||||
-6 -15 0
|
||||
-2 -17 0
|
||||
-4 -20 0
|
||||
-2 -10 0
|
||||
-9 -6 0
|
||||
3 0 1 2
|
||||
3 6 1 0
|
||||
3 7 8 3
|
||||
3 9 8 10
|
||||
3 4 1 5
|
||||
3 2 1 12
|
||||
3 8 5 3
|
||||
3 8 9 11
|
||||
3 3 5 1
|
||||
3 7 10 8
|
||||
3 12 1 4
|
||||
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
OFF
|
||||
4 2 0
|
||||
|
||||
-9 -11 0
|
||||
-9 -14 0
|
||||
-5 -10 0
|
||||
-6 -15 0
|
||||
3 3 2 1
|
||||
3 1 2 0
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
OFF
|
||||
3 1 0
|
||||
|
||||
-9 -11 0
|
||||
-9 -14 0
|
||||
-5 -10 0
|
||||
3 1 2 0
|
||||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
data_link/test01.off
|
||||
data_link/test02.off
|
||||
data_link/test03.off
|
||||
data_link/test04.off
|
||||
data_link/test05.off
|
||||
data_link/test06.off
|
||||
data_link/test07.off
|
||||
data_link/test08.off
|
||||
data_link/test09.off
|
||||
data_link/test10.off
|
||||
data/elephant.off
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Surface_mesh.h>
|
||||
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Edge_profile.h>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/tuple/tuple_comparison.hpp>
|
||||
#include <fstream>
|
||||
|
||||
typedef CGAL::Simple_cartesian<double> K;
|
||||
typedef CGAL::Surface_mesh<K::Point_3> Mesh;
|
||||
typedef CGAL::Surface_mesh_simplification::Edge_profile<Mesh> Profile;
|
||||
|
||||
void naive_all_triangles(Mesh::Halfedge_index h, Mesh& m, std::set<Mesh::Face_index>& triangles)
|
||||
{
|
||||
BOOST_FOREACH(Mesh::Halfedge_index hh, CGAL::halfedges_around_source(h, m))
|
||||
{
|
||||
if (!is_border(hh, m))
|
||||
triangles.insert(face(hh,m));
|
||||
}
|
||||
BOOST_FOREACH(Mesh::Halfedge_index hh, CGAL::halfedges_around_target(h, m))
|
||||
{
|
||||
if (!is_border(hh, m))
|
||||
triangles.insert(face(hh,m));
|
||||
}
|
||||
}
|
||||
|
||||
void naive_link_vertices(Mesh::Halfedge_index h, Mesh& m,
|
||||
const std::set<Mesh::Face_index>& triangles,
|
||||
std::set<Mesh::Vertex_index>& link_vertices)
|
||||
{
|
||||
BOOST_FOREACH(Mesh::Face_index f, triangles)
|
||||
{
|
||||
BOOST_FOREACH(Mesh::Halfedge_index h, CGAL::halfedges_around_face(halfedge(f, m), m))
|
||||
{
|
||||
link_vertices.insert(target(h, m));
|
||||
}
|
||||
}
|
||||
link_vertices.erase( source(h, m) );
|
||||
link_vertices.erase( target(h, m) );
|
||||
}
|
||||
|
||||
struct A{};
|
||||
|
||||
boost::tuple<Mesh::Vertex_index, Mesh::Vertex_index, Mesh::Vertex_index>
|
||||
make_canonical_tuple(Mesh::Vertex_index v1, Mesh::Vertex_index v2, Mesh::Vertex_index v3)
|
||||
{
|
||||
Mesh::Vertex_index vs[3]={v1, v2, v3};
|
||||
std::sort(&vs[0], &vs[0]+3);
|
||||
return boost::make_tuple(vs[0], vs[1], vs[2]);
|
||||
}
|
||||
|
||||
boost::tuple<Mesh::Vertex_index, Mesh::Vertex_index, Mesh::Vertex_index>
|
||||
make_canonical_tuple(const Profile::Triangle& t)
|
||||
{
|
||||
return make_canonical_tuple(t.v0, t.v1, t.v2);
|
||||
}
|
||||
|
||||
boost::tuple<Mesh::Vertex_index, Mesh::Vertex_index, Mesh::Vertex_index>
|
||||
make_canonical_tuple(Mesh::Face_index f, Mesh& m)
|
||||
{
|
||||
Mesh::Halfedge_index h=halfedge(f, m);
|
||||
return make_canonical_tuple(source(h,m), target(h,m), target(next(h, m), m));
|
||||
}
|
||||
|
||||
void test(const char* fname)
|
||||
{
|
||||
Mesh m;
|
||||
std::ifstream input(fname);
|
||||
assert( bool(input) );
|
||||
input >> m;
|
||||
assert(num_vertices(m)!=0);
|
||||
A a;
|
||||
|
||||
BOOST_FOREACH(Mesh::Halfedge_index h, halfedges(m))
|
||||
{
|
||||
std::set<Mesh::Face_index> triangles;
|
||||
naive_all_triangles(h, m, triangles);
|
||||
|
||||
Profile profile(h, m, a, get(boost::vertex_point, m), a, true);
|
||||
|
||||
if (CGAL::Euler::does_satisfy_link_condition(edge(h, m), m))
|
||||
{
|
||||
std::set<Mesh::Vertex_index> link_vertices;
|
||||
naive_link_vertices(h, m, triangles, link_vertices);
|
||||
assert( link_vertices.size()==profile.link().size() );
|
||||
assert( std::set<Mesh::Vertex_index>(profile.link().begin(),
|
||||
profile.link().end()).size()
|
||||
== link_vertices.size() );
|
||||
|
||||
BOOST_FOREACH(const Mesh::Vertex_index& v, profile.link())
|
||||
{
|
||||
assert( link_vertices.count(v) == 1 );
|
||||
}
|
||||
}
|
||||
|
||||
assert(triangles.size() == profile.triangles().size());
|
||||
std::set<boost::tuple<Mesh::Vertex_index, Mesh::Vertex_index, Mesh::Vertex_index> > triple_set;
|
||||
BOOST_FOREACH(const Profile::Triangle& t, profile.triangles())
|
||||
{
|
||||
triple_set.insert( make_canonical_tuple(t) );
|
||||
}
|
||||
BOOST_FOREACH(Mesh::Face_index f, triangles)
|
||||
{
|
||||
assert( triple_set.count( make_canonical_tuple(f, m) ) == 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
for (int i=1; i<argc; ++i)
|
||||
{
|
||||
std::cout << "Testing " << argv[i] << "\n";
|
||||
test(argv[i]);
|
||||
}
|
||||
if (argc==1)
|
||||
{
|
||||
std::cout << "No file provided, nothing tested\n";
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue