diff --git a/src/Unittests/unittests_trimesh_iterators.hh b/src/Unittests/unittests_trimesh_iterators.hh index f1da04c8..936fb15a 100644 --- a/src/Unittests/unittests_trimesh_iterators.hh +++ b/src/Unittests/unittests_trimesh_iterators.hh @@ -227,6 +227,206 @@ TEST_F(OpenMeshIterators, EdgeIter) { } +/* Adds a cube to a trimesh and runs over all halfedges + */ +TEST_F(OpenMeshIterators, HalfedgeIterSkipping) { + + mesh_.clear(); + + // Add some vertices + Mesh::VertexHandle vhandle[8]; + vhandle[0] = mesh_.add_vertex(Mesh::Point(-1, -1, 1)); + vhandle[1] = mesh_.add_vertex(Mesh::Point( 1, -1, 1)); + vhandle[2] = mesh_.add_vertex(Mesh::Point( 1, 1, 1)); + vhandle[3] = mesh_.add_vertex(Mesh::Point(-1, 1, 1)); + vhandle[4] = mesh_.add_vertex(Mesh::Point(-1, -1, -1)); + vhandle[5] = mesh_.add_vertex(Mesh::Point( 1, -1, -1)); + vhandle[6] = mesh_.add_vertex(Mesh::Point( 1, 1, -1)); + vhandle[7] = mesh_.add_vertex(Mesh::Point(-1, 1, -1)); + + // Add six faces to form a cube + std::vector face_vhandles; + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[3]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[3]); + mesh_.add_face(face_vhandles); + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[6]); + face_vhandles.push_back(vhandle[5]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[5]); + mesh_.add_face(face_vhandles); + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[5]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[6]); + mesh_.add_face(face_vhandles); + + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[6]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[6]); + face_vhandles.push_back(vhandle[7]); + mesh_.add_face(face_vhandles); + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[7]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + + // Test setup: + // + // + // 3 ======== 2 + // / /| + // / / | z + // 0 ======== 1 | | + // | | | | y + // | 7 | 6 | / + // | | / | / + // | |/ |/ + // 4 ======== 5 -------> x + // + + // Check setup + EXPECT_EQ(18u, mesh_.n_edges() ) << "Wrong number of Edges"; + EXPECT_EQ(36u, mesh_.n_halfedges() ) << "Wrong number of HalfEdges"; + EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong number of vertices"; + EXPECT_EQ(12u, mesh_.n_faces() ) << "Wrong number of faces"; + + + // Run over all halfedges + unsigned int heCounter = 0; + + mesh_.request_face_status(); + mesh_.request_vertex_status(); + mesh_.request_halfedge_status(); + + // Get second edge + Mesh::EdgeHandle eh = mesh_.edge_handle(2); + + // Delete one edge + mesh_.delete_edge(eh); + + // Check setup ( No garbage collection, so nothing should change!) + EXPECT_EQ(18u, mesh_.n_edges() ) << "Wrong number of Edges after delete"; + EXPECT_EQ(36u, mesh_.n_halfedges() ) << "Wrong number of HalfEdges after delete"; + EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong number of vertices after delete"; + EXPECT_EQ(12u, mesh_.n_faces() ) << "Wrong number of faces after delete"; + + Mesh::HalfedgeIter he_it = mesh_.halfedges_sbegin(); + Mesh::HalfedgeIter he_end = mesh_.halfedges_end(); + + EXPECT_EQ(0, he_it.handle().idx()) << "Wrong start index in halfedge iterator"; + EXPECT_EQ(36, he_end.handle().idx()) << "Wrong end index in halfedge iterator"; + + + // ===================================================== + // Check skipping iterator + // ===================================================== + bool ok_4 = true; + bool ok_5 = true; + + unsigned int count = 0; + + while (he_it != he_end) { + if ( he_it.handle().idx() == 4 ) + ok_4 = false; + + if ( he_it.handle().idx() == 5 ) + ok_5 = false; + + ++he_it; + ++count; + } + + EXPECT_EQ(34u,count) << "Skipping iterator count error"; + EXPECT_TRUE( ok_4 ) << "Skipping iterator hit deleted halfedge 4"; + EXPECT_TRUE( ok_5 ) << "Skipping iterator hit deleted halfedge 5"; + + // ===================================================== + // Check non skipping iterator + // ===================================================== + he_it = mesh_.halfedges_begin(); + + count = 0; + ok_4 = false; + ok_5 = false; + + while (he_it != he_end) { + if ( he_it.handle().idx() == 4 ) + ok_4 = true; + + if ( he_it.handle().idx() == 5 ) + ok_5 = true; + + + ++he_it; + ++count; + } + + EXPECT_EQ(36u,count) << "Non-skipping iterator count error"; + EXPECT_TRUE( ok_4 ) << "Non-skipping iterator missed deleted halfedge 4"; + EXPECT_TRUE( ok_5 ) << "Non-skipping iterator missed deleted halfedge 5"; +} + /* * Test with a mesh with one deleted face */