Commit d8d26b7c authored by Matthias Möller's avatar Matthias Möller

ply ascii reader:

- add read support for custom list properties (vertices and faces)


closes #2370

git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@1268 fdac6126-5c0c-442c-9429-916003d36597
parent eed151aa
This diff is collapsed.
......@@ -65,6 +65,7 @@
#include <string>
#include <stdio.h>
#include <fstream>
#include <vector>
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Utils/SingletonT.hh>
......@@ -92,7 +93,8 @@ class BaseImporter;
/**
Implementation of the PLY format reader. This class is singleton'ed by
SingletonT to OFFReader.
SingletonT to OFFReader. It can read custom properties, accessible via the name
of the custom properties. List properties has the type std::vector<Type>.
*/
......@@ -136,7 +138,8 @@ private:
bool read_binary(std::istream& _in, BaseImporter& _bi, bool swap, const Options& _opt) const;
float readToFloatValue(ValueType _type , std::fstream& _in) const;
void readCustomProperty(std::istream& _in, BaseImporter& _bi, VertexHandle _vh, const std::string& _propName, const ValueType _valueType) const;
template<typename Handle>
void readCustomProperty(std::istream& _in, BaseImporter& _bi, Handle _h, const std::string& _propName, const ValueType _valueType, const ValueType _listIndexType) const;
void readValue(ValueType _type , std::istream& _in, float& _value) const;
void readValue(ValueType _type, std::istream& _in, double& _value) const;
......@@ -165,14 +168,11 @@ private:
mutable ValueType vertexType_;
mutable uint vertexDimension_;
mutable ValueType faceIndexType_;
mutable ValueType faceEntryType_;
enum VertexProperty {
enum Property {
XCOORD,YCOORD,ZCOORD,
TEXX,TEXY,
COLORRED,COLORGREEN,COLORBLUE,COLORALPHA,
XNORM,YNORM,ZNORM, CUSTOM_PROP,
XNORM,YNORM,ZNORM, CUSTOM_PROP, VERTEX_INDICES,
UNSUPPORTED
};
......@@ -180,17 +180,18 @@ private:
mutable std::map<ValueType, int> scalar_size_;
// Number of vertex properties
mutable unsigned int vertexPropertyCount_;
struct VertexPropertyInfo
struct PropertyInfo
{
VertexProperty property;
Property property;
ValueType value;
std::string name;//for custom properties
VertexPropertyInfo():property(UNSUPPORTED),value(Unsupported),name(""){}
VertexPropertyInfo(VertexProperty _p, ValueType _v):property(_p),value(_v),name(""){}
VertexPropertyInfo(VertexProperty _p, ValueType _v, const std::string& _n):property(_p),value(_v),name(_n){}
ValueType listIndexType;//if type is unsupported, the poerty is not a list. otherwise, it the index type
PropertyInfo():property(UNSUPPORTED),value(Unsupported),name(""),listIndexType(Unsupported){}
PropertyInfo(Property _p, ValueType _v):property(_p),value(_v),name(""),listIndexType(Unsupported){}
PropertyInfo(Property _p, ValueType _v, const std::string& _n):property(_p),value(_v),name(_n),listIndexType(Unsupported){}
};
mutable std::map< int , VertexPropertyInfo > vertexPropertyMap_;
mutable std::vector< PropertyInfo > vertexProperties_;
mutable std::vector< PropertyInfo > faceProperties_;
};
......
......@@ -9,20 +9,22 @@ property float32 ny
property float32 nz
property float32 quality
property uint index
property list uint8 int32 test_values
element face 6
property list uint8 int32 vertex_indices
property list uint8 float32 texcoords
end_header
-1 -1 -1 0.0 0.0 1.0 1.0 0
1 -1 -1 0.0 1.0 0.0 0.5 1
1 1 -1 0.0 1.0 1.0 0.7 2
-1 1 -1 1.0 0.0 0.0 1.0 3
-1 -1 1 1.0 0.0 1.0 0.1 4
1 -1 1 1.0 1.0 0.0 0.0 5
1 1 1 1.0 1.0 1.0 2.0 6
-1 1 1 1.0 1.0 2.0 5.0 7
4 0 1 2 3
4 5 4 7 6
4 6 2 1 5
4 3 7 4 0
4 7 3 2 6
4 5 1 0 4
-1 -1 -1 0.0 0.0 1.0 1.0 0 2 1 2
1 -1 -1 0.0 1.0 0.0 0.5 1 2 3 4
1 1 -1 0.0 1.0 1.0 0.7 2 2 5 6
-1 1 -1 1.0 0.0 0.0 1.0 3 2 7 8
-1 -1 1 1.0 0.0 1.0 0.1 4 2 9 10
1 -1 1 1.0 1.0 0.0 0.0 5 2 11 12
1 1 1 1.0 1.0 1.0 2.0 6 2 13 14
-1 1 1 1.0 1.0 2.0 5.0 7 2 15 16
4 0 1 2 3 8 1.0 1.0 -1.0 -1.0 0.0 0.0 -0.5 -0.5
4 5 4 7 6 8 1.0 1.0 -1.0 -1.0 0.0 0.0 -0.5 -0.5
4 6 2 1 5 8 1.0 1.0 -1.0 -1.0 0.0 0.0 -0.5 -0.5
4 3 7 4 0 8 1.0 1.0 -1.0 -1.0 0.0 0.0 -0.5 -0.5
4 7 3 2 6 8 1.0 1.0 -1.0 -1.0 0.0 0.0 -0.5 -0.5
4 5 1 0 4 8 1.0 1.0 -1.0 -1.0 0.0 0.0 -0.5 -0.5
......@@ -445,37 +445,86 @@ TEST_F(OpenMeshReadWritePLY, LoadSimplePLYWithNormals) {
*/
TEST_F(OpenMeshReadWritePLY, LoadSimplePLYWithCustomProps) {
mesh_.clear();
PolyMesh mesh;
OpenMesh::IO::Options options;
options += OpenMesh::IO::Options::Custom;
bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-custom_props.ply", options);
bool ok = OpenMesh::IO::read_mesh(mesh, "cube-minimal-custom_props.ply", options);
EXPECT_TRUE(ok) << "Unable to load cube-minimal-custom_props.ply";
EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
EXPECT_EQ(8u , mesh.n_vertices()) << "The number of loaded vertices is not correct!";
EXPECT_EQ(12u , mesh.n_edges()) << "The number of loaded edges is not correct!";
EXPECT_EQ(6u , mesh.n_faces()) << "The number of loaded faces is not correct!";
OpenMesh::VPropHandleT<float> qualityProp;
OpenMesh::VPropHandleT<unsigned int> indexProp;
EXPECT_TRUE(mesh_.get_property_handle(qualityProp,"quality")) << "Could not access quality property";
EXPECT_TRUE(mesh_.get_property_handle(indexProp,"index")) << "Could not access index property";
EXPECT_TRUE(mesh.get_property_handle(qualityProp,"quality")) << "Could not access quality property";
EXPECT_TRUE(mesh.get_property_handle(indexProp,"index")) << "Could not access index property";
if (!mesh.get_property_handle(qualityProp,"quality"))
return;
if (!mesh.get_property_handle(indexProp,"index"))
return;
//check index property
for (unsigned i = 0; i < mesh_.n_vertices(); ++i)
EXPECT_EQ(i ,mesh_.property(indexProp,OpenMesh::VertexHandle(i))) << "Vertex index at vertex " << i << " is wrong";
for (unsigned i = 0; i < mesh.n_vertices(); ++i)
EXPECT_EQ(i ,mesh.property(indexProp,OpenMesh::VertexHandle(i))) << "Vertex index at vertex " << i << " is wrong";
//check quality property
EXPECT_EQ(1.f,mesh_.property(qualityProp,OpenMesh::VertexHandle(0))) << "Wrong quality value at Vertex 0";
EXPECT_EQ(0.5f,mesh_.property(qualityProp,OpenMesh::VertexHandle(1))) << "Wrong quality value at Vertex 1";
EXPECT_EQ(0.7f,mesh_.property(qualityProp,OpenMesh::VertexHandle(2))) << "Wrong quality value at Vertex 2";
EXPECT_EQ(1.f,mesh_.property(qualityProp,OpenMesh::VertexHandle(3))) << "Wrong quality value at Vertex 3";
EXPECT_EQ(0.1f,mesh_.property(qualityProp,OpenMesh::VertexHandle(4))) << "Wrong quality value at Vertex 4";
EXPECT_EQ(0.f,mesh_.property(qualityProp,OpenMesh::VertexHandle(5))) << "Wrong quality value at Vertex 5";
EXPECT_EQ(2.f,mesh_.property(qualityProp,OpenMesh::VertexHandle(6))) << "Wrong quality value at Vertex 6";
EXPECT_EQ(5.f,mesh_.property(qualityProp,OpenMesh::VertexHandle(7))) << "Wrong quality value at Vertex 7";
EXPECT_EQ(1.f,mesh.property(qualityProp,OpenMesh::VertexHandle(0))) << "Wrong quality value at Vertex 0";
EXPECT_EQ(0.5f,mesh.property(qualityProp,OpenMesh::VertexHandle(1))) << "Wrong quality value at Vertex 1";
EXPECT_EQ(0.7f,mesh.property(qualityProp,OpenMesh::VertexHandle(2))) << "Wrong quality value at Vertex 2";
EXPECT_EQ(1.f,mesh.property(qualityProp,OpenMesh::VertexHandle(3))) << "Wrong quality value at Vertex 3";
EXPECT_EQ(0.1f,mesh.property(qualityProp,OpenMesh::VertexHandle(4))) << "Wrong quality value at Vertex 4";
EXPECT_EQ(0.f,mesh.property(qualityProp,OpenMesh::VertexHandle(5))) << "Wrong quality value at Vertex 5";
EXPECT_EQ(2.f,mesh.property(qualityProp,OpenMesh::VertexHandle(6))) << "Wrong quality value at Vertex 6";
EXPECT_EQ(5.f,mesh.property(qualityProp,OpenMesh::VertexHandle(7))) << "Wrong quality value at Vertex 7";
//check for custom list properties
OpenMesh::VPropHandleT< std::vector<int> > testValues;
EXPECT_TRUE(mesh.get_property_handle(testValues,"test_values")) << "Could not access texcoords per face";
if (!mesh.get_property_handle(testValues,"test_values"))
return;
EXPECT_EQ(2u,mesh.property(testValues,OpenMesh::VertexHandle(0)).size()) << "Wrong verctor size";
EXPECT_EQ(1,mesh.property(testValues,OpenMesh::VertexHandle(0))[0]) << "Wrong list value at Vertex 0";
EXPECT_EQ(4,mesh.property(testValues,OpenMesh::VertexHandle(1))[1]) << "Wrong list value at Vertex 1";
EXPECT_EQ(5,mesh.property(testValues,OpenMesh::VertexHandle(2))[0]) << "Wrong list value at Vertex 2";
EXPECT_EQ(8,mesh.property(testValues,OpenMesh::VertexHandle(3))[1]) << "Wrong list value at Vertex 3";
EXPECT_EQ(9,mesh.property(testValues,OpenMesh::VertexHandle(4))[0]) << "Wrong list value at Vertex 4";
EXPECT_EQ(12,mesh.property(testValues,OpenMesh::VertexHandle(5))[1]) << "Wrong list value at Vertex 5";
EXPECT_EQ(13,mesh.property(testValues,OpenMesh::VertexHandle(6))[0]) << "Wrong list value at Vertex 6";
EXPECT_EQ(16,mesh.property(testValues,OpenMesh::VertexHandle(7))[1]) << "Wrong list value at Vertex 7";
OpenMesh::FPropHandleT< std::vector<float> > texCoordsPerFace;
EXPECT_TRUE(mesh.get_property_handle(texCoordsPerFace,"texcoords")) << "Could not access texcoords per face";
if (!mesh.get_property_handle(texCoordsPerFace,"texcoords"))
return;
for (Mesh::FaceIter f_iter = mesh.faces_begin(); f_iter != mesh.faces_end(); ++f_iter)
{
EXPECT_EQ(8u, mesh.property(texCoordsPerFace, *f_iter).size()) << "Texcoords per face container has wrong size on face: " << f_iter->idx();
if (!mesh.property(texCoordsPerFace, *f_iter).empty())
{
EXPECT_EQ(1.0, mesh.property(texCoordsPerFace, *f_iter)[0]) << "Texcoords wrong on index 0 with face: " << f_iter->idx();
EXPECT_EQ(1.0, mesh.property(texCoordsPerFace, *f_iter)[1]) << "Texcoords wrong on index 1 with face: " << f_iter->idx();
EXPECT_EQ(-1.0f, mesh.property(texCoordsPerFace, *f_iter)[2]) << "Texcoords wrong on index 2 with face: " << f_iter->idx();
EXPECT_EQ(-1.0f, mesh.property(texCoordsPerFace, *f_iter)[3]) << "Texcoords wrong on index 3 with face: " << f_iter->idx();
EXPECT_EQ(0.0f, mesh.property(texCoordsPerFace, *f_iter)[4]) << "Texcoords wrong on index 4 with face: " << f_iter->idx();
EXPECT_EQ(0.0f, mesh.property(texCoordsPerFace, *f_iter)[5]) << "Texcoords wrong on index 5 with face: " << f_iter->idx();
EXPECT_EQ(-0.5f, mesh.property(texCoordsPerFace, *f_iter)[6]) << "Texcoords wrong on index 6 with face: " << f_iter->idx();
EXPECT_EQ(-0.5f, mesh.property(texCoordsPerFace, *f_iter)[7]) << "Texcoords wrong on index 7 with face: " << f_iter->idx();
}
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment