diff --git a/src/OpenMesh/Core/IO/reader/OBJReader.cc b/src/OpenMesh/Core/IO/reader/OBJReader.cc index 3e8f8e39..2c7036c7 100644 --- a/src/OpenMesh/Core/IO/reader/OBJReader.cc +++ b/src/OpenMesh/Core/IO/reader/OBJReader.cc @@ -279,6 +279,128 @@ read_material(std::fstream& _in) } return true; } +//----------------------------------------------------------------------------- + +bool +_OBJReader_:: +read_vertices(std::istream& _in, BaseImporter& _bi, Options& _opt, + std::vector & normals, + std::vector & colors, + std::vector & texcoords3d, + std::vector & texcoords, + std::vector & vertexHandles, + Options & fileOptions) +{ + float x, y, z, u, v, w; + float r, g, b; + + std::string line; + std::string keyWrd; + + std::stringstream stream; + + + // Options supplied by the user + const Options & userOptions = _opt; + + while( _in && !_in.eof() ) + { + std::getline(_in,line); + if ( _in.bad() ){ + omerr() << " Warning! Could not read file properly!\n"; + return false; + } + + // Trim Both leading and trailing spaces + trimString(line); + + // comment + if ( line.size() == 0 || line[0] == '#' || isspace(line[0]) ) { + continue; + } + + stream.str(line); + stream.clear(); + + stream >> keyWrd; + + // vertex + if (keyWrd == "v") + { + stream >> x; stream >> y; stream >> z; + + if ( !stream.fail() ) + { + vertexHandles.push_back(_bi.add_vertex(OpenMesh::Vec3f(x,y,z))); + stream >> r; stream >> g; stream >> b; + + if ( !stream.fail() ) + { + if ( userOptions.vertex_has_color() ) { + fileOptions += Options::VertexColor; + colors.push_back(OpenMesh::Vec3f(r,g,b)); + } + } + } + } + + // texture coord + else if (keyWrd == "vt") + { + stream >> u; stream >> v; + + if ( !stream.fail() ){ + + 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; + + // try to read the w component as it is optional + stream >> w; + if ( !stream.fail() ) + texcoords3d.push_back(OpenMesh::Vec3f(u, v, w)); + + } + + }else{ + omerr() << "Only single 2D or 3D texture coordinate per vertex" + << "allowed!" << std::endl; + return false; + } + } + + // color per vertex + else if (keyWrd == "vc") + { + stream >> r; stream >> g; stream >> b; + + if ( !stream.fail() ){ + if ( userOptions.vertex_has_color() ) { + colors.push_back(OpenMesh::Vec3f(r,g,b)); + fileOptions += Options::VertexColor; + } + } + } + + // normal + else if (keyWrd == "vn") + { + stream >> x; stream >> y; stream >> z; + + if ( !stream.fail() ) { + if (userOptions.vertex_has_normal() ){ + normals.push_back(OpenMesh::Vec3f(x,y,z)); + fileOptions += Options::VertexNormal; + } + } + } + } + + return true; +} //----------------------------------------------------------------------------- @@ -286,19 +408,19 @@ bool _OBJReader_:: read(std::istream& _in, BaseImporter& _bi, Options& _opt) { - std::string line; std::string keyWrd; - float x, y, z, u, v, w; - float r, g, b; - BaseImporter::VHandles vhandles; std::vector normals; std::vector colors; - std::vector texcoords3d, face_texcoords3d; - std::vector texcoords, face_texcoords; + std::vector texcoords3d; + std::vector texcoords; std::vector vertexHandles; + BaseImporter::VHandles vhandles; + std::vector face_texcoords3d; + std::vector face_texcoords; + std::string matname; std::stringstream stream, lineData, tmp; @@ -310,7 +432,18 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt) // Options collected via file parsing Options fileOptions; + // pass 1: read vertices + if ( !read_vertices(_in, _bi, _opt, + normals, colors, texcoords3d, texcoords, + vertexHandles, fileOptions) ){ + return false; + } + // reset stream for second pass + _in.clear(); + _in.seekg(0, std::ios::beg); + + // pass 2: read vertices while( _in && !_in.eof() ) { std::getline(_in,line); @@ -351,11 +484,11 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt) if ( matStream ){ if ( !read_material( matStream ) ) - omerr() << " Warning! Could not read file properly!\n"; + omerr() << " Warning! Could not read file properly!\n"; matStream.close(); }else - omerr() << " Warning! Material file '" << matFile << "' not found!\n"; + omerr() << " Warning! Material file '" << matFile << "' not found!\n"; //omlog() << " " << materials_.size() << " materials loaded.\n"; @@ -380,82 +513,7 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt) } } - // vertex - else if (keyWrd == "v") - { - stream >> x; stream >> y; stream >> z; - - if ( !stream.fail() ) - { - vertexHandles.push_back(_bi.add_vertex(OpenMesh::Vec3f(x,y,z))); - stream >> r; stream >> g; stream >> b; - - if ( !stream.fail() ) - { - if ( userOptions.vertex_has_color() ) { - fileOptions += Options::VertexColor; - colors.push_back(OpenMesh::Vec3f(r,g,b)); - } - } - } - } - - // texture coord - else if (keyWrd == "vt") - { - stream >> u; stream >> v; - - if ( !stream.fail() ){ - - 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; - - // try to read the w component as it is optional - stream >> w; - if ( !stream.fail() ) - texcoords3d.push_back(OpenMesh::Vec3f(u, v, w)); - - } - - }else{ - omerr() << "Only single 2D or 3D texture coordinate per vertex" - << "allowed!" << std::endl; - return false; - } - } - - // color per vertex - else if (keyWrd == "vc") - { - stream >> r; stream >> g; stream >> b; - - if ( !stream.fail() ){ - if ( userOptions.vertex_has_color() ) { - colors.push_back(OpenMesh::Vec3f(r,g,b)); - fileOptions += Options::VertexColor; - } - } - } - - // normal - else if (keyWrd == "vn") - { - stream >> x; stream >> y; stream >> z; - - if ( !stream.fail() ) { - if (userOptions.vertex_has_normal() ){ - normals.push_back(OpenMesh::Vec3f(x,y,z)); - fileOptions += Options::VertexNormal; - } - } - } - - - // face + // faces else if (keyWrd == "f") { int component(0), nV(0); diff --git a/src/OpenMesh/Core/IO/reader/OBJReader.hh b/src/OpenMesh/Core/IO/reader/OBJReader.hh index d1fb0f39..70c3a2fe 100644 --- a/src/OpenMesh/Core/IO/reader/OBJReader.hh +++ b/src/OpenMesh/Core/IO/reader/OBJReader.hh @@ -170,8 +170,17 @@ private: bool read_material( std::fstream& _in ); + private: + bool read_vertices(std::istream& _in, BaseImporter& _bi, Options& _opt, + std::vector & normals, + std::vector & colors, + std::vector & texcoords3d, + std::vector & texcoords, + std::vector & vertexHandles, + Options & fileOptions); + std::string path_; };