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:
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
BIN
src/Unittests/TestFiles/cube-minimal-extra-elements-binary.ply
Normal file
BIN
src/Unittests/TestFiles/cube-minimal-extra-elements-binary.ply
Normal file
Binary file not shown.
38
src/Unittests/TestFiles/cube-minimal-extra-elements.ply
Normal file
38
src/Unittests/TestFiles/cube-minimal-extra-elements.ply
Normal 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
|
||||||
@@ -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!";
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user