Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
unittests_trimesh_iterators.cc
1 #include <gtest/gtest.h>
2 #include <Unittests/unittests_common.hh>
3 
4 #include <iostream>
5 
6 namespace {
7 
8 class OpenMeshIterators : 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  // Member already defined in OpenMeshBase
23  //Mesh mesh_;
24 };
25 
26 /*
27  * ====================================================================
28  * Define tests below
29  * ====================================================================
30  */
31 
32 /*
33  * Small VertexIterator Test
34  */
35 TEST_F(OpenMeshIterators, VertexIter) {
36 
37  mesh_.clear();
38 
39  // Add some vertices
40  Mesh::VertexHandle vhandle[4];
41 
42  vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
43  vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
44  vhandle[2] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
45  vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
46 
47  // Add two faces
48  std::vector<Mesh::VertexHandle> face_vhandles;
49 
50  face_vhandles.push_back(vhandle[2]);
51  face_vhandles.push_back(vhandle[1]);
52  face_vhandles.push_back(vhandle[0]);
53  mesh_.add_face(face_vhandles);
54 
55  face_vhandles.clear();
56 
57  face_vhandles.push_back(vhandle[2]);
58  face_vhandles.push_back(vhandle[0]);
59  face_vhandles.push_back(vhandle[3]);
60  mesh_.add_face(face_vhandles);
61 
62  // Test setup:
63  // 1 === 2
64  // | / |
65  // | / |
66  // | / |
67  // 0 === 3
68 
69  Mesh::VertexIter v_it = mesh_.vertices_begin();
70  Mesh::VertexIter v_end = mesh_.vertices_end();
71 
72  EXPECT_EQ(0, v_it->idx()) << "Index wrong for vertex iterator vertices_begin()";
73  ++v_it;
74  EXPECT_EQ(1, v_it->idx()) << "Index wrong in vertex iterator";
75  ++v_it;
76  EXPECT_EQ(2, v_it->idx()) << "Index wrong in vertex iterator";
77  ++v_it;
78  EXPECT_EQ(3, v_it->idx()) << "Index wrong in vertex iterator";
79  ++v_it;
80  EXPECT_EQ(4, v_it->idx()) << "Index wrong in vertex iterator";
81 
82  // Check end iterator
83  EXPECT_EQ(4, v_end->idx()) << "Index wrong in vertex iterator for vertices_end()";
84 
85 
86  // Second iterator test to start at a specific position
87 
88 }
89 
90 /*
91  * Small VertexIterator Test to check if we can start iterating at a specific handle
92  */
93 TEST_F(OpenMeshIterators, VertexIterStartPosition) {
94 
95  mesh_.clear();
96 
97  // Add some vertices
98  Mesh::VertexHandle vhandle[4];
99 
100  vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
101  vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
102  vhandle[2] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
103  vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
104 
105  // Add two faces
106  std::vector<Mesh::VertexHandle> face_vhandles;
107 
108  face_vhandles.push_back(vhandle[2]);
109  face_vhandles.push_back(vhandle[1]);
110  face_vhandles.push_back(vhandle[0]);
111  mesh_.add_face(face_vhandles);
112 
113  face_vhandles.clear();
114 
115  face_vhandles.push_back(vhandle[2]);
116  face_vhandles.push_back(vhandle[0]);
117  face_vhandles.push_back(vhandle[3]);
118  mesh_.add_face(face_vhandles);
119 
120  // Test setup:
121  // 1 === 2
122  // | / |
123  // | / |
124  // | / |
125  // 0 === 3
126 
127  Mesh::VertexIter v_it = Mesh::VertexIter(mesh_,mesh_.vertex_handle(2));
128  Mesh::VertexIter v_end = mesh_.vertices_end();
129 
130  EXPECT_EQ(2, v_it->idx()) << "Index wrong in vertex iterator";
131  ++v_it;
132  EXPECT_EQ(3, v_it->idx()) << "Index wrong in vertex iterator";
133  ++v_it;
134  EXPECT_EQ(4, v_it->idx()) << "Index wrong in vertex iterator";
135 
136  // Check end iterator
137  EXPECT_EQ(4, v_end->idx()) << "Index wrong in vertex iterator for vertices_end()";
138 
139 
140 }
141 
142 
143 /*
144  * Small VertexIterator Test to check if we can continue from the end after adding vertices
145  */
146 TEST_F(OpenMeshIterators, VertexIterContinueAfterEnd) {
147 
148  mesh_.clear();
149 
150  // Add some vertices
151  Mesh::VertexHandle vhandle[4];
152 
153  vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
154  vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
155  vhandle[2] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
156  vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
157 
158  // Add two faces
159  std::vector<Mesh::VertexHandle> face_vhandles;
160 
161  face_vhandles.push_back(vhandle[2]);
162  face_vhandles.push_back(vhandle[1]);
163  face_vhandles.push_back(vhandle[0]);
164  mesh_.add_face(face_vhandles);
165 
166  face_vhandles.clear();
167 
168  face_vhandles.push_back(vhandle[2]);
169  face_vhandles.push_back(vhandle[0]);
170  face_vhandles.push_back(vhandle[3]);
171  mesh_.add_face(face_vhandles);
172 
173  // Test setup:
174  // 1 === 2
175  // | / |
176  // | / |
177  // | / |
178  // 0 === 3
179 
180 
181 
182  // Add a double vertex property
183  OpenMesh::VPropHandleT<int> intHandle;
184  EXPECT_FALSE( mesh_.get_property_handle(intHandle,"intProp") );
185  mesh_.add_property(intHandle,"intProp");
186 
187  // Initialize existing properties:
188  int i = 0;
189  for (Mesh::VertexIter v_it = mesh_.vertices_begin(); v_it != mesh_.vertices_end() ; ++ v_it) {
190  mesh_.property(intHandle,*v_it) = i;
191  ++i;
192  }
193 
194  // Check property
195  EXPECT_TRUE(mesh_.get_property_handle(intHandle,"intProp"));
196 
197  // Remember old end iterator
198  Mesh::VertexIter old_end = mesh_.vertices_end();
199 
200  // Set properties to perform test
201  for ( unsigned int j = 0 ; j < 4 ; ++j ) {
202  OpenMesh::VertexHandle vh = mesh_.add_vertex(Mesh::Point(1, 0, 0));
203  mesh_.property(intHandle,vh) = i;
204  ++i;
205  }
206 
207  // Reset to first expected value
208  i = 4;
209 
210  for ( Mesh::VertexIter test = old_end ; test != mesh_.vertices_end() ; ++test ) {
211  EXPECT_EQ( mesh_.property(intHandle,*test) , i);
212  ++i;
213  }
214 
215 }
216 
217 /*
218  * Small EdgeIterator Test
219  */
220 TEST_F(OpenMeshIterators, EdgeIter) {
221 
222  mesh_.clear();
223 
224  // Add some vertices
225  Mesh::VertexHandle vhandle[4];
226 
227  vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
228  vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
229  vhandle[2] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
230  vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
231 
232  // Add two faces
233  std::vector<Mesh::VertexHandle> face_vhandles;
234 
235  face_vhandles.push_back(vhandle[2]);
236  face_vhandles.push_back(vhandle[1]);
237  face_vhandles.push_back(vhandle[0]);
238  mesh_.add_face(face_vhandles);
239 
240  face_vhandles.clear();
241 
242  face_vhandles.push_back(vhandle[2]);
243  face_vhandles.push_back(vhandle[0]);
244  face_vhandles.push_back(vhandle[3]);
245  mesh_.add_face(face_vhandles);
246 
247  // Test setup:
248  // 1 === 2
249  // | / |
250  // | / |
251  // | / |
252  // 0 === 3
253 
254 
255  Mesh::EdgeIter e_it = mesh_.edges_begin();
256  Mesh::EdgeIter e_end = mesh_.edges_end();
257 
258  EXPECT_EQ(0, e_it->idx()) << "Wrong start index in edge iterator";
259  EXPECT_EQ(5, e_end->idx()) << "Wrong end index in edge iterator";
260 
261  EXPECT_EQ(1, mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it,0)).idx() ) << "1: Wrong to vertex handle of halfedge 0";
262  EXPECT_EQ(2, mesh_.from_vertex_handle(mesh_.halfedge_handle(*e_it,0)).idx() ) << "1: Wrong from vertex handle of halfedge 0";
263  EXPECT_EQ(2, mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it,1)).idx() ) << "1: Wrong to vertex handle of halfedge 1";
264  EXPECT_EQ(1, mesh_.from_vertex_handle(mesh_.halfedge_handle(*e_it,1)).idx() ) << "1: Wrong from vertex handle of halfedge 1";
265 
266  ++e_it;
267  EXPECT_EQ(1, e_it->idx()) << "Wrong index in edge iterator";
268 
269  EXPECT_EQ(0, mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it,0)).idx() ) << "2: Wrong to vertex handle of halfedge 0";
270  EXPECT_EQ(1, mesh_.from_vertex_handle(mesh_.halfedge_handle(*e_it,0)).idx() ) << "2: Wrong from vertex handle of halfedge 0";
271  EXPECT_EQ(1, mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it,1)).idx() ) << "2: Wrong to vertex handle of halfedge 1";
272  EXPECT_EQ(0, mesh_.from_vertex_handle(mesh_.halfedge_handle(*e_it,1)).idx() ) << "2: Wrong from vertex handle of halfedge 1";
273 
274 
275  ++e_it;
276  EXPECT_EQ(2, e_it->idx()) << "Wrong index in edge iterator";
277 
278  EXPECT_EQ(2, mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it,0)).idx() ) << "3: Wrong to vertex handle of halfedge 0";
279  EXPECT_EQ(0, mesh_.from_vertex_handle(mesh_.halfedge_handle(*e_it,0)).idx() ) << "3: Wrong from vertex handle of halfedge 0";
280  EXPECT_EQ(0, mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it,1)).idx() ) << "3: Wrong to vertex handle of halfedge 1";
281  EXPECT_EQ(2, mesh_.from_vertex_handle(mesh_.halfedge_handle(*e_it,1)).idx() ) << "3: Wrong from vertex handle of halfedge 1";
282 
283 
284  ++e_it;
285  EXPECT_EQ(3, e_it->idx()) << "Wrong index in edge iterator";
286 
287  EXPECT_EQ(3, mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it,0)).idx() ) << "4: Wrong to vertex handle of halfedge 0";
288  EXPECT_EQ(0, mesh_.from_vertex_handle(mesh_.halfedge_handle(*e_it,0)).idx() ) << "4: Wrong from vertex handle of halfedge 0";
289  EXPECT_EQ(0, mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it,1)).idx() ) << "4: Wrong to vertex handle of halfedge 1";
290  EXPECT_EQ(3, mesh_.from_vertex_handle(mesh_.halfedge_handle(*e_it,1)).idx() ) << "4: Wrong from vertex handle of halfedge 1";
291 
292 
293  ++e_it;
294  EXPECT_EQ(4, e_it->idx()) << "Wrong index in edge iterator";
295 
296  EXPECT_EQ(2, mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it,0)).idx() ) << "5: Wrong to vertex handle of halfedge 0";
297  EXPECT_EQ(3, mesh_.from_vertex_handle(mesh_.halfedge_handle(*e_it,0)).idx() ) << "5: Wrong from vertex handle of halfedge 0";
298  EXPECT_EQ(3, mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it,1)).idx() ) << "5: Wrong to vertex handle of halfedge 1";
299  EXPECT_EQ(2, mesh_.from_vertex_handle(mesh_.halfedge_handle(*e_it,1)).idx() ) << "5: Wrong from vertex handle of halfedge 1";
300 
301 
302 }
303 
304 /* Adds a cube to a trimesh and runs over all halfedges
305  */
306 TEST_F(OpenMeshIterators, HalfedgeIterSkipping) {
307 
308  mesh_.clear();
309 
310  // Add some vertices
311  Mesh::VertexHandle vhandle[8];
312  vhandle[0] = mesh_.add_vertex(Mesh::Point(-1, -1, 1));
313  vhandle[1] = mesh_.add_vertex(Mesh::Point( 1, -1, 1));
314  vhandle[2] = mesh_.add_vertex(Mesh::Point( 1, 1, 1));
315  vhandle[3] = mesh_.add_vertex(Mesh::Point(-1, 1, 1));
316  vhandle[4] = mesh_.add_vertex(Mesh::Point(-1, -1, -1));
317  vhandle[5] = mesh_.add_vertex(Mesh::Point( 1, -1, -1));
318  vhandle[6] = mesh_.add_vertex(Mesh::Point( 1, 1, -1));
319  vhandle[7] = mesh_.add_vertex(Mesh::Point(-1, 1, -1));
320 
321  // Add six faces to form a cube
322  std::vector<Mesh::VertexHandle> face_vhandles;
323 
324  face_vhandles.clear();
325  face_vhandles.push_back(vhandle[0]);
326  face_vhandles.push_back(vhandle[1]);
327  face_vhandles.push_back(vhandle[3]);
328  mesh_.add_face(face_vhandles);
329 
330  face_vhandles.clear();
331  face_vhandles.push_back(vhandle[1]);
332  face_vhandles.push_back(vhandle[2]);
333  face_vhandles.push_back(vhandle[3]);
334  mesh_.add_face(face_vhandles);
335 
336  //=======================
337 
338  face_vhandles.clear();
339  face_vhandles.push_back(vhandle[7]);
340  face_vhandles.push_back(vhandle[6]);
341  face_vhandles.push_back(vhandle[5]);
342  mesh_.add_face(face_vhandles);
343 
344  face_vhandles.clear();
345  face_vhandles.push_back(vhandle[7]);
346  face_vhandles.push_back(vhandle[5]);
347  face_vhandles.push_back(vhandle[4]);
348  mesh_.add_face(face_vhandles);
349 
350  //=======================
351 
352  face_vhandles.clear();
353  face_vhandles.push_back(vhandle[1]);
354  face_vhandles.push_back(vhandle[0]);
355  face_vhandles.push_back(vhandle[4]);
356  mesh_.add_face(face_vhandles);
357 
358  face_vhandles.clear();
359  face_vhandles.push_back(vhandle[1]);
360  face_vhandles.push_back(vhandle[4]);
361  face_vhandles.push_back(vhandle[5]);
362  mesh_.add_face(face_vhandles);
363 
364  //=======================
365 
366  face_vhandles.clear();
367  face_vhandles.push_back(vhandle[2]);
368  face_vhandles.push_back(vhandle[1]);
369  face_vhandles.push_back(vhandle[5]);
370  mesh_.add_face(face_vhandles);
371 
372  face_vhandles.clear();
373  face_vhandles.push_back(vhandle[2]);
374  face_vhandles.push_back(vhandle[5]);
375  face_vhandles.push_back(vhandle[6]);
376  mesh_.add_face(face_vhandles);
377 
378 
379  //=======================
380 
381  face_vhandles.clear();
382  face_vhandles.push_back(vhandle[3]);
383  face_vhandles.push_back(vhandle[2]);
384  face_vhandles.push_back(vhandle[6]);
385  mesh_.add_face(face_vhandles);
386 
387  face_vhandles.clear();
388  face_vhandles.push_back(vhandle[3]);
389  face_vhandles.push_back(vhandle[6]);
390  face_vhandles.push_back(vhandle[7]);
391  mesh_.add_face(face_vhandles);
392 
393  //=======================
394 
395  face_vhandles.clear();
396  face_vhandles.push_back(vhandle[0]);
397  face_vhandles.push_back(vhandle[3]);
398  face_vhandles.push_back(vhandle[7]);
399  mesh_.add_face(face_vhandles);
400 
401  face_vhandles.clear();
402  face_vhandles.push_back(vhandle[0]);
403  face_vhandles.push_back(vhandle[7]);
404  face_vhandles.push_back(vhandle[4]);
405  mesh_.add_face(face_vhandles);
406 
407 
408  // Test setup:
409  //
410  //
411  // 3 ======== 2
412  // / /|
413  // / / | z
414  // 0 ======== 1 | |
415  // | | | | y
416  // | 7 | 6 | /
417  // | | / | /
418  // | |/ |/
419  // 4 ======== 5 -------> x
420  //
421 
422  // Check setup
423  EXPECT_EQ(18u, mesh_.n_edges() ) << "Wrong number of Edges";
424  EXPECT_EQ(36u, mesh_.n_halfedges() ) << "Wrong number of HalfEdges";
425  EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong number of vertices";
426  EXPECT_EQ(12u, mesh_.n_faces() ) << "Wrong number of faces";
427 
428  mesh_.request_face_status();
429  mesh_.request_vertex_status();
430  mesh_.request_halfedge_status();
431 
432  // Get second edge
433  Mesh::EdgeHandle eh = mesh_.edge_handle(2);
434 
435  // Delete one edge
436  mesh_.delete_edge(eh);
437 
438  // Check setup ( No garbage collection, so nothing should change!)
439  EXPECT_EQ(18u, mesh_.n_edges() ) << "Wrong number of Edges after delete";
440  EXPECT_EQ(36u, mesh_.n_halfedges() ) << "Wrong number of HalfEdges after delete";
441  EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong number of vertices after delete";
442  EXPECT_EQ(12u, mesh_.n_faces() ) << "Wrong number of faces after delete";
443 
444  Mesh::HalfedgeIter he_it = mesh_.halfedges_sbegin();
445  Mesh::HalfedgeIter he_end = mesh_.halfedges_end();
446 
447  EXPECT_EQ(0, he_it->idx()) << "Wrong start index in halfedge iterator";
448  EXPECT_EQ(36, he_end->idx()) << "Wrong end index in halfedge iterator";
449 
450 
451  // =====================================================
452  // Check skipping iterator
453  // =====================================================
454  bool ok_4 = true;
455  bool ok_5 = true;
456 
457  unsigned int count = 0;
458 
459  while (he_it != he_end) {
460  if ( he_it->idx() == 4 )
461  ok_4 = false;
462 
463  if ( he_it->idx() == 5 )
464  ok_5 = false;
465 
466  ++he_it;
467  ++count;
468  }
469 
470  EXPECT_EQ(34u,count) << "Skipping iterator count error";
471  EXPECT_TRUE( ok_4 ) << "Skipping iterator hit deleted halfedge 4";
472  EXPECT_TRUE( ok_5 ) << "Skipping iterator hit deleted halfedge 5";
473 
474  // =====================================================
475  // Check non skipping iterator
476  // =====================================================
477  he_it = mesh_.halfedges_begin();
478 
479  count = 0;
480  ok_4 = false;
481  ok_5 = false;
482 
483  while (he_it != he_end) {
484  if ( he_it->idx() == 4 )
485  ok_4 = true;
486 
487  if ( he_it->idx() == 5 )
488  ok_5 = true;
489 
490 
491  ++he_it;
492  ++count;
493  }
494 
495  EXPECT_EQ(36u,count) << "Non-skipping iterator count error";
496  EXPECT_TRUE( ok_4 ) << "Non-skipping iterator missed deleted halfedge 4";
497  EXPECT_TRUE( ok_5 ) << "Non-skipping iterator missed deleted halfedge 5";
498 }
499 
500 /* Adds a cube to a trimesh and runs over all halfedges
501  */
502 TEST_F(OpenMeshIterators, HalfedgeIterSkippingLowLevel) {
503 
504  mesh_.clear();
505 
506  // Add some vertices
507  Mesh::VertexHandle vhandle[8];
508  vhandle[0] = mesh_.add_vertex(Mesh::Point(-1, -1, 1));
509  vhandle[1] = mesh_.add_vertex(Mesh::Point( 1, -1, 1));
510  vhandle[2] = mesh_.add_vertex(Mesh::Point( 1, 1, 1));
511  vhandle[3] = mesh_.add_vertex(Mesh::Point(-1, 1, 1));
512  vhandle[4] = mesh_.add_vertex(Mesh::Point(-1, -1, -1));
513  vhandle[5] = mesh_.add_vertex(Mesh::Point( 1, -1, -1));
514  vhandle[6] = mesh_.add_vertex(Mesh::Point( 1, 1, -1));
515  vhandle[7] = mesh_.add_vertex(Mesh::Point(-1, 1, -1));
516 
517  // Add six faces to form a cube
518  std::vector<Mesh::VertexHandle> face_vhandles;
519 
520  face_vhandles.clear();
521  face_vhandles.push_back(vhandle[0]);
522  face_vhandles.push_back(vhandle[1]);
523  face_vhandles.push_back(vhandle[3]);
524  mesh_.add_face(face_vhandles);
525 
526  face_vhandles.clear();
527  face_vhandles.push_back(vhandle[1]);
528  face_vhandles.push_back(vhandle[2]);
529  face_vhandles.push_back(vhandle[3]);
530  mesh_.add_face(face_vhandles);
531 
532  //=======================
533 
534  face_vhandles.clear();
535  face_vhandles.push_back(vhandle[7]);
536  face_vhandles.push_back(vhandle[6]);
537  face_vhandles.push_back(vhandle[5]);
538  mesh_.add_face(face_vhandles);
539 
540  face_vhandles.clear();
541  face_vhandles.push_back(vhandle[7]);
542  face_vhandles.push_back(vhandle[5]);
543  face_vhandles.push_back(vhandle[4]);
544  mesh_.add_face(face_vhandles);
545 
546  //=======================
547 
548  face_vhandles.clear();
549  face_vhandles.push_back(vhandle[1]);
550  face_vhandles.push_back(vhandle[0]);
551  face_vhandles.push_back(vhandle[4]);
552  mesh_.add_face(face_vhandles);
553 
554  face_vhandles.clear();
555  face_vhandles.push_back(vhandle[1]);
556  face_vhandles.push_back(vhandle[4]);
557  face_vhandles.push_back(vhandle[5]);
558  mesh_.add_face(face_vhandles);
559 
560  //=======================
561 
562  face_vhandles.clear();
563  face_vhandles.push_back(vhandle[2]);
564  face_vhandles.push_back(vhandle[1]);
565  face_vhandles.push_back(vhandle[5]);
566  mesh_.add_face(face_vhandles);
567 
568  face_vhandles.clear();
569  face_vhandles.push_back(vhandle[2]);
570  face_vhandles.push_back(vhandle[5]);
571  face_vhandles.push_back(vhandle[6]);
572  mesh_.add_face(face_vhandles);
573 
574 
575  //=======================
576 
577  face_vhandles.clear();
578  face_vhandles.push_back(vhandle[3]);
579  face_vhandles.push_back(vhandle[2]);
580  face_vhandles.push_back(vhandle[6]);
581  mesh_.add_face(face_vhandles);
582 
583  face_vhandles.clear();
584  face_vhandles.push_back(vhandle[3]);
585  face_vhandles.push_back(vhandle[6]);
586  face_vhandles.push_back(vhandle[7]);
587  mesh_.add_face(face_vhandles);
588 
589  //=======================
590 
591  face_vhandles.clear();
592  face_vhandles.push_back(vhandle[0]);
593  face_vhandles.push_back(vhandle[3]);
594  face_vhandles.push_back(vhandle[7]);
595  mesh_.add_face(face_vhandles);
596 
597  face_vhandles.clear();
598  face_vhandles.push_back(vhandle[0]);
599  face_vhandles.push_back(vhandle[7]);
600  face_vhandles.push_back(vhandle[4]);
601  mesh_.add_face(face_vhandles);
602 
603 
604  // Test setup:
605  //
606  //
607  // 3 ======== 2
608  // / /|
609  // / / | z
610  // 0 ======== 1 | |
611  // | | | | y
612  // | 7 | 6 | /
613  // | | / | /
614  // | |/ |/
615  // 4 ======== 5 -------> x
616  //
617 
618  // Check setup
619  EXPECT_EQ(18u, mesh_.n_edges() ) << "Wrong number of Edges";
620  EXPECT_EQ(36u, mesh_.n_halfedges() ) << "Wrong number of HalfEdges";
621  EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong number of vertices";
622  EXPECT_EQ(12u, mesh_.n_faces() ) << "Wrong number of faces";
623 
624  mesh_.request_face_status();
625  mesh_.request_vertex_status();
626  mesh_.request_halfedge_status();
627 
628  // Get second edge
629  Mesh::EdgeHandle eh = mesh_.edge_handle(2);
630 
631  // Check setup ( No garbage collection, so nothing should change!)
632  EXPECT_EQ(18u, mesh_.n_edges() ) << "Wrong number of Edges after delete";
633  EXPECT_EQ(36u, mesh_.n_halfedges() ) << "Wrong number of HalfEdges after delete";
634  EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong number of vertices after delete";
635  EXPECT_EQ(12u, mesh_.n_faces() ) << "Wrong number of faces after delete";
636 
637  Mesh::HalfedgeIter he_it = mesh_.halfedges_sbegin();
638  Mesh::HalfedgeIter he_end = mesh_.halfedges_end();
639 
640  EXPECT_EQ(0, he_it->idx()) << "Wrong start index in halfedge iterator";
641  EXPECT_EQ(36, he_end->idx()) << "Wrong end index in halfedge iterator";
642 
643  // =====================================================
644  // Try to add low level edge with invalid incidents and
645  // check skipping iterator
646  // =====================================================
647 
648  // Add a low level edge without handles
649  Mesh::EdgeHandle eh_test = mesh_.edge_handle(mesh_.new_edge(Mesh::VertexHandle(),Mesh::VertexHandle()));
650 
651  he_it = mesh_.halfedges_sbegin();
652  he_end = mesh_.halfedges_end();
653 
654  unsigned int count = 0;
655  bool found_36 = false;
656  bool found_37 = false;
657 
658  while (he_it != he_end) {
659  if ( he_it->idx() == 36 )
660  found_36 = true;
661 
662  if ( he_it->idx() == 37 )
663  found_37 = true;
664 
665  ++he_it;
666  ++count;
667  }
668 
669  EXPECT_EQ(38u,count) << "Skipping iterator count error";
670  EXPECT_TRUE( found_36 ) << "Skipping iterator missed halfedge 36";
671  EXPECT_TRUE( found_37 ) << "Skipping iterator missed halfedge 37";
672 
673  // =====================================================
674  // Try to delete one edge with valid incidents and
675  // check skipping iterator
676  // =====================================================
677 
678  // delete one edge and recheck (Halfedges 4 and 5)
679  mesh_.delete_edge(eh);
680 
681  he_it = mesh_.halfedges_sbegin();
682  he_end = mesh_.halfedges_end();
683 
684  count = 0;
685  bool found_4 = false;
686  bool found_5 = false;
687  found_36 = false;
688  found_37 = false;
689 
690  while (he_it != he_end) {
691 
692  if ( he_it->idx() == 4 )
693  found_4 = true;
694 
695  if ( he_it->idx() == 5 )
696  found_5 = true;
697 
698  if ( he_it->idx() == 36 )
699  found_36 = true;
700 
701  if ( he_it->idx() == 37 )
702  found_37 = true;
703 
704  ++he_it;
705  ++count;
706  }
707 
708  EXPECT_EQ(36u,count) << "Deleted valid: Skipping iterator count error";
709  EXPECT_FALSE( found_4 ) << "Deleted valid: Skipping iterator hit deleted halfedge 4";
710  EXPECT_FALSE( found_5 ) << "Deleted valid: Skipping iterator hit deleted halfedge 5";
711  EXPECT_TRUE( found_36 ) << "Deleted valid: Skipping iterator missed halfedge 36";
712  EXPECT_TRUE( found_37 ) << "Deleted valid: Skipping iterator missed halfedge 37";
713 
714  // =====================================================
715  // Try to delete one edge with invalid incidents and
716  // check skipping iterator
717  // =====================================================
718 
719  // delete one edge and recheck (Halfedges 4 and 5)
720  mesh_.delete_edge(eh_test);
721 
722  he_it = mesh_.halfedges_sbegin();
723  he_end = mesh_.halfedges_end();
724 
725  count = 0;
726  found_4 = false;
727  found_5 = false;
728  found_36 = false;
729  found_37 = false;
730 
731  while (he_it != he_end) {
732 
733  if ( he_it->idx() == 4 )
734  found_4 = true;
735 
736  if ( he_it->idx() == 5 )
737  found_5 = true;
738 
739  if ( he_it->idx() == 36 )
740  found_36 = true;
741 
742  if ( he_it->idx() == 37 )
743  found_37 = true;
744 
745  ++he_it;
746  ++count;
747  }
748 
749  EXPECT_EQ(34u,count) << "Deleted invalid: Skipping iterator count error";
750  EXPECT_FALSE( found_4 ) << "Deleted invalid: Skipping iterator hit deleted halfedge 4";
751  EXPECT_FALSE( found_5 ) << "Deleted invalid: Skipping iterator hit deleted halfedge 5";
752  EXPECT_FALSE( found_36 ) << "Deleted invalid: Skipping iterator hit deleted halfedge 36";
753  EXPECT_FALSE( found_37 ) << "Deleted invalid: Skipping iterator hit deleted halfedge 37";
754 
755 }
756 
757 /*
758  * Test with a mesh with one deleted face
759  */
760 TEST_F(OpenMeshIterators, FaceIterEmptyMeshOneDeletedFace) {
761 
762  mesh_.clear();
763 
764  // request delete_face capability
765  mesh_.request_vertex_status();
766  mesh_.request_edge_status();
767  mesh_.request_face_status();
768 
769  // Add some vertices
770  Mesh::VertexHandle vhandle[4];
771 
772  vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
773  vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
774  vhandle[2] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
775 
776  // Add two faces
777  std::vector<Mesh::VertexHandle> face_vhandles;
778 
779  face_vhandles.push_back(vhandle[2]);
780  face_vhandles.push_back(vhandle[1]);
781  face_vhandles.push_back(vhandle[0]);
782  Mesh::FaceHandle fh = mesh_.add_face(face_vhandles);
783 
784  // Delete face but keep vertices
785  bool const is_delete_isolated_vertex = false;
786  mesh_.delete_face(fh, is_delete_isolated_vertex);
787 
788  // Test setup (Face deleted but vertices kept.
789  // 1 === 2
790  // | /
791  // | /
792  // | /
793  // 0
794 
795  Mesh::FaceIter f_it = mesh_.faces_begin();
796  Mesh::FaceIter f_end = mesh_.faces_end();
797 
798  EXPECT_EQ(0, f_it->idx()) << "Wrong start index in FaceIterator";
799 
800  EXPECT_EQ(1, f_end->idx()) << "Wrong end index in FaceIterator";
801 
802  ++f_it;
803  EXPECT_EQ(1, f_it->idx()) << "Wrong end index in FaceIterator after one step";
804  EXPECT_TRUE(f_it == f_end ) << "Iterator not at end for FaceIterator after one step";
805 
806  Mesh::ConstFaceIter cf_it = mesh_.faces_begin();
807  Mesh::ConstFaceIter cf_end = mesh_.faces_end();
808 
809  EXPECT_EQ(0, cf_it->idx()) << "Wrong start index in ConstFaceIterator";
810 
811  EXPECT_EQ(1, cf_end->idx()) << "Wrong end index in ConstFaceIterator";
812 
813  ++cf_it;
814  EXPECT_EQ(1, cf_it->idx()) << "Wrong end index in ConstFaceIterator after one step";
815  EXPECT_TRUE(cf_it == cf_end ) << "Iterator not at end for ConstFaceIterator after one step";
816 
817 
818  // Same with skipping iterators:
819  f_it = mesh_.faces_sbegin();
820  f_end = mesh_.faces_end();
821 
822  EXPECT_EQ(1, f_it->idx()) << "Wrong start index in FaceIterator with skipping";
823 
824  EXPECT_EQ(1, f_end->idx()) << "Wrong end index in FaceIterator with skipping";
825 
826  EXPECT_TRUE(f_it == f_end ) << "Iterator not at end for FaceIterator with skipping";
827 
828  // Same with skipping iterators:
829  cf_it = mesh_.faces_sbegin();
830  cf_end = mesh_.faces_end();
831 
832  EXPECT_EQ(1, cf_it->idx()) << "Wrong start index in ConstFaceIterator with skipping";
833 
834  EXPECT_EQ(1, cf_end->idx()) << "Wrong end index in ConstFaceIterator with skipping";
835 
836  EXPECT_TRUE(cf_it == cf_end ) << "Iterator not at end for ConstFaceIterator with skipping";
837 
838 
839  mesh_.release_vertex_status();
840  mesh_.release_edge_status();
841  mesh_.release_face_status();
842 
843 }
844 }
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
Handle for a vertex entity.
Definition: Handles.hh:125
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:139