From 57f98ce1fd7656c2a875a4bb1421ec587999a03a Mon Sep 17 00:00:00 2001 From: TheNumbat Date: Wed, 30 Sep 2020 20:32:32 -0400 Subject: [PATCH] fix multi-boundary mesh loading --- src/geometry/halfedge.cpp | 39 +++++++++++++++++++++------------------ src/geometry/halfedge.h | 1 + src/gui/model.cpp | 32 ++++++++++++++++++-------------- 3 files changed, 40 insertions(+), 32 deletions(-) diff --git a/src/geometry/halfedge.cpp b/src/geometry/halfedge.cpp index 55de9bd..9edf1d1 100644 --- a/src/geometry/halfedge.cpp +++ b/src/geometry/halfedge.cpp @@ -28,6 +28,7 @@ void Halfedge_Mesh::clear() { faces.clear(); boundaries.clear(); render_dirty_flag = true; + next_id = Gui::n_Widget_IDs; } void Halfedge_Mesh::copy_to(Halfedge_Mesh &mesh) { copy_to(mesh, 0); } @@ -42,10 +43,10 @@ Halfedge_Mesh::ElementRef Halfedge_Mesh::copy_to(Halfedge_Mesh &mesh, unsigned i // with elements of the new mesh. (Note that we can use a single // map for both interior and boundary faces, because the map // doesn't care which list of faces these iterators come from.) - std::unordered_map halfedgeOldToNew(n_halfedges()); - std::unordered_map vertexOldToNew(n_vertices()); - std::unordered_map edgeOldToNew(n_edges()); - std::unordered_map faceOldToNew(n_faces()); + std::unordered_map halfedgeOldToNew(n_halfedges()); + std::unordered_map vertexOldToNew(n_vertices()); + std::unordered_map edgeOldToNew(n_edges()); + std::unordered_map faceOldToNew(n_faces()); // Copy geometry from the original mesh and create a map from // pointers in the original mesh to those in the new mesh. @@ -53,49 +54,49 @@ Halfedge_Mesh::ElementRef Halfedge_Mesh::copy_to(Halfedge_Mesh &mesh, unsigned i auto hn = mesh.halfedges.insert(mesh.halfedges.end(), *h); if (h->id() == eid) ret = hn; - halfedgeOldToNew[h] = hn; + halfedgeOldToNew[h->id()] = hn; } for (VertexCRef v = vertices_begin(); v != vertices_end(); v++) { auto vn = mesh.vertices.insert(mesh.vertices.end(), *v); if (v->id() == eid) ret = vn; - vertexOldToNew[v] = vn; + vertexOldToNew[v->id()] = vn; } for (EdgeCRef e = edges_begin(); e != edges_end(); e++) { auto en = mesh.edges.insert(mesh.edges.end(), *e); if (e->id() == eid) ret = en; - edgeOldToNew[e] = en; + edgeOldToNew[e->id()] = en; } for (FaceCRef f = faces_begin(); f != faces_end(); f++) { auto fn = mesh.faces.insert(mesh.faces.end(), *f); if (f->id() == eid) ret = fn; - faceOldToNew[f] = fn; + faceOldToNew[f->id()] = fn; } for (FaceCRef b = boundaries_begin(); b != boundaries_end(); b++) { auto bn = mesh.boundaries.insert(mesh.boundaries.end(), *b); if (b->id() == eid) ret = bn; - faceOldToNew[b] = bn; + faceOldToNew[b->id()] = bn; } // "Search and replace" old pointers with new ones. for (HalfedgeRef he = mesh.halfedges_begin(); he != mesh.halfedges_end(); he++) { - he->next() = halfedgeOldToNew[he->next()]; - he->twin() = halfedgeOldToNew[he->twin()]; - he->vertex() = vertexOldToNew[he->vertex()]; - he->edge() = edgeOldToNew[he->edge()]; - he->face() = faceOldToNew[he->face()]; + he->next() = halfedgeOldToNew[he->next()->id()]; + he->twin() = halfedgeOldToNew[he->twin()->id()]; + he->vertex() = vertexOldToNew[he->vertex()->id()]; + he->edge() = edgeOldToNew[he->edge()->id()]; + he->face() = faceOldToNew[he->face()->id()]; } for (VertexRef v = mesh.vertices_begin(); v != mesh.vertices_end(); v++) - v->halfedge() = halfedgeOldToNew[v->halfedge()]; + v->halfedge() = halfedgeOldToNew[v->halfedge()->id()]; for (EdgeRef e = mesh.edges_begin(); e != mesh.edges_end(); e++) - e->halfedge() = halfedgeOldToNew[e->halfedge()]; + e->halfedge() = halfedgeOldToNew[e->halfedge()->id()]; for (FaceRef f = mesh.faces_begin(); f != mesh.faces_end(); f++) - f->halfedge() = halfedgeOldToNew[f->halfedge()]; + f->halfedge() = halfedgeOldToNew[f->halfedge()->id()]; for (FaceRef b = mesh.boundaries_begin(); b != mesh.boundaries_end(); b++) - b->halfedge() = halfedgeOldToNew[b->halfedge()]; + b->halfedge() = halfedgeOldToNew[b->halfedge()->id()]; mesh.render_dirty_flag = true; mesh.next_id = next_id; @@ -467,6 +468,8 @@ bool Halfedge_Mesh::subdivide(SubD strategy) { } break; case SubD::loop: { + if (boundaries.size()) + return false; for (FaceRef f = faces_begin(); f != faces_end(); f++) { if (f->degree() != 3) return false; diff --git a/src/geometry/halfedge.h b/src/geometry/halfedge.h index d78e4f3..d1161f6 100644 --- a/src/geometry/halfedge.h +++ b/src/geometry/halfedge.h @@ -508,6 +508,7 @@ public: Size n_vertices() const { return vertices.size(); }; Size n_edges() const { return edges.size(); }; Size n_faces() const { return faces.size(); }; + Size n_boundaries() const { return boundaries.size(); }; Size n_halfedges() const { return halfedges.size(); }; /// Check if half-edge mesh is valid diff --git a/src/gui/model.cpp b/src/gui/model.cpp index b35f986..7ec0584 100644 --- a/src/gui/model.cpp +++ b/src/gui/model.cpp @@ -62,24 +62,30 @@ void Model::update_vertex(Halfedge_Mesh::VertexRef vert) { vertex_viz(v, d, vi.transform); vert_sizes[v->id()] = d; - size_t idx = id_to_info[h->face()->id()].instance; - face_viz(h->face(), face_mesh.edit_verts(), face_mesh.edit_indices(), idx); - - Halfedge_Mesh::HalfedgeRef fh = h->face()->halfedge(); - do { - halfedge_viz(fh, arrows.get(id_to_info[fh->id()].instance).transform); - fh = fh->next(); - } while (fh != h->face()->halfedge()); + if(!h->face()->is_boundary()) { + size_t idx = id_to_info[h->face()->id()].instance; + face_viz(h->face(), face_mesh.edit_verts(), face_mesh.edit_indices(), idx); + + Halfedge_Mesh::HalfedgeRef fh = h->face()->halfedge(); + do { + halfedge_viz(fh, arrows.get(id_to_info[fh->id()].instance).transform); + fh = fh->next(); + } while (fh != h->face()->halfedge()); + } h = h->twin()->next(); } while (h != vert->halfedge()); // Update surrounding halfedges & edges do { - GL::Instances::Info &hi = arrows.get(id_to_info[h->id()].instance); - halfedge_viz(h, hi.transform); - GL::Instances::Info &thi = arrows.get(id_to_info[h->twin()->id()].instance); - halfedge_viz(h->twin(), thi.transform); + if(!h->is_boundary()) { + GL::Instances::Info &hi = arrows.get(id_to_info[h->id()].instance); + halfedge_viz(h, hi.transform); + } + if(!h->twin()->is_boundary()) { + GL::Instances::Info &thi = arrows.get(id_to_info[h->twin()->id()].instance); + halfedge_viz(h->twin(), thi.transform); + } GL::Instances::Info &e = cylinders.get(id_to_info[h->edge()->id()].instance); edge_viz(h->edge(), e.transform); @@ -375,8 +381,6 @@ void Model::rebuild() { std::vector idxs; for (auto f = mesh.faces_begin(); f != mesh.faces_end(); f++) { - if (f->is_boundary()) - continue; face_viz(f, verts, idxs, verts.size()); } face_mesh.recreate(std::move(verts), std::move(idxs)); -- GitLab