Example #1
0
void Mesh::loadOBJ(const char* filePath){
	QFile file(filePath);
	if(!file.open(QIODevice::ReadOnly)){
		return;
	}
	QTextStream data(&file);
	int usingMTL = 0;
	while(!data.atEnd()){
		QString line = data.readLine();
		if(line.size() == 0 || line[0] == '#')
			continue;
		QStringList arg = line.split(' ');
		if(arg.size() >= 4 && arg[0] == "v"){
			vertices.push_back(vec3(arg[1].toFloat(), arg[2].toFloat(), arg[3].toFloat()));
		}
		else if(arg.size() >= 3 && arg[0] == "vt"){
			uvs.push_back(vec3(arg[1].toFloat(), arg[2].toFloat(), 0));
		}
		else if(arg.size() >= 4 && arg[0] == "vn"){
			normals.push_back(vec3(arg[1].toFloat(), arg[2].toFloat(), arg[3].toFloat()));
		}
		else if(arg.size() >= 4 && arg[0] == "f"){
			QVector<VerticesData> f;
			for(int i = 1;i<arg.size();++i){
				VerticesData index;
				QStringList info = arg[i].split('/');
				if(info.size() == 1){
					index.v = info[0].toInt() - 1;
					index.vt = -1;
					index.vn = -1;
				}
				else if(info.size() == 2){
					index.v = info[0].toInt() - 1;
					index.vt = info[1].toInt() - 1;
					index.vn = -1;
				}
				else if(info.size() == 3){
					index.v = info[0].toInt() - 1;
					index.vt = info[1].toInt() - 1;
					index.vn = info[2].toInt() - 1;
				}
				f.push_back(index);
			}
			faces[usingMTL].push_back(f);
		}
		else if(arg.size() >= 2 && arg[0] == "mtllib"){
			QString path;
			QStringList pathSplit = QString(filePath).split('/');
			for(int i = 0;i < pathSplit.size()-1;++i)
				path += pathSplit[i] + '/';
			loadMTL(arg[1], path);
		}
		else if(arg.size() >= 2 && arg[0] == "usemtl"){
			usingMTL = materialName[arg[1]];
		}
	}
	file.close();
	update();
}
void renderObject::genBuffer(GLuint shader)
{
	glDisableVertexAttribArray;

	std::vector< GLuint > indexes;
	std::vector < objBuffer > objB;
	std::string mtlFileName;
	
	std::string fileName = "mustang.obj";
	bool res;
	
	res = loadOBJ(MESH_FOLDER + fileName, mtlFileName, objB, indexes);
	res = loadMTL(MESH_FOLDER + mtlFileName, mtl);
	res = loadTexture(MESH_FOLDER + mtl.texturePath, textureID);
	indexSize = indexes.size();

	glGenBuffers(1, &vBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, vBuffer);
	glBufferData(GL_ARRAY_BUFFER, objB.size() * sizeof(objBuffer), &objB[0], GL_DYNAMIC_DRAW);

	glGenBuffers(1, &indexBuffer);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexes.size() * sizeof(GLuint), &indexes[0], GL_DYNAMIC_DRAW);

	glGenVertexArrays(1, &vArray);
	glBindVertexArray(vArray);

	GLuint vertexPos = glGetAttribLocation(shader, "vertex_position");
	glEnableVertexAttribArray(vertexPos);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(objBuffer), BUFFER_OFFSET(0));
	
	GLuint textureNormal = glGetAttribLocation(shader, "texture_normal");
	glEnableVertexAttribArray(textureNormal);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(objBuffer), BUFFER_OFFSET(3 * sizeof(GLfloat)));
	
	GLuint vertexNormal = glGetAttribLocation(shader, "vertex_normal");
	glEnableVertexAttribArray(vertexNormal);
	glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(objBuffer), BUFFER_OFFSET(5 * sizeof(GLfloat)));

	glFlush();
}
Example #3
0
/*! \brief load the geometry defined in an OBJ/Wavefront file
 *  \param filename is the path to the OJB file
 */
ObjReader::ObjReader(const char *filename)
{
    std::ifstream ifs;
    // extract the path from the filename (used to read the material file)
    std::string path = getFilePath(filename);
    try {
        ifs.open(filename);
        if (ifs.fail()) throw std::runtime_error("can't open file " + std::string(filename));

        // create a default material
        std::shared_ptr<Material> defaultMaterial(new Material("Default"));
        curMaterial = defaultMaterial;

        char line[MAX_LINE_LENGTH]; // line buffer
        
        while (ifs.peek() != EOF) // read each line until EOF is found
        {
            ifs.getline(line, sizeof(line), '\n');
            const char* token = line + strspn(line, " \t"); // ignore space and tabs

			//printf("strncmp(token, vt,  2) --> %d\n", strncmp(token, "vt",  2));
            if (token[0] == 0) continue; // line is empty, ignore
            // read a vertex
            if (token[0] == 'v' && isSep(token[1])) { v.push_back(getVec3f(token += 2)); continue; }
            // read a normal
            if (!strncmp(token, "vn",  2) && isSep(token[2])) { vn.push_back(getVec3f(token += 3)); continue; }
            // read a texture coordinates
            if (!strncmp(token, "vt",  2) && isSep(token[2])) { vt.push_back(getVec2f(token += 3)); continue; }
            //if (!strncmp(token, "vt",  2) && isSep(token[2])) { printf("vt: %.3f\n", getVec2f(token += 3).x); continue; }
            // read a face
            if (token[0] == 'f' && isSep(token[1])) {
                parseSep(token += 1);
                std::vector<Vertex> face;
                while (token[0]) {
                    face.push_back(getInt3(token));
                    parseSepOpt(token);
                }
                curGroup.push_back(face);
                continue;
            }
            
            /*! use material */
            if (!strncmp(token, "usemtl", 6) && isSep(token[6]))
            {
                flushFaceGroup();
                std::string name(parseSep(token += 6));
                if (materials.find(name) == materials.end()) curMaterial = defaultMaterial;
                else curMaterial = materials[name];
                continue;
            }
            
            /* load material library */
            if (!strncmp(token, "mtllib", 6) && isSep(token[6])) {
                loadMTL(path + "/" + std::string(parseSep(token += 6)));
                continue;
            }
        }
    }
    catch (const std::exception &e) {
        std::cerr << e.what() << std::endl;
    }
    flushFaceGroup(); // flush the last loaded object
    ifs.close();
}
  OBJLoader::OBJLoader(const FileName &fileName, const bool subdivMode) 
    : path(fileName.path()), group(new SceneGraph::GroupNode), subdivMode(subdivMode)
  {
    /* open file */
    std::ifstream cin;
    cin.open(fileName.c_str());
    if (!cin.is_open()) {
      THROW_RUNTIME_ERROR("cannot open " + fileName.str());
      return;
    }

    /* generate default material */
    Material objmtl; new (&objmtl) OBJMaterial;
    Ref<SceneGraph::MaterialNode> defaultMaterial = new SceneGraph::MaterialNode(objmtl);
    curMaterial = defaultMaterial;

    char line[10000];
    memset(line, 0, sizeof(line));

    while (cin.peek() != -1)
    {
      /* load next multiline */
      char* pline = line;
      while (true) {
        cin.getline(pline, sizeof(line) - (pline - line) - 16, '\n');
        ssize_t last = strlen(pline) - 1;
        if (last < 0 || pline[last] != '\\') break;
        pline += last;
        *pline++ = ' ';
      }

      const char* token = trimEnd(line + strspn(line, " \t"));
      if (token[0] == 0) continue;

      /*! parse position */
      if (token[0] == 'v' && isSep(token[1])) { 
        v.push_back(getVec3f(token += 2)); continue;
      }

      /* parse normal */
      if (token[0] == 'v' && token[1] == 'n' && isSep(token[2])) { 
        vn.push_back(getVec3f(token += 3)); 
        continue; 
      }

      /* parse texcoord */
      if (token[0] == 'v' && token[1] == 't' && isSep(token[2])) { vt.push_back(getVec2f(token += 3)); continue; }

      /*! parse face */
      if (token[0] == 'f' && isSep(token[1]))
      {
        parseSep(token += 1);

        std::vector<Vertex> face;
        while (token[0]) {
	  Vertex vtx = getInt3(token);
          face.push_back(vtx);
          parseSepOpt(token);
        }
        curGroup.push_back(face);
        continue;
      }

      /*! parse edge crease */
      if (token[0] == 'e' && token[1] == 'c' && isSep(token[2]))
      {
	parseSep(token += 2);
	float w = getFloat(token);
	parseSepOpt(token);
	int a = fix_v(getInt(token));
	parseSepOpt(token);
	int b = fix_v(getInt(token));
	parseSepOpt(token);
	ec.push_back(Crease(w, a, b));
	continue;
      }

      /*! use material */
      if (!strncmp(token, "usemtl", 6) && isSep(token[6]))
      {
        flushFaceGroup();
        std::string name(parseSep(token += 6));
        if (material.find(name) == material.end()) curMaterial = defaultMaterial;
        else curMaterial = material[name];
        continue;
      }

      /* load material library */
      if (!strncmp(token, "mtllib", 6) && isSep(token[6])) {
        loadMTL(path + std::string(parseSep(token += 6)));
        continue;
      }

      // ignore unknown stuff
    }
    flushFaceGroup();

    cin.close();
  }
Example #5
0
nMeshInstance *nObjFileLoader::loadObjMesh(string name, string object, double scale, nMeshInstance *inst)
{
	if(!isupper(name[0]) && !(name.substr(1, 3) == "/:" || name.substr(1, 3) == "\\:"))
		name = nGine::instance()->appPath() + name;

	nTimer timer;
	timer.start();

	ifstream file(name.c_str(), ios::in);
	if(!file)
	{
		nGine::instance()->getLogger()->addDebugLog("\nUnable to open " + name);
		return 0;
	}

	nMeshInstance *dp = inst;
	if(!dp)
		dp = new nMeshInstance;
	bool cull  = false;
	string line;

	unsigned int totalVertexCount = 0;
	unsigned int triangleCount = 0;
	while(getline(file, line))
		if(line.substr(0, 1) == "o")
			cull = (line.substr(2) != object && object.size());
		else if(line.substr(0, 2) == "v ")
			totalVertexCount++;
		else if(line.substr(0, 1) == "f" && !cull)
			triangleCount++;

	file.close();
	file.open(name.c_str(), ios::in);

	unsigned int triangles = 0;

	nIndexedTriangle *indexedTriangles = new nIndexedTriangle[triangleCount];

	vector<vector<unsigned int> > index;
	vector<nVertex> vertices;
	vector<nVec3> normals;
	vector<nVec2> coords;
	vector<nMaterial *> materials;
	string obj;
	nMaterial *mat = 0;
	bool smooth = false;

	unsigned int vertexCount = 0;

	unsigned int li = 0;

	index.resize(totalVertexCount);
	//int faceParseType = 0; // 0 = unknown, 1 = position only, 2 = position + normal, 3 = pos + norm + tex

	while(getline(file, line))
	{
		if(line.substr(0, 2) == "vt")
		{
			nVec2 c;
			sscanf(&line[0], "vt %lf %lf", &c.x, &c.y);
			coords.push_back(c);
		}
		else if(line.substr(0, 2) == "vn")
		{
			nVec3 n;
			sscanf(&line[0], "vn %lf %lf %lf", &n.x, &n.y, &n.z);
			normals.push_back(n);
		}
		else if(line.substr(0, 2) == "v ")
		{
			nVec3 v;
			sscanf(&line[0], "v %lf %lf %lf", &v.x, &v.y, &v.z);
			index[vertexCount].push_back(vertices.size());
			vertices.push_back(nVertex(v * scale));
			vertexCount++;
		}
	}

	//cout<<" ["<<timer.elapsed()<<"]";

	file.close();
	file.open(name.c_str(), ios::in);

	while(getline(file, line))
	{
		li++;
		if(line.substr(0, 1) == "o")
		{
			bool culled = cull;
			obj = line.substr(2);
			cull = (obj != object && object.size());
			if(cull && !culled)
				break;
		}
		else if(line.substr(0, 6) == "mtllib")
		{
			string fileName;
			unsigned int backslash = name.find_last_of('\\');
			unsigned int slash = name.find_last_of('/');
			if(backslash != string::npos && (backslash > slash || slash == string::npos))
				fileName = name.substr(0, name.find_last_of('\\')) + "\\" + line.substr(7);
			else if(slash != string::npos)
				fileName = name.substr(0, name.find_last_of('/')) + "/" + line.substr(7);
			else
				fileName = line.substr(7);
			materials = loadMTL(fileName);
		}
		else if(line.substr(0, 6) == "usemtl")
		{
			mat = materials[0];
			for(double i = 0; i != materials.size(); i++)
				if(materials[i]->getName() == line.substr(7))
				{
					mat = materials[i];
					break;
				}
		}
		else if(line.substr(0, 1) == "s")
		{
			smooth = (line != "s off");
		}
		else if(line.substr(0, 1) == "f" && !cull)
		{
			if(line.find("//") != string::npos)
			{
				unsigned int v[6];
				sscanf(&line[0], "f %d//%d %d//%d %d//%d", &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
				bool exists[3] = {false, false, false};
				nIndexedTriangle tr;
				tr.material = mat;
				for(unsigned int j = 0; j != 3; j++)
					for(unsigned int i = 0; i != index[v[2 * j] - 1].size(); i++)
						if(vertices[index[v[2 * j] - 1][i]].normal.isNull() || vertices[index[v[2 * j] - 1][i]].normal == normals[v[2 * j + 1] - 1])
						{
							tr.v[j] = index[v[2 * j] - 1][i];
							vertices[index[v[2 * j] - 1][i]].normal = normals[v[2 * j + 1] - 1];
							exists[j] = true;
						}
				for(unsigned int j = 0; j != 3; j++)
					if(!exists[j])
					{
						index[v[2 * j] - 1].push_back(vertices.size());
						tr.v[j] = vertices.size();
						vertices.push_back(nVertex(vertices[v[2 * j] - 1].position, normals[v[2 * j + 1] - 1]));
					}
				indexedTriangles[triangles] = tr;
				triangles++;
			}
			else if(line.find("/") != string::npos)
			{
				unsigned int v[9];
				sscanf(&line[0], "f %d/%d/%d %d/%d/%d %d/%d/%d", &v[0], &v[1], &v[2], &v[3], &v[4], &v[5], &v[6], &v[7], &v[8]);
				bool exists[3] = {false, false, false};
				nIndexedTriangle tr;
				tr.material = mat;
				for(unsigned int j = 0; j != 3; j++)
					for(unsigned int i = 0; i != index[v[3 * j] - 1].size(); i++)
						#ifdef N_MULTI_TEX_COORD
							if((vertices[index[v[3 * j] - 1][i]].normal.isNull() || vertices[index[v[3 * j] - 1][i]].normal == normals[v[3 * j + 2] - 1])
							&& (isinf(vertices[index[v[3 * j] - 1][i]].tex[0].x) || vertices[index[v[3 * j] - 1][i]].tex[0] == coords[v[3 * j + 1] - 1]))
						#else
							if((vertices[index[v[3 * j] - 1][i]].normal.isNull() || vertices[index[v[3 * j] - 1][i]].normal == normals[v[3 * j + 2] - 1])
							&& (isinf(vertices[index[v[3 * j] - 1][i]].coords.x) || vertices[index[v[3 * j] - 1][i]].coords == coords[v[3 * j + 1] - 1]))
						#endif
						{
							tr.v[j] = index[v[3 * j] - 1][i];
							vertices[index[v[3 * j] - 1][i]].normal = normals[v[3 * j + 2] - 1];
							#ifdef N_MULTI_TEX_COORD
								vertices[index[v[3 * j] - 1][i]].tex[0] = coords[v[3 * j + 1] - 1];
							#else
								vertices[index[v[3 * j] - 1][i]].coords = coords[v[3 * j + 1] - 1];
							#endif
							exists[j] = true;
						}
				for(unsigned int j = 0; j != 3; j++)
					if(!exists[j])
					{
						index[v[3 * j] - 1].push_back(vertices.size());
						tr.v[j] = vertices.size();
						vertices.push_back(nVertex(vertices[v[3 * j] - 1].position, normals[v[3 * j + 2] - 1], coords[v[3 * j + 1] - 1]));
					}
				indexedTriangles[triangles] = tr;
				triangles++;
			}
			else
			{
				unsigned int v1[3];
				sscanf(&line[0], "f %d %d %d", &v1[0], &v1[1], &v1[2]);
				indexedTriangles[triangles] = nIndexedTriangle(v1[0] - 1, v1[1] - 1, v1[2] - 1, mat);
				triangles++;
			}
		}
	}
	for(unsigned int i = 0; i != vertices.size(); i++)
		dp->addVertex(vertices[i]);
	for(unsigned int i = 0; i != triangles; i++)
		dp->addTriangle(indexedTriangles[i]);
	delete indexedTriangles;

	for(unsigned int i = 0; i != index.size(); i++)
		index[i].clear();
	index.clear();
	vertices.clear();
	normals.clear();
	coords.clear();
	materials.clear();


	if(object.size())
		dp->computeUnused();

	cout<<"    ["<<timer.reset() * 1000<<"ms]";
	dp->build(nMeshInstance::Mesh);
	cout<<" ["<<timer.elapsed() * 1000<<"ms]"<<endl;

	return dp;

	/*string line;

	while(getline(file, line))
		if(line.substr(0, 1) == "o")
			cull = (line.substr(2) != object && object.size());
		else if(line.substr(0, 2) == "v ")
			dp->setVertexCount(dp->getVertexCount() + 1);
		else if(line.substr(0, 1) == "f" && !cull)
			dp->setTriangleCount(dp->getTriangleCount() + 1);

	file.close();
	file.open(name.c_str(), ios::in);

	unsigned int triangles = 0;

	dp->triangles = new nIndexedTriangle[dp->getTriangleCount()];

	vector<vector<unsigned int> > index;
	vector<nVertex> vertices;
	vector<nVec3> normals;
	vector<nVec2> coords;
	vector<nMaterial *> materials;
	string obj;
	nMaterial *mat = 0;
	bool smooth = false;

	unsigned int vertexCount = 0;

	unsigned int li = 0;

	index.resize(dp->getVertexCount());
	//int faceParseType = 0; // 0 = unknown, 1 = position only, 2 = position + normal, 3 = pos + norm + tex

	while(getline(file, line))
	{
		if(line.substr(0, 2) == "vt")
		{
			nVec2 c;
			sscanf(&line[0], "vt %lf %lf", &c.x, &c.y);
			coords.push_back(c);
		}
		else if(line.substr(0, 2) == "vn")
		{
			nVec3 n;
			sscanf(&line[0], "vn %lf %lf %lf", &n.x, &n.y, &n.z);
			normals.push_back(n);
		}
		else if(line.substr(0, 2) == "v ")
		{
			nVec3 v;
			sscanf(&line[0], "v %lf %lf %lf", &v.x, &v.y, &v.z);
			index[vertexCount].push_back(vertices.size());
			vertices.push_back(nVertex(v * scale));
			vertexCount++;
		}
	}

	//cout<<" ["<<timer.elapsed()<<"]";

	file.close();
	file.open(name.c_str(), ios::in);

	while(getline(file, line))
	{
		li++;
		if(line.substr(0, 1) == "o")
		{
			bool culled = cull;
			obj = line.substr(2);
			cull = (obj != object && object.size());
			if(cull && !culled)
				break;
		}
		else if(line.substr(0, 6) == "mtllib")
		{
			string fileName;
			unsigned int backslash = name.find_last_of('\\');
			unsigned int slash = name.find_last_of('/');
			if(backslash != string::npos && (backslash > slash || slash == string::npos))
				fileName = name.substr(0, name.find_last_of('\\')) + "\\" + line.substr(7);
			else if(slash != string::npos)
				fileName = name.substr(0, name.find_last_of('/')) + "/" + line.substr(7);
			else
				fileName = line.substr(7);
			materials = loadMTL(fileName);
		}
		else if(line.substr(0, 6) == "usemtl")
		{
			mat = materials[0];
			for(double i = 0; i != materials.size(); i++)
				if(materials[i]->getName() == line.substr(7))
				{
					mat = materials[i];
					break;
				}
		}
		else if(line.substr(0, 1) == "s")
		{
			smooth = (line != "s off");
		}
		else if(line.substr(0, 1) == "f" && !cull)
		{
			if(line.find("//") != string::npos)
			{
				unsigned int v[6];
				sscanf(&line[0], "f %d//%d %d//%d %d//%d", &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
				bool exists[3] = {false, false, false};
				nIndexedTriangle tr;
				tr.material = mat;
				for(unsigned int j = 0; j != 3; j++)
					for(unsigned int i = 0; i != index[v[2 * j] - 1].size(); i++)
						if(vertices[index[v[2 * j] - 1][i]].normal.isNull() || vertices[index[v[2 * j] - 1][i]].normal == normals[v[2 * j + 1] - 1])
						{
							tr.v[j] = index[v[2 * j] - 1][i];
							vertices[index[v[2 * j] - 1][i]].normal = normals[v[2 * j + 1] - 1];
							exists[j] = true;
						}
				for(unsigned int j = 0; j != 3; j++)
					if(!exists[j])
					{
						index[v[2 * j] - 1].push_back(vertices.size());
						tr.v[j] = vertices.size();
						vertices.push_back(nVertex(vertices[v[2 * j] - 1].position, normals[v[2 * j + 1] - 1]));
					}
				dp->triangles[triangles] = tr;
				triangles++;
			}
			else if(line.find("/") != string::npos)
			{
				unsigned int v[9];
				sscanf(&line[0], "f %d/%d/%d %d/%d/%d %d/%d/%d", &v[0], &v[1], &v[2], &v[3], &v[4], &v[5], &v[6], &v[7], &v[8]);
				bool exists[3] = {false, false, false};
				nIndexedTriangle tr;
				tr.material = mat;
				for(unsigned int j = 0; j != 3; j++)
					for(unsigned int i = 0; i != index[v[3 * j] - 1].size(); i++)
						#ifdef N_MULTI_TEX_COORD
							if((vertices[index[v[3 * j] - 1][i]].normal.isNull() || vertices[index[v[3 * j] - 1][i]].normal == normals[v[3 * j + 2] - 1])
							&& (isinf(vertices[index[v[3 * j] - 1][i]].tex[0].x) || vertices[index[v[3 * j] - 1][i]].tex[0] == coords[v[3 * j + 1] - 1]))
						#else
							if((vertices[index[v[3 * j] - 1][i]].normal.isNull() || vertices[index[v[3 * j] - 1][i]].normal == normals[v[3 * j + 2] - 1])
							&& (isinf(vertices[index[v[3 * j] - 1][i]].coords.x) || vertices[index[v[3 * j] - 1][i]].coords == coords[v[3 * j + 1] - 1]))
						#endif
						{
							tr.v[j] = index[v[3 * j] - 1][i];
							vertices[index[v[3 * j] - 1][i]].normal = normals[v[3 * j + 2] - 1];
							#ifdef N_MULTI_TEX_COORD
								vertices[index[v[3 * j] - 1][i]].tex[0] = coords[v[3 * j + 1] - 1];
							#else
								vertices[index[v[3 * j] - 1][i]].coords = coords[v[3 * j + 1] - 1];
							#endif
							exists[j] = true;
						}
				for(unsigned int j = 0; j != 3; j++)
					if(!exists[j])
					{
						index[v[3 * j] - 1].push_back(vertices.size());
						tr.v[j] = vertices.size();
						vertices.push_back(nVertex(vertices[v[3 * j] - 1].position, normals[v[3 * j + 2] - 1], coords[v[3 * j + 1] - 1]));
					}
				dp->triangles[triangles] = tr;
				triangles++;
			}
			else
			{
				unsigned int v1[3];
				sscanf(&line[0], "f %d %d %d", &v1[0], &v1[1], &v1[2]);
				dp->triangles[triangles] = nIndexedTriangle(v1[0] - 1, v1[1] - 1, v1[2] - 1, mat);
				triangles++;
			}
		}
	}
	dp->setVertexCount(vertices.size());
	dp->vertices = new nVertex[dp->getVertexCount()];
	for(unsigned int i = 0; i != dp->getVertexCount(); i++)
		dp->vertices[i] = vertices[i];

	for(unsigned int i = 0; i != index.size(); i++)
		index[i].clear();
	index.clear();
	vertices.clear();
	normals.clear();
	coords.clear();
	materials.clear();


	if(object.size())
		dp->computeUnused();

	cout<<"    ["<<timer.reset() * 1000<<"ms]";
	dp->build(nMeshInstance::BuildMesh);
	cout<<" ["<<timer.elapsed() * 1000<<"ms]"<<endl;

	return dp;*/
}
Example #6
0
bool ObjModel::loadOBJ(string filePath, string objFile){
    this->filePath = filePath;
    this->objFile = objFile;
    
    cout << "Loading OBJ file " << objFile << endl;
    
    vector<unsigned int> vertexIndices, textureIndices, normalIndices;
    
    vector<vec3> temp_vertices;
    vector<vec2> temp_textures;
    vector<vec3> temp_normals;
    
    
    ObjGroup temp_group;
    
    
    string filename = filePath + "/" + objFile;
    
    FILE* file = fopen(filename.c_str(), "r");
    
    if( file == NULL ){
        printf("Impossible to open the OBJ file !!!\n");
        return false;
    }
    
    while(true){
        
        char lineHeader[128];
        // read the first word of the line
        int res = fscanf(file, "%s", lineHeader);
        if (res == EOF)
            break; // EOF = End Of File. Quit the loop.
        
        // else : parse lineHeader
        
        
        
        if (strcmp(lineHeader, "mtllib") == 0 ){
            char ch[128];
            fscanf(file, "%s", ch);
            mtlFile = ch;
            
            loadMTL();
        }
        
        else if (strcmp(lineHeader, "g") == 0 ){
            if (!temp_group.name.empty()){
                groups.push_back(temp_group);
            }
            temp_group.clear();
            
            char chname[128];
            fscanf(file, "%s", chname);
            temp_group.name = chname;
        }
        else if (strcmp(lineHeader, "usemtl") == 0 ){
            if (!temp_group.quads.empty() || !temp_group.triangles.empty()){
                groups.push_back(temp_group);
                temp_group.clear();
            }
            
            char chmtl[128];
            fscanf(file, "%s", chmtl);
            temp_group.material = chmtl;
        }
        else if (strcmp(lineHeader, "v") == 0){
            vec3 vertex;
            fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z );
            temp_vertices.push_back(vertex);
        }
        else if (strcmp(lineHeader, "vt") == 0 ){
            vec2 uv;
            fscanf(file, "%f %f\n", &uv.x, &uv.y );
            //            uv.y = -uv.y; // Invert V coordinate since we will only use DDS texture, which are inverted. Remove if you want to use TGA or BMP loaders.
            temp_textures.push_back(uv);
            

        }
        else if (strcmp(lineHeader, "vn") == 0 ){
            vec3 normal;
            fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z );
            temp_normals.push_back(normal);
        }
        else if (strcmp(lineHeader, "f") == 0 ){
            bool isTriangle = true;
            unsigned int vertexIndex[4], textureIndex[4], normalIndex[4];
            
            for (int k = 0; k < 4; k++){
                char c_s[100];
                fscanf(file, "%s", c_s);
                string s(c_s);
                
                if (k == 3){
                    if (s[0] >= '0' && s[0] <= '9'){
                        isTriangle = false;
                    }
                    else{
                        fseek(file, -s.size(), SEEK_CUR);
                        break;
                    }
                }
                
                int fpos = s.find_first_of('/');
                
                if (fpos == string::npos){
                    vertexIndex[k] = atoi(s.c_str());
                    textureIndex[k] = 0;
                    normalIndex[k] = 0;
                    continue;
                }
                
                vertexIndex[k] = atoi(s.substr(0, fpos).c_str());
                
                int lpos = s.find_last_of('/');
                
                if (fpos == lpos){
                    textureIndex[k] = atoi(s.substr(lpos + 1, s.size() - lpos - 1).c_str());
                    normalIndex[k] = 0;
                }
                else if (lpos == fpos + 1){
                    textureIndex[k] = 0;
                    normalIndex[k] = atoi(s.substr(lpos + 1, s.size() - lpos - 1).c_str());
                }
                else{
                    textureIndex[k] = atoi(s.substr(fpos + 1, lpos - fpos - 1).c_str());
                    normalIndex[k] = atoi(s.substr(lpos + 1, s.size() - lpos - 1).c_str());
                }
                
            }
            
            
            if (isTriangle){
                ObjPoint point[3];
                ObjTriangle triangle;
                
                for (int i = 0; i < 3; i++){
                    point[i].vertex.x = temp_vertices[vertexIndex[i] - 1].x;
                    point[i].vertex.y = temp_vertices[vertexIndex[i] - 1].y;
                    point[i].vertex.z = temp_vertices[vertexIndex[i] - 1].z;
                    
                    if (textureIndex[i] > 0){
                        point[i].texCoord.x = temp_textures[textureIndex[i] - 1].x;
                        point[i].texCoord.y = temp_textures[textureIndex[i] - 1].y;
                    }
                    else{
                        point[i].texCoord.x = -100;
                        point[i].texCoord.y = -100;
                    }
                    
                    if (normalIndex[i] > 0){
                        point[i].normal.x = temp_normals[normalIndex[i] - 1].x;
                        point[i].normal.y = temp_normals[normalIndex[i] - 1].y;
                        point[i].normal.z = temp_normals[normalIndex[i] - 1].z;
                    }
                    else{
                        point[i].normal.x = -100;
                        point[i].normal.y = -100;
                        point[i].normal.z = -100;
                        
                    }
                    triangle.points[i] = point[i];
                }
                temp_group.triangles.push_back(triangle);
            }
            else{
                ObjPoint point[4];
                ObjQuad quad;
                
                for (int i = 0; i < 4; i++){
                    point[i].vertex.x = temp_vertices[vertexIndex[i] - 1].x;
                    point[i].vertex.y = temp_vertices[vertexIndex[i] - 1].y;
                    point[i].vertex.z = temp_vertices[vertexIndex[i] - 1].z;
                    
                    if (textureIndex[i] > 0){
                        point[i].texCoord.x = temp_textures[textureIndex[i] - 1].x;
                        point[i].texCoord.y = temp_textures[textureIndex[i] - 1].y;
                    }
                    else{
                        point[i].texCoord.x = -1;
                        point[i].texCoord.y = -1;
                    }
                    
                    if (normalIndex[i] > 0){
                        point[i].normal.x = temp_normals[normalIndex[i] - 1].x;
                        point[i].normal.y = temp_normals[normalIndex[i] - 1].y;
                        point[i].normal.z = temp_normals[normalIndex[i] - 1].z;
                    }
                    else{
                        point[i].normal.x = -1;
                        point[i].normal.y = -1;
                        point[i].normal.z = -1;
                        
                    }
                    quad.points[i] = point[i];
                }
                temp_group.quads.push_back(quad);
            }
            
        }
        else{
            // Probably a comment, eat up the rest of the line
            char stupidBuffer[1000];
            fgets(stupidBuffer, 1000, file);
        }
    }
    
    if (!temp_group.triangles.empty() || !temp_group.quads.empty()){
        groups.push_back(temp_group);
    }
    
    if (groups.empty()){
        temp_group.name = "default";
        groups.push_back(temp_group);
    }
    
    setArea();
    return true;
}
Example #7
0
int readOBJ(struct OBJ_Model * obj)
{

  if (obj->filename == 0 ) { fprintf(stderr,"readOBJ called with a null filename , cannot continue \n"); return 0; }
  /* Read the .obj model from file FILENAME */
  /* All faces are converted to be triangles */
  FILE *file=0;
  char buf[128];
  char buf1[128];
  unsigned int wrongDecimalSeperatorBug=0;
  long unsigned int    numvertices;		/* number of vertices in model */
  long unsigned int    numnormals;                 /* number of normals in model */
  long unsigned int    numcolors;
  long unsigned int    numtexs;                 /* number of normals in texture coordintaes */
  long unsigned int    numfaces;			/* number of faces in model */
  long unsigned int    numgroups;			/* number of groups in model */
  GLuint cur_group,material, mat;
  long unsigned int v,n,t,i;
  int grp;

  fprintf(stderr,"TODO : proper string allocation here for filename %s \n",obj->filename);
  char fname[2*MAX_MODEL_PATHS+1]={0};
  snprintf(fname,2*MAX_MODEL_PATHS,"%s/%s.obj",obj->directory , obj->filename);

  fprintf(stderr,"Opening File %s ..\n",fname);
  file=fopen(fname,"r");
  if(file==0) { fprintf(stderr,"Could not open file %s for reading Object\n",fname); return 0;  }
 // strcpy(name,filename);
  strcpy(obj->matLib,"");
  //Group Pass
  rewind(file);
  numgroups = 1;
  while(fscanf(file, "%s", buf) != EOF)
  {
	  if(buf[0]=='g')
		  numgroups++;
	  else
		  fgets(buf, sizeof(buf), file); // eat up rest of line
  }
  if(numgroups==0) { numgroups=1; }
  obj->groups = (Group*) malloc(sizeof(Group)* numgroups);
  if (obj->groups == 0) { fprintf(stderr,"Could not make enough space for %lu groups \n",numgroups); fclose(file); return 0; }
  obj->numGroups = 0;
  obj->numFaces =0;

  // 1st Pass
  rewind(file);
  numtexs = 0;
  numvertices = 0;
  numnormals = 0;
  numcolors = 0;
  numfaces = 0;
  cur_group = AddGroup(obj,"default");
  obj->groups[0].material=0;
  while(fscanf(file, "%s", buf) != EOF)
  {

	  if(strcmp(buf, "mtllib")==0)
	  {
		  fscanf(file, "%s", buf1);
		  strcpy(obj->matLib,  buf1);
		  loadMTL(obj,obj->directory ,buf1);
		  printf("loadmtl %s survived\n", obj->matLib);
	  }
    switch(buf[0])
    {
    case '#':	fgets(buf, sizeof(buf), file);	 break;		// comment   eat up rest of line

    // v, vn, vt
    case 'v':
               switch(buf[1])
               {
                  case '\0': // vertex  eat up rest of line
	                         fgets(buf, sizeof(buf), file);
	                         numvertices++;
	                         if (floatingPointCheck(buf,strlen(buf)) ) { ++wrongDecimalSeperatorBug; }
	                         if (countChar(buf,strlen(buf),' ',buf[1])==6) { numcolors++ ; } //meshlab extension for colors on obj files
	              break;
                  case 'n': // normal  eat up rest of line
	                         fgets(buf, sizeof(buf), file);
	                         numnormals++;
                  break;
                  case 't':	//texture coordinate  eat up rest of line
	                         fgets(buf, sizeof(buf), file);
	                         numtexs ++;
	              break;
                  default:
	                         fprintf(stderr,"Unexpected characters  ( \"%s\" ) while waiting for v, vn ,vt .\n", buf);
	                         return 0;
	              break;
                }
     break;

     case 'm': fgets(buf, sizeof(buf), file);  break;
     case 'u': fgets(buf, sizeof(buf), file);  break;// eat up rest of line

     case 'g': //group eat up rest of line
               fgets(buf, sizeof(buf), file);
               sscanf(buf, "%s", buf);
	           cur_group = AddGroup(obj,buf);
     break;

     case 'f':	// face
                v =0; n = 0; t = 0;
                fscanf(file, "%s", buf); // can be one of %d, %d//%d, %d/%d, %d/%d/%d
                if (strstr(buf, "//"))
                  { //        v//n
	                sscanf(buf, "%d//%d", &v, &n);
	                fscanf(file, "%d//%d", &v, &n);
	                fscanf(file, "%d//%d", &v, &n);
	                obj->numFaces++;
	                while(fscanf(file, "%d//%d", &v, &n) > 0) { obj->numFaces++; }
	              } else
                if (sscanf(buf, "%d/%d/%d", &v, &t, &n) == 3)
                  { //        v/t/n
	                fscanf(file, "%d/%d/%d", &v, &t, &n);
	                fscanf(file, "%d/%d/%d", &v, &t, &n);
	                obj->numFaces++;
	                while(fscanf(file, "%d/%d/%d", &v, &t, &n) > 0) { obj->numFaces++; }
	               } else
                if (sscanf(buf, "%d/%d", &v, &t) == 2)
                  { //        v/t
	                fscanf(file, "%d/%d", &v, &t);
	                fscanf(file, "%d/%d", &v, &t);
	                obj->numFaces++;
	                while(fscanf(file, "%d/%d", &v, &t) > 0) { obj->numFaces++; }
	              } else
	              { //        v
	                fscanf(file, "%d", &v);
	                fscanf(file, "%d", &v);
	                obj->numFaces++;
	                while(fscanf(file, "%d", &v) > 0)  { obj->numFaces++; }
	              }
      break; //end of face case

    default: fgets(buf, sizeof(buf), file); break; // eat up rest of line


    }
  }





  // set the stats in the model structure
  obj->numVertices  = numvertices;
  obj->numNormals   = numnormals;
  obj->numTexs = numtexs;
  obj->numColors = numcolors;

  printf("Vertices : %ld\n",obj->numVertices);
  printf("Normals  : %ld\n",obj->numNormals);
  printf("Faces    : %ld\n",obj->numFaces);
  printf("Groups   : %ld\n",obj->numGroups);
  printf("Texes   : %ld\n",obj->numTexs);
  printf("Colors   : %ld\n",obj->numColors);

  if (wrongDecimalSeperatorBug)
  {
      fprintf(stderr,RED "! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !\n");
      fprintf(stderr,RED "\n\n\n\nThis OBJ file has a wrong seperator for floating point numbers \n");
      fprintf(stderr,"         please use    sed -i 's/,/./g' %s         \n\n\n" NORMAL,obj->filename);
      fprintf(stderr,RED "! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !\n");
  }

  for(i=0; i<obj->numGroups; i++)
  {
	  obj->groups[i].numFaces=0;
	  printf("%d\n", obj->groups[i].hasNormals);//0, 0
  }

  // Allocating memory
  fprintf(stderr,"Allocating memory for faces\n");
  obj->faceList = (Face*) malloc(sizeof(Face)*(obj->numFaces+2));
  if (obj->faceList == 0) { fprintf(stderr,"Could not allocate enough memory for face struct\n"); }
  memset (obj->faceList,0,sizeof(Face)*(obj->numFaces+2));

  fprintf(stderr,"Allocating memory for vertices\n");
  obj->vertexList = (Vertex*) malloc(sizeof(Vertex)*(obj->numVertices+2));
  if (obj->vertexList == 0) { fprintf(stderr,"Could not allocate enough memory for vertex struct\n"); }
  memset (obj->vertexList,0,sizeof(Vertex)*(obj->numVertices+2));

  if(obj->numNormals!=0)
  {
    fprintf(stderr,"Allocating memory for normals\n");
    obj->normalList=(Normal*)malloc(sizeof(Normal)*(obj->numNormals+2));
    if (obj->normalList == 0) { fprintf(stderr,"Could not allocate enough memory for normal struct\n"); }
    memset (obj->normalList,0,sizeof(Normal)*(obj->numNormals+2));
  }

  if(obj->numTexs!=0)
  {
    fprintf(stderr,"Allocating memory for textures\n");
    obj->texList=(TexCoords*)malloc(sizeof(TexCoords)*(obj->numTexs+2));
    if (obj->texList == 0) { fprintf(stderr,"Could not allocate enough memory for texture struct\n"); }
    memset (obj->texList,0,sizeof(TexCoords)*(obj->numTexs+2));
  }


  if(obj->numColors!=0)
  {
    fprintf(stderr,"Allocating memory for colors\n");
    obj->colorList=(RGBColors*)malloc(sizeof(RGBColors)*(obj->numColors+2));
    if (obj->colorList == 0) { fprintf(stderr,"Could not allocate enough memory for colors struct\n"); }
    memset (obj->colorList,0,sizeof(RGBColors)*(obj->numColors+2));
  }

  // Second Pass
  rewind(file);

  //These dont work if they become 0 :P
  obj->numVertices = 1;
  obj->numNormals = 1;
  obj->numTexs = 1;
  obj->numColors = 1;
  obj->customColor =( obj->numColors > 0 );
  obj->numFaces = 0;
  material = 0;
  grp = 0;

  while(!feof(file))
  {
    fscanf(file, "%s", buf);

	if(!strcmp(buf, "usemtl"))
	{
		  fscanf(file, "%s", buf1);
		  unsigned int foundMaterial;
		  if ( FindMaterial( obj, buf1 , &foundMaterial) )
          {
		    mat = foundMaterial;
		    obj->groups[grp].material = mat;
		    strcpy(obj->matLib, buf1);
		    printf("loadmtl %s\n", obj->matLib);
          }
    }
	switch(buf[0])
	{
      case '#':	fgets(buf, sizeof(buf), file);	break;		// comment  eat up rest of line

      case 'v':	 // v, vn, vt
                  switch(buf[1])
                  {
                       case '\0': //  vertex
                                  if ( obj->customColor )
                                    {
	                                 fscanf(file, "%f %f %f %f %f %f",
	                                 &obj->vertexList[obj->numVertices].x,
	                                 &obj->vertexList[obj->numVertices].y,
	                                 &obj->vertexList[obj->numVertices].z,
	                                 &obj->colorList[obj->numColors].r,
	                                 &obj->colorList[obj->numColors].g,
	                                 &obj->colorList[obj->numColors].b
	                                 );

	                                  obj->numVertices++;
	                                  obj->numColors++;

                                    } else
                                    {
	                                 fscanf(file, "%f %f %f",
	                                 &obj->vertexList[obj->numVertices].x,
	                                 &obj->vertexList[obj->numVertices].y,
	                                 &obj->vertexList[obj->numVertices].z);
	                                 obj->numVertices++;
                                    }


	                   break;
                       case 'n': // normal
	                             fscanf(file, "%f %f %f",
	                             &obj->normalList[obj->numNormals].n1,
	                             &obj->normalList[obj->numNormals].n2,
	                             &obj->normalList[obj->numNormals].n3);
	                             obj->numNormals++;
	                   break;

	                   case 't': // normal
	                             fscanf(file, "%f %f",
	                             &obj->texList[obj->numTexs].u,
	                             &obj->texList[obj->numTexs].v);
	                             obj->numTexs++;
	                   break;
                  }
      break;

      case 'u': fgets(buf, sizeof(buf), file);  break; // eat up rest of line

      case 'g': // group eat up rest of line
                fgets(buf, sizeof(buf), file);
	            sscanf(buf, "%s", buf);
	            grp = FindGroup(obj,buf);
                obj->groups[grp].material = material;
	  break;

      case 'f': //face
                v = 0;  n = 0; t = 0;
                fscanf(file, "%s", buf);
                // can be one of %d, %d//%d, %d/%d, %d/%d/%d
                if (strstr(buf, "//"))
                { //  v//n
	              sscanf(buf, "%d//%d", &v, &n);
	              obj->faceList[obj->numFaces].v[0] = v;
	              obj->faceList[obj->numFaces].n[0] = n;
	              fscanf(file, "%d//%d", &v, &n);
	              obj->faceList[obj->numFaces].v[1] = v;
	              obj->faceList[obj->numFaces].n[1] = n;
	              fscanf(file, "%d//%d", &v, &n);
	              obj->faceList[obj->numFaces].v[2] = v;
	              obj->faceList[obj->numFaces].n[2] = n;
	              AddFacetoG(&obj->groups[grp],obj->numFaces);
	              obj->numFaces++;
	              obj->groups[grp].hasNormals = 1;
	              obj->groups[grp].hasTex = 0;
	              while(fscanf(file, "%d//%d", &v, &n) > 0)
	               {
	                 obj->faceList[obj->numFaces].v[0] = obj->faceList[obj->numFaces-1].v[0];
	                 obj->faceList[obj->numFaces].n[0] = obj->faceList[obj->numFaces-1].n[0];
	                 obj->faceList[obj->numFaces].v[1] = obj->faceList[obj->numFaces-1].v[2];
	                 obj->faceList[obj->numFaces].n[1] = obj->faceList[obj->numFaces-1].n[2];
	                 obj->faceList[obj->numFaces].v[2] = v;
	                 obj->faceList[obj->numFaces].n[2] = n;
	                 AddFacetoG(&obj->groups[grp],obj->numFaces);
	                 obj->numFaces++;
	               }
	             } else
	             if (sscanf(buf, "%d/%d/%d", &v, &t, &n) == 3)
	             { // v/t/n
	                obj->faceList[obj->numFaces].v[0] = v;
	                obj->faceList[obj->numFaces].n[0] = n;
	                obj->faceList[obj->numFaces].t[0] = t;
	                fscanf(file, "%d/%d/%d", &v, &t, &n);
	                obj->faceList[obj->numFaces].v[1] = v;
	                obj->faceList[obj->numFaces].n[1] = n;
	                obj->faceList[obj->numFaces].t[1] = t;
	                fscanf(file, "%d/%d/%d", &v, &t, &n);
	                obj->faceList[obj->numFaces].v[2] = v;
	                obj->faceList[obj->numFaces].n[2] = n;
	                obj->faceList[obj->numFaces].t[2] = t;
	                AddFacetoG(&obj->groups[grp],obj->numFaces);
	                obj->numFaces++;
	                obj->groups[grp].hasNormals = 1;
	                obj->groups[grp].hasTex = 1;

	                while(fscanf(file, "%d/%d/%d", &v, &t, &n) > 0)
	                  {
	                    obj->faceList[obj->numFaces].v[0] = obj->faceList[obj->numFaces-1].v[0];
	                    obj->faceList[obj->numFaces].n[0] = obj->faceList[obj->numFaces-1].n[0];
	                    obj->faceList[obj->numFaces].t[0] = obj->faceList[obj->numFaces-1].t[0];
	                    obj->faceList[obj->numFaces].v[1] = obj->faceList[obj->numFaces-1].v[2];
	                    obj->faceList[obj->numFaces].n[1] = obj->faceList[obj->numFaces-1].n[2];
	                    obj->faceList[obj->numFaces].t[1] = obj->faceList[obj->numFaces-1].t[2];
	                    obj->faceList[obj->numFaces].v[2] = v;
	                    obj->faceList[obj->numFaces].n[2] = n;
	                    obj->faceList[obj->numFaces].t[2] = t;
	                    AddFacetoG(&obj->groups[grp],obj->numFaces);
	                    obj->numFaces++;
	                  }
                } else
                if (sscanf(buf, "%d/%d", &v, &t) == 2)
                { // v/t
		          obj->groups[grp].hasTex = 1;
		          obj->faceList[obj->numFaces].v[0] = v;
		          obj->faceList[obj->numFaces].t[0] = t;
		          fscanf(file, "%d/%d", &v, &t);
		          obj->faceList[obj->numFaces].v[1] = v;
		          obj->faceList[obj->numFaces].t[1] = t;
		          fscanf(file, "%d/%d", &v, &t);
		          obj->faceList[obj->numFaces].v[2] = v;
		          obj->faceList[obj->numFaces].t[2] = t;
		          AddFacetoG(&obj->groups[grp],obj->numFaces);
		          obj->numFaces++;
		          while(fscanf(file, "%d/%d", &v, &t) > 0)
		          {
	  	           obj->faceList[obj->numFaces].v[0] = obj->faceList[obj->numFaces-1].v[0];
	  	           obj->faceList[obj->numFaces].t[0] = obj->faceList[obj->numFaces-1].t[0];
	  	           obj->faceList[obj->numFaces].v[1] = obj->faceList[obj->numFaces-1].v[2];
	  	           obj->faceList[obj->numFaces].t[1] = obj->faceList[obj->numFaces-1].t[2];
	  	           obj->faceList[obj->numFaces].v[2] = v;
	  	           obj->faceList[obj->numFaces].t[2] = t;
	  	           AddFacetoG(&obj->groups[grp],obj->numFaces);
	  	           obj->numFaces++;
		          }//while
               } else
               { // v
	             sscanf(buf, "%d", &v);
	             obj->faceList[obj->numFaces].v[0] = v;
	             fscanf(file, "%d", &v);
	             obj->faceList[obj->numFaces].v[1] = v;
	             fscanf(file, "%d", &v);
	             obj->faceList[obj->numFaces].v[2] = v;
	             obj->groups[grp].hasNormals = 0;
	             obj->groups[grp].hasTex = 0;
	             AddFacetoG(&obj->groups[grp],obj->numFaces);
	             obj->numFaces++;
	             while(fscanf(file, "%d", &v) == 1)
	              {
	               obj->faceList[obj->numFaces].v[0] = obj->faceList[obj->numFaces-1].v[0];
	               obj->faceList[obj->numFaces].v[1] = obj->faceList[obj->numFaces-1].v[2];
	               obj->faceList[obj->numFaces].v[2] = v;
	               AddFacetoG(&obj->groups[grp],obj->numFaces);
	               obj->numFaces++;
	              }
                }
      break;

     default: fgets(buf, sizeof(buf), file); break; // eat up rest of line
    }
  }
  fclose(file);
  printf("Model has %ld faces %u colors \n",obj->numFaces, obj->numColors);
  for(i=0; i<obj->numGroups; i++)
  {
	 // fprintf(stderr,"Group %s has %ld faces and material %s, \t \n",obj->groups[i].name,obj->groups[i].numFaces,obj->matList[obj->groups[i].material].name);
  }


#if CALCULATE_3D_BOUNDING_BOX
  calculateOBJBBox(obj);
#endif // CALCULATE_3D_BOUNDING_BOX

 return 1;
}
Example #8
0
void ArticulatedModel::initOBJ(const std::string& filename, const Preprocess& preprocess) {
    Stopwatch loadTimer;

    TextInput::Settings set;
    set.cppBlockComments = false;
    set.cppLineComments = false;
    set.otherCommentCharacter = '#';
    set.generateNewlineTokens = true;

    // Notes on OBJ file format.  See also:
    //
    // -  http://www.martinreddy.net/gfx/3d/OBJ.spec
    // -  http://en.wikipedia.org/wiki/Obj
    // -  http://www.royriggs.com/obj.html
    //
    // OBJ indexing is 1-based.
    // Line breaks are significant.
    // The first token on a line indicates the contents of the line.
    //
    // Faces contain separate indices for normals and texcoords.
    // We load the raw vertices and then form our own optimized
    // gl indices from them.
    //
    // Negative indices are relative to the last coordinate seen.

    // Raw arrays with independent indexing, as imported from the file
    Array<Vector3> rawVertex;
    Array<Vector3> rawNormal;
    Array<Vector2> rawTexCoord;

    // part.geometry.vertexArray[i] = rawVertex[cookVertex[i]];
    Array<int>      cookVertex;
    Array<int>      cookNormal;
    Array<int>      cookTexCoord;

    // Put everything into a single part
    // Convert to a Part
    Part& part = partArray.next();

    part.cframe = CoordinateFrame();
    part.name = "root";
    part.parent = -1;

    // v,t,n repeated for each vertex
    Array<int>     faceTempIndex;

    // Count of errors from mismatched texcoord and vertex
    int texCoordChanged = 0;
    int normalChanged = 0;

    Table<std::string, Material::Ref> materialLibrary;
    Table<std::string, TriListSpec*> groupTable;

    TriListSpec* currentTriList = NULL;
    int numTris = 0;

    const Matrix3 normalXform = preprocess.xform.upper3x3().transpose().inverse();

    const std::string& basePath = FilePath::parent(FileSystem::resolve(filename));

    {
        TextInput ti(filename, set);
        while (ti.hasMore()) {
            // Consume comments/newlines
            while (ti.hasMore() && (ti.peek().type() == Token::NEWLINE)) {
                // Consume the newline
                ti.read();
            }

            if (! ti.hasMore()) {
                break;
            }

            // Process one line
            const std::string& cmd = ti.readSymbol();

            if (cmd == "mtllib") {

                // Specify material library
                const std::string& mtlFilename = ti.readUntilNewlineAsString();
                loadMTL(FilePath::concat(basePath, mtlFilename), materialLibrary, preprocess);

            } else if (cmd == "g") {

                // New trilist
                const std::string& name = ti.readUntilNewlineAsString();
                if (! groupTable.containsKey(name)) {
                    currentTriList = new TriListSpec();
                    currentTriList->name = name;
                    groupTable.set(name, currentTriList);
                } else {
                    currentTriList = groupTable[name];
                }


            } else if (cmd == "usemtl") {
                if (currentTriList) {
                    currentTriList->materialName = ti.readUntilNewlineAsString();
                }
            } else if (cmd == "v") {
                rawVertex.append(readVertex(ti, preprocess.xform));
            } else if (cmd == "vt") {
                // Texcoord
                Vector2& t = rawTexCoord.next();
                t.x = ti.readNumber();
                t.y = 1.0f - ti.readNumber();
            } else if (cmd == "vn") {
                // Normal
                rawNormal.append(readNormal(ti, normalXform));
            } else if ((cmd == "f") && currentTriList) {
                // Face

                // Read each vertex
                while (ti.hasMore() && (ti.peek().type() != Token::NEWLINE)) {

                    // Read one 3-part index
                    int v = ti.readNumber();
                    if (v < 0) {
                        v = rawVertex.size() + 1 + v;
                    }

                    int n = 0;
                    int t = 0;

                    if (ti.peek().type() == Token::SYMBOL) {
                        ti.readSymbol("/");
                        if (ti.peek().type() == Token::NUMBER) {
                            t = ti.readNumber();
                            if (t < 0) {
                                t = rawTexCoord.size() + 1 + t;
                            }
                        }
                        if (ti.peek().type() == Token::SYMBOL) {
                            ti.readSymbol("/");
                            if (ti.peek().type() == Token::NUMBER) {
                                n = ti.readNumber();
                                if (n < 0) {
                                    n = rawNormal.size() + 1 + n;
                                }
                            }
                        }
                    }

                    // Switch to zero-based indexing
                    --v;
                    --n;
                    --t;

                    faceTempIndex.append(v, t, n);
                }

                alwaysAssertM(faceTempIndex.size() >= 3*3, "Face with fewer than three vertices in model.");
                numTris += (faceTempIndex.size()/3) - 2;
                // The faceTempIndex is now a triangle fan.  Convert it to a triangle list and use unique vertices
                for (int i = 2; i < faceTempIndex.size()/3; ++i) {
                    // Always start with vertex 0
                    cookVertex.append(faceTempIndex[0]);
                    cookTexCoord.append(faceTempIndex[1]);
                    cookNormal.append(faceTempIndex[2]);

                    // The vertex just before the one we're adding
                    int j = (i - 1) * 3;
                    cookVertex.append(faceTempIndex[j]);
                    cookTexCoord.append(faceTempIndex[j+1]);
                    cookNormal.append(faceTempIndex[j+2]);

                    // The vertex we're adding
                    j = i * 3;
                    cookVertex.append(faceTempIndex[j]);
                    cookTexCoord.append(faceTempIndex[j+1]);
                    cookNormal.append(faceTempIndex[j+2]);

                    // Update the index array to contain the three vertices we just added
                    currentTriList->cpuIndex.append(cookVertex.size() - 3, cookVertex.size() - 2, cookVertex.size() - 1);
                }

                faceTempIndex.fastClear();

            }

            // Read until the end of the line
            while (ti.hasMore() && (ti.read().type() != Token::NEWLINE));
        }
    }

    debugPrintf("Creating TriLists\n");

    // Copy geometry
    const int N = cookVertex.size();
    part.geometry.vertexArray.resize(N);
    for (int i = 0; i < N; ++i) {
        part.geometry.vertexArray[i] = rawVertex[cookVertex[i]];
    }

    // Optional normals
    if (rawNormal.size() > 0) {
        part.geometry.normalArray.resize(N);
        for (int i = 0; i < N; ++i) {
            part.geometry.normalArray[i] = rawNormal[cookNormal[i]];
        }
    }

    // Optional texcoords
    if (rawTexCoord.size() > 0) {
        part.texCoordArray.resize(N);
        for (int i = 0; i < N; ++i) {
            part.texCoordArray[i] = rawTexCoord[cookTexCoord[i]];
        }
    }

    // Create trilists
    for (Table<std::string, TriListSpec*>::Iterator it = groupTable.begin(); it.hasMore(); ++it) {
        TriListSpec* s = it->value;

        Material::Ref material;
        if (materialLibrary.containsKey(s->materialName)) {
            material = materialLibrary[s->materialName];
        } else {
            material = Material::createDiffuse(Color3::white() * 0.8f);
            debugPrintf("Warning: unrecognized material: %s\n", s->materialName.c_str());
        }

        Part::TriList::Ref triList = part.newTriList(material);
        triList->twoSided = false;
        triList->indexArray = s->cpuIndex;
    }
    groupTable.deleteValues();
    groupTable.clear();

    debugPrintf("Done loading.  %d vertices, %d faces, %d frames\n\n", cookVertex.size(), numTris, N);
    loadTimer.after("Loading");
}