1 #include <gtest/gtest.h>
2 #include <Unittests/unittests_common.hh>
13 virtual void SetUp() {
17 virtual void TearDown() {
36 TEST_F(OpenMeshCollapse, CollapseQuadWithCenter) {
60 std::vector<Mesh::VertexHandle> face_vhandles;
62 face_vhandles.push_back(vhandle[0]);
63 face_vhandles.push_back(vhandle[2]);
64 face_vhandles.push_back(vhandle[1]);
65 mesh_.add_face(face_vhandles);
67 face_vhandles.clear();
69 face_vhandles.push_back(vhandle[0]);
70 face_vhandles.push_back(vhandle[3]);
71 face_vhandles.push_back(vhandle[2]);
72 mesh_.add_face(face_vhandles);
74 face_vhandles.clear();
76 face_vhandles.push_back(vhandle[4]);
77 face_vhandles.push_back(vhandle[2]);
78 face_vhandles.push_back(vhandle[3]);
79 mesh_.add_face(face_vhandles);
81 face_vhandles.clear();
83 face_vhandles.push_back(vhandle[4]);
84 face_vhandles.push_back(vhandle[1]);
85 face_vhandles.push_back(vhandle[2]);
86 mesh_.add_face(face_vhandles);
88 mesh_.request_vertex_status();
89 mesh_.request_edge_status();
90 mesh_.request_face_status();
94 Mesh::HalfedgeHandle v2v1 = mesh_.find_halfedge(vhandle[2], vhandle[1]);
96 EXPECT_TRUE( v2v1.is_valid() ) <<
"Invalid halfedge returned although it shoud exist";
97 EXPECT_TRUE( mesh_.is_collapse_ok(v2v1) ) <<
"Collapse retuned illegal althoug legal";
100 mesh_.collapse(v2v1);
109 TEST_F(OpenMeshCollapse, CollapseTetrahedronComplex) {
122 std::vector<Mesh::VertexHandle> face_vhandles;
124 face_vhandles.push_back(vhandle[0]);
125 face_vhandles.push_back(vhandle[1]);
126 face_vhandles.push_back(vhandle[2]);
127 mesh_.add_face(face_vhandles);
129 face_vhandles.clear();
131 face_vhandles.push_back(vhandle[0]);
132 face_vhandles.push_back(vhandle[2]);
133 face_vhandles.push_back(vhandle[3]);
134 mesh_.add_face(face_vhandles);
136 face_vhandles.clear();
138 face_vhandles.push_back(vhandle[2]);
139 face_vhandles.push_back(vhandle[1]);
140 face_vhandles.push_back(vhandle[3]);
141 mesh_.add_face(face_vhandles);
143 face_vhandles.clear();
145 face_vhandles.push_back(vhandle[3]);
146 face_vhandles.push_back(vhandle[1]);
147 face_vhandles.push_back(vhandle[0]);
148 mesh_.add_face(face_vhandles);
150 mesh_.request_vertex_status();
151 mesh_.request_edge_status();
152 mesh_.request_face_status();
154 Mesh::HalfedgeHandle v0v1 = mesh_.halfedge_handle(0);
155 Mesh::HalfedgeHandle v1v0 = mesh_.opposite_halfedge_handle(v0v1);
157 Mesh::HalfedgeHandle v1vL = mesh_.next_halfedge_handle(v0v1);
158 Mesh::HalfedgeHandle vLv1 = mesh_.opposite_halfedge_handle(v1vL);
159 Mesh::HalfedgeHandle vLv0 = mesh_.next_halfedge_handle(v1vL);
160 Mesh::HalfedgeHandle v0vL = mesh_.opposite_halfedge_handle(vLv0);
162 Mesh::HalfedgeHandle vLvR = mesh_.next_halfedge_handle(v0vL);
163 Mesh::HalfedgeHandle vRvL = mesh_.opposite_halfedge_handle(vLvR);
165 Mesh::HalfedgeHandle v0vR = mesh_.next_halfedge_handle(v1v0);
166 Mesh::HalfedgeHandle vRv0 = mesh_.opposite_halfedge_handle(v0vR);
167 Mesh::HalfedgeHandle vRv1 = mesh_.next_halfedge_handle(v0vR);
168 Mesh::HalfedgeHandle v1vR = mesh_.opposite_halfedge_handle(vRv1);
181 EXPECT_TRUE( mesh_.is_collapse_ok(v0v1) ) <<
"Collapse not ok for halfedge 0";
182 EXPECT_TRUE( mesh_.is_collapse_ok(v1v0) ) <<
"Collapse not ok for opposite of halfedge 0";
185 EXPECT_EQ(0, v0.idx() ) <<
"Index wrong for from vertex of collapse halfedge";
186 EXPECT_EQ(1, v1.idx() ) <<
"Index wrong for to vertex of collapse halfedge";
187 EXPECT_EQ(2, vL.idx() ) <<
"Index wrong for left vertex of collapse halfedge";
188 EXPECT_EQ(3, vR.idx() ) <<
"Index wrong for right vertex of collapse halfedge";
191 EXPECT_EQ(0, v0v1.idx() ) <<
"Index wrong for collapse halfedge";
192 EXPECT_EQ(1, v1v0.idx() ) <<
"Index wrong for opposite collapse halfedge";
194 EXPECT_EQ(2 , v1vL.idx() ) <<
"Index wrong for v1vL halfedge";
195 EXPECT_EQ(3 , vLv1.idx() ) <<
"Index wrong for vLv1 halfedge";
196 EXPECT_EQ(4 , vLv0.idx() ) <<
"Index wrong for vLv0 halfedge";
197 EXPECT_EQ(5 , v0vL.idx() ) <<
"Index wrong for v0vL halfedge";
199 EXPECT_EQ(6 , vLvR.idx() ) <<
"Index wrong for vLvR halfedge";
200 EXPECT_EQ(7 , vRvL.idx() ) <<
"Index wrong for vRvL halfedge";
202 EXPECT_EQ(8 , vRv0.idx() ) <<
"Index wrong for vRv0 halfedge";
203 EXPECT_EQ(9 , v0vR.idx() ) <<
"Index wrong for v0vR halfedge";
205 EXPECT_EQ(10 , v1vR.idx() ) <<
"Index wrong for v1vR halfedge";
206 EXPECT_EQ(11 , vRv1.idx() ) <<
"Index wrong for vRv1 halfedge";
212 mesh_.collapse(v0v1);
233 EXPECT_EQ(4u , mesh_.n_faces() ) <<
"Wrong number of faces (garbage collection not executed!)";
236 EXPECT_TRUE( mesh_.status(mesh_.face_handle(0)).deleted() ) <<
"Face 0 not deleted";
237 EXPECT_FALSE( mesh_.status(mesh_.face_handle(1)).deleted() ) <<
"Face 1 deleted";
238 EXPECT_FALSE( mesh_.status(mesh_.face_handle(2)).deleted() ) <<
"Face 2 deleted";
239 EXPECT_TRUE( mesh_.status(mesh_.face_handle(3)).deleted() ) <<
"Face 3 not deleted";
242 Mesh::FaceHandle fh_1 = mesh_.face_handle(1);
243 Mesh::FaceHandle fh_2 = mesh_.face_handle(2);
247 EXPECT_EQ(1 , fv_it->idx() ) <<
"Index wrong for Vertex 1 of face 1";
249 EXPECT_EQ(2 , fv_it->idx() ) <<
"Index wrong for Vertex 2 of face 1";
251 EXPECT_EQ(3 , fv_it->idx() ) <<
"Index wrong for Vertex 3 of face 1";
253 fv_it = mesh_.fv_begin(fh_2);
254 EXPECT_EQ(2 , fv_it->idx() ) <<
"Index wrong for Vertex 1 of face 2";
256 EXPECT_EQ(1 , fv_it->idx() ) <<
"Index wrong for Vertex 2 of face 2";
258 EXPECT_EQ(3 , fv_it->idx() ) <<
"Index wrong for Vertex 3 of face 2";
261 Mesh::HalfedgeHandle fh_1_he = mesh_.halfedge_handle(fh_1);
263 EXPECT_EQ(11 , fh_1_he.idx() ) <<
"Index wrong for first halfedge of face 1";
264 EXPECT_EQ(1 , mesh_.to_vertex_handle(fh_1_he).idx() ) <<
"First halfedge inside face 1 pointing to wrong vertex";
266 Mesh::HalfedgeHandle next = mesh_.next_halfedge_handle(fh_1_he);
267 EXPECT_EQ(2 , next.idx() ) <<
"Index wrong for second halfedge inside face 1 ";
268 EXPECT_EQ(2 , mesh_.to_vertex_handle(next).idx() ) <<
"second halfedge inside face 1 pointing to wrong vertex ";
270 next = mesh_.next_halfedge_handle(next);
271 EXPECT_EQ(6 , next.idx() ) <<
"Index wrong for third halfedge inside face 1 ";
272 EXPECT_EQ(3 , mesh_.to_vertex_handle(next).idx() ) <<
"Third halfedge inside face 1 pointing to wrong vertex ";
275 Mesh::HalfedgeHandle fh_2_he = mesh_.halfedge_handle(fh_2);
277 EXPECT_EQ(7 , fh_2_he.idx() ) <<
"Index wrong for first halfedge of face 2";
278 EXPECT_EQ(2 , mesh_.to_vertex_handle(fh_2_he).idx() ) <<
"First halfedge inside face 2 pointing to wrong vertex";
280 next = mesh_.next_halfedge_handle(fh_2_he);
281 EXPECT_EQ(3 , next.idx() ) <<
"Index wrong for second halfedge inside face 2";
282 EXPECT_EQ(1 , mesh_.to_vertex_handle(next).idx() ) <<
"second halfedge inside face 2 pointing to wrong vertex ";
284 next = mesh_.next_halfedge_handle(next);
285 EXPECT_EQ(10 , next.idx() ) <<
"Index wrong for third halfedge inside face 2";
286 EXPECT_EQ(3 , mesh_.to_vertex_handle(next).idx() ) <<
"Third halfedge inside face 2 pointing to wrong vertex ";
290 EXPECT_EQ(10 , voh_it->idx() ) <<
"Index wrong for first outgoing halfedge of vertex 1";
292 EXPECT_EQ(2 , voh_it->idx() ) <<
"Index wrong for second outgoing halfedge of vertex 1";
294 EXPECT_EQ(10 , voh_it->idx() ) <<
"Index wrong for third(one lap) outgoing halfedge of vertex 1";
297 voh_it = mesh_.voh_begin(mesh_.vertex_handle(2));
298 EXPECT_EQ(3 , voh_it->idx() ) <<
"Index wrong for first outgoing halfedge of vertex 2";
300 EXPECT_EQ(6 , voh_it->idx() ) <<
"Index wrong for second outgoing halfedge of vertex 2";
302 EXPECT_EQ(3 , voh_it->idx() ) <<
"Index wrong for third(one lap) outgoing halfedge of vertex 2";
305 voh_it = mesh_.voh_begin(mesh_.vertex_handle(3));
306 EXPECT_EQ(11 , voh_it->idx() ) <<
"Index wrong for first outgoing halfedge of vertex 3";
308 EXPECT_EQ(7 , voh_it->idx() ) <<
"Index wrong for second outgoing halfedge of vertex 3";
310 EXPECT_EQ(11 , voh_it->idx() ) <<
"Index wrong for third(one lap) outgoing halfedge of vertex 3";
315 mesh_.garbage_collection();
335 EXPECT_EQ(2u , mesh_.n_faces() ) <<
"Wrong number of faces (garbage collection executed!)";
338 Mesh::FaceHandle fh_0 = mesh_.face_handle(0);
339 fh_1 = mesh_.face_handle(1);
341 fv_it = mesh_.fv_begin(fh_0);
343 EXPECT_EQ(2 , fv_it->idx() ) <<
"Index wrong for Vertex 1 of face 0 after garbage collection";
345 EXPECT_EQ(1 , fv_it->idx() ) <<
"Index wrong for Vertex 2 of face 0 after garbage collection";
347 EXPECT_EQ(0 , fv_it->idx() ) <<
"Index wrong for Vertex 3 of face 0 after garbage collection";
349 fv_it = mesh_.fv_begin(fh_1);
350 EXPECT_EQ(1 , fv_it->idx() ) <<
"Index wrong for Vertex 1 of face 1 after garbage collection";
352 EXPECT_EQ(2 , fv_it->idx() ) <<
"Index wrong for Vertex 2 of face 1 after garbage collection";
354 EXPECT_EQ(0 , fv_it->idx() ) <<
"Index wrong for Vertex 3 of face 1 after garbage collection";
357 Mesh::HalfedgeHandle fh_0_he = mesh_.halfedge_handle(fh_0);
359 EXPECT_EQ(5 , fh_0_he.idx() ) <<
"Index wrong for first halfedge of face 0";
360 EXPECT_EQ(2 , mesh_.to_vertex_handle(fh_0_he).idx() ) <<
"First halfedge inside face 0 pointing to wrong vertex";
362 next = mesh_.next_halfedge_handle(fh_0_he);
363 EXPECT_EQ(3 , next.idx() ) <<
"Index wrong for second halfedge inside face 0 ";
364 EXPECT_EQ(1 , mesh_.to_vertex_handle(next).idx() ) <<
"second halfedge inside face 0 pointing to wrong vertex ";
366 next = mesh_.next_halfedge_handle(next);
367 EXPECT_EQ(0 , next.idx() ) <<
"Index wrong for third halfedge inside face 0 ";
368 EXPECT_EQ(0 , mesh_.to_vertex_handle(next).idx() ) <<
"Third halfedge inside face 0 pointing to wrong vertex ";
371 fh_1_he = mesh_.halfedge_handle(fh_1);
373 EXPECT_EQ(1 , fh_1_he.idx() ) <<
"Index wrong for first halfedge of face 1";
374 EXPECT_EQ(1 , mesh_.to_vertex_handle(fh_1_he).idx() ) <<
"First halfedge inside face 1 pointing to wrong vertex";
376 next = mesh_.next_halfedge_handle(fh_1_he);
377 EXPECT_EQ(2 , next.idx() ) <<
"Index wrong for second halfedge inside face 1 ";
378 EXPECT_EQ(2 , mesh_.to_vertex_handle(next).idx() ) <<
"second halfedge inside face 1 pointing to wrong vertex ";
380 next = mesh_.next_halfedge_handle(next);
381 EXPECT_EQ(4 , next.idx() ) <<
"Index wrong for third halfedge inside face 1 ";
382 EXPECT_EQ(0 , mesh_.to_vertex_handle(next).idx() ) <<
"Third halfedge inside face 1 pointing to wrong vertex ";
386 voh_it = mesh_.voh_begin(mesh_.vertex_handle(0));
387 EXPECT_EQ(1 , voh_it->idx() ) <<
"Index wrong for first outgoing halfedge of vertex 0";
389 EXPECT_EQ(5 , voh_it->idx() ) <<
"Index wrong for second outgoing halfedge of vertex 0";
391 EXPECT_EQ(1 , voh_it->idx() ) <<
"Index wrong for third(one lap) outgoing halfedge of vertex 0";
394 voh_it = mesh_.voh_begin(mesh_.vertex_handle(1));
395 EXPECT_EQ(0 , voh_it->idx() ) <<
"Index wrong for first outgoing halfedge of vertex 1";
397 EXPECT_EQ(2 , voh_it->idx() ) <<
"Index wrong for second outgoing halfedge of vertex 1";
399 EXPECT_EQ(0 , voh_it->idx() ) <<
"Index wrong for third(one lap) outgoing halfedge of vertex 1";
402 voh_it = mesh_.voh_begin(mesh_.vertex_handle(2));
403 EXPECT_EQ(3 , voh_it->idx() ) <<
"Index wrong for first outgoing halfedge of vertex 2";
405 EXPECT_EQ(4 , voh_it->idx() ) <<
"Index wrong for second outgoing halfedge of vertex 2";
407 EXPECT_EQ(3 , voh_it->idx() ) <<
"Index wrong for third(one lap) outgoing halfedge of vertex 2";
409 EXPECT_FALSE( mesh_.is_collapse_ok(mesh_.halfedge_handle(0)) ) <<
"Collapse should be not ok for halfedge 0";
410 EXPECT_FALSE( mesh_.is_collapse_ok(mesh_.halfedge_handle(1)) ) <<
"Collapse should be not ok for halfedge 1";
411 EXPECT_FALSE( mesh_.is_collapse_ok(mesh_.halfedge_handle(2)) ) <<
"Collapse should be not ok for halfedge 2";
412 EXPECT_FALSE( mesh_.is_collapse_ok(mesh_.halfedge_handle(3)) ) <<
"Collapse should be not ok for halfedge 3";
413 EXPECT_FALSE( mesh_.is_collapse_ok(mesh_.halfedge_handle(4)) ) <<
"Collapse should be not ok for halfedge 4";
414 EXPECT_FALSE( mesh_.is_collapse_ok(mesh_.halfedge_handle(5)) ) <<
"Collapse should be not ok for halfedge 5";
420 TEST_F(OpenMeshCollapse, CollapseTetrahedron) {
435 std::vector<Mesh::VertexHandle> face_vhandles;
437 face_vhandles.push_back(vhandle[0]);
438 face_vhandles.push_back(vhandle[4]);
439 face_vhandles.push_back(vhandle[2]);
440 mesh_.add_face(face_vhandles);
442 face_vhandles.clear();
444 face_vhandles.push_back(vhandle[3]);
445 face_vhandles.push_back(vhandle[4]);
446 face_vhandles.push_back(vhandle[0]);
447 mesh_.add_face(face_vhandles);
449 face_vhandles.clear();
451 face_vhandles.push_back(vhandle[2]);
452 face_vhandles.push_back(vhandle[4]);
453 face_vhandles.push_back(vhandle[3]);
454 mesh_.add_face(face_vhandles);
456 face_vhandles.clear();
458 face_vhandles.push_back(vhandle[2]);
459 face_vhandles.push_back(vhandle[1]);
460 face_vhandles.push_back(vhandle[0]);
461 mesh_.add_face(face_vhandles);
463 face_vhandles.clear();
465 face_vhandles.push_back(vhandle[0]);
466 face_vhandles.push_back(vhandle[1]);
467 face_vhandles.push_back(vhandle[3]);
468 mesh_.add_face(face_vhandles);
470 mesh_.request_vertex_status();
471 mesh_.request_edge_status();
472 mesh_.request_face_status();
479 Mesh::HalfedgeHandle heh_collapse1 = mesh_.halfedge_handle(0);
481 EXPECT_EQ(4, mesh_.to_vertex_handle(heh_collapse1).idx() ) <<
"To vertex of collapse halfedge 1 is wrong";
482 EXPECT_EQ(0, mesh_.from_vertex_handle(heh_collapse1).idx() ) <<
"from vertex of collapse halfedge 1 is wrong";
484 EXPECT_TRUE( mesh_.is_collapse_ok(heh_collapse1) ) <<
"Collapse not ok for collapse first halfedge (0)";
485 mesh_.collapse(heh_collapse1);
487 Mesh::HalfedgeHandle heh_collapse2 = mesh_.halfedge_handle(2);
489 EXPECT_EQ(2, mesh_.to_vertex_handle(heh_collapse2).idx() ) <<
"To vertex of collapse halfedge 2 is wrong";
490 EXPECT_EQ(4, mesh_.from_vertex_handle(heh_collapse2).idx() ) <<
"from vertex of collapse halfedge 2 is wrong";
492 EXPECT_TRUE( mesh_.is_collapse_ok(heh_collapse2) ) <<
"Collapse not ok for collapse second halfedge (2)";
493 mesh_.collapse(heh_collapse2);
495 Mesh::HalfedgeHandle heh_collapse3 = mesh_.halfedge_handle(6);
497 EXPECT_EQ(2, mesh_.to_vertex_handle(heh_collapse3).idx() ) <<
"To vertex of collapse halfedge 3 is wrong";
498 EXPECT_EQ(3, mesh_.from_vertex_handle(heh_collapse3).idx() ) <<
"from vertex of collapse halfedge 3 is wrong";
500 EXPECT_FALSE( mesh_.is_collapse_ok(heh_collapse3) ) <<
"Collapse not ok for collapse third halfedge (6)";
509 TEST_F(OpenMeshCollapse, LargeCollapseHalfEdge) {
525 std::vector<Mesh::VertexHandle> face_vhandles;
527 face_vhandles.push_back(vhandle[0]);
528 face_vhandles.push_back(vhandle[5]);
529 face_vhandles.push_back(vhandle[1]);
530 mesh_.add_face(face_vhandles);
532 face_vhandles.clear();
534 face_vhandles.push_back(vhandle[1]);
535 face_vhandles.push_back(vhandle[5]);
536 face_vhandles.push_back(vhandle[3]);
537 mesh_.add_face(face_vhandles);
539 face_vhandles.clear();
541 face_vhandles.push_back(vhandle[0]);
542 face_vhandles.push_back(vhandle[1]);
543 face_vhandles.push_back(vhandle[2]);
544 mesh_.add_face(face_vhandles);
546 face_vhandles.clear();
548 face_vhandles.push_back(vhandle[1]);
549 face_vhandles.push_back(vhandle[3]);
550 face_vhandles.push_back(vhandle[4]);
551 mesh_.add_face(face_vhandles);
553 face_vhandles.clear();
555 face_vhandles.push_back(vhandle[2]);
556 face_vhandles.push_back(vhandle[1]);
557 face_vhandles.push_back(vhandle[4]);
558 mesh_.add_face(face_vhandles);
560 face_vhandles.clear();
562 face_vhandles.push_back(vhandle[2]);
563 face_vhandles.push_back(vhandle[4]);
564 face_vhandles.push_back(vhandle[6]);
565 mesh_.add_face(face_vhandles);
577 mesh_.request_vertex_status();
578 mesh_.request_edge_status();
579 mesh_.request_face_status();
585 Mesh::HalfedgeHandle heh_collapse;
588 for ( Mesh::HalfedgeIter he_it = mesh_.halfedges_begin() ; he_it != mesh_.halfedges_end() ; ++he_it ) {
589 if ( mesh_.from_vertex_handle(*he_it).idx() == 1 && mesh_.to_vertex_handle(*he_it).idx() == 4 )
590 heh_collapse = *he_it;
594 EXPECT_EQ(4, mesh_.to_vertex_handle(heh_collapse).idx() ) <<
"To vertex of collapse halfedge is wrong";
595 EXPECT_EQ(1, mesh_.from_vertex_handle(heh_collapse).idx() ) <<
"from vertex of collapse halfedge is wrong";
596 EXPECT_TRUE( mesh_.is_collapse_ok(heh_collapse) ) <<
"Collapse not ok for collapse first halfedge (0)";
603 mesh_.collapse(heh_collapse);
605 EXPECT_TRUE( mesh_.status(vh_from).deleted() ) <<
"From vertex not deleted";
606 EXPECT_FALSE( mesh_.status(vh_to).deleted() ) <<
"To Vertex deleted";
Kernel::Point Point
Coordinate type.
VertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
Kernel::VertexOHalfedgeIter VertexOHalfedgeIter
Circulator.
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Kernel::FaceVertexIter FaceVertexIter
Circulator.