Developer Documentation

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 one 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
845
846
847 /*
848 * Test range iterators
849 */
850 TEST_F(OpenMeshIterators, RangeIterators) {
851
852 mesh_.clear();
853
854 // request delete_face capability
855 mesh_.request_vertex_status();
856 mesh_.request_edge_status();
857 mesh_.request_halfedge_status();
858 mesh_.request_face_status();
859
860 // Add some vertices
861 Mesh::VertexHandle vhandle[4];
862
863 vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
864 vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
865 vhandle[2] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
866 vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
867
868 // Add two faces
869 std::vector<Mesh::VertexHandle> face_vhandles;
870
871 face_vhandles.push_back(vhandle[2]);
872 face_vhandles.push_back(vhandle[1]);
873 face_vhandles.push_back(vhandle[0]);
874 mesh_.add_face(face_vhandles);
875
876 face_vhandles.clear();
877 face_vhandles.push_back(vhandle[0]);
878 face_vhandles.push_back(vhandle[3]);
879 face_vhandles.push_back(vhandle[2]);
880 Mesh::FaceHandle fh = mesh_.add_face(face_vhandles);
881
882 // Delete one face
883 mesh_.delete_face(fh);
884
885 // Test setup (right face deleted)
886 // 1 --- 2
887 // | / |
888 // | / |
889 // | / |
890 // 0 --- 3
891
892
893 // ====== Faces ======
894
895 int count_faces_iter = 0;
896 for (auto f_it = mesh_.faces_begin(); f_it != mesh_.faces_end(); ++f_it)
897 ++count_faces_iter;
898 EXPECT_EQ(2, count_faces_iter) << "Wrong number of visited faces.";
899
900 int count_faces_skipping_iter = 0;
901 for (auto f_it = mesh_.faces_sbegin(); f_it != mesh_.faces_end(); ++f_it)
902 ++count_faces_skipping_iter;
903 EXPECT_EQ(1, count_faces_skipping_iter) << "Wrong number of visited faces.";
904
905 int count_faces_range = 0;
906 for (auto fh : mesh_.faces())
907 if (fh.is_valid()) // not actually necessary but fixes unused variable warning
908 ++count_faces_range;
909 EXPECT_EQ(1, count_faces_range) << "Wrong number of visited faces.";
910
911 int count_faces_range_all = 0;
912 for (auto fh : mesh_.all_faces())
913 if (fh.is_valid()) // not actually necessary but fixes unused variable warning
914 ++count_faces_range_all;
915 EXPECT_EQ(2, count_faces_range_all) << "Wrong number of visited faces.";
916
917
918 // ====== Edges ======
919
920 int count_edges_iter = 0;
921 for (auto e_it = mesh_.edges_begin(); e_it != mesh_.edges_end(); ++e_it)
922 ++count_edges_iter;
923 EXPECT_EQ(5, count_edges_iter) << "Wrong number of visited edges.";
924
925 int count_edges_skipping_iter = 0;
926 for (auto e_it = mesh_.edges_sbegin(); e_it != mesh_.edges_end(); ++e_it)
927 ++count_edges_skipping_iter;
928 EXPECT_EQ(3, count_edges_skipping_iter) << "Wrong number of visited edges.";
929
930 int count_edges_range = 0;
931 for (auto eh : mesh_.edges())
932 if (eh.is_valid()) // not actually necessary but fixes unused variable warning
933 ++count_edges_range;
934 EXPECT_EQ(3, count_edges_range) << "Wrong number of visited edges.";
935
936 int count_edges_range_all = 0;
937 for (auto eh : mesh_.all_edges())
938 if (eh.is_valid()) // not actually necessary but fixes unused variable warning
939 ++count_edges_range_all;
940 EXPECT_EQ(5, count_edges_range_all) << "Wrong number of visited edges.";
941
942
943 // ====== Halfedges ======
944
945 int count_halfedges_iter = 0;
946 for (auto h_it = mesh_.halfedges_begin(); h_it != mesh_.halfedges_end(); ++h_it)
947 ++count_halfedges_iter;
948 EXPECT_EQ(10, count_halfedges_iter) << "Wrong number of visited halfedges.";
949
950 int count_halfedges_skipping_iter = 0;
951 for (auto h_it = mesh_.halfedges_sbegin(); h_it != mesh_.halfedges_end(); ++h_it)
952 ++count_halfedges_skipping_iter;
953 EXPECT_EQ(6, count_halfedges_skipping_iter) << "Wrong number of visited halfedges.";
954
955 int count_halfedges_range = 0;
956 for (auto heh : mesh_.halfedges())
957 if (heh.is_valid()) // not actually necessary but fixes unused variable warning
958 ++count_halfedges_range;
959 EXPECT_EQ(6, count_halfedges_range) << "Wrong number of visited halfedges.";
960
961 int count_halfedges_range_all = 0;
962 for (auto heh : mesh_.all_halfedges())
963 if (heh.is_valid()) // not actually necessary but fixes unused variable warning
964 ++count_halfedges_range_all;
965 EXPECT_EQ(10, count_halfedges_range_all) << "Wrong number of visited halfedges.";
966
967
968 // ====== Vertices ======
969
970 int count_vertices_iter = 0;
971 for (auto v_it = mesh_.vertices_begin(); v_it != mesh_.vertices_end(); ++v_it)
972 ++count_vertices_iter;
973 EXPECT_EQ(4, count_vertices_iter) << "Wrong number of visited vertices.";
974
975 int count_vertices_skipping_iter = 0;
976 for (auto v_it = mesh_.vertices_sbegin(); v_it != mesh_.vertices_end(); ++v_it)
977 ++count_vertices_skipping_iter;
978 EXPECT_EQ(3, count_vertices_skipping_iter) << "Wrong number of visited vertices.";
979
980 int count_vertices_range = 0;
981 for (auto vh : mesh_.vertices())
982 if (vh.is_valid()) // not actually necessary but fixes unused variable warning
983 ++count_vertices_range;
984 EXPECT_EQ(3, count_vertices_range) << "Wrong number of visited vertices.";
985
986 int count_vertices_range_all = 0;
987 for (auto vh : mesh_.all_vertices())
988 if (vh.is_valid()) // not actually necessary but fixes unused variable warning
989 ++count_vertices_range_all;
990 EXPECT_EQ(4, count_vertices_range_all) << "Wrong number of visited vertices.";
991
992
993 mesh_.release_vertex_status();
994 mesh_.release_edge_status();
995 mesh_.release_halfedge_status();
996 mesh_.release_face_status();
997
998 }
999
1000
1001
1002 }
OpenMesh::VPropHandleT< int >
OpenMesh::PolyMeshT::Point
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:112
OpenMesh::VertexHandle
Handle for a vertex entity.
Definition: Handles.hh:120
OpenMesh::BaseHandle::is_valid
bool is_valid() const
The handle is valid iff the index is not negative.
Definition: Handles.hh:72
test
Definition: minimalExecutionTest.cc:5
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