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  * Just load a ply file and set vertex color option before loading
86  */
87 TEST_F(OpenMeshReadWritePLY, LoadSimplePLYForceVertexColorsAlthoughNotAvailable) {
88 
89  mesh_.clear();
90 
91  mesh_.request_vertex_colors();
92 
93  std::string file_name = "cube-minimal.ply";
94 
95  OpenMesh::IO::Options options;
97 
98  bool ok = OpenMesh::IO::read_mesh(mesh_, file_name,options);
99 
100  EXPECT_TRUE(ok) << file_name;
101 
102  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
103  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
104  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
105  EXPECT_EQ(36u , mesh_.n_halfedges()) << "The number of loaded halfedges is not correct!";
106 
107  EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!";
108  EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
109  EXPECT_FALSE(options.vertex_has_color()) << "Wrong user options are returned!";
110 }
111 
112 /*
113  * Just load a ply file of a cube with vertex colors
114  */
115 TEST_F(OpenMeshReadWritePLY, LoadSimplePLYWithVertexColors) {
116 
117  mesh_.clear();
118 
119  mesh_.request_vertex_colors();
120 
121  OpenMesh::IO::Options options;
123 
124  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-vertexColors.ply",options);
125 
126  EXPECT_TRUE(ok) << "Unable to load cube-minimal-vertexColors.ply";
127 
128  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
129  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
130  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
131 
132  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0";
133  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1";
134  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2";
135 
136  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0";
137  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1";
138  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2";
139 
140  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0";
141  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1";
142  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2";
143 
144  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0";
145  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1";
146  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2";
147 
148  EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!";
149  EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
150  EXPECT_TRUE(options.vertex_has_color()) << "Wrong user options are returned!";
151 
152  mesh_.release_vertex_colors();
153 }
154 
155 /*
156  * Just load a ply file of a cube with vertex colors
157  */
158 TEST_F(OpenMeshReadWritePLY, LoadPLYFromMeshLabWithVertexColors) {
159 
160  mesh_.clear();
161 
162  mesh_.request_vertex_colors();
163 
164  OpenMesh::IO::Options options;
166 
167  bool ok = OpenMesh::IO::read_mesh(mesh_, "meshlab.ply",options);
168 
169  EXPECT_TRUE(ok) << "Unable to load meshlab.ply";
170 
171  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
172  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
173  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
174 
175  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0";
176  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1";
177  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2";
178 
179  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0";
180  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1";
181  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2";
182 
183  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0";
184  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1";
185  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2";
186 
187  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0";
188  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1";
189  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2";
190 
191  EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!";
192  EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
193  EXPECT_TRUE(options.vertex_has_color()) << "Wrong user options are returned!";
194 
195  mesh_.release_vertex_colors();
196 }
197 
198 /*
199  * Just read and write a binary ply file of a cube with vertex colors
200  */
201 TEST_F(OpenMeshReadWritePLY, WriteAndReadBinaryPLYWithVertexColors) {
202 
203  mesh_.clear();
204 
205  mesh_.request_vertex_colors();
206 
207  OpenMesh::IO::Options options;
209 
210  bool ok = OpenMesh::IO::read_mesh(mesh_, "meshlab.ply",options);
211 
212  EXPECT_TRUE(ok) << "Unable to load meshlab.ply";
213 
215 
216  ok = OpenMesh::IO::write_mesh(mesh_, "meshlab_binary.ply",options);
217  EXPECT_TRUE(ok) << "Unable to write meshlab_binary.ply";
218 
219  mesh_.clear();
220  ok = OpenMesh::IO::read_mesh(mesh_, "meshlab_binary.ply",options);
221  EXPECT_TRUE(ok) << "Unable to load meshlab_binary.ply";
222 
223  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
224  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
225  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
226 
227  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0";
228  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1";
229  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2";
230 
231  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0";
232  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1";
233  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2";
234 
235  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0";
236  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1";
237  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2";
238 
239  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0";
240  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1";
241  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2";
242 
243  EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!";
244  EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
245  EXPECT_TRUE(options.vertex_has_color()) << "Wrong user options are returned!";
246 
247  mesh_.release_vertex_colors();
248 }
249 
250 /*
251  * Just read and write a ply file of a cube with float vertex colors
252  */
253 TEST_F(OpenMeshReadWritePLY, WriteAndReadPLYWithFloatVertexColors) {
254 
255  mesh_.clear();
256 
257  mesh_.request_vertex_colors();
258 
259  OpenMesh::IO::Options options;
261 
262  bool ok = OpenMesh::IO::read_mesh(mesh_, "meshlab.ply",options);
263 
264  EXPECT_TRUE(ok) << "Unable to load meshlab.ply";
265 
267 
268  ok = OpenMesh::IO::write_mesh(mesh_, "meshlab_float.ply",options);
269  EXPECT_TRUE(ok) << "Unable to write meshlab_float.ply";
270 
271  mesh_.clear();
272  ok = OpenMesh::IO::read_mesh(mesh_, "meshlab_float.ply",options);
273  EXPECT_TRUE(ok) << "Unable to load meshlab_float.ply";
274 
275  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
276  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
277  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
278 
279  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0";
280  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1";
281  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2";
282 
283  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0";
284  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1";
285  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2";
286 
287  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0";
288  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1";
289  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2";
290 
291  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0";
292  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1";
293  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2";
294 
295  EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!";
296  EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
297  EXPECT_TRUE(options.vertex_has_color()) << "Wrong user options are returned!";
298  EXPECT_TRUE(options.color_is_float()) << "Wrong user options are returned!";
299 
300  mesh_.release_vertex_colors();
301 }
302 
303 /*
304  * Just read and write a binary ply file of a cube with float vertex colors
305  */
306 TEST_F(OpenMeshReadWritePLY, WriteAndReadBinaryPLYWithFloatVertexColors) {
307 
308  mesh_.clear();
309 
310  mesh_.request_vertex_colors();
311 
312  OpenMesh::IO::Options options;
314 
315  bool ok = OpenMesh::IO::read_mesh(mesh_, "meshlab.ply",options);
316 
317  EXPECT_TRUE(ok) << "Unable to load meshlab.ply";
318 
321 
322  ok = OpenMesh::IO::write_mesh(mesh_, "meshlab_binary_float.ply",options);
323  EXPECT_TRUE(ok) << "Unable to write meshlab_binary_float.ply";
324 
325  mesh_.clear();
326  ok = OpenMesh::IO::read_mesh(mesh_, "meshlab_binary_float.ply",options);
327  EXPECT_TRUE(ok) << "Unable to load meshlab_binary_float.ply";
328 
329  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
330  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
331  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
332 
333  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0";
334  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1";
335  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2";
336 
337  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0";
338  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1";
339  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2";
340 
341  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0";
342  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1";
343  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2";
344 
345  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0";
346  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1";
347  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2";
348 
349  EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!";
350  EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
351  EXPECT_TRUE(options.vertex_has_color()) << "Wrong user options are returned!";
352  EXPECT_TRUE(options.color_is_float()) << "Wrong user options are returned!";
353  EXPECT_TRUE(options.is_binary()) << "Wrong user options are returned!";
354 
355  mesh_.release_vertex_colors();
356 }
357 
358 /*
359  * Just load a ply file of a cube with vertex texCoords
360  */
361 TEST_F(OpenMeshReadWritePLY, LoadSimplePLYWithTexCoords) {
362 
363  mesh_.clear();
364 
365  mesh_.request_vertex_texcoords2D();
366 
367  OpenMesh::IO::Options options;
369 
370  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-texCoords.ply",options);
371 
372  EXPECT_TRUE(ok) << "Unable to load cube-minimal-texCoords.ply";
373 
374  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
375  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
376  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
377 
378  EXPECT_EQ(10, mesh_.texcoord2D(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0";
379  EXPECT_EQ(10, mesh_.texcoord2D(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1";
380 
381  EXPECT_EQ(6, mesh_.texcoord2D(mesh_.vertex_handle(2))[0] ) << "Wrong vertex color at vertex 2 component 0";
382  EXPECT_EQ(6, mesh_.texcoord2D(mesh_.vertex_handle(2))[1] ) << "Wrong vertex color at vertex 2 component 1";
383 
384  EXPECT_EQ(9, mesh_.texcoord2D(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0";
385  EXPECT_EQ(9, mesh_.texcoord2D(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1";
386 
387  EXPECT_EQ(12, mesh_.texcoord2D(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0";
388  EXPECT_EQ(12, mesh_.texcoord2D(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1";
389 
390 
391  EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!";
392  EXPECT_TRUE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
393  EXPECT_FALSE(options.vertex_has_color()) << "Wrong user options are returned!";
394 
395  mesh_.release_vertex_texcoords2D();
396 }
397 
398 /*
399  * Just load a ply with normals, ascii mode
400  */
401 TEST_F(OpenMeshReadWritePLY, LoadSimplePLYWithNormals) {
402 
403  mesh_.clear();
404 
405  mesh_.request_vertex_normals();
406 
407  OpenMesh::IO::Options options;
409 
410  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-normals.ply", options);
411 
412  EXPECT_TRUE(ok) << "Unable to load cube-minimal-normals.ply";
413 
414  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
415  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
416  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
417 
418  EXPECT_TRUE(options.vertex_has_normal()) << "Wrong user options are returned!";
419  EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
420  EXPECT_FALSE(options.vertex_has_color()) << "Wrong user options are returned!";
421 
422 
423  EXPECT_EQ(0, mesh_.normal(mesh_.vertex_handle(0))[0] ) << "Wrong normal at vertex 0 component 0";
424  EXPECT_EQ(0, mesh_.normal(mesh_.vertex_handle(0))[1] ) << "Wrong normal at vertex 0 component 1";
425  EXPECT_EQ(1, mesh_.normal(mesh_.vertex_handle(0))[2] ) << "Wrong normal at vertex 0 component 2";
426 
427  EXPECT_EQ(1, mesh_.normal(mesh_.vertex_handle(3))[0] ) << "Wrong normal at vertex 3 component 0";
428  EXPECT_EQ(0, mesh_.normal(mesh_.vertex_handle(3))[1] ) << "Wrong normal at vertex 3 component 1";
429  EXPECT_EQ(0, mesh_.normal(mesh_.vertex_handle(3))[2] ) << "Wrong normal at vertex 3 component 2";
430 
431  EXPECT_EQ(1, mesh_.normal(mesh_.vertex_handle(4))[0] ) << "Wrong normal at vertex 4 component 0";
432  EXPECT_EQ(0, mesh_.normal(mesh_.vertex_handle(4))[1] ) << "Wrong normal at vertex 4 component 1";
433  EXPECT_EQ(1, mesh_.normal(mesh_.vertex_handle(4))[2] ) << "Wrong normal at vertex 4 component 2";
434 
435  EXPECT_EQ(1, mesh_.normal(mesh_.vertex_handle(7))[0] ) << "Wrong normal at vertex 7 component 0";
436  EXPECT_EQ(1, mesh_.normal(mesh_.vertex_handle(7))[1] ) << "Wrong normal at vertex 7 component 1";
437  EXPECT_EQ(2, mesh_.normal(mesh_.vertex_handle(7))[2] ) << "Wrong normal at vertex 7 component 2";
438 
439  mesh_.release_vertex_normals();
440 
441 }
442 
443 /*
444  * Just load a ply with custom properties, ascii mode
445  */
446 TEST_F(OpenMeshReadWritePLY, LoadSimplePLYWithCustomProps) {
447 
448  PolyMesh mesh;
449 
450  OpenMesh::IO::Options options;
452 
453  bool ok = OpenMesh::IO::read_mesh(mesh, "cube-minimal-custom_props.ply", options);
454 
455  EXPECT_TRUE(ok) << "Unable to load cube-minimal-custom_props.ply";
456 
457  EXPECT_EQ(8u , mesh.n_vertices()) << "The number of loaded vertices is not correct!";
458  EXPECT_EQ(12u , mesh.n_edges()) << "The number of loaded edges is not correct!";
459  EXPECT_EQ(6u , mesh.n_faces()) << "The number of loaded faces is not correct!";
460 
461  OpenMesh::VPropHandleT<float> qualityProp;
463  ASSERT_TRUE(mesh.get_property_handle(qualityProp,"quality")) << "Could not access quality property";
464  ASSERT_TRUE(mesh.get_property_handle(indexProp,"index")) << "Could not access index property";
465 
466  //check index property
467  for (unsigned i = 0; i < mesh.n_vertices(); ++i)
468  EXPECT_EQ(i ,mesh.property(indexProp,OpenMesh::VertexHandle(i))) << "Vertex index at vertex " << i << " is wrong";
469 
470  //check quality property
471  EXPECT_EQ(1.f,mesh.property(qualityProp,OpenMesh::VertexHandle(0))) << "Wrong quality value at Vertex 0";
472  EXPECT_EQ(0.5f,mesh.property(qualityProp,OpenMesh::VertexHandle(1))) << "Wrong quality value at Vertex 1";
473  EXPECT_EQ(0.7f,mesh.property(qualityProp,OpenMesh::VertexHandle(2))) << "Wrong quality value at Vertex 2";
474  EXPECT_EQ(1.f,mesh.property(qualityProp,OpenMesh::VertexHandle(3))) << "Wrong quality value at Vertex 3";
475  EXPECT_EQ(0.1f,mesh.property(qualityProp,OpenMesh::VertexHandle(4))) << "Wrong quality value at Vertex 4";
476  EXPECT_EQ(0.f,mesh.property(qualityProp,OpenMesh::VertexHandle(5))) << "Wrong quality value at Vertex 5";
477  EXPECT_EQ(2.f,mesh.property(qualityProp,OpenMesh::VertexHandle(6))) << "Wrong quality value at Vertex 6";
478  EXPECT_EQ(5.f,mesh.property(qualityProp,OpenMesh::VertexHandle(7))) << "Wrong quality value at Vertex 7";
479 
480  //check for custom list properties
481 
483  ASSERT_TRUE(mesh.get_property_handle(testValues,"test_values")) << "Could not access texcoords per face";
484 
485  EXPECT_EQ(2u,mesh.property(testValues,OpenMesh::VertexHandle(0)).size()) << "Wrong verctor size";
486 
487  EXPECT_EQ(1,mesh.property(testValues,OpenMesh::VertexHandle(0))[0]) << "Wrong list value at Vertex 0";
488  EXPECT_EQ(4,mesh.property(testValues,OpenMesh::VertexHandle(1))[1]) << "Wrong list value at Vertex 1";
489  EXPECT_EQ(5,mesh.property(testValues,OpenMesh::VertexHandle(2))[0]) << "Wrong list value at Vertex 2";
490  EXPECT_EQ(8,mesh.property(testValues,OpenMesh::VertexHandle(3))[1]) << "Wrong list value at Vertex 3";
491  EXPECT_EQ(9,mesh.property(testValues,OpenMesh::VertexHandle(4))[0]) << "Wrong list value at Vertex 4";
492  EXPECT_EQ(12,mesh.property(testValues,OpenMesh::VertexHandle(5))[1]) << "Wrong list value at Vertex 5";
493  EXPECT_EQ(13,mesh.property(testValues,OpenMesh::VertexHandle(6))[0]) << "Wrong list value at Vertex 6";
494  EXPECT_EQ(16,mesh.property(testValues,OpenMesh::VertexHandle(7))[1]) << "Wrong list value at Vertex 7";
495 
497  ASSERT_TRUE(mesh.get_property_handle(texCoordsPerFace,"texcoords")) << "Could not access texcoords per face";
498 
499  for (Mesh::FaceIter f_iter = mesh.faces_begin(); f_iter != mesh.faces_end(); ++f_iter)
500  {
501  EXPECT_EQ(8u, mesh.property(texCoordsPerFace, *f_iter).size()) << "Texcoords per face container has wrong size on face: " << f_iter->idx();
502  if (!mesh.property(texCoordsPerFace, *f_iter).empty())
503  {
504  EXPECT_EQ(1.0, mesh.property(texCoordsPerFace, *f_iter)[0]) << "Texcoords wrong on index 0 with face: " << f_iter->idx();
505  EXPECT_EQ(1.0, mesh.property(texCoordsPerFace, *f_iter)[1]) << "Texcoords wrong on index 1 with face: " << f_iter->idx();
506  EXPECT_EQ(-1.0f, mesh.property(texCoordsPerFace, *f_iter)[2]) << "Texcoords wrong on index 2 with face: " << f_iter->idx();
507  EXPECT_EQ(-1.0f, mesh.property(texCoordsPerFace, *f_iter)[3]) << "Texcoords wrong on index 3 with face: " << f_iter->idx();
508  EXPECT_EQ(0.0f, mesh.property(texCoordsPerFace, *f_iter)[4]) << "Texcoords wrong on index 4 with face: " << f_iter->idx();
509  EXPECT_EQ(0.0f, mesh.property(texCoordsPerFace, *f_iter)[5]) << "Texcoords wrong on index 5 with face: " << f_iter->idx();
510  EXPECT_EQ(-0.5f, mesh.property(texCoordsPerFace, *f_iter)[6]) << "Texcoords wrong on index 6 with face: " << f_iter->idx();
511  EXPECT_EQ(-0.5f, mesh.property(texCoordsPerFace, *f_iter)[7]) << "Texcoords wrong on index 7 with face: " << f_iter->idx();
512  }
513 
514  }
515 
517  ASSERT_TRUE(mesh.get_property_handle(faceIndex,"faceIndex")) << "Could not access faceIndex per face";
518 
519  EXPECT_EQ(0u,mesh.property(faceIndex,OpenMesh::FaceHandle(0))) << "Wrong index value at FaceHandle 0";
520  EXPECT_EQ(1u,mesh.property(faceIndex,OpenMesh::FaceHandle(1))) << "Wrong index value at FaceHandle 1";
521  EXPECT_EQ(2u,mesh.property(faceIndex,OpenMesh::FaceHandle(2))) << "Wrong index value at FaceHandle 2";
522  EXPECT_EQ(3u,mesh.property(faceIndex,OpenMesh::FaceHandle(3))) << "Wrong index value at FaceHandle 3";
523  EXPECT_EQ(4u,mesh.property(faceIndex,OpenMesh::FaceHandle(4))) << "Wrong index value at FaceHandle 4";
524  EXPECT_EQ(5u,mesh.property(faceIndex,OpenMesh::FaceHandle(5))) << "Wrong index value at FaceHandle 5";
525 
526 }
527 
528 
529 TEST_F(OpenMeshReadWritePLY, WriteReadSimplePLYWithCustomProps) {
530 
531  PolyMesh mesh;
532 
533  OpenMesh::IO::Options options;
534  bool ok = OpenMesh::IO::read_mesh(mesh, "cube-minimal.ply", options);
535 
536 
539  OpenMesh::VPropHandleT<double> qualityProp;
541  OpenMesh::VPropHandleT<int> removedProp;
542 
543  const std::string indexPropName = "mySuperIndexProperty";
544  const std::string qualityPropName = "quality";
545  const std::string facePropName = "anotherPropForFaces";
546  const std::string nonPersistantName = "nonPersistant";
547  const std::string removedPropName = "willBeRemoved";
548 
549  mesh.add_property(indexProp,indexPropName);
550  mesh.add_property(qualityProp,qualityPropName);
551  mesh.add_property(removedProp, removedPropName);
552  mesh.add_property(faceProp,facePropName);
553  mesh.add_property(nonPersistant,nonPersistantName);
554 
555  mesh.property(indexProp).set_persistent(true);
556  mesh.property(qualityProp).set_persistent(true);
557  mesh.property(faceProp).set_persistent(true);
558  mesh.remove_property(removedProp);
559 
560  signed char i=0;
561  for (Mesh::VertexIter v_iter = mesh.vertices_begin(); v_iter != mesh.vertices_end(); ++v_iter, ++i)
562  {
563  mesh.property(indexProp, *v_iter) = i;
564  mesh.property(qualityProp, *v_iter) = 3.5*i;
565  }
566 
567  i = 0;
568  for (Mesh::FaceIter f_iter = mesh.faces_begin(); f_iter != mesh.faces_end(); ++f_iter, ++i)
569  {
570  mesh.property(faceProp, *f_iter) = -i;
571  }
572 
573  const char* outFilename = "cube-minimal-customprops_openmeshOutputTestfile.ply";
574  ok = OpenMesh::IO::write_mesh(mesh, outFilename);
575 
576  ASSERT_TRUE(ok);
577 
578  PolyMesh loadedMesh;
579 
580  EXPECT_FALSE(loadedMesh.get_property_handle(indexProp,indexPropName)) << "Could access to property which was deleted";
581 
583  ok = OpenMesh::IO::read_mesh(loadedMesh, outFilename, options);
584 
585  ASSERT_TRUE(ok);
586 
587 
588  ASSERT_TRUE(loadedMesh.get_property_handle(indexProp,indexPropName)) << "Could not access index property";
589  ASSERT_TRUE(loadedMesh.get_property_handle(qualityProp,qualityPropName)) << "Could not access quality property";
590  ASSERT_TRUE(loadedMesh.get_property_handle(faceProp,facePropName)) << "Could not access face property";
591  EXPECT_FALSE(loadedMesh.get_property_handle(nonPersistant,nonPersistantName)) << "Could access non persistant property";
592 
593  i=0;
594  for (Mesh::VertexIter v_iter = loadedMesh.vertices_begin(); v_iter != loadedMesh.vertices_end(); ++v_iter, ++i)
595  {
596  EXPECT_EQ(loadedMesh.property(indexProp, *v_iter), static_cast<unsigned>(i));
597  EXPECT_EQ(loadedMesh.property(qualityProp, *v_iter),3.5*i);
598  }
599 
600  i = 0;
601  for (Mesh::FaceIter f_iter = loadedMesh.faces_begin(); f_iter != loadedMesh.faces_end(); ++f_iter, ++i)
602  {
603  EXPECT_EQ(loadedMesh.property(faceProp, *f_iter),-i);
604  }
605 
606 
607  remove(outFilename);
608 
609 }
610 
611 TEST_F(OpenMeshReadWritePLY, WriteReadBinaryPLYWithCustomProps) {
612 
613  PolyMesh mesh;
614 
615  OpenMesh::IO::Options options;
616  bool ok = OpenMesh::IO::read_mesh(mesh, "cube-minimal.ply", options);
617 
618 
621  OpenMesh::VPropHandleT<double> qualityProp;
623  OpenMesh::VPropHandleT<int> removedProp;
624 
625  const std::string indexPropName = "mySuperIndexProperty";
626  const std::string qualityPropName = "quality";
627  const std::string facePropName = "anotherPropForFaces";
628  const std::string nonPersistantName = "nonPersistant";
629  const std::string removedPropName = "willBeRemoved";
630 
631  mesh.add_property(indexProp,indexPropName);
632  mesh.add_property(qualityProp,qualityPropName);
633  mesh.add_property(removedProp, removedPropName);
634  mesh.add_property(faceProp,facePropName);
635  mesh.add_property(nonPersistant,nonPersistantName);
636 
637  mesh.property(indexProp).set_persistent(true);
638  mesh.property(qualityProp).set_persistent(true);
639  mesh.property(faceProp).set_persistent(true);
640  mesh.remove_property(removedProp);
641 
642  signed char i=0;
643  for (Mesh::VertexIter v_iter = mesh.vertices_begin(); v_iter != mesh.vertices_end(); ++v_iter, ++i)
644  {
645  mesh.property(indexProp, *v_iter) = i;
646  mesh.property(qualityProp, *v_iter) = 3.5*i;
647  }
648 
649  i = 0;
650  for (Mesh::FaceIter f_iter = mesh.faces_begin(); f_iter != mesh.faces_end(); ++f_iter, ++i)
651  {
652  mesh.property(faceProp, *f_iter) = -i;
653  }
654 
655  const char* outFilename = "cube-minimal-customprops_openmeshOutputTestfileBinary.ply";
657  ok = OpenMesh::IO::write_mesh(mesh, outFilename, options);
658 
659  ASSERT_TRUE(ok);
660 
661  PolyMesh loadedMesh;
662 
663  EXPECT_FALSE(loadedMesh.get_property_handle(indexProp,indexPropName)) << "Could access to property which was deleted";
664 
665  options.clear();
668  ok = OpenMesh::IO::read_mesh(loadedMesh, outFilename, options);
669 
670  ASSERT_TRUE(ok);
671 
672 
673  ASSERT_TRUE(loadedMesh.get_property_handle(indexProp,indexPropName)) << "Could not access index property";
674  ASSERT_TRUE(loadedMesh.get_property_handle(qualityProp,qualityPropName)) << "Could not access quality property";
675  ASSERT_TRUE(loadedMesh.get_property_handle(faceProp,facePropName)) << "Could not access face property";
676  EXPECT_FALSE(loadedMesh.get_property_handle(nonPersistant,nonPersistantName)) << "Could access non persistant property";
677 
678  i=0;
679  for (Mesh::VertexIter v_iter = loadedMesh.vertices_begin(); v_iter != loadedMesh.vertices_end(); ++v_iter, ++i)
680  {
681  EXPECT_EQ(loadedMesh.property(indexProp, *v_iter), static_cast<unsigned>(i));
682  EXPECT_EQ(loadedMesh.property(qualityProp, *v_iter),3.5*i);
683  }
684 
685  i = 0;
686  for (Mesh::FaceIter f_iter = loadedMesh.faces_begin(); f_iter != loadedMesh.faces_end(); ++f_iter, ++i)
687  {
688  EXPECT_EQ(loadedMesh.property(faceProp, *f_iter),-i);
689  }
690 
691 
692  //remove(outFilename);
693 
694 }
695 }
Has (r) custom properties (currently only implemented in PLY Reader ASCII version) ...
Definition: Options.hh:118
Has (r) / store (w) texture coordinates.
Definition: Options.hh:111
Set binary mode for r/w.
Definition: Options.hh:105
Has (r) / store (w) vertex normals.
Definition: Options.hh:109
void clear(void)
Clear all bits.
Definition: Options.hh:151
Has (r) / store (w) float values for colors (currently only implemented for PLY and OFF files) ...
Definition: Options.hh:117
int idx() const
Get the underlying index of this handle.
Definition: Handles.hh:74
bool read_mesh(Mesh &_mesh, const std::string &_filename)
Read a mesh from file _filename.
Definition: MeshIO.hh:104
Set options for reader/writer modules.
Definition: Options.hh:95
Handle for a vertex entity.
Definition: Handles.hh:125
Handle for a face entity.
Definition: Handles.hh:146
Has (r) / store (w) vertex colors.
Definition: Options.hh:110
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:199