diff --git a/src/Unittests/TestFiles/cube_tri_with_properties_2_1.om b/src/Unittests/TestFiles/cube_tri_with_properties_2_1.om new file mode 100644 index 00000000..26c4e171 Binary files /dev/null and b/src/Unittests/TestFiles/cube_tri_with_properties_2_1.om differ diff --git a/src/Unittests/unittests_read_write_OM.cc b/src/Unittests/unittests_read_write_OM.cc index 35e4522d..4766b629 100644 --- a/src/Unittests/unittests_read_write_OM.cc +++ b/src/Unittests/unittests_read_write_OM.cc @@ -1,6 +1,7 @@ #include #include +#include namespace { @@ -1458,6 +1459,195 @@ TEST_F(OpenMeshReadWriteOM, LoadPolyMeshVersion_2_0) { } + +std::string get_type_string(OpenMesh::FaceHandle) { return "Face"; } +std::string get_type_string(OpenMesh::EdgeHandle) { return "Edge"; } +std::string get_type_string(OpenMesh::HalfedgeHandle) { return "Halfedge"; } +std::string get_type_string(OpenMesh::VertexHandle) { return "Vertex"; } + +std::string get_type_string(char) { return "char"; } +std::string get_type_string(double) { return "double"; } +std::string get_type_string(float) { return "float"; } +std::string get_type_string(int) { return "int"; } +std::string get_type_string(short) { return "short"; } +std::string get_type_string(unsigned char) { return "unsigned char"; } +std::string get_type_string(unsigned int) { return "unsigned int"; } +std::string get_type_string(unsigned short) { return "unsigned short"; } +std::string get_type_string(bool) { return "bool"; } + +template +std::string get_type_string(std::vector) { return "std::vector of " + get_type_string(T()); } + +template +std::string get_type_string(OpenMesh::VectorT) { return "OM vector of dimension " + std::to_string(Dim) + " of type " + get_type_string(T()); } + + +template +T get_value(int seed, T, int seed2 = 0) +{ + return (seed * 3 + seed2) % 20; +} + +template +std::vector get_value(int seed, const std::vector&) +{ + int size = get_value(seed, 3); + std::vector res(size); + for (int i = 0; i < size; ++i) + res[i] = get_value(seed, T(), i); + return res; +} + +template +OpenMesh::VectorT get_value(int seed, const OpenMesh::VectorT&) +{ + OpenMesh::VectorT res; + for (int i = 0; i < Dim; ++i) + res[i] = get_value(seed, T(), i); + return res; +} + +template +OpenMesh::Prop add_property(MeshT& _mesh) +{ + std::string name = get_type_string(HandleT()) + ": " + get_type_string(T()); + OpenMesh::Prop prop(_mesh, name.c_str()); + _mesh.property(prop.getRawProperty()).set_persistent(true); + for (auto e : _mesh.template elements()) + prop[e] = get_value(e.idx(), T()); + + return prop; +} + +template +void check_property(MeshT& _mesh) +{ + std::string name = get_type_string(HandleT()) + ": " + get_type_string(T()); + bool has_prop = OpenMesh::hasProperty(_mesh, name.c_str()); + EXPECT_TRUE(has_prop) << "Property " << name << " is not available"; + if (!has_prop) + return; + OpenMesh::Prop prop(_mesh, name.c_str()); + for (auto e : _mesh.template elements()) + EXPECT_EQ(prop[e], get_value(e.idx(), T())) << "For property " << name; +} + +template +void request_property(MeshT& _mesh) +{ + std::string name = get_type_string(HandleT()) + ": " + get_type_string(T()); + OpenMesh::Prop prop(_mesh, name.c_str()); +} + + +enum class PropertyAction +{ + Add, Check, Request +}; + + +template +void do_property(MeshT& _mesh, PropertyAction action) +{ + switch (action) + { + case PropertyAction::Add: + add_property(_mesh); + break; + case PropertyAction::Check: + check_property(_mesh); + break; + case PropertyAction::Request: + request_property(_mesh); + break; + } +} + + + +template +void do_all_property_types(MeshT& _mesh, PropertyAction action) +{ + // TODO: add support for commented out types + do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); +// do_property (_mesh, action); +// do_property> (_mesh, action); +// do_property>(_mesh, action); +// do_property> (_mesh, action); +// do_property> (_mesh, action); +// do_property> (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); +// do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); +// do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); +// do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); +// do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); + do_property (_mesh, action); +} + +template +void do_all_properties(MeshT& _mesh, PropertyAction action) +{ + do_all_property_types (_mesh, action); + do_all_property_types (_mesh, action); + do_all_property_types(_mesh, action); + do_all_property_types (_mesh, action); +} + +template void add_all_properties(MeshT& _mesh) { do_all_properties(_mesh, PropertyAction::Add ); } +template void check_all_properties(MeshT& _mesh) { do_all_properties(_mesh, PropertyAction::Check ); } +template void request_all_properties(MeshT& _mesh) { do_all_properties(_mesh, PropertyAction::Request); } + +/* + * Load a triangle mesh from an om file of version 2.1 with properties + */ +TEST_F(OpenMeshReadWriteOM, LoadTriangleMeshWithPropertiesVersion_2_1) { + + mesh_.clear(); + + std::string file_name = "cube_tri_with_properties_2_1.om"; + + request_all_properties(mesh_); + bool ok = OpenMesh::IO::read_mesh(mesh_, file_name); + + ASSERT_TRUE(ok) << file_name; + + ASSERT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!"; + ASSERT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!"; + ASSERT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!"; + ASSERT_EQ(36u , mesh_.n_halfedges()) << "The number of loaded halfedges is not correct!"; + + check_all_properties(mesh_); +} + /* * Try to load mesh from om file with a version that is not yet supported */