Developer Documentation
unittests_trimesh_garbage_collection.cc
1 #include <gtest/gtest.h>
2 #include <Unittests/unittests_common.hh>
3 
4 #include <iostream>
5 
6 namespace {
7 
8 class OpenMeshTriMeshGarbageCollection : public OpenMeshBase {
9 
10  protected:
11 
12  // This function is called before each test is run
13  virtual void SetUp() {
14  }
15 
16  // This function is called after all tests are through
17  virtual void TearDown() {
18 
19  // Do some final stuff with the member data here...
20  }
21 
22  // Member already defined in OpenMeshBase
23  //Mesh mesh_;
24 };
25 
26 /*
27  * ====================================================================
28  * Define tests below
29  * ====================================================================
30  */
31 
32 /* Adds a cube to a trimesh and deletes vertex 0 and calls garbage collection afterwards
33  */
34 TEST_F(OpenMeshTriMeshGarbageCollection, StandardGarbageCollection) {
35 
36  mesh_.clear();
37 
38  mesh_.request_vertex_status();
39  mesh_.request_edge_status();
40  mesh_.request_halfedge_status();
41  mesh_.request_face_status();
42 
43  // Add some vertices
44  Mesh::VertexHandle vhandle[8];
45  vhandle[0] = mesh_.add_vertex(Mesh::Point(-1, -1, 1));
46  vhandle[1] = mesh_.add_vertex(Mesh::Point( 1, -1, 1));
47  vhandle[2] = mesh_.add_vertex(Mesh::Point( 1, 1, 1));
48  vhandle[3] = mesh_.add_vertex(Mesh::Point(-1, 1, 1));
49  vhandle[4] = mesh_.add_vertex(Mesh::Point(-1, -1, -1));
50  vhandle[5] = mesh_.add_vertex(Mesh::Point( 1, -1, -1));
51  vhandle[6] = mesh_.add_vertex(Mesh::Point( 1, 1, -1));
52  vhandle[7] = mesh_.add_vertex(Mesh::Point(-1, 1, -1));
53 
54  // Add six faces to form a cube
55  std::vector<Mesh::VertexHandle> face_vhandles;
56 
57  face_vhandles.clear();
58  face_vhandles.push_back(vhandle[0]);
59  face_vhandles.push_back(vhandle[1]);
60  face_vhandles.push_back(vhandle[3]);
61  mesh_.add_face(face_vhandles);
62 
63  face_vhandles.clear();
64  face_vhandles.push_back(vhandle[1]);
65  face_vhandles.push_back(vhandle[2]);
66  face_vhandles.push_back(vhandle[3]);
67  mesh_.add_face(face_vhandles);
68 
69  //=======================
70 
71  face_vhandles.clear();
72  face_vhandles.push_back(vhandle[7]);
73  face_vhandles.push_back(vhandle[6]);
74  face_vhandles.push_back(vhandle[5]);
75  mesh_.add_face(face_vhandles);
76 
77  face_vhandles.clear();
78  face_vhandles.push_back(vhandle[7]);
79  face_vhandles.push_back(vhandle[5]);
80  face_vhandles.push_back(vhandle[4]);
81  mesh_.add_face(face_vhandles);
82 
83  //=======================
84 
85  face_vhandles.clear();
86  face_vhandles.push_back(vhandle[1]);
87  face_vhandles.push_back(vhandle[0]);
88  face_vhandles.push_back(vhandle[4]);
89  mesh_.add_face(face_vhandles);
90 
91  face_vhandles.clear();
92  face_vhandles.push_back(vhandle[1]);
93  face_vhandles.push_back(vhandle[4]);
94  face_vhandles.push_back(vhandle[5]);
95  mesh_.add_face(face_vhandles);
96 
97  //=======================
98 
99  face_vhandles.clear();
100  face_vhandles.push_back(vhandle[2]);
101  face_vhandles.push_back(vhandle[1]);
102  face_vhandles.push_back(vhandle[5]);
103  mesh_.add_face(face_vhandles);
104 
105  face_vhandles.clear();
106  face_vhandles.push_back(vhandle[2]);
107  face_vhandles.push_back(vhandle[5]);
108  face_vhandles.push_back(vhandle[6]);
109  mesh_.add_face(face_vhandles);
110 
111 
112  //=======================
113 
114  face_vhandles.clear();
115  face_vhandles.push_back(vhandle[3]);
116  face_vhandles.push_back(vhandle[2]);
117  face_vhandles.push_back(vhandle[6]);
118  mesh_.add_face(face_vhandles);
119 
120  face_vhandles.clear();
121  face_vhandles.push_back(vhandle[3]);
122  face_vhandles.push_back(vhandle[6]);
123  face_vhandles.push_back(vhandle[7]);
124  mesh_.add_face(face_vhandles);
125 
126  //=======================
127 
128  face_vhandles.clear();
129  face_vhandles.push_back(vhandle[0]);
130  face_vhandles.push_back(vhandle[3]);
131  face_vhandles.push_back(vhandle[7]);
132  mesh_.add_face(face_vhandles);
133 
134  face_vhandles.clear();
135  face_vhandles.push_back(vhandle[0]);
136  face_vhandles.push_back(vhandle[7]);
137  face_vhandles.push_back(vhandle[4]);
138  mesh_.add_face(face_vhandles);
139 
140 
141  // Test setup:
142  //
143  //
144  // 3 ======== 2
145  // / /|
146  // / / | z
147  // 0 ======== 1 | |
148  // | | | | y
149  // | 7 | 6 | /
150  // | | / | /
151  // | |/ |/
152  // 4 ======== 5 -------> x
153  //
154 
155  // Check setup
156  EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong initial number of vertices";
157  EXPECT_EQ(12u, mesh_.n_faces() ) << "Wrong initial number of faces";
158 
159  mesh_.delete_vertex(vhandle[0]);
160 
161  // Check setup
162  EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong number of vertices after deletion";
163  EXPECT_EQ(12u, mesh_.n_faces() ) << "Wrong number of faces after deletion";
164 
165  mesh_.garbage_collection();
166 
167  // Check setup
168  EXPECT_EQ(7u, mesh_.n_vertices() ) << "Wrong number of vertices after garbage collection";
169  EXPECT_EQ(8u, mesh_.n_faces() ) << "Wrong number of faces after garbage collection";
170 
171 }
172 
173 /* Adds a cube to a trimesh and deletes vertex 0 and calls garbage collection afterwards.
174  * But this time, we track the vertex handles , halfedge handles, and face handles
175  */
176 TEST_F(OpenMeshTriMeshGarbageCollection, TrackedGarbageCollection) {
177 
178  mesh_.clear();
179 
180  mesh_.request_vertex_status();
181  mesh_.request_edge_status();
182  mesh_.request_halfedge_status();
183  mesh_.request_face_status();
184 
185  // Add some vertices
186  Mesh::VertexHandle vhandle[8];
187  vhandle[0] = mesh_.add_vertex(Mesh::Point(-1, -1, 1));
188  vhandle[1] = mesh_.add_vertex(Mesh::Point( 1, -1, 1));
189  vhandle[2] = mesh_.add_vertex(Mesh::Point( 1, 1, 1));
190  vhandle[3] = mesh_.add_vertex(Mesh::Point(-1, 1, 1));
191  vhandle[4] = mesh_.add_vertex(Mesh::Point(-1, -1, -1));
192  vhandle[5] = mesh_.add_vertex(Mesh::Point( 1, -1, -1));
193  vhandle[6] = mesh_.add_vertex(Mesh::Point( 1, 1, -1));
194  vhandle[7] = mesh_.add_vertex(Mesh::Point(-1, 1, -1));
195 
196  // Add six faces to form a cube
197  std::vector<Mesh::VertexHandle> face_vhandles;
198 
199  // 0
200  face_vhandles.clear();
201  face_vhandles.push_back(vhandle[0]);
202  face_vhandles.push_back(vhandle[1]);
203  face_vhandles.push_back(vhandle[3]);
204  mesh_.add_face(face_vhandles);
205 
206  // 1
207  face_vhandles.clear();
208  face_vhandles.push_back(vhandle[1]);
209  face_vhandles.push_back(vhandle[2]);
210  face_vhandles.push_back(vhandle[3]);
211  mesh_.add_face(face_vhandles);
212 
213  //=======================
214 
215  // 2
216  face_vhandles.clear();
217  face_vhandles.push_back(vhandle[7]);
218  face_vhandles.push_back(vhandle[6]);
219  face_vhandles.push_back(vhandle[5]);
220  mesh_.add_face(face_vhandles);
221 
222  // 3
223  face_vhandles.clear();
224  face_vhandles.push_back(vhandle[7]);
225  face_vhandles.push_back(vhandle[5]);
226  face_vhandles.push_back(vhandle[4]);
227  mesh_.add_face(face_vhandles);
228 
229  //=======================
230 
231  // 4
232  face_vhandles.clear();
233  face_vhandles.push_back(vhandle[1]);
234  face_vhandles.push_back(vhandle[0]);
235  face_vhandles.push_back(vhandle[4]);
236  mesh_.add_face(face_vhandles);
237 
238  // 5
239  face_vhandles.clear();
240  face_vhandles.push_back(vhandle[1]);
241  face_vhandles.push_back(vhandle[4]);
242  face_vhandles.push_back(vhandle[5]);
243  mesh_.add_face(face_vhandles);
244 
245  //=======================
246 
247  // 6
248  face_vhandles.clear();
249  face_vhandles.push_back(vhandle[2]);
250  face_vhandles.push_back(vhandle[1]);
251  face_vhandles.push_back(vhandle[5]);
252  mesh_.add_face(face_vhandles);
253 
254  // 7
255  face_vhandles.clear();
256  face_vhandles.push_back(vhandle[2]);
257  face_vhandles.push_back(vhandle[5]);
258  face_vhandles.push_back(vhandle[6]);
259  mesh_.add_face(face_vhandles);
260 
261 
262  //=======================
263 
264  // 8
265  face_vhandles.clear();
266  face_vhandles.push_back(vhandle[3]);
267  face_vhandles.push_back(vhandle[2]);
268  face_vhandles.push_back(vhandle[6]);
269  mesh_.add_face(face_vhandles);
270 
271  // 9
272  face_vhandles.clear();
273  face_vhandles.push_back(vhandle[3]);
274  face_vhandles.push_back(vhandle[6]);
275  face_vhandles.push_back(vhandle[7]);
276  mesh_.add_face(face_vhandles);
277 
278  //=======================
279 
280  // 10
281  face_vhandles.clear();
282  face_vhandles.push_back(vhandle[0]);
283  face_vhandles.push_back(vhandle[3]);
284  face_vhandles.push_back(vhandle[7]);
285  mesh_.add_face(face_vhandles);
286 
287  // 11
288  face_vhandles.clear();
289  face_vhandles.push_back(vhandle[0]);
290  face_vhandles.push_back(vhandle[7]);
291  face_vhandles.push_back(vhandle[4]);
292  mesh_.add_face(face_vhandles);
293 
294 
295  // Test setup:
296  //
297  //
298  // 3 ======== 2
299  // / /|
300  // / / | z
301  // 0 ======== 1 | |
302  // | | | | y
303  // | 7 | 6 | /
304  // | | / | /
305  // | |/ |/
306  // 4 ======== 5 -------> x
307  //
308 
309  // Check setup
310  EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong initial number of vertices";
311  EXPECT_EQ(12u, mesh_.n_faces() ) << "Wrong initial number of faces";
312 
313  //==================================================
314  // Create vectors containing the current handles
315  //==================================================
316  std::vector<Mesh::VertexHandle> vertexHandles;
317  for ( Mesh::VertexIter v_it = mesh_.vertices_begin(); v_it != mesh_.vertices_end(); ++v_it)
318  vertexHandles.push_back(*v_it);
319 
320  std::vector<Mesh::HalfedgeHandle> halfedgeHandles;
321  for ( Mesh::HalfedgeIter he_it = mesh_.halfedges_begin(); he_it != mesh_.halfedges_end(); ++he_it)
322  halfedgeHandles.push_back(*he_it);
323 
324  std::vector<Mesh::FaceHandle> faceHandles;
325  for ( Mesh::FaceIter f_it = mesh_.faces_begin(); f_it != mesh_.faces_end(); ++f_it)
326  faceHandles.push_back(*f_it);
327 
328  //==================================================
329  // Create vectors containing pointers current handles
330  //==================================================
331  std::vector<Mesh::VertexHandle*> vertexHandlesP;
332  for ( unsigned int i = 0 ; i < vertexHandles.size() ; ++i)
333  vertexHandlesP.push_back(&(vertexHandles[i]));
334 
335  std::vector<Mesh::HalfedgeHandle*> halfedgeHandlesP;
336  for ( unsigned int i = 0 ; i < halfedgeHandles.size() ; ++i) {
337  halfedgeHandlesP.push_back(&(halfedgeHandles[i]));
338  }
339 
340  std::vector<Mesh::FaceHandle*> faceHandlesP;
341  for ( unsigned int i = 0 ; i < faceHandles.size() ; ++i)
342  faceHandlesP.push_back(&(faceHandles[i]));
343 
344 // // REMOVE
345 //
346 // OpenMesh::HPropHandleT<int> handle;
347 // mesh_.add_property(handle,"tmp");
348 //
349 //
350 // int count = 0;
351 //
352 // for ( Mesh::HalfedgeIter he_it = mesh_.halfedges_begin(); he_it != mesh_.halfedges_end() ; ++he_it) {
353 // mesh_.property(handle,he_it) =count;
354 // ++count;
355 // }
356 
357 // std::cerr << "Vertex : ";
358 // for ( unsigned int i = 0 ; i < vertexHandles.size() ; ++i)
359 // std::cerr << vertexHandles[i].idx() << " ";
360 // std::cerr << std::endl;
361 //
362 // std::cerr << "Halfedge : ";
363 // for ( unsigned int i = 0 ; i < halfedgeHandles.size() ; ++i)
364 // std::cerr << halfedgeHandles[i].idx() << " ";
365 // std::cerr << std::endl;
366 //
367 // std::cerr << "Halfedge property : ";
368 // for ( Mesh::HalfedgeIter he_it = mesh_.halfedges_begin(); he_it != mesh_.halfedges_end() ; ++he_it) {
369 // std::cerr << mesh_.property(handle,he_it) << " ";
370 // }
371 // std::cerr << std::endl;
372 //
373 // std::cerr << "Face : ";
374 // for ( unsigned int i = 0 ; i < faceHandles.size() ; ++i)
375 // std::cerr << faceHandles[i].idx() << " ";
376 // std::cerr << std::endl;
377  // REMOVE END
378 
379 
380  // Deleting vertex 0
381  // -> deletes vertex 0
382  // -> deletes faces 0,4,10,11
383  mesh_.delete_vertex(vhandle[0]);
384  //mesh_.delete_vertex(vhandle[7]);
385 
386  // Check setup
387  EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong number of vertices after deletion";
388  EXPECT_EQ(12u, mesh_.n_faces() ) << "Wrong number of faces after deletion";
389 
390  mesh_.garbage_collection(vertexHandlesP,halfedgeHandlesP,faceHandlesP,true,true,true);
391 
392  // Check setup
393  EXPECT_EQ(7u, mesh_.n_vertices() ) << "Wrong number of vertices after garbage collection";
394  EXPECT_EQ(8u, mesh_.n_faces() ) << "Wrong number of faces after garbage collection";
395 
396  //================================
397  // Check the updated handles
398  //================================
399 
400 // // // REMOVE
401 // std::cerr << "Vertex : ";
402 // for ( unsigned int i = 0 ; i < vertexHandles.size() ; ++i)
403 // std::cerr << vertexHandles[i].idx() << " ";
404 // std::cerr << std::endl;
405 //
406 // std::cerr << "Halfedge : ";
407 // for ( unsigned int i = 0 ; i < halfedgeHandles.size() ; ++i)
408 // std::cerr << halfedgeHandles[i].idx() << " ";
409 // std::cerr << std::endl;
410 //
411 // std::cerr << "Halfedge property : ";
412 // for ( Mesh::HalfedgeIter he_it = mesh_.halfedges_begin(); he_it != mesh_.halfedges_end() ; ++he_it) {
413 // std::cerr << mesh_.property(handle,he_it) << " ";
414 // }
415 // std::cerr << std::endl;
416 //
417 // std::cerr << "Face : ";
418 // for ( unsigned int i = 0 ; i < faceHandles.size() ; ++i)
419 // std::cerr << faceHandles[i].idx() << " ";
420 // std::cerr << std::endl;
421  // REMOVE END
422 
423  // Check setup of vertices
424  EXPECT_EQ(-1, vertexHandles[0].idx() ) << "Wrong vertex handle after update";
425  EXPECT_EQ(1 , vertexHandles[1].idx() ) << "Wrong vertex handle after update";
426  EXPECT_EQ(2 , vertexHandles[2].idx() ) << "Wrong vertex handle after update";
427  EXPECT_EQ(3 , vertexHandles[3].idx() ) << "Wrong vertex handle after update";
428  EXPECT_EQ(4 , vertexHandles[4].idx() ) << "Wrong vertex handle after update";
429  EXPECT_EQ(5 , vertexHandles[5].idx() ) << "Wrong vertex handle after update";
430  EXPECT_EQ(6 , vertexHandles[6].idx() ) << "Wrong vertex handle after update";
431  EXPECT_EQ(0 , vertexHandles[7].idx() ) << "Wrong vertex handle after update";
432 
433  // Check setup of halfedge handles
434  EXPECT_EQ(-1, halfedgeHandles[0 ].idx() ) << "Wrong halfedge handle after update";
435  EXPECT_EQ(-1, halfedgeHandles[1 ].idx() ) << "Wrong halfedge handle after update";
436  EXPECT_EQ( 2, halfedgeHandles[2 ].idx() ) << "Wrong halfedge handle after update";
437  EXPECT_EQ( 3, halfedgeHandles[3 ].idx() ) << "Wrong halfedge handle after update";
438  EXPECT_EQ(-1, halfedgeHandles[4 ].idx() ) << "Wrong halfedge handle after update";
439  EXPECT_EQ(-1, halfedgeHandles[5 ].idx() ) << "Wrong halfedge handle after update";
440  EXPECT_EQ( 6, halfedgeHandles[6 ].idx() ) << "Wrong halfedge handle after update";
441  EXPECT_EQ( 7, halfedgeHandles[7 ].idx() ) << "Wrong halfedge handle after update";
442  EXPECT_EQ( 8, halfedgeHandles[8 ].idx() ) << "Wrong halfedge handle after update";
443  EXPECT_EQ( 9, halfedgeHandles[9 ].idx() ) << "Wrong halfedge handle after update";
444  EXPECT_EQ(10, halfedgeHandles[10].idx() ) << "Wrong halfedge handle after update";
445  EXPECT_EQ(11, halfedgeHandles[11].idx() ) << "Wrong halfedge handle after update";
446  EXPECT_EQ(12, halfedgeHandles[12].idx() ) << "Wrong halfedge handle after update";
447  EXPECT_EQ(13, halfedgeHandles[13].idx() ) << "Wrong halfedge handle after update";
448  EXPECT_EQ(14, halfedgeHandles[14].idx() ) << "Wrong halfedge handle after update";
449  EXPECT_EQ(15, halfedgeHandles[15].idx() ) << "Wrong halfedge handle after update";
450  EXPECT_EQ(16, halfedgeHandles[16].idx() ) << "Wrong halfedge handle after update";
451  EXPECT_EQ(17, halfedgeHandles[17].idx() ) << "Wrong halfedge handle after update";
452  EXPECT_EQ(18, halfedgeHandles[18].idx() ) << "Wrong halfedge handle after update";
453  EXPECT_EQ(19, halfedgeHandles[19].idx() ) << "Wrong halfedge handle after update";
454  EXPECT_EQ(-1, halfedgeHandles[20].idx() ) << "Wrong halfedge handle after update";
455  EXPECT_EQ(-1, halfedgeHandles[21].idx() ) << "Wrong halfedge handle after update";
456  EXPECT_EQ(22, halfedgeHandles[22].idx() ) << "Wrong halfedge handle after update";
457  EXPECT_EQ(23, halfedgeHandles[23].idx() ) << "Wrong halfedge handle after update";
458  EXPECT_EQ(24, halfedgeHandles[24].idx() ) << "Wrong halfedge handle after update";
459  EXPECT_EQ(25, halfedgeHandles[25].idx() ) << "Wrong halfedge handle after update";
460  EXPECT_EQ(26, halfedgeHandles[26].idx() ) << "Wrong halfedge handle after update";
461  EXPECT_EQ(27, halfedgeHandles[27].idx() ) << "Wrong halfedge handle after update";
462  EXPECT_EQ(20, halfedgeHandles[28].idx() ) << "Wrong halfedge handle after update";
463  EXPECT_EQ(21, halfedgeHandles[29].idx() ) << "Wrong halfedge handle after update";
464  EXPECT_EQ( 4, halfedgeHandles[30].idx() ) << "Wrong halfedge handle after update";
465  EXPECT_EQ( 5, halfedgeHandles[31].idx() ) << "Wrong halfedge handle after update";
466  EXPECT_EQ( 0, halfedgeHandles[32].idx() ) << "Wrong halfedge handle after update";
467  EXPECT_EQ( 1, halfedgeHandles[33].idx() ) << "Wrong halfedge handle after update";
468  EXPECT_EQ(-1, halfedgeHandles[34].idx() ) << "Wrong halfedge handle after update";
469  EXPECT_EQ(-1, halfedgeHandles[35].idx() ) << "Wrong halfedge handle after update";
470 
471  // Check setup of faces
472  EXPECT_EQ(-1 , faceHandles[0 ].idx() ) << "Wrong face handle after update";
473  EXPECT_EQ(1 , faceHandles[1 ].idx() ) << "Wrong face handle after update";
474  EXPECT_EQ(2 , faceHandles[2 ].idx() ) << "Wrong face handle after update";
475  EXPECT_EQ(3 , faceHandles[3 ].idx() ) << "Wrong face handle after update";
476  EXPECT_EQ(-1 , faceHandles[4 ].idx() ) << "Wrong face handle after update";
477  EXPECT_EQ(5 , faceHandles[5 ].idx() ) << "Wrong face handle after update";
478  EXPECT_EQ(6 , faceHandles[6 ].idx() ) << "Wrong face handle after update";
479  EXPECT_EQ(7 , faceHandles[7 ].idx() ) << "Wrong face handle after update";
480  EXPECT_EQ(4 , faceHandles[8 ].idx() ) << "Wrong face handle after update";
481  EXPECT_EQ(0 , faceHandles[9 ].idx() ) << "Wrong face handle after update";
482  EXPECT_EQ(-1 , faceHandles[10].idx() ) << "Wrong face handle after update";
483  EXPECT_EQ(-1 , faceHandles[11].idx() ) << "Wrong face handle after update";
484 
485 }
486 
487 
488 }
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:139
VertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
Definition: PolyMeshT.hh:236
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:115