Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
unittests_propertymanager.cc
1 #include <gtest/gtest.h>
2 #include <Unittests/unittests_common.hh>
3 #include <OpenMesh/Core/Utils/PropertyManager.hh>
4
5 #include <iostream>
6
7 namespace {
8
9 class OpenMeshPropertyManager : public OpenMeshBase {
10
11 protected:
12
13 // This function is called before each test is run
14 virtual void SetUp() {
15 }
16
17 // This function is called after all tests are through
18 virtual void TearDown() {
19
20 // Do some final stuff with the member data here...
21 }
22
23 // Member already defined in OpenMeshBase
24 //Mesh mesh_;
25 };
26
27 /*
28 * ====================================================================
29 * General Tests
30 * ====================================================================
31 */
32
33 /*
34 * Collapsing a tetrahedron
35 */
36 TEST_F(OpenMeshPropertyManager, set_range_bool) {
37
38 mesh_.clear();
39
40 // Add some vertices
41 Mesh::VertexHandle vhandle[4];
42
43 vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
44 vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
45 vhandle[2] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
46 vhandle[3] = mesh_.add_vertex(Mesh::Point(0, 0, 1));
47
48 // Add two faces
49 std::vector<Mesh::VertexHandle> face_vhandles;
50
51 face_vhandles.push_back(vhandle[0]);
52 face_vhandles.push_back(vhandle[1]);
53 face_vhandles.push_back(vhandle[2]);
54 mesh_.add_face(face_vhandles);
55
56 face_vhandles.clear();
57
58 face_vhandles.push_back(vhandle[0]);
59 face_vhandles.push_back(vhandle[2]);
60 face_vhandles.push_back(vhandle[3]);
61 mesh_.add_face(face_vhandles);
62
63 OpenMesh::PropertyManager<
64 OpenMesh::VPropHandleT<bool>, Mesh> pm_v_bool(mesh_, "pm_v_bool");
65 pm_v_bool.set_range(mesh_.vertices_begin(), mesh_.vertices_end(), false);
66 for (int i = 0; i < 4; ++i)
67 ASSERT_FALSE(pm_v_bool[vhandle[i]]);
68 pm_v_bool.set_range(mesh_.vertices_begin(), mesh_.vertices_end(), true);
69 for (int i = 0; i < 4; ++i)
70 ASSERT_TRUE(pm_v_bool[vhandle[i]]);
71
72 OpenMesh::PropertyManager<
73 OpenMesh::EPropHandleT<bool>, Mesh> pm_e_bool(mesh_, "pm_e_bool");
74 pm_e_bool.set_range(mesh_.edges_begin(), mesh_.edges_end(), false);
75 for (Mesh::EdgeIter e_it = mesh_.edges_begin(), f_end = mesh_.edges_end();
76 e_it != f_end; ++e_it)
77 ASSERT_FALSE(pm_e_bool[*e_it]);
78 pm_e_bool.set_range(mesh_.edges_begin(), mesh_.edges_end(), true);
79 for (Mesh::EdgeIter e_it = mesh_.edges_begin(), f_end = mesh_.edges_end();
80 e_it != f_end; ++e_it)
81 ASSERT_TRUE(pm_e_bool[*e_it]);
82
83 OpenMesh::PropertyManager<
84 OpenMesh::FPropHandleT<bool>, Mesh> pm_f_bool(mesh_, "pm_f_bool");
85 pm_f_bool.set_range(mesh_.faces_begin(), mesh_.faces_end(), false);
86 for (Mesh::FaceIter f_it = mesh_.faces_begin(), f_end = mesh_.faces_end();
87 f_it != f_end; ++f_it)
88 ASSERT_FALSE(pm_f_bool[*f_it]);
89 pm_f_bool.set_range(mesh_.faces_begin(), mesh_.faces_end(), true);
90 for (Mesh::FaceIter f_it = mesh_.faces_begin(), f_end = mesh_.faces_end();
91 f_it != f_end; ++f_it)
92 ASSERT_TRUE(pm_f_bool[*f_it]);
93 }
94
95 /*
96 * ====================================================================
97 * C++11 Specific Tests
98 * ====================================================================
99 */
100 #if _MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
101
102 template<typename PropHandle, typename Mesh>
103 bool has_property(const Mesh& _mesh, const std::string& _name) {
104 auto dummy_handle = PropHandle{};
105 return _mesh.get_property_handle(dummy_handle, _name);
106 }
107
108 /*
109 * Temporary property
110 */
111 TEST_F(OpenMeshPropertyManager, cpp11_temp_property) {
112 using handle_type = OpenMesh::VPropHandleT<int>;
113 const auto prop_name = "pm_v_test_property";
114 ASSERT_FALSE(has_property<handle_type>(mesh_, prop_name));
115
116 {
117 auto vprop = OpenMesh::makePropertyManagerFromNew<handle_type>(mesh_, prop_name);
118 static_cast<void>(vprop); // Unused variable
119 ASSERT_TRUE(has_property<handle_type>(mesh_, prop_name));
120 }
121
122 ASSERT_FALSE(has_property<handle_type>(mesh_, prop_name));
123 }
124
125 /*
126 * Two temporary properties on a mesh using the same name and type. The second
127 * (inner) one shadows the first (outer) one instead of aliasing.
128 */
129 TEST_F(OpenMeshPropertyManager, cpp11_temp_property_shadowing) {
130 auto vh = mesh_.add_vertex({0,0,0}); // Dummy vertex to attach properties to
131
132 using handle_type = OpenMesh::VPropHandleT<int>;
133 const auto prop_name = "pm_v_test_property";
134
135 auto outer_prop = OpenMesh::makePropertyManagerFromNew<handle_type>(mesh_, prop_name);
136 outer_prop[vh] = 100;
137 ASSERT_EQ(100, outer_prop[vh]);
138
139 {
140 // inner_prop uses same type and name as outer_prop
141 auto inner_prop = OpenMesh::makePropertyManagerFromNew<handle_type>(mesh_, prop_name);
142 inner_prop[vh] = 200;
143 ASSERT_EQ(200, inner_prop[vh]);
144 // End of scope: inner_prop is removed from mesh_
145 }
146
147 // Ensure outer_prop still exists and its data has not been overwritten by inner_prop
148 ASSERT_TRUE(has_property<handle_type>(mesh_, prop_name));
149 ASSERT_EQ(100, outer_prop[vh]);
150 }
151
152 /*
153 * In sequence:
154 * - add a persistent property to a mesh
155 * - retrieve an existing property of a mesh and modify it
156 * - obtain a non-owning property handle
157 * - attempt to obtain a non-owning handle to a non-existing property (throws)
158 */
159 TEST_F(OpenMeshPropertyManager, cpp11_persistent_and_non_owning_properties) {
160 auto vh = mesh_.add_vertex({0,0,0}); // Dummy vertex to attach properties to
161
162 using handle_type = OpenMesh::VPropHandleT<int>;
163 const auto prop_name = "pm_v_test_property";
164
165 ASSERT_FALSE(has_property<handle_type>(mesh_, prop_name));
166
167 {
168 auto prop = OpenMesh::makePropertyManagerFromExistingOrNew<handle_type>(mesh_, prop_name);
169 prop[vh] = 100;
170 // End of scope, property persists
171 }
172
173 ASSERT_TRUE(has_property<handle_type>(mesh_, prop_name));
174
175 {
176 // Since a property of the same name and type already exists, this refers to the existing property.
177 auto prop = OpenMesh::makePropertyManagerFromExistingOrNew<handle_type>(mesh_, prop_name);
178 ASSERT_EQ(100, prop[vh]);
179 prop[vh] = 200;
180 // End of scope, property persists
181 }
182
183 ASSERT_TRUE(has_property<handle_type>(mesh_, prop_name));
184
185 {
186 // Acquire non-owning handle to the property, knowing it exists
187 auto prop = OpenMesh::makePropertyManagerFromExisting<handle_type>(mesh_, prop_name);
188 ASSERT_EQ(200, prop[vh]);
189 }
190
191 ASSERT_TRUE(has_property<handle_type>(mesh_, prop_name));
192
193 {
194 // Attempt to acquire non-owning handle for a non-existing property
195 ASSERT_THROW(OpenMesh::makePropertyManagerFromExisting<handle_type>(mesh_, "wrong_property_name"), std::runtime_error);
196 }
197
198 ASSERT_TRUE(has_property<handle_type>(mesh_, prop_name));
199 }
200
201 #endif
202
203 }
OpenMeshBase
Definition: unittests_common.hh:21
OpenMesh::PolyMeshT::Point
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:115
OpenMesh::PolyMeshT::add_vertex
VertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
Definition: PolyMeshT.hh:236
OpenMesh::PropertyManager
Definition: PropertyManager.hh:94
OpenMesh::EPropHandleT
Definition: Property.hh:515
OpenMesh::TriMesh_ArrayKernelT
Definition: TriMesh_ArrayKernelT.hh:98
OpenMesh::VPropHandleT< bool >
OpenMesh::PolyMeshT::VertexHandle
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:139
OpenMesh::FPropHandleT< bool >