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

primitive attributes

parent 2cadd067
......@@ -331,19 +331,19 @@ private:
// attributes
private:
// linked lists of all attributes
mutable vertex_attribute_base *mVertexAttrs = nullptr;
mutable face_attribute_base *mFaceAttrs = nullptr;
mutable edge_attribute_base *mEdgeAttrs = nullptr;
mutable halfedge_attribute_base *mHalfedgeAttrs = nullptr;
void register_attr(vertex_attribute_base *attr) const;
void deregister_attr(vertex_attribute_base *attr) const;
void register_attr(face_attribute_base *attr) const;
void deregister_attr(face_attribute_base *attr) const;
void register_attr(edge_attribute_base *attr) const;
void deregister_attr(edge_attribute_base *attr) const;
void register_attr(halfedge_attribute_base *attr) const;
void deregister_attr(halfedge_attribute_base *attr) const;
mutable primitive_attribute_base<vertex_tag> *mVertexAttrs = nullptr;
mutable primitive_attribute_base<face_tag> *mFaceAttrs = nullptr;
mutable primitive_attribute_base<edge_tag> *mEdgeAttrs = nullptr;
mutable primitive_attribute_base<halfedge_tag> *mHalfedgeAttrs = nullptr;
void register_attr(primitive_attribute_base<vertex_tag> *attr) const;
void deregister_attr(primitive_attribute_base<vertex_tag> *attr) const;
void register_attr(primitive_attribute_base<face_tag> *attr) const;
void deregister_attr(primitive_attribute_base<face_tag> *attr) const;
void register_attr(primitive_attribute_base<edge_tag> *attr) const;
void deregister_attr(primitive_attribute_base<edge_tag> *attr) const;
void register_attr(primitive_attribute_base<halfedge_tag> *attr) const;
void deregister_attr(primitive_attribute_base<halfedge_tag> *attr) const;
// friends
private:
......@@ -378,6 +378,21 @@ private:
friend struct valid_halfedge_collection;
friend struct const_halfedge_collection;
friend struct halfedge_attribute_base;
template <class tag>
friend struct primitive_handle;
template <class tag>
friend struct primitive_collection;
template <class tag>
friend struct primitive_iterator;
template <class tag>
friend struct valid_primitive_iterator;
template <class tag>
friend struct valid_primitive_collection;
template <class tag>
friend struct const_primitive_collection;
template <class tag>
friend struct primitive_attribute_base;
};
/// ======== IMPLEMENTATION ========
......@@ -952,6 +967,46 @@ inline void valid_halfedge_iterator::move_to_valid()
/// ======== RANGES IMPLEMENTATION ========
inline vertex_collection primitive<vertex_tag>::collection_of(Mesh &m)
{
return m.vertices();
}
inline const_vertex_collection primitive<vertex_tag>::collection_of(const Mesh &m)
{
return m.vertices();
}
inline face_collection primitive<face_tag>::collection_of(Mesh &m)
{
return m.faces();
}
inline const_face_collection primitive<face_tag>::collection_of(const Mesh &m)
{
return m.faces();
}
inline edge_collection primitive<edge_tag>::collection_of(Mesh &m)
{
return m.edges();
}
inline const_edge_collection primitive<edge_tag>::collection_of(const Mesh &m)
{
return m.edges();
}
inline halfedge_collection primitive<halfedge_tag>::collection_of(Mesh &m)
{
return m.halfedges();
}
inline const_halfedge_collection primitive<halfedge_tag>::collection_of(const Mesh &m)
{
return m.halfedges();
}
// - Vertices -
inline int vertex_collection::size() const
......@@ -1693,7 +1748,7 @@ halfedge_attribute<AttrT> const_halfedge_collection::make_attribute(const AttrT
return halfedge_attribute<AttrT>(mesh, def_value);
}
inline void Mesh::register_attr(vertex_attribute_base *attr) const
inline void Mesh::register_attr(primitive_attribute_base<vertex_tag> *attr) const
{
// insert in front
auto nextAttrs = mVertexAttrs;
......@@ -1706,7 +1761,7 @@ inline void Mesh::register_attr(vertex_attribute_base *attr) const
attr->resize(vertices().size(), false);
}
inline void Mesh::deregister_attr(vertex_attribute_base *attr) const
inline void Mesh::deregister_attr(primitive_attribute_base<vertex_tag> *attr) const
{
if (attr->mPrevAttribute)
attr->mPrevAttribute->mNextAttribute = attr->mNextAttribute;
......@@ -1721,7 +1776,7 @@ inline void Mesh::deregister_attr(vertex_attribute_base *attr) const
attr->mPrevAttribute = nullptr;
}
inline void Mesh::register_attr(face_attribute_base *attr) const
inline void Mesh::register_attr(primitive_attribute_base<face_tag> *attr) const
{
// insert in front
auto nextAttrs = mFaceAttrs;
......@@ -1734,7 +1789,7 @@ inline void Mesh::register_attr(face_attribute_base *attr) const
attr->resize(faces().size(), false);
}
inline void Mesh::deregister_attr(face_attribute_base *attr) const
inline void Mesh::deregister_attr(primitive_attribute_base<face_tag> *attr) const
{
if (attr->mPrevAttribute)
attr->mPrevAttribute->mNextAttribute = attr->mNextAttribute;
......@@ -1749,7 +1804,7 @@ inline void Mesh::deregister_attr(face_attribute_base *attr) const
attr->mPrevAttribute = nullptr;
}
inline void Mesh::register_attr(edge_attribute_base *attr) const
inline void Mesh::register_attr(primitive_attribute_base<edge_tag> *attr) const
{
// insert in front
auto nextAttrs = mEdgeAttrs;
......@@ -1762,7 +1817,7 @@ inline void Mesh::register_attr(edge_attribute_base *attr) const
attr->resize(edges().size(), false);
}
inline void Mesh::deregister_attr(edge_attribute_base *attr) const
inline void Mesh::deregister_attr(primitive_attribute_base<edge_tag> *attr) const
{
if (attr->mPrevAttribute)
attr->mPrevAttribute->mNextAttribute = attr->mNextAttribute;
......@@ -1777,7 +1832,7 @@ inline void Mesh::deregister_attr(edge_attribute_base *attr) const
attr->mPrevAttribute = nullptr;
}
inline void Mesh::register_attr(halfedge_attribute_base *attr) const
inline void Mesh::register_attr(primitive_attribute_base<halfedge_tag> *attr) const
{
// insert in front
auto nextAttrs = mHalfedgeAttrs;
......@@ -1790,7 +1845,7 @@ inline void Mesh::register_attr(halfedge_attribute_base *attr) const
attr->resize(halfedges().size(), false);
}
inline void Mesh::deregister_attr(halfedge_attribute_base *attr) const
inline void Mesh::deregister_attr(primitive_attribute_base<halfedge_tag> *attr) const
{
if (attr->mPrevAttribute)
attr->mPrevAttribute->mNextAttribute = attr->mNextAttribute;
......@@ -1805,54 +1860,14 @@ inline void Mesh::deregister_attr(halfedge_attribute_base *attr) const
attr->mPrevAttribute = nullptr;
}
inline vertex_attribute_base::vertex_attribute_base(const Mesh *mesh) : mMesh(mesh)
{
// mMesh->register_attr(this); TOO EARLY!
}
inline face_attribute_base::face_attribute_base(const Mesh *mesh) : mMesh(mesh)
{
// mMesh->register_attr(this); TOO EARLY!
}
inline edge_attribute_base::edge_attribute_base(const Mesh *mesh) : mMesh(mesh)
template <class tag>
void primitive_attribute_base<tag>::register_attr()
{
// mMesh->register_attr(this); TOO EARLY!
}
inline halfedge_attribute_base::halfedge_attribute_base(const Mesh *mesh) : mMesh(mesh)
{
// mMesh->register_attr(this); TOO EARLY!
}
inline void vertex_attribute_base::deregister_attr()
{
if (mMesh)
{
mMesh->deregister_attr(this);
mMesh = nullptr;
}
}
inline void face_attribute_base::deregister_attr()
{
if (mMesh)
{
mMesh->deregister_attr(this);
mMesh = nullptr;
}
}
inline void edge_attribute_base::deregister_attr()
{
if (mMesh)
{
mMesh->deregister_attr(this);
mMesh = nullptr;
}
mMesh->register_attr(this);
}
inline void halfedge_attribute_base::deregister_attr()
template <class tag>
void primitive_attribute_base<tag>::deregister_attr()
{
if (mMesh)
{
......@@ -1861,131 +1876,37 @@ inline void halfedge_attribute_base::deregister_attr()
}
}
inline void vertex_attribute_base::register_attr()
{
mMesh->register_attr(this);
}
inline void face_attribute_base::register_attr()
{
mMesh->register_attr(this);
}
inline void edge_attribute_base::register_attr()
{
mMesh->register_attr(this);
}
inline void halfedge_attribute_base::register_attr()
{
mMesh->register_attr(this);
}
template <class AttrT>
vertex_attribute<AttrT>::vertex_attribute(const Mesh *mesh, const AttrT &def_value)
: vertex_attribute_base(mesh), mDefaultValue(def_value)
{
register_attr();
}
template <class AttrT>
face_attribute<AttrT>::face_attribute(const Mesh *mesh, const AttrT &def_value)
: face_attribute_base(mesh), mDefaultValue(def_value)
{
register_attr();
}
template <class AttrT>
edge_attribute<AttrT>::edge_attribute(const Mesh *mesh, const AttrT &def_value)
: edge_attribute_base(mesh), mDefaultValue(def_value)
{
register_attr();
}
template <class AttrT>
halfedge_attribute<AttrT>::halfedge_attribute(const Mesh *mesh, const AttrT &def_value)
: halfedge_attribute_base(mesh), mDefaultValue(def_value)
{
register_attr();
}
template <class AttrT>
int vertex_attribute<AttrT>::size() const
{
return mMesh->vertices().size();
}
template <class AttrT>
void vertex_attribute<AttrT>::clear(AttrT const &value)
{
mData.clear();
mData.resize(mMesh->vertices().size(), value);
}
template <class AttrT>
void vertex_attribute<AttrT>::clear()
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)
{
clear(mDefaultValue);
this->register_attr();
}
template <class AttrT>
int face_attribute<AttrT>::size() const
template <class tag, class AttrT>
int primitive_attribute<tag, AttrT>::size() const
{
return mMesh->vertices().size();
return primitive<tag>::collection_of(*this->mMesh).size();
}
template <class AttrT>
void face_attribute<AttrT>::clear(AttrT const &value)
template <class tag, class AttrT>
void primitive_attribute<tag, AttrT>::clear(AttrT const &value)
{
mData.clear();
mData.resize(mMesh->vertices().size(), value);
}
template <class AttrT>
void face_attribute<AttrT>::clear()
{
clear(mDefaultValue);
this->mData.clear();
this->mData.resize(size(), value);
}
template <class AttrT>
int edge_attribute<AttrT>::size() const
template <class tag, class AttrT>
void primitive_attribute<tag, AttrT>::clear()
{
return mMesh->vertices().size();
this->clear(this->mDefaultValue);
}
template <class AttrT>
void edge_attribute<AttrT>::clear(AttrT const &value)
{
mData.clear();
mData.resize(mMesh->vertices().size(), value);
}
template <class AttrT>
void edge_attribute<AttrT>::clear()
{
clear(mDefaultValue);
}
template <class AttrT>
int halfedge_attribute<AttrT>::size() const
{
return mMesh->vertices().size();
}
template <class AttrT>
void halfedge_attribute<AttrT>::clear(AttrT const &value)
{
mData.clear();
mData.resize(mMesh->vertices().size(), value);
}
template <class AttrT>
void halfedge_attribute<AttrT>::clear()
{
clear(mDefaultValue);
}
template <class AttrT>
template <class tag, class AttrT>
template <class FuncT>
auto vertex_attribute<AttrT>::map(FuncT f) const -> vertex_attribute<tmp::result_type_of<FuncT, AttrT>>
auto primitive_attribute<tag, AttrT>::map(FuncT f) const -> attribute<tmp::result_type_of<FuncT, AttrT>>
{
auto attr = mMesh->vertices().make_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();
......
......@@ -85,11 +85,12 @@ struct attribute_data
}
};
struct vertex_attribute_base
template <class tag>
struct primitive_attribute_base
{
private:
vertex_attribute_base* mNextAttribute = nullptr;
vertex_attribute_base* mPrevAttribute = nullptr;
primitive_attribute_base* mNextAttribute = nullptr;
primitive_attribute_base* mPrevAttribute = nullptr;
void resize(int newSize, bool force)
{
......@@ -110,110 +111,8 @@ private:
protected:
int mDataSize = 0;
Mesh const* mMesh;
vertex_attribute_base(Mesh const* mesh);
virtual ~vertex_attribute_base() { deregister_attr(); }
virtual void on_resize(int newSize) = 0;
virtual void apply_remapping(std::vector<int> const& map) = 0;
void register_attr();
void deregister_attr();
friend class Mesh;
};
struct face_attribute_base
{
private:
face_attribute_base* mNextAttribute = nullptr;
face_attribute_base* mPrevAttribute = nullptr;
void resize(int newSize, bool force)
{
if (force)
{
mDataSize = newSize;
on_resize(mDataSize);
return;
}
if (mDataSize < newSize)
{
mDataSize = std::max(newSize, 1 + mDataSize + (mDataSize >> 1)); // 1 + s * 1.5
on_resize(mDataSize);
}
}
protected:
int mDataSize = 0;
Mesh const* mMesh;
face_attribute_base(Mesh const* mesh);
virtual ~face_attribute_base() { deregister_attr(); }
virtual void on_resize(int newSize) = 0;
virtual void apply_remapping(std::vector<int> const& map) = 0;
void register_attr();
void deregister_attr();
friend class Mesh;
};
struct edge_attribute_base
{
private:
edge_attribute_base* mNextAttribute = nullptr;
edge_attribute_base* mPrevAttribute = nullptr;
void resize(int newSize, bool force)
{
if (force)
{
mDataSize = newSize;
on_resize(mDataSize);
return;
}
if (mDataSize < newSize)
{
mDataSize = std::max(newSize, 1 + mDataSize + (mDataSize >> 1)); // 1 + s * 1.5
on_resize(mDataSize);
}
}
protected:
int mDataSize = 0;
Mesh const* mMesh;
edge_attribute_base(Mesh const* mesh);
virtual ~edge_attribute_base() { deregister_attr(); }
virtual void on_resize(int newSize) = 0;
virtual void apply_remapping(std::vector<int> const& map) = 0;
void register_attr();
void deregister_attr();
friend class Mesh;
};
struct halfedge_attribute_base
{
private:
halfedge_attribute_base* mNextAttribute = nullptr;
halfedge_attribute_base* mPrevAttribute = nullptr;
void resize(int newSize, bool force)
{
if (force)
{
mDataSize = newSize;
on_resize(mDataSize);
return;
}
if (mDataSize < newSize)
{
mDataSize = std::max(newSize, 1 + mDataSize + (mDataSize >> 1)); // 1 + s * 1.5
on_resize(mDataSize);
}
}
protected:
int mDataSize = 0;
Mesh const* mMesh;
halfedge_attribute_base(Mesh const* mesh);
virtual ~halfedge_attribute_base() { deregister_attr(); }
primitive_attribute_base(Mesh const* mesh) : mMesh(mesh) {} // no registration, it's too early!
virtual ~primitive_attribute_base() { deregister_attr(); }
virtual void on_resize(int newSize) = 0;
virtual void apply_remapping(std::vector<int> const& map) = 0;
void register_attr();
......
......@@ -10,7 +10,7 @@ namespace polymesh
struct attribute_collection
{
private:
std::map<std::string, vertex_attribute_base> mVertexAttrs;
std::map<std::string, primitive_attribute_base<vertex_tag>> mVertexAttrs;
// TODO
};
}
......@@ -23,25 +23,20 @@
namespace polymesh
{
template <class Primitive, class AttrT>
struct primitive_attribute
template <class tag, class AttrT>
struct primitive_attribute : primitive_attribute_base<tag>
{
};
// ===========================================
// OLD CODE:
template <class A>
using attribute = typename primitive<tag>::template attribute<A>;
using index_t = typename primitive<tag>::index;
using handle_t = typename primitive<tag>::handle;
template <class AttrT>
struct vertex_attribute : vertex_attribute_base
{
// data access
public:
AttrT& operator[](vertex_handle v) { return mData[v.idx.value]; }
AttrT const& operator[](vertex_handle v) const { return mData[v.idx.value]; }
AttrT& operator[](vertex_index v) { return mData[v.value]; }
AttrT const& operator[](vertex_index v) const { return mData[v.value]; }
AttrT& operator[](handle_t v) { return mData[v.idx.value]; }
AttrT const& operator[](handle_t v) const { return mData[v.idx.value]; }
AttrT& operator[](index_t v) { return mData[v.value]; }
AttrT const& operator[](index_t v) const { return mData[v.value]; }
AttrT* data() { return mData.data; }
AttrT const* data() const { return mData.data; }
......@@ -54,13 +49,13 @@ public:
/// returns a new attribute where the given function was applied to each entry
template <class FuncT>
auto map(FuncT f) const -> vertex_attribute<tmp::result_type_of<FuncT, AttrT>>;
auto map(FuncT f) const -> attribute<tmp::result_type_of<FuncT, AttrT>>;
/// applies to given function to each attribute entry
template <class FuncT>
void apply(FuncT f);
// data
private:
protected:
attribute_data<AttrT> mData;
AttrT mDefaultValue;
......@@ -68,357 +63,105 @@ private:
void apply_remapping(std::vector<int> const& map) override;
// ctor
private:
vertex_attribute(Mesh const* mesh, AttrT const& def_value);
friend struct vertex_collection;
friend struct const_vertex_collection;
protected:
primitive_attribute(Mesh const* mesh, AttrT const& def_value);
// move & copy
public:
vertex_attribute(vertex_attribute const&);
vertex_attribute(vertex_attribute&&);
vertex_attribute& operator=(vertex_attribute const&);
vertex_attribute& operator=(vertex_attribute&&);
primitive_attribute(primitive_attribute const&);
primitive_attribute(primitive_attribute&&);
primitive_attribute& operator=(primitive_attribute const&);
primitive_attribute& operator=(primitive_attribute&&);
};
template <class AttrT>
struct face_attribute : face_attribute_base
struct vertex_attribute : primitive_attribute<vertex_tag, AttrT>
{
// data access
public:
AttrT& operator[](face_handle v) { return mData[v.idx.value]; }
AttrT const& operator[](face_handle v) const { return mData[v.idx.value]; }
AttrT& operator[](face_index v) { return mData[v.value]; }
AttrT const& operator[](face_index v) const { return mData[v.value]; }
AttrT* data() { return mData.data(); }
AttrT const* data() const { return mData.data(); }
int size() const;
// methods