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

primitive iterators and circulators finished

parent 83b5410a
......@@ -9,6 +9,8 @@
namespace polymesh
{
// ================= ITERATOR =================
template <typename tag>
struct valid_primitive_iterator
{
......@@ -20,11 +22,11 @@ struct valid_primitive_iterator
handle_t operator*() const { return handle; }
valid_primitive_iterator& operator++()
{
handle.idx.value++;
++handle.idx.value;
handle.idx = handle.mesh->next_valid_idx_from(handle.idx);
return *this;
}
valid_primitive_iterator operator++(int)
valid_primitive_iterator operator++(int) const
{
auto i = *this;
return ++i;
......@@ -57,10 +59,10 @@ struct all_primitive_iterator
handle_t operator*() const { return handle; }
all_primitive_iterator& operator++()
{
handle.idx.value++;
++handle.idx.value;
return *this;
}
all_primitive_iterator operator++(int)
all_primitive_iterator operator++(int) const
{
auto i = *this;
return ++i;
......@@ -82,312 +84,98 @@ private:
handle_t handle;
};
// ===========================================
// OLD CODE:
// ================= CIRCULATOR =================
/// Iterates over all vertices of a given face
struct face_vertex_circulator
/// Generic half-edge circulator (via CRTP)
/// implement operator* given the current `handle`
/// implement void advance() to change `handle`
/// inherit ctor's from primitive_circulator
template<typename this_t>
struct primitive_circulator
{
face_vertex_circulator() = default;
face_vertex_circulator(face_handle handle, bool not_at_begin) : handle(handle.any_halfedge()), not_at_begin(not_at_begin) {}
primitive_circulator() = default;
primitive_circulator(halfedge_handle handle, bool not_at_begin) : handle(handle), not_at_begin(not_at_begin) {}
vertex_handle operator*() const { return handle.vertex_to(); }
face_vertex_circulator& operator++()
primitive_circulator& operator++()
{
handle = handle.next();
static_cast<this_t*>(this)->advance();
not_at_begin = true;
return *this;
}
face_vertex_circulator operator++(int)
primitive_circulator operator++(int) const
{
auto i = *this;
return ++i;
}
bool operator==(face_vertex_circulator const& rhs) const
bool operator==(primitive_circulator const& rhs) const
{
assert(handle.mesh == rhs.handle.mesh && "comparing iterators from different meshes");
return not_at_begin == rhs.not_at_begin && handle.idx == rhs.handle.idx;
}
bool operator!=(face_vertex_circulator const& rhs) const
bool operator!=(primitive_circulator const& rhs) const
{
assert(handle.mesh == rhs.handle.mesh && "comparing iterators from different meshes");
return not_at_begin != rhs.not_at_begin || handle.idx != rhs.handle.idx;
}
private:
protected:
halfedge_handle handle;
bool not_at_begin;
};
/// Iterates over all halfedges of a given face
struct face_halfedge_circulator
struct face_vertex_circulator : primitive_circulator<face_vertex_circulator>
{
face_halfedge_circulator() = default;
face_halfedge_circulator(face_handle handle, bool not_at_begin) : handle(handle.any_halfedge()), not_at_begin(not_at_begin) {}
using primitive_circulator<face_vertex_circulator>::primitive_circulator;
vertex_handle operator*() const { return handle.vertex_to(); }
void advance() { handle = handle.next(); }
};
struct face_halfedge_circulator : primitive_circulator<face_halfedge_circulator>
{
using primitive_circulator<face_halfedge_circulator>::primitive_circulator;
halfedge_handle operator*() const { return handle; }
face_halfedge_circulator& operator++()
{
handle = handle.next();
not_at_begin = true;
return *this;
}
face_halfedge_circulator operator++(int)
{
auto i = *this;
return ++i;
}
bool operator==(face_halfedge_circulator const& rhs) const
{
assert(handle.mesh == rhs.handle.mesh && "comparing iterators from different meshes");
return not_at_begin == rhs.not_at_begin && handle.idx == rhs.handle.idx;
}
bool operator!=(face_halfedge_circulator const& rhs) const
{
assert(handle.mesh == rhs.handle.mesh && "comparing iterators from different meshes");
return not_at_begin != rhs.not_at_begin || handle.idx != rhs.handle.idx;
}
private:
halfedge_handle handle;
bool not_at_begin;
void advance() { handle = handle.next(); }
};
/// Iterates over all edges of a given face
struct face_edge_circulator
struct face_edge_circulator : primitive_circulator<face_edge_circulator>
{
face_edge_circulator() = default;
face_edge_circulator(face_handle handle, bool not_at_begin) : handle(handle.any_halfedge()), not_at_begin(not_at_begin) {}
using primitive_circulator<face_edge_circulator>::primitive_circulator;
edge_handle operator*() const { return handle.edge(); }
face_edge_circulator& operator++()
{
handle = handle.next();
not_at_begin = true;
return *this;
}
face_edge_circulator operator++(int)
{
auto i = *this;
return ++i;
}
bool operator==(face_edge_circulator const& rhs) const
{
assert(handle.mesh == rhs.handle.mesh && "comparing iterators from different meshes");
return not_at_begin == rhs.not_at_begin && handle.idx == rhs.handle.idx;
}
bool operator!=(face_edge_circulator const& rhs) const
{
assert(handle.mesh == rhs.handle.mesh && "comparing iterators from different meshes");
return not_at_begin != rhs.not_at_begin || handle.idx != rhs.handle.idx;
}
private:
halfedge_handle handle;
bool not_at_begin;
void advance() { handle = handle.next(); }
};
/// Iterates over all adjacent faces of a given face
struct face_face_circulator
struct face_face_circulator : primitive_circulator<face_vertex_circulator>
{
face_face_circulator() = default;
face_face_circulator(face_handle handle, bool not_at_begin) : handle(handle.any_halfedge()), not_at_begin(not_at_begin) {}
using primitive_circulator<face_vertex_circulator>::primitive_circulator;
face_handle operator*() const { return handle.opposite_face(); }
face_face_circulator& operator++()
{
handle = handle.next();
not_at_begin = true;
return *this;
}
face_face_circulator operator++(int)
{
auto i = *this;
return ++i;
}
bool operator==(face_face_circulator const& rhs) const
{
assert(handle.mesh == rhs.handle.mesh && "comparing iterators from different meshes");
return not_at_begin == rhs.not_at_begin && handle.idx == rhs.handle.idx;
}
bool operator!=(face_face_circulator const& rhs) const
{
assert(handle.mesh == rhs.handle.mesh && "comparing iterators from different meshes");
return not_at_begin != rhs.not_at_begin || handle.idx != rhs.handle.idx;
}
private:
halfedge_handle handle;
bool not_at_begin;
void advance() { handle = handle.next(); }
};
/// Iterates over all outgoing halfedges of a given vertex
struct vertex_halfedge_out_circulator
struct vertex_halfedge_out_circulator : primitive_circulator<vertex_halfedge_out_circulator>
{
vertex_halfedge_out_circulator() = default;
vertex_halfedge_out_circulator(vertex_handle handle, bool not_at_begin) : handle(handle.any_outgoing_halfedge()), not_at_begin(not_at_begin) {}
using primitive_circulator<vertex_halfedge_out_circulator>::primitive_circulator;
halfedge_handle operator*() const { return handle; }
vertex_halfedge_out_circulator& operator++()
{
handle = handle.opposite().next();
not_at_begin = true;
return *this;
}
vertex_halfedge_out_circulator operator++(int)
{
auto i = *this;
return ++i;
}
bool operator==(vertex_halfedge_out_circulator const& rhs) const
{
assert(handle.mesh == rhs.handle.mesh && "comparing iterators from different meshes");
return not_at_begin == rhs.not_at_begin && handle.idx == rhs.handle.idx;
}
bool operator!=(vertex_halfedge_out_circulator const& rhs) const
{
assert(handle.mesh == rhs.handle.mesh && "comparing iterators from different meshes");
return not_at_begin != rhs.not_at_begin || handle.idx != rhs.handle.idx;
}
private:
halfedge_handle handle;
bool not_at_begin;
void advance() { handle = handle.opposite().next(); }
};
/// Iterates over all incoming halfedges of a given vertex
struct vertex_halfedge_in_circulator
struct vertex_halfedge_in_circulator : primitive_circulator<vertex_halfedge_in_circulator>
{
vertex_halfedge_in_circulator() = default;
vertex_halfedge_in_circulator(vertex_handle handle, bool not_at_begin) : handle(handle.any_outgoing_halfedge()), not_at_begin(not_at_begin) {}
using primitive_circulator<vertex_halfedge_in_circulator>::primitive_circulator;
halfedge_handle operator*() const { return handle.opposite(); }
vertex_halfedge_in_circulator& operator++()
{
handle = handle.opposite().next();
not_at_begin = true;
return *this;
}
vertex_halfedge_in_circulator operator++(int)
{
auto i = *this;
return ++i;
}
bool operator==(vertex_halfedge_in_circulator const& rhs) const
{
assert(handle.mesh == rhs.handle.mesh && "comparing iterators from different meshes");
return not_at_begin == rhs.not_at_begin && handle.idx == rhs.handle.idx;
}
bool operator!=(vertex_halfedge_in_circulator const& rhs) const
{
assert(handle.mesh == rhs.handle.mesh && "comparing iterators from different meshes");
return not_at_begin != rhs.not_at_begin || handle.idx != rhs.handle.idx;
}
private:
halfedge_handle handle;
bool not_at_begin;
void advance() { handle = handle.opposite().next(); }
};
/// Iterates over all adjacent faces of a given vertex INCLUDING invalid ones
struct vertex_face_circulator
struct vertex_face_circulator : primitive_circulator<vertex_face_circulator>
{
vertex_face_circulator() = default;
vertex_face_circulator(vertex_handle handle, bool not_at_begin) : handle(handle.any_outgoing_halfedge()), not_at_begin(not_at_begin) {}
using primitive_circulator<vertex_face_circulator>::primitive_circulator;
face_handle operator*() const { return handle.face(); }
vertex_face_circulator& operator++()
{
handle = handle.opposite().next();
not_at_begin = true;
return *this;
}
vertex_face_circulator operator++(int)
{
auto i = *this;
return ++i;
}
bool operator==(vertex_face_circulator const& rhs) const
{
assert(handle.mesh == rhs.handle.mesh && "comparing iterators from different meshes");
return not_at_begin == rhs.not_at_begin && handle.idx == rhs.handle.idx;
}
bool operator!=(vertex_face_circulator const& rhs) const
{
assert(handle.mesh == rhs.handle.mesh && "comparing iterators from different meshes");
return not_at_begin != rhs.not_at_begin || handle.idx != rhs.handle.idx;
}
private:
halfedge_handle handle;
bool not_at_begin;
void advance() { handle = handle.opposite().next(); }
};
/// Iterates over all adjacent vertices of a given vertex
struct vertex_vertex_circulator
struct vertex_vertex_circulator : primitive_circulator<vertex_vertex_circulator>
{
vertex_vertex_circulator() = default;
vertex_vertex_circulator(vertex_handle handle, bool not_at_begin) : handle(handle.any_outgoing_halfedge()), not_at_begin(not_at_begin) {}
using primitive_circulator<vertex_vertex_circulator>::primitive_circulator;
vertex_handle operator*() const { return handle.vertex_to(); }
vertex_vertex_circulator& operator++()
{
handle = handle.opposite().next();
not_at_begin = true;
return *this;
}
vertex_vertex_circulator operator++(int)
{
auto i = *this;
return ++i;
}
bool operator==(vertex_vertex_circulator const& rhs) const
{
assert(handle.mesh == rhs.handle.mesh && "comparing iterators from different meshes");
return not_at_begin == rhs.not_at_begin && handle.idx == rhs.handle.idx;
}
bool operator!=(vertex_vertex_circulator const& rhs) const
{
assert(handle.mesh == rhs.handle.mesh && "comparing iterators from different meshes");
return not_at_begin != rhs.not_at_begin || handle.idx != rhs.handle.idx;
}
private:
halfedge_handle handle;
bool not_at_begin;
void advance() { handle = handle.opposite().next(); }
};
/// Iterates over all adjacent edges of a given vertex
struct vertex_edge_circulator
struct vertex_edge_circulator : primitive_circulator<vertex_edge_circulator>
{
vertex_edge_circulator() = default;
vertex_edge_circulator(vertex_handle handle, bool not_at_begin) : handle(handle.any_outgoing_halfedge()), not_at_begin(not_at_begin) {}
using primitive_circulator<vertex_edge_circulator>::primitive_circulator;
edge_handle operator*() const { return handle.edge(); }
vertex_edge_circulator& operator++()
{
handle = handle.opposite().next();
not_at_begin = true;
return *this;
}
vertex_edge_circulator operator++(int)
{
auto i = *this;
return ++i;
}
bool operator==(vertex_edge_circulator const& rhs) const
{
assert(handle.mesh == rhs.handle.mesh && "comparing iterators from different meshes");
return not_at_begin == rhs.not_at_begin && handle.idx == rhs.handle.idx;
}
bool operator!=(vertex_edge_circulator const& rhs) const
{
assert(handle.mesh == rhs.handle.mesh && "comparing iterators from different meshes");
return not_at_begin != rhs.not_at_begin || handle.idx != rhs.handle.idx;
}
private:
halfedge_handle handle;
bool not_at_begin;
void advance() { handle = handle.opposite().next(); }
};
}
......@@ -7,6 +7,8 @@
namespace polymesh
{
// ================= COLLECTION =================
template <class mesh_ptr, class tag, class iterator>
struct smart_collection
{
......@@ -180,6 +182,8 @@ struct valid_halfedge_const_collection : smart_collection<Mesh const*, halfedge_
{
};
// ================= RINGS =================
// rings
/// all vertices belonging to a face
......@@ -194,8 +198,8 @@ struct face_vertex_ring
bool contains(vertex_handle v) const;
// Iteration:
face_vertex_circulator begin() const { return {face, false}; }
face_vertex_circulator end() const { return {face, true}; }
face_vertex_circulator begin() const { return {face.any_halfedge(), false}; }
face_vertex_circulator end() const { return {face.any_halfedge(), true}; }
};
/// all halfedges belonging to a face
......@@ -210,8 +214,8 @@ struct face_halfedge_ring
bool contains(halfedge_handle h) const;
// Iteration:
face_halfedge_circulator begin() const { return {face, false}; }
face_halfedge_circulator end() const { return {face, true}; }
face_halfedge_circulator begin() const { return {face.any_halfedge(), false}; }
face_halfedge_circulator end() const { return {face.any_halfedge(), true}; }
};
/// all edges belonging to a face
......@@ -226,8 +230,8 @@ struct face_edge_ring
bool contains(edge_handle e) const;
// Iteration:
face_edge_circulator begin() const { return {face, false}; }
face_edge_circulator end() const { return {face, true}; }
face_edge_circulator begin() const { return {face.any_halfedge(), false}; }
face_edge_circulator end() const { return {face.any_halfedge(), true}; }
};
/// all adjacent faces belonging to a face
......@@ -242,8 +246,8 @@ struct face_face_ring
bool contains(face_handle f) const;
// Iteration:
face_face_circulator begin() const { return {face, false}; }
face_face_circulator end() const { return {face, true}; }
face_face_circulator begin() const { return {face.any_halfedge(), false}; }
face_face_circulator end() const { return {face.any_halfedge(), true}; }
};
/// all outgoing half-edges from a vertex
......@@ -258,8 +262,8 @@ struct vertex_halfedge_out_ring
bool contains(halfedge_handle h) const;
// Iteration:
vertex_halfedge_out_circulator begin() const { return {vertex, vertex.is_isolated()}; }
vertex_halfedge_out_circulator end() const { return {vertex, true}; }
vertex_halfedge_out_circulator begin() const { return {vertex.any_outgoing_halfedge(), vertex.is_isolated()}; }
vertex_halfedge_out_circulator end() const { return {vertex.any_outgoing_halfedge(), true}; }
};
/// all incoming half-edges from a vertex
......@@ -274,8 +278,8 @@ struct vertex_halfedge_in_ring
bool contains(halfedge_handle h) const;
// Iteration:
vertex_halfedge_in_circulator begin() const { return {vertex, vertex.is_isolated()}; }
vertex_halfedge_in_circulator end() const { return {vertex, true}; }
vertex_halfedge_in_circulator begin() const { return {vertex.any_outgoing_halfedge(), vertex.is_isolated()}; }
vertex_halfedge_in_circulator end() const { return {vertex.any_outgoing_halfedge(), true}; }
};
/// all adjacent vertices of a vertex
......@@ -290,8 +294,8 @@ struct vertex_vertex_ring
bool contains(vertex_handle v) const;
// Iteration:
vertex_vertex_circulator begin() const { return {vertex, vertex.is_isolated()}; }
vertex_vertex_circulator end() const { return {vertex, true}; }
vertex_vertex_circulator begin() const { return {vertex.any_outgoing_halfedge(), vertex.is_isolated()}; }
vertex_vertex_circulator end() const { return {vertex.any_outgoing_halfedge(), true}; }
};
/// all adjacent edges of a vertex
......@@ -306,8 +310,8 @@ struct vertex_edge_ring
bool contains(edge_handle e) const;
// Iteration:
vertex_edge_circulator begin() const { return {vertex, vertex.is_isolated()}; }
vertex_edge_circulator end() const { return {vertex, true}; }
vertex_edge_circulator begin() const { return {vertex.any_outgoing_halfedge(), vertex.is_isolated()}; }
vertex_edge_circulator end() const { return {vertex.any_outgoing_halfedge(), true}; }
};
/// all adjacent faces of a vertex (INCLUDES invalid ones for boundaries)
......@@ -322,8 +326,8 @@ struct vertex_face_ring
bool contains(face_handle f) const;
// Iteration:
vertex_face_circulator begin() const { return {vertex, vertex.is_isolated()}; }
vertex_face_circulator end() const { return {vertex, true}; }
vertex_face_circulator begin() const { return {vertex.any_outgoing_halfedge(), vertex.is_isolated()}; }
vertex_face_circulator end() const { return {vertex.any_outgoing_halfedge(), true}; }
};
......
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