From c015a687bc1271e30de37aef914095949a3a62b6 Mon Sep 17 00:00:00 2001 From: TheNumbat <mjslater@andrew.cmu.edu> Date: Sun, 17 Oct 2021 03:38:10 -0400 Subject: [PATCH] add vert/edge/face accessibility check --- src/geometry/halfedge.cpp | 59 +++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/src/geometry/halfedge.cpp b/src/geometry/halfedge.cpp index 401b254..79e890f 100644 --- a/src/geometry/halfedge.cpp +++ b/src/geometry/halfedge.cpp @@ -375,6 +375,9 @@ std::optional<std::pair<Halfedge_Mesh::ElementRef, std::string>> Halfedge_Mesh:: if(!finite) return {{v, "A vertex position was set to a non-finite value."}}; } + std::unordered_map<VertexRef, std::set<HalfedgeRef>> v_accessible; + std::unordered_map<EdgeRef, std::set<HalfedgeRef>> e_accessible; + std::unordered_map<FaceRef, std::set<HalfedgeRef>> f_accessible; std::set<HalfedgeRef> permutation; // Check valid halfedge permutation @@ -406,24 +409,6 @@ std::optional<std::pair<Halfedge_Mesh::ElementRef, std::string>> Halfedge_Mesh:: } } - for(HalfedgeRef h = halfedges_begin(); h != halfedges_end(); h++) { - - if(herased.find(h) != herased.end()) continue; - - // Check whether each halfedge was pointed to by a halfedge - if(permutation.find(h) == permutation.end()) { - return {{h, "A halfedge is the next of zero halfedges!"}}; - } - - // Check twin relationships - if(h->twin() == h) { - return {{h, "A halfedge's twin is itself!"}}; - } - if(h->twin()->twin() != h) { - return {{h, "A halfedge's twin's twin is not itself!"}}; - } - } - // Check whether each halfedge incident on a vertex points to that vertex for(VertexRef v = vertices_begin(); v != vertices_end(); v++) { @@ -434,12 +419,15 @@ std::optional<std::pair<Halfedge_Mesh::ElementRef, std::string>> Halfedge_Mesh:: return {{v, "A vertex's halfedge is erased!"}}; } + std::set<HalfedgeRef> accessible; do { + accessible.insert(h); if(h->vertex() != v) { return {{h, "A vertex's halfedge does not point to that vertex!"}}; } h = h->twin()->next(); } while(h != v->halfedge()); + v_accessible[v] = std::move(accessible); } // Check whether each halfedge incident on an edge points to that edge @@ -452,12 +440,15 @@ std::optional<std::pair<Halfedge_Mesh::ElementRef, std::string>> Halfedge_Mesh:: return {{e, "An edge's halfedge is erased!"}}; } + std::set<HalfedgeRef> accessible; do { + accessible.insert(h); if(h->edge() != e) { return {{h, "An edge's halfedge does not point to that edge!"}}; } h = h->twin(); } while(h != e->halfedge()); + e_accessible[e] = std::move(accessible); } // Check whether each halfedge incident on a face points to that face @@ -470,12 +461,44 @@ std::optional<std::pair<Halfedge_Mesh::ElementRef, std::string>> Halfedge_Mesh:: return {{f, "A face's halfedge is erased!"}}; } + std::set<HalfedgeRef> accessible; do { + accessible.insert(h); if(h->face() != f) { return {{h, "A face's halfedge does not point to that face!"}}; } h = h->next(); } while(h != f->halfedge()); + f_accessible[f] = std::move(accessible); + } + + for(HalfedgeRef h = halfedges_begin(); h != halfedges_end(); h++) { + + if(herased.find(h) != herased.end()) continue; + + // Check whether each halfedge was pointed to by a halfedge + if(permutation.find(h) == permutation.end()) { + return {{h, "A halfedge is the next of zero halfedges!"}}; + } + + // Check twin relationships + if(h->twin() == h) { + return {{h, "A halfedge's twin is itself!"}}; + } + if(h->twin()->twin() != h) { + return {{h, "A halfedge's twin's twin is not itself!"}}; + } + + // Check that the halfedge can be found via its vertex, edge, and face + if(v_accessible[h->vertex()].count(h) == 0) { + return {{h, "A halfedge is not accessible from its vertex!"}}; + } + if(e_accessible[h->edge()].count(h) == 0) { + return {{h, "A halfedge is not accessible from its edge!"}}; + } + if(f_accessible[h->face()].count(h) == 0) { + return {{h, "A halfedge is not accessible from its face!"}}; + } } do_erase(); -- GitLab