Fixed broken indices for some cases of OBJ parsing by using two passes
This commit is contained in:
@@ -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_;
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user