Commit 6b33318b authored by Philip Trettner's avatar Philip Trettner
Browse files

working on collections

parent a7a0c367
This diff is collapsed.
......@@ -79,32 +79,32 @@ struct vertex_attribute : primitive_attribute<vertex_tag, AttrT>
{
using primitive_attribute<vertex_tag, AttrT>::primitive_attribute;
friend struct vertex_collection;
friend struct const_vertex_collection;
template<class mesh_ptr, class tag, class iterator>
friend struct smart_collection;
};
template <class AttrT>
struct face_attribute : primitive_attribute<face_tag, AttrT>
{
using primitive_attribute<face_tag, AttrT>::primitive_attribute;
friend struct face_collection;
friend struct const_face_collection;
template<class mesh_ptr, class tag, class iterator>
friend struct smart_collection;
};
template <class AttrT>
struct edge_attribute : primitive_attribute<edge_tag, AttrT>
{
using primitive_attribute<edge_tag, AttrT>::primitive_attribute;
friend struct edge_collection;
friend struct const_edge_collection;
template<class mesh_ptr, class tag, class iterator>
friend struct smart_collection;
};
template <class AttrT>
struct halfedge_attribute : primitive_attribute<halfedge_tag, AttrT>
{
using primitive_attribute<halfedge_tag, AttrT>::primitive_attribute;
friend struct halfedge_collection;
friend struct const_halfedge_collection;
template<class mesh_ptr, class tag, class iterator>
friend struct smart_collection;
};
/// ======== IMPLEMENTATION ========
......
......@@ -33,15 +33,25 @@ struct face_handle;
struct edge_handle;
struct halfedge_handle;
struct vertex_collection;
struct face_collection;
struct edge_collection;
struct halfedge_collection;
struct const_vertex_collection;
struct const_face_collection;
struct const_edge_collection;
struct const_halfedge_collection;
struct all_vertex_collection;
struct all_face_collection;
struct all_edge_collection;
struct all_halfedge_collection;
struct valid_vertex_collection;
struct valid_face_collection;
struct valid_edge_collection;
struct valid_halfedge_collection;
struct all_vertex_const_collection;
struct all_face_const_collection;
struct all_edge_const_collection;
struct all_halfedge_const_collection;
struct valid_vertex_const_collection;
struct valid_face_const_collection;
struct valid_edge_const_collection;
struct valid_halfedge_const_collection;
struct face_vertex_ring;
struct face_edge_ring;
......
#pragma once
#include "../Mesh.hh"
namespace polymesh
{
template <class AttrT>
vertex_attribute<AttrT> vertex_collection::make_attribute(const AttrT &def_value)
{
return vertex_attribute<AttrT>(mesh, def_value);
}
template <class AttrT>
vertex_attribute<AttrT> const_vertex_collection::make_attribute(const AttrT &def_value)
{
return vertex_attribute<AttrT>(mesh, def_value);
}
template <class AttrT>
face_attribute<AttrT> face_collection::make_attribute(const AttrT &def_value)
{
return face_attribute<AttrT>(mesh, def_value);
}
template <class AttrT>
face_attribute<AttrT> const_face_collection::make_attribute(const AttrT &def_value)
{
return face_attribute<AttrT>(mesh, def_value);
}
template <class AttrT>
edge_attribute<AttrT> edge_collection::make_attribute(const AttrT &def_value)
{
return edge_attribute<AttrT>(mesh, def_value);
}
template <class AttrT>
edge_attribute<AttrT> const_edge_collection::make_attribute(const AttrT &def_value)
{
return edge_attribute<AttrT>(mesh, def_value);
}
template <class AttrT>
halfedge_attribute<AttrT> halfedge_collection::make_attribute(const AttrT &def_value)
{
return halfedge_attribute<AttrT>(mesh, def_value);
}
template <class AttrT>
halfedge_attribute<AttrT> const_halfedge_collection::make_attribute(const AttrT &def_value)
{
return halfedge_attribute<AttrT>(mesh, def_value);
}
inline void Mesh::register_attr(primitive_attribute_base<vertex_tag> *attr) const
{
// insert in front
auto nextAttrs = mVertexAttrs;
mVertexAttrs = attr;
attr->mNextAttribute = nextAttrs;
if (nextAttrs)
nextAttrs->mPrevAttribute = attr;
// resize attr
attr->resize(vertices().size(), false);
}
inline void Mesh::deregister_attr(primitive_attribute_base<vertex_tag> *attr) const
{
if (attr->mPrevAttribute)
attr->mPrevAttribute->mNextAttribute = attr->mNextAttribute;
if (attr->mNextAttribute)
attr->mNextAttribute->mPrevAttribute = attr->mPrevAttribute;
if (mVertexAttrs == attr)
mVertexAttrs = attr->mNextAttribute;
attr->mNextAttribute = nullptr;
attr->mPrevAttribute = nullptr;
}
inline void Mesh::register_attr(primitive_attribute_base<face_tag> *attr) const
{
// insert in front
auto nextAttrs = mFaceAttrs;
mFaceAttrs = attr;
attr->mNextAttribute = nextAttrs;
if (nextAttrs)
nextAttrs->mPrevAttribute = attr;
// resize attr
attr->resize(faces().size(), false);
}
inline void Mesh::deregister_attr(primitive_attribute_base<face_tag> *attr) const
{
if (attr->mPrevAttribute)
attr->mPrevAttribute->mNextAttribute = attr->mNextAttribute;
if (attr->mNextAttribute)
attr->mNextAttribute->mPrevAttribute = attr->mPrevAttribute;
if (mFaceAttrs == attr)
mFaceAttrs = attr->mNextAttribute;
attr->mNextAttribute = nullptr;
attr->mPrevAttribute = nullptr;
}
inline void Mesh::register_attr(primitive_attribute_base<edge_tag> *attr) const
{
// insert in front
auto nextAttrs = mEdgeAttrs;
mEdgeAttrs = attr;
attr->mNextAttribute = nextAttrs;
if (nextAttrs)
nextAttrs->mPrevAttribute = attr;
// resize attr
attr->resize(edges().size(), false);
}
inline void Mesh::deregister_attr(primitive_attribute_base<edge_tag> *attr) const
{
if (attr->mPrevAttribute)
attr->mPrevAttribute->mNextAttribute = attr->mNextAttribute;
if (attr->mNextAttribute)
attr->mNextAttribute->mPrevAttribute = attr->mPrevAttribute;
if (mEdgeAttrs == attr)
mEdgeAttrs = attr->mNextAttribute;
attr->mNextAttribute = nullptr;
attr->mPrevAttribute = nullptr;
}
inline void Mesh::register_attr(primitive_attribute_base<halfedge_tag> *attr) const
{
// insert in front
auto nextAttrs = mHalfedgeAttrs;
mHalfedgeAttrs = attr;
attr->mNextAttribute = nextAttrs;
if (nextAttrs)
nextAttrs->mPrevAttribute = attr;
// resize attr
attr->resize(halfedges().size(), false);
}
inline void Mesh::deregister_attr(primitive_attribute_base<halfedge_tag> *attr) const
{
if (attr->mPrevAttribute)
attr->mPrevAttribute->mNextAttribute = attr->mNextAttribute;
if (attr->mNextAttribute)
attr->mNextAttribute->mPrevAttribute = attr->mPrevAttribute;
if (mHalfedgeAttrs == attr)
mHalfedgeAttrs = attr->mNextAttribute;
attr->mNextAttribute = nullptr;
attr->mPrevAttribute = nullptr;
}
template <class tag>
void primitive_attribute_base<tag>::register_attr()
{
mMesh->register_attr(this);
}
template <class tag>
void primitive_attribute_base<tag>::deregister_attr()
{
if (mMesh)
{
mMesh->deregister_attr(this);
mMesh = nullptr;
}
}
template <class tag, class AttrT>
primitive_attribute<tag, AttrT>::primitive_attribute(const Mesh *mesh, const AttrT &def_value)
: primitive_attribute_base<tag>(mesh), mDefaultValue(def_value)
{
this->register_attr();
}
template <class tag, class AttrT>
int primitive_attribute<tag, AttrT>::size() const
{
return primitive<tag>::collection_of(*this->mMesh).size();
}
template <class tag, class AttrT>
void primitive_attribute<tag, AttrT>::clear(AttrT const &value)
{
this->mData.clear();
this->mData.resize(size(), value);
}
template <class tag, class AttrT>
void primitive_attribute<tag, AttrT>::clear()
{
this->clear(this->mDefaultValue);
}
template <class tag, class AttrT>
template <class FuncT>
auto primitive_attribute<tag, AttrT>::map(FuncT f) const -> attribute<tmp::result_type_of<FuncT, AttrT>>
{
auto attr = primitive<tag>::collection_of(*this->mMesh).template make_attribute<tmp::result_type_of<FuncT, AttrT>>();
auto s = size();
auto d_in = data();
auto d_out = attr.data();
for (auto i = 0; i < s; ++i)
d_out[i] = f(d_in[i]);
return attr; // copy elison
}
}
#pragma once
#include "../Mesh.hh"
namespace polymesh
{
inline bool vertex_handle::is_removed() const
{
return idx.is_valid() && !mesh->vertex(idx).is_valid();
}
inline bool face_handle::is_removed() const
{
return idx.is_valid() && !mesh->face(idx).is_valid();
}
inline bool edge_handle::is_removed() const
{
return idx.is_valid() && !mesh->halfedge(idx, 0).is_valid();
}
inline bool halfedge_handle::is_removed() const
{
return idx.is_valid() && !mesh->halfedge(idx).is_valid();
}
inline bool vertex_handle::is_isolated() const
{
return mesh->vertex(idx).is_isolated();
}
inline bool vertex_handle::is_boundary() const
{
auto const &v = mesh->vertex(idx);
if (v.is_isolated())
return true;
return mesh->halfedge(v.outgoing_halfedge).is_free();
}
inline bool face_handle::is_boundary() const
{
return mesh->halfedge(mesh->opposite(mesh->face(idx).halfedge)).is_free();
}
inline bool edge_handle::is_isolated() const
{
return mesh->halfedge(idx, 0).is_free() && mesh->halfedge(idx, 1).is_free();
}
inline bool edge_handle::is_boundary() const
{
return mesh->halfedge(idx, 0).is_free() || mesh->halfedge(idx, 1).is_free();
}
inline bool halfedge_handle::is_boundary() const
{
return mesh->halfedge(idx).is_free();
}
inline vertex_handle halfedge_handle::vertex_to() const
{
return mesh->handle_of(mesh->halfedge(idx).to_vertex);
}
inline vertex_handle halfedge_handle::vertex_from() const
{
return mesh->handle_of(mesh->halfedge(mesh->opposite(idx)).to_vertex);
}
inline edge_handle halfedge_handle::edge() const
{
return mesh->handle_of(mesh->edge_of(idx));
}
inline face_handle halfedge_handle::face() const
{
return mesh->handle_of(mesh->halfedge(idx).face);
}
inline halfedge_handle halfedge_handle::next() const
{
return mesh->handle_of(mesh->halfedge(idx).next_halfedge);
}
inline halfedge_handle halfedge_handle::prev() const
{
return mesh->handle_of(mesh->halfedge(idx).prev_halfedge);
}
inline halfedge_handle halfedge_handle::opposite() const
{
return mesh->handle_of(mesh->opposite(idx));
}
inline face_handle halfedge_handle::opposite_face() const
{
return mesh->handle_of(mesh->halfedge(mesh->opposite(idx)).face);
}
inline halfedge_handle edge_handle::halfedgeA() const
{
return mesh->handle_of(mesh->halfedge_of(idx, 0));
}
inline halfedge_handle edge_handle::halfedgeB() const
{
return mesh->handle_of(mesh->halfedge_of(idx, 1));
}
inline vertex_handle edge_handle::vertexA() const
{
return mesh->handle_of(mesh->halfedge(mesh->halfedge_of(idx, 0)).to_vertex);
}
inline vertex_handle edge_handle::vertexB() const
{
return mesh->handle_of(mesh->halfedge(mesh->halfedge_of(idx, 1)).to_vertex);
}
inline face_handle edge_handle::faceA() const
{
return mesh->handle_of(mesh->halfedge(mesh->halfedge_of(idx, 0)).face);
}
inline face_handle edge_handle::faceB() const
{
return mesh->handle_of(mesh->halfedge(mesh->halfedge_of(idx, 1)).face);
}
inline face_handle vertex_handle::any_face() const
{
auto h = mesh->vertex(idx).outgoing_halfedge;
return mesh->handle_of(h.is_valid() ? mesh->halfedge(h).face : face_index::invalid());
}
inline face_handle vertex_handle::any_valid_face() const
{
for (auto f : faces())
if (f.is_valid())
return f;
return mesh->handle_of(face_index::invalid());
}
inline halfedge_handle vertex_handle::any_outgoing_halfedge() const
{
return mesh->handle_of(mesh->vertex(idx).outgoing_halfedge);
}
inline halfedge_handle vertex_handle::any_incoming_halfedge() const
{
auto h = mesh->vertex(idx).outgoing_halfedge;
return mesh->handle_of(h.is_valid() ? mesh->opposite(h) : halfedge_index::invalid());
}
inline edge_handle vertex_handle::any_edge() const
{
auto h = mesh->vertex(idx).outgoing_halfedge;
return mesh->handle_of(h.is_valid() ? mesh->edge_of(h) : edge_index::invalid());
}
inline vertex_handle face_handle::any_vertex() const
{
return mesh->handle_of(mesh->halfedge(mesh->face(idx).halfedge).to_vertex);
}
inline halfedge_handle face_handle::any_halfedge() const
{
return mesh->handle_of(mesh->face(idx).halfedge);
}
inline face_vertex_ring face_handle::vertices() const
{
return {*this};
}
inline face_edge_ring face_handle::edges() const
{
return {*this};
}
inline face_halfedge_ring face_handle::halfedges() const
{
return {*this};
}
inline face_face_ring face_handle::adjacent_faces() const
{
return {*this};
}
inline vertex_halfedge_in_ring vertex_handle::incoming_halfedges() const
{
return {*this};
}
inline vertex_halfedge_out_ring vertex_handle::outgoing_halfedges() const
{
return {*this};
}
inline vertex_edge_ring vertex_handle::edges() const
{
return {*this};
}
inline vertex_face_ring vertex_handle::faces() const
{
return {*this};
}
inline vertex_vertex_ring vertex_handle::adjacent_vertices() const
{
return {*this};
}
}
#pragma once
#include "../Mesh.hh"
namespace polymesh
{
inline valid_vertex_iterator &valid_vertex_iterator::operator++()
{
handle.idx.value++;
handle.idx = handle.mesh->next_valid_idx_from(handle.idx);
return *this;
}
inline all_vertex_iterator &all_vertex_iterator::operator++()
{
handle.idx.value++;
return *this;
}
inline void valid_vertex_iterator::move_to_valid()
{
handle.idx = handle.mesh->next_valid_idx_from(handle.idx);
}
inline valid_face_iterator &valid_face_iterator::operator++()
{
handle.idx.value++;
handle.idx = handle.mesh->next_valid_idx_from(handle.idx);
return *this;
}
inline face_iterator &face_iterator::operator++()
{
handle.idx.value++;
return *this;
}
inline void valid_face_iterator::move_to_valid()
{
handle.idx = handle.mesh->next_valid_idx_from(handle.idx);
}
inline valid_edge_iterator &valid_edge_iterator::operator++()
{
handle.idx.value++;
handle.idx = handle.mesh->next_valid_idx_from(handle.idx);
return *this;
}
inline edge_iterator &edge_iterator::operator++()
{
handle.idx.value++;
return *this;
}
inline void valid_edge_iterator::move_to_valid()
{
handle.idx = handle.mesh->next_valid_idx_from(handle.idx);
}
inline valid_halfedge_iterator &valid_halfedge_iterator::operator++()
{
handle.idx.value++;
handle.idx = handle.mesh->next_valid_idx_from(handle.idx);
return *this;
}
inline halfedge_iterator &halfedge_iterator::operator++()
{
handle.idx.value++;
return *this;
}
inline void valid_halfedge_iterator::move_to_valid()
{
handle.idx = handle.mesh->next_valid_idx_from(handle.idx);
}
}
#pragma once
#include "../Mesh.hh"
namespace polymesh
{
inline void primitive<vertex_tag>::reserve(Mesh& m, int capacity)
{
m.reserve_vertices(capacity);
}