Developer Documentation
Loading...
Searching...
No Matches
unittests_subdivider_uniform.cc
1
2#include <gtest/gtest.h>
3#include <Unittests/unittests_common.hh>
8#include <OpenMesh/Tools/Subdivider/Uniform/MidpointT.hh>
9
10namespace {
11
12class OpenMeshSubdividerUniform_Poly : public OpenMeshBasePoly {
13protected:
14 // This function is called before each test is run
15 virtual void SetUp() {
16 // Do some initial stuff with the member data here...
17 }
18
19 // This function is called after all tests are through
20 virtual void TearDown() {
21 // Do some final stuff with the member data here...
22 }
23
24 // Member already defined in OpenMeshBase
25 //Mesh mesh_;
26};
27
28class OpenMeshSubdividerUniform_Triangle : public OpenMeshBase {
29protected:
30 // This function is called before each test is run
31 virtual void SetUp() {
32 // Do some initial stuff with the member data here...
33 }
34
35 // This function is called after all tests are through
36 virtual void TearDown() {
37 // Do some final stuff with the member data here...
38 }
39
40 // Member already defined in OpenMeshBase
41 //Mesh mesh_;
42};
43
44/*
45 * ====================================================================
46 * Define tests below
47 * ====================================================================
48 */
49
50TEST_F(OpenMeshSubdividerUniform_Triangle, Subdivider_Sqrt3) {
51 mesh_.clear();
52
53 // Add some vertices
54 Mesh::VertexHandle vhandle[9];
55
56 vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
57 vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
58 vhandle[2] = mesh_.add_vertex(Mesh::Point(0, 2, 0));
59 vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
60 vhandle[4] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
61 vhandle[5] = mesh_.add_vertex(Mesh::Point(1, 2, 0));
62 vhandle[6] = mesh_.add_vertex(Mesh::Point(2, 0, 0));
63 vhandle[7] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
64 vhandle[8] = mesh_.add_vertex(Mesh::Point(2, 2, 0));
65
66 // Add eight faces
67 std::vector<Mesh::VertexHandle> face_vhandles;
68
69 face_vhandles.push_back(vhandle[0]);
70 face_vhandles.push_back(vhandle[4]);
71 face_vhandles.push_back(vhandle[3]);
72
73 mesh_.add_face(face_vhandles);
74 face_vhandles.clear();
75
76 face_vhandles.push_back(vhandle[0]);
77 face_vhandles.push_back(vhandle[1]);
78 face_vhandles.push_back(vhandle[4]);
79
80 mesh_.add_face(face_vhandles);
81 face_vhandles.clear();
82
83 face_vhandles.push_back(vhandle[1]);
84 face_vhandles.push_back(vhandle[2]);
85 face_vhandles.push_back(vhandle[4]);
86
87 mesh_.add_face(face_vhandles);
88 face_vhandles.clear();
89
90 face_vhandles.push_back(vhandle[2]);
91 face_vhandles.push_back(vhandle[5]);
92 face_vhandles.push_back(vhandle[4]);
93
94 mesh_.add_face(face_vhandles);
95 face_vhandles.clear();
96
97 face_vhandles.push_back(vhandle[3]);
98 face_vhandles.push_back(vhandle[7]);
99 face_vhandles.push_back(vhandle[6]);
100
101 mesh_.add_face(face_vhandles);
102 face_vhandles.clear();
103
104 face_vhandles.push_back(vhandle[3]);
105 face_vhandles.push_back(vhandle[4]);
106 face_vhandles.push_back(vhandle[7]);
107
108 mesh_.add_face(face_vhandles);
109 face_vhandles.clear();
110
111 face_vhandles.push_back(vhandle[4]);
112 face_vhandles.push_back(vhandle[8]);
113 face_vhandles.push_back(vhandle[7]);
114
115 mesh_.add_face(face_vhandles);
116 face_vhandles.clear();
117
118 face_vhandles.push_back(vhandle[4]);
119 face_vhandles.push_back(vhandle[5]);
120 face_vhandles.push_back(vhandle[8]);
121
122 mesh_.add_face(face_vhandles);
123
124 // Test setup:
125 // 6 === 7 === 8
126 // | / | / |
127 // | / | / |
128 // | / | / |
129 // 3 === 4 === 5
130 // | / | \ |
131 // | / | \ |
132 // | / | \ |
133 // 0 === 1 === 2
134
135 // Initialize subdivider
137
138 // Check setup
139 EXPECT_EQ(9u, mesh_.n_vertices() ) << "Wrong number of vertices";
140 EXPECT_EQ(8u, mesh_.n_faces() ) << "Wrong number of faces";
141
142 // Execute 3 subdivision steps
143 sqrt3.attach(mesh_);
144 sqrt3( 3 );
145 sqrt3.detach();
146
147 // Check setup
148 EXPECT_EQ(121u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with sqrt3";
149 EXPECT_EQ(216u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with sqrt3";
150}
151
152
153TEST_F(OpenMeshSubdividerUniform_Triangle, Subdivider_Sqrt3_delete_vertex) {
154
155 for (bool collect_garbage : { false, true })
156 {
157 mesh_.clear();
158
159 // Request status flags to use delete and garbage collection
160 mesh_.request_vertex_status();
161 mesh_.request_halfedge_status();
162 mesh_.request_edge_status();
163 mesh_.request_face_status();
164
165 // Add some vertices
166 Mesh::VertexHandle vhandle[9];
167
168 vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
169 vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
170 vhandle[2] = mesh_.add_vertex(Mesh::Point(0, 2, 0));
171 vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
172 vhandle[4] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
173 vhandle[5] = mesh_.add_vertex(Mesh::Point(1, 2, 0));
174 vhandle[6] = mesh_.add_vertex(Mesh::Point(2, 0, 0));
175 vhandle[7] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
176 vhandle[8] = mesh_.add_vertex(Mesh::Point(2, 2, 0));
177
178 // Add eight faces
179 std::vector<Mesh::VertexHandle> face_vhandles;
180
181 face_vhandles.push_back(vhandle[0]);
182 face_vhandles.push_back(vhandle[4]);
183 face_vhandles.push_back(vhandle[3]);
184
185 mesh_.add_face(face_vhandles);
186 face_vhandles.clear();
187
188 face_vhandles.push_back(vhandle[0]);
189 face_vhandles.push_back(vhandle[1]);
190 face_vhandles.push_back(vhandle[4]);
191
192 mesh_.add_face(face_vhandles);
193 face_vhandles.clear();
194
195 face_vhandles.push_back(vhandle[1]);
196 face_vhandles.push_back(vhandle[2]);
197 face_vhandles.push_back(vhandle[4]);
198
199 mesh_.add_face(face_vhandles);
200 face_vhandles.clear();
201
202 face_vhandles.push_back(vhandle[2]);
203 face_vhandles.push_back(vhandle[5]);
204 face_vhandles.push_back(vhandle[4]);
205
206 mesh_.add_face(face_vhandles);
207 face_vhandles.clear();
208
209 face_vhandles.push_back(vhandle[3]);
210 face_vhandles.push_back(vhandle[7]);
211 face_vhandles.push_back(vhandle[6]);
212
213 mesh_.add_face(face_vhandles);
214 face_vhandles.clear();
215
216 face_vhandles.push_back(vhandle[3]);
217 face_vhandles.push_back(vhandle[4]);
218 face_vhandles.push_back(vhandle[7]);
219
220 mesh_.add_face(face_vhandles);
221 face_vhandles.clear();
222
223 face_vhandles.push_back(vhandle[4]);
224 face_vhandles.push_back(vhandle[8]);
225 face_vhandles.push_back(vhandle[7]);
226
227 mesh_.add_face(face_vhandles);
228 face_vhandles.clear();
229
230 face_vhandles.push_back(vhandle[4]);
231 face_vhandles.push_back(vhandle[5]);
232 face_vhandles.push_back(vhandle[8]);
233
234 mesh_.add_face(face_vhandles);
235
236 // Test setup:
237 // 6 === 7 === 8
238 // | / | / |
239 // | / | / |
240 // | / | / |
241 // 3 === 4 === 5
242 // | / | \ |
243 // | / | \ |
244 // | / | \ |
245 // 0 === 1 === 2
246
247 // Delete one vertex
248 mesh_.delete_vertex(vhandle[1]);
249 // Check setup
250 if (collect_garbage)
251 {
252 mesh_.garbage_collection();
253 EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong number of vertices";
254 EXPECT_EQ(6u, mesh_.n_faces() ) << "Wrong number of faces";
255 }
256 else
257 {
258 EXPECT_EQ(9u, mesh_.n_vertices() ) << "Wrong number of vertices";
259 EXPECT_EQ(8u, mesh_.n_faces() ) << "Wrong number of faces";
260 }
261
262
263 // Initialize subdivider
265
266
267 // Execute 3 subdivision steps
268 sqrt3.attach(mesh_);
269 sqrt3( 3 );
270 sqrt3.detach();
271
272 if (!collect_garbage)
273 mesh_.garbage_collection(); // if we did not collect garbage before, do so now
274
275 // Check setup
276 EXPECT_EQ(94u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with sqrt3";
277 EXPECT_EQ(162u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with sqrt3";
278 }
279}
280
281
282TEST_F(OpenMeshSubdividerUniform_Triangle, Subdivider_Loop) {
283 mesh_.clear();
284
285 // Add some vertices
286 Mesh::VertexHandle vhandle[9];
287
288 vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
289 vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
290 vhandle[2] = mesh_.add_vertex(Mesh::Point(0, 2, 0));
291 vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
292 vhandle[4] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
293 vhandle[5] = mesh_.add_vertex(Mesh::Point(1, 2, 0));
294 vhandle[6] = mesh_.add_vertex(Mesh::Point(2, 0, 0));
295 vhandle[7] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
296 vhandle[8] = mesh_.add_vertex(Mesh::Point(2, 2, 0));
297
298 // Add eight faces
299 std::vector<Mesh::VertexHandle> face_vhandles;
300
301 face_vhandles.push_back(vhandle[0]);
302 face_vhandles.push_back(vhandle[4]);
303 face_vhandles.push_back(vhandle[3]);
304
305 mesh_.add_face(face_vhandles);
306 face_vhandles.clear();
307
308 face_vhandles.push_back(vhandle[0]);
309 face_vhandles.push_back(vhandle[1]);
310 face_vhandles.push_back(vhandle[4]);
311
312 mesh_.add_face(face_vhandles);
313 face_vhandles.clear();
314
315 face_vhandles.push_back(vhandle[1]);
316 face_vhandles.push_back(vhandle[2]);
317 face_vhandles.push_back(vhandle[4]);
318
319 mesh_.add_face(face_vhandles);
320 face_vhandles.clear();
321
322 face_vhandles.push_back(vhandle[2]);
323 face_vhandles.push_back(vhandle[5]);
324 face_vhandles.push_back(vhandle[4]);
325
326 mesh_.add_face(face_vhandles);
327 face_vhandles.clear();
328
329 face_vhandles.push_back(vhandle[3]);
330 face_vhandles.push_back(vhandle[7]);
331 face_vhandles.push_back(vhandle[6]);
332
333 mesh_.add_face(face_vhandles);
334 face_vhandles.clear();
335
336 face_vhandles.push_back(vhandle[3]);
337 face_vhandles.push_back(vhandle[4]);
338 face_vhandles.push_back(vhandle[7]);
339
340 mesh_.add_face(face_vhandles);
341 face_vhandles.clear();
342
343 face_vhandles.push_back(vhandle[4]);
344 face_vhandles.push_back(vhandle[8]);
345 face_vhandles.push_back(vhandle[7]);
346
347 mesh_.add_face(face_vhandles);
348 face_vhandles.clear();
349
350 face_vhandles.push_back(vhandle[4]);
351 face_vhandles.push_back(vhandle[5]);
352 face_vhandles.push_back(vhandle[8]);
353
354 mesh_.add_face(face_vhandles);
355
356 // Test setup:
357 // 6 === 7 === 8
358 // | / | / |
359 // | / | / |
360 // | / | / |
361 // 3 === 4 === 5
362 // | / | \ |
363 // | / | \ |
364 // | / | \ |
365 // 0 === 1 === 2
366
367 // Initialize subdivider
369
370 // Check setup
371 EXPECT_EQ(9u, mesh_.n_vertices() ) << "Wrong number of vertices";
372 EXPECT_EQ(8u, mesh_.n_faces() ) << "Wrong number of faces";
373
374 // Execute 3 subdivision steps
375 loop.attach(mesh_);
376 loop( 3 );
377 loop.detach();
378
379 // Check setup
380 EXPECT_EQ(289u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with loop";
381 EXPECT_EQ(512u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with loop";
382}
383
384
385
386TEST_F(OpenMeshSubdividerUniform_Triangle, Subdivider_Loop_delete_vertex) {
387
388 for (bool collect_garbage : { false, true })
389 {
390 mesh_.clear();
391
392 // Request status flags to use delete and garbage collection
393 mesh_.request_vertex_status();
394 mesh_.request_halfedge_status();
395 mesh_.request_edge_status();
396 mesh_.request_face_status();
397
398 // Add some vertices
399 Mesh::VertexHandle vhandle[9];
400
401 vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
402 vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
403 vhandle[2] = mesh_.add_vertex(Mesh::Point(0, 2, 0));
404 vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
405 vhandle[4] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
406 vhandle[5] = mesh_.add_vertex(Mesh::Point(1, 2, 0));
407 vhandle[6] = mesh_.add_vertex(Mesh::Point(2, 0, 0));
408 vhandle[7] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
409 vhandle[8] = mesh_.add_vertex(Mesh::Point(2, 2, 0));
410
411 // Add eight faces
412 std::vector<Mesh::VertexHandle> face_vhandles;
413
414 face_vhandles.push_back(vhandle[0]);
415 face_vhandles.push_back(vhandle[4]);
416 face_vhandles.push_back(vhandle[3]);
417
418 mesh_.add_face(face_vhandles);
419 face_vhandles.clear();
420
421 face_vhandles.push_back(vhandle[0]);
422 face_vhandles.push_back(vhandle[1]);
423 face_vhandles.push_back(vhandle[4]);
424
425 mesh_.add_face(face_vhandles);
426 face_vhandles.clear();
427
428 face_vhandles.push_back(vhandle[1]);
429 face_vhandles.push_back(vhandle[2]);
430 face_vhandles.push_back(vhandle[4]);
431
432 mesh_.add_face(face_vhandles);
433 face_vhandles.clear();
434
435 face_vhandles.push_back(vhandle[2]);
436 face_vhandles.push_back(vhandle[5]);
437 face_vhandles.push_back(vhandle[4]);
438
439 mesh_.add_face(face_vhandles);
440 face_vhandles.clear();
441
442 face_vhandles.push_back(vhandle[3]);
443 face_vhandles.push_back(vhandle[7]);
444 face_vhandles.push_back(vhandle[6]);
445
446 mesh_.add_face(face_vhandles);
447 face_vhandles.clear();
448
449 face_vhandles.push_back(vhandle[3]);
450 face_vhandles.push_back(vhandle[4]);
451 face_vhandles.push_back(vhandle[7]);
452
453 mesh_.add_face(face_vhandles);
454 face_vhandles.clear();
455
456 face_vhandles.push_back(vhandle[4]);
457 face_vhandles.push_back(vhandle[8]);
458 face_vhandles.push_back(vhandle[7]);
459
460 mesh_.add_face(face_vhandles);
461 face_vhandles.clear();
462
463 face_vhandles.push_back(vhandle[4]);
464 face_vhandles.push_back(vhandle[5]);
465 face_vhandles.push_back(vhandle[8]);
466
467 mesh_.add_face(face_vhandles);
468
469 // Test setup:
470 // 6 === 7 === 8
471 // | / | / |
472 // | / | / |
473 // | / | / |
474 // 3 === 4 === 5
475 // | / | \ |
476 // | / | \ |
477 // | / | \ |
478 // 0 === 1 === 2
479
480 // Delete one vertex
481 mesh_.delete_vertex(vhandle[1]);
482 if (collect_garbage)
483 {
484 mesh_.garbage_collection();
485 // Check setup
486 EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong number of vertices";
487 EXPECT_EQ(6u, mesh_.n_faces() ) << "Wrong number of faces";
488 }
489 else
490 {
491 // Check setup
492 EXPECT_EQ(9u, mesh_.n_vertices() ) << "Wrong number of vertices";
493 EXPECT_EQ(8u, mesh_.n_faces() ) << "Wrong number of faces";
494 }
495
496 // Initialize subdivider
498
499
500 // Execute 3 subdivision steps
501 loop.attach(mesh_);
502 loop( 3 );
503 loop.detach();
504
505 if (!collect_garbage)
506 mesh_.garbage_collection(); // if we did not collect garbage before, do so now
507
508 // Check setup
509 EXPECT_EQ(225u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with loop";
510 EXPECT_EQ(384u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with loop";
511
512 }
513}
514
515
516
517/*
518 * ====================================================================
519 * Define tests below
520 * ====================================================================
521 */
522
523/*
524 */
525TEST_F(OpenMeshSubdividerUniform_Poly, Subdivider_CatmullClark) {
526 mesh_.clear();
527
528 // Add some vertices
529 Mesh::VertexHandle vhandle[9];
530
531 vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
532 vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
533 vhandle[2] = mesh_.add_vertex(Mesh::Point(0, 2, 0));
534 vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
535 vhandle[4] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
536 vhandle[5] = mesh_.add_vertex(Mesh::Point(1, 2, 0));
537 vhandle[6] = mesh_.add_vertex(Mesh::Point(2, 0, 0));
538 vhandle[7] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
539 vhandle[8] = mesh_.add_vertex(Mesh::Point(2, 2, 0));
540
541 // Add four faces
542 std::vector<Mesh::VertexHandle> face_vhandles;
543
544 face_vhandles.push_back(vhandle[0]);
545 face_vhandles.push_back(vhandle[1]);
546 face_vhandles.push_back(vhandle[4]);
547 face_vhandles.push_back(vhandle[3]);
548
549 mesh_.add_face(face_vhandles);
550 face_vhandles.clear();
551
552 face_vhandles.push_back(vhandle[1]);
553 face_vhandles.push_back(vhandle[2]);
554 face_vhandles.push_back(vhandle[5]);
555 face_vhandles.push_back(vhandle[4]);
556
557 mesh_.add_face(face_vhandles);
558 face_vhandles.clear();
559
560 face_vhandles.push_back(vhandle[4]);
561 face_vhandles.push_back(vhandle[5]);
562 face_vhandles.push_back(vhandle[8]);
563 face_vhandles.push_back(vhandle[7]);
564
565 mesh_.add_face(face_vhandles);
566 face_vhandles.clear();
567
568 face_vhandles.push_back(vhandle[3]);
569 face_vhandles.push_back(vhandle[4]);
570 face_vhandles.push_back(vhandle[7]);
571 face_vhandles.push_back(vhandle[6]);
572
573 mesh_.add_face(face_vhandles);
574
575 // Test setup:
576 // 6 === 7 === 8
577 // | | |
578 // | | |
579 // | | |
580 // 3 === 4 === 5
581 // | | |
582 // | | |
583 // | | |
584 // 0 === 1 === 2
585
586 // Initialize subdivider
588
589 // Check setup
590 EXPECT_EQ(9u, mesh_.n_vertices() ) << "Wrong number of vertices";
591 EXPECT_EQ(4u, mesh_.n_faces() ) << "Wrong number of faces";
592
593 // Execute 3 subdivision steps
594 catmull.attach(mesh_);
595 catmull( 3 );
596 catmull.detach();
597
598 EXPECT_EQ(289u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with catmull clark";
599 EXPECT_EQ(256u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with catmull clark";
600}
601
602
603TEST_F(OpenMeshSubdividerUniform_Poly, Subdivider_CatmullClark_delete_vertex) {
604
605 for (bool collect_garbage : { false, true })
606 {
607 mesh_.clear();
608
609 // Request status flags to use delete and garbage collection
610 mesh_.request_vertex_status();
611 mesh_.request_halfedge_status();
612 mesh_.request_edge_status();
613 mesh_.request_face_status();
614
615 // Add some vertices
616 Mesh::VertexHandle vhandle[9];
617
618 vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
619 vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
620 vhandle[2] = mesh_.add_vertex(Mesh::Point(0, 2, 0));
621 vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
622 vhandle[4] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
623 vhandle[5] = mesh_.add_vertex(Mesh::Point(1, 2, 0));
624 vhandle[6] = mesh_.add_vertex(Mesh::Point(2, 0, 0));
625 vhandle[7] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
626 vhandle[8] = mesh_.add_vertex(Mesh::Point(2, 2, 0));
627
628 // Add four faces
629 std::vector<Mesh::VertexHandle> face_vhandles;
630
631 face_vhandles.push_back(vhandle[0]);
632 face_vhandles.push_back(vhandle[1]);
633 face_vhandles.push_back(vhandle[4]);
634 face_vhandles.push_back(vhandle[3]);
635
636 mesh_.add_face(face_vhandles);
637 face_vhandles.clear();
638
639 face_vhandles.push_back(vhandle[1]);
640 face_vhandles.push_back(vhandle[2]);
641 face_vhandles.push_back(vhandle[5]);
642 face_vhandles.push_back(vhandle[4]);
643
644 mesh_.add_face(face_vhandles);
645 face_vhandles.clear();
646
647 face_vhandles.push_back(vhandle[4]);
648 face_vhandles.push_back(vhandle[5]);
649 face_vhandles.push_back(vhandle[8]);
650 face_vhandles.push_back(vhandle[7]);
651
652 mesh_.add_face(face_vhandles);
653 face_vhandles.clear();
654
655 face_vhandles.push_back(vhandle[3]);
656 face_vhandles.push_back(vhandle[4]);
657 face_vhandles.push_back(vhandle[7]);
658 face_vhandles.push_back(vhandle[6]);
659
660 mesh_.add_face(face_vhandles);
661
662 // Test setup:
663 // 6 === 7 === 8
664 // | | |
665 // | | |
666 // | | |
667 // 3 === 4 === 5
668 // | | |
669 // | | |
670 // | | |
671 // 0 === 1 === 2
672
673
674 mesh_.delete_vertex(vhandle[1]);
675 // Check setup
676 if (collect_garbage)
677 {
678 mesh_.garbage_collection();
679 EXPECT_EQ(6u, mesh_.n_vertices() ) << "Wrong number of vertices";
680 EXPECT_EQ(2u, mesh_.n_faces() ) << "Wrong number of faces";
681 }
682 else
683 {
684 EXPECT_EQ(9u, mesh_.n_vertices() ) << "Wrong number of vertices";
685 EXPECT_EQ(4u, mesh_.n_faces() ) << "Wrong number of faces";
686 }
687
688 // Initialize subdivider
690
691 // Execute 3 subdivision steps
692 catmull.attach(mesh_);
693 catmull( 3 );
694 catmull.detach();
695
696 if (!collect_garbage)
697 mesh_.garbage_collection(); // if we did not collect garbage before, do so now
698
699 EXPECT_EQ(153u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with catmull clark";
700 EXPECT_EQ(128u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with catmull clark";
701 }
702}
703
704/* Adds a cube to a polymesh
705 */
706TEST_F(OpenMeshSubdividerUniform_Poly, Midpoint) {
707 mesh_.clear();
708
709 // Add some vertices
710 Mesh::VertexHandle vhandle[8];
711 vhandle[0] = mesh_.add_vertex(PolyMesh::Point(-1, -1, 1));
712 vhandle[1] = mesh_.add_vertex(PolyMesh::Point( 1, -1, 1));
713 vhandle[2] = mesh_.add_vertex(PolyMesh::Point( 1, 1, 1));
714 vhandle[3] = mesh_.add_vertex(PolyMesh::Point(-1, 1, 1));
715 vhandle[4] = mesh_.add_vertex(PolyMesh::Point(-1, -1, -1));
716 vhandle[5] = mesh_.add_vertex(PolyMesh::Point( 1, -1, -1));
717 vhandle[6] = mesh_.add_vertex(PolyMesh::Point( 1, 1, -1));
718 vhandle[7] = mesh_.add_vertex(PolyMesh::Point(-1, 1, -1));
719
720 // Add six faces to form a cube
721 std::vector<Mesh::VertexHandle> face_vhandles;
722
723 face_vhandles.clear();
724 face_vhandles.push_back(vhandle[0]);
725 face_vhandles.push_back(vhandle[1]);
726 face_vhandles.push_back(vhandle[2]);
727 face_vhandles.push_back(vhandle[3]);
728 mesh_.add_face(face_vhandles);
729
730 face_vhandles.clear();
731 face_vhandles.push_back(vhandle[7]);
732 face_vhandles.push_back(vhandle[6]);
733 face_vhandles.push_back(vhandle[5]);
734 face_vhandles.push_back(vhandle[4]);
735 mesh_.add_face(face_vhandles);
736
737 face_vhandles.clear();
738 face_vhandles.push_back(vhandle[1]);
739 face_vhandles.push_back(vhandle[0]);
740 face_vhandles.push_back(vhandle[4]);
741 face_vhandles.push_back(vhandle[5]);
742 mesh_.add_face(face_vhandles);
743
744 face_vhandles.clear();
745 face_vhandles.push_back(vhandle[2]);
746 face_vhandles.push_back(vhandle[1]);
747 face_vhandles.push_back(vhandle[5]);
748 face_vhandles.push_back(vhandle[6]);
749 mesh_.add_face(face_vhandles);
750
751 face_vhandles.clear();
752 face_vhandles.push_back(vhandle[3]);
753 face_vhandles.push_back(vhandle[2]);
754 face_vhandles.push_back(vhandle[6]);
755 face_vhandles.push_back(vhandle[7]);
756 mesh_.add_face(face_vhandles);
757
758 face_vhandles.clear();
759 face_vhandles.push_back(vhandle[0]);
760 face_vhandles.push_back(vhandle[3]);
761 face_vhandles.push_back(vhandle[7]);
762 face_vhandles.push_back(vhandle[4]);
763 mesh_.add_face(face_vhandles);
764
765
766 // Test setup:
767 //
768 //
769 // 3 ======== 2
770 // / /|
771 // / / | z
772 // 0 ======== 1 | |
773 // | | | | y
774 // | 7 | 6 | /
775 // | | / | /
776 // | |/ |/
777 // 4 ======== 5 -------> x
778 //
779
780 // Check setup
781 EXPECT_EQ(12u, mesh_.n_edges()) << "Wrong number of Edges";
782 EXPECT_EQ(24u, mesh_.n_halfedges()) << "Wrong number of HalfEdges";
783 EXPECT_EQ(8u, mesh_.n_vertices()) << "Wrong number of vertices";
784 EXPECT_EQ(6u, mesh_.n_faces()) << "Wrong number of faces";
785
786 // Initialize subdivider
788
789 // Execute 2 subdivision steps
790 midpoint.attach(mesh_);
791 midpoint(2);
792 midpoint.detach();
793
794 // Check Result
795 EXPECT_EQ(48u, mesh_.n_edges()) << "Wrong number of Edges";
796 EXPECT_EQ(96u, mesh_.n_halfedges()) << "Wrong number of HalfEdges";
797 EXPECT_EQ(24u, mesh_.n_vertices()) << "Wrong number of vertices";
798 EXPECT_EQ(26u, mesh_.n_faces()) << "Wrong number of faces";
799}
800
801
802TEST_F(OpenMeshSubdividerUniform_Poly, Midpoint_delete_vertex) {
803
804 for (bool collect_garbage : { false, true })
805 {
806 mesh_.clear();
807
808 // Request status flags to use delete and garbage collection
809 mesh_.request_vertex_status();
810 mesh_.request_halfedge_status();
811 mesh_.request_edge_status();
812 mesh_.request_face_status();
813
814 // Add some vertices
815 Mesh::VertexHandle vhandle[8];
816 vhandle[0] = mesh_.add_vertex(PolyMesh::Point(-1, -1, 1));
817 vhandle[1] = mesh_.add_vertex(PolyMesh::Point( 1, -1, 1));
818 vhandle[2] = mesh_.add_vertex(PolyMesh::Point( 1, 1, 1));
819 vhandle[3] = mesh_.add_vertex(PolyMesh::Point(-1, 1, 1));
820 vhandle[4] = mesh_.add_vertex(PolyMesh::Point(-1, -1, -1));
821 vhandle[5] = mesh_.add_vertex(PolyMesh::Point( 1, -1, -1));
822 vhandle[6] = mesh_.add_vertex(PolyMesh::Point( 1, 1, -1));
823 vhandle[7] = mesh_.add_vertex(PolyMesh::Point(-1, 1, -1));
824
825 // Add six faces to form a cube
826 std::vector<Mesh::VertexHandle> face_vhandles;
827
828 face_vhandles.clear();
829 face_vhandles.push_back(vhandle[0]);
830 face_vhandles.push_back(vhandle[1]);
831 face_vhandles.push_back(vhandle[2]);
832 face_vhandles.push_back(vhandle[3]);
833 mesh_.add_face(face_vhandles);
834
835 face_vhandles.clear();
836 face_vhandles.push_back(vhandle[7]);
837 face_vhandles.push_back(vhandle[6]);
838 face_vhandles.push_back(vhandle[5]);
839 face_vhandles.push_back(vhandle[4]);
840 mesh_.add_face(face_vhandles);
841
842 face_vhandles.clear();
843 face_vhandles.push_back(vhandle[1]);
844 face_vhandles.push_back(vhandle[0]);
845 face_vhandles.push_back(vhandle[4]);
846 face_vhandles.push_back(vhandle[5]);
847 mesh_.add_face(face_vhandles);
848
849 face_vhandles.clear();
850 face_vhandles.push_back(vhandle[2]);
851 face_vhandles.push_back(vhandle[1]);
852 face_vhandles.push_back(vhandle[5]);
853 face_vhandles.push_back(vhandle[6]);
854 mesh_.add_face(face_vhandles);
855
856 face_vhandles.clear();
857 face_vhandles.push_back(vhandle[3]);
858 face_vhandles.push_back(vhandle[2]);
859 face_vhandles.push_back(vhandle[6]);
860 face_vhandles.push_back(vhandle[7]);
861 mesh_.add_face(face_vhandles);
862
863 face_vhandles.clear();
864 face_vhandles.push_back(vhandle[0]);
865 face_vhandles.push_back(vhandle[3]);
866 face_vhandles.push_back(vhandle[7]);
867 face_vhandles.push_back(vhandle[4]);
868 mesh_.add_face(face_vhandles);
869
870
871 // Test setup:
872 //
873 //
874 // 3 ======== 2
875 // / /|
876 // / / | z
877 // 0 ======== 1 | |
878 // | | | | y
879 // | 7 | 6 | /
880 // | | / | /
881 // | |/ |/
882 // 4 ======== 5 -------> x
883 //
884
885 mesh_.delete_vertex(vhandle[1]);
886 // Check setup
887 if (collect_garbage)
888 {
889 mesh_.garbage_collection();
890 EXPECT_EQ(9u, mesh_.n_edges()) << "Wrong number of Edges";
891 EXPECT_EQ(18u, mesh_.n_halfedges()) << "Wrong number of HalfEdges";
892 EXPECT_EQ(7u, mesh_.n_vertices()) << "Wrong number of vertices";
893 EXPECT_EQ(3u, mesh_.n_faces()) << "Wrong number of faces";
894 }
895 else
896 {
897 EXPECT_EQ(12u, mesh_.n_edges()) << "Wrong number of Edges";
898 EXPECT_EQ(24u, mesh_.n_halfedges()) << "Wrong number of HalfEdges";
899 EXPECT_EQ(8u, mesh_.n_vertices()) << "Wrong number of vertices";
900 EXPECT_EQ(6u, mesh_.n_faces()) << "Wrong number of faces";
901 }
902
903 // Check setup
904
905 // Initialize subdivider
907
908 // Execute 2 subdivision steps
909 midpoint.attach(mesh_);
910 midpoint(2);
911 midpoint.detach();
912
913 if (!collect_garbage)
914 mesh_.garbage_collection(); // if we did not collect garbage before, do so now
915
916 // Check Result
917 EXPECT_EQ(15u, mesh_.n_edges()) << "Wrong number of Edges";
918 EXPECT_EQ(30u, mesh_.n_halfedges()) << "Wrong number of HalfEdges";
919 EXPECT_EQ(12u, mesh_.n_vertices()) << "Wrong number of vertices";
920 EXPECT_EQ(4u, mesh_.n_faces()) << "Wrong number of faces";
921 }
922}
923
924
925
926TEST_F(OpenMeshSubdividerUniform_Triangle, Modified_Butterfly) {
927 mesh_.clear();
928
929 // Add some vertices
930 Mesh::VertexHandle vhandle[9];
931
932 vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
933 vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
934 vhandle[2] = mesh_.add_vertex(Mesh::Point(0, 2, 0));
935 vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
936 vhandle[4] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
937 vhandle[5] = mesh_.add_vertex(Mesh::Point(1, 2, 0));
938 vhandle[6] = mesh_.add_vertex(Mesh::Point(2, 0, 0));
939 vhandle[7] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
940 vhandle[8] = mesh_.add_vertex(Mesh::Point(2, 2, 0));
941
942 // Add eight faces
943 std::vector<Mesh::VertexHandle> face_vhandles;
944
945 face_vhandles.push_back(vhandle[0]);
946 face_vhandles.push_back(vhandle[4]);
947 face_vhandles.push_back(vhandle[3]);
948
949 mesh_.add_face(face_vhandles);
950 face_vhandles.clear();
951
952 face_vhandles.push_back(vhandle[0]);
953 face_vhandles.push_back(vhandle[1]);
954 face_vhandles.push_back(vhandle[4]);
955
956 mesh_.add_face(face_vhandles);
957 face_vhandles.clear();
958
959 face_vhandles.push_back(vhandle[1]);
960 face_vhandles.push_back(vhandle[2]);
961 face_vhandles.push_back(vhandle[4]);
962
963 mesh_.add_face(face_vhandles);
964 face_vhandles.clear();
965
966 face_vhandles.push_back(vhandle[2]);
967 face_vhandles.push_back(vhandle[5]);
968 face_vhandles.push_back(vhandle[4]);
969
970 mesh_.add_face(face_vhandles);
971 face_vhandles.clear();
972
973 face_vhandles.push_back(vhandle[3]);
974 face_vhandles.push_back(vhandle[7]);
975 face_vhandles.push_back(vhandle[6]);
976
977 mesh_.add_face(face_vhandles);
978 face_vhandles.clear();
979
980 face_vhandles.push_back(vhandle[3]);
981 face_vhandles.push_back(vhandle[4]);
982 face_vhandles.push_back(vhandle[7]);
983
984 mesh_.add_face(face_vhandles);
985 face_vhandles.clear();
986
987 face_vhandles.push_back(vhandle[4]);
988 face_vhandles.push_back(vhandle[8]);
989 face_vhandles.push_back(vhandle[7]);
990
991 mesh_.add_face(face_vhandles);
992 face_vhandles.clear();
993
994 face_vhandles.push_back(vhandle[4]);
995 face_vhandles.push_back(vhandle[5]);
996 face_vhandles.push_back(vhandle[8]);
997
998 mesh_.add_face(face_vhandles);
999
1000 // Test setup:
1001 // 6 === 7 === 8
1002 // | / | / |
1003 // | / | / |
1004 // | / | / |
1005 // 3 === 4 === 5
1006 // | / | \ |
1007 // | / | \ |
1008 // | / | \ |
1009 // 0 === 1 === 2
1010
1011 // Initialize subdivider
1013
1014 // Check setup
1015 EXPECT_EQ(9u, mesh_.n_vertices() ) << "Wrong number of vertices";
1016 EXPECT_EQ(8u, mesh_.n_faces() ) << "Wrong number of faces";
1017
1018 // Execute 3 subdivision steps
1019 butter.attach(mesh_);
1020 butter( 3 );
1021 butter.detach();
1022
1023 // Check setup
1024 EXPECT_EQ(289u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with loop";
1025 EXPECT_EQ(512u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with loop";
1026}
1027
1028
1029
1030TEST_F(OpenMeshSubdividerUniform_Triangle, Modified_Butterfly_cylinder) {
1031 mesh_.clear();
1032
1033 OpenMesh::IO::read_mesh(mesh_, "cylinder.om");
1034
1035 // Initialize subdivider
1037
1038 // Check setup
1039 EXPECT_EQ(66u, mesh_.n_vertices() ) << "Wrong number of vertices";
1040 EXPECT_EQ(128u, mesh_.n_faces() ) << "Wrong number of faces";
1041
1042 // Execute 3 subdivision steps
1043 butter( mesh_,3,true );
1044
1045 // Check setup
1046 EXPECT_EQ(4098u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with loop";
1047 EXPECT_EQ(8192u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with loop";
1048}
1049
1050
1051
1052TEST_F(OpenMeshSubdividerUniform_Triangle, Modified_Butterfly_delete_vertex) {
1053
1054 for (bool collect_garbage : { false, true })
1055 {
1056 mesh_.clear();
1057
1058 // Request status flags to use delete and garbage collection
1059 mesh_.request_vertex_status();
1060 mesh_.request_halfedge_status();
1061 mesh_.request_edge_status();
1062 mesh_.request_face_status();
1063
1064 // Add some vertices
1065 Mesh::VertexHandle vhandle[9];
1066
1067 vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
1068 vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
1069 vhandle[2] = mesh_.add_vertex(Mesh::Point(0, 2, 0));
1070 vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
1071 vhandle[4] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
1072 vhandle[5] = mesh_.add_vertex(Mesh::Point(1, 2, 0));
1073 vhandle[6] = mesh_.add_vertex(Mesh::Point(2, 0, 0));
1074 vhandle[7] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
1075 vhandle[8] = mesh_.add_vertex(Mesh::Point(2, 2, 0));
1076
1077 // Add eight faces
1078 std::vector<Mesh::VertexHandle> face_vhandles;
1079
1080 face_vhandles.push_back(vhandle[0]);
1081 face_vhandles.push_back(vhandle[4]);
1082 face_vhandles.push_back(vhandle[3]);
1083
1084 mesh_.add_face(face_vhandles);
1085 face_vhandles.clear();
1086
1087 face_vhandles.push_back(vhandle[0]);
1088 face_vhandles.push_back(vhandle[1]);
1089 face_vhandles.push_back(vhandle[4]);
1090
1091 mesh_.add_face(face_vhandles);
1092 face_vhandles.clear();
1093
1094 face_vhandles.push_back(vhandle[1]);
1095 face_vhandles.push_back(vhandle[2]);
1096 face_vhandles.push_back(vhandle[4]);
1097
1098 mesh_.add_face(face_vhandles);
1099 face_vhandles.clear();
1100
1101 face_vhandles.push_back(vhandle[2]);
1102 face_vhandles.push_back(vhandle[5]);
1103 face_vhandles.push_back(vhandle[4]);
1104
1105 mesh_.add_face(face_vhandles);
1106 face_vhandles.clear();
1107
1108 face_vhandles.push_back(vhandle[3]);
1109 face_vhandles.push_back(vhandle[7]);
1110 face_vhandles.push_back(vhandle[6]);
1111
1112 mesh_.add_face(face_vhandles);
1113 face_vhandles.clear();
1114
1115 face_vhandles.push_back(vhandle[3]);
1116 face_vhandles.push_back(vhandle[4]);
1117 face_vhandles.push_back(vhandle[7]);
1118
1119 mesh_.add_face(face_vhandles);
1120 face_vhandles.clear();
1121
1122 face_vhandles.push_back(vhandle[4]);
1123 face_vhandles.push_back(vhandle[8]);
1124 face_vhandles.push_back(vhandle[7]);
1125
1126 mesh_.add_face(face_vhandles);
1127 face_vhandles.clear();
1128
1129 face_vhandles.push_back(vhandle[4]);
1130 face_vhandles.push_back(vhandle[5]);
1131 face_vhandles.push_back(vhandle[8]);
1132
1133 mesh_.add_face(face_vhandles);
1134
1135 // Test setup:
1136 // 6 === 7 === 8
1137 // | / | / |
1138 // | / | / |
1139 // | / | / |
1140 // 3 === 4 === 5
1141 // | / | \ |
1142 // | / | \ |
1143 // | / | \ |
1144 // 0 === 1 === 2
1145
1146
1147 // Delete one vertex
1148 mesh_.delete_vertex(vhandle[1]);
1149 // Check setup
1150 if (collect_garbage)
1151 {
1152 mesh_.garbage_collection();
1153 EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong number of vertices";
1154 EXPECT_EQ(6u, mesh_.n_faces() ) << "Wrong number of faces";
1155 }
1156 else
1157 {
1158 EXPECT_EQ(9u, mesh_.n_vertices() ) << "Wrong number of vertices";
1159 EXPECT_EQ(8u, mesh_.n_faces() ) << "Wrong number of faces";
1160 }
1161
1162 // Initialize subdivider
1164
1165
1166 // Execute 3 subdivision steps
1167 butter.attach(mesh_);
1168 butter( 3 );
1169 butter.detach();
1170
1171 if (!collect_garbage)
1172 mesh_.garbage_collection(); // if we did not collect garbage before, do so now
1173
1174 // Check setup
1175 EXPECT_EQ(225u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with butter";
1176 EXPECT_EQ(384u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with butter";
1177 }
1178}
1179
1180
1181
1182
1183}
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition PolyMeshT.hh:136
SmartVertexHandle add_vertex(const Point _p)
Definition PolyMeshT.hh:255
Kernel::Point Point
Coordinate type.
Definition PolyMeshT.hh:112
bool read_mesh(Mesh &_mesh, const std::string &_filename)
Read a mesh from file _filename.
Definition MeshIO.hh:95