Merge branch 'lyonm/custom-property-writing' into 'master'

only write custom properties if the Custom option is set

See merge request OpenMesh/OpenMesh!326
This commit is contained in:
Jan Möbius
2023-02-27 13:26:38 +00:00
5 changed files with 75 additions and 53 deletions

View File

@@ -97,7 +97,7 @@ public:
/// Definitions of %Options for reading and writing. The options can be /// Definitions of %Options for reading and writing. The options can be
/// or'ed. /// or'ed.
enum Flag { enum Flag {
Default = 0x0000, ///< No options None = 0x0000, ///< No options
Binary = 0x0001, ///< Set binary mode for r/w Binary = 0x0001, ///< Set binary mode for r/w
MSB = 0x0002, ///< Assume big endian byte ordering MSB = 0x0002, ///< Assume big endian byte ordering
LSB = 0x0004, ///< Assume little endian byte ordering LSB = 0x0004, ///< Assume little endian byte ordering
@@ -111,9 +111,10 @@ public:
FaceTexCoord = 0x0400, ///< Has (r) / store (w) face texture coordinates FaceTexCoord = 0x0400, ///< Has (r) / store (w) face texture coordinates
ColorAlpha = 0x0800, ///< Has (r) / store (w) alpha values for colors ColorAlpha = 0x0800, ///< Has (r) / store (w) alpha values for colors
ColorFloat = 0x1000, ///< Has (r) / store (w) float values for colors (currently only implemented for PLY and OFF files) ColorFloat = 0x1000, ///< Has (r) / store (w) float values for colors (currently only implemented for PLY and OFF files)
Custom = 0x2000, ///< Has (r) custom properties (currently only implemented in PLY Reader ASCII version) Custom = 0x2000, ///< Has (r) / store (w) custom properties marked persistent (currently PLY only supports reading and only ASCII version. OM supports reading and writing)
Status = 0x4000, ///< Has (r) / store (w) status properties Status = 0x4000, ///< Has (r) / store (w) status properties
TexCoordST = 0x8000 ///< Write texture coordinates as ST instead of UV TexCoordST = 0x8000, ///< Write texture coordinates as ST instead of UV
Default = Custom, ///< By default write persistent custom properties
}; };
/// Texture filename. This will be written as /// Texture filename. This will be written as

View File

@@ -406,7 +406,8 @@ bool _OMReader_::read_binary_vertex_chunk(std::istream &_is, BaseImporter &_bi,
{ {
Chunk::PropertyName property_type; Chunk::PropertyName property_type;
bytes_ += restore(_is, property_type, _swap); bytes_ += restore(_is, property_type, _swap);
add_generic_property(property_type, _bi); if (_opt.check(Options::Custom))
add_generic_property(property_type, _bi);
} }
bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_vprop(property_name_), header_.n_vertices_, _swap); bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_vprop(property_name_), header_.n_vertices_, _swap);
@@ -563,7 +564,8 @@ bool _OMReader_::read_binary_face_chunk(std::istream &_is, BaseImporter &_bi, Op
{ {
Chunk::PropertyName property_type; Chunk::PropertyName property_type;
bytes_ += restore(_is, property_type, _swap); bytes_ += restore(_is, property_type, _swap);
add_generic_property(property_type, _bi); if (_opt.check(Options::Custom))
add_generic_property(property_type, _bi);
} }
bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_fprop(property_name_), header_.n_faces_, _swap); bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_fprop(property_name_), header_.n_faces_, _swap);
@@ -604,7 +606,8 @@ bool _OMReader_::read_binary_edge_chunk(std::istream &_is, BaseImporter &_bi, Op
{ {
Chunk::PropertyName property_type; Chunk::PropertyName property_type;
bytes_ += restore(_is, property_type, _swap); bytes_ += restore(_is, property_type, _swap);
add_generic_property(property_type, _bi); if (_opt.check(Options::Custom))
add_generic_property(property_type, _bi);
} }
bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_eprop(property_name_), header_.n_edges_, _swap); bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_eprop(property_name_), header_.n_edges_, _swap);
@@ -654,7 +657,8 @@ bool _OMReader_::read_binary_halfedge_chunk(std::istream &_is, BaseImporter &_bi
{ {
Chunk::PropertyName property_type; Chunk::PropertyName property_type;
bytes_ += restore(_is, property_type, _swap); bytes_ += restore(_is, property_type, _swap);
add_generic_property(property_type, _bi); if (_opt.check(Options::Custom))
add_generic_property(property_type, _bi);
} }
bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_hprop(property_name_), 2 * header_.n_edges_, _swap); bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_hprop(property_name_), 2 * header_.n_edges_, _swap);
@@ -745,7 +749,7 @@ bool _OMReader_::read_binary_halfedge_chunk(std::istream &_is, BaseImporter &_bi
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool _OMReader_::read_binary_mesh_chunk(std::istream &_is, BaseImporter &_bi, Options & /* _opt */, bool _swap) const bool _OMReader_::read_binary_mesh_chunk(std::istream &_is, BaseImporter &_bi, Options& _opt , bool _swap) const
{ {
using OMFormat::Chunk; using OMFormat::Chunk;
@@ -760,7 +764,8 @@ bool _OMReader_::read_binary_mesh_chunk(std::istream &_is, BaseImporter &_bi, Op
{ {
Chunk::PropertyName property_type; Chunk::PropertyName property_type;
bytes_ += restore(_is, property_type, _swap); bytes_ += restore(_is, property_type, _swap);
add_generic_property(property_type, _bi); if (_opt.check(Options::Custom))
add_generic_property(property_type, _bi);
} }
bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_mprop(property_name_), 1, _swap); bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_mprop(property_name_), 1, _swap);

View File

@@ -562,34 +562,35 @@ bool _OMWriter_::write_binary(std::ostream& _os, BaseExporter& _be,
// -------------------- write custom properties // -------------------- write custom properties
if (_opt.check(Options::Custom))
const auto store_property = [this, &_os, swap, &bytes](
const BaseKernel::const_prop_iterator _it_begin,
const BaseKernel::const_prop_iterator _it_end,
const OMFormat::Chunk::Entity _ent)
{ {
for (auto prop = _it_begin; prop != _it_end; ++prop) const auto store_property = [this, &_os, swap, &bytes](
const BaseKernel::const_prop_iterator _it_begin,
const BaseKernel::const_prop_iterator _it_end,
const OMFormat::Chunk::Entity _ent)
{ {
if (!*prop || (*prop)->name().empty() || for (auto prop = _it_begin; prop != _it_end; ++prop)
((*prop)->name().size() > 1 && (*prop)->name()[1] == ':')) {
{ // skip dead and "private" properties (no name or name matches "?:*") if (!*prop || (*prop)->name().empty() ||
continue; ((*prop)->name().size() > 1 && (*prop)->name()[1] == ':'))
{ // skip dead and "private" properties (no name or name matches "?:*")
continue;
}
bytes += store_binary_custom_chunk(_os, **prop, _ent, swap);
} }
bytes += store_binary_custom_chunk(_os, **prop, _ent, swap); };
}
};
store_property(_be.kernel()->vprops_begin(), _be.kernel()->vprops_end(), store_property(_be.kernel()->vprops_begin(), _be.kernel()->vprops_end(),
OMFormat::Chunk::Entity_Vertex); OMFormat::Chunk::Entity_Vertex);
store_property(_be.kernel()->fprops_begin(), _be.kernel()->fprops_end(), store_property(_be.kernel()->fprops_begin(), _be.kernel()->fprops_end(),
OMFormat::Chunk::Entity_Face); OMFormat::Chunk::Entity_Face);
store_property(_be.kernel()->eprops_begin(), _be.kernel()->eprops_end(), store_property(_be.kernel()->eprops_begin(), _be.kernel()->eprops_end(),
OMFormat::Chunk::Entity_Edge); OMFormat::Chunk::Entity_Edge);
store_property(_be.kernel()->hprops_begin(), _be.kernel()->hprops_end(), store_property(_be.kernel()->hprops_begin(), _be.kernel()->hprops_end(),
OMFormat::Chunk::Entity_Halfedge); OMFormat::Chunk::Entity_Halfedge);
store_property(_be.kernel()->mprops_begin(), _be.kernel()->mprops_end(), store_property(_be.kernel()->mprops_begin(), _be.kernel()->mprops_end(),
OMFormat::Chunk::Entity_Mesh); OMFormat::Chunk::Entity_Mesh);
}
memset(&chunk_header, 0, sizeof(chunk_header)); memset(&chunk_header, 0, sizeof(chunk_header));
chunk_header.name_ = false; chunk_header.name_ = false;

View File

@@ -365,7 +365,9 @@ TEST_F(OpenMeshReadWriteOM, WriteTriangleVertexBoolProperty) {
mesh.property(prop,v3) = true; mesh.property(prop,v3) = true;
// save // save
bool ok = OpenMesh::IO::write_mesh(mesh,filename); OpenMesh::IO::Options opts = OpenMesh::IO::Options::Custom;
bool ok = OpenMesh::IO::write_mesh(mesh, filename, opts);
EXPECT_TRUE(ok) << "Unable to write "<<filename; EXPECT_TRUE(ok) << "Unable to write "<<filename;
// load // load
@@ -375,7 +377,7 @@ TEST_F(OpenMeshReadWriteOM, WriteTriangleVertexBoolProperty) {
cmpMesh.add_property(prop,"VBProp"); cmpMesh.add_property(prop,"VBProp");
cmpMesh.property(prop).set_persistent(true); cmpMesh.property(prop).set_persistent(true);
ok = OpenMesh::IO::read_mesh(cmpMesh,filename); ok = OpenMesh::IO::read_mesh(cmpMesh, filename, opts);
EXPECT_TRUE(ok) << "Unable to read "<<filename; EXPECT_TRUE(ok) << "Unable to read "<<filename;
// compare // compare
@@ -436,7 +438,9 @@ TEST_F(OpenMeshReadWriteOM, WriteTriangleVertexBoolPropertySpaceEquivalent) {
mesh.property(prop,v9) = true; mesh.property(prop,v9) = true;
// save // save
bool ok = OpenMesh::IO::write_mesh(mesh,filename); OpenMesh::IO::Options opts = OpenMesh::IO::Options::Custom;
bool ok = OpenMesh::IO::write_mesh(mesh, filename, opts);
EXPECT_TRUE(ok) << "Unable to write "<<filename; EXPECT_TRUE(ok) << "Unable to write "<<filename;
// load // load
@@ -445,7 +449,7 @@ TEST_F(OpenMeshReadWriteOM, WriteTriangleVertexBoolPropertySpaceEquivalent) {
cmpMesh.add_property(prop,"VBProp"); cmpMesh.add_property(prop,"VBProp");
cmpMesh.property(prop).set_persistent(true); cmpMesh.property(prop).set_persistent(true);
ok = OpenMesh::IO::read_mesh(cmpMesh,filename); ok = OpenMesh::IO::read_mesh(cmpMesh, filename, opts);
EXPECT_TRUE(ok) << "Unable to read "<<filename; EXPECT_TRUE(ok) << "Unable to read "<<filename;
// compare // compare
@@ -500,7 +504,9 @@ TEST_F(OpenMeshReadWriteOM, WriteTriangleTwoVertexBoolProperty) {
mesh.property(prop2,v3) = false; mesh.property(prop2,v3) = false;
// save // save
bool ok = OpenMesh::IO::write_mesh(mesh,filename); OpenMesh::IO::Options opts = OpenMesh::IO::Options::Custom;
bool ok = OpenMesh::IO::write_mesh(mesh, filename, opts);
EXPECT_TRUE(ok) << "Unable to write "<<filename; EXPECT_TRUE(ok) << "Unable to write "<<filename;
@@ -512,7 +518,7 @@ TEST_F(OpenMeshReadWriteOM, WriteTriangleTwoVertexBoolProperty) {
cmpMesh.add_property(prop2,"VBProp2"); cmpMesh.add_property(prop2,"VBProp2");
cmpMesh.property(prop2).set_persistent(true); cmpMesh.property(prop2).set_persistent(true);
ok = OpenMesh::IO::read_mesh(cmpMesh,filename); ok = OpenMesh::IO::read_mesh(cmpMesh, filename, opts);
EXPECT_TRUE(ok) << "Unable to read "<<filename; EXPECT_TRUE(ok) << "Unable to read "<<filename;
// compare // compare
@@ -570,7 +576,9 @@ TEST_F(OpenMeshReadWriteOM, WriteTriangleEdgeIntProperty) {
mesh.property(prop,e3) = value3; mesh.property(prop,e3) = value3;
// save // save
bool ok = OpenMesh::IO::write_mesh(mesh,filename); OpenMesh::IO::Options opts = OpenMesh::IO::Options::Custom;
bool ok = OpenMesh::IO::write_mesh(mesh, filename, opts);
EXPECT_TRUE(ok) << "Unable to write "<<filename; EXPECT_TRUE(ok) << "Unable to write "<<filename;
// load // load
@@ -579,7 +587,7 @@ TEST_F(OpenMeshReadWriteOM, WriteTriangleEdgeIntProperty) {
cmpMesh.add_property(prop,propName); cmpMesh.add_property(prop,propName);
cmpMesh.property(prop).set_persistent(true); cmpMesh.property(prop).set_persistent(true);
ok = OpenMesh::IO::read_mesh(cmpMesh,filename); ok = OpenMesh::IO::read_mesh(cmpMesh, filename, opts);
EXPECT_TRUE(ok) << "Unable to read "<<filename; EXPECT_TRUE(ok) << "Unable to read "<<filename;
// compare // compare
@@ -646,8 +654,9 @@ TEST_F(OpenMeshReadWriteOM, WriteSplitTriangleEdgeIntProperty) {
mesh.property(prop,e6) = value6; mesh.property(prop,e6) = value6;
// save // save
OpenMesh::IO::Options options; OpenMesh::IO::Options opts = OpenMesh::IO::Options::Custom;
bool ok = OpenMesh::IO::write_mesh(mesh,filename);
bool ok = OpenMesh::IO::write_mesh(mesh, filename, opts);
EXPECT_TRUE(ok) << "Unable to write "<<filename; EXPECT_TRUE(ok) << "Unable to write "<<filename;
// load // load
@@ -656,7 +665,7 @@ TEST_F(OpenMeshReadWriteOM, WriteSplitTriangleEdgeIntProperty) {
cmpMesh.add_property(prop,propName); cmpMesh.add_property(prop,propName);
cmpMesh.property(prop).set_persistent(true); cmpMesh.property(prop).set_persistent(true);
ok = OpenMesh::IO::read_mesh(cmpMesh,filename); ok = OpenMesh::IO::read_mesh(cmpMesh, filename, opts);
EXPECT_TRUE(ok) << "Unable to read "<<filename; EXPECT_TRUE(ok) << "Unable to read "<<filename;
// compare // compare
@@ -929,7 +938,9 @@ TEST_F(OpenMeshReadWriteOM, WriteTriangleFaceDoubleProperty) {
mesh.property(prop,f1) = va1ue1; mesh.property(prop,f1) = va1ue1;
// save // save
bool ok = OpenMesh::IO::write_mesh(mesh,filename); OpenMesh::IO::Options opts = OpenMesh::IO::Options::Custom;
bool ok = OpenMesh::IO::write_mesh(mesh, filename, opts);
EXPECT_TRUE(ok) << "Unable to write "<<filename; EXPECT_TRUE(ok) << "Unable to write "<<filename;
// load // load
@@ -938,7 +949,7 @@ TEST_F(OpenMeshReadWriteOM, WriteTriangleFaceDoubleProperty) {
cmpMesh.add_property(prop,propName); cmpMesh.add_property(prop,propName);
cmpMesh.property(prop).set_persistent(true); cmpMesh.property(prop).set_persistent(true);
ok = OpenMesh::IO::read_mesh(cmpMesh,filename); ok = OpenMesh::IO::read_mesh(cmpMesh, filename, opts);
EXPECT_TRUE(ok) << "Unable to read "<<filename; EXPECT_TRUE(ok) << "Unable to read "<<filename;
// compare // compare
@@ -983,7 +994,9 @@ TEST_F(OpenMeshReadWriteOM, WriteTriangleFaceFloatProperty) {
mesh.property(prop,f1) = va1ue1; mesh.property(prop,f1) = va1ue1;
// save // save
bool ok = OpenMesh::IO::write_mesh(mesh,filename); OpenMesh::IO::Options opts = OpenMesh::IO::Options::Custom;
bool ok = OpenMesh::IO::write_mesh(mesh, filename, opts);
EXPECT_TRUE(ok) << "Unable to write "<<filename; EXPECT_TRUE(ok) << "Unable to write "<<filename;
@@ -992,7 +1005,7 @@ TEST_F(OpenMeshReadWriteOM, WriteTriangleFaceFloatProperty) {
cmpMesh.add_property(prop,propName); cmpMesh.add_property(prop,propName);
cmpMesh.property(prop).set_persistent(true); cmpMesh.property(prop).set_persistent(true);
ok = OpenMesh::IO::read_mesh(cmpMesh,filename); ok = OpenMesh::IO::read_mesh(cmpMesh, filename, opts);
EXPECT_TRUE(ok) << "Unable to read "<<filename; EXPECT_TRUE(ok) << "Unable to read "<<filename;
// compare // compare
@@ -1050,7 +1063,8 @@ TEST_F(OpenMeshReadWriteOM, ReadBigMeshWithCustomProperty) {
mesh.add_property(vertexProp, "IVProp"); mesh.add_property(vertexProp, "IVProp");
mesh.property(vertexProp).set_persistent(true); mesh.property(vertexProp).set_persistent(true);
ok = OpenMesh::IO::read_mesh(mesh,"cube1_customProps.om"); OpenMesh::IO::Options opts = OpenMesh::IO::Options::Custom;
ok = OpenMesh::IO::read_mesh(mesh,"cube1_customProps.om", opts);
EXPECT_TRUE(ok) << "Unable to read cube1_customProps.om"; EXPECT_TRUE(ok) << "Unable to read cube1_customProps.om";
///=============== result ====================== ///=============== result ======================
@@ -1066,7 +1080,7 @@ TEST_F(OpenMeshReadWriteOM, ReadBigMeshWithCustomProperty) {
wrong = false; wrong = false;
for (Mesh::VertexIter vIter = mesh.vertices_begin(); vIter != mesh.vertices_end() && !wrong; ++vIter) for (Mesh::VertexIter vIter = mesh.vertices_begin(); vIter != mesh.vertices_end() && !wrong; ++vIter)
wrong = (vIter->idx() != mesh.property(vertexProp,*vIter)); wrong = (vIter->idx() != mesh.property(vertexProp,*vIter));
EXPECT_FALSE(wrong) << "min one vertex has worng vertex property"; EXPECT_FALSE(wrong) << "min one vertex has wrong vertex property";
} }

View File

@@ -781,14 +781,15 @@ TEST_F(OpenMeshTutorials, storing_custom_properties) {
EXPECT_TRUE(mesh.mproperty(mprop_map).persistent()) << "property should be persistent"; EXPECT_TRUE(mesh.mproperty(mprop_map).persistent()) << "property should be persistent";
// write mesh // write mesh
bool ok = OpenMesh::IO::write_mesh( mesh, "persistence-check.om" ); OpenMesh::IO::Options opts(OpenMesh::IO::Options::Custom);
bool ok = OpenMesh::IO::write_mesh(mesh, "persistence-check.om", opts);
EXPECT_TRUE(ok) << "Cannot write mesh to file 'persistent-check.om'"; EXPECT_TRUE(ok) << "Cannot write mesh to file 'persistent-check.om'";
// clear mesh // clear mesh
mesh.clear(); mesh.clear();
//Read back mesh //Read back mesh
ok = OpenMesh::IO::read_mesh( mesh, "persistence-check.om" ); ok = OpenMesh::IO::read_mesh(mesh, "persistence-check.om", opts);
EXPECT_TRUE(ok) << "Cannot read mesh from file 'persistence-check.om'"; EXPECT_TRUE(ok) << "Cannot read mesh from file 'persistence-check.om'";
// check props // check props