Extend MeshChecker to detect more invalid configurations.
This commit is contained in:
@@ -73,23 +73,14 @@ check(unsigned int _targets, std::ostream& _os)
|
|||||||
|
|
||||||
if (_targets & CHECK_VERTICES)
|
if (_targets & CHECK_VERTICES)
|
||||||
{
|
{
|
||||||
typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()), v_end(mesh_.vertices_end());
|
|
||||||
typename Mesh::VertexHandle vh;
|
|
||||||
typename Mesh::ConstVertexVertexCWIter vv_it;
|
|
||||||
typename Mesh::HalfedgeHandle heh;
|
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
const unsigned int max_valence(10000);
|
const unsigned int max_valence(10000);
|
||||||
|
|
||||||
|
|
||||||
for (; v_it != v_end; ++v_it)
|
for (const auto vh: mesh_.vertices())
|
||||||
{
|
{
|
||||||
if (!is_deleted(*v_it))
|
|
||||||
{
|
|
||||||
vh = *v_it;
|
|
||||||
|
|
||||||
|
|
||||||
/* The outgoing halfedge of a boundary vertex has to be a boundary halfedge */
|
/* The outgoing halfedge of a boundary vertex has to be a boundary halfedge */
|
||||||
heh = mesh_.halfedge_handle(vh);
|
auto heh = vh.halfedge();
|
||||||
if (heh.is_valid() && !mesh_.is_boundary(heh))
|
if (heh.is_valid() && !mesh_.is_boundary(heh))
|
||||||
{
|
{
|
||||||
for (typename Mesh::ConstVertexOHalfedgeIter vh_it(mesh_, vh);
|
for (typename Mesh::ConstVertexOHalfedgeIter vh_it(mesh_, vh);
|
||||||
@@ -103,6 +94,18 @@ check(unsigned int _targets, std::ostream& _os)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (heh.is_valid()) {
|
||||||
|
if (heh.idx() < -1 || heh.idx() >= mesh_.n_halfedges()) {
|
||||||
|
_os << "MeshChecker: vertex " << vh
|
||||||
|
<< " has out-of-bounds outgoing HE: " << heh;
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
if (is_deleted(heh.edge())) {
|
||||||
|
_os << "MeshChecker: vertex " << vh
|
||||||
|
<< " has deleted outgoing HE: " << heh;
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -117,7 +120,7 @@ check(unsigned int _targets, std::ostream& _os)
|
|||||||
|
|
||||||
|
|
||||||
// check whether circulators are still in order
|
// check whether circulators are still in order
|
||||||
vv_it = mesh_.cvv_cwiter(vh);
|
auto vv_it = mesh_.cvv_cwiter(vh);
|
||||||
for (count=0; vv_it.is_valid() && (count < max_valence); ++vv_it, ++count) {};
|
for (count=0; vv_it.is_valid() && (count < max_valence); ++vv_it, ++count) {};
|
||||||
if (count == max_valence)
|
if (count == max_valence)
|
||||||
{
|
{
|
||||||
@@ -133,7 +136,6 @@ check(unsigned int _targets, std::ostream& _os)
|
|||||||
<< ": --circulator problem, one ring corrupt\n";
|
<< ": --circulator problem, one ring corrupt\n";
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,45 +150,61 @@ check(unsigned int _targets, std::ostream& _os)
|
|||||||
typename Mesh::HalfedgeHandle hh, hstart, hhh;
|
typename Mesh::HalfedgeHandle hh, hstart, hhh;
|
||||||
size_t count, n_halfedges = 2*mesh_.n_edges();
|
size_t count, n_halfedges = 2*mesh_.n_edges();
|
||||||
|
|
||||||
for (; h_it != h_end; ++h_it)
|
for (const auto hh: mesh_.halfedges())
|
||||||
{
|
{
|
||||||
if (!is_deleted(mesh_.edge_handle(*h_it)))
|
if (!hh.to().halfedge().is_valid()) {
|
||||||
|
_os << "MeshChecker: vertex " << hh.from()
|
||||||
|
<< " has no outgoing halfedge, but it is not isolated.\n";
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
// degenerated halfedge ?
|
||||||
|
if (mesh_.from_vertex_handle(hh) == mesh_.to_vertex_handle(hh))
|
||||||
{
|
{
|
||||||
hh = *h_it;
|
_os << "MeshChecker: halfedge " << hh
|
||||||
|
<< ": to-vertex == from-vertex\n";
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// degenerated halfedge ?
|
// next <-> prev check
|
||||||
if (mesh_.from_vertex_handle(hh) == mesh_.to_vertex_handle(hh))
|
if (mesh_.next_halfedge_handle(mesh_.prev_halfedge_handle(hh)) != hh)
|
||||||
{
|
{
|
||||||
_os << "MeshChecker: halfedge " << hh
|
_os << "MeshChecker: halfedge " << hh
|
||||||
<< ": to-vertex == from-vertex\n";
|
<< ": prev->next != this\n";
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// heh.to == heh.next.from?
|
||||||
|
if (mesh_.to_vertex_handle(hh) != mesh_.from_vertex_handle(
|
||||||
|
mesh_.next_halfedge_handle(hh)))
|
||||||
|
{
|
||||||
|
_os << "MeshChecker: halfedge " << hh
|
||||||
|
<< ".to != he.next.from\n";
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
// heh.from == heh.prev.to?
|
||||||
|
if (mesh_.from_vertex_handle(hh) != mesh_.to_vertex_handle(
|
||||||
|
mesh_.prev_halfedge_handle(hh)))
|
||||||
|
{
|
||||||
|
_os << "MeshChecker: halfedge " << hh
|
||||||
|
<< ".from != he.prev.to\n";
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// next <-> prev check
|
// halfedges should form a cycle
|
||||||
if (mesh_.next_halfedge_handle(mesh_.prev_halfedge_handle(hh)) != hh)
|
count=0; hstart=hhh=hh;
|
||||||
{
|
do
|
||||||
_os << "MeshChecker: halfedge " << hh
|
{
|
||||||
<< ": prev->next != this\n";
|
hhh = mesh_.next_halfedge_handle(hhh);
|
||||||
ok = false;
|
++count;
|
||||||
}
|
} while (hhh != hstart && count < n_halfedges);
|
||||||
|
|
||||||
|
if (count == n_halfedges)
|
||||||
// halfedges should form a cycle
|
{
|
||||||
count=0; hstart=hhh=hh;
|
_os << "MeshChecker: halfedges starting from " << hh
|
||||||
do
|
<< " do not form a cycle\n";
|
||||||
{
|
ok = false;
|
||||||
hhh = mesh_.next_halfedge_handle(hhh);
|
|
||||||
++count;
|
|
||||||
} while (hhh != hstart && count < n_halfedges);
|
|
||||||
|
|
||||||
if (count == n_halfedges)
|
|
||||||
{
|
|
||||||
_os << "MeshChecker: halfedges starting from " << hh
|
|
||||||
<< " do not form a cycle\n";
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user