Resolve conflicts between 4.13 branch and master

This commit is contained in:
Mael Rouxel-Labbé 2019-05-08 19:01:11 +02:00
commit d4ad35b136
1 changed files with 193 additions and 146 deletions

View File

@ -373,130 +373,152 @@ bool is_valid_face_descriptor( typename boost::graph_traits<FaceGraph>::face_des
template<typename Graph> template<typename Graph>
bool is_valid_halfedge_graph(const Graph& g, bool verb = false) bool is_valid_halfedge_graph(const Graph& g, bool verb = false)
{ {
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<Graph>::vertices_size_type vertex_size_type; typedef typename boost::graph_traits<Graph>::vertices_size_type vertex_size_type;
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<Graph>::halfedges_size_type halfedges_size_type; typedef typename boost::graph_traits<Graph>::halfedges_size_type halfedges_size_type;
Verbose_ostream verr(verb); Verbose_ostream verr(verb);
std::size_t num_v(std::distance(boost::begin(vertices(g)), boost::end(vertices(g)))), std::size_t num_v(std::distance(boost::begin(vertices(g)), boost::end(vertices(g)))),
num_e(std::distance(boost::begin(edges(g)), boost::end(edges(g)))),
num_h(std::distance(boost::begin(halfedges(g)), boost::end(halfedges(g)))); num_h(std::distance(boost::begin(halfedges(g)), boost::end(halfedges(g))));
bool valid = ( 1 != (num_h& 1));
bool valid = (1 != (num_h&1) && (2*num_e == num_h));
if(!valid) if(!valid)
verr << "number of halfedges is odd." << std::endl; verr << "number of halfedges is odd." << std::endl;
// All halfedges. // All halfedges.
halfedges_size_type n = 0; halfedges_size_type n = 0;
for(halfedge_descriptor begin : halfedges(g)) { for(halfedge_descriptor begin : halfedges(g))
{
if(!valid) if(!valid)
break; break;
verr << "halfedge " << n << std::endl;
// Pointer integrity. // Pointer integrity.
valid = valid && (next(begin, g) != boost::graph_traits<Graph>::null_halfedge()); valid = valid && (next(begin, g) != boost::graph_traits<Graph>::null_halfedge());
valid = valid && (opposite(begin, g) != boost::graph_traits<Graph>::null_halfedge()); valid = valid && (opposite(begin, g) != boost::graph_traits<Graph>::null_halfedge());
if ( ! valid) { if(!valid)
verr << " pointer integrity corrupted (ptr==0)." {
<< std::endl; verr << "halfedge " << n << " next / opposite halfedges are null." << std::endl;
break; break;
} }
// edge integrity // edge integrity
valid = valid && (halfedge(edge(begin, g), g) == begin); valid = valid && (halfedge(edge(begin, g), g) == begin);
// opposite integrity. // opposite integrity.
valid = valid && (opposite(begin, g) != begin); valid = valid && (opposite(begin, g) != begin);
valid = valid && (opposite(opposite(begin, g), g) == begin); valid = valid && (opposite(opposite(begin, g), g) == begin);
if ( ! valid) { if(!valid)
verr << " opposite pointer integrity corrupted." {
<< std::endl; verr << "halfedge " << n << " invalid halfedge opposite()." << std::endl;
break; break;
} }
// previous integrity. // previous integrity.
valid = valid && (prev(next(begin, g), g) == begin); valid = valid && (prev(next(begin, g), g) == begin);
valid = valid && (next(prev(begin, g), g) == begin); valid = valid && (next(prev(begin, g), g) == begin);
if ( ! valid) { if(!valid)
verr << " previous pointer integrity corrupted." {
<< std::endl; verr << "halfedge " << n << " prev(next(hd)) != hd OR next(prev(hd)) != hd" << std::endl;
break; break;
} }
// vertex integrity. // vertex integrity.
valid = valid && (target(begin, g) != boost::graph_traits<Graph>::null_vertex()); valid = valid && (target(begin, g) != boost::graph_traits<Graph>::null_vertex());
if ( ! valid) { if(!valid)
verr << " vertex pointer integrity corrupted." {
<< std::endl; verr << "halfedge " << n << " target of halfedge is the null vertex." << std::endl;
break; break;
} }
valid = valid && ( target(begin, g) ==
target(opposite(next(begin, g), g), g)); valid = valid && (target(begin, g) == target(opposite(next(begin, g), g), g));
if ( ! valid) { if(!valid)
verr << " vertex pointer integrity2 corrupted." {
<< std::endl; verr << "halfedge " << n << " target(hd) != source(next(hd))." << std::endl;
break; break;
} }
++n; ++n;
} }
if(valid && n != num_h) if(valid && n != num_h)
verr << "counting halfedges failed." << std::endl; verr << "counting halfedges failed." << std::endl;
// All vertices. // All vertices.
vertex_size_type v = 0; vertex_size_type v = 0;
n = 0; n = 0;
for(vertex_descriptor vbegin : vertices(g)){ for(vertex_descriptor vbegin : vertices(g))
{
if(!valid) if(!valid)
break; break;
verr << "vertex " << v << std::endl;
// Pointer integrity. // Pointer integrity.
if(halfedge(vbegin, g) != boost::graph_traits<Graph>::null_halfedge()) if(halfedge(vbegin, g) != boost::graph_traits<Graph>::null_halfedge())
valid = valid && ( valid = valid && (target(halfedge(vbegin, g), g) == vbegin);
target( halfedge(vbegin, g), g) == vbegin);
else else
valid = false; valid = false;
if ( ! valid) {
verr << " halfedge pointer in vertex corrupted." if(!valid)
<< std::endl; {
verr << "vertex " << v << " halfedge incident to vertex is the null halfedge." << std::endl;
break; break;
} }
// cycle-around-vertex test. // cycle-around-vertex test.
halfedge_descriptor h = halfedge(vbegin, g); halfedge_descriptor h = halfedge(vbegin, g);
if ( h != boost::graph_traits<Graph>::null_halfedge()) { if(h != boost::graph_traits<Graph>::null_halfedge())
{
halfedge_descriptor ge = h; halfedge_descriptor ge = h;
do { do
verr << " halfedge " << n << std::endl; {
++n; ++n;
h = opposite(next(h, g), g); h = opposite(next(h, g), g);
valid = valid && (n <= num_h && n!=0); valid = valid && (n <= num_h && n!=0);
if(!valid) if(!valid)
verr << " too many halfedges around vertices." {
<< std::endl; verr << "vertex " << v << " too many halfedges around vertex." << std::endl;
} while ( valid && (h != ge)); break;
} }
}
while (valid && (h != ge));
}
if(!valid)
break;
++v; ++v;
} }
if(valid && v != num_v) if(valid && v != num_v)
verr << "counting vertices failed." << std::endl; verr << "counting vertices failed." << std::endl;
if(valid && (n != num_h)) if(valid && (n != num_h))
verr << "counting halfedges via vertices failed." << std::endl; verr << "counting halfedges via vertices failed." << std::endl;
valid = valid && ( v == num_v);
valid = valid && (v == num_v);
// All halfedges. // All halfedges.
n = 0; n = 0;
for(halfedge_descriptor i : halfedges(g)){ for(halfedge_descriptor i : halfedges(g))
verr << "halfedge " << n << std::endl; {
// At least triangular facets and distinct geometry. // At least triangular facets and distinct geometry.
valid = valid && (next(i, g) != i); valid = valid && (next(i, g) != i);
valid = valid && (target(i, g) != target(opposite(i, g), g)); valid = valid && (target(i, g) != target(opposite(i, g), g));
if ( ! valid) { if(!valid)
verr << " pointer validity corrupted." {
<< std::endl; verr << "halfedge " << n << " pointer validity corrupted." << std::endl;
break; break;
} }
++n; ++n;
} }
valid = valid && (n == num_h); valid = valid && (n == num_h);
if(n != num_h) if(n != num_h)
verr << "counting halfedges failed." << std::endl; verr << "counting halfedges failed." << std::endl;
verr << "Halfedge Graph Structure is " << (valid ? "valid." : "NOT VALID.") << std::endl;
verr << "structure is "
<< ( valid ? "valid." : "NOT VALID.") << std::endl;
return valid; return valid;
} }
@ -520,78 +542,99 @@ template<typename Graph>
bool is_valid_face_graph(const Graph& g, bool verb = false) bool is_valid_face_graph(const Graph& g, bool verb = false)
{ {
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<Graph>::halfedges_size_type halfedges_size_type;
typedef typename boost::graph_traits<Graph>::face_descriptor face_descriptor; typedef typename boost::graph_traits<Graph>::face_descriptor face_descriptor;
typedef typename boost::graph_traits<Graph>::faces_size_type faces_size_type; typedef typename boost::graph_traits<Graph>::faces_size_type faces_size_type;
typedef typename boost::graph_traits<Graph>::halfedges_size_type halfedges_size_type;
std::size_t num_f(std::distance(boost::begin(faces(g)), boost::end(faces(g)))), std::size_t num_f(std::distance(boost::begin(faces(g)), boost::end(faces(g)))),
num_h(std::distance(boost::begin(halfedges(g)), boost::end(halfedges(g)))); num_h(std::distance(boost::begin(halfedges(g)), boost::end(halfedges(g))));
//is valid halfedge_graph ? //is valid halfedge_graph ?
bool valid = is_valid_halfedge_graph(g, verb); bool valid = is_valid_halfedge_graph(g, verb);
if ( ! valid) { if(!valid)
return false; return false;
}
Verbose_ostream verr(verb); Verbose_ostream verr(verb);
// All faces. // All faces.
faces_size_type f = 0; faces_size_type f = 0;
std::size_t n = 0; std::size_t n = 0;
halfedges_size_type nb = 0; halfedges_size_type nb = 0;
for(face_descriptor fbegin : faces(g)){
for(face_descriptor fbegin : faces(g))
{
if(!valid) if(!valid)
break; break;
verr << "face " << f << std::endl;
// Pointer integrity. // Pointer integrity.
if(halfedge(fbegin, g) != boost::graph_traits<Graph>::null_halfedge()) if(halfedge(fbegin, g) != boost::graph_traits<Graph>::null_halfedge())
valid = valid && ( valid = valid && (face(halfedge(fbegin, g), g) == fbegin);
face(halfedge(fbegin, g), g) == fbegin);
else else
valid = false; valid = false;
if ( ! valid) {
verr << " halfedge pointer in face corrupted." << std::endl; if(! valid)
{
verr << "face " << f << " halfedge incident to face is the null halfedge." << std::endl;
break; break;
} }
// cycle-around-face test. // cycle-around-face test.
halfedge_descriptor h = halfedge( fbegin, g); halfedge_descriptor h = halfedge( fbegin, g);
if (h != boost::graph_traits<Graph>::null_halfedge()) { if(h != boost::graph_traits<Graph>::null_halfedge())
{
halfedge_descriptor ge = h; halfedge_descriptor ge = h;
do { do
verr << " halfedge " << n << std::endl; {
++n; ++n;
h = next(h, g); h = next(h, g);
valid = valid && (n <= num_h && n != 0); valid = valid && (n <= num_h && n != 0);
if(!valid) if(!valid)
verr << " too many halfedges around faces." {
<< std::endl; verr << "face " << f << " too many halfedges around face." << std::endl;
} while ( valid && (h != ge));
}
++f;
}
if ( valid && f != num_f)
verr << "counting faces failed." << std::endl;
for(halfedge_descriptor i : halfedges(g)){
//counting borders
if ( is_border(i, g))
++nb;
// face integrity.
valid = valid && ( face(i, g) == face(next(i, g), g));
if ( ! valid) {
verr << " face pointer integrity2 corrupted."
<< std::endl;
break; break;
} }
} }
while(valid && (h != ge));
}
if(! valid)
break;
++f;
}
if(valid && f != num_f)
verr << "counting faces failed." << std::endl;
std::size_t hn = 0;
for(halfedge_descriptor i : halfedges(g))
{
++hn;
//counting borders
if(is_border(i, g))
++nb;
// face integrity.
valid = valid && (face(i, g) == face(next(i, g), g));
if(!valid)
{
verr << "halfedge " << hn << " face(hd) != face(next(hd))." << std::endl;
break;
}
}
verr << "sum border halfedges (2*nb) = " << 2 * nb << std::endl; verr << "sum border halfedges (2*nb) = " << 2 * nb << std::endl;
if(valid && n + nb != num_h) if(valid && n + nb != num_h)
verr << "counting halfedges via faces failed." << std::endl; verr << "counting halfedges via faces failed." << std::endl;
valid = valid && (f == num_f); valid = valid && (f == num_f);
valid = valid && (n + nb == num_h); valid = valid && (n + nb == num_h);
verr << "is_valid(): structure is " << ( valid ? "valid." : verr << "Face Graph Structure is " << (valid ? "valid." : "NOT VALID.") << std::endl;
"NOT VALID.") << std::endl;
return valid; return valid;
} }
/*! /*!
\ingroup PkgBGLHelperFct \ingroup PkgBGLHelperFct
* \brief checks the integrity of `g`. * \brief checks the integrity of `g`.
@ -614,33 +657,37 @@ template <typename Mesh>
bool is_valid_polygon_mesh(const Mesh& g, bool verb = false) bool is_valid_polygon_mesh(const Mesh& g, bool verb = false)
{ {
typedef typename boost::graph_traits<Mesh>::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits<Mesh>::halfedge_descriptor halfedge_descriptor;
Verbose_ostream verr(verb); Verbose_ostream verr(verb);
bool valid = is_valid_face_graph(g, verb); bool valid = is_valid_face_graph(g, verb);
if(!valid)
return false;
// test for 2-manifoldness // test for 2-manifoldness
// Distinct facets on each side of an halfedge. // Distinct facets on each side of an halfedge.
for(halfedge_descriptor i : halfedges(g)){ for(halfedge_descriptor i : halfedges(g))
{
valid = valid && (face(i, g) != face(opposite(i, g), g)); valid = valid && (face(i, g) != face(opposite(i, g), g));
if ( ! valid) { if(!valid)
{
verr << " both incident facets are equal." << std::endl; verr << " both incident facets are equal." << std::endl;
break; break;
} }
valid = valid && (next(next(i, g), g) != i); valid = valid && (next(next(i, g), g) != i);
valid = valid && (target(i, g) != target(next(i, g), g)); valid = valid && (target(i, g) != target(next(i, g), g));
valid = valid && (target(i, g) != target(next(next(i, g), g), g)); valid = valid && (target(i, g) != target(next(next(i, g), g), g));
if ( ! valid) { if(!valid)
verr << " incident facet is not at least a triangle." {
<< std::endl; verr << " incident facet is not at least a triangle." << std::endl;
break; break;
} }
if ( ! valid) {
verr << " incident facet is not at least a triangle."
<< std::endl;
break;
}
}
return valid;
} }
verr << "Polygon Mesh Structure is " << (valid ? "valid." : "NOT VALID.") << std::endl;
return valid;
}
/*! /*!
\ingroup PkgBGLHelperFct \ingroup PkgBGLHelperFct