Commit f53429fd authored by Max Limper's avatar Max Limper

Fixed broken indices for some cases of OBJ parsing by using two passes

parent ffba4767
Pipeline #2573 passed with stage
in 78 minutes and 35 seconds
......@@ -279,6 +279,128 @@ read_material(std::fstream& _in)
}
return true;
}
//-----------------------------------------------------------------------------
bool
_OBJReader_::
read_vertices(std::istream& _in, BaseImporter& _bi, Options& _opt,
std::vector<Vec3f> & normals,
std::vector<Vec3f> & colors,
std::vector<Vec3f> & texcoords3d,
std::vector<Vec2f> & texcoords,
std::vector<VertexHandle> & 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<Vec3f> normals;
std::vector<Vec3f> colors;
std::vector<Vec3f> texcoords3d, face_texcoords3d;
std::vector<Vec2f> texcoords, face_texcoords;
std::vector<Vec3f> texcoords3d;
std::vector<Vec2f> texcoords;
std::vector<VertexHandle> vertexHandles;
BaseImporter::VHandles vhandles;
std::vector<Vec3f> face_texcoords3d;
std::vector<Vec2f> 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);
......
......@@ -170,8 +170,17 @@ private:
bool read_material( std::fstream& _in );
private:
bool read_vertices(std::istream& _in, BaseImporter& _bi, Options& _opt,
std::vector<Vec3f> & normals,
std::vector<Vec3f> & colors,
std::vector<Vec3f> & texcoords3d,
std::vector<Vec2f> & texcoords,
std::vector<VertexHandle> & vertexHandles,
Options & fileOptions);
std::string path_;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment