OpenMesh
 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

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