Developer Documentation
unittests_subdivider_uniform.cc
1 
2 #include <gtest/gtest.h>
3 #include <Unittests/unittests_common.hh>
6 #include <OpenMesh/Tools/Subdivider/Uniform/MidpointT.hh>
7 
8 namespace {
9 
10 class OpenMeshSubdividerUniform_Poly : public OpenMeshBasePoly {
11 protected:
12  // This function is called before each test is run
13  virtual void SetUp() {
14  // Do some initial stuff with the member data here...
15  }
16 
17  // This function is called after all tests are through
18  virtual void TearDown() {
19  // Do some final stuff with the member data here...
20  }
21 
22  // Member already defined in OpenMeshBase
23  //Mesh mesh_;
24 };
25 
26 class OpenMeshSubdividerUniform_Triangle : public OpenMeshBase {
27 protected:
28  // This function is called before each test is run
29  virtual void SetUp() {
30  // Do some initial stuff with the member data here...
31  }
32 
33  // This function is called after all tests are through
34  virtual void TearDown() {
35  // Do some final stuff with the member data here...
36  }
37 
38  // Member already defined in OpenMeshBase
39  //Mesh mesh_;
40 };
41 
42 /*
43  * ====================================================================
44  * Define tests below
45  * ====================================================================
46  */
47 
48 TEST_F(OpenMeshSubdividerUniform_Triangle, Subdivider_Sqrt3) {
49  mesh_.clear();
50 
51  // Add some vertices
52  Mesh::VertexHandle vhandle[9];
53 
54  vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
55  vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
56  vhandle[2] = mesh_.add_vertex(Mesh::Point(0, 2, 0));
57  vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
58  vhandle[4] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
59  vhandle[5] = mesh_.add_vertex(Mesh::Point(1, 2, 0));
60  vhandle[6] = mesh_.add_vertex(Mesh::Point(2, 0, 0));
61  vhandle[7] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
62  vhandle[8] = mesh_.add_vertex(Mesh::Point(2, 2, 0));
63 
64  // Add eight faces
65  std::vector<Mesh::VertexHandle> face_vhandles;
66 
67  face_vhandles.push_back(vhandle[0]);
68  face_vhandles.push_back(vhandle[4]);
69  face_vhandles.push_back(vhandle[3]);
70 
71  mesh_.add_face(face_vhandles);
72  face_vhandles.clear();
73 
74  face_vhandles.push_back(vhandle[0]);
75  face_vhandles.push_back(vhandle[1]);
76  face_vhandles.push_back(vhandle[4]);
77 
78  mesh_.add_face(face_vhandles);
79  face_vhandles.clear();
80 
81  face_vhandles.push_back(vhandle[1]);
82  face_vhandles.push_back(vhandle[2]);
83  face_vhandles.push_back(vhandle[4]);
84 
85  mesh_.add_face(face_vhandles);
86  face_vhandles.clear();
87 
88  face_vhandles.push_back(vhandle[2]);
89  face_vhandles.push_back(vhandle[5]);
90  face_vhandles.push_back(vhandle[4]);
91 
92  mesh_.add_face(face_vhandles);
93  face_vhandles.clear();
94 
95  face_vhandles.push_back(vhandle[3]);
96  face_vhandles.push_back(vhandle[7]);
97  face_vhandles.push_back(vhandle[6]);
98 
99  mesh_.add_face(face_vhandles);
100  face_vhandles.clear();
101 
102  face_vhandles.push_back(vhandle[3]);
103  face_vhandles.push_back(vhandle[4]);
104  face_vhandles.push_back(vhandle[7]);
105 
106  mesh_.add_face(face_vhandles);
107  face_vhandles.clear();
108 
109  face_vhandles.push_back(vhandle[4]);
110  face_vhandles.push_back(vhandle[8]);
111  face_vhandles.push_back(vhandle[7]);
112 
113  mesh_.add_face(face_vhandles);
114  face_vhandles.clear();
115 
116  face_vhandles.push_back(vhandle[4]);
117  face_vhandles.push_back(vhandle[5]);
118  face_vhandles.push_back(vhandle[8]);
119 
120  mesh_.add_face(face_vhandles);
121 
122  // Test setup:
123  // 6 === 7 === 8
124  // | / | / |
125  // | / | / |
126  // | / | / |
127  // 3 === 4 === 5
128  // | / | \ |
129  // | / | \ |
130  // | / | \ |
131  // 0 === 1 === 2
132 
133  // Initialize subdivider
135 
136  // Check setup
137  EXPECT_EQ(9u, mesh_.n_vertices() ) << "Wrong number of vertices";
138  EXPECT_EQ(8u, mesh_.n_faces() ) << "Wrong number of faces";
139 
140  // Execute 3 subdivision steps
141  sqrt3.attach(mesh_);
142  sqrt3( 3 );
143  sqrt3.detach();
144 
145  // Check setup
146  EXPECT_EQ(121u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with sqrt3";
147  EXPECT_EQ(216u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with sqrt3";
148 }
149 
150 /*
151  * ====================================================================
152  * Define tests below
153  * ====================================================================
154  */
155 
156 /*
157  */
158 TEST_F(OpenMeshSubdividerUniform_Poly, Subdivider_CatmullClark) {
159  mesh_.clear();
160 
161  // Add some vertices
162  Mesh::VertexHandle vhandle[9];
163 
164  vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
165  vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
166  vhandle[2] = mesh_.add_vertex(Mesh::Point(0, 2, 0));
167  vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
168  vhandle[4] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
169  vhandle[5] = mesh_.add_vertex(Mesh::Point(1, 2, 0));
170  vhandle[6] = mesh_.add_vertex(Mesh::Point(2, 0, 0));
171  vhandle[7] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
172  vhandle[8] = mesh_.add_vertex(Mesh::Point(2, 2, 0));
173 
174  // Add four faces
175  std::vector<Mesh::VertexHandle> face_vhandles;
176 
177  face_vhandles.push_back(vhandle[0]);
178  face_vhandles.push_back(vhandle[1]);
179  face_vhandles.push_back(vhandle[4]);
180  face_vhandles.push_back(vhandle[3]);
181 
182  mesh_.add_face(face_vhandles);
183  face_vhandles.clear();
184 
185  face_vhandles.push_back(vhandle[1]);
186  face_vhandles.push_back(vhandle[2]);
187  face_vhandles.push_back(vhandle[5]);
188  face_vhandles.push_back(vhandle[4]);
189 
190  mesh_.add_face(face_vhandles);
191  face_vhandles.clear();
192 
193  face_vhandles.push_back(vhandle[4]);
194  face_vhandles.push_back(vhandle[5]);
195  face_vhandles.push_back(vhandle[8]);
196  face_vhandles.push_back(vhandle[7]);
197 
198  mesh_.add_face(face_vhandles);
199  face_vhandles.clear();
200 
201  face_vhandles.push_back(vhandle[3]);
202  face_vhandles.push_back(vhandle[4]);
203  face_vhandles.push_back(vhandle[7]);
204  face_vhandles.push_back(vhandle[6]);
205 
206  mesh_.add_face(face_vhandles);
207 
208  // Test setup:
209  // 6 === 7 === 8
210  // | | |
211  // | | |
212  // | | |
213  // 3 === 4 === 5
214  // | | |
215  // | | |
216  // | | |
217  // 0 === 1 === 2
218 
219  // Initialize subdivider
221 
222  // Check setup
223  EXPECT_EQ(9u, mesh_.n_vertices() ) << "Wrong number of vertices";
224  EXPECT_EQ(4u, mesh_.n_faces() ) << "Wrong number of faces";
225 
226  // Execute 3 subdivision steps
227  catmull.attach(mesh_);
228  catmull( 3 );
229  catmull.detach();
230 
231  EXPECT_EQ(289u, mesh_.n_vertices() ) << "Wrong number of vertices after subdivision with catmull clark";
232  EXPECT_EQ(256u, mesh_.n_faces() ) << "Wrong number of faces after subdivision with catmull clark";
233 }
234 
235 /* Adds a cube to a polymesh
236  */
237 TEST_F(OpenMeshSubdividerUniform_Poly, Midpoint) {
238  mesh_.clear();
239 
240  // Add some vertices
241  Mesh::VertexHandle vhandle[8];
242  vhandle[0] = mesh_.add_vertex(PolyMesh::Point(-1, -1, 1));
243  vhandle[1] = mesh_.add_vertex(PolyMesh::Point( 1, -1, 1));
244  vhandle[2] = mesh_.add_vertex(PolyMesh::Point( 1, 1, 1));
245  vhandle[3] = mesh_.add_vertex(PolyMesh::Point(-1, 1, 1));
246  vhandle[4] = mesh_.add_vertex(PolyMesh::Point(-1, -1, -1));
247  vhandle[5] = mesh_.add_vertex(PolyMesh::Point( 1, -1, -1));
248  vhandle[6] = mesh_.add_vertex(PolyMesh::Point( 1, 1, -1));
249  vhandle[7] = mesh_.add_vertex(PolyMesh::Point(-1, 1, -1));
250 
251  // Add six faces to form a cube
252  std::vector<Mesh::VertexHandle> face_vhandles;
253 
254  face_vhandles.clear();
255  face_vhandles.push_back(vhandle[0]);
256  face_vhandles.push_back(vhandle[1]);
257  face_vhandles.push_back(vhandle[2]);
258  face_vhandles.push_back(vhandle[3]);
259  mesh_.add_face(face_vhandles);
260 
261  face_vhandles.clear();
262  face_vhandles.push_back(vhandle[7]);
263  face_vhandles.push_back(vhandle[6]);
264  face_vhandles.push_back(vhandle[5]);
265  face_vhandles.push_back(vhandle[4]);
266  mesh_.add_face(face_vhandles);
267 
268  face_vhandles.clear();
269  face_vhandles.push_back(vhandle[1]);
270  face_vhandles.push_back(vhandle[0]);
271  face_vhandles.push_back(vhandle[4]);
272  face_vhandles.push_back(vhandle[5]);
273  mesh_.add_face(face_vhandles);
274 
275  face_vhandles.clear();
276  face_vhandles.push_back(vhandle[2]);
277  face_vhandles.push_back(vhandle[1]);
278  face_vhandles.push_back(vhandle[5]);
279  face_vhandles.push_back(vhandle[6]);
280  mesh_.add_face(face_vhandles);
281 
282  face_vhandles.clear();
283  face_vhandles.push_back(vhandle[3]);
284  face_vhandles.push_back(vhandle[2]);
285  face_vhandles.push_back(vhandle[6]);
286  face_vhandles.push_back(vhandle[7]);
287  mesh_.add_face(face_vhandles);
288 
289  face_vhandles.clear();
290  face_vhandles.push_back(vhandle[0]);
291  face_vhandles.push_back(vhandle[3]);
292  face_vhandles.push_back(vhandle[7]);
293  face_vhandles.push_back(vhandle[4]);
294  mesh_.add_face(face_vhandles);
295 
296 
297  // Test setup:
298  //
299  //
300  // 3 ======== 2
301  // / /|
302  // / / | z
303  // 0 ======== 1 | |
304  // | | | | y
305  // | 7 | 6 | /
306  // | | / | /
307  // | |/ |/
308  // 4 ======== 5 -------> x
309  //
310 
311  // Check setup
312  EXPECT_EQ(12u, mesh_.n_edges()) << "Wrong number of Edges";
313  EXPECT_EQ(24u, mesh_.n_halfedges()) << "Wrong number of HalfEdges";
314  EXPECT_EQ(8u, mesh_.n_vertices()) << "Wrong number of vertices";
315  EXPECT_EQ(6u, mesh_.n_faces()) << "Wrong number of faces";
316 
317  // Initialize subdivider
319 
320  // Execute 2 subdivision steps
321  midpoint.attach(mesh_);
322  midpoint(2);
323  midpoint.detach();
324 
325  // Check Result
326  EXPECT_EQ(48u, mesh_.n_edges()) << "Wrong number of Edges";
327  EXPECT_EQ(96u, mesh_.n_halfedges()) << "Wrong number of HalfEdges";
328  EXPECT_EQ(24u, mesh_.n_vertices()) << "Wrong number of vertices";
329  EXPECT_EQ(26u, mesh_.n_faces()) << "Wrong number of faces";
330 }
331 
332 }
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:112
VertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
Definition: PolyMeshT.hh:235
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:136