Commit bfe307a3 authored by Philip Trettner's avatar Philip Trettner
Browse files

added add_or_get with edges

parent 8b89bacb
......@@ -18,7 +18,7 @@ Best used with glm and glow.
* smart ranges: filter, map
* vector, set, map -> range
* opposite edges (from vertex)
* cotangens weights etc.
* cotangents weights etc.
* smoothing
* make handle.<primitives>() contain only valid ones and provide an all_<primitives>() version
* _copy versions of topological operations that copy attributes
......@@ -28,4 +28,5 @@ Best used with glm and glow.
* attribute iterator
* primitive sort functions, better remap function, cache optimization
* structure of arrays instead of AOS
* lowlevel API that allows direct half-edge manipulation and does not fix boundaries (but also mirrors high level one)
\ No newline at end of file
* lowlevel API that allows direct half-edge manipulation and does not fix boundaries (but also mirrors high level one)
* primitive collection sort and sort_by functions
\ No newline at end of file
......@@ -161,9 +161,20 @@ private:
/// Adds an edge between two existing, distinct vertices
/// if edge already exists, returns it
edge_index add_or_get_edge(vertex_index v_from, vertex_index v_to);
/// Adds an edge between to existing, distinct vertices that are pointed to by two given halfedges
/// if edge already exists, returns it
edge_index add_or_get_edge(halfedge_index h_from, halfedge_index h_to);
/// same as add_or_get_edge but returns the apattrriate half-edge
/// Assures:
/// return_value.from_vertex == v_from
/// return_value.to_vertex == v_to
halfedge_index add_or_get_halfedge(vertex_index v_from, vertex_index v_to);
/// same as add_or_get_edge but returns the apattrriate half-edge
/// Assures:
/// return_value.from_vertex == h_from.to_vertex
/// return_value.to_vertex == h_to.to_vertex
halfedge_index add_or_get_halfedge(halfedge_index h_from, halfedge_index h_to);
/// connect two half-edges in a prev-next relation
void connect_prev_next(halfedge_index prev, halfedge_index next);
......
......@@ -213,6 +213,84 @@ inline halfedge_index Mesh::add_or_get_halfedge(vertex_index v_from, vertex_inde
return halfedge(h0).to_vertex == v_to ? h0 : h1;
}
inline edge_index Mesh::add_or_get_edge(halfedge_index h_from, halfedge_index h_to)
{
assert(h_from != h_to);
auto &hd_from = halfedge(h_from);
auto &hd_to = halfedge(h_to);
auto v_from = hd_from.to_vertex;
auto v_to = hd_to.to_vertex;
auto ex_he = find_halfedge(v_from, v_to);
if (ex_he.is_valid())
{
auto &existing_hed = halfedge(ex_he);
auto &ex_opp_hed = halfedge(opposite(ex_he));
assert(existing_hed.prev_halfedge == h_from && ex_opp_hed.prev_halfedge == h_to);
(void)existing_hed;
(void)ex_opp_hed;
// TODO: Maybe try rewriting an existing halfedge that does NOT yet have the right connection.
return edge_of(ex_he);
}
assert(hd_from.face.is_invalid() && hd_to.face.is_invalid() && "Cannot insert into a face");
// allocate new
auto he_size = (int)mHalfedges.size();
auto h_from_to_idx = halfedge_index(he_size + 0);
auto h_to_from_idx = halfedge_index(he_size + 1);
auto eidx = edge_index(he_size >> 1);
halfedge_info h_from_to;
halfedge_info h_to_from;
// setup data (self-connected edge)
h_from_to.to_vertex = v_to;
h_to_from.to_vertex = v_from;
// Link from side
auto h_from_next_idx = hd_from.next_halfedge;
auto &h_from_next = halfedge(h_from_next_idx);
hd_from.next_halfedge = h_from_to_idx;
h_from_to.prev_halfedge = h_from;
h_from_next.prev_halfedge = h_to_from_idx;
h_to_from.next_halfedge = h_from_next_idx;
// Link to side
auto h_to_next_idx = hd_to.next_halfedge;
auto &h_to_next = halfedge(h_to_next_idx);
hd_to.next_halfedge = h_to_from_idx;
h_to_from.prev_halfedge = h_to;
h_to_next.prev_halfedge = h_from_to_idx;
h_from_to.next_halfedge = h_to_next_idx;
// finalize
mHalfedges.push_back(h_from_to);
mHalfedges.push_back(h_to_from);
// notify attributes
auto hCnt = (int)mHalfedges.size();
auto eCnt = hCnt >> 1;
for (auto p = mHalfedgeAttrs; p; p = p->mNextAttribute)
p->resize(hCnt, false);
for (auto p = mEdgeAttrs; p; p = p->mNextAttribute)
p->resize(eCnt, false);
return eidx;
}
inline halfedge_index Mesh::add_or_get_halfedge(halfedge_index h_from, halfedge_index h_to)
{
auto e = add_or_get_edge(h_from, h_to);
auto h0 = halfedge_of(e, 0);
auto h1 = halfedge_of(e, 1);
return halfedge(h_from).next_halfedge == h0 ? h0 : h1;
}
inline void Mesh::make_adjacent(halfedge_index he_in, halfedge_index he_out)
{
// see http://kaba.hilvi.org/homepage/blog/halfedge/halfedge.htm ::makeAdjacent
......
......@@ -687,6 +687,18 @@ halfedge_handle halfedge_collection<iterator>::add_or_get(vertex_handle v_from,
return this->mesh->handle_of(this->mesh->add_or_get_halfedge(v_from.idx, v_to.idx));
}
template <class iterator>
edge_handle edge_collection<iterator>::add_or_get(halfedge_handle h_from, halfedge_handle h_to) const
{
return this->mesh->handle_of(this->mesh->add_or_get_edge(h_from.idx, h_to.idx));
}
template <class iterator>
halfedge_handle halfedge_collection<iterator>::add_or_get(halfedge_handle h_from, halfedge_handle h_to) const
{
return this->mesh->handle_of(this->mesh->add_or_get_halfedge(h_from.idx, h_to.idx));
}
template <class iterator>
edge_handle edge_collection<iterator>::find(vertex_handle v_from, vertex_handle v_to) const
{
......
......@@ -253,6 +253,9 @@ struct edge_collection : smart_collection<Mesh*, edge_tag, iterator>
/// Adds an edge between two existing, distinct vertices
/// if edge already exists, returns it
edge_handle add_or_get(vertex_handle v_from, vertex_handle v_to) const;
/// Adds an edge between two existing, distict halfedges
/// if edge already exists, returns it
edge_handle add_or_get(halfedge_handle h_from, halfedge_handle h_to) const;
/// Returns the edge handle between two vertices (invalid if not found)
/// O(valence) computation
......@@ -291,6 +294,10 @@ struct halfedge_collection : smart_collection<Mesh*, halfedge_tag, iterator>
/// if half-edge already exists, returns it
/// (always adds opposite half-edge as well)
halfedge_handle add_or_get(vertex_handle v_from, vertex_handle v_to) const;
/// Adds an half-edge between two existing, distinct hafledges
/// if half-edge already exists, returns it
/// (always adds opposite half-edge as well)
halfedge_handle add_or_get(halfedge_handle h_from, halfedge_handle h_to) const;
/// Returns the half-edge handle between two vertices (invalid if not found)
/// O(valence) computation
......
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