Developer Documentation
Loading...
Searching...
No Matches
unittests_files.cc
1#include "unittests_common.hh"
2#include <gtest/gtest-typed-test.h>
3
4#include <OpenVolumeMesh/FileManager/FileManager.hh>
5#include <OpenVolumeMesh/IO/ovmb_read.hh>
6#include <OpenVolumeMesh/IO/ovmb_write.hh>
7
8using namespace OpenVolumeMesh;
9
10using namespace Geometry;
11
12template<bool Binary>
13class LoadSave {
14public:
15 template<typename MeshT>
16 bool readFile(const char *filename,
17 MeshT &mesh,
18 bool _topo_check = true,
19 bool _bottom_up = true) const
20 {
21 if constexpr(Binary) {
22 std::string ovmb_filename = filename;
23 ovmb_filename += 'b';
25 options.topology_check = _topo_check;
26 options.bottom_up_incidences = _bottom_up;
27 auto result = OpenVolumeMesh::IO::ovmb_read(ovmb_filename.c_str(), mesh, options);
28 return result == OpenVolumeMesh::IO::ReadResult::Ok;
29 } else {
31 return fileManager.readFile(filename, mesh, _topo_check, _bottom_up);
32 }
33 }
34 template<typename MeshT>
35 bool writeFile(const char *filename,
36 MeshT const &mesh) const
37 {
38 if constexpr(Binary) {
39 std::string ovmb_filename = filename;
40 ovmb_filename += 'b';
41 auto result = OpenVolumeMesh::IO::ovmb_write(ovmb_filename.c_str(), mesh);
42 return result == OpenVolumeMesh::IO::WriteResult::Ok;
43 } else {
45 return fileManager.writeFile(filename, mesh);
46 }
47 }
48 bool isHexahedralMesh(const char *filename) const
49 {
50 if constexpr(Binary) {
51 std::string ovmb_filename = filename;
52 ovmb_filename += 'b';
53 std::ifstream stream(ovmb_filename, std::ios::binary);
54 auto result = OpenVolumeMesh::IO::make_ovmb_reader(
55 stream,
57 OpenVolumeMesh::IO::g_default_property_codecs);
58 auto topo_type = result->topo_type();
59 return topo_type.has_value() &&
60 topo_type.value() == OpenVolumeMesh::IO::TopoType::Hexahedral;
61 } else {
63 return fileManager.isHexahedralMesh(filename);
64 }
65 }
66
67};
68
69template<typename use_binary>
71 , public LoadSave<use_binary::value>
72{
73public:
74 using LoadSave<use_binary::value>::readFile;
75 using LoadSave<use_binary::value>::writeFile;
76 using LoadSave<use_binary::value>::isHexahedralMesh;
77};
78
79template<typename use_binary>
81 , public LoadSave<use_binary::value>
82{
83public:
84 using LoadSave<use_binary::value>::readFile;
85 using LoadSave<use_binary::value>::writeFile;
86 using LoadSave<use_binary::value>::isHexahedralMesh;
87};
88
89using TrueFalse = testing::Types<std::true_type, std::false_type>;
90TYPED_TEST_SUITE(PolyhedralFileTest, TrueFalse);
91TYPED_TEST_SUITE(HexahedralFileTest, TrueFalse);
92
93TYPED_TEST(PolyhedralFileTest, LoadFile)
94{
95 PolyhedralMesh &mesh = this->mesh_;
96
97 ASSERT_TRUE(this->readFile("Cylinder.ovm", mesh));
98
99
100 EXPECT_EQ(399u, mesh.n_vertices());
101 EXPECT_EQ(1070u, mesh.n_edges());
102 EXPECT_EQ(960u, mesh.n_faces());
103 EXPECT_EQ(288u, mesh.n_cells());
104 auto v0 = mesh.vertex(VH(0));
105 EXPECT_DOUBLE_EQ(v0[0], 4.97203);
106 EXPECT_DOUBLE_EQ(v0[1], 0.504645);
107 EXPECT_DOUBLE_EQ(v0[2], 0.913112);
108}
109
110TYPED_TEST(PolyhedralFileTest, LoadNonManifoldMesh) {
111
112 PolyhedralMesh &mesh = this->mesh_;
113
114 ASSERT_TRUE(this->readFile("NonManifold.ovm", mesh));
115
116 EXPECT_EQ(12u, mesh.n_vertices());
117 EXPECT_EQ(20u, mesh.n_edges());
118 EXPECT_EQ(11u, mesh.n_faces());
119 EXPECT_EQ(2u, mesh.n_cells());
120}
121
122TYPED_TEST(HexahedralFileTest, LoadFile) {
123
124 HexahedralMesh &mesh = this->mesh_;
125
126 ASSERT_TRUE(this->isHexahedralMesh("Cylinder.ovm"));
127 ASSERT_TRUE(this->readFile("Cylinder.ovm", mesh));
128
129 EXPECT_EQ(399u, mesh.n_vertices());
130 EXPECT_EQ(1070u, mesh.n_edges());
131 EXPECT_EQ(960u, mesh.n_faces());
132 EXPECT_EQ(288u, mesh.n_cells());
133}
134
135TYPED_TEST(PolyhedralFileTest, SaveFile) {
136
137 PolyhedralMesh &mesh = this->mesh_;
138
139 ASSERT_TRUE(this->readFile("Cylinder.ovm", mesh));
140
141 EXPECT_EQ(399u, mesh.n_vertices());
142 EXPECT_EQ(1070u, mesh.n_edges());
143 EXPECT_EQ(960u, mesh.n_faces());
144 EXPECT_EQ(288u, mesh.n_cells());
145
146 // Write file
147 ASSERT_TRUE(this->writeFile("Cylinder.copy.ovm", mesh));
148
149 mesh.clear();
150
151 ASSERT_TRUE(this->readFile("Cylinder.copy.ovm", mesh));
152
153 EXPECT_EQ(399u, mesh.n_vertices());
154 EXPECT_EQ(1070u, mesh.n_edges());
155 EXPECT_EQ(960u, mesh.n_faces());
156 EXPECT_EQ(288u, mesh.n_cells());
157 auto v0 = mesh.vertex(VH(0));
158 EXPECT_DOUBLE_EQ(v0[0], 4.97203);
159 EXPECT_DOUBLE_EQ(v0[1], 0.504645);
160 EXPECT_DOUBLE_EQ(v0[2], 0.913112);
161}
162
163TYPED_TEST(PolyhedralFileTest, SaveFileWithProps) {
164
165 PolyhedralMesh &mesh = this->mesh_;
166
167 ASSERT_TRUE(this->readFile("Cylinder.ovm", mesh));
168
169 EXPECT_EQ(399u, mesh.n_vertices());
170 EXPECT_EQ(1070u, mesh.n_edges());
171 EXPECT_EQ(960u, mesh.n_faces());
172 EXPECT_EQ(288u, mesh.n_cells());
173
174 // Attach non-persistent properties
175 HalfFacePropertyT<float> hfprop = mesh.request_halfface_property<float>("MyHalfFaceProp");
176 VertexPropertyT<unsigned int> vprop = mesh.request_vertex_property<unsigned int>("MyVertexProp");
177
178 for(unsigned int i = 0; i < mesh.n_halffaces(); ++i) {
179 hfprop[HalfFaceHandle(i)] = (float)i/2.0f;
180 }
181 for(unsigned int i = 0; i < mesh.n_vertices(); ++i) {
182 vprop[VertexHandle(i)] = i;
183 }
184
185 mesh.set_persistent(hfprop);
186 mesh.set_persistent(vprop);
187
188 // Write file
189 ASSERT_TRUE(this->writeFile("Cylinder.copy.ovm", mesh));
190
191 mesh.clear();
192
193 EXPECT_EQ(0u, mesh.n_persistent_props<Entity::HalfFace>());
194 EXPECT_EQ(0u, mesh.n_persistent_props<Entity::Vertex>());
195
196 ASSERT_TRUE(this->readFile("Cylinder.copy.ovm", mesh));
197
198 EXPECT_EQ(399u, mesh.n_vertices());
199 EXPECT_EQ(1070u, mesh.n_edges());
200 EXPECT_EQ(960u, mesh.n_faces());
201 EXPECT_EQ(288u, mesh.n_cells());
202
203 EXPECT_EQ(1u, mesh.n_persistent_props<Entity::HalfFace>());
204 EXPECT_EQ(1u, mesh.n_persistent_props<Entity::Vertex>());
205
206 HalfFacePropertyT<float> hfprop2 = mesh.request_halfface_property<float>("MyHalfFaceProp");
207 VertexPropertyT<unsigned int> vprop2 = mesh.request_vertex_property<unsigned int>("MyVertexProp");
208
209 for(unsigned int i = 0; i < mesh.n_halffaces(); ++i) {
210 EXPECT_FLOAT_EQ((float)i/2.0f, hfprop2[HalfFaceHandle(i)]);
211 }
212 for(unsigned int i = 0; i < mesh.n_vertices(); ++i) {
213 EXPECT_EQ(i, vprop2[VertexHandle(i)]);
214 }
215}
216
217TYPED_TEST(PolyhedralFileTest, SaveFileWithVectorProps) {
218
219 PolyhedralMesh &mesh = this->mesh_;
220
221 ASSERT_TRUE(this->readFile("Cylinder.ovm", mesh));
222
223 EXPECT_EQ(399u, mesh.n_vertices());
224 EXPECT_EQ(1070u, mesh.n_edges());
225 EXPECT_EQ(960u, mesh.n_faces());
226 EXPECT_EQ(288u, mesh.n_cells());
227
228 // Attach non-persistent properties
229 HalfFacePropertyT<Vec3d> hfprop = mesh.request_halfface_property<Vec3d>("MyHalfFaceProp");
230 VertexPropertyT<Vec2i> vprop = mesh.request_vertex_property<Vec2i>("MyVertexProp");
231
232 for(unsigned int i = 0; i < mesh.n_halffaces(); ++i) {
233 hfprop[HalfFaceHandle(i)] = Vec3d((double)i/2.0, (double)i/2.0, (double)i/2.0);
234 }
235 for(unsigned int i = 0; i < mesh.n_vertices(); ++i) {
236 vprop[VertexHandle(i)] = Vec2i(i, i);
237 }
238
239 mesh.set_persistent(hfprop);
240 mesh.set_persistent(vprop);
241
242 // Write file
243 ASSERT_TRUE(this->writeFile("Cylinder.copy.ovm", mesh));
244
245 mesh.clear();
246 EXPECT_EQ(0u, mesh.n_persistent_props<Entity::HalfFace>());
247 EXPECT_EQ(0u, mesh.n_persistent_props<Entity::Vertex>());
248
249 ASSERT_TRUE(this->readFile("Cylinder.copy.ovm", mesh, true, false));
250
251 EXPECT_EQ(399u, mesh.n_vertices());
252 EXPECT_EQ(1070u, mesh.n_edges());
253 EXPECT_EQ(960u, mesh.n_faces());
254 EXPECT_EQ(288u, mesh.n_cells());
255
256 EXPECT_EQ(1u, mesh.n_persistent_props<Entity::HalfFace>());
257 EXPECT_EQ(1u, mesh.n_persistent_props<Entity::Vertex>());
258
259 HalfFacePropertyT<Vec3d> hfprop2 = mesh.request_halfface_property<Vec3d>("MyHalfFaceProp");
260 VertexPropertyT<Vec2i> vprop2 = mesh.request_vertex_property<Vec2i>("MyVertexProp");
261
262 for(unsigned int i = 0; i < mesh.n_halffaces(); ++i) {
263 HalfFaceHandle hfh(i);
264 EXPECT_DOUBLE_EQ((double)i/2.0, hfprop2[hfh][0]);
265 EXPECT_DOUBLE_EQ((double)i/2.0, hfprop2[hfh][1]);
266 EXPECT_DOUBLE_EQ((double)i/2.0, hfprop2[hfh][2]);
267 }
268 for(unsigned int i = 0; i < mesh.n_vertices(); ++i) {
269 VertexHandle vh(i);
270 EXPECT_EQ((int)i, vprop2[vh][0]);
271 EXPECT_EQ((int)i, vprop2[vh][1]);
272 }
273}
274
275TYPED_TEST(PolyhedralFileTest, SerializeVectorValuedProperties) {
276
277 PolyhedralMesh &mesh = this->mesh_;
278
279 ASSERT_TRUE(this->readFile("Cylinder.ovm", mesh));
280
281 EXPECT_EQ(399u, mesh.n_vertices());
282 EXPECT_EQ(1070u, mesh.n_edges());
283 EXPECT_EQ(960u, mesh.n_faces());
284 EXPECT_EQ(288u, mesh.n_cells());
285
286 // Attach persistent properties
287 HalfFacePropertyT<Vec3d> hfprop = mesh.request_halfface_property<Vec3d>("MyHalfFaceProp");
288 VertexPropertyT<Vec2i> vprop = mesh.request_vertex_property<Vec2i>("MyVertexProp");
289
290 for(unsigned int i = 0; i < mesh.n_halffaces(); ++i) {
291 HalfFaceHandle hfh(i);
292 hfprop[hfh] = Vec3d((double)i/2.0, (double)i/2.0, (double)i/2.0);
293 }
294 for(unsigned int i = 0; i < mesh.n_vertices(); ++i) {
295 VertexHandle vh(i);
296 vprop[vh] = Vec2i(i, i);
297 }
298
299 mesh.set_persistent(hfprop);
300 mesh.set_persistent(vprop);
301
302 std::ofstream ofs1("hfVecPropTest");
303 std::ofstream ofs2("vVecPropTest");
304
305 hfprop.serialize(ofs1);
306 vprop.serialize(ofs2);
307
308 ofs1.close();
309 ofs2.close();
310
311 /*
312 * Change property values
313 */
314 for(unsigned int i = 0; i < mesh.n_halffaces(); ++i) {
315 hfprop[HalfFaceHandle(i)] = Vec3d((double)i/3.0, (double)i/3.0, (double)i/3.0);
316 }
317
318 for(unsigned int i = 0; i < mesh.n_vertices(); ++i) {
319 vprop[VertexHandle(i)] = Vec2i(2*i, 2*i);
320 }
321
322 std::ifstream ifs1("hfVecPropTest");
323 std::ifstream ifs2("vVecPropTest");
324
325 hfprop.deserialize(ifs1);
326 vprop.deserialize(ifs2);
327
328 ifs1.close();
329 ifs2.close();
330
331 for(unsigned int i = 0; i < mesh.n_halffaces(); ++i) {
332 HalfFaceHandle hfh(i);
333 EXPECT_DOUBLE_EQ((double)i/2.0, hfprop[hfh][0]);
334 EXPECT_DOUBLE_EQ((double)i/2.0, hfprop[hfh][1]);
335 EXPECT_DOUBLE_EQ((double)i/2.0, hfprop[hfh][2]);
336 }
337 for(unsigned int i = 0; i < mesh.n_vertices(); ++i) {
338 VertexHandle vh(i);
339 EXPECT_EQ((int)i, vprop[vh][0]);
340 EXPECT_EQ((int)i, vprop[vh][1]);
341 }
342}
343
344TYPED_TEST(PolyhedralFileTest, LoadFileWithProps) {
345
346 PolyhedralMesh &mesh = this->mesh_;
347
348 ASSERT_TRUE(this->readFile("Cube_with_props.ovm", mesh, true, false));
349
350 EXPECT_EQ(8u, mesh.n_vertices());
351 EXPECT_EQ(12u, mesh.n_edges());
352 EXPECT_EQ(6u, mesh.n_faces());
353 EXPECT_EQ(1u, mesh.n_cells());
354
355 EXPECT_EQ(2u, mesh.n_props<Entity::Vertex>());
356 EXPECT_EQ(1u, mesh.n_props<Entity::Edge>());
357 EXPECT_EQ(0u, mesh.n_props<Entity::HalfEdge>());
358 EXPECT_EQ(1u, mesh.n_props<Entity::Face>());
359 EXPECT_EQ(1u, mesh.n_props<Entity::HalfFace>());
360 EXPECT_EQ(0u, mesh.n_props<Entity::Cell>());
361}
362
363TYPED_TEST(PolyhedralFileTest, SaveFileWithProps2) {
364
365 PolyhedralMesh &mesh = this->mesh_;
366
367 ASSERT_TRUE(this->readFile("Cube_with_props.ovm", mesh, true, false));
368
369 EXPECT_EQ(8u, mesh.n_vertices());
370 EXPECT_EQ(12u, mesh.n_edges());
371 EXPECT_EQ(6u, mesh.n_faces());
372 EXPECT_EQ(1u, mesh.n_cells());
373
374 EXPECT_EQ(2u, mesh.n_props<Entity::Vertex>());
375 EXPECT_EQ(1u, mesh.n_props<Entity::Edge>());
376 EXPECT_EQ(0u, mesh.n_props<Entity::HalfEdge>());
377 EXPECT_EQ(1u, mesh.n_props<Entity::Face>());
378 EXPECT_EQ(1u, mesh.n_props<Entity::HalfFace>());
379 EXPECT_EQ(0u, mesh.n_props<Entity::Cell>());
380
381 ASSERT_TRUE(this->writeFile("Cube_with_props.copy.ovm", mesh));
382
383 mesh.clear();
384
385 ASSERT_TRUE(this->readFile("Cube_with_props.copy.ovm", mesh, true, false));
386
387 EXPECT_EQ(8u, mesh.n_vertices());
388 EXPECT_EQ(12u, mesh.n_edges());
389 EXPECT_EQ(6u, mesh.n_faces());
390 EXPECT_EQ(1u, mesh.n_cells());
391
392 EXPECT_EQ(2u, mesh.n_props<Entity::Vertex>());
393 EXPECT_EQ(1u, mesh.n_props<Entity::Edge>());
394 EXPECT_EQ(0u, mesh.n_props<Entity::HalfEdge>());
395 EXPECT_EQ(1u, mesh.n_props<Entity::Face>());
396 EXPECT_EQ(1u, mesh.n_props<Entity::HalfFace>());
397 EXPECT_EQ(0u, mesh.n_props<Entity::Cell>());
398}
399
Read/Write mesh data from/to files.
bool readFile(const std::string &_filename, MeshT &_mesh, bool _topologyCheck=true, bool _computeBottomUpIncidences=true) const
Read a mesh from a file.
bool writeFile(const std::string &_filename, const MeshT &_mesh) const
Write a mesh to a file.
bool isHexahedralMesh(const std::string &_filename) const
Test whether given file contains a hexahedral mesh.