Commit 36ceca6e authored by Martin Heistermann's avatar Martin Heistermann

Fix deferred vertex deletion, add unit tests.

GeometryKernel::collect_garbage used to first perform the TopologyKernel
garbage collection, usually shrinking its vertex_deleted_ member, then
accessed it using is_deleted() with the old vertex indices.

This caused out-of-bounds memory access (made visible by
cmake -DSTL_VECTOR_CHECKS=ON) and non-fast deletion also resulted in wrong
results, the remaining vertices had wrong coordinates.
parent 865fdba5
......@@ -107,13 +107,17 @@ public:
virtual void collect_garbage()
{
TopologyKernelT::collect_garbage();
for (unsigned int i = vertices_.size(); i > 0; --i)
if (TopologyKernelT::is_deleted(VertexHandle(i-1)))
{
vertices_.erase(vertices_.begin() + (i-1));
}
if (TopologyKernel::fast_deletion_enabled()) {
TopologyKernelT::collect_garbage();
vertices_.resize(TopologyKernel::n_vertices());
} else {
for (unsigned int i = vertices_.size(); i > 0; --i)
if (TopologyKernelT::is_deleted(VertexHandle(i-1)))
{
vertices_.erase(vertices_.begin() + (i-1));
}
TopologyKernelT::collect_garbage();
}
}
......
......@@ -2002,3 +2002,22 @@ TEST_F(PolyhedralMeshBase, SwapVertices) {
EXPECT_EQ(12u, mesh_.n_vertices());
}
void testDeferredDelete(PolyhedralMesh &mesh) {
mesh.add_vertex(Vec3d(1,0,0));
mesh.add_vertex(Vec3d(0,1,0));
mesh.delete_vertex(VertexHandle(0));
mesh.collect_garbage();
EXPECT_DOUBLE_EQ(mesh.vertex(VertexHandle(0))[1], 1);
}
TEST_F(PolyhedralMeshBase, DeferredDelete) {
mesh_.enable_deferred_deletion(true);
mesh_.enable_fast_deletion(false);
testDeferredDelete(mesh_);
}
TEST_F(PolyhedralMeshBase, DeferredFastDelete) {
mesh_.enable_deferred_deletion(true);
mesh_.enable_fast_deletion(true);
testDeferredDelete(mesh_);
}
Markdown is supported
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