diff --git a/src/OpenMesh/Core/Mesh/SmartRange.hh b/src/OpenMesh/Core/Mesh/SmartRange.hh index 04053153..8f026b19 100644 --- a/src/OpenMesh/Core/Mesh/SmartRange.hh +++ b/src/OpenMesh/Core/Mesh/SmartRange.hh @@ -408,6 +408,20 @@ struct SmartRangeT return FilteredSmartRangeT::type>(f, b, e); } + /** @brief Only iterate over a subset of elements + * + * Returns a smart range which skips all elements that do not satisfy functor \p f + * + * @param f Functor that needs to be evaluated to true if the element should not be skipped. + */ + template + auto filtered(Functor& f) -> FilteredSmartRangeT::type&> + { + auto range = static_cast(this); + auto b = (*range).begin(); + auto e = (*range).end(); + return FilteredSmartRangeT::type&>(f, b, e); + } }; @@ -423,7 +437,7 @@ struct FilteredSmartRangeT : public SmartRangeT to_be_visited(true, mesh_); + int visited_faces_in_main_loop = 0; + int visited_faces_in_sub_loop = 0; + for (auto fh : mesh_.faces().filtered(to_be_visited)) + { + to_be_visited(fh) = false; + ++visited_faces_in_main_loop; + for (auto neighbor : fh.faces().filtered(to_be_visited)) + { + to_be_visited(neighbor) = false; + ++visited_faces_in_sub_loop; + } + } + + EXPECT_LT(visited_faces_in_main_loop, mesh_.n_faces()) << "Visted more faces than expected"; + EXPECT_TRUE(mesh_.faces().all_of([&](FH fh) { return !to_be_visited(fh); })) << "did not visit all faces"; + EXPECT_EQ(visited_faces_in_main_loop + visited_faces_in_sub_loop, mesh_.n_faces()) << "Did not visited all faces exactly once"; + } + + { + OpenMesh::FProp to_be_visited(true, mesh_); + const auto& to_be_visited_const_ref = to_be_visited; + int visited_faces_in_main_loop = 0; + int visited_faces_in_sub_loop = 0; + for (auto fh : mesh_.faces().filtered(to_be_visited_const_ref)) + { + to_be_visited(fh) = false; + ++visited_faces_in_main_loop; + for (auto neighbor : fh.faces().filtered(to_be_visited_const_ref)) + { + to_be_visited(neighbor) = false; + ++visited_faces_in_sub_loop; + } + } + + EXPECT_LT(visited_faces_in_main_loop, mesh_.n_faces()) << "Visted more faces than expected"; + EXPECT_TRUE(mesh_.faces().all_of([&](FH fh) { return !to_be_visited(fh); })) << "did not visit all faces"; + EXPECT_EQ(visited_faces_in_main_loop + visited_faces_in_sub_loop, mesh_.n_faces()) << "Did not visited all faces exactly once"; + } + }