From 34d9e6796042e0cf4832e091d6475dd4419e33f1 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Sat, 17 Sep 2022 00:37:52 +0300 Subject: [PATCH] Store previous edge in dcel edges to support non-triangle meshes --- libs/cg/include/psemek/cg/dcel.hpp | 37 +++++++++++++++++-- .../psemek/cg/triangulation/delaunay.hpp | 12 +++--- .../psemek/cg/triangulation/triangulation.hpp | 22 +++++------ 3 files changed, 50 insertions(+), 21 deletions(-) diff --git a/libs/cg/include/psemek/cg/dcel.hpp b/libs/cg/include/psemek/cg/dcel.hpp index ab1c7a96..8d87016d 100644 --- a/libs/cg/include/psemek/cg/dcel.hpp +++ b/libs/cg/include/psemek/cg/dcel.hpp @@ -24,6 +24,7 @@ namespace psemek::cg struct edge_rec : util::ebo_helper { Index origin; + Index prev; Index next; Index twin; Index face; @@ -160,11 +161,13 @@ namespace psemek::cg Edge & data() const; point_handle origin() const; + edge_handle prev() const; edge_handle next() const; edge_handle twin() const; face_handle face() const; void origin(point_handle h) const; + void prev(edge_handle h) const; void next(edge_handle h) const; void twin(edge_handle h) const; void face(face_handle h) const; @@ -185,6 +188,7 @@ namespace psemek::cg Edge const & data() const; point_handle_const origin() const; + edge_handle_const prev() const; edge_handle_const next() const; edge_handle_const twin() const; face_handle_const face() const; @@ -274,7 +278,7 @@ namespace psemek::cg edge_handle push_edge(Edge data = {}) { auto i = static_cast(edges.size()); - edges.push_back({{std::move(data)}, null, null, null, null}); + edges.push_back({{std::move(data)}, null, null, null, null, null}); return edge(i); } @@ -298,7 +302,7 @@ namespace psemek::cg edge_handle insert_edge(Index i, Edge data = {}) { - edges.insert(edges.begin() + i, {{std::move(data)}, null, null, null, null}); + edges.insert(edges.begin() + i, {{std::move(data)}, null, null, null, null, null}); for (auto & p : points) { if (p.edge >= i) @@ -306,6 +310,8 @@ namespace psemek::cg } for (auto & e : edges) { + if (e.prev >= i) + ++e.prev; if (e.next >= i) ++e.next; if (e.twin >= i) @@ -350,6 +356,8 @@ namespace psemek::cg } for (auto & e : edges) { + if (e.prev > h.index()) + --e.prev; if (e.next > h.index()) --e.next; if (e.twin > h.index()) @@ -415,6 +423,12 @@ namespace psemek::cg return point_handle{this->owner_, get().origin}; } + template + typename dcel::edge_handle dcel::edge_handle::prev() const + { + return edge_handle{this->owner_, get().prev}; + } + template typename dcel::edge_handle dcel::edge_handle::next() const { @@ -439,6 +453,12 @@ namespace psemek::cg get().origin = h.index(); } + template + void dcel::edge_handle::prev(edge_handle h) const + { + get().prev = h.index(); + } + template void dcel::edge_handle::next(edge_handle h) const { @@ -469,6 +489,12 @@ namespace psemek::cg return point_handle_const{this->owner_, get().origin}; } + template + typename dcel::edge_handle_const dcel::edge_handle_const::prev() const + { + return edge_handle_const{this->owner_, get().prev}; + } + template typename dcel::edge_handle_const dcel::edge_handle_const::next() const { @@ -542,6 +568,7 @@ namespace psemek::cg { typename result_type::edge_rec rec; rec.origin = static_cast(e.origin); + rec.prev = static_cast(e.prev); rec.next = static_cast(e.next); rec.twin = static_cast(e.twin); rec.face = static_cast(e.face); @@ -587,12 +614,14 @@ namespace psemek::cg result.points[i].edge = 2 * i; result.edges[2 * i].face = 0; - result.edges[2 * i].next = (2 * i + 2) % (2 * N); + result.edges[2 * i].prev = 2 * ((i + N - 1) % N); + result.edges[2 * i].next = 2 * ((i + 1) % N); result.edges[2 * i].twin = 2 * i + 1; result.edges[2 * i].origin = i; result.edges[2 * i + 1].face = 1; - result.edges[2 * i + 1].next = (2 * i + 2 * N - 1) % (2 * N); + result.edges[2 * i + 1].prev = 2 * ((i + 1) % N) + 1; + result.edges[2 * i + 1].next = 2 * ((i + N - 1) % N) + 1; result.edges[2 * i + 1].twin = 2 * i; result.edges[2 * i + 1].origin = (i + 1) % N; } diff --git a/libs/cg/include/psemek/cg/triangulation/delaunay.hpp b/libs/cg/include/psemek/cg/triangulation/delaunay.hpp index 6d6995a9..f5e46816 100644 --- a/libs/cg/include/psemek/cg/triangulation/delaunay.hpp +++ b/libs/cg/include/psemek/cg/triangulation/delaunay.hpp @@ -66,20 +66,20 @@ namespace psemek::cg auto f1 = twin.face(); e.origin(p0); - e.next(tprev); + e.next(tprev); tprev.prev(e); - next.next(e); + next.next(e); e.prev(next); prev.face(f1); - prev.next(tnext); + prev.next(tnext); tnext.prev(prev); twin.origin(p3); - twin.next(prev); + twin.next(prev); prev.prev(twin); - tnext.next(twin); + tnext.next(twin); twin.prev(tnext); tprev.face(f0); - tprev.next(next); + tprev.next(next); next.prev(tprev); p1.edge(tnext); p2.edge(next); diff --git a/libs/cg/include/psemek/cg/triangulation/triangulation.hpp b/libs/cg/include/psemek/cg/triangulation/triangulation.hpp index af1d5d76..7dcc7b32 100644 --- a/libs/cg/include/psemek/cg/triangulation/triangulation.hpp +++ b/libs/cg/include/psemek/cg/triangulation/triangulation.hpp @@ -61,11 +61,11 @@ namespace psemek::cg p1.edge(e10); e01.origin(p0); - e01.next(e10); + e01.next(e10); e10.prev(e01); e01.face(outer_face); e01.twin(e10); e10.origin(p1); - e10.next(e01); + e10.next(e01); e01.prev(e10); e10.face(outer_face); e10.twin(e01); outer_face.edge(e01); @@ -155,14 +155,14 @@ namespace psemek::cg auto pnext = result.push_edge(); auto pprev = result.push_edge(); - qprev.next(pprev); + qprev.next(pprev); pprev.prev(qprev); - pprev.next(pnext); + pprev.next(pnext); pnext.prev(pprev); pprev.origin(q); pprev.twin(pnext); pprev.face(outer_face); - pnext.next(qnext); + pnext.next(qnext); qnext.prev(pnext); pnext.origin(p); pnext.twin(pprev); pnext.face(outer_face); @@ -188,7 +188,7 @@ namespace psemek::cg { prev_hull_edge = prev_hull_edge.next().twin(); } - prev_hull_edge.next(first_mid_edge); + prev_hull_edge.next(first_mid_edge); first_mid_edge.prev(prev_hull_edge); } // until current edge is visible @@ -209,15 +209,15 @@ namespace psemek::cg mid_edge.twin(ep0); ep0.origin(p); - ep0.next(cur_hull_edge); + ep0.next(cur_hull_edge); cur_hull_edge.prev(ep0); ep0.twin(mid_edge); ep0.face(f); e1p.origin(hp1); - e1p.next(ep0); + e1p.next(ep0); ep0.prev(e1p); e1p.face(f); - cur_hull_edge.next(e1p); + cur_hull_edge.next(e1p); e1p.prev(cur_hull_edge); cur_hull_edge.face(f); f.edge(ep0); @@ -231,11 +231,11 @@ namespace psemek::cg last_mid_edge.origin(p); last_mid_edge.face(outer_face); last_mid_edge.twin(mid_edge); - last_mid_edge.next(cur_hull_edge); + last_mid_edge.next(cur_hull_edge); cur_hull_edge.prev(last_mid_edge); mid_edge.twin(last_mid_edge); - first_mid_edge.next(last_mid_edge); + first_mid_edge.next(last_mid_edge); last_mid_edge.prev(first_mid_edge); // update first hull edge