Commit 4af91043 authored by Philip Trettner's avatar Philip Trettner
Browse files

removal and compactify, also more circulators

parent 6721c1cc
......@@ -16,3 +16,5 @@ Best used with glm and glow.
* Adding/Removing
* Compacting via remap-vectors
* std::less and std::hash for _index (and maybe _handle)
* attribute transformations (also between different types)
* lambda to attribute (from attribute to attribute or from make_attribute to attribute)
......@@ -4,16 +4,6 @@
using namespace polymesh;
void Mesh::compactify()
{
if (is_compact())
return;
/// TODO
mCompact = true;
}
void Mesh::assert_consistency() const
{
/// TODO
......
This diff is collapsed.
......@@ -18,3 +18,6 @@
// - triangulation
// - geodesics
// - topological information (as free functions)
// - angle to next/prev
// - valence_of, valences
// - subdivision-to-acute
#pragma once
#include <vector>
#include <cstddef>
// Helper for mesh-based attribute bookkeeping
......@@ -29,7 +30,8 @@ protected:
vertex_attribute_base(Mesh const* mesh);
virtual ~vertex_attribute_base();
virtual void on_resize(size_t newSize) = 0;
void register_prop();
virtual void apply_remapping(std::vector<int> const& map) = 0;
void register_attr();
friend class Mesh;
};
......@@ -54,7 +56,8 @@ protected:
face_attribute_base(Mesh const* mesh);
virtual ~face_attribute_base();
virtual void on_resize(size_t newSize) = 0;
void register_prop();
virtual void apply_remapping(std::vector<int> const& map) = 0;
void register_attr();
friend class Mesh;
};
......@@ -79,7 +82,8 @@ protected:
edge_attribute_base(Mesh const* mesh);
virtual ~edge_attribute_base();
virtual void on_resize(size_t newSize) = 0;
void register_prop();
virtual void apply_remapping(std::vector<int> const& map) = 0;
void register_attr();
friend class Mesh;
};
......@@ -104,7 +108,8 @@ protected:
halfedge_attribute_base(Mesh const* mesh);
virtual ~halfedge_attribute_base();
virtual void on_resize(size_t newSize) = 0;
void register_prop();
virtual void apply_remapping(std::vector<int> const& map) = 0;
void register_attr();
friend class Mesh;
};
}
......@@ -6,238 +6,267 @@
#include "cursors.hh"
#include "attribute_base.hh"
/** Properties
/** Attrerties
*
* Golden rule:
* - the Mesh must always outlive the attribute!
*
* Create properties:
* auto myProp = mesh.vertices().make_attribute(0.0f);
* Create attributes:
* auto myAttr = mesh.vertices().make_attribute(0.0f);
*
* Access properties:
* Access attributes:
* vertex_handle v; // or _index
* v[myProp] = 7;
* myProp[v] = 7;
* v[myAttr] = 7;
* myAttr[v] = 7;
*
* TODO: correct copy and move ctors/assignments
*/
namespace polymesh
{
template <typename PropT>
template <typename AttrT>
struct vertex_attribute : vertex_attribute_base
{
// data access
public:
PropT& operator[](vertex_handle v) { return mData[v.idx.value]; }
PropT const& operator[](vertex_handle v) const { return mData[v.idx.value]; }
PropT& operator[](vertex_index v) { return mData[v.value]; }
PropT const& operator[](vertex_index v) const { return mData[v.value]; }
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]; }
PropT* data() { return mData.data(); }
PropT const* data() const { return mData.data(); }
AttrT* data() { return mData.data(); }
AttrT const* data() const { return mData.data(); }
size_t size() const;
// methods
public:
void clear(PropT const& value);
void clear(AttrT const& value);
void clear();
// data
private:
std::vector<PropT> mData;
PropT mDefaultValue;
std::vector<AttrT> mData;
AttrT mDefaultValue;
void on_resize(size_t newSize) override { mData.resize(newSize, mDefaultValue); }
void apply_remapping(std::vector<int> const& map) override;
// ctor
private:
vertex_attribute(Mesh const* mesh, PropT const& def_value);
vertex_attribute(Mesh const* mesh, AttrT const& def_value);
friend struct vertex_collection;
};
template <typename PropT>
template <typename AttrT>
struct face_attribute : face_attribute_base
{
// data access
public:
PropT& operator[](face_handle v) { return mData[v.idx.value]; }
PropT const& operator[](face_handle v) const { return mData[v.idx.value]; }
PropT& operator[](face_index v) { return mData[v.value]; }
PropT const& operator[](face_index v) const { return mData[v.value]; }
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]; }
PropT* data() { return mData.data(); }
PropT const* data() const { return mData.data(); }
AttrT* data() { return mData.data(); }
AttrT const* data() const { return mData.data(); }
size_t size() const;
// methods
public:
void clear(PropT const& value);
void clear(AttrT const& value);
void clear();
// data
private:
std::vector<PropT> mData;
PropT mDefaultValue;
std::vector<AttrT> mData;
AttrT mDefaultValue;
void on_resize(size_t newSize) override { mData.resize(newSize, mDefaultValue); }
void apply_remapping(std::vector<int> const& map) override;
// ctor
private:
face_attribute(Mesh const* mesh, PropT const& def_value);
face_attribute(Mesh const* mesh, AttrT const& def_value);
friend struct face_collection;
};
template <typename PropT>
template <typename AttrT>
struct edge_attribute : edge_attribute_base
{
// data access
public:
PropT& operator[](edge_handle v) { return mData[v.idx.value]; }
PropT const& operator[](edge_handle v) const { return mData[v.idx.value]; }
PropT& operator[](edge_index v) { return mData[v.value]; }
PropT const& operator[](edge_index v) const { return mData[v.value]; }
AttrT& operator[](edge_handle v) { return mData[v.idx.value]; }
AttrT const& operator[](edge_handle v) const { return mData[v.idx.value]; }
AttrT& operator[](edge_index v) { return mData[v.value]; }
AttrT const& operator[](edge_index v) const { return mData[v.value]; }
PropT* data() { return mData.data(); }
PropT const* data() const { return mData.data(); }
AttrT* data() { return mData.data(); }
AttrT const* data() const { return mData.data(); }
size_t size() const;
// methods
public:
void clear(PropT const& value);
void clear(AttrT const& value);
void clear();
// data
private:
std::vector<PropT> mData;
PropT mDefaultValue;
std::vector<AttrT> mData;
AttrT mDefaultValue;
void on_resize(size_t newSize) override { mData.resize(newSize, mDefaultValue); }
void apply_remapping(std::vector<int> const& map) override;
// ctor
private:
edge_attribute(Mesh const* mesh, PropT const& def_value);
edge_attribute(Mesh const* mesh, AttrT const& def_value);
friend struct edge_collection;
};
template <typename PropT>
template <typename AttrT>
struct halfedge_attribute : halfedge_attribute_base
{
// data access
public:
PropT& operator[](halfedge_handle v) { return mData[v.idx.value]; }
PropT const& operator[](halfedge_handle v) const { return mData[v.idx.value]; }
PropT& operator[](halfedge_index v) { return mData[v.value]; }
PropT const& operator[](halfedge_index v) const { return mData[v.value]; }
AttrT& operator[](halfedge_handle v) { return mData[v.idx.value]; }
AttrT const& operator[](halfedge_handle v) const { return mData[v.idx.value]; }
AttrT& operator[](halfedge_index v) { return mData[v.value]; }
AttrT const& operator[](halfedge_index v) const { return mData[v.value]; }
PropT* data() { return mData.data(); }
PropT const* data() const { return mData.data(); }
AttrT* data() { return mData.data(); }
AttrT const* data() const { return mData.data(); }
size_t size() const;
// methods
public:
void clear(PropT const& value);
void clear(AttrT const& value);
void clear();
void on_resize(size_t newSize) override { mData.resize(newSize, mDefaultValue); }
void apply_remapping(std::vector<int> const& map) override;
// data
private:
std::vector<PropT> mData;
PropT mDefaultValue;
std::vector<AttrT> mData;
AttrT mDefaultValue;
// ctor
private:
halfedge_attribute(Mesh const* mesh, PropT const& def_value);
halfedge_attribute(Mesh const* mesh, AttrT const& def_value);
friend struct halfedge_collection;
};
/// ======== IMPLEMENTATION ========
template<typename AttrT>
void vertex_attribute<AttrT>::apply_remapping(const std::vector<int> &map)
{
for (auto i = 0u; i < map.size(); ++i)
mData[i] = mData[map[i]];
}
template<typename AttrT>
void face_attribute<AttrT>::apply_remapping(const std::vector<int> &map)
{
for (auto i = 0u; i < map.size(); ++i)
mData[i] = mData[map[i]];
}
template<typename AttrT>
void edge_attribute<AttrT>::apply_remapping(const std::vector<int> &map)
{
for (auto i = 0u; i < map.size(); ++i)
mData[i] = mData[map[i]];
}
template<typename AttrT>
void halfedge_attribute<AttrT>::apply_remapping(const std::vector<int> &map)
{
for (auto i = 0u; i < map.size(); ++i)
mData[i] = mData[map[i]];
}
/// ======== CURSOR IMPLEMENTATION ========
template <typename PropT>
PropT& face_index::operator[](face_attribute<PropT>& prop) const
template <typename AttrT>
AttrT& face_index::operator[](face_attribute<AttrT>& attr) const
{
return prop[*this];
return attr[*this];
}
template <typename PropT>
PropT const& face_index::operator[](face_attribute<PropT> const& prop) const
template <typename AttrT>
AttrT const& face_index::operator[](face_attribute<AttrT> const& attr) const
{
return prop[*this];
return attr[*this];
}
template <typename PropT>
PropT& face_handle::operator[](face_attribute<PropT>& prop) const
template <typename AttrT>
AttrT& face_handle::operator[](face_attribute<AttrT>& attr) const
{
return prop[*this];
return attr[*this];
}
template <typename PropT>
PropT const& face_handle::operator[](face_attribute<PropT> const& prop) const
template <typename AttrT>
AttrT const& face_handle::operator[](face_attribute<AttrT> const& attr) const
{
return prop[*this];
return attr[*this];
}
template <typename PropT>
PropT& vertex_index::operator[](vertex_attribute<PropT>& prop) const
template <typename AttrT>
AttrT& vertex_index::operator[](vertex_attribute<AttrT>& attr) const
{
return prop[*this];
return attr[*this];
}
template <typename PropT>
PropT const& vertex_index::operator[](vertex_attribute<PropT> const& prop) const
template <typename AttrT>
AttrT const& vertex_index::operator[](vertex_attribute<AttrT> const& attr) const
{
return prop[*this];
return attr[*this];
}
template <typename PropT>
PropT& vertex_handle::operator[](vertex_attribute<PropT>& prop) const
template <typename AttrT>
AttrT& vertex_handle::operator[](vertex_attribute<AttrT>& attr) const
{
return prop[*this];
return attr[*this];
}
template <typename PropT>
PropT const& vertex_handle::operator[](vertex_attribute<PropT> const& prop) const
template <typename AttrT>
AttrT const& vertex_handle::operator[](vertex_attribute<AttrT> const& attr) const
{
return prop[*this];
return attr[*this];
}
template <typename PropT>
PropT& edge_index::operator[](edge_attribute<PropT>& prop) const
template <typename AttrT>
AttrT& edge_index::operator[](edge_attribute<AttrT>& attr) const
{
return prop[*this];
return attr[*this];
}
template <typename PropT>
PropT const& edge_index::operator[](edge_attribute<PropT> const& prop) const
template <typename AttrT>
AttrT const& edge_index::operator[](edge_attribute<AttrT> const& attr) const
{
return prop[*this];
return attr[*this];
}
template <typename PropT>
PropT& edge_handle::operator[](edge_attribute<PropT>& prop) const
template <typename AttrT>
AttrT& edge_handle::operator[](edge_attribute<AttrT>& attr) const
{
return prop[*this];
return attr[*this];
}
template <typename PropT>
PropT const& edge_handle::operator[](edge_attribute<PropT> const& prop) const
template <typename AttrT>
AttrT const& edge_handle::operator[](edge_attribute<AttrT> const& attr) const
{
return prop[*this];
return attr[*this];
}
template <typename PropT>
PropT& halfedge_index::operator[](halfedge_attribute<PropT>& prop) const
template <typename AttrT>
AttrT& halfedge_index::operator[](halfedge_attribute<AttrT>& attr) const
{
return prop[*this];
return attr[*this];
}
template <typename PropT>
PropT const& halfedge_index::operator[](halfedge_attribute<PropT> const& prop) const
template <typename AttrT>
AttrT const& halfedge_index::operator[](halfedge_attribute<AttrT> const& attr) const
{
return prop[*this];
return attr[*this];
}
template <typename PropT>
PropT& halfedge_handle::operator[](halfedge_attribute<PropT>& prop) const
template <typename AttrT>
AttrT& halfedge_handle::operator[](halfedge_attribute<AttrT>& attr) const
{
return prop[*this];
return attr[*this];
}
template <typename PropT>
PropT const& halfedge_handle::operator[](halfedge_attribute<PropT> const& prop) const
template <typename AttrT>
AttrT const& halfedge_handle::operator[](halfedge_attribute<AttrT> const& attr) const
{
return prop[*this];
return attr[*this];
}
}
......@@ -19,6 +19,15 @@ struct edge_handle;
struct halfedge_handle;
struct face_vertex_ring;
struct face_edge_ring;
struct face_halfedge_ring;
struct face_face_ring;
struct vertex_halfedge_out_ring;
struct vertex_halfedge_in_ring;
struct vertex_face_ring;
struct vertex_edge_ring;
struct vertex_vertex_ring;
// ======================== INDICES ========================
......@@ -124,12 +133,9 @@ struct face_handle
halfedge_handle any_halfedge() const;
face_vertex_ring vertices() const;
// TODO:
// faces (1-ring)
// edges
// halfedges
// vertices
face_edge_ring edges() const;
face_halfedge_ring halfedges() const;
face_face_ring adjacent_faces() const;
};
struct vertex_handle
......@@ -153,7 +159,14 @@ struct vertex_handle
bool is_removed() const; ///< marked for deletion (or invalid idx)
face_handle any_face() const;
halfedge_handle any_halfedge() const;
halfedge_handle any_outgoing_halfedge() const;
halfedge_handle any_incoming_halfedge() const;
vertex_halfedge_in_ring incoming_halfedges() const;
vertex_halfedge_out_ring outcoming_halfedges() const;
vertex_edge_ring edges() const;
vertex_face_ring faces() const; ///< includes invalid ones for boundaries!
vertex_vertex_ring adjacent_vertices() const;
};
struct edge_handle
......@@ -178,6 +191,10 @@ struct edge_handle
halfedge_handle halfedgeA() const;