add custom property support for PLY reader ASCII version
git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@1181 fdac6126-5c0c-442c-9429-916003d36597
This commit is contained in:
@@ -106,8 +106,9 @@ public:
|
|||||||
FaceNormal = 0x0100, ///< Has (r) / store (w) face normals
|
FaceNormal = 0x0100, ///< Has (r) / store (w) face normals
|
||||||
FaceColor = 0x0200, ///< Has (r) / store (w) face colors
|
FaceColor = 0x0200, ///< Has (r) / store (w) face colors
|
||||||
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)
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -89,6 +89,9 @@ public:
|
|||||||
// add a vertex with coordinate \c _point
|
// add a vertex with coordinate \c _point
|
||||||
virtual VertexHandle add_vertex(const Vec3f& _point) = 0;
|
virtual VertexHandle add_vertex(const Vec3f& _point) = 0;
|
||||||
|
|
||||||
|
// add a vertex without coordinate. Use set_point to set the position deferred
|
||||||
|
virtual VertexHandle add_vertex() = 0;
|
||||||
|
|
||||||
// add a face with indices _indices refering to vertices
|
// add a face with indices _indices refering to vertices
|
||||||
typedef std::vector<VertexHandle> VHandles;
|
typedef std::vector<VertexHandle> VHandles;
|
||||||
virtual FaceHandle add_face(const VHandles& _indices) = 0;
|
virtual FaceHandle add_face(const VHandles& _indices) = 0;
|
||||||
@@ -99,6 +102,9 @@ public:
|
|||||||
// Set the texture index for a face
|
// Set the texture index for a face
|
||||||
virtual void set_face_texindex( FaceHandle _fh, int _texId ) = 0;
|
virtual void set_face_texindex( FaceHandle _fh, int _texId ) = 0;
|
||||||
|
|
||||||
|
// Set coordinate of the given vertex. Use this function, if you created a vertex without coordinate
|
||||||
|
virtual void set_point(VertexHandle _vh, const Vec3f& _point) = 0;
|
||||||
|
|
||||||
// set vertex normal
|
// set vertex normal
|
||||||
virtual void set_normal(VertexHandle _vh, const Vec3f& _normal) = 0;
|
virtual void set_normal(VertexHandle _vh, const Vec3f& _normal) = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -94,6 +94,10 @@ public:
|
|||||||
return mesh_.add_vertex(vector_cast<Point>(_point));
|
return mesh_.add_vertex(vector_cast<Point>(_point));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual VertexHandle add_vertex()
|
||||||
|
{
|
||||||
|
return mesh_.new_vertex();
|
||||||
|
}
|
||||||
|
|
||||||
virtual FaceHandle add_face(const VHandles& _indices)
|
virtual FaceHandle add_face(const VHandles& _indices)
|
||||||
{
|
{
|
||||||
@@ -154,6 +158,11 @@ public:
|
|||||||
|
|
||||||
// vertex attributes
|
// vertex attributes
|
||||||
|
|
||||||
|
virtual void set_point(VertexHandle _vh, const Vec3f& _point)
|
||||||
|
{
|
||||||
|
mesh_.set_point(_vh,vector_cast<Point>(_point));
|
||||||
|
}
|
||||||
|
|
||||||
virtual void set_normal(VertexHandle _vh, const Vec3f& _normal)
|
virtual void set_normal(VertexHandle _vh, const Vec3f& _normal)
|
||||||
{
|
{
|
||||||
if (mesh_.has_vertex_normals())
|
if (mesh_.has_vertex_normals())
|
||||||
|
|||||||
@@ -156,6 +156,9 @@ bool _PLYReader_::read(std::istream& _in, BaseImporter& _bi, Options& _opt) {
|
|||||||
if (options_.color_is_float()) {
|
if (options_.color_is_float()) {
|
||||||
_opt += Options::ColorFloat;
|
_opt += Options::ColorFloat;
|
||||||
}
|
}
|
||||||
|
if (options_.check(Options::Custom) && userOptions_.check(Options::Custom)) {
|
||||||
|
_opt += Options::Custom;
|
||||||
|
}
|
||||||
|
|
||||||
// //force user-choice for the alpha value when reading binary
|
// //force user-choice for the alpha value when reading binary
|
||||||
// if ( options_.is_binary() && userOptions_.color_has_alpha() )
|
// if ( options_.is_binary() && userOptions_.color_has_alpha() )
|
||||||
@@ -165,6 +168,55 @@ bool _PLYReader_::read(std::istream& _in, BaseImporter& _bi, Options& _opt) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void assignCustomProperty(std::istream& _in, BaseImporter& _bi, VertexHandle _vh, const std::string& _propName)
|
||||||
|
{
|
||||||
|
OpenMesh::VPropHandleT<T> prop;
|
||||||
|
if (!_bi.kernel()->get_property_handle(prop,_propName))
|
||||||
|
_bi.kernel()->add_property(prop,_propName);
|
||||||
|
T in;
|
||||||
|
_in >> in;
|
||||||
|
_bi.kernel()->property(prop,_vh) = in;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void _PLYReader_::readCustomProperty(std::istream& _in, BaseImporter& _bi, VertexHandle _vh, const std::string& _propName, const ValueType _valueType) const
|
||||||
|
{
|
||||||
|
switch (_valueType)
|
||||||
|
{
|
||||||
|
case ValueTypeINT8:
|
||||||
|
case ValueTypeCHAR:
|
||||||
|
assignCustomProperty<char>(_in,_bi,_vh,_propName);
|
||||||
|
break;
|
||||||
|
case ValueTypeINT16:
|
||||||
|
case ValueTypeSHORT:
|
||||||
|
assignCustomProperty<short>(_in,_bi,_vh,_propName);
|
||||||
|
break;
|
||||||
|
case ValueTypeUINT16:
|
||||||
|
case ValueTypeUSHORT:
|
||||||
|
assignCustomProperty<unsigned short>(_in,_bi,_vh,_propName);
|
||||||
|
break;
|
||||||
|
case ValueTypeINT32:
|
||||||
|
case ValueTypeINT:
|
||||||
|
assignCustomProperty<int>(_in,_bi,_vh,_propName);
|
||||||
|
break;
|
||||||
|
case ValueTypeUINT32:
|
||||||
|
case ValueTypeUINT:
|
||||||
|
assignCustomProperty<unsigned int>(_in,_bi,_vh,_propName);
|
||||||
|
break;
|
||||||
|
case ValueTypeFLOAT32:
|
||||||
|
case ValueTypeFLOAT:
|
||||||
|
assignCustomProperty<float>(_in,_bi,_vh,_propName);
|
||||||
|
break;
|
||||||
|
case ValueTypeFLOAT64:
|
||||||
|
case ValueTypeDOUBLE:
|
||||||
|
assignCustomProperty<double>(_in,_bi,_vh,_propName);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
std::cerr << "unsupported type" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -196,6 +248,8 @@ bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options
|
|||||||
|
|
||||||
// read vertices:
|
// read vertices:
|
||||||
for (i = 0; i < vertexCount_ && !_in.eof(); ++i) {
|
for (i = 0; i < vertexCount_ && !_in.eof(); ++i) {
|
||||||
|
vh = _bi.add_vertex();
|
||||||
|
|
||||||
v[0] = 0.0;
|
v[0] = 0.0;
|
||||||
v[1] = 0.0;
|
v[1] = 0.0;
|
||||||
v[2] = 0.0;
|
v[2] = 0.0;
|
||||||
@@ -213,7 +267,7 @@ bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options
|
|||||||
c[3] = 255;
|
c[3] = 255;
|
||||||
|
|
||||||
for (uint propertyIndex = 0; propertyIndex < vertexPropertyCount_; ++propertyIndex) {
|
for (uint propertyIndex = 0; propertyIndex < vertexPropertyCount_; ++propertyIndex) {
|
||||||
switch (vertexPropertyMap_[propertyIndex].first) {
|
switch (vertexPropertyMap_[propertyIndex].property) {
|
||||||
case XCOORD:
|
case XCOORD:
|
||||||
_in >> v[0];
|
_in >> v[0];
|
||||||
break;
|
break;
|
||||||
@@ -239,44 +293,50 @@ bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options
|
|||||||
_in >> t[1];
|
_in >> t[1];
|
||||||
break;
|
break;
|
||||||
case COLORRED:
|
case COLORRED:
|
||||||
if (vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT32 ||
|
if (vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT32 ||
|
||||||
vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT) {
|
vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT) {
|
||||||
_in >> tmp;
|
_in >> tmp;
|
||||||
c[0] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
c[0] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||||
} else
|
} else
|
||||||
_in >> c[0];
|
_in >> c[0];
|
||||||
break;
|
break;
|
||||||
case COLORGREEN:
|
case COLORGREEN:
|
||||||
if (vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT32 ||
|
if (vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT32 ||
|
||||||
vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT) {
|
vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT) {
|
||||||
_in >> tmp;
|
_in >> tmp;
|
||||||
c[1] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
c[1] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||||
} else
|
} else
|
||||||
_in >> c[1];
|
_in >> c[1];
|
||||||
break;
|
break;
|
||||||
case COLORBLUE:
|
case COLORBLUE:
|
||||||
if (vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT32 ||
|
if (vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT32 ||
|
||||||
vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT) {
|
vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT) {
|
||||||
_in >> tmp;
|
_in >> tmp;
|
||||||
c[2] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
c[2] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||||
} else
|
} else
|
||||||
_in >> c[2];
|
_in >> c[2];
|
||||||
break;
|
break;
|
||||||
case COLORALPHA:
|
case COLORALPHA:
|
||||||
if (vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT32 ||
|
if (vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT32 ||
|
||||||
vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT) {
|
vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT) {
|
||||||
_in >> tmp;
|
_in >> tmp;
|
||||||
c[3] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
c[3] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||||
} else
|
} else
|
||||||
_in >> c[3];
|
_in >> c[3];
|
||||||
break;
|
break;
|
||||||
|
case CUSTOM_PROP:
|
||||||
|
if (_opt.check(Options::Custom))
|
||||||
|
readCustomProperty(_in, _bi, vh, vertexPropertyMap_[propertyIndex].name, vertexPropertyMap_[propertyIndex].value);
|
||||||
|
else
|
||||||
|
_in >> trash;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
_in >> trash;
|
_in >> trash;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vh = _bi.add_vertex(v);
|
_bi.set_point(vh, v);
|
||||||
if (_opt.vertex_has_normal())
|
if (_opt.vertex_has_normal())
|
||||||
_bi.set_normal(vh, n);
|
_bi.set_normal(vh, n);
|
||||||
if (_opt.vertex_has_texcoord())
|
if (_opt.vertex_has_texcoord())
|
||||||
@@ -356,71 +416,71 @@ bool _PLYReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap
|
|||||||
c[3] = 255;
|
c[3] = 255;
|
||||||
|
|
||||||
for (uint propertyIndex = 0; propertyIndex < vertexPropertyCount_; ++propertyIndex) {
|
for (uint propertyIndex = 0; propertyIndex < vertexPropertyCount_; ++propertyIndex) {
|
||||||
switch (vertexPropertyMap_[propertyIndex].first) {
|
switch (vertexPropertyMap_[propertyIndex].property) {
|
||||||
case XCOORD:
|
case XCOORD:
|
||||||
readValue(vertexPropertyMap_[propertyIndex].second, _in, v[0]);
|
readValue(vertexPropertyMap_[propertyIndex].value, _in, v[0]);
|
||||||
break;
|
break;
|
||||||
case YCOORD:
|
case YCOORD:
|
||||||
readValue(vertexPropertyMap_[propertyIndex].second, _in, v[1]);
|
readValue(vertexPropertyMap_[propertyIndex].value, _in, v[1]);
|
||||||
break;
|
break;
|
||||||
case ZCOORD:
|
case ZCOORD:
|
||||||
readValue(vertexPropertyMap_[propertyIndex].second, _in, v[2]);
|
readValue(vertexPropertyMap_[propertyIndex].value, _in, v[2]);
|
||||||
break;
|
break;
|
||||||
case XNORM:
|
case XNORM:
|
||||||
readValue(vertexPropertyMap_[propertyIndex].second, _in, n[0]);
|
readValue(vertexPropertyMap_[propertyIndex].value, _in, n[0]);
|
||||||
break;
|
break;
|
||||||
case YNORM:
|
case YNORM:
|
||||||
readValue(vertexPropertyMap_[propertyIndex].second, _in, n[1]);
|
readValue(vertexPropertyMap_[propertyIndex].value, _in, n[1]);
|
||||||
break;
|
break;
|
||||||
case ZNORM:
|
case ZNORM:
|
||||||
readValue(vertexPropertyMap_[propertyIndex].second, _in, n[2]);
|
readValue(vertexPropertyMap_[propertyIndex].value, _in, n[2]);
|
||||||
break;
|
break;
|
||||||
case TEXX:
|
case TEXX:
|
||||||
readValue(vertexPropertyMap_[propertyIndex].second, _in, t[0]);
|
readValue(vertexPropertyMap_[propertyIndex].value, _in, t[0]);
|
||||||
break;
|
break;
|
||||||
case TEXY:
|
case TEXY:
|
||||||
readValue(vertexPropertyMap_[propertyIndex].second, _in, t[1]);
|
readValue(vertexPropertyMap_[propertyIndex].value, _in, t[1]);
|
||||||
break;
|
break;
|
||||||
case COLORRED:
|
case COLORRED:
|
||||||
if (vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT32 ||
|
if (vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT32 ||
|
||||||
vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT) {
|
vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT) {
|
||||||
readValue(vertexPropertyMap_[propertyIndex].second, _in, tmp);
|
readValue(vertexPropertyMap_[propertyIndex].value, _in, tmp);
|
||||||
|
|
||||||
c[0] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
c[0] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||||
} else
|
} else
|
||||||
readInteger(vertexPropertyMap_[propertyIndex].second, _in, c[0]);
|
readInteger(vertexPropertyMap_[propertyIndex].value, _in, c[0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case COLORGREEN:
|
case COLORGREEN:
|
||||||
if (vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT32 ||
|
if (vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT32 ||
|
||||||
vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT) {
|
vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT) {
|
||||||
readValue(vertexPropertyMap_[propertyIndex].second, _in, tmp);
|
readValue(vertexPropertyMap_[propertyIndex].value, _in, tmp);
|
||||||
c[1] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
c[1] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||||
} else
|
} else
|
||||||
readInteger(vertexPropertyMap_[propertyIndex].second, _in, c[1]);
|
readInteger(vertexPropertyMap_[propertyIndex].value, _in, c[1]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case COLORBLUE:
|
case COLORBLUE:
|
||||||
if (vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT32 ||
|
if (vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT32 ||
|
||||||
vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT) {
|
vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT) {
|
||||||
readValue(vertexPropertyMap_[propertyIndex].second, _in, tmp);
|
readValue(vertexPropertyMap_[propertyIndex].value, _in, tmp);
|
||||||
c[2] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
c[2] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||||
} else
|
} else
|
||||||
readInteger(vertexPropertyMap_[propertyIndex].second, _in, c[2]);
|
readInteger(vertexPropertyMap_[propertyIndex].value, _in, c[2]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case COLORALPHA:
|
case COLORALPHA:
|
||||||
if (vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT32 ||
|
if (vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT32 ||
|
||||||
vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT) {
|
vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT) {
|
||||||
readValue(vertexPropertyMap_[propertyIndex].second, _in, tmp);
|
readValue(vertexPropertyMap_[propertyIndex].value, _in, tmp);
|
||||||
c[3] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
c[3] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||||
} else
|
} else
|
||||||
readInteger(vertexPropertyMap_[propertyIndex].second, _in, c[3]);
|
readInteger(vertexPropertyMap_[propertyIndex].value, _in, c[3]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Read unsupported property
|
// Read unsupported property
|
||||||
consume_input(_in, scalar_size_[vertexPropertyMap_[propertyIndex].second]);
|
consume_input(_in, scalar_size_[vertexPropertyMap_[propertyIndex].value]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -959,84 +1019,86 @@ bool _PLYReader_::can_u_read(std::istream& _is) const {
|
|||||||
propertyName = get_property_name(tmp1, tmp2);
|
propertyName = get_property_name(tmp1, tmp2);
|
||||||
|
|
||||||
if (propertyName == "x") {
|
if (propertyName == "x") {
|
||||||
std::pair<VertexProperty, ValueType> entry(XCOORD, valueType);
|
VertexPropertyInfo entry(XCOORD, valueType);
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
||||||
vertexDimension_++;
|
vertexDimension_++;
|
||||||
} else if (propertyName == "y") {
|
} else if (propertyName == "y") {
|
||||||
std::pair<VertexProperty, ValueType> entry(YCOORD, valueType);
|
VertexPropertyInfo entry(YCOORD, valueType);
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
||||||
vertexDimension_++;
|
vertexDimension_++;
|
||||||
} else if (propertyName == "z") {
|
} else if (propertyName == "z") {
|
||||||
std::pair<VertexProperty, ValueType> entry(ZCOORD, valueType);
|
VertexPropertyInfo entry(ZCOORD, valueType);
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
||||||
vertexDimension_++;
|
vertexDimension_++;
|
||||||
} else if (propertyName == "nx") {
|
} else if (propertyName == "nx") {
|
||||||
std::pair<VertexProperty, ValueType> entry(XNORM, valueType);
|
VertexPropertyInfo entry(XNORM, valueType);
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
||||||
options_ += Options::VertexNormal;
|
options_ += Options::VertexNormal;
|
||||||
} else if (propertyName == "ny") {
|
} else if (propertyName == "ny") {
|
||||||
std::pair<VertexProperty, ValueType> entry(YNORM, valueType);
|
VertexPropertyInfo entry(YNORM, valueType);
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
||||||
options_ += Options::VertexNormal;
|
options_ += Options::VertexNormal;
|
||||||
} else if (propertyName == "nz") {
|
} else if (propertyName == "nz") {
|
||||||
std::pair<VertexProperty, ValueType> entry(ZNORM, valueType);
|
VertexPropertyInfo entry(ZNORM, valueType);
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
||||||
options_ += Options::VertexNormal;
|
options_ += Options::VertexNormal;
|
||||||
} else if (propertyName == "u" || propertyName == "s") {
|
} else if (propertyName == "u" || propertyName == "s") {
|
||||||
std::pair<VertexProperty, ValueType> entry(TEXX, valueType);
|
VertexPropertyInfo entry(TEXX, valueType);
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
||||||
options_ += Options::VertexTexCoord;
|
options_ += Options::VertexTexCoord;
|
||||||
} else if (propertyName == "v" || propertyName == "t") {
|
} else if (propertyName == "v" || propertyName == "t") {
|
||||||
std::pair<VertexProperty, ValueType> entry(TEXY, valueType);
|
VertexPropertyInfo entry(TEXY, valueType);
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
||||||
options_ += Options::VertexTexCoord;
|
options_ += Options::VertexTexCoord;
|
||||||
} else if (propertyName == "red") {
|
} else if (propertyName == "red") {
|
||||||
std::pair<VertexProperty, ValueType> entry(COLORRED, valueType);
|
VertexPropertyInfo entry(COLORRED, valueType);
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
||||||
options_ += Options::VertexColor;
|
options_ += Options::VertexColor;
|
||||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||||
options_ += Options::ColorFloat;
|
options_ += Options::ColorFloat;
|
||||||
} else if (propertyName == "green") {
|
} else if (propertyName == "green") {
|
||||||
std::pair<VertexProperty, ValueType> entry(COLORGREEN, valueType);
|
VertexPropertyInfo entry(COLORGREEN, valueType);
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
||||||
options_ += Options::VertexColor;
|
options_ += Options::VertexColor;
|
||||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||||
options_ += Options::ColorFloat;
|
options_ += Options::ColorFloat;
|
||||||
} else if (propertyName == "blue") {
|
} else if (propertyName == "blue") {
|
||||||
std::pair<VertexProperty, ValueType> entry(COLORBLUE, valueType);
|
VertexPropertyInfo entry(COLORBLUE, valueType);
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
||||||
options_ += Options::VertexColor;
|
options_ += Options::VertexColor;
|
||||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||||
options_ += Options::ColorFloat;
|
options_ += Options::ColorFloat;
|
||||||
} else if (propertyName == "diffuse_red") {
|
} else if (propertyName == "diffuse_red") {
|
||||||
std::pair<VertexProperty, ValueType> entry(COLORRED, valueType);
|
VertexPropertyInfo entry(COLORRED, valueType);
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
||||||
options_ += Options::VertexColor;
|
options_ += Options::VertexColor;
|
||||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||||
options_ += Options::ColorFloat;
|
options_ += Options::ColorFloat;
|
||||||
} else if (propertyName == "diffuse_green") {
|
} else if (propertyName == "diffuse_green") {
|
||||||
std::pair<VertexProperty, ValueType> entry(COLORGREEN, valueType);
|
VertexPropertyInfo entry(COLORGREEN, valueType);
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
||||||
options_ += Options::VertexColor;
|
options_ += Options::VertexColor;
|
||||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||||
options_ += Options::ColorFloat;
|
options_ += Options::ColorFloat;
|
||||||
} else if (propertyName == "diffuse_blue") {
|
} else if (propertyName == "diffuse_blue") {
|
||||||
std::pair<VertexProperty, ValueType> entry(COLORBLUE, valueType);
|
VertexPropertyInfo entry(COLORBLUE, valueType);
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
||||||
options_ += Options::VertexColor;
|
options_ += Options::VertexColor;
|
||||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||||
options_ += Options::ColorFloat;
|
options_ += Options::ColorFloat;
|
||||||
} else if (propertyName == "alpha") {
|
} else if (propertyName == "alpha") {
|
||||||
std::pair<VertexProperty, ValueType> entry(COLORALPHA, valueType);
|
VertexPropertyInfo entry(COLORALPHA, valueType);
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
||||||
options_ += Options::VertexColor;
|
options_ += Options::VertexColor;
|
||||||
options_ += Options::ColorAlpha;
|
options_ += Options::ColorAlpha;
|
||||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||||
options_ += Options::ColorFloat;
|
options_ += Options::ColorFloat;
|
||||||
} else {
|
} else {
|
||||||
std::pair<VertexProperty, ValueType> entry(UNSUPPORTED, valueType);
|
VertexProperty prop = (!options_.is_binary()) ? CUSTOM_PROP : UNSUPPORTED; // loading vertex properties is not yet supported by the binary loader
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
if (prop != UNSUPPORTED)
|
||||||
std::cerr << "Unsupported property : " << propertyName << std::endl;
|
options_ += Options::Custom;
|
||||||
|
VertexPropertyInfo entry(prop, valueType, propertyName);
|
||||||
|
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
vertexPropertyCount_++;
|
vertexPropertyCount_++;
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ private:
|
|||||||
bool read_binary(std::istream& _in, BaseImporter& _bi, bool swap, const Options& _opt) const;
|
bool read_binary(std::istream& _in, BaseImporter& _bi, bool swap, const Options& _opt) const;
|
||||||
|
|
||||||
float readToFloatValue(ValueType _type , std::fstream& _in) 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;
|
||||||
|
|
||||||
void readValue(ValueType _type , std::istream& _in, float& _value) const;
|
void readValue(ValueType _type , std::istream& _in, float& _value) const;
|
||||||
void readValue(ValueType _type, std::istream& _in, double& _value) const;
|
void readValue(ValueType _type, std::istream& _in, double& _value) const;
|
||||||
@@ -164,7 +165,7 @@ private:
|
|||||||
XCOORD,YCOORD,ZCOORD,
|
XCOORD,YCOORD,ZCOORD,
|
||||||
TEXX,TEXY,
|
TEXX,TEXY,
|
||||||
COLORRED,COLORGREEN,COLORBLUE,COLORALPHA,
|
COLORRED,COLORGREEN,COLORBLUE,COLORALPHA,
|
||||||
XNORM,YNORM,ZNORM,
|
XNORM,YNORM,ZNORM, CUSTOM_PROP,
|
||||||
UNSUPPORTED
|
UNSUPPORTED
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -173,7 +174,16 @@ private:
|
|||||||
|
|
||||||
// Number of vertex properties
|
// Number of vertex properties
|
||||||
mutable unsigned int vertexPropertyCount_;
|
mutable unsigned int vertexPropertyCount_;
|
||||||
mutable std::map< int , std::pair< VertexProperty, ValueType> > vertexPropertyMap_;
|
struct VertexPropertyInfo
|
||||||
|
{
|
||||||
|
VertexProperty 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){}
|
||||||
|
};
|
||||||
|
mutable std::map< int , VertexPropertyInfo > vertexPropertyMap_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
28
src/Unittests/TestFiles/cube-minimal-custom_props.ply
Normal file
28
src/Unittests/TestFiles/cube-minimal-custom_props.ply
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
ply
|
||||||
|
format ascii 1.0
|
||||||
|
element vertex 8
|
||||||
|
property float32 x
|
||||||
|
property float32 y
|
||||||
|
property float32 z
|
||||||
|
property float32 nx
|
||||||
|
property float32 ny
|
||||||
|
property float32 nz
|
||||||
|
property float32 quality
|
||||||
|
property uint index
|
||||||
|
element face 6
|
||||||
|
property list uint8 int32 vertex_indices
|
||||||
|
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
|
||||||
@@ -438,5 +438,44 @@ TEST_F(OpenMeshReadWritePLY, LoadSimplePLYWithNormals) {
|
|||||||
|
|
||||||
mesh_.release_vertex_normals();
|
mesh_.release_vertex_normals();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Just load a ply with custom properties, ascii mode
|
||||||
|
*/
|
||||||
|
TEST_F(OpenMeshReadWritePLY, LoadSimplePLYWithCustomProps) {
|
||||||
|
|
||||||
|
mesh_.clear();
|
||||||
|
|
||||||
|
OpenMesh::IO::Options options;
|
||||||
|
options += OpenMesh::IO::Options::Custom;
|
||||||
|
|
||||||
|
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!";
|
||||||
|
|
||||||
|
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";
|
||||||
|
|
||||||
|
//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";
|
||||||
|
|
||||||
|
//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";
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user