1#include <gtest/gtest.h>
2#include <Unittests/unittests_common.hh>
4#include <OpenMesh/Core/Mesh/PolyConnectivity.hh>
5#include <OpenMesh/Core/Utils/PropertyManager.hh>
6#include <OpenMesh/Core/Utils/Predicates.hh>
18 virtual void SetUp() {
34 std::vector<Mesh::VertexHandle> face_vhandles;
36 face_vhandles.clear();
37 face_vhandles.push_back(vhandle[0]);
38 face_vhandles.push_back(vhandle[1]);
39 face_vhandles.push_back(vhandle[3]);
40 mesh_.add_face(face_vhandles);
42 face_vhandles.clear();
43 face_vhandles.push_back(vhandle[1]);
44 face_vhandles.push_back(vhandle[2]);
45 face_vhandles.push_back(vhandle[3]);
46 mesh_.add_face(face_vhandles);
50 face_vhandles.clear();
51 face_vhandles.push_back(vhandle[7]);
52 face_vhandles.push_back(vhandle[6]);
53 face_vhandles.push_back(vhandle[5]);
54 mesh_.add_face(face_vhandles);
56 face_vhandles.clear();
57 face_vhandles.push_back(vhandle[7]);
58 face_vhandles.push_back(vhandle[5]);
59 face_vhandles.push_back(vhandle[4]);
60 mesh_.add_face(face_vhandles);
64 face_vhandles.clear();
65 face_vhandles.push_back(vhandle[1]);
66 face_vhandles.push_back(vhandle[0]);
67 face_vhandles.push_back(vhandle[4]);
68 mesh_.add_face(face_vhandles);
70 face_vhandles.clear();
71 face_vhandles.push_back(vhandle[1]);
72 face_vhandles.push_back(vhandle[4]);
73 face_vhandles.push_back(vhandle[5]);
74 mesh_.add_face(face_vhandles);
78 face_vhandles.clear();
79 face_vhandles.push_back(vhandle[2]);
80 face_vhandles.push_back(vhandle[1]);
81 face_vhandles.push_back(vhandle[5]);
82 mesh_.add_face(face_vhandles);
84 face_vhandles.clear();
85 face_vhandles.push_back(vhandle[2]);
86 face_vhandles.push_back(vhandle[5]);
87 face_vhandles.push_back(vhandle[6]);
88 mesh_.add_face(face_vhandles);
93 face_vhandles.clear();
94 face_vhandles.push_back(vhandle[3]);
95 face_vhandles.push_back(vhandle[2]);
96 face_vhandles.push_back(vhandle[6]);
97 mesh_.add_face(face_vhandles);
99 face_vhandles.clear();
100 face_vhandles.push_back(vhandle[3]);
101 face_vhandles.push_back(vhandle[6]);
102 face_vhandles.push_back(vhandle[7]);
103 mesh_.add_face(face_vhandles);
107 face_vhandles.clear();
108 face_vhandles.push_back(vhandle[0]);
109 face_vhandles.push_back(vhandle[3]);
110 face_vhandles.push_back(vhandle[7]);
111 mesh_.add_face(face_vhandles);
113 face_vhandles.clear();
114 face_vhandles.push_back(vhandle[0]);
115 face_vhandles.push_back(vhandle[7]);
116 face_vhandles.push_back(vhandle[4]);
117 mesh_.add_face(face_vhandles);
135 EXPECT_EQ(18u, mesh_.n_edges() ) <<
"Wrong number of Edges";
136 EXPECT_EQ(36u, mesh_.n_halfedges() ) <<
"Wrong number of HalfEdges";
137 EXPECT_EQ(8u, mesh_.n_vertices() ) <<
"Wrong number of vertices";
138 EXPECT_EQ(12u, mesh_.n_faces() ) <<
"Wrong number of faces";
142 virtual void TearDown() {
160template <
typename HandleT>
163 unsigned int operator()(HandleT ) {
return 1; }
168TEST_F(OpenMeshSmartRanges, Sum)
171 EXPECT_EQ(mesh_.vertices().sum(one), mesh_.n_vertices());
172 EXPECT_EQ(mesh_.vertices().sum(F<OpenMesh::VertexHandle>()), mesh_.n_vertices());
173 EXPECT_EQ(mesh_.halfedges().sum(F<OpenMesh::HalfedgeHandle>()), mesh_.n_halfedges());
174 EXPECT_EQ(mesh_.edges().sum(F<OpenMesh::EdgeHandle>()), mesh_.n_edges());
175 EXPECT_EQ(mesh_.faces().sum(F<OpenMesh::FaceHandle>()), mesh_.n_faces());
177 for (
auto vh : mesh_.vertices())
178 EXPECT_EQ(vh.vertices().sum(F<
OpenMesh::VertexHandle>()), mesh_.valence(vh));
179 for (
auto vh : mesh_.vertices())
180 EXPECT_EQ(vh.faces().sum(F<
OpenMesh::FaceHandle>()), mesh_.valence(vh));
181 for (
auto vh : mesh_.vertices())
182 EXPECT_EQ(vh.outgoing_halfedges().sum(F<
OpenMesh::HalfedgeHandle>()), mesh_.valence(vh));
183 for (
auto vh : mesh_.vertices())
184 EXPECT_EQ(vh.incoming_halfedges().sum(F<
OpenMesh::HalfedgeHandle>()), mesh_.valence(vh));
186 for (
auto fh : mesh_.faces())
187 EXPECT_EQ(fh.vertices().sum(F<
OpenMesh::VertexHandle>()), mesh_.valence(fh));
188 for (
auto fh : mesh_.faces())
189 EXPECT_EQ(fh.halfedges().sum(F<
OpenMesh::HalfedgeHandle>()), mesh_.valence(fh));
190 for (
auto fh : mesh_.faces())
191 EXPECT_EQ(fh.edges().sum(F<
OpenMesh::EdgeHandle>()), mesh_.valence(fh));
192 for (
auto fh : mesh_.faces())
193 EXPECT_EQ(fh.faces().sum(F<
OpenMesh::FaceHandle>()), 3u);
199TEST_F(OpenMeshSmartRanges, PropertyManagerAsFunctor)
202 for (
auto vh : mesh_.vertices())
203 myPos(vh) = mesh_.point(vh);
206 for (
auto vh : mesh_.vertices())
207 cog += mesh_.point(vh);
208 cog /= mesh_.n_vertices();
210 auto cog2 = mesh_.vertices().avg(myPos);
212 EXPECT_LT(norm(cog - cog2), 0.00001) <<
"Computed center of gravities are significantly different.";
217TEST_F(OpenMeshSmartRanges, ToVector)
221 for (
auto heh : mesh_.halfedges())
224 for (
auto fh : mesh_.faces())
226 auto tri_uvs = fh.halfedges().to_vector(uvs);
227 auto heh_handles = fh.halfedges().to_vector();
228 for (
auto heh : heh_handles)
232 auto vertex_vec = mesh_.vertices().to_vector();
233 for (
auto vh : vertex_vec)
239TEST_F(OpenMeshSmartRanges, ToArray)
243 for (
auto heh : mesh_.halfedges())
246 for (
auto fh : mesh_.faces())
248 fh.halfedges().to_array<3>(uvs);
249 fh.halfedges().to_array<3>();
256TEST_F(OpenMeshSmartRanges, BoundingBox)
261 for (
auto vh : mesh_.vertices())
262 for (int i = 0; i < 3; ++i)
263 myPos(vh)[i] = mesh_.point(vh)[i];
265 auto bb_min = mesh_.vertices().min(myPos);
266 auto bb_max = mesh_.vertices().max(myPos);
267 mesh_.vertices().minmax(myPos);
269 EXPECT_LT(norm(bb_min -
OpenMesh::Vec3f(-1,-1,-1)), 0.000001) <<
"Bounding box minimum seems off";
270 EXPECT_LT(norm(bb_max -
OpenMesh::Vec3f( 1, 1, 1)), 0.000001) <<
"Bounding box maximum seems off";
273 auto uvs = OpenMesh::makeTemporaryProperty<OpenMesh::HalfedgeHandle, OpenMesh::Vec2d>(mesh_);
274 for (
auto heh : mesh_.halfedges())
277 for (
auto fh : mesh_.faces())
279 fh.halfedges().
min(uvs);
280 fh.halfedges().max(uvs);
287TEST_F(OpenMeshSmartRanges, ForEach)
289 std::vector<int> vec;
292 mesh_.vertices().for_each(f);
294 ASSERT_EQ(vec.size(), mesh_.n_vertices()) <<
"vec has wrong size";
295 for (
size_t i = 0; i < vec.size(); ++i)
296 EXPECT_EQ(vec[i],
static_cast<int>(i)) <<
"wrong index in vector";
302TEST_F(OpenMeshSmartRanges, Filtered)
307 auto is_even = [](VH vh) {
return vh.
idx() % 2 == 0; };
308 auto is_odd = [](VH vh) {
return vh.idx() % 2 == 1; };
309 auto is_divisible_by_3 = [](VH vh) {
return vh.idx() % 3 == 0; };
310 auto to_id = [](VH vh) {
return vh.idx(); };
312 auto even_vertices = mesh_.vertices().filtered(is_even).to_vector(to_id);
313 EXPECT_EQ(even_vertices.size(), 4u);
314 EXPECT_EQ(even_vertices[0], 0);
315 EXPECT_EQ(even_vertices[1], 2);
316 EXPECT_EQ(even_vertices[2], 4);
317 EXPECT_EQ(even_vertices[3], 6);
319 auto odd_vertices = mesh_.vertices().filtered(is_odd).to_vector(to_id);
320 EXPECT_EQ(odd_vertices.size(), 4u);
321 EXPECT_EQ(odd_vertices[0], 1);
322 EXPECT_EQ(odd_vertices[1], 3);
323 EXPECT_EQ(odd_vertices[2], 5);
324 EXPECT_EQ(odd_vertices[3], 7);
326 auto even_3_vertices = mesh_.vertices().filtered(is_even).filtered(is_divisible_by_3).to_vector(to_id);
327 EXPECT_EQ(even_3_vertices.size(), 2u);
328 EXPECT_EQ(even_3_vertices[0], 0);
329 EXPECT_EQ(even_3_vertices[1], 6);
331 auto odd_3_vertices = mesh_.vertices().filtered(is_odd).filtered(is_divisible_by_3).to_vector(to_id);
332 EXPECT_EQ(odd_3_vertices.size(), 1u);
333 EXPECT_EQ(odd_3_vertices[0], 3);
337 std::vector<VH> vertices;
339 auto store_vertex = [&](VH vh) { to_be_processed(vh) =
false; vertices.push_back(vh); };
341 for (
auto fh : mesh_.faces())
342 fh.vertices().filtered(to_be_processed).for_each(store_vertex);
344 EXPECT_EQ(vertices.size(), mesh_.n_vertices()) <<
" number of visited vertices not correct";
345 EXPECT_TRUE(mesh_.vertices().all_of([&](VH vh) { return !to_be_processed(vh); })) <<
"did not visit all vertices";
349 size_t visited_faces_in_main_loop = 0;
350 size_t visited_faces_in_sub_loop = 0;
351 for (
auto fh : mesh_.faces().filtered(to_be_visited))
353 to_be_visited(fh) =
false;
354 ++visited_faces_in_main_loop;
355 for (
auto neighbor : fh.faces().filtered(to_be_visited))
357 to_be_visited(neighbor) =
false;
358 ++visited_faces_in_sub_loop;
362 EXPECT_LT(visited_faces_in_main_loop, mesh_.n_faces()) <<
"Visted more faces than expected";
363 EXPECT_TRUE(mesh_.faces().all_of([&](FH fh) { return !to_be_visited(fh); })) <<
"did not visit all faces";
364 EXPECT_EQ(visited_faces_in_main_loop + visited_faces_in_sub_loop, mesh_.n_faces()) <<
"Did not visited all faces exactly once";
369 const auto& to_be_visited_const_ref = to_be_visited;
370 size_t visited_faces_in_main_loop = 0;
371 size_t visited_faces_in_sub_loop = 0;
372 for (
auto fh : mesh_.faces().filtered(to_be_visited_const_ref))
374 to_be_visited(fh) =
false;
375 ++visited_faces_in_main_loop;
376 for (
auto neighbor : fh.faces().filtered(to_be_visited_const_ref))
378 to_be_visited(neighbor) =
false;
379 ++visited_faces_in_sub_loop;
383 EXPECT_LT(visited_faces_in_main_loop, mesh_.n_faces()) <<
"Visted more faces than expected";
384 EXPECT_TRUE(mesh_.faces().all_of([&](FH fh) { return !to_be_visited(fh); })) <<
"did not visit all faces";
385 EXPECT_EQ(visited_faces_in_main_loop + visited_faces_in_sub_loop, mesh_.n_faces()) <<
"Did not visited all faces exactly once";
392TEST_F(OpenMeshSmartRanges, Avg)
396 for (
auto vh : mesh_.vertices())
397 cog += mesh_.point(vh);
398 cog /= mesh_.n_vertices();
400 auto points = OpenMesh::getPointsProperty(mesh_);
401 auto cog2 = mesh_.vertices().avg(points);
403 EXPECT_LT(norm(cog - cog2), 0.00001) <<
"Computed center of gravities are significantly different.";
408TEST_F(OpenMeshSmartRanges, WeightedAvg)
411 for (
auto fh : mesh_.faces())
412 cog += mesh_.calc_face_centroid(fh);
413 cog /= mesh_.n_faces();
416 for (
auto fh : mesh_.faces())
417 area[fh] = mesh_.calc_face_area(fh);
421 EXPECT_LT(norm(cog - cog2), 0.00001) <<
"Computed area weighted center of gravities are significantly different.";
425template <
typename HandleT>
426void test_range_predicates(
Mesh& _mesh)
428 using namespace OpenMesh::Predicates;
430 auto get_random_set = [&](
int n)
432 auto max = _mesh.n_elements<HandleT>();
433 std::vector<HandleT> set;
434 set.push_back(HandleT(0));
435 for (
int i = 0; i < n; ++i)
436 set.push_back(HandleT(rand() % max));
437 std::sort(set.begin(), set.end());
438 set.erase(std::unique(set.begin(), set.end()), set.end());
444 for (
auto el : _mesh.elements<HandleT>())
445 _mesh.status(el).set_feature(false);
446 auto set = get_random_set(4);
448 _mesh.status(el).set_feature(true);
450 auto set2 = _mesh.elements<HandleT>().filtered(
Feature()).to_vector();
452 EXPECT_EQ(set.size(), set2.size()) <<
"Set sizes differ";
453 for (
size_t i = 0; i < std::min(set.size(), set2.size()); ++i)
454 EXPECT_EQ(set[i], set2[i]) <<
"Sets differ at position " << i;
456 for (
auto el : _mesh.elements<HandleT>())
457 _mesh.status(el).set_feature(false);
462 for (
auto el : _mesh.elements<HandleT>())
463 _mesh.status(el).set_selected(false);
464 auto set = get_random_set(4);
466 _mesh.status(el).set_selected(true);
468 auto set2 = _mesh.elements<HandleT>().filtered(
Selected()).to_vector();
470 EXPECT_EQ(set.size(), set2.size()) <<
"Set sizes differ";
471 for (
size_t i = 0; i < std::min(set.size(), set2.size()); ++i)
472 EXPECT_EQ(set[i], set2[i]) <<
"Sets differ at position " << i;
474 for (
auto el : _mesh.elements<HandleT>())
475 _mesh.status(el).set_selected(false);
480 for (
auto el : _mesh.elements<HandleT>())
481 _mesh.status(el).set_tagged(false);
482 auto set = get_random_set(4);
484 _mesh.status(el).set_tagged(true);
486 auto set2 = _mesh.elements<HandleT>().filtered(
Tagged()).to_vector();
488 EXPECT_EQ(set.size(), set2.size()) <<
"Set sizes differ";
489 for (
size_t i = 0; i < std::min(set.size(), set2.size()); ++i)
490 EXPECT_EQ(set[i], set2[i]) <<
"Sets differ at position " << i;
492 for (
auto el : _mesh.elements<HandleT>())
493 _mesh.status(el).set_tagged(false);
498 for (
auto el : _mesh.elements<HandleT>())
499 _mesh.status(el).set_tagged2(false);
500 auto set = get_random_set(4);
502 _mesh.status(el).set_tagged2(true);
504 auto set2 = _mesh.elements<HandleT>().filtered(
Tagged2()).to_vector();
506 EXPECT_EQ(set.size(), set2.size()) <<
"Set sizes differ";
507 for (
size_t i = 0; i < std::min(set.size(), set2.size()); ++i)
508 EXPECT_EQ(set[i], set2[i]) <<
"Sets differ at position " << i;
510 for (
auto el : _mesh.elements<HandleT>())
511 _mesh.status(el).set_tagged2(false);
516 for (
auto el : _mesh.elements<HandleT>())
517 _mesh.status(el).set_locked(false);
518 auto set = get_random_set(4);
520 _mesh.status(el).set_locked(true);
522 auto set2 = _mesh.elements<HandleT>().filtered(
Locked()).to_vector();
524 EXPECT_EQ(set.size(), set2.size()) <<
"Set sizes differ";
525 for (
size_t i = 0; i < std::min(set.size(), set2.size()); ++i)
526 EXPECT_EQ(set[i], set2[i]) <<
"Sets differ at position " << i;
528 for (
auto el : _mesh.elements<HandleT>())
529 _mesh.status(el).set_locked(false);
534 for (
auto el : _mesh.all_elements<HandleT>())
535 _mesh.status(el).set_hidden(false);
536 auto set = get_random_set(4);
538 _mesh.status(el).set_hidden(true);
540 auto set2 = _mesh.all_elements<HandleT>().filtered(
Hidden()).to_vector();
542 EXPECT_EQ(set.size(), set2.size()) <<
"Set sizes differ";
543 for (
size_t i = 0; i < std::min(set.size(), set2.size()); ++i)
544 EXPECT_EQ(set[i], set2[i]) <<
"Sets differ at position " << i;
546 for (
auto el : _mesh.all_elements<HandleT>())
547 _mesh.status(el).set_hidden(false);
552 for (
auto el : _mesh.all_elements<HandleT>())
553 _mesh.status(el).set_deleted(false);
554 auto set = get_random_set(4);
556 _mesh.status(el).set_deleted(true);
558 auto set2 = _mesh.all_elements<HandleT>().filtered(
Deleted()).to_vector();
560 EXPECT_EQ(set.size(), set2.size()) <<
"Set sizes differ";
561 for (
size_t i = 0; i < std::min(set.size(), set2.size()); ++i)
562 EXPECT_EQ(set[i], set2[i]) <<
"Sets differ at position " << i;
564 for (
auto el : _mesh.all_elements<HandleT>())
565 _mesh.status(el).set_deleted(false);
571 auto set = get_random_set(4);
575 auto set2 = _mesh.elements<HandleT>().filtered(prop).to_vector();
577 EXPECT_EQ(set.size(), set2.size()) <<
"Set sizes differ";
578 for (
size_t i = 0; i < std::min(set.size(), set2.size()); ++i)
579 EXPECT_EQ(set[i], set2[i]) <<
"Sets differ at position " << i;
584 for (
auto el : _mesh.elements<HandleT>().filtered(
Boundary()))
585 EXPECT_TRUE(el.is_boundary());
586 int n_boundary1 = 0.0;
587 for (
auto el : _mesh.elements<HandleT>())
588 if (el.is_boundary())
590 int n_boundary2 = _mesh.elements<HandleT>().count_if(
Boundary());
591 EXPECT_EQ(n_boundary1, n_boundary2);
595template <
typename HandleT>
596void test_range_predicate_combinations(
Mesh& _mesh)
598 using namespace OpenMesh::Predicates;
600 auto n_elements = _mesh.n_elements<HandleT>();
601 auto get_random_set = [&](
int n)
603 std::vector<HandleT> set;
604 for (
int i = 0; i < n; ++i)
605 set.push_back(HandleT(rand() % n_elements));
606 std::sort(set.begin(), set.end());
607 set.erase(std::unique(set.begin(), set.end()), set.end());
613 auto set = get_random_set(4);
614 for (
auto el : _mesh.elements<HandleT>())
615 _mesh.status(el).set_selected(false);
617 _mesh.status(el).set_selected(true);
619 auto true_set = _mesh.elements<HandleT>().filtered(
Selected()).to_vector();
620 auto false_set = _mesh.elements<HandleT>().filtered(!
Selected()).to_vector();
622 std::vector<HandleT> intersection;
623 std::set_intersection(true_set.begin(), true_set.end(), false_set.begin(), false_set.end(), std::back_inserter(intersection));
625 EXPECT_TRUE(intersection.empty());
626 EXPECT_EQ(true_set.size() + false_set.size(), n_elements);
628 for (
auto el : _mesh.elements<HandleT>())
629 _mesh.status(el).set_selected(false);
634 auto set1 = get_random_set(4);
635 auto set2 = get_random_set(4);
638 auto set3 = get_random_set(3);
639 set1.insert(set1.end(), set3.begin(), set3.end());
640 set2.insert(set2.end(), set3.begin(), set3.end());
641 std::sort(set1.begin(), set1.end());
642 std::sort(set2.begin(), set2.end());
643 set1.erase(std::unique(set1.begin(), set1.end()), set1.end());
644 set2.erase(std::unique(set2.begin(), set2.end()), set2.end());
647 for (
auto el : _mesh.elements<HandleT>())
648 _mesh.status(el).set_selected(false);
649 for (
auto el : _mesh.elements<HandleT>())
650 _mesh.status(el).set_tagged(false);
652 _mesh.status(el).set_selected(true);
654 _mesh.status(el).set_tagged(true);
656 auto set = _mesh.elements<HandleT>().filtered(
Selected() &&
Tagged()).to_vector();
658 std::vector<HandleT> intersection;
659 std::set_intersection(set1.begin(), set1.end(), set2.begin(), set2.end(), std::back_inserter(intersection));
661 EXPECT_EQ(intersection.size(), set.size());
662 for (
size_t i = 0; i < std::min(intersection.size(), set.size()); ++i)
663 EXPECT_EQ(intersection[i], set[i]) <<
"Sets differ at position " << i;
665 for (
auto el : _mesh.elements<HandleT>())
666 _mesh.status(el).set_selected(false);
667 for (
auto el : _mesh.elements<HandleT>())
668 _mesh.status(el).set_tagged(false);
673 auto set1 = get_random_set(4);
674 auto set2 = get_random_set(4);
675 for (
auto el : _mesh.elements<HandleT>())
676 _mesh.status(el).set_selected(false);
677 for (
auto el : _mesh.elements<HandleT>())
678 _mesh.status(el).set_tagged(false);
680 _mesh.status(el).set_selected(true);
682 _mesh.status(el).set_tagged(true);
684 auto set = _mesh.elements<HandleT>().filtered(
Selected() ||
Tagged()).to_vector();
686 std::vector<HandleT> union_set;
687 std::set_union(set1.begin(), set1.end(), set2.begin(), set2.end(), std::back_inserter(union_set));
689 EXPECT_EQ(union_set.size(), set.size());
690 for (
size_t i = 0; i < std::min(union_set.size(), set.size()); ++i)
691 EXPECT_EQ(union_set[i], set[i]) <<
"Sets differ at position " << i;
693 for (
auto el : _mesh.elements<HandleT>())
694 _mesh.status(el).set_selected(false);
695 for (
auto el : _mesh.elements<HandleT>())
696 _mesh.status(el).set_tagged(false);
701template <
typename HandleT>
702bool test_func(HandleT _h)
704 return _h.idx() % 3 == 0;
707template <
typename HandleT>
708void test_make_predicate(
Mesh& _mesh)
710 using namespace OpenMesh::Predicates;
712 auto n_elements = _mesh.n_elements<HandleT>();
713 auto get_random_set = [&](
int n)
715 std::vector<HandleT> set;
716 for (
int i = 0; i < n; ++i)
717 set.push_back(HandleT(rand() % n_elements));
718 std::sort(set.begin(), set.end());
719 set.erase(std::unique(set.begin(), set.end()), set.end());
726 auto set1 = get_random_set(4);
727 auto set2 = get_random_set(4);
730 for (
auto el : _mesh.elements<HandleT>())
731 _mesh.status(el).set_selected(false);
733 _mesh.status(el).set_selected(true);
735 auto set = _mesh.elements<HandleT>().filtered(
Selected() || make_predicate(prop)).to_vector();
737 std::vector<HandleT> union_set;
738 std::set_union(set1.begin(), set1.end(), set2.begin(), set2.end(), std::back_inserter(union_set));
740 EXPECT_EQ(union_set.size(), set.size());
741 for (
size_t i = 0; i < std::min(union_set.size(), set.size()); ++i)
742 EXPECT_EQ(union_set[i], set[i]) <<
"Sets differ at position " << i;
744 for (
auto el : _mesh.elements<HandleT>())
745 _mesh.status(el).set_selected(false);
746 for (
auto el : _mesh.elements<HandleT>())
747 _mesh.status(el).set_tagged(false);
753 auto set1 = get_random_set(4);
754 auto set2 = get_random_set(4);
757 for (
auto el : _mesh.elements<HandleT>())
758 _mesh.status(el).set_selected(false);
760 _mesh.status(el).set_selected(true);
762 auto test = [&](HandleT h) {
return prop(h); };
764 auto set = _mesh.elements<HandleT>().filtered(
Selected() || make_predicate(
test)).to_vector();
766 std::vector<HandleT> union_set;
767 std::set_union(set1.begin(), set1.end(), set2.begin(), set2.end(), std::back_inserter(union_set));
769 EXPECT_EQ(union_set.size(), set.size());
770 for (
size_t i = 0; i < std::min(union_set.size(), set.size()); ++i)
771 EXPECT_EQ(union_set[i], set[i]) <<
"Sets differ at position " << i;
773 for (
auto el : _mesh.elements<HandleT>())
774 _mesh.status(el).set_selected(false);
775 for (
auto el : _mesh.elements<HandleT>())
776 _mesh.status(el).set_tagged(false);
782 auto set1 = get_random_set(4);
783 auto set2 = get_random_set(4);
786 for (
auto el : _mesh.elements<HandleT>())
787 _mesh.status(el).set_selected(false);
789 _mesh.status(el).set_selected(true);
791 auto set = _mesh.elements<HandleT>().filtered(
Selected() || make_predicate([&](HandleT h) {
return prop(h); })).to_vector();
793 std::vector<HandleT> union_set;
794 std::set_union(set1.begin(), set1.end(), set2.begin(), set2.end(), std::back_inserter(union_set));
796 EXPECT_EQ(union_set.size(), set.size());
797 for (
size_t i = 0; i < std::min(union_set.size(), set.size()); ++i)
798 EXPECT_EQ(union_set[i], set[i]) <<
"Sets differ at position " << i;
800 for (
auto el : _mesh.elements<HandleT>())
801 _mesh.status(el).set_selected(false);
802 for (
auto el : _mesh.elements<HandleT>())
803 _mesh.status(el).set_tagged(false);
808 auto set1 = _mesh.elements<HandleT>().filtered([&](
const HandleT& h) {
return test_func(h); }).to_vector();
809 auto set2 = get_random_set(4);
810 for (
auto el : _mesh.elements<HandleT>())
811 _mesh.status(el).set_selected(false);
813 _mesh.status(el).set_selected(true);
815 auto set = _mesh.elements<HandleT>().filtered(
Selected() || make_predicate(test_func<HandleT>)).to_vector();
817 std::vector<HandleT> union_set;
818 std::set_union(set1.begin(), set1.end(), set2.begin(), set2.end(), std::back_inserter(union_set));
820 EXPECT_EQ(union_set.size(), set.size());
821 for (
size_t i = 0; i < std::min(union_set.size(), set.size()); ++i)
822 EXPECT_EQ(union_set[i], set[i]) <<
"Sets differ at position " << i;
824 for (
auto el : _mesh.elements<HandleT>())
825 _mesh.status(el).set_selected(false);
826 for (
auto el : _mesh.elements<HandleT>())
827 _mesh.status(el).set_tagged(false);
835 mesh_.request_vertex_status();
836 mesh_.request_halfedge_status();
837 mesh_.request_edge_status();
838 mesh_.request_face_status();
840 mesh_.delete_face(FaceHandle(0));
841 mesh_.garbage_collection();
843 test_range_predicates<VertexHandle>(mesh_);
844 test_range_predicates<HalfedgeHandle>(mesh_);
845 test_range_predicates<EdgeHandle>(mesh_);
846 test_range_predicates<FaceHandle>(mesh_);
848 test_range_predicate_combinations<VertexHandle>(mesh_);
849 test_range_predicate_combinations<HalfedgeHandle>(mesh_);
850 test_range_predicate_combinations<EdgeHandle>(mesh_);
851 test_range_predicate_combinations<FaceHandle>(mesh_);
853 test_make_predicate<VertexHandle>(mesh_);
854 test_make_predicate<HalfedgeHandle>(mesh_);
855 test_make_predicate<EdgeHandle>(mesh_);
856 test_make_predicate<FaceHandle>(mesh_);
859struct MemberFunctionWrapperTestStruct
861 MemberFunctionWrapperTestStruct(
int _i)
874 return _eh.
idx() % 2 == 0;
879 return vh.
edges().
sum(OM_MFW(get_i));
885TEST_F(OpenMeshSmartRanges, MemberFunctionFunctor)
887 using namespace OpenMesh::Predicates;
889 EXPECT_TRUE(mesh_.n_vertices() > 0) <<
"Mesh has no vertices";
890 EXPECT_TRUE(mesh_.n_edges() > 0) <<
"Mesh has no edges";
893 MemberFunctionWrapperTestStruct test_object(factor);
896 EXPECT_EQ(
static_cast<int>(mesh_.n_edges() / 2), mesh_.edges().count_if(make_member_function_wrapper(test_object, &MemberFunctionWrapperTestStruct::id_divisible_by_2)));
900 for (
auto vh : mesh_.vertices())
901 EXPECT_EQ(test_object.valence_times_i(vh), static_cast<int>(vh.valence()) * factor);
904 test_object.i_ = factor;
905 for (
auto vh : mesh_.vertices())
907 EXPECT_EQ(test_object.valence_times_i(vh),
static_cast<int>(vh.
valence() * factor));
int idx() const
Get the underlying index of this handle.
void calc_face_centroid(FaceHandle _fh, Point &_pt) const
calculates the average of the vertices defining _fh
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
SmartVertexHandle add_vertex(const Point _p)
Kernel::Point Point
Coordinate type.
Scalar min() const
return the minimal component
Handle for a face entity.
auto sum(Functor &&f) -> typename std::decay< decltype(f(std::declval< HandleT >()))>::type
Computes the sum of elements.
Smart version of VertexHandle contains a pointer to the corresponding mesh and allows easier access t...
uint valence() const
Returns valence of the vertex.
PolyConnectivity::ConstVertexEdgeRange edges() const
Returns a range of edges incident to the vertex (PolyConnectivity::ve_range())
Handle for a vertex entity.