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

debugging the data structure

parent 03cc6993
......@@ -18,3 +18,5 @@ Best used with glm and glow.
* 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)
* Debug: store compactify generation in handles to check for invalidation
* Debug: insert is_removed assertions into handle access
\ No newline at end of file
......@@ -203,7 +203,7 @@ void Mesh::assert_consistency() const
{
assert(v.any_incoming_halfedge().is_valid());
assert(v.any_outgoing_halfedge().is_valid());
assert(v.any_valid_face().is_valid());
// assert(v.any_valid_face().is_valid()); -> wiremeshes are non-isolated but have no faces
assert(v.any_edge().is_valid());
assert(v.any_incoming_halfedge().vertex_to() == v);
......@@ -313,8 +313,36 @@ void Mesh::assert_consistency() const
v_e_sum += v.edges().size();
}
assert(v_e_sum == 2 * size_edges());
assert(v_e_sum == 2 * size_valid_edges());
// TODO: more?
}
// compactness
if (is_compact())
{
for (auto v : vertices())
{
assert(v.is_valid());
assert(!v.is_removed());
}
for (auto f : faces())
{
assert(f.is_valid());
assert(!f.is_removed());
}
for (auto e : edges())
{
assert(e.is_valid());
assert(!e.is_removed());
}
for (auto h : halfedges())
{
assert(h.is_valid());
assert(!h.is_removed());
}
}
}
......@@ -274,42 +274,42 @@ private:
struct face_info &face(face_index i)
{
assert(i.is_valid());
assert(i.is_valid() && i.value < size_faces());
return mFaces[i.value];
}
struct face_info const &face(face_index i) const
{
assert(i.is_valid());
assert(i.is_valid() && i.value < size_faces());
return mFaces[i.value];
}
struct vertex_info &vertex(vertex_index i)
{
assert(i.is_valid());
assert(i.is_valid() && i.value < size_vertices());
return mVertices[i.value];
}
struct vertex_info const &vertex(vertex_index i) const
{
assert(i.is_valid());
assert(i.is_valid() && i.value < size_vertices());
return mVertices[i.value];
}
struct halfedge_info &halfedge(halfedge_index i)
{
assert(i.is_valid());
assert(i.is_valid() && i.value < size_halfedges());
return mHalfedges[i.value];
}
struct halfedge_info const &halfedge(halfedge_index i) const
{
assert(i.is_valid());
assert(i.is_valid() && i.value < size_halfedges());
return mHalfedges[i.value];
}
struct halfedge_info &halfedge(edge_index i, int h)
{
assert(i.is_valid());
assert(i.is_valid() && i.value < size_edges());
return mHalfedges[(i.value << 1) + h];
}
struct halfedge_info const &halfedge(edge_index i, int h) const
{
assert(i.is_valid());
assert(i.is_valid() && i.value < size_edges());
return mHalfedges[(i.value << 1) + h];
}
......@@ -623,6 +623,7 @@ inline void Mesh::remove_face(face_index f_idx)
// bookkeeping
mRemovedFaces++;
mCompact = false;
}
inline void Mesh::remove_edge(edge_index e_idx)
......@@ -686,6 +687,7 @@ inline void Mesh::remove_edge(edge_index e_idx)
// bookkeeping
mRemovedHalfedges++;
mRemovedHalfedges++;
mCompact = false;
}
inline void Mesh::remove_vertex(vertex_index v_idx)
......@@ -702,6 +704,7 @@ inline void Mesh::remove_vertex(vertex_index v_idx)
// bookkeeping
mRemovedVertices++;
mCompact = false;
}
inline void Mesh::fix_boundary_state_of(vertex_index v_idx)
......@@ -888,6 +891,10 @@ inline vertex_iterator &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++()
{
......@@ -900,6 +907,10 @@ 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++()
{
......@@ -912,6 +923,10 @@ 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++()
{
......@@ -924,6 +939,10 @@ 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);
}
/// ======== RANGES IMPLEMENTATION ========
......@@ -1271,15 +1290,18 @@ inline void Mesh::compactify()
v_old_to_new[i] = v_new_to_old.size();
v_new_to_old.push_back(i);
}
for (auto i = 0; i < f_cnt; ++i)
if (mFaces[i].is_valid())
{
f_old_to_new[i] = f_new_to_old.size();
f_new_to_old.push_back(i);
}
for (auto i = 0; i < e_cnt; ++i)
if (mHalfedges[i << 1].is_valid())
e_new_to_old.push_back(i);
for (auto i = 0; i < h_cnt; ++i)
if (mHalfedges[i].is_valid())
{
......
......@@ -15,50 +15,51 @@
// - vertex normal
// - curvature
namespace polymesh
{
{
/// returns the vertex valence (number of adjacent vertices)
int valence_of(vertex_handle v);
/// see http://geomalgorithms.com/a01-_area.html#3D%20Polygons
/// TODO
/// returns the area of the (flat) polygonal face
float face_area(face_handle f, vertex_attribute<glm::vec3> const& position);
/// returns the signed area of the (flat) polygonal face
float signed_face_area(face_handle f, vertex_attribute<glm::vec3> const& position);
/// returns the center of gravity for a given (flat) polygonal face
glm::vec3 face_centroid(face_handle f, vertex_attribute<glm::vec3> const& position);
/// ======== IMPLEMENTATION ========
inline int valence_of(vertex_handle v)
{
return v.adjacent_vertices().size();
inline int valence_of(vertex_handle v)
{
return v.adjacent_vertices().size();
}
inline float face_area(face_handle f, vertex_attribute<glm::vec3> const& position)
{
return glm::abs(signed_face_area(f, position));
}
glm::vec3 varea;
inline float signed_face_area(face_handle f, vertex_attribute<glm::vec3> const& position)
{
auto area = 0.0f;
auto h = f.any_halfedge();
for (auto h : f.halfedges())
auto v0 = h.vertex_from();
auto p0 = v0[position];
auto p_prev = h.vertex_to()[position];
h = h.next();
do
{
auto v0 = h.vertex_from()[position];
auto v1 = h.vertex_to()[position];
auto p_curr = h.vertex_to()[position];
area += cross(v0, v1);
}
varea += cross(p_prev - p0, p_curr - p0);
// circulate
h = h.next();
} while (h.vertex_to() != v0);
return area / 2;
return length(varea) / 2;
}
inline glm::vec3 face_centroid(face_handle f, vertex_attribute<glm::vec3> const& position)
{
/*
glm::vec3 centroid;
auto area = 0.0f;
......@@ -73,6 +74,8 @@ inline glm::vec3 face_centroid(face_handle f, vertex_attribute<glm::vec3> const&
}
return centroid;
*/
assert(false);
return {};
}
}
}
\ No newline at end of file
......@@ -174,7 +174,7 @@ struct vertex_handle
bool is_boundary() const; ///< true if this vertex lies at a boundary
face_handle any_face() const; ///< invalid if at boundary
face_handle any_valid_face() const; ///< invalid if isolated
face_handle any_valid_face() const; ///< invalid if isolated (and can be if at boundary)
halfedge_handle any_outgoing_halfedge() const; ///< invalid if isolated
halfedge_handle any_incoming_halfedge() const; ///< invalid if isolated
edge_handle any_edge() const; ///< invalid if isolated
......
......@@ -12,7 +12,7 @@ namespace polymesh
struct valid_vertex_iterator
{
valid_vertex_iterator() = default;
valid_vertex_iterator(vertex_handle handle) : handle(handle) {}
valid_vertex_iterator(vertex_handle handle) : handle(handle) { move_to_valid(); }
vertex_handle operator*() const { return handle; }
valid_vertex_iterator& operator++();
......@@ -34,6 +34,8 @@ struct valid_vertex_iterator
private:
vertex_handle handle;
void move_to_valid();
};
struct vertex_iterator
......@@ -66,7 +68,7 @@ private:
struct valid_face_iterator
{
valid_face_iterator() = default;
valid_face_iterator(face_handle handle) : handle(handle) {}
valid_face_iterator(face_handle handle) : handle(handle) { move_to_valid(); }
face_handle operator*() const { return handle; }
valid_face_iterator& operator++();
......@@ -88,6 +90,8 @@ struct valid_face_iterator
private:
face_handle handle;
void move_to_valid();
};
struct face_iterator
......@@ -120,7 +124,7 @@ private:
struct valid_edge_iterator
{
valid_edge_iterator() = default;
valid_edge_iterator(edge_handle handle) : handle(handle) {}
valid_edge_iterator(edge_handle handle) : handle(handle) { move_to_valid(); }
edge_handle operator*() const { return handle; }
valid_edge_iterator& operator++();
......@@ -142,6 +146,8 @@ struct valid_edge_iterator
private:
edge_handle handle;
void move_to_valid();
};
struct edge_iterator
......@@ -174,7 +180,7 @@ private:
struct valid_halfedge_iterator
{
valid_halfedge_iterator() = default;
valid_halfedge_iterator(halfedge_handle handle) : handle(handle) {}
valid_halfedge_iterator(halfedge_handle handle) : handle(handle) { move_to_valid(); }
halfedge_handle operator*() const { return handle; }
valid_halfedge_iterator& operator++();
......@@ -196,6 +202,8 @@ struct valid_halfedge_iterator
private:
halfedge_handle handle;
void move_to_valid();
};
struct halfedge_iterator
......
......@@ -59,7 +59,7 @@ void obj_writer::write_mesh(const Mesh &mesh,
++normal_idx;
}
for (auto f : mesh.faces())
for (auto f : mesh.valid_faces())
{
*out << "f";
for (auto v : f.vertices())
......
Supports Markdown
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