Developer Documentation
unittests_read_write_OBJ.cc
1 
2 #include <gtest/gtest.h>
3 #include <Unittests/unittests_common.hh>
4 #include <cstdio>
5 
6 
7 namespace {
8 
9 class OpenMeshReadWriteOBJ : public OpenMeshBase {
10 
11  protected:
12 
13  // This function is called before each test is run
14  virtual void SetUp() {
15 
16  // Do some initial stuff with the member data here...
17  }
18 
19  // This function is called after all tests are through
20  virtual void TearDown() {
21 
22  // Do some final stuff with the member data here...
23  }
24 
25  // Member already defined in OpenMeshBase
26  //Mesh mesh_;
27 };
28 
29 /*
30  * ====================================================================
31  * Define tests below
32  * ====================================================================
33  */
34 
35 /*
36  * Just load a obj file of a cube
37  */
38 TEST_F(OpenMeshReadWriteOBJ, LoadSimpleOBJ) {
39 
40  mesh_.clear();
41 
42  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal.obj");
43 
44  EXPECT_TRUE(ok) << "Unable to load cube-minimal.obj";
45 
46  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
47  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
48  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
49 }
50 
51 /*
52  * Just load a obj file of a cube with degenerated faces
53  */
54 TEST_F(OpenMeshReadWriteOBJ, LoadDegeneratedOBJ) {
55 
56  mesh_.clear();
57 
58  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-degenerated.obj");
59 
60  EXPECT_TRUE(ok) << "Unable to load cube-minimal-degenerated.obj";
61 
62  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
63  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
64  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
65 }
66 
67 /*
68  * Just load a obj file of a cube and checks the halfedge and vertex normals
69  */
70 TEST_F(OpenMeshReadWriteOBJ, LoadSimpleOBJCheckHalfEdgeAndVertexNormals) {
71 
72  mesh_.clear();
73 
74  mesh_.request_halfedge_normals();
75  mesh_.request_vertex_normals();
76 
77  OpenMesh::IO::Options options;
79 
80  std::string file_name = "cube-minimal.obj";
81 
82  bool ok = OpenMesh::IO::read_mesh(mesh_, file_name,options);
83 
84  EXPECT_TRUE(ok) << file_name;
85 
86  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
87  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
88  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
89  EXPECT_EQ(36u , mesh_.n_halfedges()) << "The number of loaded halfedges is not correct!";
90 
92  //check vertex normals
93  EXPECT_EQ(0, mesh_.normal(mesh_.vertex_handle(0))[0] ) << "Wrong vertex normal at vertex 0 component 0";
94  EXPECT_EQ(-1, mesh_.normal(mesh_.vertex_handle(0))[1] ) << "Wrong vertex normal at vertex 0 component 1";
95  EXPECT_EQ(0, mesh_.normal(mesh_.vertex_handle(0))[2] ) << "Wrong vertex normal at vertex 0 component 2";
96 
97  EXPECT_EQ(0, mesh_.normal(mesh_.vertex_handle(3))[0] ) << "Wrong vertex normal at vertex 3 component 0";
98  EXPECT_EQ(0, mesh_.normal(mesh_.vertex_handle(3))[1] ) << "Wrong vertex normal at vertex 3 component 1";
99  EXPECT_EQ(1, mesh_.normal(mesh_.vertex_handle(3))[2] ) << "Wrong vertex normal at vertex 3 component 2";
100 
101  EXPECT_EQ(0, mesh_.normal(mesh_.vertex_handle(4))[0] ) << "Wrong vertex normal at vertex 4 component 0";
102  EXPECT_EQ(-1, mesh_.normal(mesh_.vertex_handle(4))[1] ) << "Wrong vertex normal at vertex 4 component 1";
103  EXPECT_EQ(0, mesh_.normal(mesh_.vertex_handle(4))[2] ) << "Wrong vertex normal at vertex 4 component 2";
104 
105  EXPECT_EQ(0, mesh_.normal(mesh_.vertex_handle(7))[0] ) << "Wrong vertex normal at vertex 7 component 0";
106  EXPECT_EQ(0, mesh_.normal(mesh_.vertex_handle(7))[1] ) << "Wrong vertex normal at vertex 7 component 1";
107  EXPECT_EQ(1, mesh_.normal(mesh_.vertex_handle(7))[2] ) << "Wrong vertex normal at vertex 7 component 2";
108 
110  //check halfedge normals
111  EXPECT_EQ(0, mesh_.normal(mesh_.halfedge_handle(0))[0] ) << "Wrong halfedge normal at halfedge 0 component 0";
112  EXPECT_EQ(0, mesh_.normal(mesh_.halfedge_handle(0))[1] ) << "Wrong halfedge normal at halfedge 0 component 1";
113  EXPECT_EQ(-1, mesh_.normal(mesh_.halfedge_handle(0))[2] ) << "Wrong halfedge normal at halfedge 0 component 2";
114 
115  EXPECT_EQ(-1, mesh_.normal(mesh_.halfedge_handle(10))[0] ) << "Wrong halfedge normal at halfedge 10 component 0";
116  EXPECT_EQ(0, mesh_.normal(mesh_.halfedge_handle(10))[1] ) << "Wrong halfedge normal at halfedge 10 component 1";
117  EXPECT_EQ(0, mesh_.normal(mesh_.halfedge_handle(10))[2] ) << "Wrong halfedge normal at halfedge 10 component 2";
118 
119  EXPECT_EQ(0, mesh_.normal(mesh_.halfedge_handle(19))[0] ) << "Wrong halfedge normal at halfedge 19 component 0";
120  EXPECT_EQ(1, mesh_.normal(mesh_.halfedge_handle(19))[1] ) << "Wrong halfedge normal at halfedge 19 component 1";
121  EXPECT_EQ(0, mesh_.normal(mesh_.halfedge_handle(19))[2] ) << "Wrong halfedge normal at halfedge 19 component 2";
122 
123  EXPECT_EQ(1, mesh_.normal(mesh_.halfedge_handle(24))[0] ) << "Wrong halfedge normal at halfedge 24 component 0";
124  EXPECT_EQ(0, mesh_.normal(mesh_.halfedge_handle(24))[1] ) << "Wrong halfedge normal at halfedge 24 component 1";
125  EXPECT_EQ(0, mesh_.normal(mesh_.halfedge_handle(24))[2] ) << "Wrong halfedge normal at halfedge 24 component 2";
126 
127  EXPECT_EQ(0, mesh_.normal(mesh_.halfedge_handle(30))[0] ) << "Wrong halfedge normal at halfedge 30 component 0";
128  EXPECT_EQ(-1, mesh_.normal(mesh_.halfedge_handle(30))[1] ) << "Wrong halfedge normal at halfedge 30 component 1";
129  EXPECT_EQ(0, mesh_.normal(mesh_.halfedge_handle(30))[2] ) << "Wrong halfedge normal at halfedge 30 component 2";
130 
131  EXPECT_EQ(0, mesh_.normal(mesh_.halfedge_handle(35))[0] ) << "Wrong halfedge normal at halfedge 35 component 0";
132  EXPECT_EQ(0, mesh_.normal(mesh_.halfedge_handle(35))[1] ) << "Wrong halfedge normal at halfedge 35 component 1";
133  EXPECT_EQ(1, mesh_.normal(mesh_.halfedge_handle(35))[2] ) << "Wrong halfedge normal at halfedge 35 component 2";
134 
135  mesh_.release_vertex_normals();
136  mesh_.release_halfedge_normals();
137 
138 }
139 
140 /*
141  * Just load a obj file and set vertex color option before loading
142  */
143 TEST_F(OpenMeshReadWriteOBJ, LoadSimpleOBJForceVertexColorsAlthoughNotAvailable) {
144 
145  mesh_.clear();
146 
147  mesh_.request_vertex_colors();
148 
149  std::string file_name = "cube-minimal.obj";
150 
151  OpenMesh::IO::Options options;
153 
154  bool ok = OpenMesh::IO::read_mesh(mesh_, file_name,options);
155 
156  EXPECT_TRUE(ok) << file_name;
157 
158  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
159  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
160  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
161  EXPECT_EQ(36u , mesh_.n_halfedges()) << "The number of loaded halfedges is not correct!";
162 
163 }
164 
165 
166 /*
167  * Just load a obj file of a cube and checks the halfedge texCoords
168  */
169 TEST_F(OpenMeshReadWriteOBJ, LoadSimpleOBJCheckTexCoords) {
170 
171  mesh_.clear();
172 
173  mesh_.request_halfedge_texcoords2D();
174 
175  OpenMesh::IO::Options options;
177 
178  std::string file_name = "cube-minimal-texCoords.obj";
179 
180  bool ok = OpenMesh::IO::read_mesh(mesh_, file_name,options);
181 
182  EXPECT_TRUE(ok) << file_name;
183 
184  EXPECT_EQ(1, mesh_.texcoord2D(mesh_.halfedge_handle(0))[0] ) << "Wrong texCoord at halfedge 0 component 0";
185  EXPECT_EQ(1, mesh_.texcoord2D(mesh_.halfedge_handle(0))[1] ) << "Wrong texCoord at halfedge 0 component 1";
186 
187  EXPECT_EQ(3, mesh_.texcoord2D(mesh_.halfedge_handle(10))[0] ) << "Wrong texCoord at halfedge 1 component 0";
188  EXPECT_EQ(3, mesh_.texcoord2D(mesh_.halfedge_handle(10))[1] ) << "Wrong texCoord at halfedge 1 component 1";
189 
190  EXPECT_EQ(6, mesh_.texcoord2D(mesh_.halfedge_handle(19))[0] ) << "Wrong texCoord at halfedge 4 component 0";
191  EXPECT_EQ(6, mesh_.texcoord2D(mesh_.halfedge_handle(19))[1] ) << "Wrong texCoord at halfedge 4 component 1";
192 
193  EXPECT_EQ(7, mesh_.texcoord2D(mesh_.halfedge_handle(24))[0] ) << "Wrong texCoord at halfedge 7 component 0";
194  EXPECT_EQ(7, mesh_.texcoord2D(mesh_.halfedge_handle(24))[1] ) << "Wrong texCoord at halfedge 7 component 1";
195 
196  EXPECT_EQ(9, mesh_.texcoord2D(mesh_.halfedge_handle(30))[0] ) << "Wrong texCoord at halfedge 9 component 0";
197  EXPECT_EQ(9, mesh_.texcoord2D(mesh_.halfedge_handle(30))[1] ) << "Wrong texCoord at halfedge 9 component 1";
198 
199  EXPECT_EQ(12, mesh_.texcoord2D(mesh_.halfedge_handle(35))[0] ) << "Wrong texCoord at halfedge 11 component 0";
200  EXPECT_EQ(12, mesh_.texcoord2D(mesh_.halfedge_handle(35))[1] ) << "Wrong texCoord at halfedge 11 component 1";
201 
202  mesh_.release_halfedge_texcoords2D();
203 }
204 
205 /*
206  * Just load and store obj file of a cube and checks the halfedge texCoords
207  */
208 TEST_F(OpenMeshReadWriteOBJ, LoadStoreSimpleOBJCheckTexCoords) {
209 
210  mesh_.clear();
211 
212  mesh_.request_halfedge_texcoords2D();
213 
214  OpenMesh::IO::Options options;
216 
217  std::string file_name = "cube-minimal-texCoords.obj";
218 
219  bool ok = OpenMesh::IO::read_mesh(mesh_, file_name,options);
220 
221  EXPECT_TRUE(ok) << file_name;
222 
223 
224 
225  options.clear();
227  bool writeOk = OpenMesh::IO::write_mesh(mesh_,"writeTest.obj",options);
228  EXPECT_TRUE(writeOk) << "writeTest.obj";
229  mesh_.release_halfedge_texcoords2D();
230 
231  Mesh loadedMesh_;
232  loadedMesh_.clear();
233 
234  loadedMesh_.request_halfedge_texcoords2D();
235 
236  options.clear();
238  bool readOk = OpenMesh::IO::read_mesh(loadedMesh_, "writeTest.obj",options);
239  EXPECT_TRUE(readOk) << file_name;
240  EXPECT_EQ(1, loadedMesh_.texcoord2D(mesh_.halfedge_handle(0))[0] ) << "Wrong texCoord at halfedge 0 component 0";
241  EXPECT_EQ(1, loadedMesh_.texcoord2D(mesh_.halfedge_handle(0))[1] ) << "Wrong texCoord at halfedge 0 component 1";
242 
243  EXPECT_EQ(3, loadedMesh_.texcoord2D(mesh_.halfedge_handle(10))[0] ) << "Wrong texCoord at halfedge 1 component 0";
244  EXPECT_EQ(3, loadedMesh_.texcoord2D(mesh_.halfedge_handle(10))[1] ) << "Wrong texCoord at halfedge 1 component 1";
245 
246  EXPECT_EQ(6, loadedMesh_.texcoord2D(mesh_.halfedge_handle(19))[0] ) << "Wrong texCoord at halfedge 4 component 0";
247  EXPECT_EQ(6, loadedMesh_.texcoord2D(mesh_.halfedge_handle(19))[1] ) << "Wrong texCoord at halfedge 4 component 1";
248 
249  EXPECT_EQ(7, loadedMesh_.texcoord2D(mesh_.halfedge_handle(24))[0] ) << "Wrong texCoord at halfedge 7 component 0";
250  EXPECT_EQ(7, loadedMesh_.texcoord2D(mesh_.halfedge_handle(24))[1] ) << "Wrong texCoord at halfedge 7 component 1";
251 
252  EXPECT_EQ(9, loadedMesh_.texcoord2D(mesh_.halfedge_handle(30))[0] ) << "Wrong texCoord at halfedge 9 component 0";
253  EXPECT_EQ(9, loadedMesh_.texcoord2D(mesh_.halfedge_handle(30))[1] ) << "Wrong texCoord at halfedge 9 component 1";
254 
255  EXPECT_EQ(12, loadedMesh_.texcoord2D(mesh_.halfedge_handle(35))[0] ) << "Wrong texCoord at halfedge 11 component 0";
256  EXPECT_EQ(12, loadedMesh_.texcoord2D(mesh_.halfedge_handle(35))[1] ) << "Wrong texCoord at halfedge 11 component 1";
257 
258  loadedMesh_.release_halfedge_texcoords2D();
259 }
260 
261 /*
262  * Just load a obj file of a cube and checks the 3d halfedge texCoords
263  */
264 TEST_F(OpenMeshReadWriteOBJ, LoadSimpleOBJCheckTexCoords3d) {
265 
266  mesh_.clear();
267 
268  mesh_.request_halfedge_texcoords3D();
269 
270  OpenMesh::IO::Options options;
272 
273  std::string file_name = "cube-minimal-texCoords3d.obj";
274 
275  bool ok = OpenMesh::IO::read_mesh(mesh_, file_name,options);
276 
277  EXPECT_TRUE(ok) << file_name;
278 
279  EXPECT_EQ(1, mesh_.texcoord3D(mesh_.halfedge_handle(0))[0] ) << "Wrong texCoord at halfedge 0 component 0";
280  EXPECT_EQ(1, mesh_.texcoord3D(mesh_.halfedge_handle(0))[1] ) << "Wrong texCoord at halfedge 0 component 1";
281  EXPECT_EQ(1, mesh_.texcoord3D(mesh_.halfedge_handle(0))[2] ) << "Wrong texCoord at halfedge 0 component 2";
282 
283  EXPECT_EQ(3, mesh_.texcoord3D(mesh_.halfedge_handle(10))[0] ) << "Wrong texCoord at halfedge 1 component 0";
284  EXPECT_EQ(3, mesh_.texcoord3D(mesh_.halfedge_handle(10))[1] ) << "Wrong texCoord at halfedge 1 component 1";
285  EXPECT_EQ(3, mesh_.texcoord3D(mesh_.halfedge_handle(10))[2] ) << "Wrong texCoord at halfedge 1 component 2";
286 
287  EXPECT_EQ(6, mesh_.texcoord3D(mesh_.halfedge_handle(19))[0] ) << "Wrong texCoord at halfedge 4 component 0";
288  EXPECT_EQ(6, mesh_.texcoord3D(mesh_.halfedge_handle(19))[1] ) << "Wrong texCoord at halfedge 4 component 1";
289  EXPECT_EQ(6, mesh_.texcoord3D(mesh_.halfedge_handle(19))[2] ) << "Wrong texCoord at halfedge 4 component 2";
290 
291  EXPECT_EQ(7, mesh_.texcoord3D(mesh_.halfedge_handle(24))[0] ) << "Wrong texCoord at halfedge 7 component 0";
292  EXPECT_EQ(7, mesh_.texcoord3D(mesh_.halfedge_handle(24))[1] ) << "Wrong texCoord at halfedge 7 component 1";
293  EXPECT_EQ(7, mesh_.texcoord3D(mesh_.halfedge_handle(24))[2] ) << "Wrong texCoord at halfedge 7 component 2";
294 
295  EXPECT_EQ(9, mesh_.texcoord3D(mesh_.halfedge_handle(30))[0] ) << "Wrong texCoord at halfedge 9 component 0";
296  EXPECT_EQ(9, mesh_.texcoord3D(mesh_.halfedge_handle(30))[1] ) << "Wrong texCoord at halfedge 9 component 1";
297  EXPECT_EQ(9, mesh_.texcoord3D(mesh_.halfedge_handle(30))[2] ) << "Wrong texCoord at halfedge 9 component 2";
298 
299  EXPECT_EQ(12, mesh_.texcoord3D(mesh_.halfedge_handle(35))[0] ) << "Wrong texCoord at halfedge 11 component 0";
300  EXPECT_EQ(12, mesh_.texcoord3D(mesh_.halfedge_handle(35))[1] ) << "Wrong texCoord at halfedge 11 component 1";
301  EXPECT_EQ(12, mesh_.texcoord3D(mesh_.halfedge_handle(35))[2] ) << "Wrong texCoord at halfedge 11 component 2";
302 
303  mesh_.request_halfedge_texcoords3D();
304 }
305 
306 /*
307  * Just load a obj file of a square with a material
308  */
309 TEST_F(OpenMeshReadWriteOBJ, LoadObjWithMaterial) {
310 
311  mesh_.clear();
312 
313  mesh_.request_face_colors();
314 
315  OpenMesh::IO::Options options;
317 
318  std::string file_name = "square_material.obj";
319 
320  bool ok = OpenMesh::IO::read_mesh(mesh_, file_name,options);
321 
322  EXPECT_TRUE(ok) << file_name;
323 
324  OpenMesh::FaceHandle fh = mesh_.face_handle(mesh_.halfedge_handle(0));
325 
326  EXPECT_TRUE(fh.is_valid()) << "fh should be valid";
327 
328 #ifdef TEST_DOUBLE_TRAITS
329  EXPECT_FLOAT_EQ(128/255.0, mesh_.color(fh)[0] ) << "Wrong vertex color at vertex 0 component 0";
330  EXPECT_FLOAT_EQ(128/255.0, mesh_.color(fh)[1] ) << "Wrong vertex color at vertex 0 component 1";
331  EXPECT_FLOAT_EQ(128/255.0, mesh_.color(fh)[2] ) << "Wrong vertex color at vertex 0 component 2";
332  EXPECT_FLOAT_EQ(1.0, mesh_.color(fh)[3] ) << "Wrong vertex color at vertex 0 component 3";
333 #else
334  EXPECT_EQ(128, mesh_.color(fh)[0] ) << "Wrong vertex color at vertex 0 component 0";
335  EXPECT_EQ(128, mesh_.color(fh)[1] ) << "Wrong vertex color at vertex 0 component 1";
336  EXPECT_EQ(128, mesh_.color(fh)[2] ) << "Wrong vertex color at vertex 0 component 2";
337 #endif
338 
339  mesh_.release_face_colors();
340 }
341 
342 TEST_F(OpenMeshReadWriteOBJ, LoadObjWithTexture) {
343 
344  mesh_.clear();
345 
346  mesh_.request_face_colors();
347  mesh_.request_face_texture_index();
348 
349  OpenMesh::IO::Options options;
351 
352  std::string file_name = "square_material_texture.obj";
353 
354  bool ok = OpenMesh::IO::read_mesh(mesh_, file_name, options);
355 
356  EXPECT_TRUE(ok) << file_name;
357 
358  //check texture mapping for the mesh
360  mesh_.get_property_handle(property, "TextureMapping");
361  EXPECT_EQ(mesh_.property(property).size(), 1u) << "More than one texture defined";
362  std::map< int, std::string >::iterator tex = mesh_.property(property).find(1);
363  EXPECT_TRUE(tex != mesh_.property(property).end()) << "Could not find texture with id 1";
364  EXPECT_TRUE((mesh_.property(property)[1] == std::string("square_material_texture.jpg"))) << "Wrong texture name";
365 
366  //check texture mapping per face
367  OpenMesh::FaceHandle fh = mesh_.face_handle(mesh_.halfedge_handle(0));
368  EXPECT_TRUE(fh.is_valid()) << "fh should be valid";
369  EXPECT_EQ(mesh_.property(mesh_.face_texture_index_pph(),fh),1) << "Face texture index is not set correctly";
370 
371  mesh_.release_face_colors();
372  mesh_.release_face_texture_index();
373 }
374 
375 /*
376  * Just load a obj file of a cube with vertex colors defined directly after the vertex definitions
377  */
378 TEST_F(OpenMeshReadWriteOBJ, LoadSimpleOBJWithVertexColorsAfterVertices) {
379 
380  mesh_.clear();
381 
382  mesh_.request_vertex_colors();
383 
384  OpenMesh::IO::Options options;
386 
387  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-vertex-colors-after-vertex-definition.obj",options);
388 
389  EXPECT_TRUE(ok) << "Unable to load cube-minimal-vertex-colors-after-vertex-definition.obj";
390 
391  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
392  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
393  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
394 
395 
396 #ifdef TEST_DOUBLE_TRAITS
397  EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0";
398  EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1";
399  EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2";
400 
401  EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0";
402  EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1";
403  EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2";
404 
405  EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0";
406  EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1";
407  EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2";
408 
409  EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0";
410  EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1";
411  EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2";
412 #else
413  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0";
414  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1";
415  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2";
416 
417  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0";
418  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1";
419  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2";
420 
421  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0";
422  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1";
423  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2";
424 
425  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0";
426  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1";
427  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2";
428 #endif
429 
430  mesh_.release_vertex_colors();
431 }
432 
433 /*
434  * Just load a obj file of a cube with vertex colors defined as separate lines
435  */
436 TEST_F(OpenMeshReadWriteOBJ, LoadSimpleOBJWithVertexColorsAsVCLines) {
437 
438  mesh_.clear();
439 
440  mesh_.request_vertex_colors();
441 
442  OpenMesh::IO::Options options;
444 
445  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-vertex-colors-as-vc-lines.obj",options);
446 
447  EXPECT_TRUE(ok) << "Unable to load cube-minimal-vertex-colors-as-vc-lines.obj";
448 
449  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
450  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
451  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
452 
453 #ifdef TEST_DOUBLE_TRAITS
454  EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0";
455  EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1";
456  EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2";
457 
458  EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0";
459  EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1";
460  EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2";
461 
462  EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0";
463  EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1";
464  EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2";
465 
466  EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0";
467  EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1";
468  EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2";
469 #else
470  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0";
471  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1";
472  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2";
473 
474  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0";
475  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1";
476  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2";
477 
478  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0";
479  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1";
480  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2";
481 
482  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0";
483  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1";
484  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2";
485 #endif
486 
487  mesh_.release_vertex_colors();
488 
489 }
490 
491 /*
492  * Load, save and load a simple obj
493  */
494 TEST_F(OpenMeshReadWriteOBJ, ReadWriteReadSimpleOBJ) {
495 
496  mesh_.clear();
497  mesh_.request_vertex_normals();
498 
499  OpenMesh::IO::Options options;
501  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal.obj", options);
502 
503  EXPECT_TRUE(ok) << "Unable to load cube-minimal.obj";
504 
505  options.clear();
507  const char* filename = "cube-minimal_openmeshOutputTestfile.obj";
508  ok = OpenMesh::IO::write_mesh(mesh_, filename, options);
509 
510  mesh_.release_vertex_normals();
511  ASSERT_TRUE(ok) << "Unable to write obj mesh";
512 
513  Mesh mesh2;
514  mesh2.request_vertex_normals();
515 
516  options.clear();
517 
519  ok = OpenMesh::IO::read_mesh(mesh2, filename, options);
520  remove(filename);
521  ASSERT_TRUE(ok) << "Unable to read written mesh";
522 
523  EXPECT_EQ(8u , mesh2.n_vertices()) << "The number of loaded vertices is not correct!";
524  EXPECT_EQ(18u , mesh2.n_edges()) << "The number of loaded edges is not correct!";
525  EXPECT_EQ(12u , mesh2.n_faces()) << "The number of loaded faces is not correct!";
526 
528  //check vertex normals
529  EXPECT_EQ(0, mesh2.normal(mesh2.vertex_handle(0))[0] ) << "Wrong vertex normal at vertex 0 component 0";
530  EXPECT_EQ(-1, mesh2.normal(mesh2.vertex_handle(0))[1] ) << "Wrong vertex normal at vertex 0 component 1";
531  EXPECT_EQ(0, mesh2.normal(mesh2.vertex_handle(0))[2] ) << "Wrong vertex normal at vertex 0 component 2";
532 
533  EXPECT_EQ(0, mesh2.normal(mesh2.vertex_handle(3))[0] ) << "Wrong vertex normal at vertex 3 component 0";
534  EXPECT_EQ(0, mesh2.normal(mesh2.vertex_handle(3))[1] ) << "Wrong vertex normal at vertex 3 component 1";
535  EXPECT_EQ(1, mesh2.normal(mesh2.vertex_handle(3))[2] ) << "Wrong vertex normal at vertex 3 component 2";
536 
537  EXPECT_EQ(0, mesh2.normal(mesh2.vertex_handle(4))[0] ) << "Wrong vertex normal at vertex 4 component 0";
538  EXPECT_EQ(-1, mesh2.normal(mesh2.vertex_handle(4))[1] ) << "Wrong vertex normal at vertex 4 component 1";
539  EXPECT_EQ(0, mesh2.normal(mesh2.vertex_handle(4))[2] ) << "Wrong vertex normal at vertex 4 component 2";
540 
541  EXPECT_EQ(0, mesh2.normal(mesh2.vertex_handle(7))[0] ) << "Wrong vertex normal at vertex 7 component 0";
542  EXPECT_EQ(0, mesh2.normal(mesh2.vertex_handle(7))[1] ) << "Wrong vertex normal at vertex 7 component 1";
543  EXPECT_EQ(1, mesh2.normal(mesh2.vertex_handle(7))[2] ) << "Wrong vertex normal at vertex 7 component 2";
544 
545 }
546 
547 
548 TEST_F(OpenMeshReadWriteOBJ, FaceTexCoordTest) {
549 
550  mesh_.clear();
551  mesh_.request_vertex_normals();
552  mesh_.request_halfedge_texcoords2D();
553 
554  // Add some vertices
555  Mesh::VertexHandle vhandle[5];
556 
557  vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
558  vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
559  vhandle[2] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
560 
561  // Add one face
562  std::vector<Mesh::VertexHandle> face_vhandles;
563 
564  face_vhandles.push_back(vhandle[2]);
565  face_vhandles.push_back(vhandle[1]);
566  face_vhandles.push_back(vhandle[0]);
567 
568  Mesh::FaceHandle fh = mesh_.add_face(face_vhandles);
569 
570  // 1 --- 2
571  // | /
572  // | /
573  // | /
574  // 0
575 
576  mesh_.set_normal(vhandle[0] , Mesh::Normal(1,0,0));
577  mesh_.set_normal(vhandle[1] , Mesh::Normal(0,1,0));
578  mesh_.set_normal(vhandle[2] , Mesh::Normal(0,0,1));
579 
580 
581  float u = 8.0f;
582  for ( auto he : mesh_.halfedges() ) {
583 
584  mesh_.set_texcoord2D(he,Mesh::TexCoord2D(u,u));
585  u += 1.0;
586  }
587 
588 
589  u = 0.0f;
590 
591  for ( auto he : mesh_.fh_range(fh) )
592  {
593 
594  mesh_.set_texcoord2D(he,Mesh::TexCoord2D(u,u));
595  u += 1.0f;
596  }
597 
598 
599 
603 
604  bool ok = OpenMesh::IO::write_mesh(mesh_, "OpenMeshReadWriteOBJ_FaceTexCoordTest.obj", wopt);
605 
606  EXPECT_TRUE(ok) << "Unable to write OpenMeshReadWriteOBJ_FaceTexCoordTest.obj";
607 
608  mesh_.clear();
609 
610 
612 
614 
615  mesh_.request_vertex_normals();
616  mesh_.request_face_normals();
617  mesh_.request_halfedge_texcoords2D();
618 
619  ok = OpenMesh::IO::read_mesh(mesh_, "OpenMeshReadWriteOBJ_FaceTexCoordTest.obj", ropt);
620 
621  EXPECT_TRUE(ok) << "Unable to read back OpenMeshReadWriteOBJ_FaceTexCoordTest.obj";
622 
623 }
624 
625 
626 
627 
628 
629 
630 }
Handle for a face entity.
Definition: Handles.hh:141
Kernel::Normal Normal
Normal type.
Definition: PolyMeshT.hh:114
Has (r) / store (w) vertex colors.
Definition: Options.hh:105
void clear(void)
Clear all bits.
Definition: Options.hh:147
Has (r) / store (w) face colors.
Definition: Options.hh:109
bool write_mesh(const Mesh &_mesh, const std::string &_filename, Options _opt=Options::Default, std::streamsize _precision=6)
Write a mesh to the file _filename.
Definition: MeshIO.hh:207
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:112
bool is_valid() const
The handle is valid iff the index is not negative.
Definition: Handles.hh:72
Has (r) / store (w) face texture coordinates.
Definition: Options.hh:110
bool read_mesh(Mesh &_mesh, const std::string &_filename)
Read a mesh from file _filename.
Definition: MeshIO.hh:112
Kernel::TexCoord2D TexCoord2D
TexCoord2D type.
Definition: PolyMeshT.hh:120
SmartVertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
Definition: PolyMeshT.hh:235
Set options for reader/writer modules.
Definition: Options.hh:90
Has (r) / store (w) vertex normals.
Definition: Options.hh:104
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:136