Developer Documentation
unittests_read_write_PLY.cc
1 #include <gtest/gtest.h>
2 #include <Unittests/unittests_common.hh>
3 
4 
5 namespace {
6 
7 class OpenMeshReadWritePLY : public OpenMeshBase {
8 
9  protected:
10 
11  // This function is called before each test is run
12  virtual void SetUp() {
13 
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 
20  // Do some final stuff with the member data here...
21  }
22 
23  // Member already defined in OpenMeshBase
24  //Mesh mesh_;
25 };
26 
27 /*
28  * ====================================================================
29  * Define tests below
30  * ====================================================================
31  */
32 
33 /*
34  * Just load a point file in ply format and count whether
35  * the right number of entities has been loaded.
36  */
37 TEST_F(OpenMeshReadWritePLY, LoadSimplePointPLYFileWithBadEncoding) {
38 
39  mesh_.clear();
40 
41  bool ok = OpenMesh::IO::read_mesh(mesh_, "pointCloudBadEncoding.ply");
42 
43  EXPECT_TRUE(ok) << "Unable to load pointCloudBadEncoding.ply";
44 
45  EXPECT_EQ(10u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
46  EXPECT_EQ(0u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
47  EXPECT_EQ(0u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
48 }
49 
50 /*
51  * Just load a point file in ply format and count whether
52  * the right number of entities has been loaded.
53  */
54 TEST_F(OpenMeshReadWritePLY, LoadSimplePointPLYFileWithGoodEncoding) {
55 
56  mesh_.clear();
57 
58  bool ok = OpenMesh::IO::read_mesh(mesh_, "pointCloudGoodEncoding.ply");
59 
60  EXPECT_TRUE(ok) << "Unable to load pointCloudGoodEncoding.ply";
61 
62  EXPECT_EQ(10u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
63  EXPECT_EQ(0u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
64  EXPECT_EQ(0u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
65 }
66 
67 /*
68  * Just load a ply
69  */
70 TEST_F(OpenMeshReadWritePLY, LoadSimplePLY) {
71 
72  mesh_.clear();
73 
74  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal.ply");
75 
76  EXPECT_TRUE(ok) << "Unable to load cube-minimal.ply";
77 
78  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
79  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
80  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
81 
82 }
83 
84 /*
85  * Load a ply ascii file without a newline at the end of the file
86  *
87  */
88 TEST_F(OpenMeshReadWritePLY, LoadSimplePLYNoEndl) {
89 
90  mesh_.clear();
91 
92  bool ok = OpenMesh::IO::read_mesh(mesh_, "sphere840.ply");
93 
94  EXPECT_TRUE(ok) << "Unable to load sphere840.ply";
95 
96  EXPECT_EQ(422u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
97  EXPECT_EQ(1260u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
98  EXPECT_EQ(840u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
99 
100 }
101 
102 /*
103  * Just load a ply file and set vertex color option before loading
104  */
105 TEST_F(OpenMeshReadWritePLY, LoadSimplePLYForceVertexColorsAlthoughNotAvailable) {
106 
107  mesh_.clear();
108 
109  mesh_.request_vertex_colors();
110 
111  std::string file_name = "cube-minimal.ply";
112 
113  OpenMesh::IO::Options options;
115 
116  bool ok = OpenMesh::IO::read_mesh(mesh_, file_name,options);
117 
118  EXPECT_TRUE(ok) << file_name;
119 
120  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
121  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
122  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
123  EXPECT_EQ(36u , mesh_.n_halfedges()) << "The number of loaded halfedges is not correct!";
124 
125  EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!";
126  EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
127  EXPECT_FALSE(options.vertex_has_color()) << "Wrong user options are returned!";
128 }
129 
130 /*
131  * Just load a ply file of a cube with vertex colors
132  */
133 TEST_F(OpenMeshReadWritePLY, LoadSimplePLYWithVertexColors) {
134 
135  mesh_.clear();
136 
137  mesh_.request_vertex_colors();
138 
139  OpenMesh::IO::Options options;
141 
142  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-vertexColors.ply",options);
143 
144  EXPECT_TRUE(ok) << "Unable to load cube-minimal-vertexColors.ply";
145 
146  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
147  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
148  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
149 
150  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0";
151  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1";
152  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2";
153 
154  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0";
155  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1";
156  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2";
157 
158  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0";
159  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1";
160  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2";
161 
162  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0";
163  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1";
164  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2";
165 
166  EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!";
167  EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
168  EXPECT_TRUE(options.vertex_has_color()) << "Wrong user options are returned!";
169 
170  mesh_.release_vertex_colors();
171 }
172 
173 /*
174  * Just load a ply file of a cube with vertex colors
175  */
176 TEST_F(OpenMeshReadWritePLY, LoadPLYFromMeshLabWithVertexColors) {
177 
178  mesh_.clear();
179 
180  mesh_.request_vertex_colors();
181 
182  OpenMesh::IO::Options options;
184 
185  bool ok = OpenMesh::IO::read_mesh(mesh_, "meshlab.ply",options);
186 
187  EXPECT_TRUE(ok) << "Unable to load meshlab.ply";
188 
189  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
190  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
191  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
192 
193  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0";
194  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1";
195  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2";
196 
197  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0";
198  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1";
199  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2";
200 
201  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0";
202  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1";
203  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2";
204 
205  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0";
206  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1";
207  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2";
208 
209  EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!";
210  EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
211  EXPECT_TRUE(options.vertex_has_color()) << "Wrong user options are returned!";
212 
213  mesh_.release_vertex_colors();
214 }
215 
216 /*
217  * Just read and write a binary ply file of a cube with vertex colors
218  */
219 TEST_F(OpenMeshReadWritePLY, WriteAndReadBinaryPLYWithVertexColors) {
220 
221  mesh_.clear();
222 
223  mesh_.request_vertex_colors();
224 
225  OpenMesh::IO::Options options;
227 
228  bool ok = OpenMesh::IO::read_mesh(mesh_, "meshlab.ply",options);
229 
230  EXPECT_TRUE(ok) << "Unable to load meshlab.ply";
231 
233 
234  ok = OpenMesh::IO::write_mesh(mesh_, "meshlab_binary.ply",options);
235  EXPECT_TRUE(ok) << "Unable to write meshlab_binary.ply";
236 
237  mesh_.clear();
238  ok = OpenMesh::IO::read_mesh(mesh_, "meshlab_binary.ply",options);
239  EXPECT_TRUE(ok) << "Unable to load meshlab_binary.ply";
240 
241  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
242  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
243  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
244 
245  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0";
246  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1";
247  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2";
248 
249  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0";
250  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1";
251  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2";
252 
253  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0";
254  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1";
255  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2";
256 
257  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0";
258  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1";
259  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2";
260 
261  EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!";
262  EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
263  EXPECT_TRUE(options.vertex_has_color()) << "Wrong user options are returned!";
264 
265  mesh_.release_vertex_colors();
266 }
267 
268 /*
269  * Just read and write a ply file of a cube with float vertex colors
270  */
271 TEST_F(OpenMeshReadWritePLY, WriteAndReadPLYWithFloatVertexColors) {
272 
273  mesh_.clear();
274 
275  mesh_.request_vertex_colors();
276 
277  OpenMesh::IO::Options options;
279 
280  bool ok = OpenMesh::IO::read_mesh(mesh_, "meshlab.ply",options);
281 
282  EXPECT_TRUE(ok) << "Unable to load meshlab.ply";
283 
285 
286  ok = OpenMesh::IO::write_mesh(mesh_, "meshlab_float.ply",options);
287  EXPECT_TRUE(ok) << "Unable to write meshlab_float.ply";
288 
289  mesh_.clear();
290  ok = OpenMesh::IO::read_mesh(mesh_, "meshlab_float.ply",options);
291  EXPECT_TRUE(ok) << "Unable to load meshlab_float.ply";
292 
293  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
294  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
295  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
296 
297  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0";
298  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1";
299  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2";
300 
301  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0";
302  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1";
303  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2";
304 
305  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0";
306  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1";
307  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2";
308 
309  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0";
310  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1";
311  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2";
312 
313  EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!";
314  EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
315  EXPECT_TRUE(options.vertex_has_color()) << "Wrong user options are returned!";
316  EXPECT_TRUE(options.color_is_float()) << "Wrong user options are returned!";
317 
318  mesh_.release_vertex_colors();
319 }
320 
321 /*
322  * Just read and write a binary ply file of a cube with float vertex colors
323  */
324 TEST_F(OpenMeshReadWritePLY, WriteAndReadBinaryPLYWithFloatVertexColors) {
325 
326  mesh_.clear();
327 
328  mesh_.request_vertex_colors();
329 
330  OpenMesh::IO::Options options;
332 
333  bool ok = OpenMesh::IO::read_mesh(mesh_, "meshlab.ply",options);
334 
335  EXPECT_TRUE(ok) << "Unable to load meshlab.ply";
336 
339 
340  ok = OpenMesh::IO::write_mesh(mesh_, "meshlab_binary_float.ply",options);
341  EXPECT_TRUE(ok) << "Unable to write meshlab_binary_float.ply";
342 
343  mesh_.clear();
344  ok = OpenMesh::IO::read_mesh(mesh_, "meshlab_binary_float.ply",options);
345  EXPECT_TRUE(ok) << "Unable to load meshlab_binary_float.ply";
346 
347  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
348  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
349  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
350 
351  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0";
352  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1";
353  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2";
354 
355  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0";
356  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1";
357  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2";
358 
359  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0";
360  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1";
361  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2";
362 
363  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0";
364  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1";
365  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2";
366 
367  EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!";
368  EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
369  EXPECT_TRUE(options.vertex_has_color()) << "Wrong user options are returned!";
370  EXPECT_TRUE(options.color_is_float()) << "Wrong user options are returned!";
371  EXPECT_TRUE(options.is_binary()) << "Wrong user options are returned!";
372 
373  mesh_.release_vertex_colors();
374 }
375 
376 /*
377  * Just load a ply file of a cube with vertex texCoords
378  */
379 TEST_F(OpenMeshReadWritePLY, LoadSimplePLYWithTexCoords) {
380 
381  mesh_.clear();
382 
383  mesh_.request_vertex_texcoords2D();
384 
385  OpenMesh::IO::Options options;
387 
388  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-texCoords.ply",options);
389 
390  EXPECT_TRUE(ok) << "Unable to load cube-minimal-texCoords.ply";
391 
392  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
393  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
394  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
395 
396  EXPECT_EQ(10, mesh_.texcoord2D(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0";
397  EXPECT_EQ(10, mesh_.texcoord2D(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1";
398 
399  EXPECT_EQ(6, mesh_.texcoord2D(mesh_.vertex_handle(2))[0] ) << "Wrong vertex color at vertex 2 component 0";
400  EXPECT_EQ(6, mesh_.texcoord2D(mesh_.vertex_handle(2))[1] ) << "Wrong vertex color at vertex 2 component 1";
401 
402  EXPECT_EQ(9, mesh_.texcoord2D(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0";
403  EXPECT_EQ(9, mesh_.texcoord2D(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1";
404 
405  EXPECT_EQ(12, mesh_.texcoord2D(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0";
406  EXPECT_EQ(12, mesh_.texcoord2D(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1";
407 
408 
409  EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!";
410  EXPECT_TRUE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
411  EXPECT_FALSE(options.vertex_has_color()) << "Wrong user options are returned!";
412 
413  mesh_.release_vertex_texcoords2D();
414 }
415 
416 /*
417  * Just load a ply with normals, ascii mode
418  */
419 TEST_F(OpenMeshReadWritePLY, LoadSimplePLYWithNormals) {
420 
421  mesh_.clear();
422 
423  mesh_.request_vertex_normals();
424 
425  OpenMesh::IO::Options options;
427 
428  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-normals.ply", options);
429 
430  EXPECT_TRUE(ok) << "Unable to load cube-minimal-normals.ply";
431 
432  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
433  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
434  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
435 
436  EXPECT_TRUE(options.vertex_has_normal()) << "Wrong user options are returned!";
437  EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
438  EXPECT_FALSE(options.vertex_has_color()) << "Wrong user options are returned!";
439 
440 
441  EXPECT_EQ(0, mesh_.normal(mesh_.vertex_handle(0))[0] ) << "Wrong normal at vertex 0 component 0";
442  EXPECT_EQ(0, mesh_.normal(mesh_.vertex_handle(0))[1] ) << "Wrong normal at vertex 0 component 1";
443  EXPECT_EQ(1, mesh_.normal(mesh_.vertex_handle(0))[2] ) << "Wrong normal at vertex 0 component 2";
444 
445  EXPECT_EQ(1, mesh_.normal(mesh_.vertex_handle(3))[0] ) << "Wrong normal at vertex 3 component 0";
446  EXPECT_EQ(0, mesh_.normal(mesh_.vertex_handle(3))[1] ) << "Wrong normal at vertex 3 component 1";
447  EXPECT_EQ(0, mesh_.normal(mesh_.vertex_handle(3))[2] ) << "Wrong normal at vertex 3 component 2";
448 
449  EXPECT_EQ(1, mesh_.normal(mesh_.vertex_handle(4))[0] ) << "Wrong normal at vertex 4 component 0";
450  EXPECT_EQ(0, mesh_.normal(mesh_.vertex_handle(4))[1] ) << "Wrong normal at vertex 4 component 1";
451  EXPECT_EQ(1, mesh_.normal(mesh_.vertex_handle(4))[2] ) << "Wrong normal at vertex 4 component 2";
452 
453  EXPECT_EQ(1, mesh_.normal(mesh_.vertex_handle(7))[0] ) << "Wrong normal at vertex 7 component 0";
454  EXPECT_EQ(1, mesh_.normal(mesh_.vertex_handle(7))[1] ) << "Wrong normal at vertex 7 component 1";
455  EXPECT_EQ(2, mesh_.normal(mesh_.vertex_handle(7))[2] ) << "Wrong normal at vertex 7 component 2";
456 
457  mesh_.release_vertex_normals();
458 
459 }
460 
461 /*
462  * Just load a ply with custom properties, ascii mode
463  */
464 TEST_F(OpenMeshReadWritePLY, LoadSimplePLYWithCustomProps) {
465 
466  PolyMesh mesh;
467 
468  OpenMesh::IO::Options options;
470 
471  bool ok = OpenMesh::IO::read_mesh(mesh, "cube-minimal-custom_props.ply", options);
472 
473  EXPECT_TRUE(ok) << "Unable to load cube-minimal-custom_props.ply";
474 
475  EXPECT_EQ(8u , mesh.n_vertices()) << "The number of loaded vertices is not correct!";
476  EXPECT_EQ(12u , mesh.n_edges()) << "The number of loaded edges is not correct!";
477  EXPECT_EQ(6u , mesh.n_faces()) << "The number of loaded faces is not correct!";
478 
479  OpenMesh::VPropHandleT<float> qualityProp;
481  ASSERT_TRUE(mesh.get_property_handle(qualityProp,"quality")) << "Could not access quality property";
482  ASSERT_TRUE(mesh.get_property_handle(indexProp,"index")) << "Could not access index property";
483 
484  //check index property
485  for (unsigned i = 0; i < mesh.n_vertices(); ++i)
486  EXPECT_EQ(i ,mesh.property(indexProp,OpenMesh::VertexHandle(i))) << "Vertex index at vertex " << i << " is wrong";
487 
488  //check quality property
489  EXPECT_EQ(1.f,mesh.property(qualityProp,OpenMesh::VertexHandle(0))) << "Wrong quality value at Vertex 0";
490  EXPECT_EQ(0.5f,mesh.property(qualityProp,OpenMesh::VertexHandle(1))) << "Wrong quality value at Vertex 1";
491  EXPECT_EQ(0.7f,mesh.property(qualityProp,OpenMesh::VertexHandle(2))) << "Wrong quality value at Vertex 2";
492  EXPECT_EQ(1.f,mesh.property(qualityProp,OpenMesh::VertexHandle(3))) << "Wrong quality value at Vertex 3";
493  EXPECT_EQ(0.1f,mesh.property(qualityProp,OpenMesh::VertexHandle(4))) << "Wrong quality value at Vertex 4";
494  EXPECT_EQ(0.f,mesh.property(qualityProp,OpenMesh::VertexHandle(5))) << "Wrong quality value at Vertex 5";
495  EXPECT_EQ(2.f,mesh.property(qualityProp,OpenMesh::VertexHandle(6))) << "Wrong quality value at Vertex 6";
496  EXPECT_EQ(5.f,mesh.property(qualityProp,OpenMesh::VertexHandle(7))) << "Wrong quality value at Vertex 7";
497 
498  //check for custom list properties
499 
501  ASSERT_TRUE(mesh.get_property_handle(testValues,"test_values")) << "Could not access texcoords per face";
502 
503  EXPECT_EQ(2u,mesh.property(testValues,OpenMesh::VertexHandle(0)).size()) << "Wrong verctor size";
504 
505  EXPECT_EQ(1,mesh.property(testValues,OpenMesh::VertexHandle(0))[0]) << "Wrong list value at Vertex 0";
506  EXPECT_EQ(4,mesh.property(testValues,OpenMesh::VertexHandle(1))[1]) << "Wrong list value at Vertex 1";
507  EXPECT_EQ(5,mesh.property(testValues,OpenMesh::VertexHandle(2))[0]) << "Wrong list value at Vertex 2";
508  EXPECT_EQ(8,mesh.property(testValues,OpenMesh::VertexHandle(3))[1]) << "Wrong list value at Vertex 3";
509  EXPECT_EQ(9,mesh.property(testValues,OpenMesh::VertexHandle(4))[0]) << "Wrong list value at Vertex 4";
510  EXPECT_EQ(12,mesh.property(testValues,OpenMesh::VertexHandle(5))[1]) << "Wrong list value at Vertex 5";
511  EXPECT_EQ(13,mesh.property(testValues,OpenMesh::VertexHandle(6))[0]) << "Wrong list value at Vertex 6";
512  EXPECT_EQ(16,mesh.property(testValues,OpenMesh::VertexHandle(7))[1]) << "Wrong list value at Vertex 7";
513 
515  ASSERT_TRUE(mesh.get_property_handle(texCoordsPerFace,"texcoords")) << "Could not access texcoords per face";
516 
517  for (Mesh::FaceIter f_iter = mesh.faces_begin(); f_iter != mesh.faces_end(); ++f_iter)
518  {
519  EXPECT_EQ(8u, mesh.property(texCoordsPerFace, *f_iter).size()) << "Texcoords per face container has wrong size on face: " << f_iter->idx();
520  if (!mesh.property(texCoordsPerFace, *f_iter).empty())
521  {
522  EXPECT_EQ(1.0, mesh.property(texCoordsPerFace, *f_iter)[0]) << "Texcoords wrong on index 0 with face: " << f_iter->idx();
523  EXPECT_EQ(1.0, mesh.property(texCoordsPerFace, *f_iter)[1]) << "Texcoords wrong on index 1 with face: " << f_iter->idx();
524  EXPECT_EQ(-1.0f, mesh.property(texCoordsPerFace, *f_iter)[2]) << "Texcoords wrong on index 2 with face: " << f_iter->idx();
525  EXPECT_EQ(-1.0f, mesh.property(texCoordsPerFace, *f_iter)[3]) << "Texcoords wrong on index 3 with face: " << f_iter->idx();
526  EXPECT_EQ(0.0f, mesh.property(texCoordsPerFace, *f_iter)[4]) << "Texcoords wrong on index 4 with face: " << f_iter->idx();
527  EXPECT_EQ(0.0f, mesh.property(texCoordsPerFace, *f_iter)[5]) << "Texcoords wrong on index 5 with face: " << f_iter->idx();
528  EXPECT_EQ(-0.5f, mesh.property(texCoordsPerFace, *f_iter)[6]) << "Texcoords wrong on index 6 with face: " << f_iter->idx();
529  EXPECT_EQ(-0.5f, mesh.property(texCoordsPerFace, *f_iter)[7]) << "Texcoords wrong on index 7 with face: " << f_iter->idx();
530  }
531 
532  }
533 
535  ASSERT_TRUE(mesh.get_property_handle(faceIndex,"faceIndex")) << "Could not access faceIndex per face";
536 
537  EXPECT_EQ(0u,mesh.property(faceIndex,OpenMesh::FaceHandle(0))) << "Wrong index value at FaceHandle 0";
538  EXPECT_EQ(1u,mesh.property(faceIndex,OpenMesh::FaceHandle(1))) << "Wrong index value at FaceHandle 1";
539  EXPECT_EQ(2u,mesh.property(faceIndex,OpenMesh::FaceHandle(2))) << "Wrong index value at FaceHandle 2";
540  EXPECT_EQ(3u,mesh.property(faceIndex,OpenMesh::FaceHandle(3))) << "Wrong index value at FaceHandle 3";
541  EXPECT_EQ(4u,mesh.property(faceIndex,OpenMesh::FaceHandle(4))) << "Wrong index value at FaceHandle 4";
542  EXPECT_EQ(5u,mesh.property(faceIndex,OpenMesh::FaceHandle(5))) << "Wrong index value at FaceHandle 5";
543 
544 }
545 
546 
547 TEST_F(OpenMeshReadWritePLY, WriteReadSimplePLYWithCustomProps) {
548 
549  PolyMesh mesh;
550 
551  OpenMesh::IO::Options options;
552  bool ok = OpenMesh::IO::read_mesh(mesh, "cube-minimal.ply", options);
553 
554 
557  OpenMesh::VPropHandleT<double> qualityProp;
559  OpenMesh::VPropHandleT<int> removedProp;
560 
561  const std::string indexPropName = "mySuperIndexProperty";
562  const std::string qualityPropName = "quality";
563  const std::string facePropName = "anotherPropForFaces";
564  const std::string nonPersistantName = "nonPersistant";
565  const std::string removedPropName = "willBeRemoved";
566 
567  mesh.add_property(indexProp,indexPropName);
568  mesh.add_property(qualityProp,qualityPropName);
569  mesh.add_property(removedProp, removedPropName);
570  mesh.add_property(faceProp,facePropName);
571  mesh.add_property(nonPersistant,nonPersistantName);
572 
573  mesh.property(indexProp).set_persistent(true);
574  mesh.property(qualityProp).set_persistent(true);
575  mesh.property(faceProp).set_persistent(true);
576  mesh.remove_property(removedProp);
577 
578  signed char i=0;
579  for (Mesh::VertexIter v_iter = mesh.vertices_begin(); v_iter != mesh.vertices_end(); ++v_iter, ++i)
580  {
581  mesh.property(indexProp, *v_iter) = i;
582  mesh.property(qualityProp, *v_iter) = 3.5*i;
583  }
584 
585  i = 0;
586  for (Mesh::FaceIter f_iter = mesh.faces_begin(); f_iter != mesh.faces_end(); ++f_iter, ++i)
587  {
588  mesh.property(faceProp, *f_iter) = -i;
589  }
590 
591  const char* outFilename = "cube-minimal-customprops_openmeshOutputTestfile.ply";
592  ok = OpenMesh::IO::write_mesh(mesh, outFilename);
593 
594  ASSERT_TRUE(ok);
595 
596  PolyMesh loadedMesh;
597 
598  EXPECT_FALSE(loadedMesh.get_property_handle(indexProp,indexPropName)) << "Could access to property which was deleted";
599 
601  ok = OpenMesh::IO::read_mesh(loadedMesh, outFilename, options);
602 
603  ASSERT_TRUE(ok);
604 
605 
606  ASSERT_TRUE(loadedMesh.get_property_handle(indexProp,indexPropName)) << "Could not access index property";
607  ASSERT_TRUE(loadedMesh.get_property_handle(qualityProp,qualityPropName)) << "Could not access quality property";
608  ASSERT_TRUE(loadedMesh.get_property_handle(faceProp,facePropName)) << "Could not access face property";
609  EXPECT_FALSE(loadedMesh.get_property_handle(nonPersistant,nonPersistantName)) << "Could access non persistant property";
610 
611  i=0;
612  for (Mesh::VertexIter v_iter = loadedMesh.vertices_begin(); v_iter != loadedMesh.vertices_end(); ++v_iter, ++i)
613  {
614  EXPECT_EQ(loadedMesh.property(indexProp, *v_iter), static_cast<unsigned>(i));
615  EXPECT_EQ(loadedMesh.property(qualityProp, *v_iter),3.5*i);
616  }
617 
618  i = 0;
619  for (Mesh::FaceIter f_iter = loadedMesh.faces_begin(); f_iter != loadedMesh.faces_end(); ++f_iter, ++i)
620  {
621  EXPECT_EQ(loadedMesh.property(faceProp, *f_iter),-i);
622  }
623 
624 
625  remove(outFilename);
626 
627 }
628 
629 TEST_F(OpenMeshReadWritePLY, WriteReadBinaryPLYWithCustomProps) {
630 
631  PolyMesh mesh;
632 
633  OpenMesh::IO::Options options;
634  bool ok = OpenMesh::IO::read_mesh(mesh, "cube-minimal.ply", options);
635 
636 
639  OpenMesh::VPropHandleT<double> qualityProp;
641  OpenMesh::VPropHandleT<int> removedProp;
642 
643  const std::string indexPropName = "mySuperIndexProperty";
644  const std::string qualityPropName = "quality";
645  const std::string facePropName = "anotherPropForFaces";
646  const std::string nonPersistantName = "nonPersistant";
647  const std::string removedPropName = "willBeRemoved";
648 
649  mesh.add_property(indexProp,indexPropName);
650  mesh.add_property(qualityProp,qualityPropName);
651  mesh.add_property(removedProp, removedPropName);
652  mesh.add_property(faceProp,facePropName);
653  mesh.add_property(nonPersistant,nonPersistantName);
654 
655  mesh.property(indexProp).set_persistent(true);
656  mesh.property(qualityProp).set_persistent(true);
657  mesh.property(faceProp).set_persistent(true);
658  mesh.remove_property(removedProp);
659 
660  signed char i=0;
661  for (Mesh::VertexIter v_iter = mesh.vertices_begin(); v_iter != mesh.vertices_end(); ++v_iter, ++i)
662  {
663  mesh.property(indexProp, *v_iter) = i;
664  mesh.property(qualityProp, *v_iter) = 3.5*i;
665  }
666 
667  i = 0;
668  for (Mesh::FaceIter f_iter = mesh.faces_begin(); f_iter != mesh.faces_end(); ++f_iter, ++i)
669  {
670  mesh.property(faceProp, *f_iter) = -i;
671  }
672 
673  const char* outFilename = "cube-minimal-customprops_openmeshOutputTestfileBinary.ply";
675  ok = OpenMesh::IO::write_mesh(mesh, outFilename, options);
676 
677  ASSERT_TRUE(ok);
678 
679  PolyMesh loadedMesh;
680 
681  EXPECT_FALSE(loadedMesh.get_property_handle(indexProp,indexPropName)) << "Could access to property which was deleted";
682 
683  options.clear();
686  ok = OpenMesh::IO::read_mesh(loadedMesh, outFilename, options);
687 
688  ASSERT_TRUE(ok);
689 
690 
691  ASSERT_TRUE(loadedMesh.get_property_handle(indexProp,indexPropName)) << "Could not access index property";
692  ASSERT_TRUE(loadedMesh.get_property_handle(qualityProp,qualityPropName)) << "Could not access quality property";
693  ASSERT_TRUE(loadedMesh.get_property_handle(faceProp,facePropName)) << "Could not access face property";
694  EXPECT_FALSE(loadedMesh.get_property_handle(nonPersistant,nonPersistantName)) << "Could access non persistant property";
695 
696  i=0;
697  for (Mesh::VertexIter v_iter = loadedMesh.vertices_begin(); v_iter != loadedMesh.vertices_end(); ++v_iter, ++i)
698  {
699  EXPECT_EQ(loadedMesh.property(indexProp, *v_iter), static_cast<unsigned>(i));
700  EXPECT_EQ(loadedMesh.property(qualityProp, *v_iter),3.5*i);
701  }
702 
703  i = 0;
704  for (Mesh::FaceIter f_iter = loadedMesh.faces_begin(); f_iter != loadedMesh.faces_end(); ++f_iter, ++i)
705  {
706  EXPECT_EQ(loadedMesh.property(faceProp, *f_iter),-i);
707  }
708 
709 
710  //remove(outFilename);
711 
712 }
713 
714 /*
715 * Just load a ply with extra elements
716 */
717 TEST_F(OpenMeshReadWritePLY, LoadSimplePLYWithExtraElements) {
718 
719  mesh_.clear();
720 
721  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-extra-elements.ply");
722 
723  EXPECT_TRUE(ok) << "Unable to load cube-minimal-extra-elements.ply";
724 
725  EXPECT_EQ(8u, mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
726  EXPECT_EQ(18u, mesh_.n_edges()) << "The number of loaded edges is not correct!";
727  EXPECT_EQ(12u, mesh_.n_faces()) << "The number of loaded faces is not correct!";
728 
729 }
730 
731 /*
732 * Just load a binary ply with extra elements
733 */
734 TEST_F(OpenMeshReadWritePLY, LoadSimpleBinaryPLYWithExtraElements) {
735 
736  mesh_.clear();
737 
739 
740  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-extra-elements-binary.ply", options);
741 
742  EXPECT_TRUE(ok) << "Unable to load cube-minimal-extra-elements-binary.ply";
743 
744  EXPECT_EQ(8u, mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
745  EXPECT_EQ(18u, mesh_.n_edges()) << "The number of loaded edges is not correct!";
746  EXPECT_EQ(12u, mesh_.n_faces()) << "The number of loaded faces is not correct!";
747 
748 }
749 
750 /*
751 * Ignore a file that does not contain vertices and faces
752 */
753 TEST_F(OpenMeshReadWritePLY, IgnoreNonMeshPlyFile) {
754 
755  mesh_.clear();
756 
757  std::stringstream data;
758  data << "ply" << "\n";
759  data << "format binary_little_endian 1.0" << "\n";
760  data << "comment Image data" << "\n";
761  data << "element image 0" << "\n";
762  data << "property list uint16 uint16 row" << "\n";
763  data << "end_header" << "\n";
764 
766 
767  bool ok = OpenMesh::IO::read_mesh(mesh_, data, ".ply", options);
768 
769  EXPECT_TRUE(ok) << "This empty file should be readable without an error!";
770 
771  EXPECT_EQ(0u, mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
772  EXPECT_EQ(0u, mesh_.n_edges()) << "The number of loaded edges is not correct!";
773  EXPECT_EQ(0u, mesh_.n_faces()) << "The number of loaded faces is not correct!";
774 }
775 
776 
777 /*
778 * Ignore a file that does not contain vertices and faces
779 */
780 TEST_F(OpenMeshReadWritePLY, FailOnUnknownPropertyTypeForLists) {
781 
782  mesh_.clear();
783 
784  std::stringstream data;
785  data << "ply" << "\n";
786  data << "format binary_little_endian 1.0" << "\n";
787  data << "comment Image data" << "\n";
788  data << "element image 0" << "\n";
789  data << "property list blibb blubb row" << "\n";
790  data << "end_header" << "\n";
791 
793 
794  bool ok = OpenMesh::IO::read_mesh(mesh_, data, ".ply", options);
795 
796  EXPECT_FALSE(ok) << "This file should fail to read!";
797 
798  EXPECT_EQ(0u, mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
799  EXPECT_EQ(0u, mesh_.n_edges()) << "The number of loaded edges is not correct!";
800  EXPECT_EQ(0u, mesh_.n_faces()) << "The number of loaded faces is not correct!";
801 }
802 
803 /*
804  * Load an ASCII PLY file of a cube with float RGB face colors
805  */
806 TEST_F(OpenMeshReadWritePLY, LoadSimplePLYWithFaceColors) {
807 
808  mesh_.clear();
809 
810  mesh_.request_face_colors();
811 
812  OpenMesh::IO::Options options;
814 
815  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-faceColors.ply",options);
816 
817  EXPECT_TRUE(ok) << "Unable to load cube-minimal-faceColors.ply";
818 
819  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
820  EXPECT_EQ(18u, mesh_.n_edges()) << "The number of loaded edges is not correct!";
821  EXPECT_EQ(12u, mesh_.n_faces()) << "The number of loaded faces is not correct!";
822 
823  EXPECT_EQ(107, mesh_.color(mesh_.face_handle(0))[0] ) << "Wrong face color at face 0";
824  EXPECT_EQ(117, mesh_.color(mesh_.face_handle(0))[1] ) << "Wrong face color at face 0";
825  EXPECT_EQ(177, mesh_.color(mesh_.face_handle(0))[2] ) << "Wrong face color at face 0";
826 
827  EXPECT_EQ(107, mesh_.color(mesh_.face_handle(3))[0] ) << "Wrong face color at face 3";
828  EXPECT_EQ(255, mesh_.color(mesh_.face_handle(3))[1] ) << "Wrong face color at face 3";
829  EXPECT_EQ(135, mesh_.color(mesh_.face_handle(3))[2] ) << "Wrong face color at face 3";
830 
831  EXPECT_EQ(163, mesh_.color(mesh_.face_handle(4))[0] ) << "Wrong face color at face 4";
832  EXPECT_EQ(107, mesh_.color(mesh_.face_handle(4))[1] ) << "Wrong face color at face 4";
833  EXPECT_EQ(177, mesh_.color(mesh_.face_handle(4))[2] ) << "Wrong face color at face 4";
834 
835  EXPECT_EQ(255, mesh_.color(mesh_.face_handle(7))[0] ) << "Wrong face color at face 7";
836  EXPECT_EQ(140, mesh_.color(mesh_.face_handle(7))[1] ) << "Wrong face color at face 7";
837  EXPECT_EQ(107, mesh_.color(mesh_.face_handle(7))[2] ) << "Wrong face color at face 7";
838 
839  EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!";
840  EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
841  EXPECT_FALSE(options.vertex_has_color()) << "Wrong user options are returned!";
842  EXPECT_TRUE(options.face_has_color()) << "Wrong user options are returned!";
843  EXPECT_FALSE(options.color_has_alpha()) << "Wrong user options are returned!";
844  EXPECT_FALSE(options.is_binary()) << "Wrong user options are returned!";
845 
846  mesh_.release_face_colors();
847 }
848 
849 /*
850  * Write and read PLY files with face colors in various formats
851  */
852 TEST_F(OpenMeshReadWritePLY, WriteAndReadPLYWithFaceColors) {
853  struct Format {
854  Format(const char* outFileName, OpenMesh::IO::Options options) :
855  _outFileName(outFileName),
856  _options(options)
857  {}
858  const char* _outFileName;
859  const OpenMesh::IO::Options _options;
860  }
861  formats[] =
862  {
863  Format("cube-minimal-faceColors_ascii_uchar.ply",
865  Format("cube-minimal-faceColors_ascii_float.ply",
867  Format("cube-minimal-faceColors_binary_uchar.ply",
869  Format("cube-minimal-faceColors_binary_float.ply",
871  // Test writing/reading alpha values (all default 1.0/255), but the test mesh
872  // Color type has no alpha channel so there's nothing to test below
873  Format("cube-minimal-faceColors_alpha_ascii_uchar.ply",
875  Format("cube-minimal-faceColors_alpha_ascii_float.ply",
877  Format("cube-minimal-faceColors_alpha_binary_uchar.ply",
879  Format("cube-minimal-faceColors_alpha_binary_float.ply",
881  };
882 
883  for (size_t i = 0; i < sizeof(formats) / sizeof(Format); ++i)
884  {
885  const char* outFileName = formats[i]._outFileName;
886 
887  mesh_.clear();
888 
889  mesh_.request_face_colors();
890 
891  OpenMesh::IO::Options options;
893 
894  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-faceColors.ply", options);
895 
896  EXPECT_TRUE(ok) << "Unable to load cube-minimal-faceColors.ply";
897 
898  options = formats[i]._options;
900  ok = OpenMesh::IO::write_mesh(mesh_, outFileName, options);
901  EXPECT_TRUE(ok) << "Unable to write " << outFileName;
902 
903  // Reset for reading: let the reader determine binary/float/etc.
905  mesh_.clear();
906  ok = OpenMesh::IO::read_mesh(mesh_, outFileName, options);
907  EXPECT_TRUE(ok) << "Unable to load " << outFileName;
908 
909  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct: " << outFileName;
910  EXPECT_EQ(18u, mesh_.n_edges()) << "The number of loaded edges is not correct: " << outFileName;
911  EXPECT_EQ(12u, mesh_.n_faces()) << "The number of loaded faces is not correct: " << outFileName;
912 
913  EXPECT_EQ(107, mesh_.color(mesh_.face_handle(0))[0] ) << "Wrong face color at face 0: " << outFileName;
914  EXPECT_EQ(117, mesh_.color(mesh_.face_handle(0))[1] ) << "Wrong face color at face 0: " << outFileName;
915  EXPECT_EQ(177, mesh_.color(mesh_.face_handle(0))[2] ) << "Wrong face color at face 0: " << outFileName;
916 
917  EXPECT_EQ(107, mesh_.color(mesh_.face_handle(3))[0] ) << "Wrong face color at face 3: " << outFileName;
918  EXPECT_EQ(255, mesh_.color(mesh_.face_handle(3))[1] ) << "Wrong face color at face 3: " << outFileName;
919  EXPECT_EQ(135, mesh_.color(mesh_.face_handle(3))[2] ) << "Wrong face color at face 3: " << outFileName;
920 
921  EXPECT_EQ(163, mesh_.color(mesh_.face_handle(4))[0] ) << "Wrong face color at face 4: " << outFileName;
922  EXPECT_EQ(107, mesh_.color(mesh_.face_handle(4))[1] ) << "Wrong face color at face 4: " << outFileName;
923  EXPECT_EQ(177, mesh_.color(mesh_.face_handle(4))[2] ) << "Wrong face color at face 4: " << outFileName;
924 
925  EXPECT_EQ(255, mesh_.color(mesh_.face_handle(7))[0] ) << "Wrong face color at face 7: " << outFileName;
926  EXPECT_EQ(140, mesh_.color(mesh_.face_handle(7))[1] ) << "Wrong face color at face 7: " << outFileName;
927  EXPECT_EQ(107, mesh_.color(mesh_.face_handle(7))[2] ) << "Wrong face color at face 7: " << outFileName;
928 
929  EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned: " << outFileName;
930  EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned: " << outFileName;
931  EXPECT_FALSE(options.vertex_has_color()) << "Wrong user options are returned: " << outFileName;
932  EXPECT_TRUE(options.face_has_color()) << "Wrong user options are returned: " << outFileName;
933  EXPECT_EQ(formats[i]._options.color_is_float(), options.color_is_float()) <<
934  "Wrong user options are returned: " << outFileName;
935  EXPECT_EQ(formats[i]._options.is_binary(), options.is_binary()) <<
936  "Wrong user options are returned: " << outFileName;
937 
938  mesh_.release_face_colors();
939  }
940 }
941 
942 }
Has (r) / store (w) vertex colors.
Definition: Options.hh:105
Handle for a vertex entity.
Definition: Handles.hh:120
Has (r) / store (w) face colors.
Definition: Options.hh:109
Has (r) / store (w) float values for colors (currently only implemented for PLY and OFF files) ...
Definition: Options.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:207
Has (r) / store (w) texture coordinates.
Definition: Options.hh:106
Handle for a face entity.
Definition: Handles.hh:141
void clear(void)
Clear all bits.
Definition: Options.hh:147
Has (r) custom properties (currently only implemented in PLY Reader ASCII version) ...
Definition: Options.hh:113
Set options for reader/writer modules.
Definition: Options.hh:90
Has (r) / store (w) alpha values for colors.
Definition: Options.hh:111
int idx() const
Get the underlying index of this handle.
Definition: Handles.hh:69
Set binary mode for r/w.
Definition: Options.hh:100
Has (r) / store (w) vertex normals.
Definition: Options.hh:104
bool read_mesh(Mesh &_mesh, const std::string &_filename)
Read a mesh from file _filename.
Definition: MeshIO.hh:112