Developer Documentation
unittests_read_write_OM.cc
1 #include <gtest/gtest.h>
2 #include <Unittests/unittests_common.hh>
3 
4 
5 namespace {
6 
7 class OpenMeshReadWriteOM : 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 an om file and set vertex color option before loading
35  */
36 TEST_F(OpenMeshReadWriteOM, LoadSimpleOMForceVertexColorsAlthoughNotAvailable) {
37 
38  mesh_.clear();
39 
40  mesh_.request_vertex_colors();
41 
42  std::string file_name = "cube-minimal.om";
43 
44  OpenMesh::IO::Options options;
46 
47  bool ok = OpenMesh::IO::read_mesh(mesh_, file_name,options);
48 
49  EXPECT_TRUE(ok) << file_name;
50 
51  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
52  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
53  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
54  EXPECT_EQ(36u , mesh_.n_halfedges()) << "The number of loaded halfedges is not correct!";
55 
56  EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!";
57  EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
58  EXPECT_FALSE(options.vertex_has_color()) << "Wrong user options are returned!";
59 }
60 
61 /*
62  * Just load an om file of a cube with vertex texCoords
63  */
64 TEST_F(OpenMeshReadWriteOM, LoadSimpleOMWithTexCoords) {
65 
66  mesh_.clear();
67 
68  mesh_.request_vertex_texcoords2D();
69 
70  OpenMesh::IO::Options options;
72 
73  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-texCoords.om",options);
74 
75  ASSERT_TRUE(ok) << "Unable to load cube-minimal-texCoords.om";
76 
77  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
78  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
79  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
80 
81  EXPECT_EQ(10, mesh_.texcoord2D(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0";
82  EXPECT_EQ(10, mesh_.texcoord2D(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1";
83 
84  EXPECT_EQ(6, mesh_.texcoord2D(mesh_.vertex_handle(2))[0] ) << "Wrong vertex color at vertex 2 component 0";
85  EXPECT_EQ(6, mesh_.texcoord2D(mesh_.vertex_handle(2))[1] ) << "Wrong vertex color at vertex 2 component 1";
86 
87  EXPECT_EQ(9, mesh_.texcoord2D(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0";
88  EXPECT_EQ(9, mesh_.texcoord2D(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1";
89 
90  EXPECT_EQ(12, mesh_.texcoord2D(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0";
91  EXPECT_EQ(12, mesh_.texcoord2D(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1";
92 
93 
94  EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!";
95  EXPECT_TRUE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
96  EXPECT_FALSE(options.vertex_has_color()) << "Wrong user options are returned!";
97 
98  mesh_.release_vertex_texcoords2D();
99 }
100 
101 /*
102  * Just load an om file of a cube with vertex colors
103  */
104 TEST_F(OpenMeshReadWriteOM, LoadSimpleOMWithVertexColors) {
105 
106  mesh_.clear();
107 
108  mesh_.request_vertex_colors();
109 
110  OpenMesh::IO::Options options;
112 
113  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-vertexColors.om",options);
114 
115  EXPECT_TRUE(ok) << "Unable to load cube-minimal-vertexColors.om";
116 
117  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
118  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
119  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
120 
121 #ifdef TEST_DOUBLE_TRAITS
122  EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0";
123  EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1";
124  EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2";
125 
126  EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0";
127  EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1";
128  EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2";
129 
130  EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0";
131  EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1";
132  EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2";
133 
134  EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0";
135  EXPECT_FLOAT_EQ(0.0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1";
136  EXPECT_FLOAT_EQ(1.0, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2";
137 #else
138  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0";
139  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1";
140  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2";
141 
142  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0";
143  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1";
144  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2";
145 
146  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0";
147  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1";
148  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2";
149 
150  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0";
151  EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1";
152  EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2";
153 #endif
154 
155  EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!";
156  EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
157  EXPECT_TRUE(options.vertex_has_color()) << "Wrong user options are returned!";
158 
159  mesh_.release_vertex_colors();
160 }
161 
162 /*
163  * Save and load simple mesh
164  */
165 TEST_F(OpenMeshReadWriteOM, WriteTriangle) {
166 
167  Mesh mesh;
168  mesh.clear();
169 
170  const std::string filename = "triangle-minimal.om";
171 
172  // generate data
173  Mesh::VertexHandle v1 = mesh.add_vertex(Mesh::Point(1.0,0.0,0.0));
174  Mesh::VertexHandle v2 = mesh.add_vertex(Mesh::Point(0.0,1.0,0.0));
175  Mesh::VertexHandle v3 = mesh.add_vertex(Mesh::Point(0.0,0.0,1.0));
176  mesh.add_face(v1,v2,v3);
177 
178  // save
179  bool ok = OpenMesh::IO::write_mesh(mesh,filename);
180  EXPECT_TRUE(ok) << "Unable to write " << filename;
181 
182  // reset
183  mesh.clear();
184 
185  // load
186  ok = OpenMesh::IO::read_mesh(mesh,filename);
187  EXPECT_TRUE(ok) << "Unable to read " << filename;
188 
189  // compare
190  EXPECT_EQ(3u , mesh.n_vertices()) << "The number of loaded vertices is not correct!";
191  EXPECT_EQ(3u , mesh.n_edges()) << "The number of loaded edges is not correct!";
192  EXPECT_EQ(1u , mesh.n_faces()) << "The number of loaded faces is not correct!";
193 
194  EXPECT_EQ(Mesh::Point(1.0,0.0,0.0) , mesh.point(v1)) << "Wrong coordinates at vertex 0";
195  EXPECT_EQ(Mesh::Point(0.0,1.0,0.0) , mesh.point(v2)) << "Wrong coordinates at vertex 1";
196  EXPECT_EQ(Mesh::Point(0.0,0.0,1.0) , mesh.point(v3)) << "Wrong coordinates at vertex 2";
197 
198  // cleanup
199  remove(filename.c_str());
200 
201 }
202 
203 /*
204  * Save and load simple mesh with integer colors per vertex
205  */
206 TEST_F(OpenMeshReadWriteOM, WriteTriangleVertexIntegerColor) {
207 
208  Mesh mesh;
209 
210  mesh.request_vertex_colors();
211 
212  OpenMesh::IO::Options options;
215 
216  const std::string filename = "triangle-minimal-ColorsPerVertex.om";
217 
218  // generate data
219  Mesh::VertexHandle v1 = mesh.add_vertex(Mesh::Point(1.0,0.0,0.0));
220  Mesh::VertexHandle v2 = mesh.add_vertex(Mesh::Point(0.0,1.0,0.0));
221  Mesh::VertexHandle v3 = mesh.add_vertex(Mesh::Point(0.0,0.0,1.0));
222  mesh.add_face(v1,v2,v3);
223 
224 #ifdef TEST_DOUBLE_TRAITS
225  Mesh::Color c1 = Mesh::Color(0,0,123/255.0,1.0),
226  c2 = Mesh::Color(21/255.0,0,0,1.0),
227  c3 = Mesh::Color(0,222/255.0,0,1.0);
228 #else
229  Mesh::Color c1 = Mesh::Color(0,0,123),
230  c2 = Mesh::Color(21,0,0),
231  c3 = Mesh::Color(0,222,0);
232 #endif
233 
234  mesh.set_color(v1,c1);
235  mesh.set_color(v2,c2);
236  mesh.set_color(v3,c3);
237 
238  // save
239  bool ok = OpenMesh::IO::write_mesh(mesh,filename,options);
240  EXPECT_TRUE(ok) << "Unable to write "<<filename;
241 
242  mesh.release_vertex_colors();
243 
244  // load
245  Mesh cmpMesh;
246  cmpMesh.request_vertex_colors();
247  ok = OpenMesh::IO::read_mesh(cmpMesh,filename,options);
248  EXPECT_TRUE(ok) << "Unable to read "<<filename;
249 
250  EXPECT_TRUE(cmpMesh.has_vertex_colors()) << "Loaded mesh has no vertex colors.";
251 
252  // compare
253  EXPECT_EQ(3u , cmpMesh.n_vertices()) << "The number of loaded vertices is not correct!";
254  EXPECT_EQ(3u , cmpMesh.n_edges()) << "The number of loaded edges is not correct!";
255  EXPECT_EQ(1u , cmpMesh.n_faces()) << "The number of loaded faces is not correct!";
256 
257  EXPECT_EQ(Mesh::Point(1.0,0.0,0.0) , cmpMesh.point(v1)) << "Wrong coordinates at vertex 0";
258  EXPECT_EQ(Mesh::Point(0.0,1.0,0.0) , cmpMesh.point(v2)) << "Wrong coordinates at vertex 1";
259  EXPECT_EQ(Mesh::Point(0.0,0.0,1.0) , cmpMesh.point(v3)) << "Wrong coordinates at vertex 2";
260 
261 #ifdef TEST_DOUBLE_TRAITS
262  // OM file format does not support writing colors as float. They are stored as unsigned character.
263  // Thus, the values will not be exactly equal.
264  for (size_t i = 0; i < c1.size(); ++i)
265  {
266  EXPECT_FLOAT_EQ(c1[i] , cmpMesh.color(v1)[i]) << "Wrong colors at coordinate " << i << " of vertex 0";
267  EXPECT_FLOAT_EQ(c2[i] , cmpMesh.color(v2)[i]) << "Wrong colors at coordinate " << i << " of vertex 1";
268  EXPECT_FLOAT_EQ(c3[i] , cmpMesh.color(v3)[i]) << "Wrong colors at coordinate " << i << " of vertex 2";
269  }
270 #else
271  EXPECT_EQ(c1 , cmpMesh.color(v1)) << "Wrong colors at vertex 0";
272  EXPECT_EQ(c2 , cmpMesh.color(v2)) << "Wrong colors at vertex 1";
273  EXPECT_EQ(c3 , cmpMesh.color(v3)) << "Wrong colors at vertex 2";
274 #endif
275 
276  //clean up
277  cmpMesh.release_vertex_colors();
278  remove(filename.c_str());
279 
280 }
281 
282 /*
283  * Save and load simple mesh with custom property
284  */
285 TEST_F(OpenMeshReadWriteOM, WriteTriangleVertexBoolProperty) {
286 
287  Mesh mesh;
288 
289  const std::string filename = "triangle-minimal-VBProp.om";
290 
291  // generate data
292  Mesh::VertexHandle v1 = mesh.add_vertex(Mesh::Point(1.0,0.0,0.0));
293  Mesh::VertexHandle v2 = mesh.add_vertex(Mesh::Point(0.0,1.0,0.0));
294  Mesh::VertexHandle v3 = mesh.add_vertex(Mesh::Point(0.0,0.0,1.0));
295  mesh.add_face(v1,v2,v3);
296 
298  mesh.add_property(prop,"VBProp");
299  mesh.property(prop).set_persistent(true);
300 
301  mesh.property(prop,v1) = true;
302  mesh.property(prop,v2) = false;
303  mesh.property(prop,v3) = true;
304 
305  // save
306  bool ok = OpenMesh::IO::write_mesh(mesh,filename);
307  EXPECT_TRUE(ok) << "Unable to write "<<filename;
308 
309  // load
310  Mesh cmpMesh;
311 
312 
313  cmpMesh.add_property(prop,"VBProp");
314  cmpMesh.property(prop).set_persistent(true);
315 
316  ok = OpenMesh::IO::read_mesh(cmpMesh,filename);
317  EXPECT_TRUE(ok) << "Unable to read "<<filename;
318 
319  // compare
320  EXPECT_EQ(3u , cmpMesh.n_vertices()) << "The number of loaded vertices is not correct!";
321  EXPECT_EQ(3u , cmpMesh.n_edges()) << "The number of loaded edges is not correct!";
322  EXPECT_EQ(1u , cmpMesh.n_faces()) << "The number of loaded faces is not correct!";
323 
324  EXPECT_EQ(Mesh::Point(1.0,0.0,0.0) , cmpMesh.point(v1)) << "Wrong coordinates at vertex 0";
325  EXPECT_EQ(Mesh::Point(0.0,1.0,0.0) , cmpMesh.point(v2)) << "Wrong coordinates at vertex 1";
326  EXPECT_EQ(Mesh::Point(0.0,0.0,1.0) , cmpMesh.point(v3)) << "Wrong coordinates at vertex 2";
327 
328  EXPECT_TRUE(cmpMesh.property(prop,v1)) << "Wrong Property value at vertex 0";
329  EXPECT_FALSE(cmpMesh.property(prop,v2)) << "Wrong Property value at vertex 1";
330  EXPECT_TRUE(cmpMesh.property(prop,v3)) << "Wrong Property value at vertex 2";
331 
332  // cleanup
333  remove(filename.c_str());
334 
335 }
336 
337 /*
338  * Save and load simple mesh with custom property
339  */
340 TEST_F(OpenMeshReadWriteOM, WriteTriangleVertexBoolPropertySpaceEquivalent) {
341 
342  Mesh mesh;
343 
344  const std::string filename = "triangle-minimal-VBProp-pattern-test.om";
345 
346  // generate data
347  Mesh::VertexHandle v1 = mesh.add_vertex(Mesh::Point(1.0,0.0,0.0));
348  Mesh::VertexHandle v2 = mesh.add_vertex(Mesh::Point(0.0,1.0,0.0));
349  Mesh::VertexHandle v3 = mesh.add_vertex(Mesh::Point(0.0,0.0,1.0));
350  mesh.add_face(v1,v2,v3);
351 
352  Mesh::VertexHandle v4 = mesh.add_vertex(Mesh::Point(0.0,0.0,1.0));
353  Mesh::VertexHandle v5 = mesh.add_vertex(Mesh::Point(0.0,0.0,1.0));
354  Mesh::VertexHandle v6 = mesh.add_vertex(Mesh::Point(0.0,0.0,1.0));
355  mesh.add_face(v4,v5,v6);
356 
357  Mesh::VertexHandle v7 = mesh.add_vertex(Mesh::Point(0.0,0.0,1.0));
358  Mesh::VertexHandle v8 = mesh.add_vertex(Mesh::Point(0.0,0.0,1.0));
359  Mesh::VertexHandle v9 = mesh.add_vertex(Mesh::Point(0.0,0.0,1.0));
360 
362  mesh.add_property(prop,"VBProp");
363  mesh.property(prop).set_persistent(true);
364 
365  // Create a 0x20 hex pattern in the bitset
366  mesh.property(prop,v1) = false;
367  mesh.property(prop,v2) = false;
368  mesh.property(prop,v3) = false;
369  mesh.property(prop,v4) = false;
370  mesh.property(prop,v5) = false;
371  mesh.property(prop,v6) = true;
372  mesh.property(prop,v7) = false;
373  mesh.property(prop,v8) = false;
374  mesh.property(prop,v9) = true;
375 
376  // save
377  bool ok = OpenMesh::IO::write_mesh(mesh,filename);
378  EXPECT_TRUE(ok) << "Unable to write "<<filename;
379 
380  // load
381  Mesh cmpMesh;
382 
383  cmpMesh.add_property(prop,"VBProp");
384  cmpMesh.property(prop).set_persistent(true);
385 
386  ok = OpenMesh::IO::read_mesh(cmpMesh,filename);
387  EXPECT_TRUE(ok) << "Unable to read "<<filename;
388 
389  // compare
390  EXPECT_EQ(9u , cmpMesh.n_vertices()) << "The number of loaded vertices is not correct!";
391  EXPECT_EQ(6u , cmpMesh.n_edges()) << "The number of loaded edges is not correct!";
392  EXPECT_EQ(2u , cmpMesh.n_faces()) << "The number of loaded faces is not correct!";
393 
394  EXPECT_FALSE(cmpMesh.property(prop,v1)) << "Wrong Property value at vertex 0";
395  EXPECT_FALSE(cmpMesh.property(prop,v2)) << "Wrong Property value at vertex 1";
396  EXPECT_FALSE(cmpMesh.property(prop,v3)) << "Wrong Property value at vertex 2";
397  EXPECT_FALSE(cmpMesh.property(prop,v4)) << "Wrong Property value at vertex 3";
398  EXPECT_FALSE(cmpMesh.property(prop,v5)) << "Wrong Property value at vertex 4";
399  EXPECT_TRUE(cmpMesh.property(prop,v6)) << "Wrong Property value at vertex 5";
400  EXPECT_FALSE(cmpMesh.property(prop,v7)) << "Wrong Property value at vertex 6";
401  EXPECT_FALSE(cmpMesh.property(prop,v8)) << "Wrong Property value at vertex 7";
402  EXPECT_TRUE(cmpMesh.property(prop,v9)) << "Wrong Property value at vertex 8";
403 
404  // cleanup
405  remove(filename.c_str());
406 
407 }
408 
409 /*
410  * Save and load simple mesh with multiple custom property
411  */
412 TEST_F(OpenMeshReadWriteOM, WriteTriangleTwoVertexBoolProperty) {
413 
414  Mesh mesh;
415 
416  const std::string filename = "triangle-minimal-VBProp.om";
417 
418  // generate data
419  Mesh::VertexHandle v1 = mesh.add_vertex(Mesh::Point(1.0,0.0,0.0));
420  Mesh::VertexHandle v2 = mesh.add_vertex(Mesh::Point(0.0,1.0,0.0));
421  Mesh::VertexHandle v3 = mesh.add_vertex(Mesh::Point(0.0,0.0,1.0));
422  mesh.add_face(v1,v2,v3);
423 
425  mesh.add_property(prop,"VBProp");
426  mesh.property(prop).set_persistent(true);
427 
428  mesh.property(prop,v1) = true;
429  mesh.property(prop,v2) = false;
430  mesh.property(prop,v3) = true;
431 
433  mesh.add_property(prop2,"VBProp2");
434  mesh.property(prop2).set_persistent(true);
435 
436  mesh.property(prop2,v1) = false;
437  mesh.property(prop2,v2) = false;
438  mesh.property(prop2,v3) = false;
439 
440  // save
441  bool ok = OpenMesh::IO::write_mesh(mesh,filename);
442  EXPECT_TRUE(ok) << "Unable to write "<<filename;
443 
444 
445  // load
446  Mesh cmpMesh;
447  cmpMesh.add_property(prop,"VBProp");
448  cmpMesh.property(prop).set_persistent(true);
449 
450  cmpMesh.add_property(prop2,"VBProp2");
451  cmpMesh.property(prop2).set_persistent(true);
452 
453  ok = OpenMesh::IO::read_mesh(cmpMesh,filename);
454  EXPECT_TRUE(ok) << "Unable to read "<<filename;
455 
456  // compare
457  EXPECT_EQ(3u , cmpMesh.n_vertices()) << "The number of loaded vertices is not correct!";
458  EXPECT_EQ(3u , cmpMesh.n_edges()) << "The number of loaded edges is not correct!";
459  EXPECT_EQ(1u , cmpMesh.n_faces()) << "The number of loaded faces is not correct!";
460 
461  EXPECT_EQ(Mesh::Point(1.0,0.0,0.0) , cmpMesh.point(v1)) << "Wrong coordinates at vertex 0";
462  EXPECT_EQ(Mesh::Point(0.0,1.0,0.0) , cmpMesh.point(v2)) << "Wrong coordinates at vertex 1";
463  EXPECT_EQ(Mesh::Point(0.0,0.0,1.0) , cmpMesh.point(v3)) << "Wrong coordinates at vertex 2";
464 
465  EXPECT_TRUE(cmpMesh.property(prop,v1)) << "Wrong Property value at vertex 0";
466  EXPECT_FALSE(cmpMesh.property(prop,v2)) << "Wrong Property value at vertex 1";
467  EXPECT_TRUE(cmpMesh.property(prop,v3)) << "Wrong Property value at vertex 2";
468 
469  EXPECT_FALSE(cmpMesh.property(prop2,v1)) << "Wrong second Property value at vertex 0";
470  EXPECT_FALSE(cmpMesh.property(prop2,v2)) << "Wrong second Property value at vertex 1";
471  EXPECT_FALSE(cmpMesh.property(prop2,v3)) << "Wrong second Property value at vertex 2";
472 
473  // cleanup
474  remove(filename.c_str());
475 
476 }
477 
478 /*
479  * Save and load simple mesh with custom property
480  */
481 TEST_F(OpenMeshReadWriteOM, WriteTriangleEdgeIntProperty) {
482 
483  Mesh mesh;
484 
485  const std::string propName = "EIProp";
486  const std::string filename = std::string("triangle-minimal-")+propName+".om";
487 
488  // generate data
489  Mesh::VertexHandle v1 = mesh.add_vertex(Mesh::Point(1.0,0.0,0.0));
490  Mesh::VertexHandle v2 = mesh.add_vertex(Mesh::Point(0.0,1.0,0.0));
491  Mesh::VertexHandle v3 = mesh.add_vertex(Mesh::Point(0.0,0.0,1.0));
492  mesh.add_face(v1,v2,v3);
493 
495  mesh.add_property(prop,propName);
496  mesh.property(prop).set_persistent(true);
497 
498  Mesh::EdgeHandle e1 = Mesh::EdgeHandle(0);
499  Mesh::EdgeHandle e2 = Mesh::EdgeHandle(1);
500  Mesh::EdgeHandle e3 = Mesh::EdgeHandle(2);
501 
502  int value1 = 10,
503  value2 = 21,
504  value3 = 32;
505 
506  mesh.property(prop,e1) = value1;
507  mesh.property(prop,e2) = value2;
508  mesh.property(prop,e3) = value3;
509 
510  // save
511  bool ok = OpenMesh::IO::write_mesh(mesh,filename);
512  EXPECT_TRUE(ok) << "Unable to write "<<filename;
513 
514  // load
515  Mesh cmpMesh;
516 
517  cmpMesh.add_property(prop,propName);
518  cmpMesh.property(prop).set_persistent(true);
519 
520  ok = OpenMesh::IO::read_mesh(cmpMesh,filename);
521  EXPECT_TRUE(ok) << "Unable to read "<<filename;
522 
523  // compare
524  EXPECT_EQ(3u , cmpMesh.n_vertices()) << "The number of loaded vertices is not correct!";
525  EXPECT_EQ(3u , cmpMesh.n_edges()) << "The number of loaded edges is not correct!";
526  EXPECT_EQ(1u , cmpMesh.n_faces()) << "The number of loaded faces is not correct!";
527 
528  EXPECT_EQ(Mesh::Point(1.0,0.0,0.0) , cmpMesh.point(v1)) << "Wrong coordinates at vertex 0";
529  EXPECT_EQ(Mesh::Point(0.0,1.0,0.0) , cmpMesh.point(v2)) << "Wrong coordinates at vertex 1";
530  EXPECT_EQ(Mesh::Point(0.0,0.0,1.0) , cmpMesh.point(v3)) << "Wrong coordinates at vertex 2";
531 
532  EXPECT_EQ(value1 , cmpMesh.property(prop,e1)) << "Wrong property at edge 0";
533  EXPECT_EQ(value2 , cmpMesh.property(prop,e2)) << "Wrong property at edge 1";
534  EXPECT_EQ(value3 , cmpMesh.property(prop,e3)) << "Wrong property at edge 2";
535 
536  // cleanup
537  remove(filename.c_str());
538 
539 }
540 
541 /*
542  * Save and load simple mesh with custom property
543  */
544 TEST_F(OpenMeshReadWriteOM, WriteSplitTriangleEdgeIntProperty) {
545 
546  Mesh mesh;
547 
548  const std::string propName = "EIProp";
549  const std::string filename = std::string("triangle-minimal-")+propName+".om";
550 
551  // generate data
552  Mesh::VertexHandle v1 = mesh.add_vertex(Mesh::Point(1.0,0.0,0.0));
553  Mesh::VertexHandle v2 = mesh.add_vertex(Mesh::Point(0.0,1.0,0.0));
554  Mesh::VertexHandle v3 = mesh.add_vertex(Mesh::Point(0.0,0.0,1.0));
555  auto fh0 = mesh.add_face(v1,v2,v3);
556  auto c = mesh.calc_face_centroid(fh0);
557  Mesh::VertexHandle v4 = mesh.add_vertex(c);
558  mesh.split(fh0, v4);
559 
560 
562  mesh.add_property(prop,propName);
563  mesh.property(prop).set_persistent(true);
564 
565  Mesh::EdgeHandle e1 = Mesh::EdgeHandle(0);
566  Mesh::EdgeHandle e2 = Mesh::EdgeHandle(1);
567  Mesh::EdgeHandle e3 = Mesh::EdgeHandle(2);
568  Mesh::EdgeHandle e4 = Mesh::EdgeHandle(3);
569  Mesh::EdgeHandle e5 = Mesh::EdgeHandle(4);
570  Mesh::EdgeHandle e6 = Mesh::EdgeHandle(5);
571 
572  int value1 = 10,
573  value2 = 21,
574  value3 = 32,
575  value4 = 43,
576  value5 = 54,
577  value6 = 65;
578 
579  mesh.property(prop,e1) = value1;
580  mesh.property(prop,e2) = value2;
581  mesh.property(prop,e3) = value3;
582  mesh.property(prop,e4) = value4;
583  mesh.property(prop,e5) = value5;
584  mesh.property(prop,e6) = value6;
585 
586  // save
587  OpenMesh::IO::Options options;
588  bool ok = OpenMesh::IO::write_mesh(mesh,filename);
589  EXPECT_TRUE(ok) << "Unable to write "<<filename;
590 
591  // load
592  Mesh cmpMesh;
593 
594  cmpMesh.add_property(prop,propName);
595  cmpMesh.property(prop).set_persistent(true);
596 
597  ok = OpenMesh::IO::read_mesh(cmpMesh,filename);
598  EXPECT_TRUE(ok) << "Unable to read "<<filename;
599 
600  // compare
601  EXPECT_EQ(4u , cmpMesh.n_vertices()) << "The number of loaded vertices is not correct!";
602  EXPECT_EQ(6u , cmpMesh.n_edges()) << "The number of loaded edges is not correct!";
603  EXPECT_EQ(3u , cmpMesh.n_faces()) << "The number of loaded faces is not correct!";
604 
605  EXPECT_EQ(Mesh::Point(1.0,0.0,0.0) , cmpMesh.point(v1)) << "Wrong coordinates at vertex 0";
606  EXPECT_EQ(Mesh::Point(0.0,1.0,0.0) , cmpMesh.point(v2)) << "Wrong coordinates at vertex 1";
607  EXPECT_EQ(Mesh::Point(0.0,0.0,1.0) , cmpMesh.point(v3)) << "Wrong coordinates at vertex 2";
608 
609 #ifdef TEST_DOUBLE_TRAITS
610  // TODO: should it be possible to read and write double precision exactly?
611  EXPECT_FLOAT_EQ(c[0] , cmpMesh.point(v4)[0]) << "Wrong coordinate 0 at vertex 4";
612  EXPECT_FLOAT_EQ(c[1] , cmpMesh.point(v4)[1]) << "Wrong coordinate 1 at vertex 4";
613  EXPECT_FLOAT_EQ(c[2] , cmpMesh.point(v4)[2]) << "Wrong coordinate 2 at vertex 4";
614 #else
615  EXPECT_EQ(c , cmpMesh.point(v4)) << "Wrong coordinates at vertex 4";
616 #endif
617 
618  EXPECT_EQ(value1 , cmpMesh.property(prop,e1)) << "Wrong property at edge 0";
619  EXPECT_EQ(value2 , cmpMesh.property(prop,e2)) << "Wrong property at edge 1";
620  EXPECT_EQ(value3 , cmpMesh.property(prop,e3)) << "Wrong property at edge 2";
621  EXPECT_EQ(value4 , cmpMesh.property(prop,e4)) << "Wrong property at edge 3";
622  EXPECT_EQ(value5 , cmpMesh.property(prop,e5)) << "Wrong property at edge 4";
623  EXPECT_EQ(value6 , cmpMesh.property(prop,e6)) << "Wrong property at edge 5";
624  // The above only shows that the edge properties are stored in the same order which is not what we want if the edges are different
625 
626  // Check edge properties based on edges defined by from and to vertex
627  for (auto eh : mesh.edges())
628  {
629  auto heh = mesh.halfedge_handle(eh, 0);
630  auto from_vh = mesh.from_vertex_handle(heh);
631  auto to_vh = mesh.to_vertex_handle(heh);
632 
633  // find corresponding halfedge in loaded mesh
634  auto cmpHeh = cmpMesh.find_halfedge(from_vh, to_vh);
635  auto cmpEh = cmpMesh.edge_handle(cmpHeh);
636 
637  EXPECT_EQ(mesh.property(prop, eh), cmpMesh.property(prop, cmpEh)) << "Wrong property at input edge " << eh.idx()
638  << " corresponding to edge " << cmpEh.idx() << " in the loaded Mesh";
639  }
640 
641 
642 
643  // cleanup
644  remove(filename.c_str());
645 
646 }
647 
648 /*
649  * Save and load simple mesh with status property
650  */
651 TEST_F(OpenMeshReadWriteOM, WriteSplitTriangleStatusProperties) {
652 
653  Mesh mesh;
654 
655  mesh.request_vertex_status();
656  mesh.request_edge_status();
657  mesh.request_halfedge_status();
658  mesh.request_face_status();
659 
660  const std::string filename = std::string("triangle-minimal-status.om");
661 
662  // generate data
663  Mesh::VertexHandle v0 = mesh.add_vertex(Mesh::Point(1.0,0.0,0.0));
664  Mesh::VertexHandle v1 = mesh.add_vertex(Mesh::Point(0.0,1.0,0.0));
665  Mesh::VertexHandle v2 = mesh.add_vertex(Mesh::Point(0.0,0.0,1.0));
666  auto fh0 = mesh.add_face(v0,v1,v2);
667  auto c = mesh.calc_face_centroid(fh0);
668  Mesh::VertexHandle v3 = mesh.add_vertex(c);
669  mesh.split(fh0, v3);
670 
671  mesh.delete_vertex(v0);
672  mesh.status(v1).set_selected(true);
673  mesh.status(v2).set_feature(true);
674  mesh.status(v3).set_tagged(true);
675  mesh.status(v2).set_tagged2(true);
676 
677  std::vector<bool> vertex_deleted;
678  std::vector<bool> vertex_selected;
679  std::vector<bool> vertex_feature;
680  std::vector<bool> vertex_tagged;
681  std::vector<bool> vertex_tagged2;
682 
683  for (auto vh : mesh.all_vertices())
684  {
685  vertex_deleted.push_back(mesh.status(vh).deleted());
686  vertex_selected.push_back(mesh.status(vh).selected());
687  vertex_feature.push_back(mesh.status(vh).feature());
688  vertex_tagged.push_back(mesh.status(vh).tagged());
689  vertex_tagged2.push_back(mesh.status(vh).tagged2());
690  }
691 
692  Mesh::EdgeHandle e1 = Mesh::EdgeHandle(0);
693  Mesh::EdgeHandle e2 = Mesh::EdgeHandle(1);
694  Mesh::EdgeHandle e3 = Mesh::EdgeHandle(2);
695  Mesh::EdgeHandle e4 = Mesh::EdgeHandle(3);
696 
697  mesh.status(e1).set_selected(true);
698  mesh.status(e2).set_feature(true);
699  mesh.status(e3).set_tagged(true);
700  mesh.status(e4).set_tagged2(true);
701 
702  std::vector<bool> edge_deleted;
703  std::vector<bool> edge_selected;
704  std::vector<bool> edge_feature;
705  std::vector<bool> edge_tagged;
706  std::vector<bool> edge_tagged2;
707 
708  for (auto eh : mesh.all_edges())
709  {
710  edge_deleted.push_back(mesh.status(eh).deleted());
711  edge_selected.push_back(mesh.status(eh).selected());
712  edge_feature.push_back(mesh.status(eh).feature());
713  edge_tagged.push_back(mesh.status(eh).tagged());
714  edge_tagged2.push_back(mesh.status(eh).tagged2());
715  }
716 
717 
718  Mesh::HalfedgeHandle he1 = Mesh::HalfedgeHandle(0);
719  Mesh::HalfedgeHandle he2 = Mesh::HalfedgeHandle(3);
720  Mesh::HalfedgeHandle he3 = Mesh::HalfedgeHandle(5);
721  Mesh::HalfedgeHandle he4 = Mesh::HalfedgeHandle(1);
722 
723  mesh.status(he1).set_selected(true);
724  mesh.status(he2).set_feature(true);
725  mesh.status(he3).set_tagged(true);
726  mesh.status(he4).set_tagged2(true);
727 
728  std::vector<bool> halfedge_deleted;
729  std::vector<bool> halfedge_selected;
730  std::vector<bool> halfedge_feature;
731  std::vector<bool> halfedge_tagged;
732  std::vector<bool> halfedge_tagged2;
733 
734  for (auto heh : mesh.all_halfedges())
735  {
736  halfedge_deleted.push_back(mesh.status(heh).deleted());
737  halfedge_selected.push_back(mesh.status(heh).selected());
738  halfedge_feature.push_back(mesh.status(heh).feature());
739  halfedge_tagged.push_back(mesh.status(heh).tagged());
740  halfedge_tagged2.push_back(mesh.status(heh).tagged2());
741  }
742 
743  Mesh::FaceHandle f1 = Mesh::FaceHandle(0);
744  Mesh::FaceHandle f2 = Mesh::FaceHandle(2);
745  Mesh::FaceHandle f3 = Mesh::FaceHandle(1);
746  Mesh::FaceHandle f4 = Mesh::FaceHandle(2);
747 
748  mesh.status(f1).set_selected(true);
749  mesh.status(f2).set_feature(true);
750  mesh.status(f3).set_tagged(true);
751  mesh.status(f4).set_tagged2(true);
752 
753  std::vector<bool> face_deleted;
754  std::vector<bool> face_selected;
755  std::vector<bool> face_feature;
756  std::vector<bool> face_tagged;
757  std::vector<bool> face_tagged2;
758 
759  for (auto fh : mesh.all_faces())
760  {
761  face_deleted.push_back(mesh.status(fh).deleted());
762  face_selected.push_back(mesh.status(fh).selected());
763  face_feature.push_back(mesh.status(fh).feature());
764  face_tagged.push_back(mesh.status(fh).tagged());
765  face_tagged2.push_back(mesh.status(fh).tagged2());
766  }
767 
768  // save
770  bool ok = OpenMesh::IO::write_mesh(mesh,filename, options);
771  EXPECT_TRUE(ok) << "Unable to write "<<filename;
772 
773  // load
774  Mesh cmpMesh;
775 
776  cmpMesh.request_vertex_status();
777  cmpMesh.request_edge_status();
778  cmpMesh.request_halfedge_status();
779  cmpMesh.request_face_status();
780 
781  ok = OpenMesh::IO::read_mesh(cmpMesh,filename, options);
782  EXPECT_TRUE(ok) << "Unable to read "<<filename;
783 
784  // compare
785  EXPECT_EQ(4u , cmpMesh.n_vertices()) << "The number of loaded vertices is not correct!";
786  EXPECT_EQ(6u , cmpMesh.n_edges()) << "The number of loaded edges is not correct!";
787  EXPECT_EQ(3u , cmpMesh.n_faces()) << "The number of loaded faces is not correct!";
788 
789  EXPECT_EQ(Mesh::Point(1.0,0.0,0.0) , cmpMesh.point(v0)) << "Wrong coordinates at vertex 0";
790  EXPECT_EQ(Mesh::Point(0.0,1.0,0.0) , cmpMesh.point(v1)) << "Wrong coordinates at vertex 1";
791  EXPECT_EQ(Mesh::Point(0.0,0.0,1.0) , cmpMesh.point(v2)) << "Wrong coordinates at vertex 2";
792 
793 #ifdef TEST_DOUBLE_TRAITS
794  // TODO: should it be possible to read and write double precision exactly?
795  EXPECT_FLOAT_EQ(c[0] , cmpMesh.point(v3)[0]) << "Wrong coordinate 0 at vertex 3";
796  EXPECT_FLOAT_EQ(c[1] , cmpMesh.point(v3)[1]) << "Wrong coordinate 1 at vertex 3";
797  EXPECT_FLOAT_EQ(c[2] , cmpMesh.point(v3)[2]) << "Wrong coordinate 2 at vertex 3";
798 #else
799  EXPECT_EQ(c , cmpMesh.point(v3)) << "Wrong coordinates at vertex 3";
800 #endif
801 
802  for (auto vh : cmpMesh.all_vertices())
803  {
804  EXPECT_EQ(cmpMesh.status(vh).deleted(), vertex_deleted [vh.idx()]) << "Wrong deleted status at vertex " << vh.idx();
805  EXPECT_EQ(cmpMesh.status(vh).selected(), vertex_selected[vh.idx()]) << "Wrong selected status at vertex " << vh.idx();
806  EXPECT_EQ(cmpMesh.status(vh).feature(), vertex_feature [vh.idx()]) << "Wrong feature status at vertex " << vh.idx();
807  EXPECT_EQ(cmpMesh.status(vh).tagged(), vertex_tagged [vh.idx()]) << "Wrong tagged status at vertex " << vh.idx();
808  EXPECT_EQ(cmpMesh.status(vh).tagged2(), vertex_tagged2 [vh.idx()]) << "Wrong tagged2 status at vertex " << vh.idx();
809  }
810 
811  for (auto eh : cmpMesh.all_edges())
812  {
813  EXPECT_EQ(cmpMesh.status(eh).deleted(), edge_deleted [eh.idx()]) << "Wrong deleted status at edge " << eh.idx();
814  EXPECT_EQ(cmpMesh.status(eh).selected(), edge_selected[eh.idx()]) << "Wrong selected status at edge " << eh.idx();
815  EXPECT_EQ(cmpMesh.status(eh).feature(), edge_feature [eh.idx()]) << "Wrong feature status at edge " << eh.idx();
816  EXPECT_EQ(cmpMesh.status(eh).tagged(), edge_tagged [eh.idx()]) << "Wrong tagged status at edge " << eh.idx();
817  EXPECT_EQ(cmpMesh.status(eh).tagged2(), edge_tagged2 [eh.idx()]) << "Wrong tagged2 status at edge " << eh.idx();
818  }
819 
820  for (auto heh : cmpMesh.all_halfedges())
821  {
822  EXPECT_EQ(cmpMesh.status(heh).deleted(), halfedge_deleted [heh.idx()]) << "Wrong deleted status at halfedge " << heh.idx();
823  EXPECT_EQ(cmpMesh.status(heh).selected(), halfedge_selected[heh.idx()]) << "Wrong selected status at halfedge " << heh.idx();
824  EXPECT_EQ(cmpMesh.status(heh).feature(), halfedge_feature [heh.idx()]) << "Wrong feature status at halfedge " << heh.idx();
825  EXPECT_EQ(cmpMesh.status(heh).tagged(), halfedge_tagged [heh.idx()]) << "Wrong tagged status at halfedge " << heh.idx();
826  EXPECT_EQ(cmpMesh.status(heh).tagged2(), halfedge_tagged2 [heh.idx()]) << "Wrong tagged2 status at halfedge " << heh.idx();
827  }
828 
829  for (auto fh : cmpMesh.all_faces())
830  {
831  EXPECT_EQ(cmpMesh.status(fh).deleted(), face_deleted [fh.idx()]) << "Wrong deleted status at face " << fh.idx();
832  EXPECT_EQ(cmpMesh.status(fh).selected(), face_selected[fh.idx()]) << "Wrong selected status at face " << fh.idx();
833  EXPECT_EQ(cmpMesh.status(fh).feature(), face_feature [fh.idx()]) << "Wrong feature status at face " << fh.idx();
834  EXPECT_EQ(cmpMesh.status(fh).tagged(), face_tagged [fh.idx()]) << "Wrong tagged status at face " << fh.idx();
835  EXPECT_EQ(cmpMesh.status(fh).tagged2(), face_tagged2 [fh.idx()]) << "Wrong tagged2 status at face " << fh.idx();
836  }
837 
838 
839  // cleanup
840  remove(filename.c_str());
841 }
842 
843 /*
844  * Save and load simple mesh with custom property
845  */
846 TEST_F(OpenMeshReadWriteOM, WriteTriangleFaceDoubleProperty) {
847 
848  Mesh mesh;
849 
850  const std::string propName = "FDProp";
851  const std::string filename = std::string("triangle-minimal-")+propName+".om";
852 
853  // generate data
854  Mesh::VertexHandle v1 = mesh.add_vertex(Mesh::Point(1.0,0.0,0.0));
855  Mesh::VertexHandle v2 = mesh.add_vertex(Mesh::Point(0.0,1.0,0.0));
856  Mesh::VertexHandle v3 = mesh.add_vertex(Mesh::Point(0.0,0.0,1.0));
857  mesh.add_face(v1,v2,v3);
858 
860  mesh.add_property(prop,propName);
861  mesh.property(prop).set_persistent(true);
862 
863  Mesh::FaceHandle f1 = Mesh::FaceHandle(0);
864 
865  double va1ue1 = 0.5;
866 
867  mesh.property(prop,f1) = va1ue1;
868 
869  // save
870  bool ok = OpenMesh::IO::write_mesh(mesh,filename);
871  EXPECT_TRUE(ok) << "Unable to write "<<filename;
872 
873  // load
874  Mesh cmpMesh;
875 
876  cmpMesh.add_property(prop,propName);
877  cmpMesh.property(prop).set_persistent(true);
878 
879  ok = OpenMesh::IO::read_mesh(cmpMesh,filename);
880  EXPECT_TRUE(ok) << "Unable to read "<<filename;
881 
882  // compare
883  EXPECT_EQ(3u , cmpMesh.n_vertices()) << "The number of loaded vertices is not correct!";
884  EXPECT_EQ(3u , cmpMesh.n_edges()) << "The number of loaded edges is not correct!";
885  EXPECT_EQ(1u , cmpMesh.n_faces()) << "The number of loaded faces is not correct!";
886 
887  EXPECT_EQ(Mesh::Point(1.0,0.0,0.0) , cmpMesh.point(v1)) << "Wrong coordinates at vertex 0";
888  EXPECT_EQ(Mesh::Point(0.0,1.0,0.0) , cmpMesh.point(v2)) << "Wrong coordinates at vertex 1";
889  EXPECT_EQ(Mesh::Point(0.0,0.0,1.0) , cmpMesh.point(v3)) << "Wrong coordinates at vertex 2";
890 
891  EXPECT_EQ(va1ue1 , cmpMesh.property(prop,f1)) << "Wrong property at edge 0";
892 
893  // cleanup
894  remove(filename.c_str());
895 
896 }
897 
898 /*
899  * Save and load simple mesh with custom property
900  */
901 TEST_F(OpenMeshReadWriteOM, WriteTriangleFaceFloatProperty) {
902 
903  const std::string propName = "FFProp";
904  const std::string filename = std::string("triangle-minimal-")+propName+".om";
905 
906  // generate data
907  Mesh mesh;
908  Mesh::VertexHandle v1 = mesh.add_vertex(Mesh::Point(1.0,0.0,0.0));
909  Mesh::VertexHandle v2 = mesh.add_vertex(Mesh::Point(0.0,1.0,0.0));
910  Mesh::VertexHandle v3 = mesh.add_vertex(Mesh::Point(0.0,0.0,1.0));
911  mesh.add_face(v1,v2,v3);
912 
914  mesh.add_property(prop,propName);
915  mesh.property(prop).set_persistent(true);
916 
917  Mesh::FaceHandle f1 = Mesh::FaceHandle(0);
918 
919  float va1ue1 = 3.1f;
920 
921  mesh.property(prop,f1) = va1ue1;
922 
923  // save
924  bool ok = OpenMesh::IO::write_mesh(mesh,filename);
925  EXPECT_TRUE(ok) << "Unable to write "<<filename;
926 
927 
928  // load
929  Mesh cmpMesh;
930  cmpMesh.add_property(prop,propName);
931  cmpMesh.property(prop).set_persistent(true);
932 
933  ok = OpenMesh::IO::read_mesh(cmpMesh,filename);
934  EXPECT_TRUE(ok) << "Unable to read "<<filename;
935 
936  // compare
937  EXPECT_EQ(3u , cmpMesh.n_vertices()) << "The number of loaded vertices is not correct!";
938  EXPECT_EQ(3u , cmpMesh.n_edges()) << "The number of loaded edges is not correct!";
939  EXPECT_EQ(1u , cmpMesh.n_faces()) << "The number of loaded faces is not correct!";
940 
941  EXPECT_EQ(Mesh::Point(1.0,0.0,0.0) , cmpMesh.point(v1)) << "Wrong coordinates at vertex 0";
942  EXPECT_EQ(Mesh::Point(0.0,1.0,0.0) , cmpMesh.point(v2)) << "Wrong coordinates at vertex 1";
943  EXPECT_EQ(Mesh::Point(0.0,0.0,1.0) , cmpMesh.point(v3)) << "Wrong coordinates at vertex 2";
944 
945  EXPECT_EQ(va1ue1 , cmpMesh.property(prop,f1)) << "Wrong property at edge 0";
946 
947  // cleanup
948  remove(filename.c_str());
949 
950 }
951 
952 /*
953  * Save and load simple mesh with custom property
954  */
955 TEST_F(OpenMeshReadWriteOM, ReadBigMeshWithCustomProperty) {
956 
958  OpenMesh::VPropHandleT<int> vertexProp;
959  bool ok;
960 
961  //generate file
962  /* mesh_.clear();
963  ok = OpenMesh::IO::read_mesh(mesh_,"cube1.off");
964 
965  mesh_.add_property(faceProp,"DFProp");
966  mesh_.property(faceProp).set_persistent(true);
967 
968  mesh_.add_property(vertexProp, "IVProp");
969  mesh_.property(vertexProp).set_persistent(true);
970 
971 
972  for (Mesh::FaceIter fIter = mesh_.faces_begin(); fIter != mesh_.faces_end(); ++fIter)
973  mesh_.property(faceProp,*fIter) = 0.3;
974 
975  for (Mesh::VertexIter vIter = mesh_.vertices_begin(); vIter != mesh_.vertices_end(); ++vIter)
976  mesh_.property(vertexProp,*vIter) = vIter->idx();
977 
978  OpenMesh::IO::write_mesh(mesh_,"cube1_customProps.om");
979 
980 
981  mesh_.clear();
982 */
983  //read file
984  Mesh mesh;
985  mesh.add_property(faceProp,"DFProp");
986  mesh.property(faceProp).set_persistent(true);
987 
988  mesh.add_property(vertexProp, "IVProp");
989  mesh.property(vertexProp).set_persistent(true);
990 
991  ok = OpenMesh::IO::read_mesh(mesh,"cube1_customProps.om");
992  EXPECT_TRUE(ok) << "Unable to read cube1_customProps.om";
993 
995  EXPECT_EQ(7526u , mesh.n_vertices()) << "The number of loaded vertices is not correct!";
996  EXPECT_EQ(22572u, mesh.n_edges()) << "The number of loaded edges is not correct!";
997  EXPECT_EQ(15048u, mesh.n_faces()) << "The number of loaded faces is not correct!";
998 
999  bool wrong = false;
1000  for (Mesh::FaceIter fIter = mesh.faces_begin(); fIter != mesh.faces_end() && !wrong; ++fIter)
1001  wrong = (0.3 != mesh.property(faceProp,*fIter));
1002  EXPECT_FALSE(wrong) << "min one face has wrong face property";
1003 
1004  wrong = false;
1005  for (Mesh::VertexIter vIter = mesh.vertices_begin(); vIter != mesh.vertices_end() && !wrong; ++vIter)
1006  wrong = (vIter->idx() != mesh.property(vertexProp,*vIter));
1007  EXPECT_FALSE(wrong) << "min one vertex has worng vertex property";
1008 }
1009 
1010 
1011 /*
1012  * Save and load simple mesh with vertex status
1013  */
1014 TEST_F(OpenMeshReadWriteOM, WriteReadStatusPropertyVertexOnly) {
1015 
1016  //read file
1017  Mesh mesh;
1018  auto vh0 = mesh.add_vertex(Mesh::Point(0,0,0));
1019  auto vh1 = mesh.add_vertex(Mesh::Point(1,0,0));
1020  auto vh2 = mesh.add_vertex(Mesh::Point(0,1,0));
1021  mesh.add_face(vh0, vh1, vh2);
1022 
1023  mesh.request_vertex_status();
1024 
1025  mesh.status(vh0).set_selected(true);
1026  mesh.status(vh1).set_feature(true);
1027  mesh.status(vh2).set_tagged(true);
1028  mesh.status(vh0).set_locked(true);
1029  mesh.status(vh1).set_deleted(true);
1030  mesh.status(vh2).set_hidden(true);
1031  mesh.status(vh0).set_fixed_nonmanifold(true);
1032 
1033 
1034  std::string filename_without_status = "no_vertex_status_test.om";
1035  std::string filename_with_status = "vertex_status_test.om";
1036 
1038  OpenMesh::IO::write_mesh(mesh, filename_without_status);
1039  OpenMesh::IO::write_mesh(mesh, filename_with_status, opt_with_status);
1040 
1041  // Load no status from file with status
1042  {
1043  Mesh loaded_mesh;
1044  OpenMesh::IO::read_mesh(loaded_mesh, filename_with_status);
1045 
1046  EXPECT_FALSE(loaded_mesh.has_vertex_status()) << "Mesh has vertex status even though they should not have been loaded";
1047  EXPECT_FALSE(loaded_mesh.has_halfedge_status()) << "Mesh has halfedge status even though file should not have a stored status";
1048  EXPECT_FALSE(loaded_mesh.has_edge_status()) << "Mesh has edge status even though file should not have a stored status";
1049  EXPECT_FALSE(loaded_mesh.has_face_status()) << "Mesh has face status even though file should not have a stored status";
1050  }
1051 
1052  // Load status from file with status
1053  {
1054  Mesh loaded_mesh;
1055  OpenMesh::IO::read_mesh(loaded_mesh, filename_with_status, opt_with_status);
1056 
1057  EXPECT_TRUE (loaded_mesh.has_vertex_status()) << "Mesh has no vertex status even though they should have been loaded";
1058  EXPECT_FALSE(loaded_mesh.has_halfedge_status()) << "Mesh has halfedge status even though file should not have a stored status";
1059  EXPECT_FALSE(loaded_mesh.has_edge_status()) << "Mesh has edge status even though file should not have a stored status";
1060  EXPECT_FALSE(loaded_mesh.has_face_status()) << "Mesh has face status even though file should not have a stored status";
1061 
1062  if (loaded_mesh.has_vertex_status())
1063  {
1064  for (auto vh : mesh.vertices())
1065  {
1066  EXPECT_EQ(mesh.status(vh).bits(), loaded_mesh.status(vh).bits());
1067  }
1068  }
1069  }
1070 
1071  // Load no status from file with status
1072  {
1073  Mesh loaded_mesh;
1074  loaded_mesh.request_vertex_status();
1075  OpenMesh::IO::read_mesh(loaded_mesh, filename_with_status);
1076 
1077  EXPECT_TRUE (loaded_mesh.has_vertex_status()) << "Mesh vertex status was removed by reading";
1078  EXPECT_FALSE(loaded_mesh.has_halfedge_status()) << "Mesh has halfedge status even though file should not have a stored status";
1079  EXPECT_FALSE(loaded_mesh.has_edge_status()) << "Mesh has edge status even though file should not have a stored status";
1080  EXPECT_FALSE(loaded_mesh.has_face_status()) << "Mesh has face status even though file should not have a stored status";
1081 
1082  for (auto vh : loaded_mesh.vertices())
1083  {
1084  EXPECT_EQ(loaded_mesh.status(vh).bits(), 0u) << "Vertex status was modified even though it should not have been loaded";
1085  }
1086  }
1087 
1088  // Try to load status from file without status
1089  {
1090  Mesh loaded_mesh;
1091  OpenMesh::IO::read_mesh(loaded_mesh, filename_without_status, opt_with_status);
1092 
1093  EXPECT_FALSE(loaded_mesh.has_vertex_status()) << "Mesh has vertex status even though file should not have a stored status";
1094  EXPECT_FALSE(loaded_mesh.has_halfedge_status()) << "Mesh has halfedge status even though file should not have a stored status";
1095  EXPECT_FALSE(loaded_mesh.has_edge_status()) << "Mesh has edge status even though they file should not have a stored status";
1096  EXPECT_FALSE(loaded_mesh.has_face_status()) << "Mesh has face status even though they file should not have a stored status";
1097  }
1098 }
1099 
1100 
1101 /*
1102  * Save and load simple mesh with halfedge status
1103  */
1104 TEST_F(OpenMeshReadWriteOM, WriteReadStatusPropertyHalfedgeOnly) {
1105 
1106  //read file
1107  Mesh mesh;
1108  auto vh0 = mesh.add_vertex(Mesh::Point(0,0,0));
1109  auto vh1 = mesh.add_vertex(Mesh::Point(1,0,0));
1110  auto vh2 = mesh.add_vertex(Mesh::Point(0,1,0));
1111  mesh.add_face(vh0, vh1, vh2);
1112 
1113  mesh.request_halfedge_status();
1114 
1115  auto heh0 = OpenMesh::HalfedgeHandle(0);
1116  auto heh1 = OpenMesh::HalfedgeHandle(1);
1117  auto heh2 = OpenMesh::HalfedgeHandle(2);
1118  auto heh3 = OpenMesh::HalfedgeHandle(3);
1119  auto heh4 = OpenMesh::HalfedgeHandle(4);
1120  auto heh5 = OpenMesh::HalfedgeHandle(5);
1121 
1122  mesh.status(heh0).set_selected(true);
1123  mesh.status(heh1).set_feature(true);
1124  mesh.status(heh2).set_tagged(true);
1125  mesh.status(heh3).set_locked(true);
1126  mesh.status(heh4).set_deleted(true);
1127  mesh.status(heh5).set_hidden(true);
1128  mesh.status(heh0).set_fixed_nonmanifold(true);
1129 
1130  std::string filename_without_status = "no_halfedge_status_test.om";
1131  std::string filename_with_status = "edge_halfstatus_test.om";
1132 
1134  OpenMesh::IO::write_mesh(mesh, filename_without_status);
1135  OpenMesh::IO::write_mesh(mesh, filename_with_status, opt_with_status);
1136 
1137  // Load no status from file with status
1138  {
1139  Mesh loaded_mesh;
1140  OpenMesh::IO::read_mesh(loaded_mesh, filename_with_status);
1141 
1142  EXPECT_FALSE(loaded_mesh.has_vertex_status()) << "Mesh has vertex status even though they should not have been loaded";
1143  EXPECT_FALSE(loaded_mesh.has_halfedge_status()) << "Mesh has halfedge status even though file should not have a stored status";
1144  EXPECT_FALSE(loaded_mesh.has_edge_status()) << "Mesh has edge status even though file should not have a stored status";
1145  EXPECT_FALSE(loaded_mesh.has_face_status()) << "Mesh has face status even though file should not have a stored status";
1146  }
1147 
1148  // Load status from file with status
1149  {
1150  Mesh loaded_mesh;
1151  OpenMesh::IO::read_mesh(loaded_mesh, filename_with_status, opt_with_status);
1152 
1153  EXPECT_FALSE(loaded_mesh.has_vertex_status()) << "Mesh has vertex status even though they should have been loaded";
1154  EXPECT_TRUE(loaded_mesh.has_halfedge_status()) << "Mesh has no halfedge status even though file should not have a stored status";
1155  EXPECT_FALSE(loaded_mesh.has_edge_status()) << "Mesh has edge status even though file should not have a stored status";
1156  EXPECT_FALSE(loaded_mesh.has_face_status()) << "Mesh has face status even though file should not have a stored status";
1157 
1158  if (loaded_mesh.has_halfedge_status())
1159  {
1160  for (auto heh : mesh.halfedges())
1161  {
1162  EXPECT_EQ(mesh.status(heh).bits(), loaded_mesh.status(heh).bits());
1163  }
1164  }
1165  }
1166 
1167  // Load no status from file with status
1168  {
1169  Mesh loaded_mesh;
1170  loaded_mesh.request_halfedge_status();
1171  OpenMesh::IO::read_mesh(loaded_mesh, filename_with_status);
1172 
1173  EXPECT_FALSE(loaded_mesh.has_vertex_status()) << "Mesh has vertex status even though file should not have a stored status";
1174  EXPECT_TRUE (loaded_mesh.has_halfedge_status()) << "Mesh halfedge status was removed by reading";
1175  EXPECT_FALSE(loaded_mesh.has_edge_status()) << "Mesh has edge status even though file should not have a stored status";
1176  EXPECT_FALSE(loaded_mesh.has_face_status()) << "Mesh has face status even though file should not have a stored status";
1177 
1178  for (auto heh : loaded_mesh.halfedges())
1179  {
1180  EXPECT_EQ(loaded_mesh.status(heh).bits(), 0u) << "Edge status was modified even though it should not have been loaded";
1181  }
1182  }
1183 
1184  // Try to load status from file without status
1185  {
1186  Mesh loaded_mesh;
1187  OpenMesh::IO::read_mesh(loaded_mesh, filename_without_status, opt_with_status);
1188 
1189  EXPECT_FALSE(loaded_mesh.has_vertex_status()) << "Mesh has vertex status even though file should not have a stored status";
1190  EXPECT_FALSE(loaded_mesh.has_halfedge_status()) << "Mesh has halfedge status even though file should not have a stored status";
1191  EXPECT_FALSE(loaded_mesh.has_edge_status()) << "Mesh has edge status even though they file should not have a stored status";
1192  EXPECT_FALSE(loaded_mesh.has_face_status()) << "Mesh has face status even though they file should not have a stored status";
1193  }
1194 }
1195 
1196 
1197 /*
1198  * Save and load simple mesh with edge status
1199  */
1200 TEST_F(OpenMeshReadWriteOM, WriteReadStatusPropertyEdgeOnly) {
1201 
1202  //read file
1203  Mesh mesh;
1204  auto vh0 = mesh.add_vertex(Mesh::Point(0,0,0));
1205  auto vh1 = mesh.add_vertex(Mesh::Point(1,0,0));
1206  auto vh2 = mesh.add_vertex(Mesh::Point(0,1,0));
1207  mesh.add_face(vh0, vh1, vh2);
1208 
1209  mesh.request_edge_status();
1210 
1211  auto eh0 = OpenMesh::EdgeHandle(0);
1212  auto eh1 = OpenMesh::EdgeHandle(1);
1213  auto eh2 = OpenMesh::EdgeHandle(2);
1214 
1215  mesh.status(eh0).set_selected(true);
1216  mesh.status(eh1).set_feature(true);
1217  mesh.status(eh2).set_tagged(true);
1218  mesh.status(eh0).set_locked(true);
1219  mesh.status(eh1).set_deleted(true);
1220  mesh.status(eh2).set_hidden(true);
1221  mesh.status(eh0).set_fixed_nonmanifold(true);
1222 
1223  std::string filename_without_status = "no_edge_status_test.om";
1224  std::string filename_with_status = "edge_status_test.om";
1225 
1227  OpenMesh::IO::write_mesh(mesh, filename_without_status);
1228  OpenMesh::IO::write_mesh(mesh, filename_with_status, opt_with_status);
1229 
1230  // Load no status from file with status
1231  {
1232  Mesh loaded_mesh;
1233  OpenMesh::IO::read_mesh(loaded_mesh, filename_with_status);
1234 
1235  EXPECT_FALSE(loaded_mesh.has_vertex_status()) << "Mesh has vertex status even though they should not have been loaded";
1236  EXPECT_FALSE(loaded_mesh.has_halfedge_status()) << "Mesh has halfedge status even though file should not have a stored status";
1237  EXPECT_FALSE(loaded_mesh.has_edge_status()) << "Mesh has edge status even though file should not have a stored status";
1238  EXPECT_FALSE(loaded_mesh.has_face_status()) << "Mesh has face status even though file should not have a stored status";
1239  }
1240 
1241  // Load status from file with status
1242  {
1243  Mesh loaded_mesh;
1244  OpenMesh::IO::read_mesh(loaded_mesh, filename_with_status, opt_with_status);
1245 
1246  EXPECT_FALSE(loaded_mesh.has_vertex_status()) << "Mesh has vertex status even though they should have been loaded";
1247  EXPECT_FALSE(loaded_mesh.has_halfedge_status()) << "Mesh has halfedge status even though file should not have a stored status";
1248  EXPECT_TRUE(loaded_mesh.has_edge_status()) << "Mesh has no edge status even though file should not have a stored status";
1249  EXPECT_FALSE(loaded_mesh.has_face_status()) << "Mesh has face status even though file should not have a stored status";
1250 
1251  if (loaded_mesh.has_edge_status())
1252  {
1253  for (auto eh : mesh.edges())
1254  {
1255  EXPECT_EQ(mesh.status(eh).bits(), loaded_mesh.status(eh).bits());
1256  }
1257  }
1258  }
1259 
1260  // Load no status from file with status
1261  {
1262  Mesh loaded_mesh;
1263  loaded_mesh.request_edge_status();
1264  OpenMesh::IO::read_mesh(loaded_mesh, filename_with_status);
1265 
1266  EXPECT_FALSE(loaded_mesh.has_vertex_status()) << "Mesh has vertex status even though file should not have a stored status";
1267  EXPECT_FALSE(loaded_mesh.has_halfedge_status()) << "Mesh has halfedge status even though file should not have a stored status";
1268  EXPECT_TRUE (loaded_mesh.has_edge_status()) << "Mesh edge status was removed by reading";
1269  EXPECT_FALSE(loaded_mesh.has_face_status()) << "Mesh has face status even though file should not have a stored status";
1270 
1271  for (auto eh : loaded_mesh.edges())
1272  {
1273  EXPECT_EQ(loaded_mesh.status(eh).bits(), 0u) << "Edge status was modified even though it should not have been loaded";
1274  }
1275  }
1276 
1277  // Try to load status from file without status
1278  {
1279  Mesh loaded_mesh;
1280  OpenMesh::IO::read_mesh(loaded_mesh, filename_without_status, opt_with_status);
1281 
1282  EXPECT_FALSE(loaded_mesh.has_vertex_status()) << "Mesh has vertex status even though file should not have a stored status";
1283  EXPECT_FALSE(loaded_mesh.has_halfedge_status()) << "Mesh has halfedge status even though file should not have a stored status";
1284  EXPECT_FALSE(loaded_mesh.has_edge_status()) << "Mesh has edge status even though they file should not have a stored status";
1285  EXPECT_FALSE(loaded_mesh.has_face_status()) << "Mesh has face status even though they file should not have a stored status";
1286  }
1287 }
1288 
1289 
1290 /*
1291  * Save and load simple mesh with face status
1292  */
1293 TEST_F(OpenMeshReadWriteOM, WriteReadStatusPropertyFaceOnly) {
1294 
1295  //read file
1296  Mesh mesh;
1297  auto vh0 = mesh.add_vertex(Mesh::Point(0,0,0));
1298  auto vh1 = mesh.add_vertex(Mesh::Point(1,0,0));
1299  auto vh2 = mesh.add_vertex(Mesh::Point(0,1,0));
1300  auto vh3 = mesh.add_vertex(Mesh::Point(1,1,0));
1301  auto fh0 = mesh.add_face(vh0, vh1, vh2);
1302  auto fh1 = mesh.add_face(vh2, vh1, vh3);
1303 
1304  mesh.request_face_status();
1305 
1306  mesh.status(fh0).set_selected(true);
1307  mesh.status(fh1).set_feature(true);
1308  mesh.status(fh0).set_tagged(true);
1309  mesh.status(fh1).set_locked(true);
1310  mesh.status(fh0).set_deleted(true);
1311  mesh.status(fh1).set_hidden(true);
1312  mesh.status(fh0).set_fixed_nonmanifold(true);
1313 
1314  std::string filename_without_status = "no_face_status_test.om";
1315  std::string filename_with_status = "face_status_test.om";
1316 
1318  OpenMesh::IO::write_mesh(mesh, filename_without_status);
1319  OpenMesh::IO::write_mesh(mesh, filename_with_status, opt_with_status);
1320 
1321  // Load no status from file with status
1322  {
1323  Mesh loaded_mesh;
1324  OpenMesh::IO::read_mesh(loaded_mesh, filename_with_status);
1325 
1326  EXPECT_FALSE(loaded_mesh.has_vertex_status()) << "Mesh has vertex status even though they should not have been loaded";
1327  EXPECT_FALSE(loaded_mesh.has_halfedge_status()) << "Mesh has halfedge status even though file should not have a stored status";
1328  EXPECT_FALSE(loaded_mesh.has_edge_status()) << "Mesh has edge status even though file should not have a stored status";
1329  EXPECT_FALSE(loaded_mesh.has_face_status()) << "Mesh has face status even though file should not have a stored status";
1330  }
1331 
1332  // Load status from file with status
1333  {
1334  Mesh loaded_mesh;
1335  OpenMesh::IO::read_mesh(loaded_mesh, filename_with_status, opt_with_status);
1336 
1337  EXPECT_FALSE(loaded_mesh.has_vertex_status()) << "Mesh has vertex status even though they should have been loaded";
1338  EXPECT_FALSE(loaded_mesh.has_halfedge_status()) << "Mesh has halfedge status even though file should not have a stored status";
1339  EXPECT_FALSE(loaded_mesh.has_edge_status()) << "Mesh has edge status even though file should not have a stored status";
1340  EXPECT_TRUE(loaded_mesh.has_face_status()) << "Mesh has no face status even though file should not have a stored status";
1341 
1342  if (loaded_mesh.has_face_status())
1343  {
1344  for (auto fh : mesh.faces())
1345  {
1346  EXPECT_EQ(mesh.status(fh).bits(), loaded_mesh.status(fh).bits());
1347  }
1348  }
1349  }
1350 
1351  // Load no status from file with status
1352  {
1353  Mesh loaded_mesh;
1354  loaded_mesh.request_face_status();
1355  OpenMesh::IO::read_mesh(loaded_mesh, filename_with_status);
1356 
1357  EXPECT_FALSE(loaded_mesh.has_vertex_status()) << "Mesh has vertex status even though file should not have a stored status";
1358  EXPECT_FALSE(loaded_mesh.has_halfedge_status()) << "Mesh has halfedge status even though file should not have a stored status";
1359  EXPECT_FALSE(loaded_mesh.has_edge_status()) << "Mesh has edgestatus even though file should not have a stored status";
1360  EXPECT_TRUE (loaded_mesh.has_face_status()) << "Mesh face status was removed by reading";
1361 
1362  for (auto fh : loaded_mesh.faces())
1363  {
1364  EXPECT_EQ(loaded_mesh.status(fh).bits(), 0u) << "Edge status was modified even though it should not have been loaded";
1365  }
1366  }
1367 
1368  // Try to load status from file without status
1369  {
1370  Mesh loaded_mesh;
1371  OpenMesh::IO::read_mesh(loaded_mesh, filename_without_status, opt_with_status);
1372 
1373  EXPECT_FALSE(loaded_mesh.has_vertex_status()) << "Mesh has vertex status even though file should not have a stored status";
1374  EXPECT_FALSE(loaded_mesh.has_halfedge_status()) << "Mesh has halfedge status even though file should not have a stored status";
1375  EXPECT_FALSE(loaded_mesh.has_edge_status()) << "Mesh has edge status even though they file should not have a stored status";
1376  EXPECT_FALSE(loaded_mesh.has_face_status()) << "Mesh has face status even though they file should not have a stored status";
1377  }
1378 }
1379 
1380 
1381 /*
1382  * Just load a triangle mesh from an om file of version 1.2
1383  */
1384 TEST_F(OpenMeshReadWriteOM, LoadTriangleMeshVersion_1_2) {
1385 
1386  mesh_.clear();
1387 
1388  std::string file_name = "cube_tri_version_1_2.om";
1389 
1390  bool ok = OpenMesh::IO::read_mesh(mesh_, file_name);
1391 
1392  EXPECT_TRUE(ok) << file_name;
1393 
1394  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
1395  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
1396  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
1397  EXPECT_EQ(36u , mesh_.n_halfedges()) << "The number of loaded halfedges is not correct!";
1398 }
1399 
1400 
1401 /*
1402  * Just load a polyhedral mesh from an om file of version 1.2
1403  */
1404 TEST_F(OpenMeshReadWriteOM, LoadPolyMeshVersion_1_2) {
1405 
1406  PolyMesh mesh;
1407 
1408  std::string file_name = "cube_poly_version_1_2.om";
1409 
1410  bool ok = OpenMesh::IO::read_mesh(mesh, file_name);
1411 
1412  EXPECT_TRUE(ok) << file_name;
1413 
1414  EXPECT_EQ(8u , mesh.n_vertices()) << "The number of loaded vertices is not correct!";
1415  EXPECT_EQ(12u , mesh.n_edges()) << "The number of loaded edges is not correct!";
1416  EXPECT_EQ(6u , mesh.n_faces()) << "The number of loaded faces is not correct!";
1417  EXPECT_EQ(24u , mesh.n_halfedges()) << "The number of loaded halfedges is not correct!";
1418 }
1419 
1420 
1421 /*
1422  * Just load a triangle mesh from an om file of version 2.0
1423  */
1424 TEST_F(OpenMeshReadWriteOM, LoadTriangleMeshVersion_2_0) {
1425 
1426  mesh_.clear();
1427 
1428  std::string file_name = "cube_tri_version_2_0.om";
1429 
1430  bool ok = OpenMesh::IO::read_mesh(mesh_, file_name);
1431 
1432  EXPECT_TRUE(ok) << file_name;
1433 
1434  EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
1435  EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
1436  EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
1437  EXPECT_EQ(36u , mesh_.n_halfedges()) << "The number of loaded halfedges is not correct!";
1438 }
1439 
1440 
1441 /*
1442  * Just load a polyhedral mesh from an om file of version 2.0
1443  */
1444 TEST_F(OpenMeshReadWriteOM, LoadPolyMeshVersion_2_0) {
1445 
1446  PolyMesh mesh;
1447 
1448  std::string file_name = "cube_poly_version_2_0.om";
1449 
1450  bool ok = OpenMesh::IO::read_mesh(mesh, file_name);
1451 
1452  EXPECT_TRUE(ok) << file_name;
1453 
1454  EXPECT_EQ(8u , mesh.n_vertices()) << "The number of loaded vertices is not correct!";
1455  EXPECT_EQ(12u , mesh.n_edges()) << "The number of loaded edges is not correct!";
1456  EXPECT_EQ(6u , mesh.n_faces()) << "The number of loaded faces is not correct!";
1457  EXPECT_EQ(24u , mesh.n_halfedges()) << "The number of loaded halfedges is not correct!";
1458 }
1459 
1460 
1461 /*
1462  * Try to load mesh from om file with a version that is not yet supported
1463  */
1464 TEST_F(OpenMeshReadWriteOM, LoadTriMeshVersion_7_5) {
1465 
1466  PolyMesh mesh;
1467 
1468  std::string file_name = "cube_tri_version_7_5.om";
1469 
1470  bool ok = OpenMesh::IO::read_mesh(mesh, file_name);
1471 
1472  EXPECT_FALSE(ok) << file_name;
1473 }
1474 
1475 }
Handle for a edge entity.
Definition: Handles.hh:134
Kernel::Color Color
Color type.
Definition: PolyMeshT.hh:116
Has (r) / store (w) vertex colors.
Definition: Options.hh:105
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) float values for colors (currently only implemented for PLY and OFF files) ...
Definition: Options.hh:112
Handle for a halfedge entity.
Definition: Handles.hh:127
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:112
bool read_mesh(Mesh &_mesh, const std::string &_filename)
Read a mesh from file _filename.
Definition: MeshIO.hh:112
SmartVertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
Definition: PolyMeshT.hh:235
SmartVertexHandle split(EdgeHandle _eh, const Point &_p)
Edge split (= 2-to-4 split)
Definition: TriMeshT.hh:267
Set options for reader/writer modules.
Definition: Options.hh:90
Has (r) / store (w) status properties.
Definition: Options.hh:114
void calc_face_centroid(FaceHandle _fh, Point &_pt) const
calculates the average of the vertices defining _fh
Definition: PolyMeshT.hh:279
Has (r) / store (w) texture coordinates.
Definition: Options.hh:106
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:136