- added color float support for the OM OFF reader/writer

- added corresponding unittests
- small fix for the PLY writer

Note that for reading binary OFF files with color floats, the user has to set the flag, that floats are expected

closes #1410

git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@818 fdac6126-5c0c-442c-9429-916003d36597
This commit is contained in:
Isaak Lim
2013-03-04 16:36:20 +00:00
parent 57b3908771
commit 837c866abb
8 changed files with 394 additions and 105 deletions

View File

@@ -4,10 +4,10 @@
* Copyright (C) 2001-2012 by Computer Graphics Group, RWTH Aachen * * Copyright (C) 2001-2012 by Computer Graphics Group, RWTH Aachen *
* www.openmesh.org * * www.openmesh.org *
* * * *
*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*
* This file is part of OpenMesh. * * This file is part of OpenMesh. *
* * * *
* OpenMesh is free software: you can redistribute it and/or modify * * OpenMesh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as * * it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of * * published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the * * the License, or (at your option) any later version with the *
@@ -30,10 +30,10 @@
* License along with OpenMesh. If not, * * License along with OpenMesh. If not, *
* see <http://www.gnu.org/licenses/>. * * see <http://www.gnu.org/licenses/>. *
* * * *
\*===========================================================================*/ \*===========================================================================*/
/*===========================================================================*\ /*===========================================================================*\
* * * *
* $Revision$ * * $Revision$ *
* $Date$ * * $Date$ *
* * * *
@@ -108,6 +108,12 @@ public:
// set vertex color // set vertex color
virtual void set_color(VertexHandle _vh, const Vec4uc& _color) = 0; virtual void set_color(VertexHandle _vh, const Vec4uc& _color) = 0;
// set vertex color
virtual void set_color(VertexHandle _vh, const Vec3f& _color) = 0;
// set vertex color
virtual void set_color(VertexHandle _vh, const Vec4f& _color) = 0;
// set vertex texture coordinate // set vertex texture coordinate
virtual void set_texcoord(VertexHandle _vh, const Vec2f& _texcoord) = 0; virtual void set_texcoord(VertexHandle _vh, const Vec2f& _texcoord) = 0;
@@ -116,10 +122,16 @@ public:
// set edge color // set edge color
virtual void set_color(EdgeHandle _eh, const Vec3uc& _color) = 0; virtual void set_color(EdgeHandle _eh, const Vec3uc& _color) = 0;
// set edge color // set edge color
virtual void set_color(EdgeHandle _eh, const Vec4uc& _color) = 0; virtual void set_color(EdgeHandle _eh, const Vec4uc& _color) = 0;
// set edge color
virtual void set_color(EdgeHandle _eh, const Vec3f& _color) = 0;
// set edge color
virtual void set_color(EdgeHandle _eh, const Vec4f& _color) = 0;
// set face normal // set face normal
virtual void set_normal(FaceHandle _fh, const Vec3f& _normal) = 0; virtual void set_normal(FaceHandle _fh, const Vec3f& _normal) = 0;
@@ -129,6 +141,12 @@ public:
// set face color // set face color
virtual void set_color(FaceHandle _fh, const Vec4uc& _color) = 0; virtual void set_color(FaceHandle _fh, const Vec4uc& _color) = 0;
// set face color
virtual void set_color(FaceHandle _fh, const Vec3f& _color) = 0;
// set face color
virtual void set_color(FaceHandle _fh, const Vec4f& _color) = 0;
// Store a property in the mesh mapping from an int to a texture file // Store a property in the mesh mapping from an int to a texture file
// Use set_face_texindex to set the index for each face // Use set_face_texindex to set the index for each face
virtual void add_texture_information( int _id , std::string _name ) = 0; virtual void add_texture_information( int _id , std::string _name ) = 0;

View File

@@ -4,10 +4,10 @@
* Copyright (C) 2001-2012 by Computer Graphics Group, RWTH Aachen * * Copyright (C) 2001-2012 by Computer Graphics Group, RWTH Aachen *
* www.openmesh.org * * www.openmesh.org *
* * * *
*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*
* This file is part of OpenMesh. * * This file is part of OpenMesh. *
* * * *
* OpenMesh is free software: you can redistribute it and/or modify * * OpenMesh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as * * it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of * * published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the * * the License, or (at your option) any later version with the *
@@ -30,10 +30,10 @@
* License along with OpenMesh. If not, * * License along with OpenMesh. If not, *
* see <http://www.gnu.org/licenses/>. * * see <http://www.gnu.org/licenses/>. *
* * * *
\*===========================================================================*/ \*===========================================================================*/
/*===========================================================================*\ /*===========================================================================*\
* * * *
* $Revision$ * * $Revision$ *
* $Date$ * * $Date$ *
* * * *
@@ -103,7 +103,7 @@ public:
{ {
VHandles::const_iterator it, it2, end(_indices.end()); VHandles::const_iterator it, it2, end(_indices.end());
// test for valid vertex indices // test for valid vertex indices
for (it=_indices.begin(); it!=end; ++it) for (it=_indices.begin(); it!=end; ++it)
if (! mesh_.is_valid_handle(*it)) if (! mesh_.is_valid_handle(*it))
@@ -177,6 +177,17 @@ public:
mesh_.set_color(_vh, color_cast<Color>(_color)); mesh_.set_color(_vh, color_cast<Color>(_color));
} }
virtual void set_color(VertexHandle _vh, const Vec4f& _color)
{
if (mesh_.has_vertex_colors())
mesh_.set_color(_vh, color_cast<Color>(_color));
}
virtual void set_color(VertexHandle _vh, const Vec3f& _color)
{
if (mesh_.has_vertex_colors())
mesh_.set_color(_vh, color_cast<Color>(_color));
}
virtual void set_texcoord(VertexHandle _vh, const Vec2f& _texcoord) virtual void set_texcoord(VertexHandle _vh, const Vec2f& _texcoord)
{ {
@@ -191,19 +202,31 @@ public:
} }
// edge attributes // edge attributes
virtual void set_color(EdgeHandle _eh, const Vec4uc& _color) virtual void set_color(EdgeHandle _eh, const Vec4uc& _color)
{ {
if (mesh_.has_edge_colors()) if (mesh_.has_edge_colors())
mesh_.set_color(_eh, color_cast<Color>(_color)); mesh_.set_color(_eh, color_cast<Color>(_color));
} }
virtual void set_color(EdgeHandle _eh, const Vec3uc& _color) virtual void set_color(EdgeHandle _eh, const Vec3uc& _color)
{ {
if (mesh_.has_edge_colors()) if (mesh_.has_edge_colors())
mesh_.set_color(_eh, color_cast<Color>(_color)); mesh_.set_color(_eh, color_cast<Color>(_color));
} }
virtual void set_color(EdgeHandle _eh, const Vec4f& _color)
{
if (mesh_.has_edge_colors())
mesh_.set_color(_eh, color_cast<Color>(_color));
}
virtual void set_color(EdgeHandle _eh, const Vec3f& _color)
{
if (mesh_.has_edge_colors())
mesh_.set_color(_eh, color_cast<Color>(_color));
}
// face attributes // face attributes
virtual void set_normal(FaceHandle _fh, const Vec3f& _normal) virtual void set_normal(FaceHandle _fh, const Vec3f& _normal)
@@ -224,6 +247,18 @@ public:
mesh_.set_color(_fh, color_cast<Color>(_color)); mesh_.set_color(_fh, color_cast<Color>(_color));
} }
virtual void set_color(FaceHandle _fh, const Vec3f& _color)
{
if (mesh_.has_face_colors())
mesh_.set_color(_fh, color_cast<Color>(_color));
}
virtual void set_color(FaceHandle _fh, const Vec4f& _color)
{
if (mesh_.has_face_colors())
mesh_.set_color(_fh, color_cast<Color>(_color));
}
virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector<Vec2f>& _face_texcoords) virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector<Vec2f>& _face_texcoords)
{ {
// get first halfedge handle // get first halfedge handle
@@ -297,7 +332,7 @@ public:
vhandles[j] = mesh_.add_vertex(p); vhandles[j] = mesh_.add_vertex(p);
// DO STORE p, reference may not work since vertex array // DO STORE p, reference may not work since vertex array
// may be relocated after adding a new vertex ! // may be relocated after adding a new vertex !
// Mark vertices of failed face as non-manifold // Mark vertices of failed face as non-manifold
if (mesh_.has_vertex_status()) { if (mesh_.has_vertex_status()) {
mesh_.status(vhandles[j]).set_fixed_nonmanifold(true); mesh_.status(vhandles[j]).set_fixed_nonmanifold(true);
@@ -306,11 +341,11 @@ public:
// add face // add face
FaceHandle fh = mesh_.add_face(vhandles); FaceHandle fh = mesh_.add_face(vhandles);
// Mark failed face as non-manifold // Mark failed face as non-manifold
if (mesh_.has_face_status()) if (mesh_.has_face_status())
mesh_.status(fh).set_fixed_nonmanifold(true); mesh_.status(fh).set_fixed_nonmanifold(true);
// Mark edges of failed face as non-two-manifold // Mark edges of failed face as non-two-manifold
if (mesh_.has_edge_status()) { if (mesh_.has_edge_status()) {
typename Mesh::FaceEdgeIter fe_it = mesh_.fe_iter(fh); typename Mesh::FaceEdgeIter fe_it = mesh_.fe_iter(fh);

View File

@@ -162,8 +162,8 @@ _OFFReader_::read(std::istream& _in, BaseImporter& _bi, Options& _opt )
options_ += Options::ColorAlpha; options_ += Options::ColorAlpha;
return (options_.is_binary() ? return (options_.is_binary() ?
read_binary(_in, _bi, swap) : read_binary(_in, _bi, _opt, swap) :
read_ascii(_in, _bi)); read_ascii(_in, _bi, _opt));
} }
@@ -172,7 +172,7 @@ _OFFReader_::read(std::istream& _in, BaseImporter& _bi, Options& _opt )
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool bool
_OFFReader_::read_ascii(std::istream& _in, BaseImporter& _bi) const _OFFReader_::read_ascii(std::istream& _in, BaseImporter& _bi, Options& _opt) const
{ {
@@ -246,13 +246,17 @@ omlog() << "[OFFReader] : read ascii file\n";
break; break;
// rgb floats // rgb floats
case 5 : stream >> c3f[0]; stream >> c3f[1]; stream >> c3f[2]; case 5 : stream >> c3f[0]; stream >> c3f[1]; stream >> c3f[2];
if ( userOptions_.vertex_has_color() ) if ( userOptions_.vertex_has_color() ) {
_bi.set_color( vh, color_cast<Vec3uc, Vec3f>(c3f) ); _bi.set_color( vh, c3f );
_opt += Options::ColorFloat;
}
break; break;
// rgba floats // rgba floats
case 6 : stream >> c4f[0]; stream >> c4f[1]; stream >> c4f[2]; stream >> c4f[3]; case 6 : stream >> c4f[0]; stream >> c4f[1]; stream >> c4f[2]; stream >> c4f[3];
if ( userOptions_.vertex_has_color() ) if ( userOptions_.vertex_has_color() ) {
_bi.set_color( vh, color_cast<Vec4uc, Vec4f>(c4f) ); _bi.set_color( vh, c4f );
_opt += Options::ColorFloat;
}
break; break;
default: default:
@@ -327,13 +331,17 @@ omlog() << "[OFFReader] : read ascii file\n";
break; break;
// rgb floats // rgb floats
case 5 : stream >> c3f[0]; stream >> c3f[1]; stream >> c3f[2]; case 5 : stream >> c3f[0]; stream >> c3f[1]; stream >> c3f[2];
if ( userOptions_.face_has_color() ) if ( userOptions_.face_has_color() ) {
_bi.set_color( fh, color_cast<Vec3uc, Vec3f>(c3f) ); _bi.set_color( fh, c3f );
_opt += Options::ColorFloat;
}
break; break;
// rgba floats // rgba floats
case 6 : stream >> c4f[0]; stream >> c4f[1]; stream >> c4f[2]; stream >> c4f[3]; case 6 : stream >> c4f[0]; stream >> c4f[1]; stream >> c4f[2]; stream >> c4f[3];
if ( userOptions_.face_has_color() ) if ( userOptions_.face_has_color() ) {
_bi.set_color( fh, color_cast<Vec4uc, Vec4f>(c4f) ); _bi.set_color( fh, c4f );
_opt += Options::ColorFloat;
}
break; break;
default: default:
@@ -423,7 +431,7 @@ void _OFFReader_::readValue(std::istream& _in, unsigned int& _value) const{
} }
bool bool
_OFFReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap*/) const _OFFReader_::read_binary(std::istream& _in, BaseImporter& _bi, Options& _opt, bool /*_swap*/) const
{ {
omlog() << "[OFFReader] : read binary file\n"; omlog() << "[OFFReader] : read binary file\n";
@@ -432,6 +440,8 @@ _OFFReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap*/) c
OpenMesh::Vec3f v, n; OpenMesh::Vec3f v, n;
OpenMesh::Vec3i c; OpenMesh::Vec3i c;
OpenMesh::Vec4i cA; OpenMesh::Vec4i cA;
OpenMesh::Vec3f cf;
OpenMesh::Vec4f cAf;
OpenMesh::Vec2f t; OpenMesh::Vec2f t;
BaseImporter::VHandles vhandles; BaseImporter::VHandles vhandles;
VertexHandle vh; VertexHandle vh;
@@ -467,23 +477,46 @@ _OFFReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap*/) c
} }
if ( options_.vertex_has_color() ) { if ( options_.vertex_has_color() ) {
//with alpha if ( userOptions_.color_is_float() ) {
if ( options_.color_has_alpha() ){ _opt += Options::ColorFloat;
readValue(_in, cA[0]); //with alpha
readValue(_in, cA[1]); if ( options_.color_has_alpha() ){
readValue(_in, cA[2]); readValue(_in, cAf[0]);
readValue(_in, cA[3]); readValue(_in, cAf[1]);
readValue(_in, cAf[2]);
readValue(_in, cAf[3]);
if ( userOptions_.vertex_has_color() ) if ( userOptions_.vertex_has_color() )
_bi.set_color( vh, Vec4uc( cA ) ); _bi.set_color( vh, cAf );
}else{ }else{
//without alpha
readValue(_in, c[0]);
readValue(_in, c[1]);
readValue(_in, c[2]);
if ( userOptions_.vertex_has_color() ) //without alpha
_bi.set_color( vh, Vec3uc( c ) ); readValue(_in, cf[0]);
readValue(_in, cf[1]);
readValue(_in, cf[2]);
if ( userOptions_.vertex_has_color() )
_bi.set_color( vh, cf );
}
} else {
//with alpha
if ( options_.color_has_alpha() ){
readValue(_in, cA[0]);
readValue(_in, cA[1]);
readValue(_in, cA[2]);
readValue(_in, cA[3]);
if ( userOptions_.vertex_has_color() )
_bi.set_color( vh, Vec4uc( cA ) );
}else{
//without alpha
readValue(_in, c[0]);
readValue(_in, c[1]);
readValue(_in, c[2]);
if ( userOptions_.vertex_has_color() )
_bi.set_color( vh, Vec3uc( c ) );
}
} }
} }
@@ -503,7 +536,6 @@ _OFFReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap*/) c
{ {
readValue(_in, nV); readValue(_in, nV);
if (nV == 3) if (nV == 3)
{ {
vhandles.resize(3); vhandles.resize(3);
@@ -514,9 +546,7 @@ _OFFReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap*/) c
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)
{ {
@@ -528,24 +558,46 @@ _OFFReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap*/) c
FaceHandle fh = _bi.add_face(vhandles); FaceHandle fh = _bi.add_face(vhandles);
//face color //face color
if ( options_.face_has_color() ) { if ( _opt.face_has_color() ) {
//with alpha if ( userOptions_.color_is_float() ) {
if ( options_.color_has_alpha() ){ _opt += Options::ColorFloat;
readValue(_in, cA[0]); //with alpha
readValue(_in, cA[1]); if ( options_.color_has_alpha() ){
readValue(_in, cA[2]); readValue(_in, cAf[0]);
readValue(_in, cA[3]); readValue(_in, cAf[1]);
readValue(_in, cAf[2]);
readValue(_in, cAf[3]);
if ( userOptions_.face_has_color() ) if ( userOptions_.face_has_color() )
_bi.set_color( fh , Vec4uc( cA ) ); _bi.set_color( fh , cAf );
}else{ }else{
//without alpha //without alpha
readValue(_in, c[0]); readValue(_in, cf[0]);
readValue(_in, c[1]); readValue(_in, cf[1]);
readValue(_in, c[2]); readValue(_in, cf[2]);
if ( userOptions_.face_has_color() ) if ( userOptions_.face_has_color() )
_bi.set_color( fh, Vec3uc( c ) ); _bi.set_color( fh, cf );
}
} else {
//with alpha
if ( options_.color_has_alpha() ){
readValue(_in, cA[0]);
readValue(_in, cA[1]);
readValue(_in, cA[2]);
readValue(_in, cA[3]);
if ( userOptions_.face_has_color() )
_bi.set_color( fh , Vec4uc( cA ) );
}else{
//without alpha
readValue(_in, c[0]);
readValue(_in, c[1]);
readValue(_in, c[2]);
if ( userOptions_.face_has_color() )
_bi.set_color( fh, Vec3uc( c ) );
}
} }
} }
@@ -619,7 +671,7 @@ bool _OFFReader_::can_u_read(std::istream& _is) const
// Detect possible garbage and make sure, we don't have an underflow // Detect possible garbage and make sure, we don't have an underflow
if ( remainingChars >= 4 ) if ( remainingChars >= 4 )
remainingChars -= 4; remainingChars -= 4;
else else
remainingChars = 0; remainingChars = 0;
if ( ( remainingChars >= 6 ) && ( strncmp(p, "BINARY", 6) == 0 ) ) if ( ( remainingChars >= 6 ) && ( strncmp(p, "BINARY", 6) == 0 ) )

View File

@@ -136,8 +136,8 @@ private:
bool can_u_read(std::istream& _is) const; bool can_u_read(std::istream& _is) const;
bool read_ascii(std::istream& _in, BaseImporter& _bi) const; bool read_ascii(std::istream& _in, BaseImporter& _bi, Options& _opt) const;
bool read_binary(std::istream& _in, BaseImporter& _bi, bool swap) const; bool read_binary(std::istream& _in, BaseImporter& _bi, Options& _opt, bool swap) const;
void readValue(std::istream& _in, float& _value) const; void readValue(std::istream& _in, float& _value) const;
void readValue(std::istream& _in, int& _value) const; void readValue(std::istream& _in, int& _value) const;

View File

@@ -183,6 +183,8 @@ write_ascii(std::ostream& _out, BaseExporter& _be, Options _opt) const
Vec2f t; Vec2f t;
OpenMesh::Vec3i c; OpenMesh::Vec3i c;
OpenMesh::Vec4i cA; OpenMesh::Vec4i cA;
OpenMesh::Vec3f cf;
OpenMesh::Vec4f cAf;
VertexHandle vh; VertexHandle vh;
std::vector<VertexHandle> vhandles; std::vector<VertexHandle> vhandles;
@@ -192,6 +194,9 @@ write_ascii(std::ostream& _out, BaseExporter& _be, Options _opt) const
_out << _be.n_faces() << " "; _out << _be.n_faces() << " ";
_out << 0 << "\n"; _out << 0 << "\n";
if (_opt.color_is_float())
_out << std::fixed;
// vertex data (point, normals, colors, texcoords) // vertex data (point, normals, colors, texcoords)
for (i=0, nV=_be.n_vertices(); i<nV; ++i) for (i=0, nV=_be.n_vertices(); i<nV; ++i)
@@ -210,14 +215,26 @@ write_ascii(std::ostream& _out, BaseExporter& _be, Options _opt) const
// VertexColor // VertexColor
if ( _opt.vertex_has_color() ) { if ( _opt.vertex_has_color() ) {
//with alpha if ( _opt.color_is_float() ) {
if ( _opt.color_has_alpha() ){ //with alpha
cA = _be.colorA(vh); if ( _opt.color_has_alpha() ){
_out << " " << cA[0] << " " << cA[1] << " " << cA[2] << " " << cA[3]; cAf = _be.colorAf(vh);
}else{ _out << " " << cAf;
//without alpha }else{
c = _be.color(vh); //without alpha
_out << " " << c[0] << " " << c[1] << " " << c[2]; cf = _be.colorf(vh);
_out << " " << cf;
}
} else {
//with alpha
if ( _opt.color_has_alpha() ){
cA = _be.colorA(vh);
_out << " " << cA;
}else{
//without alpha
c = _be.color(vh);
_out << " " << c;
}
} }
} }
@@ -244,14 +261,26 @@ write_ascii(std::ostream& _out, BaseExporter& _be, Options _opt) const
//face color //face color
if ( _opt.face_has_color() ){ if ( _opt.face_has_color() ){
//with alpha if ( _opt.color_is_float() ) {
if ( _opt.color_has_alpha() ){ //with alpha
cA = _be.colorA( FaceHandle(i) ); if ( _opt.color_has_alpha() ){
_out << " " << cA[0] << " " << cA[1] << " " << cA[2] << " " << cA[3]; cAf = _be.colorAf( FaceHandle(i) );
}else{ _out << " " << cAf;
//without alpha }else{
c = _be.color( FaceHandle(i) ); //without alpha
_out << " " << c[0] << " " << c[1] << " " << c[2]; cf = _be.colorf( FaceHandle(i) );
_out << " " << cf;
}
} else {
//with alpha
if ( _opt.color_has_alpha() ){
cA = _be.colorA( FaceHandle(i) );
_out << " " << cA;
}else{
//without alpha
c = _be.color( FaceHandle(i) );
_out << " " << c;
}
} }
} }
_out << "\n"; _out << "\n";
@@ -268,14 +297,26 @@ write_ascii(std::ostream& _out, BaseExporter& _be, Options _opt) const
//face color //face color
if ( _opt.face_has_color() ){ if ( _opt.face_has_color() ){
//with alpha if ( _opt.color_is_float() ) {
if ( _opt.color_has_alpha() ){ //with alpha
cA = _be.colorA( FaceHandle(i) ); if ( _opt.color_has_alpha() ){
_out << cA[0] << " " << cA[1] << " " << cA[2] << " " << cA[3]; cAf = _be.colorAf( FaceHandle(i) );
}else{ _out << " " << cAf;
//without alpha }else{
c = _be.color( FaceHandle(i) ); //without alpha
_out << c[0] << " " << c[1] << " " << c[2]; cf = _be.colorf( FaceHandle(i) );
_out << " " << cf;
}
} else {
//with alpha
if ( _opt.color_has_alpha() ){
cA = _be.colorA( FaceHandle(i) );
_out << " " << cA;
}else{
//without alpha
c = _be.color( FaceHandle(i) );
_out << " " << c;
}
} }
} }
@@ -312,23 +353,22 @@ bool
_OFFWriter_:: _OFFWriter_::
write_binary(std::ostream& _out, BaseExporter& _be, Options _opt) const write_binary(std::ostream& _out, BaseExporter& _be, Options _opt) const
{ {
omlog() << "[OFFWriter] : write ascii file\n"; omlog() << "[OFFWriter] : write binary file\n";
unsigned int i, j, nV, nF; unsigned int i, j, nV, nF;
Vec3f v, n; Vec3f v, n;
Vec2f t; Vec2f t;
OpenMesh::Vec4i c; OpenMesh::Vec4i c;
OpenMesh::Vec4f cf;
VertexHandle vh; VertexHandle vh;
std::vector<VertexHandle> vhandles; std::vector<VertexHandle> vhandles;
// #vertices, #faces // #vertices, #faces
writeValue(_out, (uint)_be.n_vertices() ); writeValue(_out, (uint)_be.n_vertices() );
writeValue(_out, (uint) _be.n_faces() ); writeValue(_out, (uint) _be.n_faces() );
writeValue(_out, 0 ); writeValue(_out, 0 );
// vertex data (point, normals, texcoords) // vertex data (point, normals, texcoords)
for (i=0, nV=_be.n_vertices(); i<nV; ++i) for (i=0, nV=_be.n_vertices(); i<nV; ++i)
{ {
@@ -349,6 +389,15 @@ write_binary(std::ostream& _out, BaseExporter& _be, Options _opt) const
} }
// vertex color // vertex color
if ( _opt.vertex_has_color() ) { if ( _opt.vertex_has_color() ) {
if ( _opt.color_is_float() ) {
cf = _be.colorAf(vh);
writeValue(_out, cf[0]);
writeValue(_out, cf[1]);
writeValue(_out, cf[2]);
if ( _opt.color_has_alpha() )
writeValue(_out, cf[3]);
} else {
c = _be.colorA(vh); c = _be.colorA(vh);
writeValue(_out, c[0]); writeValue(_out, c[0]);
writeValue(_out, c[1]); writeValue(_out, c[1]);
@@ -356,6 +405,7 @@ write_binary(std::ostream& _out, BaseExporter& _be, Options _opt) const
if ( _opt.color_has_alpha() ) if ( _opt.color_has_alpha() )
writeValue(_out, c[3]); writeValue(_out, c[3]);
}
} }
// texCoords // texCoords
if (_opt.vertex_has_texcoord() ) { if (_opt.vertex_has_texcoord() ) {
@@ -380,13 +430,23 @@ write_binary(std::ostream& _out, BaseExporter& _be, Options _opt) const
//face color //face color
if ( _opt.face_has_color() ){ if ( _opt.face_has_color() ){
c = _be.colorA( FaceHandle(i) ); if ( _opt.color_is_float() ) {
writeValue(_out, c[0]); cf = _be.colorAf( FaceHandle(i) );
writeValue(_out, c[1]); writeValue(_out, cf[0]);
writeValue(_out, c[2]); writeValue(_out, cf[1]);
writeValue(_out, cf[2]);
if ( _opt.color_has_alpha() ) if ( _opt.color_has_alpha() )
writeValue(_out, c[3]); writeValue(_out, cf[3]);
} else {
c = _be.colorA( FaceHandle(i) );
writeValue(_out, c[0]);
writeValue(_out, c[1]);
writeValue(_out, c[2]);
if ( _opt.color_has_alpha() )
writeValue(_out, c[3]);
}
} }
} }
} }
@@ -402,13 +462,23 @@ write_binary(std::ostream& _out, BaseExporter& _be, Options _opt) const
//face color //face color
if ( _opt.face_has_color() ){ if ( _opt.face_has_color() ){
c = _be.colorA( FaceHandle(i) ); if ( _opt.color_is_float() ) {
writeValue(_out, c[0]); cf = _be.colorAf( FaceHandle(i) );
writeValue(_out, c[1]); writeValue(_out, cf[0]);
writeValue(_out, c[2]); writeValue(_out, cf[1]);
writeValue(_out, cf[2]);
if ( _opt.color_has_alpha() ) if ( _opt.color_has_alpha() )
writeValue(_out, c[3]); writeValue(_out, cf[3]);
} else {
c = _be.colorA( FaceHandle(i) );
writeValue(_out, c[0]);
writeValue(_out, c[1]);
writeValue(_out, c[2]);
if ( _opt.color_has_alpha() )
writeValue(_out, c[3]);
}
} }
} }
} }

View File

@@ -245,6 +245,9 @@ write_ascii(std::ostream& _out, BaseExporter& _be, Options _opt) const
write_header(_out, _be, _opt); write_header(_out, _be, _opt);
if (_opt.color_is_float())
_out << std::fixed;
// vertex data (point, normals, colors, texcoords) // vertex data (point, normals, colors, texcoords)
for (i=0, nV=_be.n_vertices(); i<nV; ++i) for (i=0, nV=_be.n_vertices(); i<nV; ++i)
{ {

View File

@@ -95,5 +95,113 @@ TEST_F(OpenMeshReadWriteOFF, WriteAndReadVertexColorsToAndFromOFFFile) {
mesh_.release_vertex_colors(); mesh_.release_vertex_colors();
} }
TEST_F(OpenMeshReadWriteOFF, WriteAndReadFloatVertexColorsToAndFromOFFFile) {
mesh_.clear();
mesh_.request_vertex_colors();
OpenMesh::IO::Options opt(OpenMesh::IO::Options::VertexColor);
bool ok = OpenMesh::IO::read_mesh(mesh_, "meshlab.ply", opt);
EXPECT_TRUE(ok) << "meshlab.ply could not be read!";
opt.clear();
opt += OpenMesh::IO::Options::VertexColor;
opt += OpenMesh::IO::Options::ColorFloat;
// write the mesh_
ok = OpenMesh::IO::write_mesh(mesh_, "cube_floating.off", opt);
EXPECT_TRUE(ok) << "cube_floating.off could not be written!";
mesh_.clear();
ok = OpenMesh::IO::read_mesh(mesh_, "cube_floating.off", opt);
EXPECT_TRUE(ok) << "cube_floating.off could not be read!";
EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0";
EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1";
EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2";
EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0";
EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1";
EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2";
EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0";
EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1";
EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2";
EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0";
EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1";
EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2";
EXPECT_FALSE(opt.vertex_has_normal()) << "Wrong user opt are returned!";
EXPECT_FALSE(opt.vertex_has_texcoord()) << "Wrong user opt are returned!";
EXPECT_TRUE(opt.vertex_has_color()) << "Wrong user opt are returned!";
EXPECT_TRUE(opt.color_is_float()) << "Wrong user opt are returned!";
mesh_.release_vertex_colors();
}
TEST_F(OpenMeshReadWriteOFF, WriteAndReadBinaryFloatVertexColorsToAndFromOFFFile) {
mesh_.clear();
mesh_.request_vertex_colors();
OpenMesh::IO::Options opt(OpenMesh::IO::Options::VertexColor);
bool ok = OpenMesh::IO::read_mesh(mesh_, "meshlab.ply", opt);
EXPECT_TRUE(ok) << "meshlab.ply could not be read!";
opt.clear();
opt += OpenMesh::IO::Options::VertexColor;
opt += OpenMesh::IO::Options::Binary;
opt += OpenMesh::IO::Options::ColorFloat;
// write the mesh_
ok = OpenMesh::IO::write_mesh(mesh_, "cube_floating_binary.off", opt);
EXPECT_TRUE(ok) << "cube_floating_binary.off could not be written!";
mesh_.clear();
opt.clear();
opt += OpenMesh::IO::Options::VertexColor;
opt += OpenMesh::IO::Options::Binary;
opt += OpenMesh::IO::Options::ColorFloat;
ok = OpenMesh::IO::read_mesh(mesh_, "cube_floating_binary.off", opt);
EXPECT_TRUE(ok) << "cube_floating_binary.off could not be read!";
EXPECT_EQ(8u , mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
EXPECT_EQ(18u , mesh_.n_edges()) << "The number of loaded edges is not correct!";
EXPECT_EQ(12u , mesh_.n_faces()) << "The number of loaded faces is not correct!";
EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[0] ) << "Wrong vertex color at vertex 0 component 0";
EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(0))[1] ) << "Wrong vertex color at vertex 0 component 1";
EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(0))[2] ) << "Wrong vertex color at vertex 0 component 2";
EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[0] ) << "Wrong vertex color at vertex 3 component 0";
EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(3))[1] ) << "Wrong vertex color at vertex 3 component 1";
EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(3))[2] ) << "Wrong vertex color at vertex 3 component 2";
EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[0] ) << "Wrong vertex color at vertex 4 component 0";
EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(4))[1] ) << "Wrong vertex color at vertex 4 component 1";
EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(4))[2] ) << "Wrong vertex color at vertex 4 component 2";
EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[0] ) << "Wrong vertex color at vertex 7 component 0";
EXPECT_EQ(0, mesh_.color(mesh_.vertex_handle(7))[1] ) << "Wrong vertex color at vertex 7 component 1";
EXPECT_EQ(255, mesh_.color(mesh_.vertex_handle(7))[2] ) << "Wrong vertex color at vertex 7 component 2";
EXPECT_FALSE(opt.vertex_has_normal()) << "Wrong user opt are returned!";
EXPECT_FALSE(opt.vertex_has_texcoord()) << "Wrong user opt are returned!";
EXPECT_FALSE(opt.face_has_color()) << "Wrong user opt are returned!";
EXPECT_TRUE(opt.vertex_has_color()) << "Wrong user opt are returned!";
EXPECT_TRUE(opt.color_is_float()) << "Wrong user opt are returned!";
EXPECT_TRUE(opt.is_binary()) << "Wrong user opt are returned!";
mesh_.release_vertex_colors();
}
#endif // INCLUDE GUARD #endif // INCLUDE GUARD

View File

@@ -296,6 +296,7 @@ TEST_F(OpenMeshReadWritePLY, WriteAndReadPLYWithFloatVertexColors) {
EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!"; EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!";
EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!"; EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
EXPECT_TRUE(options.vertex_has_color()) << "Wrong user options are returned!"; EXPECT_TRUE(options.vertex_has_color()) << "Wrong user options are returned!";
EXPECT_TRUE(options.color_is_float()) << "Wrong user options are returned!";
mesh_.release_vertex_colors(); mesh_.release_vertex_colors();
} }
@@ -349,6 +350,8 @@ TEST_F(OpenMeshReadWritePLY, WriteAndReadBinaryPLYWithFloatVertexColors) {
EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!"; EXPECT_FALSE(options.vertex_has_normal()) << "Wrong user options are returned!";
EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!"; EXPECT_FALSE(options.vertex_has_texcoord()) << "Wrong user options are returned!";
EXPECT_TRUE(options.vertex_has_color()) << "Wrong user options are returned!"; EXPECT_TRUE(options.vertex_has_color()) << "Wrong user options are returned!";
EXPECT_TRUE(options.color_is_float()) << "Wrong user options are returned!";
EXPECT_TRUE(options.is_binary()) << "Wrong user options are returned!";
mesh_.release_vertex_colors(); mesh_.release_vertex_colors();
} }