Commit 9e4ec6a3 authored by Philip Trettner's avatar Philip Trettner
Browse files

added collapse stubs

parent 43331e55
......@@ -160,12 +160,22 @@ private:
/// same as add_or_get_edge but returns the apattrriate half-edge
halfedge_index add_or_get_halfedge(vertex_index v_from, vertex_index v_to);
/// connect two half-edges in a prev-next relation
void connect_prev_next(halfedge_index prev, halfedge_index next);
/// splits a face
vertex_index face_split(face_index f);
/// splits an edge
vertex_index edge_split(edge_index f);
vertex_index edge_split(edge_index e);
/// splits a half-edge
vertex_index halfedge_split(halfedge_index f);
vertex_index halfedge_split(halfedge_index h);
/// collapse a vertex
void vertex_collapse(vertex_handle v) const;
/// collapse an edge
void edge_collapse(edge_handle e) const;
/// collapse a half-edge
void halfedge_collapse(halfedge_handle h) const;
/// rotates an edge to next
void edge_rotate_next(edge_index e);
......
......@@ -530,6 +530,15 @@ inline halfedge_index Mesh::prev_valid_idx_from(halfedge_index idx) const
return {}; // invalid
}
inline void Mesh::connect_prev_next(halfedge_index prev, halfedge_index next)
{
auto& prev_ref = halfedge(prev);
auto& next_ref = halfedge(next);
prev_ref.next_halfedge = next;
next_ref.prev_halfedge = prev;
}
inline vertex_index Mesh::face_split(face_index f)
{
// TODO: can be made more performant
......@@ -558,19 +567,84 @@ inline vertex_index Mesh::face_split(face_index f)
return vs[0];
}
inline vertex_index Mesh::edge_split(edge_index f)
inline vertex_index Mesh::edge_split(edge_index e)
{
// remove edge
auto h0 = halfedge_of(e, 0);
auto h1 = halfedge_of(e, 1);
auto &h0_ref = halfedge(h0);
auto &h1_ref = halfedge(h1);
auto v0 = h0_ref.to_vertex;
auto v1 = h1_ref.to_vertex;
auto f0 = h0_ref.face;
auto f1 = h1_ref.face;
// add vertex
auto v = add_vertex();
// add two new edges
auto e1 = alloc_edge();
auto e2 = alloc_edge();
auto e1h0 = halfedge_of(e1, 0);
auto e1h1 = halfedge_of(e1, 1);
auto e2h0 = halfedge_of(e2, 0);
auto e2h1 = halfedge_of(e2, 1);
// rewire edges
auto &e1h0_ref = halfedge(e1h0);
auto &e1h1_ref = halfedge(e1h1);
auto &e2h0_ref = halfedge(e2h0);
auto &e2h1_ref = halfedge(e2h1);
assert(0 && "not implemented");
return {};
auto h0_prev = h0_ref.prev_halfedge;
auto h0_next = h0_ref.next_halfedge;
auto h1_prev = h1_ref.prev_halfedge;
auto h1_next = h1_ref.next_halfedge;
e1h0_ref.face = f0;
e2h0_ref.face = f0;
e1h1_ref.face = f1;
e2h1_ref.face = f1;
e1h0_ref.to_vertex = v0;
e2h0_ref.to_vertex = v;
e1h1_ref.to_vertex = v;
e2h1_ref.to_vertex = v1;
connect_prev_next(h0_prev, e2h0);
connect_prev_next(e2h0, e1h0);
connect_prev_next(e1h0, h0_next);
connect_prev_next(h1_prev, e1h1);
connect_prev_next(e1h1, e2h1);
connect_prev_next(e2h1, h1_next);
// rewire vertices
auto &v0_ref = vertex(h0_ref.to_vertex);
auto &v1_ref = vertex(h1_ref.to_vertex);
if (v0_ref.outgoing_halfedge == h1)
v0_ref.outgoing_halfedge = e1h1;
if (v1_ref.outgoing_halfedge == h0)
v1_ref.outgoing_halfedge = e2h0;
// rewire faces
auto &f0_ref = face(f0);
auto &f1_ref = face(f1);
if (f0_ref.halfedge == h0)
f0_ref.halfedge = e1h0;
if (f1_ref.halfedge == h1)
f1_ref.halfedge = e2h1;
// remove edge
h0_ref.set_removed();
h1_ref.set_removed();
mRemovedHalfedges += 2;
mCompact = false;
return v;
}
inline vertex_index Mesh::halfedge_split(halfedge_index f)
inline vertex_index Mesh::halfedge_split(halfedge_index h)
{
// add vertex
......@@ -580,6 +654,12 @@ inline vertex_index Mesh::halfedge_split(halfedge_index f)
return {};
}
inline void Mesh::vertex_collapse(vertex_handle v) const { assert(0 && "not implemented"); }
inline void Mesh::edge_collapse(edge_handle e) const { assert(0 && "not implemented"); }
inline void Mesh::halfedge_collapse(halfedge_handle h) const { assert(0 && "not implemented"); }
inline void Mesh::edge_rotate_next(edge_index e)
{
assert(!handle_of(e).is_boundary() && "does not work on boundaries");
......
......@@ -558,6 +558,24 @@ vertex_handle edge_collection<iterator>::split(edge_handle e) const
return this->mesh->handle_of(this->mesh->edge_split(e.idx));
}
template <class iterator>
void vertex_collection<iterator>::collapse(vertex_handle v) const
{
this->mesh->vertex_collapse(v.idx);
}
template<class iterator>
void edge_collection<iterator>::collapse(edge_handle e) const
{
this->mesh->edge_collapse(e.idx);
}
template<class iterator>
void halfedge_collection<iterator>::collapse(halfedge_handle h) const
{
this->mesh->halfedge_collapse(h.idx);
}
template <class iterator>
void edge_collection<iterator>::rotate_next(edge_handle e) const
{
......
......@@ -154,6 +154,10 @@ struct vertex_collection : smart_collection<Mesh*, vertex_tag, iterator>
/// Does NOT invalidate any iterator!
vertex_handle add() const;
/// Collapsed the given vertex by removing it and merging the adjacent faces
/// Preserves half-edge properties but not face ones
void collapse(vertex_handle v) const;
/// Removes a vertex (and all adjacent faces and edges)
/// (marks them as removed, compactify mesh to actually remove them)
void remove(vertex_handle v) const;
......@@ -208,6 +212,10 @@ struct edge_collection : smart_collection<Mesh*, edge_tag, iterator>
/// The edge itself is deleted and two new ones are created
vertex_handle split(edge_handle e) const;
/// Collapsed the given edge by removing it, adding a new vertex, and triangles for each opposite edge
/// Preserves half-edge properties but not face or vertex ones
void collapse(edge_handle e) const;
/// Moves both half-edges vertices to their next half-edge vertex
/// Equivalent to an edge flip if both faces are triangular
/// Preserves all attributes
......@@ -236,6 +244,11 @@ struct halfedge_collection : smart_collection<Mesh*, halfedge_tag, iterator>
/// O(valence) computation
halfedge_handle find(vertex_handle v_from, vertex_handle v_to) const;
/// Collapsed the given half-edge by removing it, keeping the to_vertex, and creating new triangles
/// Preserves half-edge properties but not face or vertex ones
/// Similar to a vertex collapse of the `from` vertex with triangulation towards `to`
void collapse(halfedge_handle h) const;
/// Splits this half-edge in half by inserting a vertex (which is returned)
/// Preserves face attributes
/// Contraty to edges().split, the edge is preserved and a single new one is inserted AFTER h
......@@ -436,4 +449,5 @@ struct halfedge_ring : halfedge_primitive_ring<halfedge_tag, halfedge_ring_circu
{
using halfedge_primitive_ring<halfedge_tag, halfedge_ring_circulator>::halfedge_primitive_ring;
};
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment