Made unittest for obj crash when colors are requested but not available

Made OBJ reader aware of user requests (Warning! Old default behaviour was wrong, because the reader read everything, without checking for the user options!)

git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@738 fdac6126-5c0c-442c-9429-916003d36597
This commit is contained in:
Jan Möbius
2012-10-08 09:45:20 +00:00
parent 505ab99324
commit 19ceb62d1e
3 changed files with 144 additions and 56 deletions

View File

@@ -105,7 +105,8 @@ public:
EdgeColor = 0x0080, ///< Has (r) / store (w) edge colors EdgeColor = 0x0080, ///< Has (r) / store (w) edge colors
FaceNormal = 0x0100, ///< Has (r) / store (w) face normals FaceNormal = 0x0100, ///< Has (r) / store (w) face normals
FaceColor = 0x0200, ///< Has (r) / store (w) face colors FaceColor = 0x0200, ///< Has (r) / store (w) face colors
ColorAlpha = 0x0400 ///< Has (r) / store (w) alpha values for colors FaceTexCoord = 0x0400, ///< Has (r) / store (w) face texture coordinates
ColorAlpha = 0x0800 ///< Has (r) / store (w) alpha values for colors
}; };
public: public:
@@ -199,6 +200,7 @@ public:
bool edge_has_color() const { return check(EdgeColor); } bool edge_has_color() const { return check(EdgeColor); }
bool face_has_normal() const { return check(FaceNormal); } bool face_has_normal() const { return check(FaceNormal); }
bool face_has_color() const { return check(FaceColor); } bool face_has_color() const { return check(FaceColor); }
bool face_has_texcoord() const { return check(FaceTexCoord); }
bool color_has_alpha() const { return check(ColorAlpha); } bool color_has_alpha() const { return check(ColorAlpha); }

View File

@@ -283,6 +283,13 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
std::string matname; std::string matname;
// Options supplied by the user
Options userOptions = _opt;
// Options collected via file parsing
Options fileOptions;
while( _in && !_in.eof() ) while( _in && !_in.eof() )
{ {
std::getline(_in,line); std::getline(_in,line);
@@ -363,11 +370,13 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
if ( !stream.fail() ) if ( !stream.fail() )
{ {
_opt += Options::VertexColor; if ( userOptions.vertex_has_color() ) {
fileOptions += Options::VertexColor;
colors.push_back(OpenMesh::Vec3uc((unsigned char)r,(unsigned char)g,(unsigned char)b)); colors.push_back(OpenMesh::Vec3uc((unsigned char)r,(unsigned char)g,(unsigned char)b));
} }
} }
} }
}
// texture coord // texture coord
else if (keyWrd == "vt") else if (keyWrd == "vt")
@@ -376,8 +385,13 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
if ( !stream.fail() ){ if ( !stream.fail() ){
if ( userOptions.vertex_has_texcoord() || userOptions.face_has_texcoord() ) {
texcoords.push_back(OpenMesh::Vec2f(u, v)); texcoords.push_back(OpenMesh::Vec2f(u, v));
_opt += Options::VertexTexCoord;
// Can be used for both!
fileOptions += Options::VertexTexCoord;
fileOptions += Options::FaceTexCoord;
}
}else{ }else{
@@ -393,8 +407,10 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
stream >> r; stream >> g; stream >> b; stream >> r; stream >> g; stream >> b;
if ( !stream.fail() ){ if ( !stream.fail() ){
if ( userOptions.vertex_has_color() ) {
colors.push_back(OpenMesh::Vec3uc((unsigned char)r,(unsigned char)g,(unsigned char)b)); colors.push_back(OpenMesh::Vec3uc((unsigned char)r,(unsigned char)g,(unsigned char)b));
_opt += Options::VertexColor; fileOptions += Options::VertexColor;
}
} }
} }
@@ -403,9 +419,11 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
{ {
stream >> x; stream >> y; stream >> z; stream >> x; stream >> y; stream >> z;
if ( !stream.fail() ){ if ( !stream.fail() ) {
if (userOptions.vertex_has_normal() ){
normals.push_back(OpenMesh::Vec3f(x,y,z)); normals.push_back(OpenMesh::Vec3f(x,y,z));
_opt += Options::VertexNormal; fileOptions += Options::VertexNormal;
}
} }
} }
@@ -491,7 +509,7 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
// Obj counts from 1 and not zero .. array counts from zero therefore -1 // Obj counts from 1 and not zero .. array counts from zero therefore -1
vhandles.push_back(VertexHandle(value-1)); vhandles.push_back(VertexHandle(value-1));
faceVertices.push_back(VertexHandle(value-1)); faceVertices.push_back(VertexHandle(value-1));
if (_opt.vertex_has_color()) if (fileOptions.vertex_has_color() )
_bi.set_color(vhandles.back(), colors[value-1]); _bi.set_color(vhandles.back(), colors[value-1]);
break; break;
@@ -503,13 +521,28 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
value = texcoords.size() + value + 1; value = texcoords.size() + value + 1;
} }
assert(!vhandles.empty()); assert(!vhandles.empty());
if ( ! texcoords.empty() && (unsigned int)(value-1) < texcoords.size() ) {
if ( fileOptions.vertex_has_texcoord() && userOptions.vertex_has_texcoord() ) {
if (!texcoords.empty() && (unsigned int) (value - 1) < texcoords.size()) {
// Obj counts from 1 and not zero .. array counts from zero therefore -1 // Obj counts from 1 and not zero .. array counts from zero therefore -1
_bi.set_texcoord(vhandles.back(), texcoords[value-1]); _bi.set_texcoord(vhandles.back(), texcoords[value - 1]);
} else {
omerr() << "Error setting Texture coordinates" << std::endl;
}
}
if (fileOptions.face_has_texcoord() && userOptions.face_has_texcoord() ) {
if (!texcoords.empty() && (unsigned int) (value - 1) < texcoords.size()) {
face_texcoords.push_back( texcoords[value-1] ); face_texcoords.push_back( texcoords[value-1] );
} else { } else {
omerr() << "Error setting Texture coordinates" << std::endl; omerr() << "Error setting Texture coordinates" << std::endl;
} }
}
break; break;
@@ -520,10 +553,13 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
// As obj counts from 1 and not zero add +1 // As obj counts from 1 and not zero add +1
value = normals.size() + value + 1; value = normals.size() + value + 1;
} }
// Obj counts from 1 and not zero .. array counts from zero therefore -1
if (fileOptions.vertex_has_normal() ) {
assert(!vhandles.empty()); assert(!vhandles.empty());
assert((unsigned int)(value-1) < normals.size()); assert((unsigned int)(value-1) < normals.size());
// Obj counts from 1 and not zero .. array counts from zero therefore -1
_bi.set_normal(vhandles.back(), normals[value-1]); _bi.set_normal(vhandles.back(), normals[value-1]);
}
break; break;
} }
@@ -546,8 +582,8 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
size_t n_faces = _bi.n_faces(); size_t n_faces = _bi.n_faces();
if( !vhandles.empty() && fh.is_valid() ) if (!vhandles.empty() && fh.is_valid() )
_bi.add_face_texcoords( fh, vhandles[0], face_texcoords ); _bi.add_face_texcoords(fh, vhandles[0], face_texcoords);
if ( !matname.empty() ) if ( !matname.empty() )
{ {
@@ -561,25 +597,36 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
if ( mat.has_Kd() ) { if ( mat.has_Kd() ) {
Vec3uc fc = color_cast<Vec3uc, Vec3f>(mat.Kd()); Vec3uc fc = color_cast<Vec3uc, Vec3f>(mat.Kd());
for (std::vector<FaceHandle>::iterator it = newfaces.begin(); if ( userOptions.face_has_color()) {
it != newfaces.end(); ++it)
_bi.set_color( *it, fc );
_opt += Options::FaceColor; for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
_bi.set_color(*it, fc);
fileOptions += Options::FaceColor;
}
} }
// Set the texture index in the face index property // Set the texture index in the face index property
if ( mat.has_map_Kd() ) { if ( mat.has_map_Kd() ) {
for (std::vector<FaceHandle>::iterator it = newfaces.begin(); if (userOptions.face_has_texcoord()) {
it != newfaces.end(); ++it)
_bi.set_face_texindex( *it, mat.map_Kd_index() ); for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
_bi.set_face_texindex(*it, mat.map_Kd_index());
fileOptions += Options::FaceTexCoord;
}
} else { } else {
// If we don't have the info, set it to no texture // If we don't have the info, set it to no texture
for (std::vector<FaceHandle>::iterator it = newfaces.begin(); if (userOptions.face_has_texcoord()) {
it != newfaces.end(); ++it)
_bi.set_face_texindex( *it, 0 ); for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
_bi.set_face_texindex(*it, 0);
}
} }
} else { } else {
@@ -589,9 +636,9 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
newfaces.push_back(FaceHandle(n_faces+i)); newfaces.push_back(FaceHandle(n_faces+i));
// Set the texture index to zero as we don't have any information // Set the texture index to zero as we don't have any information
for (std::vector<FaceHandle>::iterator it = newfaces.begin(); if ( userOptions.face_has_texcoord() )
it != newfaces.end(); ++it) for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
_bi.set_face_texindex( *it, 0 ); _bi.set_face_texindex(*it, 0);
} }
} }
@@ -600,23 +647,24 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
// If we do not have any faces, // If we do not have any faces,
// assume this is a point cloud and read the normals and colors directly // assume this is a point cloud and read the normals and colors directly
if (_bi.n_faces()==0) if (_bi.n_faces() == 0)
{ {
int i=0; int i = 0;
// add normal per vertex // add normal per vertex
if ( normals.size() == _bi.n_vertices() )
for (std::vector<VertexHandle>::iterator it = vertexHandles.begin(); if (normals.size() == _bi.n_vertices()) {
it != vertexHandles.end(); ++it, i++) { if ( fileOptions.vertex_has_normal() && userOptions.vertex_has_normal() ) {
_bi.set_normal( *it, normals[i] ); for (std::vector<VertexHandle>::iterator it = vertexHandles.begin(); it != vertexHandles.end(); ++it, i++)
_bi.set_normal(*it, normals[i]);
}
} }
// add color per vertex // add color per vertex
i=0; i = 0;
if ( colors.size() >= _bi.n_vertices() ) if (colors.size() >= _bi.n_vertices())
for (std::vector<VertexHandle>::iterator it = vertexHandles.begin(); if (fileOptions.vertex_has_color() && userOptions.vertex_has_color()) {
it != vertexHandles.end(); ++it, i++) { for (std::vector<VertexHandle>::iterator it = vertexHandles.begin(); it != vertexHandles.end(); ++it, i++)
_bi.set_color( *it, colors[i] ); _bi.set_color(*it, colors[i]);
} }
} }

View File

@@ -149,9 +149,12 @@ TEST_F(OpenMeshLoader, LoadSimpleOBJCheckHalfEdgeAndVertexNormals) {
mesh_.request_halfedge_normals(); mesh_.request_halfedge_normals();
mesh_.request_vertex_normals(); mesh_.request_vertex_normals();
OpenMesh::IO::Options options;
options += OpenMesh::IO::Options::VertexNormal;
std::string file_name = "cube-minimal.obj"; std::string file_name = "cube-minimal.obj";
bool ok = OpenMesh::IO::read_mesh(mesh_, file_name); bool ok = OpenMesh::IO::read_mesh(mesh_, file_name,options);
EXPECT_TRUE(ok) << file_name; EXPECT_TRUE(ok) << file_name;
@@ -209,6 +212,32 @@ TEST_F(OpenMeshLoader, LoadSimpleOBJCheckHalfEdgeAndVertexNormals) {
} }
/*
* Just load a obj file and set vertex color option before loading
*/
TEST_F(OpenMeshLoader, LoadSimpleOBJForceVertexColorsAlthoughNotAvailable) {
mesh_.clear();
mesh_.request_vertex_colors();
std::string file_name = "cube-minimal.obj";
OpenMesh::IO::Options options;
options += OpenMesh::IO::Options::VertexColor;
bool ok = OpenMesh::IO::read_mesh(mesh_, file_name,options);
EXPECT_TRUE(ok) << file_name;
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(36u , mesh_.n_halfedges()) << "The number of loaded halfedges is not correct!";
}
/* /*
* Just load a obj file of a cube and checks the halfedge texCoords * Just load a obj file of a cube and checks the halfedge texCoords
*/ */
@@ -218,9 +247,12 @@ TEST_F(OpenMeshLoader, LoadSimpleOBJCheckTexCoords) {
mesh_.request_halfedge_texcoords2D(); mesh_.request_halfedge_texcoords2D();
OpenMesh::IO::Options options;
options += OpenMesh::IO::Options::FaceTexCoord;
std::string file_name = "cube-minimal-texCoords.obj"; std::string file_name = "cube-minimal-texCoords.obj";
bool ok = OpenMesh::IO::read_mesh(mesh_, file_name); bool ok = OpenMesh::IO::read_mesh(mesh_, file_name,options);
EXPECT_TRUE(ok) << file_name; EXPECT_TRUE(ok) << file_name;
@@ -255,7 +287,10 @@ TEST_F(OpenMeshLoader, LoadSimpleOBJWithVertexColorsAfterVertices) {
mesh_.request_vertex_colors(); mesh_.request_vertex_colors();
bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-vertex-colors-after-vertex-definition.obj"); OpenMesh::IO::Options options;
options += OpenMesh::IO::Options::VertexColor;
bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-vertex-colors-after-vertex-definition.obj",options);
EXPECT_TRUE(ok) << "Unable to load cube-minimal-vertex-colors-after-vertex-definition.obj"; EXPECT_TRUE(ok) << "Unable to load cube-minimal-vertex-colors-after-vertex-definition.obj";
@@ -291,7 +326,10 @@ TEST_F(OpenMeshLoader, LoadSimpleOBJWithVertexColorsAsVCLines) {
mesh_.request_vertex_colors(); mesh_.request_vertex_colors();
bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-vertex-colors-as-vc-lines.obj"); OpenMesh::IO::Options options;
options += OpenMesh::IO::Options::VertexColor;
bool ok = OpenMesh::IO::read_mesh(mesh_, "cube-minimal-vertex-colors-as-vc-lines.obj",options);
EXPECT_TRUE(ok) << "Unable to load cube-minimal-vertex-colors-as-vc-lines.obj"; EXPECT_TRUE(ok) << "Unable to load cube-minimal-vertex-colors-as-vc-lines.obj";