Commit 83b5410a authored by Philip Trettner's avatar Philip Trettner
Browse files

templated collections

parent 6b33318b
......@@ -8,7 +8,7 @@ Standard: Cpp11
# 80 columns guideline
ColumnLimit: 120
ColumnLimit: 150
PenaltyExcessCharacter: 1
PenaltyBreakString: 50
......@@ -17,7 +17,7 @@ PenaltyBreakString: 50
IndentWidth: 4
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortFunctionsOnASingleLine: All
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: true
#BraceBreakingStyle: ???
......
......@@ -30,68 +30,68 @@ void Mesh::assert_consistency() const
auto invalid_edge_cnt = 0;
auto invalid_halfedge_cnt = 0;
for (auto h : vertices())
for (auto h : all_vertices())
{
++vertex_cnt;
if (h.is_removed())
++invalid_vertex_cnt;
}
for (auto h : faces())
for (auto h : all_faces())
{
++face_cnt;
if (h.is_removed())
++invalid_face_cnt;
}
for (auto h : edges())
for (auto h : all_edges())
{
++edge_cnt;
if (h.is_removed())
++invalid_edge_cnt;
}
for (auto h : halfedges())
for (auto h : all_halfedges())
{
++halfedge_cnt;
if (h.is_removed())
++invalid_halfedge_cnt;
}
for (auto h : valid_vertices())
for (auto h : vertices())
{
assert(h.is_valid());
assert(!h.is_removed());
++valid_vertex_cnt;
}
for (auto h : valid_faces())
for (auto h : faces())
{
assert(h.is_valid());
assert(!h.is_removed());
++valid_face_cnt;
}
for (auto h : valid_edges())
for (auto h : edges())
{
assert(h.is_valid());
assert(!h.is_removed());
++valid_edge_cnt;
}
for (auto h : valid_halfedges())
for (auto h : halfedges())
{
assert(h.is_valid());
assert(!h.is_removed());
++valid_halfedge_cnt;
}
assert(vertex_cnt == vertices().size());
assert(face_cnt == faces().size());
assert(edge_cnt == edges().size());
assert(halfedge_cnt == halfedges().size());
assert(vertex_cnt == all_vertices().size());
assert(face_cnt == all_faces().size());
assert(edge_cnt == all_edges().size());
assert(halfedge_cnt == all_halfedges().size());
assert(valid_vertex_cnt == valid_vertices().size());
assert(valid_face_cnt == valid_faces().size());
assert(valid_edge_cnt == valid_edges().size());
assert(valid_halfedge_cnt == valid_halfedges().size());
assert(valid_vertex_cnt == vertices().size());
assert(valid_face_cnt == faces().size());
assert(valid_edge_cnt == edges().size());
assert(valid_halfedge_cnt == halfedges().size());
assert(vertex_cnt == valid_vertex_cnt + invalid_vertex_cnt);
assert(face_cnt == valid_face_cnt + invalid_face_cnt);
......@@ -107,7 +107,7 @@ void Mesh::assert_consistency() const
}
// check only non-removed can be accessed topologically
for (auto f : valid_faces())
for (auto f : faces())
{
assert(!f.any_halfedge().is_removed());
assert(!f.any_vertex().is_removed());
......@@ -124,7 +124,7 @@ void Mesh::assert_consistency() const
for (auto f : f.edges())
assert(!f.is_removed());
}
for (auto v : valid_vertices())
for (auto v : vertices())
{
assert(!v.any_face().is_removed());
assert(!v.any_edge().is_removed());
......@@ -146,7 +146,7 @@ void Mesh::assert_consistency() const
for (auto f : v.edges())
assert(!f.is_removed());
}
for (auto e : valid_edges())
for (auto e : edges())
{
assert(!e.faceA().is_removed());
assert(!e.faceB().is_removed());
......@@ -157,7 +157,7 @@ void Mesh::assert_consistency() const
assert(!e.halfedgeA().is_removed());
assert(!e.halfedgeB().is_removed());
}
for (auto h : valid_halfedges())
for (auto h : halfedges())
{
assert(!h.prev().is_removed());
assert(!h.next().is_removed());
......@@ -170,7 +170,7 @@ void Mesh::assert_consistency() const
}
// check half-edge consistencies
for (auto h : valid_halfedges())
for (auto h : halfedges())
{
assert(h.next().is_valid());
assert(h.prev().is_valid());
......@@ -192,7 +192,7 @@ void Mesh::assert_consistency() const
}
// check vertex consistencies
for (auto v : valid_vertices())
for (auto v : vertices())
{
if (!v.is_isolated())
{
......@@ -237,7 +237,7 @@ void Mesh::assert_consistency() const
}
// check face consistencies
for (auto f : valid_faces())
for (auto f : faces())
{
assert(f.any_halfedge().is_valid());
assert(f.any_vertex().is_valid());
......@@ -260,7 +260,7 @@ void Mesh::assert_consistency() const
}
// check edge consistencies
for (auto e : valid_edges())
for (auto e : edges())
{
assert(e.vertexA().is_valid());
assert(e.vertexB().is_valid());
......@@ -279,7 +279,7 @@ void Mesh::assert_consistency() const
}
// check boundaries
for (auto h : valid_halfedges())
for (auto h : halfedges())
if (h.is_boundary())
{
assert(h.face().is_invalid());
......@@ -304,11 +304,11 @@ void Mesh::assert_consistency() const
auto v_e_sum = 0;
auto f_h_sum = 0;
for (auto v : valid_vertices())
for (auto v : vertices())
{
v_e_sum += v.edges().size();
}
for (auto f : valid_faces())
for (auto f : faces())
{
f_h_sum += f.halfedges().size();
}
......@@ -322,25 +322,25 @@ void Mesh::assert_consistency() const
// compactness
if (is_compact())
{
for (auto v : vertices())
for (auto v : all_vertices())
{
assert(v.is_valid());
assert(!v.is_removed());
}
for (auto f : faces())
for (auto f : all_faces())
{
assert(f.is_valid());
assert(!f.is_removed());
}
for (auto e : edges())
for (auto e : all_edges())
{
assert(e.is_valid());
assert(!e.is_removed());
}
for (auto h : halfedges())
for (auto h : all_halfedges())
{
assert(h.is_valid());
assert(!h.is_removed());
......@@ -349,7 +349,7 @@ void Mesh::assert_consistency() const
// check half-edge uniqueness
std::map<int, std::set<int>> hes;
for (auto h : valid_halfedges())
for (auto h : halfedges())
{
auto v0 = h.vertex_from().idx.value;
auto v1 = h.vertex_to().idx.value;
......
......@@ -136,27 +136,6 @@ private:
face_index prev_valid_idx_from(face_index idx) const;
halfedge_index prev_valid_idx_from(halfedge_index idx) const;
// Iterators
all_vertex_iterator vertices_begin() const { return {{this, vertex_index(0)}}; }
all_vertex_iterator vertices_end() const { return {{this, vertex_index(size_vertices())}}; }
valid_vertex_iterator valid_vertices_begin() const { return {{this, vertex_index(0)}}; }
valid_vertex_iterator valid_vertices_end() const { return {{this, vertex_index(size_vertices())}}; }
face_iterator faces_begin() const { return {{this, face_index(0)}}; }
face_iterator faces_end() const { return {{this, face_index(size_faces())}}; }
valid_face_iterator valid_faces_begin() const { return {{this, face_index(0)}}; }
valid_face_iterator valid_faces_end() const { return {{this, face_index(size_faces())}}; }
edge_iterator edges_begin() const { return {{this, edge_index(0)}}; }
edge_iterator edges_end() const { return {{this, edge_index(size_edges())}}; }
valid_edge_iterator valid_edges_begin() const { return {{this, edge_index(0)}}; }
valid_edge_iterator valid_edges_end() const { return {{this, edge_index(size_edges())}}; }
halfedge_iterator halfedges_begin() const { return {{this, halfedge_index(0)}}; }
halfedge_iterator halfedges_end() const { return {{this, halfedge_index(size_halfedges())}}; }
valid_halfedge_iterator valid_halfedges_begin() const { return {{this, halfedge_index(0)}}; }
valid_halfedge_iterator valid_halfedges_end() const { return {{this, halfedge_index(size_halfedges())}}; }
/// Adds a single non-connected vertex
/// Does NOT invalidate iterators!
vertex_index add_vertex();
......@@ -382,18 +361,17 @@ private:
friend struct const_primitive_collection;
template <class tag>
friend struct primitive_attribute_base;
template<class mesh_ptr, class tag, class iterator>
template <class mesh_ptr, class tag, class iterator>
friend struct smart_collection;
template<class iterator>
struct vertex_collection;
template<class iterator>
struct face_collection;
template<class iterator>
struct edge_collection;
template<class iterator>
struct halfedge_collection;
template <class iterator>
friend struct vertex_collection;
template <class iterator>
friend struct face_collection;
template <class iterator>
friend struct edge_collection;
template <class iterator>
friend struct halfedge_collection;
};
}
/// ======== IMPLEMENTATIONS ========
......@@ -403,3 +381,4 @@ private:
#include "impl/impl_iterators.hh"
#include "impl/impl_mesh.hh"
#include "impl/impl_ranges.hh"
#include "impl/impl_primitive.hh"
#pragma once
#include <algorithm>
#include <cstddef>
#include <vector>
......@@ -19,7 +20,7 @@ struct attribute_data
DataT const& operator[](int i) const { return data[i]; }
attribute_data() = default;
attribute_data(attribute_data<DataT> const& rhs) // copy
attribute_data(attribute_data<DataT> const& rhs) noexcept // copy
{
size = rhs.size;
data = new DataT[size];
......@@ -27,7 +28,7 @@ struct attribute_data
for (int i = 0; i < size; ++i)
data[i] = rhs.data[i];
}
attribute_data(attribute_data<DataT>&& rhs) // move
attribute_data(attribute_data<DataT>&& rhs) noexcept // move
{
size = rhs.size;
data = rhs.data;
......@@ -35,7 +36,7 @@ struct attribute_data
rhs.size = 0;
rhs.data = nullptr;
}
attribute_data<DataT>& operator=(attribute_data<DataT> const& rhs) // copy
attribute_data<DataT>& operator=(attribute_data<DataT> const& rhs) noexcept // copy
{
delete[] data;
......@@ -47,7 +48,7 @@ struct attribute_data
return *this;
}
attribute_data<DataT>& operator=(attribute_data<DataT>&& rhs) // move
attribute_data<DataT>& operator=(attribute_data<DataT>&& rhs) noexcept // move
{
delete[] data;
......@@ -67,15 +68,15 @@ struct attribute_data
if (new_size < size)
{
for (int i = 0; i < new_size; ++i)
for (auto i = 0; i < new_size; ++i)
new_data[i] = data[i];
}
else
{
for (int i = 0; i < size; ++i)
for (auto i = 0; i < size; ++i)
new_data[i] = data[i];
for (int i = size; i < new_size; ++i)
for (auto i = size; i < new_size; ++i)
new_data[i] = default_value;
}
......@@ -92,18 +93,18 @@ private:
primitive_attribute_base* mNextAttribute = nullptr;
primitive_attribute_base* mPrevAttribute = nullptr;
void resize(int newSize, bool force)
void resize(int new_size, bool force)
{
if (force)
{
mDataSize = newSize;
mDataSize = new_size;
on_resize(mDataSize);
return;
}
if (mDataSize < newSize)
if (mDataSize < new_size)
{
mDataSize = std::max(newSize, 1 + mDataSize + (mDataSize >> 1)); // 1 + s * 1.5
mDataSize = std::max(new_size, 1 + mDataSize + (mDataSize >> 1)); // 1 + s * 1.5
on_resize(mDataSize);
}
}
......@@ -113,7 +114,7 @@ protected:
Mesh const* mMesh;
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 on_resize(int new_size) = 0;
virtual void apply_remapping(std::vector<int> const& map) = 0;
void register_attr();
void deregister_attr();
......
......@@ -68,10 +68,10 @@ protected:
// move & copy
public:
primitive_attribute(primitive_attribute const&);
primitive_attribute(primitive_attribute&&);
primitive_attribute& operator=(primitive_attribute const&);
primitive_attribute& operator=(primitive_attribute&&);
primitive_attribute(primitive_attribute const&) noexcept;
primitive_attribute(primitive_attribute&&) noexcept;
primitive_attribute& operator=(primitive_attribute const&) noexcept;
primitive_attribute& operator=(primitive_attribute&&) noexcept;
};
template <class AttrT>
......@@ -79,7 +79,7 @@ struct vertex_attribute : primitive_attribute<vertex_tag, AttrT>
{
using primitive_attribute<vertex_tag, AttrT>::primitive_attribute;
template<class mesh_ptr, class tag, class iterator>
template <class mesh_ptr, class tag, class iterator>
friend struct smart_collection;
};
template <class AttrT>
......@@ -87,7 +87,7 @@ struct face_attribute : primitive_attribute<face_tag, AttrT>
{
using primitive_attribute<face_tag, AttrT>::primitive_attribute;
template<class mesh_ptr, class tag, class iterator>
template <class mesh_ptr, class tag, class iterator>
friend struct smart_collection;
};
template <class AttrT>
......@@ -95,7 +95,7 @@ struct edge_attribute : primitive_attribute<edge_tag, AttrT>
{
using primitive_attribute<edge_tag, AttrT>::primitive_attribute;
template<class mesh_ptr, class tag, class iterator>
template <class mesh_ptr, class tag, class iterator>
friend struct smart_collection;
};
template <class AttrT>
......@@ -103,7 +103,7 @@ struct halfedge_attribute : primitive_attribute<halfedge_tag, AttrT>
{
using primitive_attribute<halfedge_tag, AttrT>::primitive_attribute;
template<class mesh_ptr, class tag, class iterator>
template <class mesh_ptr, class tag, class iterator>
friend struct smart_collection;
};
......@@ -117,7 +117,7 @@ void primitive_attribute<tag, AttrT>::apply_remapping(const std::vector<int>& ma
}
template <class tag, class AttrT>
primitive_attribute<tag, AttrT>::primitive_attribute(primitive_attribute const& rhs) : primitive_attribute_base<tag>(rhs.mMesh) // copy
primitive_attribute<tag, AttrT>::primitive_attribute(primitive_attribute const& rhs) noexcept : primitive_attribute_base<tag>(rhs.mMesh) // copy
{
this->mDefaultValue = rhs.mDefaultValue;
this->mData = rhs.mData;
......@@ -127,7 +127,7 @@ primitive_attribute<tag, AttrT>::primitive_attribute(primitive_attribute const&
}
template <class tag, class AttrT>
primitive_attribute<tag, AttrT>::primitive_attribute(primitive_attribute&& rhs) : primitive_attribute_base<tag>(rhs.mMesh) // move
primitive_attribute<tag, AttrT>::primitive_attribute(primitive_attribute&& rhs) noexcept : primitive_attribute_base<tag>(rhs.mMesh) // move
{
this->mDefaultValue = std::move(rhs.mDefaultValue);
this->mData = std::move(rhs.mData);
......@@ -138,7 +138,7 @@ primitive_attribute<tag, AttrT>::primitive_attribute(primitive_attribute&& rhs)
}
template <class tag, class AttrT>
primitive_attribute<tag, AttrT>& primitive_attribute<tag, AttrT>::operator=(primitive_attribute const& rhs) // copy
primitive_attribute<tag, AttrT>& primitive_attribute<tag, AttrT>::operator=(primitive_attribute const& rhs) noexcept // copy
{
this->deregister_attr();
......@@ -148,10 +148,12 @@ primitive_attribute<tag, AttrT>& primitive_attribute<tag, AttrT>::operator=(prim
this->mDataSize = rhs.mDataSize;
this->register_attr();
return *this;
}
template <class tag, class AttrT>
primitive_attribute<tag, AttrT>& primitive_attribute<tag, AttrT>::operator=(primitive_attribute&& rhs) // move
primitive_attribute<tag, AttrT>& primitive_attribute<tag, AttrT>::operator=(primitive_attribute&& rhs) noexcept // move
{
this->deregister_attr();
......@@ -162,58 +164,59 @@ primitive_attribute<tag, AttrT>& primitive_attribute<tag, AttrT>::operator=(prim
rhs.deregister_attr();
this->register_attr();
return *this;
}
/// ======== CURSOR IMPLEMENTATION ========
template <class tag>
template <class AttrT>
AttrT& primitive_index<tag>::operator[](primitive_index::attribute<AttrT>& attr) const
AttrT& primitive_index<tag>::operator[](attribute<AttrT>& attr) const
{
return attr[*this];
}
template <class tag>
template <class AttrT>
AttrT const& primitive_index<tag>::operator[](primitive_index::attribute<AttrT> const& attr) const
AttrT const& primitive_index<tag>::operator[](attribute<AttrT> const& attr) const
{
return attr[*this];
}
template <class tag>
template <class AttrT>
AttrT& primitive_index<tag>::operator[](primitive_index::attribute<AttrT>* attr) const
AttrT& primitive_index<tag>::operator[](attribute<AttrT>* attr) const
{
return (*attr)[*this];
}
template <class tag>
template <class AttrT>
AttrT const& primitive_index<tag>::operator[](primitive_index::attribute<AttrT> const* attr) const
AttrT const& primitive_index<tag>::operator[](attribute<AttrT> const* attr) const
{
return (*attr)[*this];
}
template <class tag>
template <class AttrT>
AttrT& primitive_handle<tag>::operator[](primitive_handle::attribute<AttrT>& attr) const
AttrT& primitive_handle<tag>::operator[](attribute<AttrT>& attr) const
{
return attr[idx];
}
template <class tag>
template <class AttrT>
AttrT const& primitive_handle<tag>::operator[](primitive_handle::attribute<AttrT> const& attr) const
AttrT const& primitive_handle<tag>::operator[](attribute<AttrT> const& attr) const
{
return attr[idx];
}
template <class tag>
template <class AttrT>
AttrT& primitive_handle<tag>::operator[](primitive_handle::attribute<AttrT>* attr) const
AttrT& primitive_handle<tag>::operator[](attribute<AttrT>* attr) const
{
return (*attr)[idx];
}
template <class tag>
template <class AttrT>
AttrT const& primitive_handle<tag>::operator[](primitive_handle::attribute<AttrT> const* attr) const
AttrT const& primitive_handle<tag>::operator[](attribute<AttrT> const* attr) const
{
return (*attr)[idx];
}
}
......@@ -21,20 +21,11 @@ obj_writer::obj_writer(const std::string &filename)
out = tmp_out;
}
obj_writer::obj_writer(std::ostream &out)
{
this->out = &out;
}
obj_writer::obj_writer(std::ostream &out) { this->out = &out; }
obj_writer::~obj_writer()
{
delete tmp_out;
}
obj_writer::~obj_writer() { delete tmp_out; }
void obj_writer::write_object_name(std::string object_name)
{
*out << "o " << object_name << "\n";
}
void obj_writer::write_object_name(std::string object_name) { *out << "o " << object_name << "\n"; }
void obj_writer::write_mesh(const Mesh &mesh,
vertex_attribute<glm::vec3> const &position,
......@@ -45,7 +36,7 @@ void obj_writer::write_mesh(const Mesh &mesh,
auto base_t = texture_idx;
auto base_n = normal_idx;
for (auto v : mesh.vertices())
for (auto v : mesh.all_vertices())
{
auto pos = v[position];
*out << "v " << pos.x << " " << pos.y << " " << pos.z << "\n";
......@@ -53,7 +44,7 @@ void obj_writer::write_mesh(const Mesh &mesh,
}
if (tex_coord)
for (auto v : mesh.vertices())
for (auto v : mesh.all_vertices())
{
auto t = v[*tex_coord];
*out << "vt " << t.x << " " << t.y << "\n";
......@@ -61,14 +52,14 @@ void obj_writer::write_mesh(const Mesh &mesh,
}
if (normal)
for (auto v : mesh.vertices())
for (auto v : mesh.all_vertices())
{
auto n = v[*normal];
*out << "vn " << n.x << " " << n.y << " " << n.z << "\n";
++normal_idx;
}
for (auto f : mesh.valid_faces())
for (auto f : mesh.faces())
{
*out << "f";
for (auto v : f.vertices())
......@@ -110,25 +101,16 @@ obj_reader::obj_reader(std::istream &in, Mesh &mesh)
parse(in, mesh);
}
vertex_attribute<glm::vec4> obj_reader::positions_vec4() const
{
return positions;
}
vertex_attribute<glm::vec4> obj_reader::positions_vec4() const { return positions; }
vertex_attribute<glm::vec3> obj_reader::positions_vec3() const
{
return positions.map([](glm::vec4 const &v) { return glm::vec3(v); });
}
halfedge_attribute<glm::vec3> obj_reader::tex_coords_vec3() const
{
return tex_coords;
}