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:
@@ -105,7 +105,8 @@ public:
|
||||
EdgeColor = 0x0080, ///< Has (r) / store (w) edge colors
|
||||
FaceNormal = 0x0100, ///< Has (r) / store (w) face normals
|
||||
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:
|
||||
@@ -199,6 +200,7 @@ public:
|
||||
bool edge_has_color() const { return check(EdgeColor); }
|
||||
bool face_has_normal() const { return check(FaceNormal); }
|
||||
bool face_has_color() const { return check(FaceColor); }
|
||||
bool face_has_texcoord() const { return check(FaceTexCoord); }
|
||||
bool color_has_alpha() const { return check(ColorAlpha); }
|
||||
|
||||
|
||||
|
||||
@@ -283,6 +283,13 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
|
||||
std::string matname;
|
||||
|
||||
|
||||
// Options supplied by the user
|
||||
Options userOptions = _opt;
|
||||
|
||||
// Options collected via file parsing
|
||||
Options fileOptions;
|
||||
|
||||
|
||||
while( _in && !_in.eof() )
|
||||
{
|
||||
std::getline(_in,line);
|
||||
@@ -363,8 +370,10 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
|
||||
|
||||
if ( !stream.fail() )
|
||||
{
|
||||
_opt += Options::VertexColor;
|
||||
colors.push_back(OpenMesh::Vec3uc((unsigned char)r,(unsigned char)g,(unsigned char)b));
|
||||
if ( userOptions.vertex_has_color() ) {
|
||||
fileOptions += Options::VertexColor;
|
||||
colors.push_back(OpenMesh::Vec3uc((unsigned char)r,(unsigned char)g,(unsigned char)b));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -374,10 +383,15 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
|
||||
{
|
||||
stream >> u; stream >> v;
|
||||
|
||||
if ( !stream.fail() ){
|
||||
if ( !stream.fail() ){
|
||||
|
||||
texcoords.push_back(OpenMesh::Vec2f(u, v));
|
||||
_opt += Options::VertexTexCoord;
|
||||
if ( userOptions.vertex_has_texcoord() || userOptions.face_has_texcoord() ) {
|
||||
texcoords.push_back(OpenMesh::Vec2f(u, v));
|
||||
|
||||
// Can be used for both!
|
||||
fileOptions += Options::VertexTexCoord;
|
||||
fileOptions += Options::FaceTexCoord;
|
||||
}
|
||||
|
||||
}else{
|
||||
|
||||
@@ -392,9 +406,11 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
|
||||
{
|
||||
stream >> r; stream >> g; stream >> b;
|
||||
|
||||
if ( !stream.fail() ){
|
||||
colors.push_back(OpenMesh::Vec3uc((unsigned char)r,(unsigned char)g,(unsigned char)b));
|
||||
_opt += Options::VertexColor;
|
||||
if ( !stream.fail() ){
|
||||
if ( userOptions.vertex_has_color() ) {
|
||||
colors.push_back(OpenMesh::Vec3uc((unsigned char)r,(unsigned char)g,(unsigned char)b));
|
||||
fileOptions += Options::VertexColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,9 +419,11 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
|
||||
{
|
||||
stream >> x; stream >> y; stream >> z;
|
||||
|
||||
if ( !stream.fail() ){
|
||||
normals.push_back(OpenMesh::Vec3f(x,y,z));
|
||||
_opt += Options::VertexNormal;
|
||||
if ( !stream.fail() ) {
|
||||
if (userOptions.vertex_has_normal() ){
|
||||
normals.push_back(OpenMesh::Vec3f(x,y,z));
|
||||
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
|
||||
vhandles.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]);
|
||||
break;
|
||||
|
||||
@@ -503,13 +521,28 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
|
||||
value = texcoords.size() + value + 1;
|
||||
}
|
||||
assert(!vhandles.empty());
|
||||
if ( ! texcoords.empty() && (unsigned int)(value-1) < texcoords.size() ) {
|
||||
// Obj counts from 1 and not zero .. array counts from zero therefore -1
|
||||
_bi.set_texcoord(vhandles.back(), texcoords[value-1]);
|
||||
face_texcoords.push_back( texcoords[value-1] );
|
||||
} else {
|
||||
omerr() << "Error setting Texture coordinates" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
_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] );
|
||||
} else {
|
||||
omerr() << "Error setting Texture coordinates" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
|
||||
@@ -520,10 +553,13 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
|
||||
// As obj counts from 1 and not zero add +1
|
||||
value = normals.size() + value + 1;
|
||||
}
|
||||
assert(!vhandles.empty());
|
||||
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]);
|
||||
if (fileOptions.vertex_has_normal() ) {
|
||||
assert(!vhandles.empty());
|
||||
assert((unsigned int)(value-1) < normals.size());
|
||||
_bi.set_normal(vhandles.back(), normals[value-1]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -546,8 +582,8 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
|
||||
|
||||
size_t n_faces = _bi.n_faces();
|
||||
|
||||
if( !vhandles.empty() && fh.is_valid() )
|
||||
_bi.add_face_texcoords( fh, vhandles[0], face_texcoords );
|
||||
if (!vhandles.empty() && fh.is_valid() )
|
||||
_bi.add_face_texcoords(fh, vhandles[0], face_texcoords);
|
||||
|
||||
if ( !matname.empty() )
|
||||
{
|
||||
@@ -561,25 +597,36 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
|
||||
if ( mat.has_Kd() ) {
|
||||
Vec3uc fc = color_cast<Vec3uc, Vec3f>(mat.Kd());
|
||||
|
||||
for (std::vector<FaceHandle>::iterator it = newfaces.begin();
|
||||
it != newfaces.end(); ++it)
|
||||
_bi.set_color( *it, fc );
|
||||
if ( userOptions.face_has_color()) {
|
||||
|
||||
_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
|
||||
if ( mat.has_map_Kd() ) {
|
||||
|
||||
for (std::vector<FaceHandle>::iterator it = newfaces.begin();
|
||||
it != newfaces.end(); ++it)
|
||||
_bi.set_face_texindex( *it, mat.map_Kd_index() );
|
||||
if (userOptions.face_has_texcoord()) {
|
||||
|
||||
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 {
|
||||
|
||||
// If we don't have the info, set it to no texture
|
||||
for (std::vector<FaceHandle>::iterator it = newfaces.begin();
|
||||
it != newfaces.end(); ++it)
|
||||
_bi.set_face_texindex( *it, 0 );
|
||||
if (userOptions.face_has_texcoord()) {
|
||||
|
||||
for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
|
||||
_bi.set_face_texindex(*it, 0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -589,9 +636,9 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
|
||||
newfaces.push_back(FaceHandle(n_faces+i));
|
||||
|
||||
// Set the texture index to zero as we don't have any information
|
||||
for (std::vector<FaceHandle>::iterator it = newfaces.begin();
|
||||
it != newfaces.end(); ++it)
|
||||
_bi.set_face_texindex( *it, 0 );
|
||||
if ( userOptions.face_has_texcoord() )
|
||||
for (std::vector<FaceHandle>::iterator it = newfaces.begin(); it != newfaces.end(); ++it)
|
||||
_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,
|
||||
// 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
|
||||
if ( normals.size() == _bi.n_vertices() )
|
||||
for (std::vector<VertexHandle>::iterator it = vertexHandles.begin();
|
||||
it != vertexHandles.end(); ++it, i++) {
|
||||
_bi.set_normal( *it, normals[i] );
|
||||
}
|
||||
|
||||
if (normals.size() == _bi.n_vertices()) {
|
||||
if ( fileOptions.vertex_has_normal() && userOptions.vertex_has_normal() ) {
|
||||
for (std::vector<VertexHandle>::iterator it = vertexHandles.begin(); it != vertexHandles.end(); ++it, i++)
|
||||
_bi.set_normal(*it, normals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// add color per vertex
|
||||
i=0;
|
||||
if ( colors.size() >= _bi.n_vertices() )
|
||||
for (std::vector<VertexHandle>::iterator it = vertexHandles.begin();
|
||||
it != vertexHandles.end(); ++it, i++) {
|
||||
_bi.set_color( *it, colors[i] );
|
||||
i = 0;
|
||||
if (colors.size() >= _bi.n_vertices())
|
||||
if (fileOptions.vertex_has_color() && userOptions.vertex_has_color()) {
|
||||
for (std::vector<VertexHandle>::iterator it = vertexHandles.begin(); it != vertexHandles.end(); ++it, i++)
|
||||
_bi.set_color(*it, colors[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -149,9 +149,12 @@ TEST_F(OpenMeshLoader, LoadSimpleOBJCheckHalfEdgeAndVertexNormals) {
|
||||
mesh_.request_halfedge_normals();
|
||||
mesh_.request_vertex_normals();
|
||||
|
||||
OpenMesh::IO::Options options;
|
||||
options += OpenMesh::IO::Options::VertexNormal;
|
||||
|
||||
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;
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -218,9 +247,12 @@ TEST_F(OpenMeshLoader, LoadSimpleOBJCheckTexCoords) {
|
||||
|
||||
mesh_.request_halfedge_texcoords2D();
|
||||
|
||||
OpenMesh::IO::Options options;
|
||||
options += OpenMesh::IO::Options::FaceTexCoord;
|
||||
|
||||
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;
|
||||
|
||||
@@ -255,13 +287,16 @@ TEST_F(OpenMeshLoader, LoadSimpleOBJWithVertexColorsAfterVertices) {
|
||||
|
||||
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_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(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";
|
||||
@@ -291,7 +326,10 @@ TEST_F(OpenMeshLoader, LoadSimpleOBJWithVertexColorsAsVCLines) {
|
||||
|
||||
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";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user