Extend MeshChecker to detect more invalid configurations.

This commit is contained in:
Martin Heistermann
2023-07-20 20:28:39 +02:00
parent 85a971f6bd
commit 197a80bcb8

View File

@@ -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;
}
} }
} }
} }