Developer Documentation
Loading...
Searching...
No Matches
unittests_read_write_OBJ.cc
1
2#include <gtest/gtest.h>
3#include <Unittests/unittests_common.hh>
4#include <cstdio>
5
6
7namespace {
8
9class 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 */
38TEST_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 */
54TEST_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 */
70TEST_F(OpenMeshReadWriteOBJ, LoadSimpleOBJCheckHalfEdgeAndVertexNormals) {
71
72 mesh_.clear();
73
74 mesh_.request_halfedge_normals();
75 mesh_.request_vertex_normals();
76
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 */
143TEST_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 */
169TEST_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 */
208TEST_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 */
264TEST_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 */
309TEST_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
342TEST_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 */
378TEST_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 */
436TEST_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 */
494TEST_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
548TEST_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 * Load, save and load a simple obj
628 */
629TEST_F(OpenMeshReadWriteOBJ, ReadOBJMTL) {
630
631 mesh_.clear();
632 mesh_.request_face_colors();
633
634 OpenMesh::IO::Options options;
636 bool ok = OpenMesh::IO::read_mesh(mesh_, "CubeCol.obj", options);
637
638 EXPECT_TRUE(ok) << "Unable to load CubeCol.obj";
639
640 OpenMesh::FaceHandle fh0 = mesh_.face_handle(0);
641 OpenMesh::FaceHandle fh1 = mesh_.face_handle(1);
642 OpenMesh::FaceHandle fh2 = mesh_.face_handle(2);
643 OpenMesh::FaceHandle fh3 = mesh_.face_handle(3);
644
645
646 EXPECT_TRUE(fh0.is_valid()) << "fh0 should be valid";
647 EXPECT_TRUE(fh1.is_valid()) << "fh1 should be valid";
648 EXPECT_TRUE(fh2.is_valid()) << "fh2 should be valid";
649 EXPECT_TRUE(fh3.is_valid()) << "fh3 should be valid";
650
651
652
653#ifdef TEST_DOUBLE_TRAITS
654 const float value1 = 32.0/255.0;
655 const float value2 = 64.0/255.0;
656 const float value3 = 128.0/255.0;
657#else
658 const float value1 = 32;
659 const float value2 = 64;
660 const float value3 = 128;
661#endif
662
663
664
665
666 EXPECT_FLOAT_EQ(value1, mesh_.color(fh0)[0] ) << "Wrong vertex color at face 0 component 0";
667 EXPECT_FLOAT_EQ(value2 , mesh_.color(fh0)[1] ) << "Wrong vertex color at face 0 component 1";
668 EXPECT_FLOAT_EQ(value3, mesh_.color(fh0)[2] ) << "Wrong vertex color at face 0 component 2";
669
670 EXPECT_FLOAT_EQ(value1, mesh_.color(fh1)[0] ) << "Wrong vertex color at face 1 component 0";
671 EXPECT_FLOAT_EQ(value2, mesh_.color(fh1)[1] ) << "Wrong vertex color at face 1 component 1";
672 EXPECT_FLOAT_EQ(value3, mesh_.color(fh1)[2] ) << "Wrong vertex color at face 1 component 2";
673
674 EXPECT_FLOAT_EQ(value1, mesh_.color(fh2)[0] ) << "Wrong vertex color at face 2 component 0";
675 EXPECT_FLOAT_EQ(value2, mesh_.color(fh2)[1] ) << "Wrong vertex color at face 2 component 1";
676 EXPECT_FLOAT_EQ(value3, mesh_.color(fh2)[2] ) << "Wrong vertex color at face 2 component 2";
677
678 EXPECT_FLOAT_EQ(value1, mesh_.color(fh3)[0] ) << "Wrong vertex color at face 3 component 0";
679 EXPECT_FLOAT_EQ(value2, mesh_.color(fh3)[1] ) << "Wrong vertex color at face 3 component 1";
680 EXPECT_FLOAT_EQ(value3, mesh_.color(fh3)[2] ) << "Wrong vertex color at face 3 component 2";
681
682}
683
684
685
686}
bool is_valid() const
The handle is valid iff the index is not negative.
Definition Handles.hh:72
Set options for reader/writer modules.
Definition Options.hh:92
void clear(void)
Clear all bits.
Definition Options.hh:143
@ FaceColor
Has (r) / store (w) face colors.
Definition Options.hh:110
@ FaceTexCoord
Has (r) / store (w) face texture coordinates.
Definition Options.hh:111
@ VertexNormal
Has (r) / store (w) vertex normals.
Definition Options.hh:105
@ VertexColor
Has (r) / store (w) vertex colors.
Definition Options.hh:106
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition PolyMeshT.hh:136
Kernel::Normal Normal
Normal type.
Definition PolyMeshT.hh:114
Kernel::TexCoord2D TexCoord2D
TexCoord2D type.
Definition PolyMeshT.hh:120
SmartVertexHandle add_vertex(const Point _p)
Definition PolyMeshT.hh:255
Kernel::FaceHandle FaceHandle
Scalar type.
Definition PolyMeshT.hh:139
Kernel::Point Point
Coordinate type.
Definition PolyMeshT.hh:112
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:190
bool read_mesh(Mesh &_mesh, const std::string &_filename)
Read a mesh from file _filename.
Definition MeshIO.hh:95
Handle for a face entity.
Definition Handles.hh:142