OpenMesh

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
unittests_trimesh_collapse.hh
1 #ifndef INCLUDE_UNITTESTS_TRIMESH_COLLAPSE_HH
2 #define INCLUDE_UNITTESTS_TRIMESH_COLLAPSE_HH
3
4 #include <gtest/gtest.h>
5 #include <Unittests/unittests_common.hh>
6
7 #include <iostream>
8
9 class OpenMeshCollapse : public OpenMeshBase {
10
11 protected:
12
13 // This function is called before each test is run
14 virtual void SetUp() {
15 }
16
17 // This function is called after all tests are through
18 virtual void TearDown() {
19
20 // Do some final stuff with the member data here...
21 }
22
23 // Member already defined in OpenMeshBase
24 //Mesh mesh_;
25 };
26
27 /*
28 * ====================================================================
29 * Define tests below
30 * ====================================================================
31 */
32
33
34 /*
35 * Collapsing a quad splitted with center vertex
36 */
37 TEST_F(OpenMeshCollapse, CollapseQuadWithCenter) {
38
39 mesh_.clear();
40
41
42 // 0--------1
43 // |\ /|
44 // | \ / |
45 // | \ / |
46 // | 2 |
47 // | / \ |
48 // | / \ |
49 // 3--------4
50
51 // Add some vertices
52 Mesh::VertexHandle vhandle[5];
53
54 vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
55 vhandle[1] = mesh_.add_vertex(Mesh::Point(2, 0, 0));
56 vhandle[2] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
57 vhandle[3] = mesh_.add_vertex(Mesh::Point(0, 2, 0));
58 vhandle[4] = mesh_.add_vertex(Mesh::Point(2, 2, 0));
59
60 // Add four faces
61 std::vector<Mesh::VertexHandle> face_vhandles;
62
63 face_vhandles.push_back(vhandle[0]);
64 face_vhandles.push_back(vhandle[2]);
65 face_vhandles.push_back(vhandle[1]);
66 mesh_.add_face(face_vhandles);
67
68 face_vhandles.clear();
69
70 face_vhandles.push_back(vhandle[0]);
71 face_vhandles.push_back(vhandle[3]);
72 face_vhandles.push_back(vhandle[2]);
73 mesh_.add_face(face_vhandles);
74
75 face_vhandles.clear();
76
77 face_vhandles.push_back(vhandle[4]);
78 face_vhandles.push_back(vhandle[2]);
79 face_vhandles.push_back(vhandle[3]);
80 mesh_.add_face(face_vhandles);
81
82 face_vhandles.clear();
83
84 face_vhandles.push_back(vhandle[4]);
85 face_vhandles.push_back(vhandle[1]);
86 face_vhandles.push_back(vhandle[2]);
87 mesh_.add_face(face_vhandles);
88
89 mesh_.request_vertex_status();
90 mesh_.request_edge_status();
91 mesh_.request_face_status();
92
93
94 // Get the halfedge
95 Mesh::HalfedgeHandle v2v1 = mesh_.find_halfedge(vhandle[2], vhandle[1]);
96
97 EXPECT_TRUE( v2v1.is_valid() ) << "Invalid halfedge returned although it shoud exist";
98 EXPECT_TRUE( mesh_.is_collapse_ok(v2v1) ) << "Collapse retuned illegal althoug legal";
99
100 // Execute it as a crash test
101 mesh_.collapse(v2v1);
102 }
103
104
105
106
107 /*
108 * Collapsing a tetrahedron
109 */
110 TEST_F(OpenMeshCollapse, CollapseTetrahedronComplex) {
111
112 mesh_.clear();
113
114 // Add some vertices
115 Mesh::VertexHandle vhandle[4];
116
117 vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
118 vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
119 vhandle[2] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
120 vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
121
122 // Add four faces
123 std::vector<Mesh::VertexHandle> face_vhandles;
124
125 face_vhandles.push_back(vhandle[0]);
126 face_vhandles.push_back(vhandle[1]);
127 face_vhandles.push_back(vhandle[2]);
128 mesh_.add_face(face_vhandles);
129
130 face_vhandles.clear();
131
132 face_vhandles.push_back(vhandle[0]);
133 face_vhandles.push_back(vhandle[2]);
134 face_vhandles.push_back(vhandle[3]);
135 mesh_.add_face(face_vhandles);
136
137 face_vhandles.clear();
138
139 face_vhandles.push_back(vhandle[2]);
140 face_vhandles.push_back(vhandle[1]);
141 face_vhandles.push_back(vhandle[3]);
142 mesh_.add_face(face_vhandles);
143
144 face_vhandles.clear();
145
146 face_vhandles.push_back(vhandle[3]);
147 face_vhandles.push_back(vhandle[1]);
148 face_vhandles.push_back(vhandle[0]);
149 mesh_.add_face(face_vhandles);
150
151 mesh_.request_vertex_status();
152 mesh_.request_edge_status();
153 mesh_.request_face_status();
154
155 Mesh::HalfedgeHandle v0v1 = mesh_.halfedge_handle(0);
156 Mesh::HalfedgeHandle v1v0 = mesh_.opposite_halfedge_handle(v0v1);
157
158 Mesh::HalfedgeHandle v1vL = mesh_.next_halfedge_handle(v0v1);
159 Mesh::HalfedgeHandle vLv1 = mesh_.opposite_halfedge_handle(v1vL);
160 Mesh::HalfedgeHandle vLv0 = mesh_.next_halfedge_handle(v1vL);
161 Mesh::HalfedgeHandle v0vL = mesh_.opposite_halfedge_handle(vLv0);
162
163 Mesh::HalfedgeHandle vLvR = mesh_.next_halfedge_handle(v0vL);
164 Mesh::HalfedgeHandle vRvL = mesh_.opposite_halfedge_handle(vLvR);
165
166 Mesh::HalfedgeHandle v0vR = mesh_.next_halfedge_handle(v1v0);
167 Mesh::HalfedgeHandle vRv0 = mesh_.opposite_halfedge_handle(v0vR);
168 Mesh::HalfedgeHandle vRv1 = mesh_.next_halfedge_handle(v0vR);
169 Mesh::HalfedgeHandle v1vR = mesh_.opposite_halfedge_handle(vRv1);
170
171
172
173 Mesh::VertexHandle v0 = mesh_.from_vertex_handle(v0v1);
174 Mesh::VertexHandle v1 = mesh_.to_vertex_handle(v0v1);
175 Mesh::VertexHandle vL = mesh_.to_vertex_handle(mesh_.next_halfedge_handle(v0v1));
176 Mesh::VertexHandle vR = mesh_.to_vertex_handle(mesh_.next_halfedge_handle(v1v0));
177
178 // ===================================================================
179 // Check preconditions
180 // ===================================================================
181
182 EXPECT_TRUE( mesh_.is_collapse_ok(v0v1) ) << "Collapse not ok for halfedge 0";
183 EXPECT_TRUE( mesh_.is_collapse_ok(v1v0) ) << "Collapse not ok for opposite of halfedge 0";
184
185 // Test the Vertex indices
186 EXPECT_EQ(0, v0.idx() ) << "Index wrong for from vertex of collapse halfedge";
187 EXPECT_EQ(1, v1.idx() ) << "Index wrong for to vertex of collapse halfedge";
188 EXPECT_EQ(2, vL.idx() ) << "Index wrong for left vertex of collapse halfedge";
189 EXPECT_EQ(3, vR.idx() ) << "Index wrong for right vertex of collapse halfedge";
190
191 // Check the halfedges
192 EXPECT_EQ(0, v0v1.idx() ) << "Index wrong for collapse halfedge";
193 EXPECT_EQ(1, v1v0.idx() ) << "Index wrong for opposite collapse halfedge";
194
195 EXPECT_EQ(2 , v1vL.idx() ) << "Index wrong for v1vL halfedge";
196 EXPECT_EQ(3 , vLv1.idx() ) << "Index wrong for vLv1 halfedge";
197 EXPECT_EQ(4 , vLv0.idx() ) << "Index wrong for vLv0 halfedge";
198 EXPECT_EQ(5 , v0vL.idx() ) << "Index wrong for v0vL halfedge";
199
200 EXPECT_EQ(6 , vLvR.idx() ) << "Index wrong for vLvR halfedge";
201 EXPECT_EQ(7 , vRvL.idx() ) << "Index wrong for vRvL halfedge";
202
203 EXPECT_EQ(8 , vRv0.idx() ) << "Index wrong for vRv0 halfedge";
204 EXPECT_EQ(9 , v0vR.idx() ) << "Index wrong for v0vR halfedge";
205
206 EXPECT_EQ(10 , v1vR.idx() ) << "Index wrong for v1vR halfedge";
207 EXPECT_EQ(11 , vRv1.idx() ) << "Index wrong for vRv1 halfedge";
208
209 // ===================================================================
210 // Execute collapse
211 // ===================================================================
212
213 mesh_.collapse(v0v1);
214
215 // ===================================================================
216 // Check configuration afterwards
217 // ===================================================================
218
234 EXPECT_EQ(4u , mesh_.n_faces() ) << "Wrong number of faces (garbage collection not executed!)";
235
236 // Check if the right vertices got deleted
237 EXPECT_TRUE( mesh_.status(mesh_.face_handle(0)).deleted() ) << "Face 0 not deleted";
238 EXPECT_FALSE( mesh_.status(mesh_.face_handle(1)).deleted() ) << "Face 1 deleted";
239 EXPECT_FALSE( mesh_.status(mesh_.face_handle(2)).deleted() ) << "Face 2 deleted";
240 EXPECT_TRUE( mesh_.status(mesh_.face_handle(3)).deleted() ) << "Face 3 not deleted";
241
242 // Check the vertices of the two remaining faces
243 Mesh::FaceHandle fh_1 = mesh_.face_handle(1);
244 Mesh::FaceHandle fh_2 = mesh_.face_handle(2);
245
246 Mesh::FaceVertexIter fv_it = mesh_.fv_begin(fh_1);
247
248 EXPECT_EQ(1 , fv_it.handle().idx() ) << "Index wrong for Vertex 1 of face 1";
249 ++fv_it;
250 EXPECT_EQ(2 , fv_it.handle().idx() ) << "Index wrong for Vertex 2 of face 1";
251 ++fv_it;
252 EXPECT_EQ(3 , fv_it.handle().idx() ) << "Index wrong for Vertex 3 of face 1";
253
254 fv_it = mesh_.fv_begin(fh_2);
255 EXPECT_EQ(2 , fv_it.handle().idx() ) << "Index wrong for Vertex 1 of face 2";
256 ++fv_it;
257 EXPECT_EQ(1 , fv_it.handle().idx() ) << "Index wrong for Vertex 2 of face 2";
258 ++fv_it;
259 EXPECT_EQ(3 , fv_it.handle().idx() ) << "Index wrong for Vertex 3 of face 2";
260
261 // Get the first halfedge of face 1
262 Mesh::HalfedgeHandle fh_1_he = mesh_.halfedge_handle(fh_1);
263
264 EXPECT_EQ(11 , fh_1_he.idx() ) << "Index wrong for first halfedge of face 1";
265 EXPECT_EQ(1 , mesh_.to_vertex_handle(fh_1_he).idx() ) << "First halfedge inside face 1 pointing to wrong vertex";
266
267 Mesh::HalfedgeHandle next = mesh_.next_halfedge_handle(fh_1_he);
268 EXPECT_EQ(2 , next.idx() ) << "Index wrong for second halfedge inside face 1 ";
269 EXPECT_EQ(2 , mesh_.to_vertex_handle(next).idx() ) << "second halfedge inside face 1 pointing to wrong vertex ";
270
271 next = mesh_.next_halfedge_handle(next);
272 EXPECT_EQ(6 , next.idx() ) << "Index wrong for third halfedge inside face 1 ";
273 EXPECT_EQ(3 , mesh_.to_vertex_handle(next).idx() ) << "Third halfedge inside face 1 pointing to wrong vertex ";
274
275 // Get the first halfedge of face 2
276 Mesh::HalfedgeHandle fh_2_he = mesh_.halfedge_handle(fh_2);
277
278 EXPECT_EQ(7 , fh_2_he.idx() ) << "Index wrong for first halfedge of face 2";
279 EXPECT_EQ(2 , mesh_.to_vertex_handle(fh_2_he).idx() ) << "First halfedge inside face 2 pointing to wrong vertex";
280
281 next = mesh_.next_halfedge_handle(fh_2_he);
282 EXPECT_EQ(3 , next.idx() ) << "Index wrong for second halfedge inside face 2";
283 EXPECT_EQ(1 , mesh_.to_vertex_handle(next).idx() ) << "second halfedge inside face 2 pointing to wrong vertex ";
284
285 next = mesh_.next_halfedge_handle(next);
286 EXPECT_EQ(10 , next.idx() ) << "Index wrong for third halfedge inside face 2";
287 EXPECT_EQ(3 , mesh_.to_vertex_handle(next).idx() ) << "Third halfedge inside face 2 pointing to wrong vertex ";
288
289 // Vertex 1 outgoing
290 Mesh::VertexOHalfedgeIter voh_it = mesh_.voh_begin(mesh_.vertex_handle(1));
291 EXPECT_EQ(10 , voh_it.handle().idx() ) << "Index wrong for first outgoing halfedge of vertex 1";
292 ++voh_it;
293 EXPECT_EQ(2 , voh_it.handle().idx() ) << "Index wrong for second outgoing halfedge of vertex 1";
294 ++voh_it;
295 EXPECT_EQ(10 , voh_it.handle().idx() ) << "Index wrong for third(one lap) outgoing halfedge of vertex 1";
296
297 // Vertex 2 outgoing
298 voh_it = mesh_.voh_begin(mesh_.vertex_handle(2));
299 EXPECT_EQ(3 , voh_it.handle().idx() ) << "Index wrong for first outgoing halfedge of vertex 2";
300 ++voh_it;
301 EXPECT_EQ(6 , voh_it.handle().idx() ) << "Index wrong for second outgoing halfedge of vertex 2";
302 ++voh_it;
303 EXPECT_EQ(3 , voh_it.handle().idx() ) << "Index wrong for third(one lap) outgoing halfedge of vertex 2";
304
305 // Vertex 3 outgoing
306 voh_it = mesh_.voh_begin(mesh_.vertex_handle(3));
307 EXPECT_EQ(11 , voh_it.handle().idx() ) << "Index wrong for first outgoing halfedge of vertex 3";
308 ++voh_it;
309 EXPECT_EQ(7 , voh_it.handle().idx() ) << "Index wrong for second outgoing halfedge of vertex 3";
310 ++voh_it;
311 EXPECT_EQ(11 , voh_it.handle().idx() ) << "Index wrong for third(one lap) outgoing halfedge of vertex 3";
312
313 // ===================================================================
314 // Cleanup
315 // ===================================================================
316 mesh_.garbage_collection();
317
318 // ===================================================================
319 // Check configuration afterwards
320 // ===================================================================
321
336 EXPECT_EQ(2u , mesh_.n_faces() ) << "Wrong number of faces (garbage collection executed!)";
337
338 // Check the vertices of the two remaining faces
339 Mesh::FaceHandle fh_0 = mesh_.face_handle(0);
340 fh_1 = mesh_.face_handle(1);
341
342 fv_it = mesh_.fv_begin(fh_0);
343
344 EXPECT_EQ(2 , fv_it.handle().idx() ) << "Index wrong for Vertex 1 of face 0 after garbage collection";
345 ++fv_it;
346 EXPECT_EQ(1 , fv_it.handle().idx() ) << "Index wrong for Vertex 2 of face 0 after garbage collection";
347 ++fv_it;
348 EXPECT_EQ(0 , fv_it.handle().idx() ) << "Index wrong for Vertex 3 of face 0 after garbage collection";
349
350 fv_it = mesh_.fv_begin(fh_1);
351 EXPECT_EQ(1 , fv_it.handle().idx() ) << "Index wrong for Vertex 1 of face 1 after garbage collection";
352 ++fv_it;
353 EXPECT_EQ(2 , fv_it.handle().idx() ) << "Index wrong for Vertex 2 of face 1 after garbage collection";
354 ++fv_it;
355 EXPECT_EQ(0 , fv_it.handle().idx() ) << "Index wrong for Vertex 3 of face 1 after garbage collection";
356
357 // Get the first halfedge of face 1
358 Mesh::HalfedgeHandle fh_0_he = mesh_.halfedge_handle(fh_0);
359
360 EXPECT_EQ(5 , fh_0_he.idx() ) << "Index wrong for first halfedge of face 0";
361 EXPECT_EQ(2 , mesh_.to_vertex_handle(fh_0_he).idx() ) << "First halfedge inside face 0 pointing to wrong vertex";
362
363 next = mesh_.next_halfedge_handle(fh_0_he);
364 EXPECT_EQ(3 , next.idx() ) << "Index wrong for second halfedge inside face 0 ";
365 EXPECT_EQ(1 , mesh_.to_vertex_handle(next).idx() ) << "second halfedge inside face 0 pointing to wrong vertex ";
366
367 next = mesh_.next_halfedge_handle(next);
368 EXPECT_EQ(0 , next.idx() ) << "Index wrong for third halfedge inside face 0 ";
369 EXPECT_EQ(0 , mesh_.to_vertex_handle(next).idx() ) << "Third halfedge inside face 0 pointing to wrong vertex ";
370
371 // Get the first halfedge of face 1
372 fh_1_he = mesh_.halfedge_handle(fh_1);
373
374 EXPECT_EQ(1 , fh_1_he.idx() ) << "Index wrong for first halfedge of face 1";
375 EXPECT_EQ(1 , mesh_.to_vertex_handle(fh_1_he).idx() ) << "First halfedge inside face 1 pointing to wrong vertex";
376
377 next = mesh_.next_halfedge_handle(fh_1_he);
378 EXPECT_EQ(2 , next.idx() ) << "Index wrong for second halfedge inside face 1 ";
379 EXPECT_EQ(2 , mesh_.to_vertex_handle(next).idx() ) << "second halfedge inside face 1 pointing to wrong vertex ";
380
381 next = mesh_.next_halfedge_handle(next);
382 EXPECT_EQ(4 , next.idx() ) << "Index wrong for third halfedge inside face 1 ";
383 EXPECT_EQ(0 , mesh_.to_vertex_handle(next).idx() ) << "Third halfedge inside face 1 pointing to wrong vertex ";
384
385
386 // Vertex 0 outgoing
387 voh_it = mesh_.voh_begin(mesh_.vertex_handle(0));
388 EXPECT_EQ(1 , voh_it.handle().idx() ) << "Index wrong for first outgoing halfedge of vertex 0";
389 ++voh_it;
390 EXPECT_EQ(5 , voh_it.handle().idx() ) << "Index wrong for second outgoing halfedge of vertex 0";
391 ++voh_it;
392 EXPECT_EQ(1 , voh_it.handle().idx() ) << "Index wrong for third(one lap) outgoing halfedge of vertex 0";
393
394 // Vertex 1 outgoing
395 voh_it = mesh_.voh_begin(mesh_.vertex_handle(1));
396 EXPECT_EQ(0 , voh_it.handle().idx() ) << "Index wrong for first outgoing halfedge of vertex 1";
397 ++voh_it;
398 EXPECT_EQ(2 , voh_it.handle().idx() ) << "Index wrong for second outgoing halfedge of vertex 1";
399 ++voh_it;
400 EXPECT_EQ(0 , voh_it.handle().idx() ) << "Index wrong for third(one lap) outgoing halfedge of vertex 1";
401
402 // Vertex 2 outgoing
403 voh_it = mesh_.voh_begin(mesh_.vertex_handle(2));
404 EXPECT_EQ(3 , voh_it.handle().idx() ) << "Index wrong for first outgoing halfedge of vertex 2";
405 ++voh_it;
406 EXPECT_EQ(4 , voh_it.handle().idx() ) << "Index wrong for second outgoing halfedge of vertex 2";
407 ++voh_it;
408 EXPECT_EQ(3 , voh_it.handle().idx() ) << "Index wrong for third(one lap) outgoing halfedge of vertex 2";
409
410 EXPECT_FALSE( mesh_.is_collapse_ok(mesh_.halfedge_handle(0)) ) << "Collapse should be not ok for halfedge 0";
411 EXPECT_FALSE( mesh_.is_collapse_ok(mesh_.halfedge_handle(1)) ) << "Collapse should be not ok for halfedge 1";
412 EXPECT_FALSE( mesh_.is_collapse_ok(mesh_.halfedge_handle(2)) ) << "Collapse should be not ok for halfedge 2";
413 EXPECT_FALSE( mesh_.is_collapse_ok(mesh_.halfedge_handle(3)) ) << "Collapse should be not ok for halfedge 3";
414 EXPECT_FALSE( mesh_.is_collapse_ok(mesh_.halfedge_handle(4)) ) << "Collapse should be not ok for halfedge 4";
415 EXPECT_FALSE( mesh_.is_collapse_ok(mesh_.halfedge_handle(5)) ) << "Collapse should be not ok for halfedge 5";
416 }
417
418 /*
419 * Collapsing a tetrahedron
420 */
421 TEST_F(OpenMeshCollapse, CollapseTetrahedron) {
422
423 mesh_.clear();
424
425 // Add some vertices
426 Mesh::VertexHandle vhandle[5];
427
428 // Setup a pyramid
429 vhandle[0] = mesh_.add_vertex(Mesh::Point(0 , 0, 0));
430 vhandle[1] = mesh_.add_vertex(Mesh::Point(1 , 0, 0));
431 vhandle[2] = mesh_.add_vertex(Mesh::Point(0 ,-1, 0));
432 vhandle[3] = mesh_.add_vertex(Mesh::Point(0 , 1, 0));
433 vhandle[4] = mesh_.add_vertex(Mesh::Point(-1, 0, 0));
434
435 // Add six faces
436 std::vector<Mesh::VertexHandle> face_vhandles;
437
438 face_vhandles.push_back(vhandle[0]);
439 face_vhandles.push_back(vhandle[4]);
440 face_vhandles.push_back(vhandle[2]);
441 mesh_.add_face(face_vhandles);
442
443 face_vhandles.clear();
444
445 face_vhandles.push_back(vhandle[3]);
446 face_vhandles.push_back(vhandle[4]);
447 face_vhandles.push_back(vhandle[0]);
448 mesh_.add_face(face_vhandles);
449
450 face_vhandles.clear();
451
452 face_vhandles.push_back(vhandle[2]);
453 face_vhandles.push_back(vhandle[4]);
454 face_vhandles.push_back(vhandle[3]);
455 mesh_.add_face(face_vhandles);
456
457 face_vhandles.clear();
458
459 face_vhandles.push_back(vhandle[2]);
460 face_vhandles.push_back(vhandle[1]);
461 face_vhandles.push_back(vhandle[0]);
462 mesh_.add_face(face_vhandles);
463
464 face_vhandles.clear();
465
466 face_vhandles.push_back(vhandle[0]);
467 face_vhandles.push_back(vhandle[1]);
468 face_vhandles.push_back(vhandle[3]);
469 mesh_.add_face(face_vhandles);
470
471 mesh_.request_vertex_status();
472 mesh_.request_edge_status();
473 mesh_.request_face_status();
474
475
476 // =============================================
477 // Collapse halfedge from 0 to 4
478 // =============================================
479
480 Mesh::HalfedgeHandle heh_collapse1 = mesh_.halfedge_handle(0);
481
482 EXPECT_EQ(4, mesh_.to_vertex_handle(heh_collapse1).idx() ) << "To vertex of collapse halfedge 1 is wrong";
483 EXPECT_EQ(0, mesh_.from_vertex_handle(heh_collapse1).idx() ) << "from vertex of collapse halfedge 1 is wrong";
484
485 EXPECT_TRUE( mesh_.is_collapse_ok(heh_collapse1) ) << "Collapse not ok for collapse first halfedge (0)";
486 mesh_.collapse(heh_collapse1);
487
488 Mesh::HalfedgeHandle heh_collapse2 = mesh_.halfedge_handle(2);
489
490 EXPECT_EQ(2, mesh_.to_vertex_handle(heh_collapse2).idx() ) << "To vertex of collapse halfedge 2 is wrong";
491 EXPECT_EQ(4, mesh_.from_vertex_handle(heh_collapse2).idx() ) << "from vertex of collapse halfedge 2 is wrong";
492
493 EXPECT_TRUE( mesh_.is_collapse_ok(heh_collapse2) ) << "Collapse not ok for collapse second halfedge (2)";
494 mesh_.collapse(heh_collapse2);
495
496 Mesh::HalfedgeHandle heh_collapse3 = mesh_.halfedge_handle(6);
497
498 EXPECT_EQ(2, mesh_.to_vertex_handle(heh_collapse3).idx() ) << "To vertex of collapse halfedge 3 is wrong";
499 EXPECT_EQ(3, mesh_.from_vertex_handle(heh_collapse3).idx() ) << "from vertex of collapse halfedge 3 is wrong";
500
501 EXPECT_FALSE( mesh_.is_collapse_ok(heh_collapse3) ) << "Collapse not ok for collapse third halfedge (6)";
502
503
504 }
505
506 /*
507 * Test collapsing an halfedge in a triangle mesh
508 *
509 */
510 TEST_F(OpenMeshCollapse, LargeCollapseHalfEdge) {
511
512 mesh_.clear();
513
514 // Add some vertices
515 Mesh::VertexHandle vhandle[7];
516
517 vhandle[0] = mesh_.add_vertex(Mesh::Point( 0, 1, 0));
518 vhandle[1] = mesh_.add_vertex(Mesh::Point( 1, 0, 0));
519 vhandle[2] = mesh_.add_vertex(Mesh::Point( 2, 1, 0));
520 vhandle[3] = mesh_.add_vertex(Mesh::Point( 0,-1, 0));
521 vhandle[4] = mesh_.add_vertex(Mesh::Point( 2,-1, 0));
522 vhandle[5] = mesh_.add_vertex(Mesh::Point(-1, 0, 0));
523 vhandle[6] = mesh_.add_vertex(Mesh::Point( 3, 0, 0));
524
525 // Add two faces
526 std::vector<Mesh::VertexHandle> face_vhandles;
527
528 face_vhandles.push_back(vhandle[0]);
529 face_vhandles.push_back(vhandle[5]);
530 face_vhandles.push_back(vhandle[1]);
531 mesh_.add_face(face_vhandles);
532
533 face_vhandles.clear();
534
535 face_vhandles.push_back(vhandle[1]);
536 face_vhandles.push_back(vhandle[5]);
537 face_vhandles.push_back(vhandle[3]);
538 mesh_.add_face(face_vhandles);
539
540 face_vhandles.clear();
541
542 face_vhandles.push_back(vhandle[0]);
543 face_vhandles.push_back(vhandle[1]);
544 face_vhandles.push_back(vhandle[2]);
545 mesh_.add_face(face_vhandles);
546
547 face_vhandles.clear();
548
549 face_vhandles.push_back(vhandle[1]);
550 face_vhandles.push_back(vhandle[3]);
551 face_vhandles.push_back(vhandle[4]);
552 mesh_.add_face(face_vhandles);
553
554 face_vhandles.clear();
555
556 face_vhandles.push_back(vhandle[2]);
557 face_vhandles.push_back(vhandle[1]);
558 face_vhandles.push_back(vhandle[4]);
559 mesh_.add_face(face_vhandles);
560
561 face_vhandles.clear();
562
563 face_vhandles.push_back(vhandle[2]);
564 face_vhandles.push_back(vhandle[4]);
565 face_vhandles.push_back(vhandle[6]);
566 mesh_.add_face(face_vhandles);
567
568 /* Test setup:
569 0 ==== 2
570 / \ /|\
571 / \ / | \
572 5 --- 1 | 6
573 \ / \ | /
574 \ / \|/
575 3 ==== 4 */
576
577 // Request the status bits
578 mesh_.request_vertex_status();
579 mesh_.request_edge_status();
580 mesh_.request_face_status();
581
582 // =============================================
583 // Collapse halfedge from 1 to 4
584 // =============================================
585
586 Mesh::HalfedgeHandle heh_collapse;
587
588 // Iterate over all halfedges to find the correct one
589 for ( Mesh::HalfedgeIter he_it = mesh_.halfedges_begin() ; he_it != mesh_.halfedges_end() ; ++he_it ) {
590 if ( mesh_.from_vertex_handle(he_it).idx() == 1 && mesh_.to_vertex_handle(he_it).idx() == 4 )
591 heh_collapse = he_it;
592 }
593
594 // Check our halfedge
595 EXPECT_EQ(4, mesh_.to_vertex_handle(heh_collapse).idx() ) << "To vertex of collapse halfedge is wrong";
596 EXPECT_EQ(1, mesh_.from_vertex_handle(heh_collapse).idx() ) << "from vertex of collapse halfedge is wrong";
597 EXPECT_TRUE( mesh_.is_collapse_ok(heh_collapse) ) << "Collapse not ok for collapse first halfedge (0)";
598
599 // Remember the end vertices
600 Mesh::VertexHandle vh_from = mesh_.from_vertex_handle(heh_collapse);
601 Mesh::VertexHandle vh_to = mesh_.to_vertex_handle(heh_collapse);
602
603 // Collapse it
604 mesh_.collapse(heh_collapse);
605
606 EXPECT_TRUE( mesh_.status(vh_from).deleted() ) << "From vertex not deleted";
607 EXPECT_FALSE( mesh_.status(vh_to).deleted() ) << "To Vertex deleted";
608
609 }
610
611
612 #endif // INCLUDE GUARD