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
This commit is contained in:
@@ -175,49 +175,92 @@ bool _PLYReader_::read(std::istream& _in, BaseImporter& _bi, Options& _opt) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T, typename Handle>
|
||||||
|
struct Handle2Prop;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void assignCustomProperty(std::istream& _in, BaseImporter& _bi, VertexHandle _vh, const std::string& _propName)
|
struct Handle2Prop<T,VertexHandle>
|
||||||
{
|
{
|
||||||
OpenMesh::VPropHandleT<T> prop;
|
typedef OpenMesh::VPropHandleT<T> PropT;
|
||||||
if (!_bi.kernel()->get_property_handle(prop,_propName))
|
};
|
||||||
_bi.kernel()->add_property(prop,_propName);
|
|
||||||
T in;
|
template<typename T>
|
||||||
_in >> in;
|
struct Handle2Prop<T,FaceHandle>
|
||||||
_bi.kernel()->property(prop,_vh) = in;
|
{
|
||||||
|
typedef OpenMesh::FPropHandleT<T> PropT;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T, typename Handle>
|
||||||
|
void assignCustomProperty(std::istream& _in, BaseImporter& _bi, Handle _h, const std::string& _propName, bool isList)
|
||||||
|
{
|
||||||
|
if (!isList)
|
||||||
|
{
|
||||||
|
//get/add property
|
||||||
|
typename Handle2Prop<T,Handle>::PropT prop;
|
||||||
|
if (!_bi.kernel()->get_property_handle(prop,_propName))
|
||||||
|
_bi.kernel()->add_property(prop,_propName);
|
||||||
|
|
||||||
|
//read and assign
|
||||||
|
T in;
|
||||||
|
_in >> in;
|
||||||
|
_bi.kernel()->property(prop,_h) = in;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//get/add property
|
||||||
|
typename Handle2Prop<std::vector<T>,Handle>::PropT prop;
|
||||||
|
if (!_bi.kernel()->get_property_handle(prop,_propName))
|
||||||
|
_bi.kernel()->add_property(prop,_propName);
|
||||||
|
|
||||||
|
//init vector
|
||||||
|
int numberOfValues;
|
||||||
|
_in >> numberOfValues;
|
||||||
|
std::vector<T> vec;
|
||||||
|
vec.reserve(numberOfValues);
|
||||||
|
//read and assign
|
||||||
|
for (int i = 0; i < numberOfValues; ++i)
|
||||||
|
{
|
||||||
|
T in;
|
||||||
|
_in >> in;
|
||||||
|
vec.push_back(in);
|
||||||
|
}
|
||||||
|
_bi.kernel()->property(prop,_h) = vec;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Handle>
|
||||||
void _PLYReader_::readCustomProperty(std::istream& _in, BaseImporter& _bi, VertexHandle _vh, const std::string& _propName, const ValueType _valueType) const
|
void _PLYReader_::readCustomProperty(std::istream& _in, BaseImporter& _bi, Handle _h, const std::string& _propName, const ValueType _valueType, const ValueType _listIndexType) const
|
||||||
{
|
{
|
||||||
|
const bool isList = _listIndexType != Unsupported;
|
||||||
switch (_valueType)
|
switch (_valueType)
|
||||||
{
|
{
|
||||||
case ValueTypeINT8:
|
case ValueTypeINT8:
|
||||||
case ValueTypeCHAR:
|
case ValueTypeCHAR:
|
||||||
assignCustomProperty<char>(_in,_bi,_vh,_propName);
|
assignCustomProperty<char>(_in,_bi,_h,_propName,isList);
|
||||||
break;
|
break;
|
||||||
case ValueTypeINT16:
|
case ValueTypeINT16:
|
||||||
case ValueTypeSHORT:
|
case ValueTypeSHORT:
|
||||||
assignCustomProperty<short>(_in,_bi,_vh,_propName);
|
assignCustomProperty<short>(_in,_bi,_h,_propName,isList);
|
||||||
break;
|
break;
|
||||||
case ValueTypeUINT16:
|
case ValueTypeUINT16:
|
||||||
case ValueTypeUSHORT:
|
case ValueTypeUSHORT:
|
||||||
assignCustomProperty<unsigned short>(_in,_bi,_vh,_propName);
|
assignCustomProperty<unsigned short>(_in,_bi,_h,_propName,isList);
|
||||||
break;
|
break;
|
||||||
case ValueTypeINT32:
|
case ValueTypeINT32:
|
||||||
case ValueTypeINT:
|
case ValueTypeINT:
|
||||||
assignCustomProperty<int>(_in,_bi,_vh,_propName);
|
assignCustomProperty<int>(_in,_bi,_h,_propName,isList);
|
||||||
break;
|
break;
|
||||||
case ValueTypeUINT32:
|
case ValueTypeUINT32:
|
||||||
case ValueTypeUINT:
|
case ValueTypeUINT:
|
||||||
assignCustomProperty<unsigned int>(_in,_bi,_vh,_propName);
|
assignCustomProperty<unsigned int>(_in,_bi,_h,_propName,isList);
|
||||||
break;
|
break;
|
||||||
case ValueTypeFLOAT32:
|
case ValueTypeFLOAT32:
|
||||||
case ValueTypeFLOAT:
|
case ValueTypeFLOAT:
|
||||||
assignCustomProperty<float>(_in,_bi,_vh,_propName);
|
assignCustomProperty<float>(_in,_bi,_h,_propName,isList);
|
||||||
break;
|
break;
|
||||||
case ValueTypeFLOAT64:
|
case ValueTypeFLOAT64:
|
||||||
case ValueTypeDOUBLE:
|
case ValueTypeDOUBLE:
|
||||||
assignCustomProperty<double>(_in,_bi,_vh,_propName);
|
assignCustomProperty<double>(_in,_bi,_h,_propName,isList);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
std::cerr << "unsupported type" << std::endl;
|
std::cerr << "unsupported type" << std::endl;
|
||||||
@@ -273,8 +316,8 @@ bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options
|
|||||||
c[2] = 0;
|
c[2] = 0;
|
||||||
c[3] = 255;
|
c[3] = 255;
|
||||||
|
|
||||||
for (uint propertyIndex = 0; propertyIndex < vertexPropertyCount_; ++propertyIndex) {
|
for (size_t propertyIndex = 0; propertyIndex < vertexProperties_.size(); ++propertyIndex) {
|
||||||
switch (vertexPropertyMap_[propertyIndex].property) {
|
switch (vertexProperties_[propertyIndex].property) {
|
||||||
case XCOORD:
|
case XCOORD:
|
||||||
_in >> v[0];
|
_in >> v[0];
|
||||||
break;
|
break;
|
||||||
@@ -300,32 +343,32 @@ 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].value == ValueTypeFLOAT32 ||
|
if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 ||
|
||||||
vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT) {
|
vertexProperties_[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].value == ValueTypeFLOAT32 ||
|
if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 ||
|
||||||
vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT) {
|
vertexProperties_[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].value == ValueTypeFLOAT32 ||
|
if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 ||
|
||||||
vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT) {
|
vertexProperties_[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].value == ValueTypeFLOAT32 ||
|
if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 ||
|
||||||
vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT) {
|
vertexProperties_[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
|
||||||
@@ -333,7 +376,7 @@ bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options
|
|||||||
break;
|
break;
|
||||||
case CUSTOM_PROP:
|
case CUSTOM_PROP:
|
||||||
if (_opt.check(Options::Custom))
|
if (_opt.check(Options::Custom))
|
||||||
readCustomProperty(_in, _bi, vh, vertexPropertyMap_[propertyIndex].name, vertexPropertyMap_[propertyIndex].value);
|
readCustomProperty(_in, _bi, vh, vertexProperties_[propertyIndex].name, vertexProperties_[propertyIndex].value, vertexProperties_[propertyIndex].listIndexType);
|
||||||
else
|
else
|
||||||
_in >> trash;
|
_in >> trash;
|
||||||
break;
|
break;
|
||||||
@@ -353,12 +396,17 @@ bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options
|
|||||||
}
|
}
|
||||||
|
|
||||||
// faces
|
// faces
|
||||||
// #N <v1> <v2> .. <v(n-1)> [color spec]
|
|
||||||
for (i = 0; i < faceCount_; ++i) {
|
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) {
|
||||||
|
|
||||||
if (nV == 3) {
|
case VERTEX_INDICES:
|
||||||
|
// nV = number of Vertices for current face
|
||||||
|
_in >> nV;
|
||||||
|
|
||||||
|
if (nV == 3) {
|
||||||
vhandles.resize(3);
|
vhandles.resize(3);
|
||||||
_in >> j;
|
_in >> j;
|
||||||
_in >> k;
|
_in >> k;
|
||||||
@@ -367,15 +415,29 @@ bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options
|
|||||||
vhandles[0] = VertexHandle(j);
|
vhandles[0] = VertexHandle(j);
|
||||||
vhandles[1] = VertexHandle(k);
|
vhandles[1] = VertexHandle(k);
|
||||||
vhandles[2] = VertexHandle(l);
|
vhandles[2] = VertexHandle(l);
|
||||||
} else {
|
} else {
|
||||||
vhandles.clear();
|
vhandles.clear();
|
||||||
for (j = 0; j < nV; ++j) {
|
for (j = 0; j < nV; ++j) {
|
||||||
_in >> idx;
|
_in >> idx;
|
||||||
vhandles.push_back(VertexHandle(idx));
|
vhandles.push_back(VertexHandle(idx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_bi.add_face(vhandles);
|
fh = _bi.add_face(vhandles);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CUSTOM_PROP:
|
||||||
|
if (_opt.check(Options::Custom) && fh.is_valid())
|
||||||
|
readCustomProperty(_in, _bi, fh, prop.name, prop.value, prop.listIndexType);
|
||||||
|
else
|
||||||
|
_in >> trash;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
_in >> trash;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,72 +484,72 @@ bool _PLYReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap
|
|||||||
c[2] = 0;
|
c[2] = 0;
|
||||||
c[3] = 255;
|
c[3] = 255;
|
||||||
|
|
||||||
for (uint propertyIndex = 0; propertyIndex < vertexPropertyCount_; ++propertyIndex) {
|
for (size_t propertyIndex = 0; propertyIndex < vertexProperties_.size(); ++propertyIndex) {
|
||||||
switch (vertexPropertyMap_[propertyIndex].property) {
|
switch (vertexProperties_[propertyIndex].property) {
|
||||||
case XCOORD:
|
case XCOORD:
|
||||||
readValue(vertexPropertyMap_[propertyIndex].value, _in, v[0]);
|
readValue(vertexProperties_[propertyIndex].value, _in, v[0]);
|
||||||
break;
|
break;
|
||||||
case YCOORD:
|
case YCOORD:
|
||||||
readValue(vertexPropertyMap_[propertyIndex].value, _in, v[1]);
|
readValue(vertexProperties_[propertyIndex].value, _in, v[1]);
|
||||||
break;
|
break;
|
||||||
case ZCOORD:
|
case ZCOORD:
|
||||||
readValue(vertexPropertyMap_[propertyIndex].value, _in, v[2]);
|
readValue(vertexProperties_[propertyIndex].value, _in, v[2]);
|
||||||
break;
|
break;
|
||||||
case XNORM:
|
case XNORM:
|
||||||
readValue(vertexPropertyMap_[propertyIndex].value, _in, n[0]);
|
readValue(vertexProperties_[propertyIndex].value, _in, n[0]);
|
||||||
break;
|
break;
|
||||||
case YNORM:
|
case YNORM:
|
||||||
readValue(vertexPropertyMap_[propertyIndex].value, _in, n[1]);
|
readValue(vertexProperties_[propertyIndex].value, _in, n[1]);
|
||||||
break;
|
break;
|
||||||
case ZNORM:
|
case ZNORM:
|
||||||
readValue(vertexPropertyMap_[propertyIndex].value, _in, n[2]);
|
readValue(vertexProperties_[propertyIndex].value, _in, n[2]);
|
||||||
break;
|
break;
|
||||||
case TEXX:
|
case TEXX:
|
||||||
readValue(vertexPropertyMap_[propertyIndex].value, _in, t[0]);
|
readValue(vertexProperties_[propertyIndex].value, _in, t[0]);
|
||||||
break;
|
break;
|
||||||
case TEXY:
|
case TEXY:
|
||||||
readValue(vertexPropertyMap_[propertyIndex].value, _in, t[1]);
|
readValue(vertexProperties_[propertyIndex].value, _in, t[1]);
|
||||||
break;
|
break;
|
||||||
case COLORRED:
|
case COLORRED:
|
||||||
if (vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT32 ||
|
if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 ||
|
||||||
vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT) {
|
vertexProperties_[propertyIndex].value == ValueTypeFLOAT) {
|
||||||
readValue(vertexPropertyMap_[propertyIndex].value, _in, tmp);
|
readValue(vertexProperties_[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].value, _in, c[0]);
|
readInteger(vertexProperties_[propertyIndex].value, _in, c[0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case COLORGREEN:
|
case COLORGREEN:
|
||||||
if (vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT32 ||
|
if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 ||
|
||||||
vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT) {
|
vertexProperties_[propertyIndex].value == ValueTypeFLOAT) {
|
||||||
readValue(vertexPropertyMap_[propertyIndex].value, _in, tmp);
|
readValue(vertexProperties_[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].value, _in, c[1]);
|
readInteger(vertexProperties_[propertyIndex].value, _in, c[1]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case COLORBLUE:
|
case COLORBLUE:
|
||||||
if (vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT32 ||
|
if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 ||
|
||||||
vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT) {
|
vertexProperties_[propertyIndex].value == ValueTypeFLOAT) {
|
||||||
readValue(vertexPropertyMap_[propertyIndex].value, _in, tmp);
|
readValue(vertexProperties_[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].value, _in, c[2]);
|
readInteger(vertexProperties_[propertyIndex].value, _in, c[2]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case COLORALPHA:
|
case COLORALPHA:
|
||||||
if (vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT32 ||
|
if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 ||
|
||||||
vertexPropertyMap_[propertyIndex].value == ValueTypeFLOAT) {
|
vertexProperties_[propertyIndex].value == ValueTypeFLOAT) {
|
||||||
readValue(vertexPropertyMap_[propertyIndex].value, _in, tmp);
|
readValue(vertexProperties_[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].value, _in, c[3]);
|
readInteger(vertexProperties_[propertyIndex].value, _in, c[3]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Read unsupported property
|
// Read unsupported property
|
||||||
consume_input(_in, scalar_size_[vertexPropertyMap_[propertyIndex].value]);
|
consume_input(_in, scalar_size_[vertexProperties_[propertyIndex].value]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -502,28 +564,31 @@ bool _PLYReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap
|
|||||||
_bi.set_color(vh, Vec4uc(c));
|
_bi.set_color(vh, Vec4uc(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < faceCount_; ++i) {
|
if(!faceProperties_.empty())
|
||||||
|
{
|
||||||
|
for (i = 0; i < faceCount_; ++i) {
|
||||||
// Read number of vertices for the current face
|
// Read number of vertices for the current face
|
||||||
readValue(faceIndexType_, _in, nV);
|
readValue(faceProperties_[0].listIndexType, _in, nV);
|
||||||
|
|
||||||
if (nV == 3) {
|
if (nV == 3) {
|
||||||
vhandles.resize(3);
|
vhandles.resize(3);
|
||||||
readInteger(faceEntryType_, _in, j);
|
readInteger(faceProperties_[0].value, _in, j);
|
||||||
readInteger(faceEntryType_, _in, k);
|
readInteger(faceProperties_[0].value, _in, k);
|
||||||
readInteger(faceEntryType_, _in, l);
|
readInteger(faceProperties_[0].value, _in, l);
|
||||||
|
|
||||||
vhandles[0] = VertexHandle(j);
|
vhandles[0] = VertexHandle(j);
|
||||||
vhandles[1] = VertexHandle(k);
|
vhandles[1] = VertexHandle(k);
|
||||||
vhandles[2] = VertexHandle(l);
|
vhandles[2] = VertexHandle(l);
|
||||||
} else {
|
} else {
|
||||||
vhandles.clear();
|
vhandles.clear();
|
||||||
for (j = 0; j < nV; ++j) {
|
for (j = 0; j < nV; ++j) {
|
||||||
readInteger(faceEntryType_, _in, idx);
|
readInteger(faceProperties_[0].value, _in, idx);
|
||||||
vhandles.push_back(VertexHandle(idx));
|
vhandles.push_back(VertexHandle(idx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_bi.add_face(vhandles);
|
_bi.add_face(vhandles);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -909,9 +974,9 @@ bool _PLYReader_::can_u_read(std::istream& _is) const {
|
|||||||
// Clear per file options
|
// Clear per file options
|
||||||
options_.cleanup();
|
options_.cleanup();
|
||||||
|
|
||||||
// clear vertex property map, will be recreated
|
// clear property maps, will be recreated
|
||||||
vertexPropertyMap_.clear();
|
vertexProperties_.clear();
|
||||||
vertexPropertyCount_ = 0;
|
faceProperties_.clear();
|
||||||
|
|
||||||
// read 1st line
|
// read 1st line
|
||||||
std::string line;
|
std::string line;
|
||||||
@@ -985,134 +1050,157 @@ bool _PLYReader_::can_u_read(std::istream& _is) const {
|
|||||||
_is >> tmp1;
|
_is >> tmp1;
|
||||||
|
|
||||||
if (tmp1 == "list") {
|
if (tmp1 == "list") {
|
||||||
if (elementName == "vertex") {
|
_is >> listIndexType;
|
||||||
omerr() << "List type not supported for vertices!" << std::endl;
|
_is >> listEntryType;
|
||||||
} else if (elementName == "face") {
|
_is >> propertyName;
|
||||||
_is >> listIndexType;
|
|
||||||
_is >> listEntryType;
|
|
||||||
_is >> propertyName;
|
|
||||||
|
|
||||||
if (listIndexType == "uint8") {
|
ValueType indexType = Unsupported;
|
||||||
faceIndexType_ = ValueTypeUINT8;
|
ValueType entryType = Unsupported;
|
||||||
} else if (listIndexType == "uchar") {
|
|
||||||
faceIndexType_ = ValueTypeUCHAR;
|
|
||||||
} else {
|
|
||||||
omerr() << "Unsupported Index type for face list: " << listIndexType << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listEntryType == "int32") {
|
if (listIndexType == "uint8") {
|
||||||
faceEntryType_ = ValueTypeINT32;
|
indexType = ValueTypeUINT8;
|
||||||
} else if (listEntryType == "int") {
|
} else if (listIndexType == "uchar") {
|
||||||
faceEntryType_ = ValueTypeINT;
|
indexType = ValueTypeUCHAR;
|
||||||
} else if (listEntryType == "uint32") {
|
} else {
|
||||||
faceEntryType_ = ValueTypeUINT32;
|
omerr() << "Unsupported Index type for property list: " << listIndexType << std::endl;
|
||||||
} else if (listEntryType == "uint") {
|
continue;
|
||||||
faceEntryType_ = ValueTypeUINT;
|
}
|
||||||
} else {
|
|
||||||
omerr() << "Unsupported Entry type for face list: " << listEntryType << std::endl;
|
entryType = get_property_type(listEntryType, listEntryType);
|
||||||
return false;
|
|
||||||
|
if (entryType == Unsupported) {
|
||||||
|
omerr() << "Unsupported Entry type for property list: " << listEntryType << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyInfo property(CUSTOM_PROP, entryType, propertyName);
|
||||||
|
property.listIndexType = indexType;
|
||||||
|
|
||||||
|
// just 2 elements supported by now
|
||||||
|
if (elementName == "vertex" && !options_.is_binary())
|
||||||
|
{
|
||||||
|
vertexProperties_.push_back(property);
|
||||||
|
}
|
||||||
|
else if (elementName == "face")
|
||||||
|
{
|
||||||
|
// special case for vertex indices, also needed by the binary version
|
||||||
|
if (propertyName == "vertex_index" || propertyName == "vertex_indices")
|
||||||
|
{
|
||||||
|
property.property = VERTEX_INDICES;
|
||||||
|
if (!faceProperties_.empty())
|
||||||
|
{
|
||||||
|
omerr() << "Custom face Properties defined, before 'vertex_indices' property was defined. They will be skipped" << std::endl;
|
||||||
|
faceProperties_.clear();
|
||||||
}
|
}
|
||||||
|
faceProperties_.push_back(property);
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
if (!options_.is_binary())
|
||||||
|
faceProperties_.push_back(property);
|
||||||
|
else
|
||||||
|
omerr() << "Custom list properties per face not supported with binary files" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
omerr() << "property " << propertyName << " belongs to unsupported element " << elementName << std::endl;
|
||||||
|
|
||||||
} 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;
|
||||||
|
|
||||||
if (elementName == "vertex") {
|
|
||||||
// Extract name and type of property
|
|
||||||
// As the order seems to be different in some files, autodetect it.
|
|
||||||
ValueType valueType = get_property_type(tmp1, tmp2);
|
|
||||||
propertyName = get_property_name(tmp1, tmp2);
|
|
||||||
|
|
||||||
if (propertyName == "x") {
|
// Extract name and type of property
|
||||||
VertexPropertyInfo entry(XCOORD, valueType);
|
// As the order seems to be different in some files, autodetect it.
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
ValueType valueType = get_property_type(tmp1, tmp2);
|
||||||
vertexDimension_++;
|
propertyName = get_property_name(tmp1, tmp2);
|
||||||
} else if (propertyName == "y") {
|
|
||||||
VertexPropertyInfo entry(YCOORD, valueType);
|
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
|
||||||
vertexDimension_++;
|
|
||||||
} else if (propertyName == "z") {
|
|
||||||
VertexPropertyInfo entry(ZCOORD, valueType);
|
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
|
||||||
vertexDimension_++;
|
|
||||||
} else if (propertyName == "nx") {
|
|
||||||
VertexPropertyInfo entry(XNORM, valueType);
|
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
|
||||||
options_ += Options::VertexNormal;
|
|
||||||
} else if (propertyName == "ny") {
|
|
||||||
VertexPropertyInfo entry(YNORM, valueType);
|
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
|
||||||
options_ += Options::VertexNormal;
|
|
||||||
} else if (propertyName == "nz") {
|
|
||||||
VertexPropertyInfo entry(ZNORM, valueType);
|
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
|
||||||
options_ += Options::VertexNormal;
|
|
||||||
} else if (propertyName == "u" || propertyName == "s") {
|
|
||||||
VertexPropertyInfo entry(TEXX, valueType);
|
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
|
||||||
options_ += Options::VertexTexCoord;
|
|
||||||
} else if (propertyName == "v" || propertyName == "t") {
|
|
||||||
VertexPropertyInfo entry(TEXY, valueType);
|
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
|
||||||
options_ += Options::VertexTexCoord;
|
|
||||||
} else if (propertyName == "red") {
|
|
||||||
VertexPropertyInfo entry(COLORRED, valueType);
|
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
|
||||||
options_ += Options::VertexColor;
|
|
||||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
|
||||||
options_ += Options::ColorFloat;
|
|
||||||
} else if (propertyName == "green") {
|
|
||||||
VertexPropertyInfo entry(COLORGREEN, valueType);
|
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
|
||||||
options_ += Options::VertexColor;
|
|
||||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
|
||||||
options_ += Options::ColorFloat;
|
|
||||||
} else if (propertyName == "blue") {
|
|
||||||
VertexPropertyInfo entry(COLORBLUE, valueType);
|
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
|
||||||
options_ += Options::VertexColor;
|
|
||||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
|
||||||
options_ += Options::ColorFloat;
|
|
||||||
} else if (propertyName == "diffuse_red") {
|
|
||||||
VertexPropertyInfo entry(COLORRED, valueType);
|
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
|
||||||
options_ += Options::VertexColor;
|
|
||||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
|
||||||
options_ += Options::ColorFloat;
|
|
||||||
} else if (propertyName == "diffuse_green") {
|
|
||||||
VertexPropertyInfo entry(COLORGREEN, valueType);
|
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
|
||||||
options_ += Options::VertexColor;
|
|
||||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
|
||||||
options_ += Options::ColorFloat;
|
|
||||||
} else if (propertyName == "diffuse_blue") {
|
|
||||||
VertexPropertyInfo entry(COLORBLUE, valueType);
|
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
|
||||||
options_ += Options::VertexColor;
|
|
||||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
|
||||||
options_ += Options::ColorFloat;
|
|
||||||
} else if (propertyName == "alpha") {
|
|
||||||
VertexPropertyInfo entry(COLORALPHA, valueType);
|
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
|
||||||
options_ += Options::VertexColor;
|
|
||||||
options_ += Options::ColorAlpha;
|
|
||||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
|
||||||
options_ += Options::ColorFloat;
|
|
||||||
} else {
|
|
||||||
VertexProperty prop = (!options_.is_binary()) ? CUSTOM_PROP : UNSUPPORTED; // loading vertex properties is not yet supported by the binary loader
|
|
||||||
if (prop != UNSUPPORTED)
|
|
||||||
options_ += Options::Custom;
|
|
||||||
VertexPropertyInfo entry(prop, valueType, propertyName);
|
|
||||||
vertexPropertyMap_[vertexPropertyCount_] = entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
vertexPropertyCount_++;
|
PropertyInfo entry;
|
||||||
|
|
||||||
} else if (elementName == "face") {
|
//special treatment for some vertex properties.
|
||||||
omerr() << "Properties not supported for faces " << std::endl;
|
if (elementName == "vertex") {
|
||||||
|
if (propertyName == "x") {
|
||||||
|
entry = PropertyInfo(XCOORD, valueType);
|
||||||
|
vertexDimension_++;
|
||||||
|
} else if (propertyName == "y") {
|
||||||
|
entry = PropertyInfo(YCOORD, valueType);
|
||||||
|
vertexDimension_++;
|
||||||
|
} else if (propertyName == "z") {
|
||||||
|
entry = PropertyInfo(ZCOORD, valueType);
|
||||||
|
vertexDimension_++;
|
||||||
|
} else if (propertyName == "nx") {
|
||||||
|
entry = PropertyInfo(XNORM, valueType);
|
||||||
|
options_ += Options::VertexNormal;
|
||||||
|
} else if (propertyName == "ny") {
|
||||||
|
entry = PropertyInfo(YNORM, valueType);
|
||||||
|
options_ += Options::VertexNormal;
|
||||||
|
} else if (propertyName == "nz") {
|
||||||
|
entry = PropertyInfo(ZNORM, valueType);
|
||||||
|
options_ += Options::VertexNormal;
|
||||||
|
} else if (propertyName == "u" || propertyName == "s") {
|
||||||
|
entry = PropertyInfo(TEXX, valueType);
|
||||||
|
options_ += Options::VertexTexCoord;
|
||||||
|
} else if (propertyName == "v" || propertyName == "t") {
|
||||||
|
entry = PropertyInfo(TEXY, valueType);
|
||||||
|
options_ += Options::VertexTexCoord;
|
||||||
|
} else if (propertyName == "red") {
|
||||||
|
entry = PropertyInfo(COLORRED, valueType);
|
||||||
|
options_ += Options::VertexColor;
|
||||||
|
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||||
|
options_ += Options::ColorFloat;
|
||||||
|
} else if (propertyName == "green") {
|
||||||
|
entry = PropertyInfo(COLORGREEN, valueType);
|
||||||
|
options_ += Options::VertexColor;
|
||||||
|
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||||
|
options_ += Options::ColorFloat;
|
||||||
|
} else if (propertyName == "blue") {
|
||||||
|
entry = PropertyInfo(COLORBLUE, valueType);
|
||||||
|
options_ += Options::VertexColor;
|
||||||
|
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||||
|
options_ += Options::ColorFloat;
|
||||||
|
} else if (propertyName == "diffuse_red") {
|
||||||
|
entry = PropertyInfo(COLORRED, valueType);
|
||||||
|
options_ += Options::VertexColor;
|
||||||
|
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||||
|
options_ += Options::ColorFloat;
|
||||||
|
} else if (propertyName == "diffuse_green") {
|
||||||
|
entry = PropertyInfo(COLORGREEN, valueType);
|
||||||
|
options_ += Options::VertexColor;
|
||||||
|
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||||
|
options_ += Options::ColorFloat;
|
||||||
|
} else if (propertyName == "diffuse_blue") {
|
||||||
|
entry = PropertyInfo(COLORBLUE, valueType);
|
||||||
|
options_ += Options::VertexColor;
|
||||||
|
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||||
|
options_ += Options::ColorFloat;
|
||||||
|
} else if (propertyName == "alpha") {
|
||||||
|
entry = PropertyInfo(COLORALPHA, valueType);
|
||||||
|
options_ += Options::VertexColor;
|
||||||
|
options_ += Options::ColorAlpha;
|
||||||
|
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||||
|
options_ += Options::ColorFloat;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//not a special property, load as custom
|
||||||
|
if (entry.value == Unsupported){
|
||||||
|
Property prop = (!options_.is_binary()) ? CUSTOM_PROP : UNSUPPORTED; // loading vertex properties is not yet supported by the binary loader
|
||||||
|
if (prop != UNSUPPORTED)
|
||||||
|
options_ += Options::Custom;
|
||||||
|
else
|
||||||
|
omerr() << "Custom Properties not supported in binary files. Skipping" << std::endl;
|
||||||
|
PropertyInfo entry(prop, valueType, propertyName);
|
||||||
|
vertexProperties_.push_back(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry.property != UNSUPPORTED)
|
||||||
|
{
|
||||||
|
if (elementName == "vertex")
|
||||||
|
vertexProperties_.push_back(entry);
|
||||||
|
else if (elementName == "face")
|
||||||
|
faceProperties_.push_back(entry);
|
||||||
|
else
|
||||||
|
omerr() << "Properties not supported in element " << elementName << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <OpenMesh/Core/System/config.h>
|
#include <OpenMesh/Core/System/config.h>
|
||||||
#include <OpenMesh/Core/Utils/SingletonT.hh>
|
#include <OpenMesh/Core/Utils/SingletonT.hh>
|
||||||
@@ -92,7 +93,8 @@ class BaseImporter;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
Implementation of the PLY format reader. This class is singleton'ed by
|
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;
|
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;
|
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, float& _value) const;
|
||||||
void readValue(ValueType _type, std::istream& _in, double& _value) const;
|
void readValue(ValueType _type, std::istream& _in, double& _value) const;
|
||||||
@@ -165,14 +168,11 @@ private:
|
|||||||
mutable ValueType vertexType_;
|
mutable ValueType vertexType_;
|
||||||
mutable uint vertexDimension_;
|
mutable uint vertexDimension_;
|
||||||
|
|
||||||
mutable ValueType faceIndexType_;
|
enum Property {
|
||||||
mutable ValueType faceEntryType_;
|
|
||||||
|
|
||||||
enum VertexProperty {
|
|
||||||
XCOORD,YCOORD,ZCOORD,
|
XCOORD,YCOORD,ZCOORD,
|
||||||
TEXX,TEXY,
|
TEXX,TEXY,
|
||||||
COLORRED,COLORGREEN,COLORBLUE,COLORALPHA,
|
COLORRED,COLORGREEN,COLORBLUE,COLORALPHA,
|
||||||
XNORM,YNORM,ZNORM, CUSTOM_PROP,
|
XNORM,YNORM,ZNORM, CUSTOM_PROP, VERTEX_INDICES,
|
||||||
UNSUPPORTED
|
UNSUPPORTED
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -180,17 +180,18 @@ private:
|
|||||||
mutable std::map<ValueType, int> scalar_size_;
|
mutable std::map<ValueType, int> scalar_size_;
|
||||||
|
|
||||||
// Number of vertex properties
|
// Number of vertex properties
|
||||||
mutable unsigned int vertexPropertyCount_;
|
struct PropertyInfo
|
||||||
struct VertexPropertyInfo
|
|
||||||
{
|
{
|
||||||
VertexProperty property;
|
Property property;
|
||||||
ValueType value;
|
ValueType value;
|
||||||
std::string name;//for custom properties
|
std::string name;//for custom properties
|
||||||
VertexPropertyInfo():property(UNSUPPORTED),value(Unsupported),name(""){}
|
ValueType listIndexType;//if type is unsupported, the poerty is not a list. otherwise, it the index type
|
||||||
VertexPropertyInfo(VertexProperty _p, ValueType _v):property(_p),value(_v),name(""){}
|
PropertyInfo():property(UNSUPPORTED),value(Unsupported),name(""),listIndexType(Unsupported){}
|
||||||
VertexPropertyInfo(VertexProperty _p, ValueType _v, const std::string& _n):property(_p),value(_v),name(_n){}
|
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 nz
|
||||||
property float32 quality
|
property float32 quality
|
||||||
property uint index
|
property uint index
|
||||||
|
property list uint8 int32 test_values
|
||||||
element face 6
|
element face 6
|
||||||
property list uint8 int32 vertex_indices
|
property list uint8 int32 vertex_indices
|
||||||
|
property list uint8 float32 texcoords
|
||||||
end_header
|
end_header
|
||||||
-1 -1 -1 0.0 0.0 1.0 1.0 0
|
-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
|
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
|
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
|
-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
|
-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
|
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
|
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
|
-1 1 1 1.0 1.0 2.0 5.0 7 2 15 16
|
||||||
4 0 1 2 3
|
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
|
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
|
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
|
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
|
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
|
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) {
|
TEST_F(OpenMeshReadWritePLY, LoadSimplePLYWithCustomProps) {
|
||||||
|
|
||||||
mesh_.clear();
|
PolyMesh mesh;
|
||||||
|
|
||||||
OpenMesh::IO::Options options;
|
OpenMesh::IO::Options options;
|
||||||
options += OpenMesh::IO::Options::Custom;
|
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_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(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_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(6u , mesh.n_faces()) << "The number of loaded faces is not correct!";
|
||||||
|
|
||||||
OpenMesh::VPropHandleT<float> qualityProp;
|
OpenMesh::VPropHandleT<float> qualityProp;
|
||||||
OpenMesh::VPropHandleT<unsigned int> indexProp;
|
OpenMesh::VPropHandleT<unsigned int> indexProp;
|
||||||
EXPECT_TRUE(mesh_.get_property_handle(qualityProp,"quality")) << "Could not access quality 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";
|
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
|
//check index property
|
||||||
for (unsigned i = 0; i < mesh_.n_vertices(); ++i)
|
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";
|
EXPECT_EQ(i ,mesh.property(indexProp,OpenMesh::VertexHandle(i))) << "Vertex index at vertex " << i << " is wrong";
|
||||||
|
|
||||||
//check quality property
|
//check quality property
|
||||||
EXPECT_EQ(1.f,mesh_.property(qualityProp,OpenMesh::VertexHandle(0))) << "Wrong quality value at Vertex 0";
|
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.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(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(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.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(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(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(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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user