Developer Documentation

unittests_subdivider_uniform.cc
1
2 #include <gtest/gtest.h>
3 #include <Unittests/unittests_common.hh>
4 #include <OpenMesh/Tools/Subdivider/Uniform/ModifiedButterFlyT.hh>
5 #include <OpenMesh/Tools/Subdivider/Uniform/CatmullClarkT.hh>
6 #include <OpenMesh/Tools/Subdivider/Uniform/LoopT.hh>
7 #include <OpenMesh/Tools/Subdivider/Uniform/Sqrt3T.hh>
8 #include <OpenMesh/Tools/Subdivider/Uniform/MidpointT.hh>
9
10 namespace {
11
12 class OpenMeshSubdividerUniform_Poly : public OpenMeshBasePoly {
13 protected:
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
28 class OpenMeshSubdividerUniform_Triangle : public OpenMeshBase {
29 protected:
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
50 TEST_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
136 OpenMesh::Subdivider::Uniform::Sqrt3T<Mesh> sqrt3;
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
153 TEST_F(OpenMeshSubdividerUniform_Triangle, Subdivider_Loop) {
154 mesh_.clear();
155
156 // Add some vertices
157 Mesh::VertexHandle vhandle[9];
158
159 vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
160 vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
161 vhandle[2] = mesh_.add_vertex(Mesh::Point(0, 2, 0));
162 vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
163 vhandle[4] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
164 vhandle[5] = mesh_.add_vertex(Mesh::Point(1, 2, 0));
165 vhandle[6] = mesh_.add_vertex(Mesh::Point(2, 0, 0));
166 vhandle[7] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
167 vhandle[8] = mesh_.add_vertex(Mesh::Point(2, 2, 0));
168
169 // Add eight faces
170 std::vector<Mesh::VertexHandle> face_vhandles;
171
172 face_vhandles.push_back(vhandle[0]);
173 face_vhandles.push_back(vhandle[4]);
174 face_vhandles.push_back(vhandle[3]);
175
176 mesh_.add_face(face_vhandles);
177 face_vhandles.clear();
178
179 face_vhandles.push_back(vhandle[0]);
180 face_vhandles.push_back(vhandle[1]);
181 face_vhandles.push_back(vhandle[4]);
182
183 mesh_.add_face(face_vhandles);
184 face_vhandles.clear();
185
186 face_vhandles.push_back(vhandle[1]);
187 face_vhandles.push_back(vhandle[2]);
188 face_vhandles.push_back(vhandle[4]);
189
190 mesh_.add_face(face_vhandles);
191 face_vhandles.clear();
192
193 face_vhandles.push_back(vhandle[2]);
194 face_vhandles.push_back(vhandle[5]);
195 face_vhandles.push_back(vhandle[4]);
196
197 mesh_.add_face(face_vhandles);
198 face_vhandles.clear();
199
200 face_vhandles.push_back(vhandle[3]);
201 face_vhandles.push_back(vhandle[7]);
202 face_vhandles.push_back(vhandle[6]);
203
204 mesh_.add_face(face_vhandles);
205 face_vhandles.clear();
206
207 face_vhandles.push_back(vhandle[3]);
208 face_vhandles.push_back(vhandle[4]);
209 face_vhandles.push_back(vhandle[7]);
210
211 mesh_.add_face(face_vhandles);
212 face_vhandles.clear();
213
214 face_vhandles.push_back(vhandle[4]);
215 face_vhandles.push_back(vhandle[8]);
216 face_vhandles.push_back(vhandle[7]);
217
218 mesh_.add_face(face_vhandles);
219 face_vhandles.clear();
220
221 face_vhandles.push_back(vhandle[4]);
222 face_vhandles.push_back(vhandle[5]);
223 face_vhandles.push_back(vhandle[8]);
224
225 mesh_.add_face(face_vhandles);
226
227 // Test setup:
228 // 6 === 7 === 8
229 // | / | / |
230 // | / | / |
231 // | / | / |
232 // 3 === 4 === 5
233 // | / | \ |
234 // | / | \ |
235 // | / | \ |
236 // 0 === 1 === 2
237
238 // Initialize subdivider
239 OpenMesh::Subdivider::Uniform::LoopT<Mesh> loop;
240
241 // Check setup
242 EXPECT_EQ(9u, mesh_.n_vertices() ) << "Wrong number of vertices";
243 EXPECT_EQ(8u, mesh_.n_faces() ) << "Wrong number of faces";
244
245 // Execute 3 subdivision steps
246 loop.attach(mesh_);
247 loop( 3 );
248 loop.detach();
249
250 // Check setup
251 EXPECT_EQ(289u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with loop";
252 EXPECT_EQ(512u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with loop";
253 }
254
255
256
257 TEST_F(OpenMeshSubdividerUniform_Triangle, Subdivider_Loop_delete_vertex) {
258 mesh_.clear();
259
260 // Request status flags to use delete and garbage collection
261 mesh_.request_vertex_status();
262 mesh_.request_halfedge_status();
263 mesh_.request_edge_status();
264 mesh_.request_face_status();
265
266 // Add some vertices
267 Mesh::VertexHandle vhandle[9];
268
269 vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
270 vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
271 vhandle[2] = mesh_.add_vertex(Mesh::Point(0, 2, 0));
272 vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
273 vhandle[4] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
274 vhandle[5] = mesh_.add_vertex(Mesh::Point(1, 2, 0));
275 vhandle[6] = mesh_.add_vertex(Mesh::Point(2, 0, 0));
276 vhandle[7] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
277 vhandle[8] = mesh_.add_vertex(Mesh::Point(2, 2, 0));
278
279 // Add eight faces
280 std::vector<Mesh::VertexHandle> face_vhandles;
281
282 face_vhandles.push_back(vhandle[0]);
283 face_vhandles.push_back(vhandle[4]);
284 face_vhandles.push_back(vhandle[3]);
285
286 mesh_.add_face(face_vhandles);
287 face_vhandles.clear();
288
289 face_vhandles.push_back(vhandle[0]);
290 face_vhandles.push_back(vhandle[1]);
291 face_vhandles.push_back(vhandle[4]);
292
293 mesh_.add_face(face_vhandles);
294 face_vhandles.clear();
295
296 face_vhandles.push_back(vhandle[1]);
297 face_vhandles.push_back(vhandle[2]);
298 face_vhandles.push_back(vhandle[4]);
299
300 mesh_.add_face(face_vhandles);
301 face_vhandles.clear();
302
303 face_vhandles.push_back(vhandle[2]);
304 face_vhandles.push_back(vhandle[5]);
305 face_vhandles.push_back(vhandle[4]);
306
307 mesh_.add_face(face_vhandles);
308 face_vhandles.clear();
309
310 face_vhandles.push_back(vhandle[3]);
311 face_vhandles.push_back(vhandle[7]);
312 face_vhandles.push_back(vhandle[6]);
313
314 mesh_.add_face(face_vhandles);
315 face_vhandles.clear();
316
317 face_vhandles.push_back(vhandle[3]);
318 face_vhandles.push_back(vhandle[4]);
319 face_vhandles.push_back(vhandle[7]);
320
321 mesh_.add_face(face_vhandles);
322 face_vhandles.clear();
323
324 face_vhandles.push_back(vhandle[4]);
325 face_vhandles.push_back(vhandle[8]);
326 face_vhandles.push_back(vhandle[7]);
327
328 mesh_.add_face(face_vhandles);
329 face_vhandles.clear();
330
331 face_vhandles.push_back(vhandle[4]);
332 face_vhandles.push_back(vhandle[5]);
333 face_vhandles.push_back(vhandle[8]);
334
335 mesh_.add_face(face_vhandles);
336
337 // Test setup:
338 // 6 === 7 === 8
339 // | / | / |
340 // | / | / |
341 // | / | / |
342 // 3 === 4 === 5
343 // | / | \ |
344 // | / | \ |
345 // | / | \ |
346 // 0 === 1 === 2
347
348
349 // Delete one vertex
350 mesh_.delete_vertex(vhandle[1]);
351 mesh_.garbage_collection();
352
353 // Initialize subdivider
354 OpenMesh::Subdivider::Uniform::LoopT<Mesh> loop;
355
356 // Check setup
357 EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong number of vertices";
358 EXPECT_EQ(6u, mesh_.n_faces() ) << "Wrong number of faces";
359
360 // Execute 3 subdivision steps
361 loop.attach(mesh_);
362 loop( 3 );
363 loop.detach();
364
365 // Check setup
366 EXPECT_EQ(225u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with loop";
367 EXPECT_EQ(384u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with loop";
368 }
369
370
371
372 /*
373 * ====================================================================
374 * Define tests below
375 * ====================================================================
376 */
377
378 /*
379 */
380 TEST_F(OpenMeshSubdividerUniform_Poly, Subdivider_CatmullClark) {
381 mesh_.clear();
382
383 // Add some vertices
384 Mesh::VertexHandle vhandle[9];
385
386 vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
387 vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
388 vhandle[2] = mesh_.add_vertex(Mesh::Point(0, 2, 0));
389 vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
390 vhandle[4] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
391 vhandle[5] = mesh_.add_vertex(Mesh::Point(1, 2, 0));
392 vhandle[6] = mesh_.add_vertex(Mesh::Point(2, 0, 0));
393 vhandle[7] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
394 vhandle[8] = mesh_.add_vertex(Mesh::Point(2, 2, 0));
395
396 // Add four faces
397 std::vector<Mesh::VertexHandle> face_vhandles;
398
399 face_vhandles.push_back(vhandle[0]);
400 face_vhandles.push_back(vhandle[1]);
401 face_vhandles.push_back(vhandle[4]);
402 face_vhandles.push_back(vhandle[3]);
403
404 mesh_.add_face(face_vhandles);
405 face_vhandles.clear();
406
407 face_vhandles.push_back(vhandle[1]);
408 face_vhandles.push_back(vhandle[2]);
409 face_vhandles.push_back(vhandle[5]);
410 face_vhandles.push_back(vhandle[4]);
411
412 mesh_.add_face(face_vhandles);
413 face_vhandles.clear();
414
415 face_vhandles.push_back(vhandle[4]);
416 face_vhandles.push_back(vhandle[5]);
417 face_vhandles.push_back(vhandle[8]);
418 face_vhandles.push_back(vhandle[7]);
419
420 mesh_.add_face(face_vhandles);
421 face_vhandles.clear();
422
423 face_vhandles.push_back(vhandle[3]);
424 face_vhandles.push_back(vhandle[4]);
425 face_vhandles.push_back(vhandle[7]);
426 face_vhandles.push_back(vhandle[6]);
427
428 mesh_.add_face(face_vhandles);
429
430 // Test setup:
431 // 6 === 7 === 8
432 // | | |
433 // | | |
434 // | | |
435 // 3 === 4 === 5
436 // | | |
437 // | | |
438 // | | |
439 // 0 === 1 === 2
440
441 // Initialize subdivider
442 OpenMesh::Subdivider::Uniform::CatmullClarkT<PolyMesh> catmull;
443
444 // Check setup
445 EXPECT_EQ(9u, mesh_.n_vertices() ) << "Wrong number of vertices";
446 EXPECT_EQ(4u, mesh_.n_faces() ) << "Wrong number of faces";
447
448 // Execute 3 subdivision steps
449 catmull.attach(mesh_);
450 catmull( 3 );
451 catmull.detach();
452
453 EXPECT_EQ(289u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with catmull clark";
454 EXPECT_EQ(256u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with catmull clark";
455 }
456
457 /* Adds a cube to a polymesh
458 */
459 TEST_F(OpenMeshSubdividerUniform_Poly, Midpoint) {
460 mesh_.clear();
461
462 // Add some vertices
463 Mesh::VertexHandle vhandle[8];
464 vhandle[0] = mesh_.add_vertex(PolyMesh::Point(-1, -1, 1));
465 vhandle[1] = mesh_.add_vertex(PolyMesh::Point( 1, -1, 1));
466 vhandle[2] = mesh_.add_vertex(PolyMesh::Point( 1, 1, 1));
467 vhandle[3] = mesh_.add_vertex(PolyMesh::Point(-1, 1, 1));
468 vhandle[4] = mesh_.add_vertex(PolyMesh::Point(-1, -1, -1));
469 vhandle[5] = mesh_.add_vertex(PolyMesh::Point( 1, -1, -1));
470 vhandle[6] = mesh_.add_vertex(PolyMesh::Point( 1, 1, -1));
471 vhandle[7] = mesh_.add_vertex(PolyMesh::Point(-1, 1, -1));
472
473 // Add six faces to form a cube
474 std::vector<Mesh::VertexHandle> face_vhandles;
475
476 face_vhandles.clear();
477 face_vhandles.push_back(vhandle[0]);
478 face_vhandles.push_back(vhandle[1]);
479 face_vhandles.push_back(vhandle[2]);
480 face_vhandles.push_back(vhandle[3]);
481 mesh_.add_face(face_vhandles);
482
483 face_vhandles.clear();
484 face_vhandles.push_back(vhandle[7]);
485 face_vhandles.push_back(vhandle[6]);
486 face_vhandles.push_back(vhandle[5]);
487 face_vhandles.push_back(vhandle[4]);
488 mesh_.add_face(face_vhandles);
489
490 face_vhandles.clear();
491 face_vhandles.push_back(vhandle[1]);
492 face_vhandles.push_back(vhandle[0]);
493 face_vhandles.push_back(vhandle[4]);
494 face_vhandles.push_back(vhandle[5]);
495 mesh_.add_face(face_vhandles);
496
497 face_vhandles.clear();
498 face_vhandles.push_back(vhandle[2]);
499 face_vhandles.push_back(vhandle[1]);
500 face_vhandles.push_back(vhandle[5]);
501 face_vhandles.push_back(vhandle[6]);
502 mesh_.add_face(face_vhandles);
503
504 face_vhandles.clear();
505 face_vhandles.push_back(vhandle[3]);
506 face_vhandles.push_back(vhandle[2]);
507 face_vhandles.push_back(vhandle[6]);
508 face_vhandles.push_back(vhandle[7]);
509 mesh_.add_face(face_vhandles);
510
511 face_vhandles.clear();
512 face_vhandles.push_back(vhandle[0]);
513 face_vhandles.push_back(vhandle[3]);
514 face_vhandles.push_back(vhandle[7]);
515 face_vhandles.push_back(vhandle[4]);
516 mesh_.add_face(face_vhandles);
517
518
519 // Test setup:
520 //
521 //
522 // 3 ======== 2
523 // / /|
524 // / / | z
525 // 0 ======== 1 | |
526 // | | | | y
527 // | 7 | 6 | /
528 // | | / | /
529 // | |/ |/
530 // 4 ======== 5 -------> x
531 //
532
533 // Check setup
534 EXPECT_EQ(12u, mesh_.n_edges()) << "Wrong number of Edges";
535 EXPECT_EQ(24u, mesh_.n_halfedges()) << "Wrong number of HalfEdges";
536 EXPECT_EQ(8u, mesh_.n_vertices()) << "Wrong number of vertices";
537 EXPECT_EQ(6u, mesh_.n_faces()) << "Wrong number of faces";
538
539 // Initialize subdivider
540 OpenMesh::Subdivider::Uniform::MidpointT<PolyMesh> midpoint;
541
542 // Execute 2 subdivision steps
543 midpoint.attach(mesh_);
544 midpoint(2);
545 midpoint.detach();
546
547 // Check Result
548 EXPECT_EQ(48u, mesh_.n_edges()) << "Wrong number of Edges";
549 EXPECT_EQ(96u, mesh_.n_halfedges()) << "Wrong number of HalfEdges";
550 EXPECT_EQ(24u, mesh_.n_vertices()) << "Wrong number of vertices";
551 EXPECT_EQ(26u, mesh_.n_faces()) << "Wrong number of faces";
552 }
553
554
555
556 TEST_F(OpenMeshSubdividerUniform_Triangle, Modified_Butterfly) {
557 mesh_.clear();
558
559 // Add some vertices
560 Mesh::VertexHandle vhandle[9];
561
562 vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
563 vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
564 vhandle[2] = mesh_.add_vertex(Mesh::Point(0, 2, 0));
565 vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
566 vhandle[4] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
567 vhandle[5] = mesh_.add_vertex(Mesh::Point(1, 2, 0));
568 vhandle[6] = mesh_.add_vertex(Mesh::Point(2, 0, 0));
569 vhandle[7] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
570 vhandle[8] = mesh_.add_vertex(Mesh::Point(2, 2, 0));
571
572 // Add eight faces
573 std::vector<Mesh::VertexHandle> face_vhandles;
574
575 face_vhandles.push_back(vhandle[0]);
576 face_vhandles.push_back(vhandle[4]);
577 face_vhandles.push_back(vhandle[3]);
578
579 mesh_.add_face(face_vhandles);
580 face_vhandles.clear();
581
582 face_vhandles.push_back(vhandle[0]);
583 face_vhandles.push_back(vhandle[1]);
584 face_vhandles.push_back(vhandle[4]);
585
586 mesh_.add_face(face_vhandles);
587 face_vhandles.clear();
588
589 face_vhandles.push_back(vhandle[1]);
590 face_vhandles.push_back(vhandle[2]);
591 face_vhandles.push_back(vhandle[4]);
592
593 mesh_.add_face(face_vhandles);
594 face_vhandles.clear();
595
596 face_vhandles.push_back(vhandle[2]);
597 face_vhandles.push_back(vhandle[5]);
598 face_vhandles.push_back(vhandle[4]);
599
600 mesh_.add_face(face_vhandles);
601 face_vhandles.clear();
602
603 face_vhandles.push_back(vhandle[3]);
604 face_vhandles.push_back(vhandle[7]);
605 face_vhandles.push_back(vhandle[6]);
606
607 mesh_.add_face(face_vhandles);
608 face_vhandles.clear();
609
610 face_vhandles.push_back(vhandle[3]);
611 face_vhandles.push_back(vhandle[4]);
612 face_vhandles.push_back(vhandle[7]);
613
614 mesh_.add_face(face_vhandles);
615 face_vhandles.clear();
616
617 face_vhandles.push_back(vhandle[4]);
618 face_vhandles.push_back(vhandle[8]);
619 face_vhandles.push_back(vhandle[7]);
620
621 mesh_.add_face(face_vhandles);
622 face_vhandles.clear();
623
624 face_vhandles.push_back(vhandle[4]);
625 face_vhandles.push_back(vhandle[5]);
626 face_vhandles.push_back(vhandle[8]);
627
628 mesh_.add_face(face_vhandles);
629
630 // Test setup:
631 // 6 === 7 === 8
632 // | / | / |
633 // | / | / |
634 // | / | / |
635 // 3 === 4 === 5
636 // | / | \ |
637 // | / | \ |
638 // | / | \ |
639 // 0 === 1 === 2
640
641 // Initialize subdivider
642 OpenMesh::Subdivider::Uniform::ModifiedButterflyT<Mesh> butter;
643
644 // Check setup
645 EXPECT_EQ(9u, mesh_.n_vertices() ) << "Wrong number of vertices";
646 EXPECT_EQ(8u, mesh_.n_faces() ) << "Wrong number of faces";
647
648 // Execute 3 subdivision steps
649 butter.attach(mesh_);
650 butter( 3 );
651 butter.detach();
652
653 // Check setup
654 EXPECT_EQ(289u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with loop";
655 EXPECT_EQ(512u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with loop";
656 }
657
658
659
660 TEST_F(OpenMeshSubdividerUniform_Triangle, Modified_Butterfly_delete_vertex) {
661 mesh_.clear();
662
663 // Request status flags to use delete and garbage collection
664 mesh_.request_vertex_status();
665 mesh_.request_halfedge_status();
666 mesh_.request_edge_status();
667 mesh_.request_face_status();
668
669 // Add some vertices
670 Mesh::VertexHandle vhandle[9];
671
672 vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
673 vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
674 vhandle[2] = mesh_.add_vertex(Mesh::Point(0, 2, 0));
675 vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
676 vhandle[4] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
677 vhandle[5] = mesh_.add_vertex(Mesh::Point(1, 2, 0));
678 vhandle[6] = mesh_.add_vertex(Mesh::Point(2, 0, 0));
679 vhandle[7] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
680 vhandle[8] = mesh_.add_vertex(Mesh::Point(2, 2, 0));
681
682 // Add eight faces
683 std::vector<Mesh::VertexHandle> face_vhandles;
684
685 face_vhandles.push_back(vhandle[0]);
686 face_vhandles.push_back(vhandle[4]);
687 face_vhandles.push_back(vhandle[3]);
688
689 mesh_.add_face(face_vhandles);
690 face_vhandles.clear();
691
692 face_vhandles.push_back(vhandle[0]);
693 face_vhandles.push_back(vhandle[1]);
694 face_vhandles.push_back(vhandle[4]);
695
696 mesh_.add_face(face_vhandles);
697 face_vhandles.clear();
698
699 face_vhandles.push_back(vhandle[1]);
700 face_vhandles.push_back(vhandle[2]);
701 face_vhandles.push_back(vhandle[4]);
702
703 mesh_.add_face(face_vhandles);
704 face_vhandles.clear();
705
706 face_vhandles.push_back(vhandle[2]);
707 face_vhandles.push_back(vhandle[5]);
708 face_vhandles.push_back(vhandle[4]);
709
710 mesh_.add_face(face_vhandles);
711 face_vhandles.clear();
712
713 face_vhandles.push_back(vhandle[3]);
714 face_vhandles.push_back(vhandle[7]);
715 face_vhandles.push_back(vhandle[6]);
716
717 mesh_.add_face(face_vhandles);
718 face_vhandles.clear();
719
720 face_vhandles.push_back(vhandle[3]);
721 face_vhandles.push_back(vhandle[4]);
722 face_vhandles.push_back(vhandle[7]);
723
724 mesh_.add_face(face_vhandles);
725 face_vhandles.clear();
726
727 face_vhandles.push_back(vhandle[4]);
728 face_vhandles.push_back(vhandle[8]);
729 face_vhandles.push_back(vhandle[7]);
730
731 mesh_.add_face(face_vhandles);
732 face_vhandles.clear();
733
734 face_vhandles.push_back(vhandle[4]);
735 face_vhandles.push_back(vhandle[5]);
736 face_vhandles.push_back(vhandle[8]);
737
738 mesh_.add_face(face_vhandles);
739
740 // Test setup:
741 // 6 === 7 === 8
742 // | / | / |
743 // | / | / |
744 // | / | / |
745 // 3 === 4 === 5
746 // | / | \ |
747 // | / | \ |
748 // | / | \ |
749 // 0 === 1 === 2
750
751
752 // Delete one vertex
753 mesh_.delete_vertex(vhandle[1]);
754 mesh_.garbage_collection();
755
756 // Initialize subdivider
757 OpenMesh::Subdivider::Uniform::ModifiedButterflyT<Mesh> butter;
758
759 // Check setup
760 EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong number of vertices";
761 EXPECT_EQ(6u, mesh_.n_faces() ) << "Wrong number of faces";
762
763 // Execute 3 subdivision steps
764 butter.attach(mesh_);
765 butter( 3 );
766 butter.detach();
767
768 // Check setup
769 EXPECT_EQ(225u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with butter";
770 EXPECT_EQ(384u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with butter";
771 }
772
773
774
775
776 }
OpenMesh::Subdivider::Uniform::SubdividerT::detach
void detach(void)
Definition: SubdividerT.hh:155
OpenMesh::Subdivider::Uniform::SubdividerT::attach
bool attach(MeshType &_m)
Definition: SubdividerT.hh:132
OpenMesh::Subdivider::Uniform::LoopT
Definition: LoopT.hh:91
OpenMesh::PolyMeshT::Point
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:112
LoopT.hh
OpenMesh::Subdivider::Uniform::CatmullClarkT
Definition: CatmullClarkT.hh:85
CatmullClarkT.hh
OpenMesh::Subdivider::Uniform::Sqrt3T
Definition: Sqrt3T.hh:98
Sqrt3T.hh
OpenMesh::Subdivider::Uniform::MidpointT
Definition: MidpointT.hh:27
OpenMesh::Subdivider::Uniform::ModifiedButterflyT
Definition: ModifiedButterFlyT.hh:92
OpenMeshBasePoly
Definition: unittests_common.hh:53
ModifiedButterFlyT.hh
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