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;
78 options += OpenMesh::IO::Options::VertexNormal;
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;
152 options += OpenMesh::IO::Options::VertexColor;
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;
176 options += OpenMesh::IO::Options::FaceTexCoord;
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;
215 options += OpenMesh::IO::Options::FaceTexCoord;
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();
226 options += OpenMesh::IO::Options::FaceTexCoord;
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();
237 options += OpenMesh::IO::Options::FaceTexCoord;
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;
271 options += OpenMesh::IO::Options::FaceTexCoord;
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;
316 options += OpenMesh::IO::Options::FaceColor;
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;
350 options += OpenMesh::IO::Options::FaceTexCoord;
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
359 OpenMesh::MPropHandleT< std::map< int, std::string > > property;
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;
385 options += OpenMesh::IO::Options::VertexColor;
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;
443 options += OpenMesh::IO::Options::VertexColor;
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;
500 options += OpenMesh::IO::Options::VertexNormal;
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();
506 options += OpenMesh::IO::Options::VertexNormal;
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
518 options += OpenMesh::IO::Options::VertexNormal;
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
600 OpenMesh::IO::Options wopt;
601 wopt += OpenMesh::IO::Options::VertexNormal;
602 wopt += OpenMesh::IO::Options::FaceTexCoord;
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
611 OpenMesh::IO::Options ropt;
612
613 ropt += OpenMesh::IO::Options::FaceTexCoord;
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 }
OpenMesh::MPropHandleT
Definition: Property.hh:544
OpenMesh::FaceHandle
Handle for a face entity.
Definition: Handles.hh:141
OpenMesh::PolyMeshT::Normal
Kernel::Normal Normal
Normal type.
Definition: PolyMeshT.hh:114
OpenMesh::IO::Options::VertexColor
Has (r) / store (w) vertex colors.
Definition: Options.hh:105
OpenMesh::IO::Options::clear
void clear(void)
Clear all bits.
Definition: Options.hh:147
OpenMesh::IO::Options::FaceColor
Has (r) / store (w) face colors.
Definition: Options.hh:109
OpenMesh::IO::write_mesh
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
OpenMesh::PolyMeshT::Point
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:112
OpenMesh::TriMesh_ArrayKernelT
Definition: PolyMesh_ArrayKernelT.hh:73
OpenMesh::BaseHandle::is_valid
bool is_valid() const
The handle is valid iff the index is not negative.
Definition: Handles.hh:72
OpenMesh::IO::Options::FaceTexCoord
Has (r) / store (w) face texture coordinates.
Definition: Options.hh:110
OpenMesh::IO::read_mesh
bool read_mesh(Mesh &_mesh, const std::string &_filename)
Read a mesh from file _filename.
Definition: MeshIO.hh:112
OpenMesh::PolyMeshT::TexCoord2D
Kernel::TexCoord2D TexCoord2D
TexCoord2D type.
Definition: PolyMeshT.hh:120
OpenMesh::PolyMeshT::add_vertex
SmartVertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
Definition: PolyMeshT.hh:235
OpenMesh::IO::Options
Set options for reader/writer modules.
Definition: Options.hh:90
OpenMeshBase
Definition: unittests_common.hh:29
OpenMesh::IO::Options::VertexNormal
Has (r) / store (w) vertex normals.
Definition: Options.hh:104
OpenMesh::PolyMeshT::VertexHandle
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:136