OpenMesh
 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

acg pic Project OpenMesh, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .