Merge branch 'ply_handle_extra_elements' into 'master'

adding support for additional elements in PLY files

See merge request !121
This commit is contained in:
Jan Möbius
2017-02-09 10:23:39 +01:00
5 changed files with 459 additions and 296 deletions

View File

@@ -309,152 +309,189 @@ bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options
if (err_enabled) if (err_enabled)
omerr().disable(); omerr().disable();
// read vertices: for (std::vector<ElementInfo>::iterator e_it = elements_.begin(); e_it != elements_.end(); ++e_it)
for (i = 0; i < vertexCount_ && !_in.eof(); ++i) { {
vh = _bi.add_vertex(); if (e_it->element_== VERTEX)
{
// read vertices:
for (i = 0; i < e_it->count_ && !_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;
n[0] = 0.0; n[0] = 0.0;
n[1] = 0.0; n[1] = 0.0;
n[2] = 0.0; n[2] = 0.0;
t[0] = 0.0; t[0] = 0.0;
t[1] = 0.0; t[1] = 0.0;
c[0] = 0; c[0] = 0;
c[1] = 0; c[1] = 0;
c[2] = 0; c[2] = 0;
c[3] = 255; c[3] = 255;
for (size_t propertyIndex = 0; propertyIndex < vertexProperties_.size(); ++propertyIndex) { for (size_t propertyIndex = 0; propertyIndex < e_it->properties_.size(); ++propertyIndex) {
switch (vertexProperties_[propertyIndex].property) { PropertyInfo prop = e_it->properties_[propertyIndex];
case XCOORD: switch (prop.property) {
_in >> v[0]; case XCOORD:
break; _in >> v[0];
case YCOORD: break;
_in >> v[1]; case YCOORD:
break; _in >> v[1];
case ZCOORD: break;
_in >> v[2]; case ZCOORD:
break; _in >> v[2];
case XNORM: break;
_in >> n[0]; case XNORM:
break; _in >> n[0];
case YNORM: break;
_in >> n[1]; case YNORM:
break; _in >> n[1];
case ZNORM: break;
_in >> n[2]; case ZNORM:
break; _in >> n[2];
case TEXX: break;
_in >> t[0]; case TEXX:
break; _in >> t[0];
case TEXY: break;
_in >> t[1]; case TEXY:
break; _in >> t[1];
case COLORRED: break;
if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 || case COLORRED:
vertexProperties_[propertyIndex].value == ValueTypeFLOAT) { if (prop.value == ValueTypeFLOAT32 ||
_in >> tmp; prop.value == ValueTypeFLOAT) {
c[0] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f); _in >> tmp;
} else c[0] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
_in >> c[0]; }
break; else
case COLORGREEN: _in >> c[0];
if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 || break;
vertexProperties_[propertyIndex].value == ValueTypeFLOAT) { case COLORGREEN:
_in >> tmp; if (prop.value == ValueTypeFLOAT32 ||
c[1] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f); prop.value == ValueTypeFLOAT) {
} else _in >> tmp;
_in >> c[1]; c[1] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
break; }
case COLORBLUE: else
if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 || _in >> c[1];
vertexProperties_[propertyIndex].value == ValueTypeFLOAT) { break;
_in >> tmp; case COLORBLUE:
c[2] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f); if (prop.value == ValueTypeFLOAT32 ||
} else prop.value == ValueTypeFLOAT) {
_in >> c[2]; _in >> tmp;
break; c[2] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
case COLORALPHA: }
if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 || else
vertexProperties_[propertyIndex].value == ValueTypeFLOAT) { _in >> c[2];
_in >> tmp; break;
c[3] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f); case COLORALPHA:
} else if (prop.value == ValueTypeFLOAT32 ||
_in >> c[3]; prop.value == ValueTypeFLOAT) {
break; _in >> tmp;
case CUSTOM_PROP: c[3] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
if (_opt.check(Options::Custom)) }
readCustomProperty<false>(_in, _bi, vh, vertexProperties_[propertyIndex].name, vertexProperties_[propertyIndex].value, vertexProperties_[propertyIndex].listIndexType); else
else _in >> c[3];
_in >> trash; break;
break; case CUSTOM_PROP:
default: if (_opt.check(Options::Custom))
_in >> trash; readCustomProperty<false>(_in, _bi, vh, prop.name, prop.value, prop.listIndexType);
break; else
} _in >> trash;
} break;
default:
_in >> trash;
break;
}
}
_bi.set_point(vh, 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())
_bi.set_texcoord(vh, t); _bi.set_texcoord(vh, t);
if (_opt.vertex_has_color()) if (_opt.vertex_has_color())
_bi.set_color(vh, Vec4uc(c)); _bi.set_color(vh, Vec4uc(c));
} }
}
else if (e_it->element_ == FACE)
{
// faces
for (i = 0; i < faceCount_ && !_in.eof(); ++i) {
FaceHandle fh;
for (size_t propertyIndex = 0; propertyIndex < e_it->properties_.size(); ++propertyIndex) {
PropertyInfo prop = e_it->properties_[propertyIndex];
switch (prop.property) {
// faces case VERTEX_INDICES:
for (i = 0; i < faceCount_; ++i) { // nV = number of Vertices for current face
FaceHandle fh; _in >> nV;
for (size_t propertyIndex = 0; propertyIndex < faceProperties_.size(); ++propertyIndex) {
PropertyInfo prop = faceProperties_[propertyIndex];
switch (prop.property) {
case VERTEX_INDICES: if (nV == 3) {
// nV = number of Vertices for current face vhandles.resize(3);
_in >> nV; _in >> j;
_in >> k;
_in >> l;
if (nV == 3) { vhandles[0] = VertexHandle(j);
vhandles.resize(3); vhandles[1] = VertexHandle(k);
_in >> j; vhandles[2] = VertexHandle(l);
_in >> k; }
_in >> l; else {
vhandles.clear();
for (j = 0; j < nV; ++j) {
_in >> idx;
vhandles.push_back(VertexHandle(idx));
}
}
vhandles[0] = VertexHandle(j); fh = _bi.add_face(vhandles);
vhandles[1] = VertexHandle(k); if (!fh.is_valid())
vhandles[2] = VertexHandle(l); ++complex_faces;
} else { break;
vhandles.clear();
for (j = 0; j < nV; ++j) {
_in >> idx;
vhandles.push_back(VertexHandle(idx));
}
}
fh = _bi.add_face(vhandles); case CUSTOM_PROP:
if (!fh.is_valid()) if (_opt.check(Options::Custom) && fh.is_valid())
++complex_faces; readCustomProperty<false>(_in, _bi, fh, prop.name, prop.value, prop.listIndexType);
break; else
_in >> trash;
break;
case CUSTOM_PROP: default:
if (_opt.check(Options::Custom) && fh.is_valid()) _in >> trash;
readCustomProperty<false>(_in, _bi, fh, prop.name, prop.value, prop.listIndexType); break;
else }
_in >> trash; }
break;
default: }
_in >> trash; }
break; else
} {
} // other elements
for (i = 0; i < e_it->count_ && !_in.eof(); ++i) {
for (size_t propertyIndex = 0; propertyIndex < e_it->properties_.size(); ++propertyIndex)
{
// just skip the values
_in >> trash;
}
}
}
} if (_in.eof()) {
if (err_enabled)
omerr().enable();
omerr() << "Unexpected end of file while reading." << std::endl;
return false;
}
if(e_it->element_== FACE)
// stop reading after the faces since additional elements are not preserved anyway
break;
}
if (err_enabled) if (err_enabled)
omerr().enable(); omerr().enable();
@@ -482,7 +519,7 @@ bool _PLYReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap
VertexHandle vh; VertexHandle vh;
OpenMesh::Vec4i c; // Color OpenMesh::Vec4i c; // Color
float tmp; float tmp;
_bi.reserve(vertexCount_, 3* vertexCount_ , faceCount_); _bi.reserve(vertexCount_, 3* vertexCount_ , faceCount_);
const bool err_enabled = omerr().is_enabled(); const bool err_enabled = omerr().is_enabled();
@@ -490,162 +527,197 @@ bool _PLYReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap
if (err_enabled) if (err_enabled)
omerr().disable(); omerr().disable();
// read vertices: for (std::vector<ElementInfo>::iterator e_it = elements_.begin(); e_it != elements_.end(); ++e_it)
for (unsigned int i = 0; i < vertexCount_ && !_in.eof(); ++i) { {
vh = _bi.add_vertex(); if (e_it->element_ == VERTEX)
{
// read vertices:
for (unsigned int i = 0; i < e_it->count_ && !_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;
n[0] = 0.0; n[0] = 0.0;
n[1] = 0.0; n[1] = 0.0;
n[2] = 0.0; n[2] = 0.0;
t[0] = 0.0; t[0] = 0.0;
t[1] = 0.0; t[1] = 0.0;
c[0] = 0; c[0] = 0;
c[1] = 0; c[1] = 0;
c[2] = 0; c[2] = 0;
c[3] = 255; c[3] = 255;
for (size_t propertyIndex = 0; propertyIndex < vertexProperties_.size(); ++propertyIndex) { for (size_t propertyIndex = 0; propertyIndex < e_it->properties_.size(); ++propertyIndex) {
switch (vertexProperties_[propertyIndex].property) { PropertyInfo prop = e_it->properties_[propertyIndex];
case XCOORD: switch (prop.property) {
readValue(vertexProperties_[propertyIndex].value, _in, v[0]); case XCOORD:
break; readValue(prop.value, _in, v[0]);
case YCOORD: break;
readValue(vertexProperties_[propertyIndex].value, _in, v[1]); case YCOORD:
break; readValue(prop.value, _in, v[1]);
case ZCOORD: break;
readValue(vertexProperties_[propertyIndex].value, _in, v[2]); case ZCOORD:
break; readValue(prop.value, _in, v[2]);
case XNORM: break;
readValue(vertexProperties_[propertyIndex].value, _in, n[0]); case XNORM:
break; readValue(prop.value, _in, n[0]);
case YNORM: break;
readValue(vertexProperties_[propertyIndex].value, _in, n[1]); case YNORM:
break; readValue(prop.value, _in, n[1]);
case ZNORM: break;
readValue(vertexProperties_[propertyIndex].value, _in, n[2]); case ZNORM:
break; readValue(prop.value, _in, n[2]);
case TEXX: break;
readValue(vertexProperties_[propertyIndex].value, _in, t[0]); case TEXX:
break; readValue(prop.value, _in, t[0]);
case TEXY: break;
readValue(vertexProperties_[propertyIndex].value, _in, t[1]); case TEXY:
break; readValue(prop.value, _in, t[1]);
case COLORRED: break;
if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 || case COLORRED:
vertexProperties_[propertyIndex].value == ValueTypeFLOAT) { if (prop.value == ValueTypeFLOAT32 ||
readValue(vertexProperties_[propertyIndex].value, _in, tmp); prop.value == ValueTypeFLOAT) {
readValue(prop.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 }
readInteger(vertexProperties_[propertyIndex].value, _in, c[0]); else
readInteger(prop.value, _in, c[0]);
break; break;
case COLORGREEN: case COLORGREEN:
if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 || if (prop.value == ValueTypeFLOAT32 ||
vertexProperties_[propertyIndex].value == ValueTypeFLOAT) { prop.value == ValueTypeFLOAT) {
readValue(vertexProperties_[propertyIndex].value, _in, tmp); readValue(prop.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 }
readInteger(vertexProperties_[propertyIndex].value, _in, c[1]); else
readInteger(prop.value, _in, c[1]);
break; break;
case COLORBLUE: case COLORBLUE:
if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 || if (prop.value == ValueTypeFLOAT32 ||
vertexProperties_[propertyIndex].value == ValueTypeFLOAT) { prop.value == ValueTypeFLOAT) {
readValue(vertexProperties_[propertyIndex].value, _in, tmp); readValue(prop.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 }
readInteger(vertexProperties_[propertyIndex].value, _in, c[2]); else
readInteger(prop.value, _in, c[2]);
break; break;
case COLORALPHA: case COLORALPHA:
if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 || if (prop.value == ValueTypeFLOAT32 ||
vertexProperties_[propertyIndex].value == ValueTypeFLOAT) { prop.value == ValueTypeFLOAT) {
readValue(vertexProperties_[propertyIndex].value, _in, tmp); readValue(prop.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 }
readInteger(vertexProperties_[propertyIndex].value, _in, c[3]); else
readInteger(prop.value, _in, c[3]);
break; break;
case CUSTOM_PROP: case CUSTOM_PROP:
if (_opt.check(Options::Custom)) if (_opt.check(Options::Custom))
readCustomProperty<true>(_in, _bi, vh, vertexProperties_[propertyIndex].name, vertexProperties_[propertyIndex].value, vertexProperties_[propertyIndex].listIndexType); readCustomProperty<true>(_in, _bi, vh, prop.name, prop.value, prop.listIndexType);
else else
consume_input(_in, scalar_size_[vertexProperties_[propertyIndex].value]); consume_input(_in, scalar_size_[prop.value]);
break; break;
default: default:
// Read unsupported property // Read unsupported property
consume_input(_in, scalar_size_[vertexProperties_[propertyIndex].value]); consume_input(_in, scalar_size_[prop.value]);
break; break;
} }
} }
_bi.set_point(vh,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())
_bi.set_texcoord(vh, t); _bi.set_texcoord(vh, t);
if (_opt.vertex_has_color()) if (_opt.vertex_has_color())
_bi.set_color(vh, Vec4uc(c)); _bi.set_color(vh, Vec4uc(c));
} }
}
else if (e_it->element_ == FACE) {
for (unsigned i = 0; i < e_it->count_ && !_in.eof(); ++i) {
FaceHandle fh;
for (size_t propertyIndex = 0; propertyIndex < e_it->properties_.size(); ++propertyIndex)
{
PropertyInfo prop = e_it->properties_[propertyIndex];
switch (prop.property) {
for (unsigned i = 0; i < faceCount_; ++i) { case VERTEX_INDICES:
FaceHandle fh; // nV = number of Vertices for current face
for (size_t propertyIndex = 0; propertyIndex < faceProperties_.size(); ++propertyIndex) unsigned int nV;
{ readInteger(prop.listIndexType, _in, nV);
PropertyInfo prop = faceProperties_[propertyIndex];
switch (prop.property) {
case VERTEX_INDICES: if (nV == 3) {
// nV = number of Vertices for current face vhandles.resize(3);
unsigned int nV; unsigned int j, k, l;
readInteger(prop.listIndexType, _in, nV); readInteger(prop.value, _in, j);
readInteger(prop.value, _in, k);
readInteger(prop.value, _in, l);
if (nV == 3) { vhandles[0] = VertexHandle(j);
vhandles.resize(3); vhandles[1] = VertexHandle(k);
unsigned int j,k,l; vhandles[2] = VertexHandle(l);
readInteger(prop.value, _in, j); }
readInteger(prop.value, _in, k); else {
readInteger(prop.value, _in, l); vhandles.clear();
for (unsigned j = 0; j < nV; ++j) {
unsigned int idx;
readInteger(prop.value, _in, idx);
vhandles.push_back(VertexHandle(idx));
}
}
vhandles[0] = VertexHandle(j); fh = _bi.add_face(vhandles);
vhandles[1] = VertexHandle(k); if (!fh.is_valid())
vhandles[2] = VertexHandle(l); ++complex_faces;
} else { break;
vhandles.clear();
for (unsigned j = 0; j < nV; ++j) {
unsigned int idx;
readInteger(prop.value, _in, idx);
vhandles.push_back(VertexHandle(idx));
}
}
fh = _bi.add_face(vhandles); case CUSTOM_PROP:
if (!fh.is_valid()) if (_opt.check(Options::Custom) && fh.is_valid())
++complex_faces; readCustomProperty<true>(_in, _bi, fh, prop.name, prop.value, prop.listIndexType);
break; else
consume_input(_in, scalar_size_[prop.value]);
break;
case CUSTOM_PROP: default:
if (_opt.check(Options::Custom) && fh.is_valid()) consume_input(_in, scalar_size_[prop.value]);
readCustomProperty<true>(_in, _bi, fh, prop.name, prop.value, prop.listIndexType); break;
else }
consume_input(_in, scalar_size_[faceProperties_[propertyIndex].value]); }
break; }
}
else {
for (unsigned int i = 0; i < e_it->count_ && !_in.eof(); ++i)
{
for (size_t propertyIndex = 0; propertyIndex < e_it->properties_.size(); ++propertyIndex)
{
PropertyInfo prop = e_it->properties_[propertyIndex];
// skip element values
consume_input(_in, scalar_size_[prop.value]);
}
}
}
default: if (_in.eof()) {
consume_input(_in, scalar_size_[faceProperties_[propertyIndex].value]); if (err_enabled)
break; omerr().enable();
}
}
}
omerr() << "Unexpected end of file while reading." << std::endl;
return false;
}
if (e_it->element_ == FACE)
// stop reading after the faces since additional elements are not preserved anyway
break;
}
if (err_enabled) if (err_enabled)
omerr().enable(); omerr().enable();
@@ -1067,9 +1139,8 @@ bool _PLYReader_::can_u_read(std::istream& _is) const {
// Clear per file options // Clear per file options
options_.cleanup(); options_.cleanup();
// clear property maps, will be recreated // clear element list
vertexProperties_.clear(); elements_.clear();
faceProperties_.clear();
// read 1st line // read 1st line
std::string line; std::string line;
@@ -1088,6 +1159,8 @@ bool _PLYReader_::can_u_read(std::istream& _is) const {
faceCount_ = 0; faceCount_ = 0;
vertexDimension_ = 0; vertexDimension_ = 0;
unsigned int elementCount = 0;
std::string keyword; std::string keyword;
std::string fileType; std::string fileType;
std::string elementName = ""; std::string elementName = "";
@@ -1132,13 +1205,24 @@ bool _PLYReader_::can_u_read(std::istream& _is) const {
std::getline(_is, line); std::getline(_is, line);
} else if (keyword == "element") { } else if (keyword == "element") {
_is >> elementName; _is >> elementName;
_is >> elementCount;
ElementInfo element;
element.name_ = elementName;
element.count_ = elementCount;
if (elementName == "vertex") { if (elementName == "vertex") {
_is >> vertexCount_; vertexCount_ = elementCount;
element.element_ = VERTEX;
} else if (elementName == "face") { } else if (elementName == "face") {
_is >> faceCount_; faceCount_ = elementCount;
element.element_ = FACE;
} else { } else {
omerr() << "PLY header unsupported element type: " << elementName << std::endl; omerr() << "PLY header unsupported element type: " << elementName << std::endl;
element.element_ = UNKNOWN;
} }
elements_.push_back(element);
} else if (keyword == "property") { } else if (keyword == "property") {
std::string tmp1; std::string tmp1;
std::string tmp2; std::string tmp2;
@@ -1174,29 +1258,26 @@ bool _PLYReader_::can_u_read(std::istream& _is) const {
PropertyInfo property(CUSTOM_PROP, entryType, propertyName); PropertyInfo property(CUSTOM_PROP, entryType, propertyName);
property.listIndexType = indexType; property.listIndexType = indexType;
// just 2 elements supported by now if (elementName == "face")
if (elementName == "vertex")
{
vertexProperties_.push_back(property);
}
else if (elementName == "face")
{ {
// special case for vertex indices // special case for vertex indices
if (propertyName == "vertex_index" || propertyName == "vertex_indices") if (propertyName == "vertex_index" || propertyName == "vertex_indices")
{ {
property.property = VERTEX_INDICES; property.property = VERTEX_INDICES;
if (!faceProperties_.empty())
{ if (!elements_.back().properties_.empty())
omerr() << "Custom face Properties defined, before 'vertex_indices' property was defined. They will be skipped" << std::endl; {
faceProperties_.clear(); omerr() << "Custom face Properties defined, before 'vertex_indices' property was defined. They will be skipped" << std::endl;
} elements_.back().properties_.clear();
}
} }
faceProperties_.push_back(property);
} }
else else
omerr() << "property " << propertyName << " belongs to unsupported element " << elementName << std::endl; omerr() << "property " << propertyName << " belongs to unsupported element " << elementName << std::endl;
elements_.back().properties_.push_back(property);
} else { } else {
// as this is not a list property, read second value of property // as this is not a list property, read second value of property
_is >> tmp2; _is >> tmp2;
@@ -1283,14 +1364,8 @@ bool _PLYReader_::can_u_read(std::istream& _is) const {
if (entry.property != UNSUPPORTED) if (entry.property != UNSUPPORTED)
{ {
if (elementName == "vertex") elements_.back().properties_.push_back(entry);
vertexProperties_.push_back(entry);
else if (elementName == "face")
faceProperties_.push_back(entry);
else
omerr() << "Properties not supported in element " << elementName << std::endl;
} }
} }
} else { } else {

View File

@@ -165,7 +165,6 @@ private:
mutable unsigned int vertexCount_; mutable unsigned int vertexCount_;
mutable unsigned int faceCount_; mutable unsigned int faceCount_;
mutable ValueType vertexType_;
mutable uint vertexDimension_; mutable uint vertexDimension_;
enum Property { enum Property {
@@ -190,8 +189,23 @@ private:
PropertyInfo(Property _p, ValueType _v):property(_p),value(_v),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){} PropertyInfo(Property _p, ValueType _v, const std::string& _n):property(_p),value(_v),name(_n),listIndexType(Unsupported){}
}; };
mutable std::vector< PropertyInfo > vertexProperties_;
mutable std::vector< PropertyInfo > faceProperties_; enum Element {
VERTEX,
FACE,
UNKNOWN
};
// Information on the elements
struct ElementInfo
{
Element element_;
std::string name_;
unsigned int count_;
std::vector< PropertyInfo > properties_;
};
mutable std::vector< ElementInfo > elements_;
template<typename T> template<typename T>
inline void read(_PLYReader_::ValueType _type, std::istream& _in, T& _value, OpenMesh::GenProg::TrueType /*_binary*/) const inline void read(_PLYReader_::ValueType _type, std::istream& _in, T& _value, OpenMesh::GenProg::TrueType /*_binary*/) const

View File

@@ -0,0 +1,38 @@
ply
format ascii 1.0
element vertex 8
property float32 x
property float32 y
property float32 z
element edge 12
property int32 vertex1
property int32 vertex2
element face 6
property list uint8 int32 vertex_indices
end_header
-1 -1 -1
1 -1 -1
1 1 -1
-1 1 -1
-1 -1 1
1 -1 1
1 1 1
-1 1 1
0 1
1 2
2 3
3 0
4 5
5 6
6 7
7 4
6 2
1 5
3 7
4 0
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

View File

@@ -691,5 +691,41 @@ TEST_F(OpenMeshReadWritePLY, WriteReadBinaryPLYWithCustomProps) {
//remove(outFilename); //remove(outFilename);
}
/*
* Just load a ply with extra elements
*/
TEST_F(OpenMeshReadWritePLY, LoadSimplePLYWithExtraElements) {
mesh_.clear();
bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-extra-elements.ply");
EXPECT_TRUE(ok) << "Unable to load cube-minimal-extra-elements.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!";
}
/*
* Just load a binary ply with extra elements
*/
TEST_F(OpenMeshReadWritePLY, LoadSimpleBinaryPLYWithExtraElements) {
mesh_.clear();
OpenMesh::IO::Options options = OpenMesh::IO::Options::Binary;
bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-extra-elements-binary.ply", options);
EXPECT_TRUE(ok) << "Unable to load cube-minimal-extra-elements-binary.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!";
} }
} }