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;
|
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_::
|
_OBJReader_::
|
||||||
read(std::istream& _in, BaseImporter& _bi, Options& _opt)
|
read(std::istream& _in, BaseImporter& _bi, Options& _opt)
|
||||||
{
|
{
|
||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
std::string keyWrd;
|
std::string keyWrd;
|
||||||
|
|
||||||
float x, y, z, u, v, w;
|
|
||||||
float r, g, b;
|
|
||||||
BaseImporter::VHandles vhandles;
|
|
||||||
std::vector<Vec3f> normals;
|
std::vector<Vec3f> normals;
|
||||||
std::vector<Vec3f> colors;
|
std::vector<Vec3f> colors;
|
||||||
std::vector<Vec3f> texcoords3d, face_texcoords3d;
|
std::vector<Vec3f> texcoords3d;
|
||||||
std::vector<Vec2f> texcoords, face_texcoords;
|
std::vector<Vec2f> texcoords;
|
||||||
std::vector<VertexHandle> vertexHandles;
|
std::vector<VertexHandle> vertexHandles;
|
||||||
|
|
||||||
|
BaseImporter::VHandles vhandles;
|
||||||
|
std::vector<Vec3f> face_texcoords3d;
|
||||||
|
std::vector<Vec2f> face_texcoords;
|
||||||
|
|
||||||
std::string matname;
|
std::string matname;
|
||||||
|
|
||||||
std::stringstream stream, lineData, tmp;
|
std::stringstream stream, lineData, tmp;
|
||||||
@@ -310,7 +432,18 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
|
|||||||
// Options collected via file parsing
|
// Options collected via file parsing
|
||||||
Options fileOptions;
|
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() )
|
while( _in && !_in.eof() )
|
||||||
{
|
{
|
||||||
std::getline(_in,line);
|
std::getline(_in,line);
|
||||||
@@ -351,11 +484,11 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
|
|||||||
if ( matStream ){
|
if ( matStream ){
|
||||||
|
|
||||||
if ( !read_material( matStream ) )
|
if ( !read_material( matStream ) )
|
||||||
omerr() << " Warning! Could not read file properly!\n";
|
omerr() << " Warning! Could not read file properly!\n";
|
||||||
matStream.close();
|
matStream.close();
|
||||||
|
|
||||||
}else
|
}else
|
||||||
omerr() << " Warning! Material file '" << matFile << "' not found!\n";
|
omerr() << " Warning! Material file '" << matFile << "' not found!\n";
|
||||||
|
|
||||||
//omlog() << " " << materials_.size() << " materials loaded.\n";
|
//omlog() << " " << materials_.size() << " materials loaded.\n";
|
||||||
|
|
||||||
@@ -380,82 +513,7 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// vertex
|
// faces
|
||||||
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
|
|
||||||
else if (keyWrd == "f")
|
else if (keyWrd == "f")
|
||||||
{
|
{
|
||||||
int component(0), nV(0);
|
int component(0), nV(0);
|
||||||
|
|||||||
@@ -170,8 +170,17 @@ private:
|
|||||||
|
|
||||||
bool read_material( std::fstream& _in );
|
bool read_material( std::fstream& _in );
|
||||||
|
|
||||||
|
|
||||||
private:
|
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_;
|
std::string path_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user