Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
unittests_trimesh_circulator_face_face.cc
1 #include <gtest/gtest.h>
2 #include <Unittests/unittests_common.hh>
3 
4 #include <iostream>
5 #include <algorithm>
6 
7 namespace {
8 
9 class OpenMeshTrimeshCirculatorFaceFace : 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 
24  // Member already defined in OpenMeshBase
25  //Mesh mesh_;
26 };
27 
28 /*
29  * ====================================================================
30  * Define tests below
31  * ====================================================================
32  */
33 
34 
35 
36 /*
37  * Small FaceFaceIterator Test with holes in it
38  */
39 TEST_F(OpenMeshTrimeshCirculatorFaceFace, FaceFaceIterWithHoles) {
40 
41  mesh_.clear();
42 
43  // Add some vertices
44  Mesh::VertexHandle vhandle[5];
45 
46  vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
47  vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
48  vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
49  vhandle[3] = mesh_.add_vertex(Mesh::Point(3, 0, 0));
50  vhandle[4] = mesh_.add_vertex(Mesh::Point(4, 1, 0));
51 
52  // Add three faces
53  std::vector<Mesh::VertexHandle> face_vhandles;
54 
55  face_vhandles.push_back(vhandle[0]);
56  face_vhandles.push_back(vhandle[1]);
57  face_vhandles.push_back(vhandle[2]);
58  mesh_.add_face(face_vhandles);
59 
60  face_vhandles.clear();
61 
62  face_vhandles.push_back(vhandle[2]);
63  face_vhandles.push_back(vhandle[1]);
64  face_vhandles.push_back(vhandle[3]);
65  mesh_.add_face(face_vhandles);
66 
67  face_vhandles.clear();
68 
69  face_vhandles.push_back(vhandle[2]);
70  face_vhandles.push_back(vhandle[3]);
71  face_vhandles.push_back(vhandle[4]);
72  mesh_.add_face(face_vhandles);
73 
74  /* Test setup:
75  *
76  * 0 ------ 2 ------ 4
77  * \ / \ /
78  * \ 0 / \ 2 /
79  * \ / 1 \ /
80  * 1 ------- 3
81  */
82 
83 
84  Mesh::FaceFaceIter ff_it = mesh_.ff_begin(mesh_.face_handle(1));
85  Mesh::FaceFaceIter ff_end = mesh_.ff_end(mesh_.face_handle(1));
86 
87  EXPECT_EQ(2, ff_it->idx() ) << "Index wrong in FaceFaceIter at initialization";
88  EXPECT_TRUE(ff_it.is_valid()) << "Iterator invalid in FaceFaceIter at initialization";
89  ++ff_it;
90  EXPECT_EQ(0, ff_it->idx() ) << "Index wrong in FaceFaceIter at step 1";
91  EXPECT_TRUE(ff_it.is_valid()) << "Iterator invalid in FaceFaceIter at step 1";
92  ++ff_it;
93  EXPECT_EQ(2, ff_it->idx() ) << "Index wrong in FaceFaceIter at end";
94  EXPECT_FALSE(ff_it.is_valid()) << "Iterator invalid in FaceFaceIter at end";
95  EXPECT_TRUE( ff_it == ff_end ) << "End iterator for FaceFaceIter not matching";
96 
97  Mesh::ConstFaceFaceIter cff_it = mesh_.cff_begin(mesh_.face_handle(1));
98  Mesh::ConstFaceFaceIter cff_end = mesh_.cff_end(mesh_.face_handle(1));
99 
100  EXPECT_EQ(2, cff_it->idx() ) << "Index wrong in ConstFaceFaceIter at initialization";
101  EXPECT_TRUE(cff_it.is_valid()) << "Iterator invalid in ConstFaceFaceIter at initialization";
102  ++cff_it;
103  EXPECT_EQ(0, cff_it->idx() ) << "Index wrong in ConstFaceFaceIter at step 1";
104  EXPECT_TRUE(cff_it.is_valid()) << "Iterator invalid in ConstFaceFaceIter at step 1";
105  ++cff_it;
106  EXPECT_EQ(2, cff_it->idx() ) << "Index wrong in ConstFaceFaceIter at end";
107  EXPECT_FALSE(cff_it.is_valid()) << "Iterator invalid in ConstFaceFaceIter at end";
108  EXPECT_TRUE( cff_it == cff_end ) << "End iterator for ConstFaceFaceIter not matching";
109 
110 }
111 
112 
113 
114 /*
115  * Small FaceFaceIterator Test with holes in it
116  */
117 TEST_F(OpenMeshTrimeshCirculatorFaceFace, FaceFaceIterWithoutHoles) {
118 
119  mesh_.clear();
120 
121  // Add some vertices
122  Mesh::VertexHandle vhandle[6];
123 
124  vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
125  vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
126  vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
127  vhandle[3] = mesh_.add_vertex(Mesh::Point(3, 0, 0));
128  vhandle[4] = mesh_.add_vertex(Mesh::Point(4, 1, 0));
129  vhandle[5] = mesh_.add_vertex(Mesh::Point(2,-1, 0));
130 
131  // Add three faces
132  std::vector<Mesh::VertexHandle> face_vhandles;
133 
134  face_vhandles.push_back(vhandle[0]);
135  face_vhandles.push_back(vhandle[1]);
136  face_vhandles.push_back(vhandle[2]);
137  mesh_.add_face(face_vhandles);
138 
139  face_vhandles.clear();
140 
141  face_vhandles.push_back(vhandle[2]);
142  face_vhandles.push_back(vhandle[1]);
143  face_vhandles.push_back(vhandle[3]);
144  mesh_.add_face(face_vhandles);
145 
146  face_vhandles.clear();
147 
148  face_vhandles.push_back(vhandle[2]);
149  face_vhandles.push_back(vhandle[3]);
150  face_vhandles.push_back(vhandle[4]);
151  mesh_.add_face(face_vhandles);
152 
153  face_vhandles.clear();
154 
155  face_vhandles.push_back(vhandle[1]);
156  face_vhandles.push_back(vhandle[5]);
157  face_vhandles.push_back(vhandle[3]);
158  mesh_.add_face(face_vhandles);
159 
160  /* Test setup:
161  *
162  * 0 ------ 2 ------ 4
163  * \ / \ /
164  * \ 0 / \ 2 /
165  * \ / 1 \ /
166  * 1 ------- 3
167  * \ /
168  * \ 3 /
169  * \ /
170  * \ /
171  * 5
172  */
173 
174 
175  Mesh::FaceFaceIter ff_it = mesh_.ff_begin(mesh_.face_handle(1));
176  Mesh::FaceFaceIter ff_end = mesh_.ff_end(mesh_.face_handle(1));
177 
178  EXPECT_EQ(2, ff_it->idx() ) << "Index wrong in FaceFaceIter at initialization";
179  EXPECT_TRUE(ff_it.is_valid()) << "Iterator invalid in FaceFaceIter at initialization";
180  ++ff_it;
181  EXPECT_EQ(0, ff_it->idx() ) << "Index wrong in FaceFaceIter at step 1";
182  EXPECT_TRUE(ff_it.is_valid()) << "Iterator invalid in FaceFaceIter at step 1";
183  ++ff_it;
184  EXPECT_EQ(3, ff_it->idx() ) << "Index wrong in FaceFaceIter at step 2";
185  EXPECT_TRUE(ff_it.is_valid()) << "Iterator invalid in FaceFaceIter at step 2";
186  ++ff_it;
187  EXPECT_EQ(2, ff_it->idx() ) << "Index wrong in FaceFaceIter at end";
188  EXPECT_FALSE(ff_it.is_valid()) << "Iterator invalid in FaceFaceIter at end";
189  EXPECT_TRUE( ff_it == ff_end ) << "End iterator for FaceFaceIter not matching";
190 
191  Mesh::ConstFaceFaceIter cff_it = mesh_.cff_begin(mesh_.face_handle(1));
192  Mesh::ConstFaceFaceIter cff_end = mesh_.cff_end(mesh_.face_handle(1));
193 
194  EXPECT_EQ(2, cff_it->idx() ) << "Index wrong in ConstFaceFaceIter at initialization";
195  EXPECT_TRUE(cff_it.is_valid()) << "Iterator invalid in ConstFaceFaceIter at initialization";
196  ++cff_it;
197  EXPECT_EQ(0, cff_it->idx() ) << "Index wrong in ConstFaceFaceIter at step 1";
198  EXPECT_TRUE(cff_it.is_valid()) << "Iterator invalid in ConstFaceFaceIter at step 1";
199  ++cff_it;
200  EXPECT_EQ(3, cff_it->idx() ) << "Index wrong in ConstFaceFaceIter at step 2";
201  EXPECT_TRUE(cff_it.is_valid()) << "Iterator invalid in ConstFaceFaceIter at step 2";
202  ++cff_it;
203  EXPECT_EQ(2, cff_it->idx() ) << "Index wrong in ConstFaceFaceIter at end";
204  EXPECT_FALSE(cff_it.is_valid()) << "Iterator invalid in ConstFaceFaceIter at end";
205  EXPECT_TRUE( cff_it == cff_end ) << "End iterator for ConstFaceFaceIter not matching";
206 
207 }
208 
209 /*
210  * Test CW and CCW iterators
211  */
212 TEST_F(OpenMeshTrimeshCirculatorFaceFace, CWAndCCWCheck) {
213 
214  mesh_.clear();
215 
216  // Add some vertices
217  Mesh::VertexHandle vhandle[6];
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(3, 0, 0));
223  vhandle[4] = mesh_.add_vertex(Mesh::Point(4, 1, 0));
224  vhandle[5] = mesh_.add_vertex(Mesh::Point(2,-1, 0));
225 
226  // Add three faces
227  std::vector<Mesh::VertexHandle> face_vhandles;
228 
229  face_vhandles.push_back(vhandle[0]);
230  face_vhandles.push_back(vhandle[1]);
231  face_vhandles.push_back(vhandle[2]);
232  mesh_.add_face(face_vhandles);
233 
234  face_vhandles.clear();
235 
236  face_vhandles.push_back(vhandle[2]);
237  face_vhandles.push_back(vhandle[1]);
238  face_vhandles.push_back(vhandle[3]);
239  mesh_.add_face(face_vhandles);
240 
241  face_vhandles.clear();
242 
243  face_vhandles.push_back(vhandle[2]);
244  face_vhandles.push_back(vhandle[3]);
245  face_vhandles.push_back(vhandle[4]);
246  mesh_.add_face(face_vhandles);
247 
248  face_vhandles.clear();
249 
250  face_vhandles.push_back(vhandle[1]);
251  face_vhandles.push_back(vhandle[5]);
252  face_vhandles.push_back(vhandle[3]);
253  mesh_.add_face(face_vhandles);
254 
255  /* Test setup:
256  *
257  * 0 ------ 2 ------ 4
258  * \ / \ /
259  * \ 0 / \ 2 /
260  * \ / 1 \ /
261  * 1 ------- 3
262  * \ /
263  * \ 3 /
264  * \ /
265  * \ /
266  * 5
267  */
268 
269 
270  int indices[4] = {2, 0, 3, 2};
271  int rev_indices[4];
272  std::reverse_copy(indices,indices+4,rev_indices);
273 
274  //CCW
275  Mesh::FaceFaceCCWIter ff_ccwit = mesh_.ff_ccwbegin(mesh_.face_handle(1));
276  Mesh::FaceFaceCCWIter ff_ccwend = mesh_.ff_ccwend(mesh_.face_handle(1));
277  size_t i = 0;
278  for (;ff_ccwit != ff_ccwend; ++ff_ccwit, ++i)
279  {
280  EXPECT_EQ(indices[i], ff_ccwit->idx()) << "Index wrong in FaceFaceCCWIter";
281  }
282 
283  EXPECT_FALSE(ff_ccwit.is_valid()) << "Iterator invalid in FaceFaceCCWIter at end";
284  EXPECT_TRUE( ff_ccwit == ff_ccwend ) << "End iterator for FaceFaceCCWIter not matching";
285 
286  //constant CCW
287  Mesh::ConstFaceFaceCCWIter cff_ccwit = mesh_.cff_ccwbegin(mesh_.face_handle(1));
288  Mesh::ConstFaceFaceCCWIter cff_ccwend = mesh_.cff_ccwend(mesh_.face_handle(1));
289  i = 0;
290  for (;cff_ccwit != cff_ccwend; ++cff_ccwit, ++i)
291  {
292  EXPECT_EQ(indices[i], cff_ccwit->idx()) << "Index wrong in ConstFaceFaceCCWIter";
293  }
294 
295  EXPECT_FALSE(cff_ccwit.is_valid()) << "Iterator invalid in ConstFaceFaceCCWIter at end";
296  EXPECT_TRUE( cff_ccwit == cff_ccwend ) << "End iterator for ConstFaceFaceCCWIter not matching";
297 
298  //CW
299  Mesh::FaceFaceCWIter ff_cwit = mesh_.ff_cwbegin(mesh_.face_handle(1));
300  Mesh::FaceFaceCWIter ff_cwend = mesh_.ff_cwend(mesh_.face_handle(1));
301  i = 0;
302  for (;ff_cwit != ff_cwend; ++ff_cwit, ++i)
303  {
304  EXPECT_EQ(rev_indices[i], ff_cwit->idx()) << "Index wrong in FaceFaceCWIter";
305  }
306  EXPECT_FALSE(ff_cwit.is_valid()) << "Iterator invalid in FaceFaceCWIter at end";
307  EXPECT_TRUE( ff_cwit == ff_cwend ) << "End iterator for FaceFaceCWIter not matching";
308 
309  //constant CW
310  Mesh::ConstFaceFaceCWIter cff_cwit = mesh_.cff_cwbegin(mesh_.face_handle(1));
311  Mesh::ConstFaceFaceCWIter cff_cwend = mesh_.cff_cwend(mesh_.face_handle(1));
312  i = 0;
313  for (;cff_cwit != cff_cwend; ++cff_cwit, ++i)
314  {
315  EXPECT_EQ(rev_indices[i], cff_cwit->idx()) << "Index wrong in ConstFaceFaceCWIter";
316  }
317  EXPECT_FALSE(cff_cwit.is_valid()) << "Iterator invalid in ConstFaceFaceCWIter at end";
318  EXPECT_TRUE( cff_cwit == cff_cwend ) << "End iterator for ConstFaceFaceCWIter not matching";
319 
320  /*
321  * conversion properties:
322  * a) cw_begin == CWIter(ccw_begin())
323  * b) cw_iter->idx() == CCWIter(cw_iter)->idx() for valid iterators
324  * c) --cw_iter == CWIter(++ccwIter) for valid iterators
325  * d) cw_end == CWIter(ccw_end()) => --cw_end != CWIter(++ccw_end()) *
326  */
327  Mesh::FaceFaceCWIter ff_cwIter = mesh_.ff_cwbegin(mesh_.face_handle(1));
328  // a)
329  EXPECT_TRUE( ff_cwIter == Mesh::FaceFaceCWIter(mesh_.ff_ccwbegin(mesh_.face_handle(1))) ) << "ccw to cw conversion failed";
330  EXPECT_TRUE( Mesh::FaceFaceCCWIter(ff_cwIter) == mesh_.ff_ccwbegin(mesh_.face_handle(1)) ) << "cw to ccw conversion failed";
331  // b)
332  EXPECT_EQ( ff_cwIter->idx(), Mesh::FaceFaceCCWIter(ff_cwIter)->idx()) << "iterators doesnt point on the same element";
333  // c)
334  ++ff_cwIter;
335  ff_ccwend = mesh_.ff_ccwend(mesh_.face_handle(1));
336  --ff_ccwend;
337  EXPECT_EQ(ff_cwIter->idx(),ff_ccwend->idx()) << "iteratoes are not equal after inc/dec";
338  // additional conversion check
339  ff_ccwend = Mesh::FaceFaceCCWIter(ff_cwIter);
340  EXPECT_EQ(ff_cwIter->idx(),ff_ccwend->idx())<< "iterators doesnt point on the same element";
341  // d)
342  ff_cwIter = Mesh::FaceFaceCWIter(mesh_.ff_ccwend(mesh_.face_handle(1)));
343  EXPECT_FALSE(ff_cwIter.is_valid()) << "end iterator is not invalid";
344  EXPECT_TRUE(Mesh::FaceFaceCCWIter(mesh_.ff_cwend(mesh_.face_handle(1))) == mesh_.ff_ccwend(mesh_.face_handle(1))) << "end iterators are not equal";
345 
346 
347 }
348 
349 
350 
351 /*
352  * Small FaceFaceIterator Test for getting handles and faces from the facefaceiterator
353  */
354 TEST_F(OpenMeshTrimeshCirculatorFaceFace, FaceFaceIteratorHandleConversion) {
355 
356  mesh_.clear();
357 
358  // Add some vertices
359  Mesh::VertexHandle vhandle[4];
360 
361  vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
362  vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
363  vhandle[2] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
364  vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
365 
366 
367  // Add two faces
368  std::vector<Mesh::VertexHandle> face_vhandles;
369 
370  face_vhandles.push_back(vhandle[0]);
371  face_vhandles.push_back(vhandle[2]);
372  face_vhandles.push_back(vhandle[1]);
373  Mesh::FaceHandle fh1 = mesh_.add_face(face_vhandles);
374 
375  face_vhandles.clear();
376 
377  face_vhandles.push_back(vhandle[0]);
378  face_vhandles.push_back(vhandle[3]);
379  face_vhandles.push_back(vhandle[2]);
380  mesh_.add_face(face_vhandles);
381 
382  face_vhandles.clear();
383 
384  /* Test setup:
385  *
386  * 1 -------- 2
387  * | f0 / |
388  * | / f1 |
389  * 0 -------- 3
390  */
391 
392  // Check setup
393  EXPECT_EQ(4u , mesh_.n_vertices() ) << "Wrong number of vertices";
394  EXPECT_EQ(2u , mesh_.n_faces() ) << "Wrong number of faces";
395 
396 
397  Mesh::ConstFaceFaceIter face_iter = mesh_.cff_iter(fh1);
398 
399 
400  // Get the face via the handle
401  Mesh::FaceHandle faceHandle1 = *face_iter;
402 
403  EXPECT_EQ(1, faceHandle1.idx() ) << "Wrong face handle index when getting from iterator via handle";
404 }
405 
406 /*
407  * Test if the end iterator stays invalid after one lap
408  */
409 //TEST_F(OpenMeshTrimeshCirculatorFaceFace, FaceFaceIterCheckInvalidationAtEnds) {
410 //
411 // mesh_.clear();
412 //
413 // // Add some vertices
414 // Mesh::VertexHandle vhandle[5];
415 //
416 // vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
417 // vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
418 // vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
419 // vhandle[3] = mesh_.add_vertex(Mesh::Point(0,-1, 0));
420 // vhandle[4] = mesh_.add_vertex(Mesh::Point(2,-1, 0));
421 //
422 // // Add two faces
423 // std::vector<Mesh::VertexHandle> face_vhandles;
424 //
425 // face_vhandles.push_back(vhandle[0]);
426 // face_vhandles.push_back(vhandle[1]);
427 // face_vhandles.push_back(vhandle[2]);
428 // Mesh::FaceHandle fh0 = mesh_.add_face(face_vhandles);
429 //
430 // face_vhandles.clear();
431 //
432 // face_vhandles.push_back(vhandle[1]);
433 // face_vhandles.push_back(vhandle[3]);
434 // face_vhandles.push_back(vhandle[4]);
435 // mesh_.add_face(face_vhandles);
436 //
437 // face_vhandles.clear();
438 //
439 // face_vhandles.push_back(vhandle[0]);
440 // face_vhandles.push_back(vhandle[3]);
441 // face_vhandles.push_back(vhandle[1]);
442 // mesh_.add_face(face_vhandles);
443 //
444 // face_vhandles.clear();
445 //
446 // face_vhandles.push_back(vhandle[2]);
447 // face_vhandles.push_back(vhandle[1]);
448 // face_vhandles.push_back(vhandle[4]);
449 // mesh_.add_face(face_vhandles);
450 //
451 // /* Test setup:
452 // 0 ==== 2
453 // |\ 0 /|
454 // | \ / |
455 // |2 1 3|
456 // | / \ |
457 // |/ 1 \|
458 // 3 ==== 4 */
459 //
460 //
461 // // Check if the end iterator stays invalid after end
462 // Mesh::FaceFaceIter endIter = mesh_.ff_end(fh0);
463 // EXPECT_FALSE(endIter.is_valid()) << "EndIter is not invalid";
464 // ++endIter ;
465 // EXPECT_FALSE(endIter.is_valid()) << "EndIter is not invalid after increment";
466 //
467 // // Check if the end iterators becomes valid after decrement
468 // endIter = mesh_.ff_end(fh0);
469 // EXPECT_FALSE(endIter.is_valid()) << "EndIter is not invalid";
470 // --endIter;
471 // EXPECT_TRUE(endIter.is_valid()) << "EndIter is invalid after decrement";
472 // EXPECT_EQ(3,endIter->idx()) << "EndIter points on the wrong element";
473 //
474 //
475 // // Check if the start iterator decrement is invalid
476 // Mesh::FaceFaceIter startIter = mesh_.ff_begin(fh0);
477 // EXPECT_TRUE(startIter.is_valid()) << "StartIter is not valid";
478 // --startIter;
479 // EXPECT_FALSE(startIter.is_valid()) << "StartIter decrement is not invalid";
480 //
481 // // Check if the start iterator becomes valid
482 // ++startIter;
483 // EXPECT_TRUE(startIter.is_valid()) << "StartIter is invalid after re-incrementing";
484 // EXPECT_EQ(startIter->idx(), mesh_.ff_begin(fh0)->idx()) << "StartIter points on the wrong element";
485 //
486 //}
487 
488 
489 }
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:115
VertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
Definition: PolyMeshT.hh:236
Kernel::FaceFaceIter FaceFaceIter
Circulator.
Definition: PolyMeshT.hh:173
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:139
Kernel::ConstFaceFaceIter ConstFaceFaceIter
Circulator.
Definition: PolyMeshT.hh:183