Refactored a bit the obj importer to remove bug caused by meshes with and without textures
This commit is contained in:
parent
524f8e8a61
commit
95a2c62104
|
@ -41,17 +41,18 @@
|
|||
|
||||
|
||||
namespace vcg {
|
||||
namespace tri {
|
||||
namespace io {
|
||||
namespace tri {
|
||||
namespace io {
|
||||
|
||||
/**
|
||||
This class encapsulate a filter for importing obj (Alias Wavefront) meshes.
|
||||
Warning: this code assume little endian (PC) architecture!!!
|
||||
*/
|
||||
template <class OpenMeshType>
|
||||
class ImporterOBJ
|
||||
{
|
||||
public:
|
||||
/**
|
||||
This class encapsulate a filter for importing obj (Alias Wavefront) meshes.
|
||||
Warning: this code assume little endian (PC) architecture!!!
|
||||
*/
|
||||
|
||||
template <class OpenMeshType>
|
||||
class ImporterOBJ
|
||||
{
|
||||
public:
|
||||
static int &MRGBLineCount(){static int _MRGBLineCount=0; return _MRGBLineCount;}
|
||||
|
||||
typedef typename OpenMeshType::VertexPointer VertexPointer;
|
||||
|
@ -67,43 +68,23 @@ namespace vcg {
|
|||
{
|
||||
public:
|
||||
|
||||
Info()
|
||||
{
|
||||
mask = 0;
|
||||
cb = 0;
|
||||
numTexCoords=0;
|
||||
}
|
||||
Info() {}
|
||||
|
||||
/// It returns a bit mask describing the field preesnt in the ply file
|
||||
int mask;
|
||||
/// It returns a bit mask describing the field present in the obj file
|
||||
int mask=0;
|
||||
|
||||
/// a Simple callback that can be used for long obj parsing.
|
||||
// it returns the current position, and formats a string with a description of what th efunction is doing (loading vertexes, faces...)
|
||||
CallBackPos *cb;
|
||||
CallBackPos *cb=nullptr;
|
||||
|
||||
/// number of vertices
|
||||
int numVertices;
|
||||
/// number of edges
|
||||
int numEdges;
|
||||
/// number of faces (the number of triangles could be
|
||||
/// larger in presence of polygonal faces
|
||||
int numFaces;
|
||||
/// number of texture coords indexes
|
||||
int numTexCoords;
|
||||
/// number of normals
|
||||
int numFaces; // Note that numFaces can be different from the final number of triangles
|
||||
int numTexCoords=0;
|
||||
int numNormals;
|
||||
|
||||
}; // end class
|
||||
|
||||
|
||||
//struct OBJFacet
|
||||
//{
|
||||
// CoordType n;
|
||||
// CoordType t;
|
||||
// CoordType v[3];
|
||||
//
|
||||
// short attr; // material index
|
||||
//};
|
||||
struct ObjIndexedFace
|
||||
{
|
||||
void set(const int & num){v.resize(num);n.resize(num); t.resize(num);}
|
||||
|
@ -244,11 +225,6 @@ namespace vcg {
|
|||
if (oi.numVertices == 0)
|
||||
return E_NO_VERTEX;
|
||||
|
||||
// Commented out this test. You should be allowed to load point clouds.
|
||||
//if (oi.numFaces == 0)
|
||||
// return E_NO_FACE;
|
||||
|
||||
|
||||
std::ifstream stream(filename);
|
||||
if (stream.fail())
|
||||
{
|
||||
|
@ -420,7 +396,7 @@ namespace vcg {
|
|||
|
||||
if( (vertexesPerFace>3) && OpenMeshType::FaceType::HasPolyInfo() )
|
||||
{
|
||||
//_BEGIN___ if you are loading a GENERIC POLYGON mesh
|
||||
//_BEGIN___ if you are filling a vcg mesh with GENERIC POLYGON
|
||||
ff.set(vertexesPerFace);
|
||||
for(int i=0;i<vertexesPerFace;++i) { // remember index starts from 1 instead of 0
|
||||
SplitToken(tokens[i+1], ff.v[i], ff.n[i], ff.t[i], inputMask);
|
||||
|
@ -474,11 +450,11 @@ namespace vcg {
|
|||
++numTriangles;
|
||||
indexedFaces.push_back(ff);
|
||||
|
||||
//_END ___ if you are loading a GENERIC POLYGON mesh
|
||||
//_END ___ if you are filling a vcg mesh with GENERIC POLYGON
|
||||
}
|
||||
else
|
||||
{
|
||||
//_BEGIN___ if you are loading a TRIMESH mesh
|
||||
//_BEGIN___ if you are filling a vcg mesh with TRIANGLES
|
||||
std::vector<std::vector<vcg::Point3f> > polygonVect(1); // it is a vector of polygon loops
|
||||
polygonVect[0].resize(vertexesPerFace);
|
||||
std::vector<int> indexVVect(vertexesPerFace);
|
||||
|
@ -599,7 +575,7 @@ namespace vcg {
|
|||
indexedFaces.push_back(ff);
|
||||
}
|
||||
|
||||
}
|
||||
} //_END ___ if you are filling a vcg mesh with TRIANGLES
|
||||
}
|
||||
else if ((header.compare("mtllib")==0) && (tokens.size() > 1)) // material library
|
||||
{
|
||||
|
@ -615,7 +591,7 @@ namespace vcg {
|
|||
}
|
||||
else if ((header.compare("usemtl")==0) && (tokens.size() > 1)) // material usage
|
||||
{
|
||||
// emergency check. If there are no materials, the materail library failed to load or was not specified
|
||||
// emergency check. If there are no materials, the material library failed to load or was not specified
|
||||
// but there are tools that save the material library with the same name of the file, but do not add the
|
||||
// "mtllib" definition in the header. So, we can try to see if this is the case
|
||||
if ((materials.size() == 1)&&(materials[0].materialName == "")){
|
||||
|
@ -860,7 +836,16 @@ namespace vcg {
|
|||
if (hasNormal)
|
||||
nId = atoi(token.substr(secondSep + 1).c_str()) - 1;
|
||||
}
|
||||
/** returns a Point3f done from (tokens[pos],tokens[pos+1],tokens[pos+2])
|
||||
|
||||
*/
|
||||
static Point3f Point3fFrom3Tokens(std::vector< std::string > &tokens, int pos)
|
||||
{
|
||||
float r = (float) atof(tokens[pos+0].c_str());
|
||||
float g = (float) atof(tokens[pos+1].c_str());
|
||||
float b = (float) atof(tokens[pos+2].c_str());
|
||||
return Point3f(r, g, b);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Retrieves infos about kind of data stored into the file and fills a mask appropriately
|
||||
|
@ -1028,54 +1013,34 @@ namespace vcg {
|
|||
}
|
||||
else if (header.compare("Ka")==0)
|
||||
{
|
||||
if (tokens.size() < 4)
|
||||
return false;
|
||||
float r = (float) atof(tokens[1].c_str());
|
||||
float g = (float) atof(tokens[2].c_str());
|
||||
float b = (float) atof(tokens[3].c_str());
|
||||
|
||||
currentMaterial.Ka = Point3f(r, g, b);
|
||||
if (tokens.size() < 4) return false;
|
||||
currentMaterial.Ka = Point3fFrom3Tokens(tokens,1);
|
||||
}
|
||||
else if (header.compare("Kd")==0)
|
||||
{
|
||||
if (tokens.size() < 4)
|
||||
return false;
|
||||
float r = (float) atof(tokens[1].c_str());
|
||||
float g = (float) atof(tokens[2].c_str());
|
||||
float b = (float) atof(tokens[3].c_str());
|
||||
|
||||
currentMaterial.Kd = Point3f(r, g, b);
|
||||
if (tokens.size() < 4) return false;
|
||||
currentMaterial.Kd = Point3fFrom3Tokens(tokens,1);
|
||||
}
|
||||
else if (header.compare("Ks")==0)
|
||||
{
|
||||
if (tokens.size() < 4)
|
||||
return false;
|
||||
float r = (float) atof(tokens[1].c_str());
|
||||
float g = (float) atof(tokens[2].c_str());
|
||||
float b = (float) atof(tokens[3].c_str());
|
||||
|
||||
currentMaterial.Ks = Point3f(r, g, b);
|
||||
if (tokens.size() < 4) return false;
|
||||
currentMaterial.Ks = Point3fFrom3Tokens(tokens,1);
|
||||
}
|
||||
else if ( (header.compare("d")==0) ||
|
||||
(header.compare("Tr")==0) ) // alpha
|
||||
{
|
||||
if (tokens.size() < 2)
|
||||
return false;
|
||||
if (tokens.size() < 2) return false;
|
||||
currentMaterial.Tr = (float) atof(tokens[1].c_str());
|
||||
}
|
||||
else if (header.compare("Ns")==0) // shininess
|
||||
{
|
||||
if (tokens.size() < 2)
|
||||
return false;
|
||||
if (tokens.size() < 2) return false;
|
||||
currentMaterial.Ns = float(atoi(tokens[1].c_str()));
|
||||
}
|
||||
else if (header.compare("illum")==0) // specular illumination on/off
|
||||
{
|
||||
if (tokens.size() < 2)
|
||||
return false;
|
||||
int illumination = atoi(tokens[1].c_str());
|
||||
//currentMaterial.bSpecular = (illumination == 2);
|
||||
currentMaterial.illum = illumination;
|
||||
if (tokens.size() < 2) return false;
|
||||
currentMaterial.illum = atoi(tokens[1].c_str());;
|
||||
}
|
||||
else if(header.compare("map_Kd")==0) // texture name
|
||||
{
|
||||
|
@ -1091,22 +1056,12 @@ namespace vcg {
|
|||
|
||||
// adding texture name into textures vector (if not already present)
|
||||
// avoid adding the same name twice
|
||||
bool found = false;
|
||||
unsigned int size = static_cast<unsigned int>(textures.size());
|
||||
unsigned j = 0;
|
||||
while (!found && (j < size))
|
||||
{
|
||||
if (textureName.compare(textures[j])==0)
|
||||
{
|
||||
currentMaterial.index = (int)j;
|
||||
found = true;
|
||||
}
|
||||
++j;
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
auto it = std::find(textures.begin(), textures.end(), textureName);
|
||||
if(it==textures.end()) {
|
||||
currentMaterial.index = textures.size();
|
||||
textures.push_back(textureName);
|
||||
currentMaterial.index = (int)size;
|
||||
} else {
|
||||
currentMaterial.index = std::distance(textures.begin(),it);
|
||||
}
|
||||
}
|
||||
// we simply ignore other situations
|
||||
|
@ -1115,13 +1070,27 @@ namespace vcg {
|
|||
materials.push_back(currentMaterial); // add last read material
|
||||
|
||||
stream.close();
|
||||
// Sometimes some materials have texture and no texture
|
||||
// in this case for sake of uniformity we just use the first texture.
|
||||
if(!textures.empty())
|
||||
{
|
||||
for(size_t i=0;i<materials.size();++i)
|
||||
{
|
||||
if(materials[i].map_Kd.empty())
|
||||
{
|
||||
materials[i].map_Kd=textures[0];
|
||||
materials[i].index=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}; // end class
|
||||
} // end Namespace tri
|
||||
} // end Namespace io
|
||||
}; // end class
|
||||
} // end Namespace tri
|
||||
} // end Namespace io
|
||||
} // end Namespace vcg
|
||||
|
||||
#endif // ndef __VCGLIB_IMPORT_OBJ
|
||||
|
|
Loading…
Reference in New Issue