Store previous edge in dcel edges to support non-triangle meshes

This commit is contained in:
Nikita Lisitsa 2022-09-17 00:37:52 +03:00
parent 83f1ac4202
commit 34d9e67960
3 changed files with 50 additions and 21 deletions

View file

@ -24,6 +24,7 @@ namespace psemek::cg
struct edge_rec : util::ebo_helper<Edge>
{
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<Index>(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 Point, typename Edge, typename Face, typename Index>
typename dcel<Point, Edge, Face, Index>::edge_handle dcel<Point, Edge, Face, Index>::edge_handle::prev() const
{
return edge_handle{this->owner_, get().prev};
}
template <typename Point, typename Edge, typename Face, typename Index>
typename dcel<Point, Edge, Face, Index>::edge_handle dcel<Point, Edge, Face, Index>::edge_handle::next() const
{
@ -439,6 +453,12 @@ namespace psemek::cg
get().origin = h.index();
}
template <typename Point, typename Edge, typename Face, typename Index>
void dcel<Point, Edge, Face, Index>::edge_handle::prev(edge_handle h) const
{
get().prev = h.index();
}
template <typename Point, typename Edge, typename Face, typename Index>
void dcel<Point, Edge, Face, Index>::edge_handle::next(edge_handle h) const
{
@ -469,6 +489,12 @@ namespace psemek::cg
return point_handle_const{this->owner_, get().origin};
}
template <typename Point, typename Edge, typename Face, typename Index>
typename dcel<Point, Edge, Face, Index>::edge_handle_const dcel<Point, Edge, Face, Index>::edge_handle_const::prev() const
{
return edge_handle_const{this->owner_, get().prev};
}
template <typename Point, typename Edge, typename Face, typename Index>
typename dcel<Point, Edge, Face, Index>::edge_handle_const dcel<Point, Edge, Face, Index>::edge_handle_const::next() const
{
@ -542,6 +568,7 @@ namespace psemek::cg
{
typename result_type::edge_rec rec;
rec.origin = static_cast<Index2>(e.origin);
rec.prev = static_cast<Index2>(e.prev);
rec.next = static_cast<Index2>(e.next);
rec.twin = static_cast<Index2>(e.twin);
rec.face = static_cast<Index2>(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;
}

View file

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

View file

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