OpenMesh

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

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator 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 * Collapsing a tetrahedron
35 */
36 TEST_F(OpenMeshCollapse, CollapseTetrahedronComplex) {
37
38 mesh_.clear();
39
40 // Add some vertices
41 Mesh::VertexHandle vhandle[4];
42
43 vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
44 vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
45 vhandle[2] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
46 vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
47
48 // Add four faces
49 std::vector<Mesh::VertexHandle> face_vhandles;
50
51 face_vhandles.push_back(vhandle[0]);
52 face_vhandles.push_back(vhandle[1]);
53 face_vhandles.push_back(vhandle[2]);
54 mesh_.add_face(face_vhandles);
55
56 face_vhandles.clear();
57
58 face_vhandles.push_back(vhandle[0]);
59 face_vhandles.push_back(vhandle[2]);
60 face_vhandles.push_back(vhandle[3]);
61 mesh_.add_face(face_vhandles);
62
63 face_vhandles.clear();
64
65 face_vhandles.push_back(vhandle[2]);
66 face_vhandles.push_back(vhandle[1]);
67 face_vhandles.push_back(vhandle[3]);
68 mesh_.add_face(face_vhandles);
69
70 face_vhandles.clear();
71
72 face_vhandles.push_back(vhandle[3]);
73 face_vhandles.push_back(vhandle[1]);
74 face_vhandles.push_back(vhandle[0]);
75 mesh_.add_face(face_vhandles);
76
77 mesh_.request_vertex_status();
78 mesh_.request_edge_status();
79 mesh_.request_face_status();
80
81 Mesh::HalfedgeHandle v0v1 = mesh_.halfedge_handle(0);
82 Mesh::HalfedgeHandle v1v0 = mesh_.opposite_halfedge_handle(v0v1);
83
84 Mesh::HalfedgeHandle v1vL = mesh_.next_halfedge_handle(v0v1);
85 Mesh::HalfedgeHandle vLv1 = mesh_.opposite_halfedge_handle(v1vL);
86 Mesh::HalfedgeHandle vLv0 = mesh_.next_halfedge_handle(v1vL);
87 Mesh::HalfedgeHandle v0vL = mesh_.opposite_halfedge_handle(vLv0);
88
89 Mesh::HalfedgeHandle vLvR = mesh_.next_halfedge_handle(v0vL);
90 Mesh::HalfedgeHandle vRvL = mesh_.opposite_halfedge_handle(vLvR);
91
92 Mesh::HalfedgeHandle v0vR = mesh_.next_halfedge_handle(v1v0);
93 Mesh::HalfedgeHandle vRv0 = mesh_.opposite_halfedge_handle(v0vR);
94 Mesh::HalfedgeHandle vRv1 = mesh_.next_halfedge_handle(v0vR);
95 Mesh::HalfedgeHandle v1vR = mesh_.opposite_halfedge_handle(vRv1);
96
97
98
99 Mesh::VertexHandle v0 = mesh_.from_vertex_handle(v0v1);
100 Mesh::VertexHandle v1 = mesh_.to_vertex_handle(v0v1);
101 Mesh::VertexHandle vL = mesh_.to_vertex_handle(mesh_.next_halfedge_handle(v0v1));
102 Mesh::VertexHandle vR = mesh_.to_vertex_handle(mesh_.next_halfedge_handle(v1v0));
103
104 // ===================================================================
105 // Check preconditions
106 // ===================================================================
107
108 EXPECT_TRUE( mesh_.is_collapse_ok(v0v1) ) << "Collapse not ok for halfedge 0";
109 EXPECT_TRUE( mesh_.is_collapse_ok(v1v0) ) << "Collapse not ok for opposite of halfedge 0";
110
111 // Test the Vertex indices
112 EXPECT_EQ(0, v0.idx() ) << "Index wrong for from vertex of collapse halfedge";
113 EXPECT_EQ(1, v1.idx() ) << "Index wrong for to vertex of collapse halfedge";
114 EXPECT_EQ(2, vL.idx() ) << "Index wrong for left vertex of collapse halfedge";
115 EXPECT_EQ(3, vR.idx() ) << "Index wrong for right vertex of collapse halfedge";
116
117 // Check the halfedges
118 EXPECT_EQ(0, v0v1.idx() ) << "Index wrong for collapse halfedge";
119 EXPECT_EQ(1, v1v0.idx() ) << "Index wrong for opposite collapse halfedge";
120
121 EXPECT_EQ(2 , v1vL.idx() ) << "Index wrong for v1vL halfedge";
122 EXPECT_EQ(3 , vLv1.idx() ) << "Index wrong for vLv1 halfedge";
123 EXPECT_EQ(4 , vLv0.idx() ) << "Index wrong for vLv0 halfedge";
124 EXPECT_EQ(5 , v0vL.idx() ) << "Index wrong for v0vL halfedge";
125
126 EXPECT_EQ(6 , vLvR.idx() ) << "Index wrong for vLvR halfedge";
127 EXPECT_EQ(7 , vRvL.idx() ) << "Index wrong for vRvL halfedge";
128
129 EXPECT_EQ(8 , vRv0.idx() ) << "Index wrong for vRv0 halfedge";
130 EXPECT_EQ(9 , v0vR.idx() ) << "Index wrong for v0vR halfedge";
131
132 EXPECT_EQ(10 , v1vR.idx() ) << "Index wrong for v1vR halfedge";
133 EXPECT_EQ(11 , vRv1.idx() ) << "Index wrong for vRv1 halfedge";
134
135 // ===================================================================
136 // Execute collapse
137 // ===================================================================
138
139 mesh_.collapse(v0v1);
140
141 // ===================================================================
142 // Check configuration afterwards
143 // ===================================================================
144
160 EXPECT_EQ(4u , mesh_.n_faces() ) << "Wrong number of faces (garbage collection not executed!)";
161
162 // Check if the right vertices got deleted
163 EXPECT_TRUE( mesh_.status(mesh_.face_handle(0)).deleted() ) << "Face 0 not deleted";
164 EXPECT_FALSE( mesh_.status(mesh_.face_handle(1)).deleted() ) << "Face 1 deleted";
165 EXPECT_FALSE( mesh_.status(mesh_.face_handle(2)).deleted() ) << "Face 2 deleted";
166 EXPECT_TRUE( mesh_.status(mesh_.face_handle(3)).deleted() ) << "Face 3 not deleted";
167
168 // Check the vertices of the two remaining faces
169 Mesh::FaceHandle fh_1 = mesh_.face_handle(1);
170 Mesh::FaceHandle fh_2 = mesh_.face_handle(2);
171
172 Mesh::FaceVertexIter fv_it = mesh_.fv_begin(fh_1);
173
174 EXPECT_EQ(1 , fv_it.handle().idx() ) << "Index wrong for Vertex 1 of face 1";
175 ++fv_it;
176 EXPECT_EQ(2 , fv_it.handle().idx() ) << "Index wrong for Vertex 2 of face 1";
177 ++fv_it;
178 EXPECT_EQ(3 , fv_it.handle().idx() ) << "Index wrong for Vertex 3 of face 1";
179
180 fv_it = mesh_.fv_begin(fh_2);
181 EXPECT_EQ(2 , fv_it.handle().idx() ) << "Index wrong for Vertex 1 of face 2";
182 ++fv_it;
183 EXPECT_EQ(1 , fv_it.handle().idx() ) << "Index wrong for Vertex 2 of face 2";
184 ++fv_it;
185 EXPECT_EQ(3 , fv_it.handle().idx() ) << "Index wrong for Vertex 3 of face 2";
186
187 // Get the first halfedge of face 1
188 Mesh::HalfedgeHandle fh_1_he = mesh_.halfedge_handle(fh_1);
189
190 EXPECT_EQ(11 , fh_1_he.idx() ) << "Index wrong for first halfedge of face 1";
191 EXPECT_EQ(1 , mesh_.to_vertex_handle(fh_1_he).idx() ) << "First halfedge inside face 1 pointing to wrong vertex";
192
193 Mesh::HalfedgeHandle next = mesh_.next_halfedge_handle(fh_1_he);
194 EXPECT_EQ(2 , next.idx() ) << "Index wrong for second halfedge inside face 1 ";
195 EXPECT_EQ(2 , mesh_.to_vertex_handle(next).idx() ) << "second halfedge inside face 1 pointing to wrong vertex ";
196
197 next = mesh_.next_halfedge_handle(next);
198 EXPECT_EQ(6 , next.idx() ) << "Index wrong for third halfedge inside face 1 ";
199 EXPECT_EQ(3 , mesh_.to_vertex_handle(next).idx() ) << "Third halfedge inside face 1 pointing to wrong vertex ";
200
201 // Get the first halfedge of face 2
202 Mesh::HalfedgeHandle fh_2_he = mesh_.halfedge_handle(fh_2);
203
204 EXPECT_EQ(7 , fh_2_he.idx() ) << "Index wrong for first halfedge of face 2";
205 EXPECT_EQ(2 , mesh_.to_vertex_handle(fh_2_he).idx() ) << "First halfedge inside face 2 pointing to wrong vertex";
206
207 next = mesh_.next_halfedge_handle(fh_2_he);
208 EXPECT_EQ(3 , next.idx() ) << "Index wrong for second halfedge inside face 2";
209 EXPECT_EQ(1 , mesh_.to_vertex_handle(next).idx() ) << "second halfedge inside face 2 pointing to wrong vertex ";
210
211 next = mesh_.next_halfedge_handle(next);
212 EXPECT_EQ(10 , next.idx() ) << "Index wrong for third halfedge inside face 2";
213 EXPECT_EQ(3 , mesh_.to_vertex_handle(next).idx() ) << "Third halfedge inside face 2 pointing to wrong vertex ";
214
215 // Vertex 1 outgoing
216 Mesh::VertexOHalfedgeIter voh_it = mesh_.voh_begin(mesh_.vertex_handle(1));
217 EXPECT_EQ(10 , voh_it.handle().idx() ) << "Index wrong for first outgoing halfedge of vertex 1";
218 ++voh_it;
219 EXPECT_EQ(2 , voh_it.handle().idx() ) << "Index wrong for second outgoing halfedge of vertex 1";
220 ++voh_it;
221 EXPECT_EQ(10 , voh_it.handle().idx() ) << "Index wrong for third(one lap) outgoing halfedge of vertex 1";
222
223 // Vertex 2 outgoing
224 voh_it = mesh_.voh_begin(mesh_.vertex_handle(2));
225 EXPECT_EQ(3 , voh_it.handle().idx() ) << "Index wrong for first outgoing halfedge of vertex 2";
226 ++voh_it;
227 EXPECT_EQ(6 , voh_it.handle().idx() ) << "Index wrong for second outgoing halfedge of vertex 2";
228 ++voh_it;
229 EXPECT_EQ(3 , voh_it.handle().idx() ) << "Index wrong for third(one lap) outgoing halfedge of vertex 2";
230
231 // Vertex 3 outgoing
232 voh_it = mesh_.voh_begin(mesh_.vertex_handle(3));
233 EXPECT_EQ(11 , voh_it.handle().idx() ) << "Index wrong for first outgoing halfedge of vertex 3";
234 ++voh_it;
235 EXPECT_EQ(7 , voh_it.handle().idx() ) << "Index wrong for second outgoing halfedge of vertex 3";
236 ++voh_it;
237 EXPECT_EQ(11 , voh_it.handle().idx() ) << "Index wrong for third(one lap) outgoing halfedge of vertex 3";
238
239 // ===================================================================
240 // Cleanup
241 // ===================================================================
242 mesh_.garbage_collection();
243
244 // ===================================================================
245 // Check configuration afterwards
246 // ===================================================================
247
262 EXPECT_EQ(2u , mesh_.n_faces() ) << "Wrong number of faces (garbage collection executed!)";
263
264 // Check the vertices of the two remaining faces
265 Mesh::FaceHandle fh_0 = mesh_.face_handle(0);
266 fh_1 = mesh_.face_handle(1);
267
268 fv_it = mesh_.fv_begin(fh_0);
269
270 EXPECT_EQ(2 , fv_it.handle().idx() ) << "Index wrong for Vertex 1 of face 0 after garbage collection";
271 ++fv_it;
272 EXPECT_EQ(1 , fv_it.handle().idx() ) << "Index wrong for Vertex 2 of face 0 after garbage collection";
273 ++fv_it;
274 EXPECT_EQ(0 , fv_it.handle().idx() ) << "Index wrong for Vertex 3 of face 0 after garbage collection";
275
276 fv_it = mesh_.fv_begin(fh_1);
277 EXPECT_EQ(1 , fv_it.handle().idx() ) << "Index wrong for Vertex 1 of face 1 after garbage collection";
278 ++fv_it;
279 EXPECT_EQ(2 , fv_it.handle().idx() ) << "Index wrong for Vertex 2 of face 1 after garbage collection";
280 ++fv_it;
281 EXPECT_EQ(0 , fv_it.handle().idx() ) << "Index wrong for Vertex 3 of face 1 after garbage collection";
282
283 // Get the first halfedge of face 1
284 Mesh::HalfedgeHandle fh_0_he = mesh_.halfedge_handle(fh_0);
285
286 EXPECT_EQ(5 , fh_0_he.idx() ) << "Index wrong for first halfedge of face 0";
287 EXPECT_EQ(2 , mesh_.to_vertex_handle(fh_0_he).idx() ) << "First halfedge inside face 0 pointing to wrong vertex";
288
289 next = mesh_.next_halfedge_handle(fh_0_he);
290 EXPECT_EQ(3 , next.idx() ) << "Index wrong for second halfedge inside face 0 ";
291 EXPECT_EQ(1 , mesh_.to_vertex_handle(next).idx() ) << "second halfedge inside face 0 pointing to wrong vertex ";
292
293 next = mesh_.next_halfedge_handle(next);
294 EXPECT_EQ(0 , next.idx() ) << "Index wrong for third halfedge inside face 0 ";
295 EXPECT_EQ(0 , mesh_.to_vertex_handle(next).idx() ) << "Third halfedge inside face 0 pointing to wrong vertex ";
296
297 // Get the first halfedge of face 1
298 fh_1_he = mesh_.halfedge_handle(fh_1);
299
300 EXPECT_EQ(1 , fh_1_he.idx() ) << "Index wrong for first halfedge of face 1";
301 EXPECT_EQ(1 , mesh_.to_vertex_handle(fh_1_he).idx() ) << "First halfedge inside face 1 pointing to wrong vertex";
302
303 next = mesh_.next_halfedge_handle(fh_1_he);
304 EXPECT_EQ(2 , next.idx() ) << "Index wrong for second halfedge inside face 1 ";
305 EXPECT_EQ(2 , mesh_.to_vertex_handle(next).idx() ) << "second halfedge inside face 1 pointing to wrong vertex ";
306
307 next = mesh_.next_halfedge_handle(next);
308 EXPECT_EQ(4 , next.idx() ) << "Index wrong for third halfedge inside face 1 ";
309 EXPECT_EQ(0 , mesh_.to_vertex_handle(next).idx() ) << "Third halfedge inside face 1 pointing to wrong vertex ";
310
311
312 // Vertex 0 outgoing
313 voh_it = mesh_.voh_begin(mesh_.vertex_handle(0));
314 EXPECT_EQ(1 , voh_it.handle().idx() ) << "Index wrong for first outgoing halfedge of vertex 0";
315 ++voh_it;
316 EXPECT_EQ(5 , voh_it.handle().idx() ) << "Index wrong for second outgoing halfedge of vertex 0";
317 ++voh_it;
318 EXPECT_EQ(1 , voh_it.handle().idx() ) << "Index wrong for third(one lap) outgoing halfedge of vertex 0";
319
320 // Vertex 1 outgoing
321 voh_it = mesh_.voh_begin(mesh_.vertex_handle(1));
322 EXPECT_EQ(0 , voh_it.handle().idx() ) << "Index wrong for first outgoing halfedge of vertex 1";
323 ++voh_it;
324 EXPECT_EQ(2 , voh_it.handle().idx() ) << "Index wrong for second outgoing halfedge of vertex 1";
325 ++voh_it;
326 EXPECT_EQ(0 , voh_it.handle().idx() ) << "Index wrong for third(one lap) outgoing halfedge of vertex 1";
327
328 // Vertex 2 outgoing
329 voh_it = mesh_.voh_begin(mesh_.vertex_handle(2));
330 EXPECT_EQ(3 , voh_it.handle().idx() ) << "Index wrong for first outgoing halfedge of vertex 2";
331 ++voh_it;
332 EXPECT_EQ(4 , voh_it.handle().idx() ) << "Index wrong for second outgoing halfedge of vertex 2";
333 ++voh_it;
334 EXPECT_EQ(3 , voh_it.handle().idx() ) << "Index wrong for third(one lap) outgoing halfedge of vertex 2";
335
336 EXPECT_FALSE( mesh_.is_collapse_ok(mesh_.halfedge_handle(0)) ) << "Collapse should be not ok for halfedge 0";
337 EXPECT_FALSE( mesh_.is_collapse_ok(mesh_.halfedge_handle(1)) ) << "Collapse should be not ok for halfedge 1";
338 EXPECT_FALSE( mesh_.is_collapse_ok(mesh_.halfedge_handle(2)) ) << "Collapse should be not ok for halfedge 2";
339 EXPECT_FALSE( mesh_.is_collapse_ok(mesh_.halfedge_handle(3)) ) << "Collapse should be not ok for halfedge 3";
340 EXPECT_FALSE( mesh_.is_collapse_ok(mesh_.halfedge_handle(4)) ) << "Collapse should be not ok for halfedge 4";
341 EXPECT_FALSE( mesh_.is_collapse_ok(mesh_.halfedge_handle(5)) ) << "Collapse should be not ok for halfedge 5";
342 }
343
344 /*
345 * Collapsing a tetrahedron
346 */
347 TEST_F(OpenMeshCollapse, CollapseTetrahedron) {
348
349 mesh_.clear();
350
351 // Add some vertices
352 Mesh::VertexHandle vhandle[5];
353
354 // Setup a pyramid
355 vhandle[0] = mesh_.add_vertex(Mesh::Point(0 , 0, 0));
356 vhandle[1] = mesh_.add_vertex(Mesh::Point(1 , 0, 0));
357 vhandle[2] = mesh_.add_vertex(Mesh::Point(0 ,-1, 0));
358 vhandle[3] = mesh_.add_vertex(Mesh::Point(0 , 1, 0));
359 vhandle[4] = mesh_.add_vertex(Mesh::Point(-1, 0, 0));
360
361 // Add six faces
362 std::vector<Mesh::VertexHandle> face_vhandles;
363
364 face_vhandles.push_back(vhandle[0]);
365 face_vhandles.push_back(vhandle[4]);
366 face_vhandles.push_back(vhandle[2]);
367 mesh_.add_face(face_vhandles);
368
369 face_vhandles.clear();
370
371 face_vhandles.push_back(vhandle[3]);
372 face_vhandles.push_back(vhandle[4]);
373 face_vhandles.push_back(vhandle[0]);
374 mesh_.add_face(face_vhandles);
375
376 face_vhandles.clear();
377
378 face_vhandles.push_back(vhandle[2]);
379 face_vhandles.push_back(vhandle[4]);
380 face_vhandles.push_back(vhandle[3]);
381 mesh_.add_face(face_vhandles);
382
383 face_vhandles.clear();
384
385 face_vhandles.push_back(vhandle[2]);
386 face_vhandles.push_back(vhandle[1]);
387 face_vhandles.push_back(vhandle[0]);
388 mesh_.add_face(face_vhandles);
389
390 face_vhandles.clear();
391
392 face_vhandles.push_back(vhandle[0]);
393 face_vhandles.push_back(vhandle[1]);
394 face_vhandles.push_back(vhandle[3]);
395 mesh_.add_face(face_vhandles);
396
397 mesh_.request_vertex_status();
398 mesh_.request_edge_status();
399 mesh_.request_face_status();
400
401
402 // =============================================
403 // Collapse halfedge from 0 to 4
404 // =============================================
405
406 Mesh::HalfedgeHandle heh_collapse1 = mesh_.halfedge_handle(0);
407
408 EXPECT_EQ(4, mesh_.to_vertex_handle(heh_collapse1).idx() ) << "To vertex of collapse halfedge 1 is wrong";
409 EXPECT_EQ(0, mesh_.from_vertex_handle(heh_collapse1).idx() ) << "from vertex of collapse halfedge 1 is wrong";
410
411 EXPECT_TRUE( mesh_.is_collapse_ok(heh_collapse1) ) << "Collapse not ok for collapse first halfedge (0)";
412 mesh_.collapse(heh_collapse1);
413
414 Mesh::HalfedgeHandle heh_collapse2 = mesh_.halfedge_handle(2);
415
416 EXPECT_EQ(2, mesh_.to_vertex_handle(heh_collapse2).idx() ) << "To vertex of collapse halfedge 2 is wrong";
417 EXPECT_EQ(4, mesh_.from_vertex_handle(heh_collapse2).idx() ) << "from vertex of collapse halfedge 2 is wrong";
418
419 EXPECT_TRUE( mesh_.is_collapse_ok(heh_collapse2) ) << "Collapse not ok for collapse second halfedge (2)";
420 mesh_.collapse(heh_collapse2);
421
422 Mesh::HalfedgeHandle heh_collapse3 = mesh_.halfedge_handle(6);
423
424 EXPECT_EQ(2, mesh_.to_vertex_handle(heh_collapse3).idx() ) << "To vertex of collapse halfedge 3 is wrong";
425 EXPECT_EQ(3, mesh_.from_vertex_handle(heh_collapse3).idx() ) << "from vertex of collapse halfedge 3 is wrong";
426
427 EXPECT_FALSE( mesh_.is_collapse_ok(heh_collapse3) ) << "Collapse not ok for collapse third halfedge (6)";
428
429
430 }
431
432 /*
433 * Test collapsing an halfedge in a triangle mesh
434 *
435 */
436 TEST_F(OpenMeshCollapse, LargeCollapseHalfEdge) {
437
438 mesh_.clear();
439
440 // Add some vertices
441 Mesh::VertexHandle vhandle[7];
442
443 vhandle[0] = mesh_.add_vertex(Mesh::Point( 0, 1, 0));
444 vhandle[1] = mesh_.add_vertex(Mesh::Point( 1, 0, 0));
445 vhandle[2] = mesh_.add_vertex(Mesh::Point( 2, 1, 0));
446 vhandle[3] = mesh_.add_vertex(Mesh::Point( 0,-1, 0));
447 vhandle[4] = mesh_.add_vertex(Mesh::Point( 2,-1, 0));
448 vhandle[5] = mesh_.add_vertex(Mesh::Point(-1, 0, 0));
449 vhandle[6] = mesh_.add_vertex(Mesh::Point( 3, 0, 0));
450
451 // Add two faces
452 std::vector<Mesh::VertexHandle> face_vhandles;
453
454 face_vhandles.push_back(vhandle[0]);
455 face_vhandles.push_back(vhandle[5]);
456 face_vhandles.push_back(vhandle[1]);
457 mesh_.add_face(face_vhandles);
458
459 face_vhandles.clear();
460
461 face_vhandles.push_back(vhandle[1]);
462 face_vhandles.push_back(vhandle[5]);
463 face_vhandles.push_back(vhandle[3]);
464 mesh_.add_face(face_vhandles);
465
466 face_vhandles.clear();
467
468 face_vhandles.push_back(vhandle[0]);
469 face_vhandles.push_back(vhandle[1]);
470 face_vhandles.push_back(vhandle[2]);
471 mesh_.add_face(face_vhandles);
472
473 face_vhandles.clear();
474
475 face_vhandles.push_back(vhandle[1]);
476 face_vhandles.push_back(vhandle[3]);
477 face_vhandles.push_back(vhandle[4]);
478 mesh_.add_face(face_vhandles);
479
480 face_vhandles.clear();
481
482 face_vhandles.push_back(vhandle[2]);
483 face_vhandles.push_back(vhandle[1]);
484 face_vhandles.push_back(vhandle[4]);
485 mesh_.add_face(face_vhandles);
486
487 face_vhandles.clear();
488
489 face_vhandles.push_back(vhandle[2]);
490 face_vhandles.push_back(vhandle[4]);
491 face_vhandles.push_back(vhandle[6]);
492 mesh_.add_face(face_vhandles);
493
494 /* Test setup:
495 0 ==== 2
496 / \ /|\
497 / \ / | \
498 5 --- 1 | 6
499 \ / \ | /
500 \ / \|/
501 3 ==== 4 */
502
503 // Request the status bits
504 mesh_.request_vertex_status();
505 mesh_.request_edge_status();
506 mesh_.request_face_status();
507
508 // =============================================
509 // Collapse halfedge from 1 to 4
510 // =============================================
511
512 Mesh::HalfedgeHandle heh_collapse;
513
514 // Iterate over all halfedges to find the correct one
515 for ( Mesh::HalfedgeIter he_it = mesh_.halfedges_begin() ; he_it != mesh_.halfedges_end() ; ++he_it ) {
516 if ( mesh_.from_vertex_handle(he_it).idx() == 1 && mesh_.to_vertex_handle(he_it).idx() == 4 )
517 heh_collapse = he_it;
518 }
519
520 // Check our halfedge
521 EXPECT_EQ(4, mesh_.to_vertex_handle(heh_collapse).idx() ) << "To vertex of collapse halfedge is wrong";
522 EXPECT_EQ(1, mesh_.from_vertex_handle(heh_collapse).idx() ) << "from vertex of collapse halfedge is wrong";
523 EXPECT_TRUE( mesh_.is_collapse_ok(heh_collapse) ) << "Collapse not ok for collapse first halfedge (0)";
524
525 // Remember the end vertices
526 Mesh::VertexHandle vh_from = mesh_.from_vertex_handle(heh_collapse);
527 Mesh::VertexHandle vh_to = mesh_.to_vertex_handle(heh_collapse);
528
529 // Collapse it
530 mesh_.collapse(heh_collapse);
531
532 EXPECT_TRUE( mesh_.status(vh_from).deleted() ) << "From vertex not deleted";
533 EXPECT_FALSE( mesh_.status(vh_to).deleted() ) << "To Vertex deleted";
534
535 }
536
537
538 #endif // INCLUDE GUARD