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;
45 options += OpenMesh::IO::Options::VertexColor;
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;
71 options += OpenMesh::IO::Options::VertexTexCoord;
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;
111 options += OpenMesh::IO::Options::VertexColor;
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;
213 options += OpenMesh::IO::Options::VertexColor;
214 options -= OpenMesh::IO::Options::ColorFloat;
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
297 OpenMesh::VPropHandleT<bool> prop;
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
361 OpenMesh::VPropHandleT<bool> prop;
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
424 OpenMesh::VPropHandleT<bool> prop;
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
432 OpenMesh::VPropHandleT<bool> prop2;
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
494 OpenMesh::EPropHandleT<int> prop;
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
561 OpenMesh::EPropHandleT<int> prop;
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
769 OpenMesh::IO::Options options = OpenMesh::IO::Options::Status;
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
859 OpenMesh::FPropHandleT<double> prop;
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
913 OpenMesh::FPropHandleT<float> prop;
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
957 OpenMesh::FPropHandleT<double> faceProp;
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
1037 OpenMesh::IO::Options opt_with_status = OpenMesh::IO::Options::Status;
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
1133 OpenMesh::IO::Options opt_with_status = OpenMesh::IO::Options::Status;
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
1226 OpenMesh::IO::Options opt_with_status = OpenMesh::IO::Options::Status;
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
1317 OpenMesh::IO::Options opt_with_status = OpenMesh::IO::Options::Status;
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 }
OpenMesh::EdgeHandle
Handle for a edge entity.
Definition: Handles.hh:134
OpenMesh::VPropHandleT< bool >
OpenMesh::PolyMeshT::Color
Kernel::Color Color
Color type.
Definition: PolyMeshT.hh:116
OpenMesh::IO::Options::VertexColor
Has (r) / store (w) vertex colors.
Definition: Options.hh:105
OpenMesh::IO::write_mesh
bool write_mesh(const Mesh &_mesh, const std::string &_filename, Options _opt=Options::Default, std::streamsize _precision=6)
Write a mesh to the file _filename.
Definition: MeshIO.hh:207
OpenMesh::EPropHandleT
Definition: Property.hh:514
OpenMesh::IO::Options::ColorFloat
Has (r) / store (w) float values for colors (currently only implemented for PLY and OFF files) ...
Definition: Options.hh:112
OpenMesh::HalfedgeHandle
Handle for a halfedge entity.
Definition: Handles.hh:127
OpenMesh::PolyMeshT::Point
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:112
OpenMesh::TriMesh_ArrayKernelT
Definition: PolyMesh_ArrayKernelT.hh:73
OpenMesh::IO::read_mesh
bool read_mesh(Mesh &_mesh, const std::string &_filename)
Read a mesh from file _filename.
Definition: MeshIO.hh:112
OpenMesh::PolyMeshT::add_vertex
SmartVertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
Definition: PolyMeshT.hh:235
OpenMesh::TriMeshT::split
SmartVertexHandle split(EdgeHandle _eh, const Point &_p)
Edge split (= 2-to-4 split)
Definition: TriMeshT.hh:267
OpenMesh::IO::Options
Set options for reader/writer modules.
Definition: Options.hh:90
OpenMeshBase
Definition: unittests_common.hh:29
OpenMesh::IO::Options::Status
Has (r) / store (w) status properties.
Definition: Options.hh:114
OpenMesh::PolyMeshT::calc_face_centroid
void calc_face_centroid(FaceHandle _fh, Point &_pt) const
calculates the average of the vertices defining _fh
Definition: PolyMeshT.hh:279
OpenMesh::FPropHandleT
Definition: Property.hh:529
OpenMesh::IO::Options::VertexTexCoord
Has (r) / store (w) texture coordinates.
Definition: Options.hh:106
OpenMesh::PolyMeshT::VertexHandle
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:136