Developer Documentation

unittests_trimesh_circulator_face_vertex.cc
1 #include <gtest/gtest.h>
2 #include <Unittests/unittests_common.hh>
3
4 #include <iostream>
5
6 namespace {
7
8 class OpenMeshTrimeshCirculatorFaceVertex : public OpenMeshBase {
9
10 protected:
11
12 // This function is called before each test is run
13 virtual void SetUp() {
14 }
15
16 // This function is called after all tests are through
17 virtual void TearDown() {
18
19 // Do some final stuff with the member data here...
20 }
21
22
23 // Member already defined in OpenMeshBase
24 //Mesh mesh_;
25 };
26
27 /*
28 * ====================================================================
29 * Define tests below
30 * ====================================================================
31 */
32
33
34
35 /*
36 * Small FaceVertexIterator Test
37 */
38 TEST_F(OpenMeshTrimeshCirculatorFaceVertex, FaceVertexIterWithoutIncrement) {
39
40 mesh_.clear();
41
42 // Add some vertices
43 Mesh::VertexHandle vhandle[5];
44
45 vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
46 vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
47 vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
48 vhandle[3] = mesh_.add_vertex(Mesh::Point(0,-1, 0));
49 vhandle[4] = mesh_.add_vertex(Mesh::Point(2,-1, 0));
50
51 // Add two faces
52 std::vector<Mesh::VertexHandle> face_vhandles;
53
54 face_vhandles.push_back(vhandle[0]);
55 face_vhandles.push_back(vhandle[1]);
56 face_vhandles.push_back(vhandle[2]);
57 Mesh::FaceHandle fh0 = mesh_.add_face(face_vhandles);
58
59 face_vhandles.clear();
60
61 face_vhandles.push_back(vhandle[1]);
62 face_vhandles.push_back(vhandle[3]);
63 face_vhandles.push_back(vhandle[4]);
64 mesh_.add_face(face_vhandles);
65
66 face_vhandles.clear();
67
68 face_vhandles.push_back(vhandle[0]);
69 face_vhandles.push_back(vhandle[3]);
70 face_vhandles.push_back(vhandle[1]);
71 mesh_.add_face(face_vhandles);
72
73 face_vhandles.clear();
74
75 face_vhandles.push_back(vhandle[2]);
76 face_vhandles.push_back(vhandle[1]);
77 face_vhandles.push_back(vhandle[4]);
78 mesh_.add_face(face_vhandles);
79
80 /* Test setup:
81 0 ==== 2
82 |\ 0 /|
83 | \ / |
84 |2 1 3|
85 | / \ |
86 |/ 1 \|
87 3 ==== 4 */
88
89
90 // Check face handle index
91 EXPECT_EQ(0, fh0.idx() ) << "Index wrong in FaceVertexIter at initialization";
92
93 // Iterate around vertex 1 at the middle (with holes in between)
94 Mesh::FaceVertexIter fv_it = mesh_.fv_begin(fh0);
95 Mesh::FaceVertexIter fv_end = mesh_.fv_end(fh0);
96 EXPECT_EQ(0, fv_it->idx() ) << "Index wrong in FaceVertexIter at initialization";
97 EXPECT_TRUE(fv_it.is_valid()) << "Iterator invalid in FaceVertexIter at initialization";
98 ++fv_it ;
99 EXPECT_EQ(1, fv_it->idx() ) << "Index wrong in FaceVertexIter at step 1";
100 EXPECT_TRUE(fv_it.is_valid()) << "Iterator invalid in FaceVertexIter at step 1";
101 ++fv_it ;
102 EXPECT_EQ(2, fv_it->idx() ) << "Index wrong in FaceVertexIter at step 2";
103 EXPECT_TRUE(fv_it.is_valid()) << "Iterator invalid in FaceVertexIter at step 2";
104 ++fv_it ;
105 EXPECT_EQ(0, fv_it->idx() ) << "Index wrong in FaceVertexIter at step 3";
106 EXPECT_FALSE(fv_it.is_valid()) << "Iterator invalid in FaceVertexIter at step 3";
107 EXPECT_TRUE( fv_it == fv_end ) << "End iterator for FaceVertexIter not matching";
108
109 // Iterate around vertex 1 at the middle (with holes in between) with const iterator
110 Mesh::ConstFaceVertexIter cfv_it = mesh_.cfv_begin(fh0);
111 Mesh::ConstFaceVertexIter cfv_end = mesh_.cfv_end(fh0);
112 EXPECT_EQ(0, cfv_it->idx() ) << "Index wrong in ConstFaceVertexIter at initialization";
113 EXPECT_TRUE(cfv_it.is_valid()) << "Iterator invalid in ConstFaceVertexIter at initialization";
114 ++cfv_it ;
115 EXPECT_EQ(1, cfv_it->idx() ) << "Index wrong in ConstFaceVertexIter at step 1";
116 EXPECT_TRUE(cfv_it.is_valid()) << "Iterator invalid in ConstFaceVertexIter at step 1";
117 ++cfv_it ;
118 EXPECT_EQ(2, cfv_it->idx() ) << "Index wrong in ConstFaceVertexIter at step 2";
119 EXPECT_TRUE(cfv_it.is_valid()) << "Iterator invalid in ConstFaceVertexIter at step 2";
120 ++cfv_it ;
121 EXPECT_EQ(0, cfv_it->idx() ) << "Index wrong in ConstFaceVertexIter at step 3";
122 EXPECT_FALSE(cfv_it.is_valid()) << "Iterator invalid in ConstFaceVertexIter at step 3";
123 EXPECT_TRUE( cfv_it == cfv_end ) << "End iterator for ConstFaceVertexIter not matching";
124 }
125
126
127 /*
128 * Test if the end iterator stays invalid after one lap
129 */
130 //TEST_F(OpenMeshTrimeshCirculatorFaceVertex, FaceVertexIterCheckInvalidationAtEnds) {
131 //
132 // mesh_.clear();
133 //
134 // // Add some vertices
135 // Mesh::VertexHandle vhandle[5];
136 //
137 // vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
138 // vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
139 // vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
140 // vhandle[3] = mesh_.add_vertex(Mesh::Point(0,-1, 0));
141 // vhandle[4] = mesh_.add_vertex(Mesh::Point(2,-1, 0));
142 //
143 // // Add two faces
144 // std::vector<Mesh::VertexHandle> face_vhandles;
145 //
146 // face_vhandles.push_back(vhandle[0]);
147 // face_vhandles.push_back(vhandle[1]);
148 // face_vhandles.push_back(vhandle[2]);
149 // Mesh::FaceHandle fh0 = mesh_.add_face(face_vhandles);
150 //
151 // face_vhandles.clear();
152 //
153 // face_vhandles.push_back(vhandle[1]);
154 // face_vhandles.push_back(vhandle[3]);
155 // face_vhandles.push_back(vhandle[4]);
156 // mesh_.add_face(face_vhandles);
157 //
158 // face_vhandles.clear();
159 //
160 // face_vhandles.push_back(vhandle[0]);
161 // face_vhandles.push_back(vhandle[3]);
162 // face_vhandles.push_back(vhandle[1]);
163 // mesh_.add_face(face_vhandles);
164 //
165 // face_vhandles.clear();
166 //
167 // face_vhandles.push_back(vhandle[2]);
168 // face_vhandles.push_back(vhandle[1]);
169 // face_vhandles.push_back(vhandle[4]);
170 // mesh_.add_face(face_vhandles);
171 //
172 // /* Test setup:
173 // 0 ==== 2
174 // |\ 0 /|
175 // | \ / |
176 // |2 1 3|
177 // | / \ |
178 // |/ 1 \|
179 // 3 ==== 4 */
180 //
181 //
182 // // Check if the end iterator stays invalid after end
183 // Mesh::FaceVertexIter endIter = mesh_.fv_end(fh0);
184 // EXPECT_FALSE(endIter.is_valid()) << "EndIter is not invalid";
185 // ++endIter ;
186 // EXPECT_FALSE(endIter.is_valid()) << "EndIter is not invalid after increment";
187 //
188 // // Check if the end iterators becomes valid after decrement
189 // endIter = mesh_.fv_end(fh0);
190 // EXPECT_FALSE(endIter.is_valid()) << "EndIter is not invalid";
191 // --endIter;
192 // EXPECT_TRUE(endIter.is_valid()) << "EndIter is invalid after decrement";
193 // EXPECT_EQ(2,endIter->idx()) << "EndIter points on the wrong element";
194 //
195 //
196 // // Check if the start iterator decrement is invalid
197 // Mesh::FaceVertexIter startIter = mesh_.fv_begin(fh0);
198 // EXPECT_TRUE(startIter.is_valid()) << "StartIter is not valid";
199 // --startIter;
200 // EXPECT_FALSE(startIter.is_valid()) << "StartIter decrement is not invalid";
201 //
202 // // Check if the start iterator becomes valid
203 // ++startIter;
204 // EXPECT_TRUE(startIter.is_valid()) << "StartIter is invalid after re-incrementing";
205 // EXPECT_EQ(startIter->idx(), mesh_.fv_begin(fh0)->idx()) << "StartIter points on the wrong element";
206 //
207 //}
208
209 /*
210 * Test CW and CCW iterators
211 */
212 TEST_F(OpenMeshTrimeshCirculatorFaceVertex, CWAndCCWCheck) {
213
214 mesh_.clear();
215
216 // Add some vertices
217 Mesh::VertexHandle vhandle[5];
218
219 vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
220 vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
221 vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
222 vhandle[3] = mesh_.add_vertex(Mesh::Point(0,-1, 0));
223 vhandle[4] = mesh_.add_vertex(Mesh::Point(2,-1, 0));
224
225 // Add two faces
226 std::vector<Mesh::VertexHandle> face_vhandles;
227
228 face_vhandles.push_back(vhandle[0]);
229 face_vhandles.push_back(vhandle[1]);
230 face_vhandles.push_back(vhandle[2]);
231 Mesh::FaceHandle fh0 = mesh_.add_face(face_vhandles);
232
233 face_vhandles.clear();
234
235 face_vhandles.push_back(vhandle[1]);
236 face_vhandles.push_back(vhandle[3]);
237 face_vhandles.push_back(vhandle[4]);
238 mesh_.add_face(face_vhandles);
239
240 face_vhandles.clear();
241
242 face_vhandles.push_back(vhandle[0]);
243 face_vhandles.push_back(vhandle[3]);
244 face_vhandles.push_back(vhandle[1]);
245 mesh_.add_face(face_vhandles);
246
247 face_vhandles.clear();
248
249 face_vhandles.push_back(vhandle[2]);
250 face_vhandles.push_back(vhandle[1]);
251 face_vhandles.push_back(vhandle[4]);
252 mesh_.add_face(face_vhandles);
253
254 /* Test setup:
255 0 ==== 2
256 |\ 0 /|
257 | \ / |
258 |2 1 3|
259 | / \ |
260 |/ 1 \|
261 3 ==== 4 */
262
263
264 int indices[4] = {0, 1, 2, 0};
265 int rev_indices[4];
266 std::reverse_copy(indices,indices+4,rev_indices);
267
268 //CCW
269 Mesh::FaceVertexCCWIter fv_ccwit = mesh_.fv_ccwbegin(fh0);
270 Mesh::FaceVertexCCWIter fv_ccwend = mesh_.fv_ccwend(fh0);
271 size_t i = 0;
272 for (;fv_ccwit != fv_ccwend; ++fv_ccwit, ++i)
273 {
274 EXPECT_EQ(indices[i], fv_ccwit->idx()) << "Index wrong in FaceVertexCCWIter";
275 }
276
277 EXPECT_FALSE(fv_ccwit.is_valid()) << "Iterator invalid in FaceVertexCCWIter at end";
278 EXPECT_TRUE( fv_ccwit == fv_ccwend ) << "End iterator for FaceVertexCCWIter not matching";
279
280 //constant CCW
281 Mesh::ConstFaceVertexCCWIter cfv_ccwit = mesh_.cfv_ccwbegin(fh0);
282 Mesh::ConstFaceVertexCCWIter cfv_ccwend = mesh_.cfv_ccwend(fh0);
283 i = 0;
284 for (;cfv_ccwit != cfv_ccwend; ++cfv_ccwit, ++i)
285 {
286 EXPECT_EQ(indices[i], cfv_ccwit->idx()) << "Index wrong in ConstFaceVertexCCWIter";
287 }
288
289 EXPECT_FALSE(cfv_ccwit.is_valid()) << "Iterator invalid in ConstFaceVertexCCWIter at end";
290 EXPECT_TRUE( cfv_ccwit == cfv_ccwend ) << "End iterator for ConstFaceVertexCCWIter not matching";
291
292 //CW
293 Mesh::FaceVertexCWIter fv_cwit = mesh_.fv_cwbegin(fh0);
294 Mesh::FaceVertexCWIter fv_cwend = mesh_.fv_cwend(fh0);
295 i = 0;
296 for (;fv_cwit != fv_cwend; ++fv_cwit, ++i)
297 {
298 EXPECT_EQ(rev_indices[i], fv_cwit->idx()) << "Index wrong in FaceVertexCWIter";
299 }
300 EXPECT_FALSE(fv_cwit.is_valid()) << "Iterator invalid in FaceVertexCWIter at end";
301 EXPECT_TRUE( fv_cwit == fv_cwend ) << "End iterator for FaceVertexCWIter not matching";
302
303 //constant CW
304 Mesh::ConstFaceVertexCWIter cfv_cwit = mesh_.cfv_cwbegin(fh0);
305 Mesh::ConstFaceVertexCWIter cfv_cwend = mesh_.cfv_cwend(fh0);
306 i = 0;
307 for (;cfv_cwit != cfv_cwend; ++cfv_cwit, ++i)
308 {
309 EXPECT_EQ(rev_indices[i], cfv_cwit->idx()) << "Index wrong in ConstFaceVertexCWIter";
310 }
311 EXPECT_FALSE(cfv_cwit.is_valid()) << "Iterator invalid in ConstFaceVertexCWIter at end";
312 EXPECT_TRUE( cfv_cwit == cfv_cwend ) << "End iterator for ConstFaceVertexCWIter not matching";
313
314 /*
315 * conversion properties:
316 * a) cw_begin == CWIter(ccw_begin())
317 * b) cw_iter->idx() == CCWIter(cw_iter)->idx() for valid iterators
318 * c) --cw_iter == CWIter(++ccwIter) for valid iterators
319 * d) cw_end == CWIter(ccw_end()) => --cw_end != CWIter(++ccw_end()) *
320 */
321 Mesh::FaceVertexCWIter fv_cwIter = mesh_.fv_cwbegin(mesh_.face_handle(1));
322 // a)
323 EXPECT_TRUE( fv_cwIter == Mesh::FaceVertexCWIter(mesh_.fv_ccwbegin(mesh_.face_handle(1))) ) << "ccw to cw conversion failed";
324 EXPECT_TRUE( Mesh::FaceVertexCCWIter(fv_cwIter) == mesh_.fv_ccwbegin(mesh_.face_handle(1)) ) << "cw to ccw conversion failed";
325 // b)
326 EXPECT_EQ( fv_cwIter->idx(), Mesh::FaceVertexCCWIter(fv_cwIter)->idx()) << "iterators doesnt point on the same element";
327 // c)
328 ++fv_cwIter;
329 fv_ccwend = mesh_.fv_ccwend(mesh_.face_handle(1));
330 --fv_ccwend;
331 EXPECT_EQ(fv_cwIter->idx(),fv_ccwend->idx()) << "iteratoes are not equal after inc/dec";
332 // additional conversion check
333 fv_ccwend = Mesh::FaceVertexCCWIter(fv_cwIter);
334 EXPECT_EQ(fv_cwIter->idx(),fv_ccwend->idx())<< "iterators doesnt point on the same element";
335 // d)
336 fv_cwIter = Mesh::FaceVertexCWIter(mesh_.fv_ccwend(mesh_.face_handle(1)));
337 EXPECT_FALSE(fv_cwIter.is_valid()) << "end iterator is not invalid";
338 EXPECT_TRUE(Mesh::FaceVertexCCWIter(mesh_.fv_cwend(mesh_.face_handle(1))) == mesh_.fv_ccwend(mesh_.face_handle(1))) << "end iterators are not equal";
339
340
341 }
342
343
344 }
OpenMesh::PolyMeshT::ConstFaceVertexIter
Kernel::ConstFaceVertexIter ConstFaceVertexIter
Circulator.
Definition: PolyMeshT.hh:177
OpenMesh::PolyMeshT::FaceVertexIter
Kernel::FaceVertexIter FaceVertexIter
Circulator.
Definition: PolyMeshT.hh:167
OpenMesh::PolyMeshT::Point
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:112
OpenMesh::PolyMeshT::add_vertex
SmartVertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
Definition: PolyMeshT.hh:235
OpenMeshBase
Definition: unittests_common.hh:29
OpenMesh::PolyMeshT::VertexHandle
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:136