void MeshObject::getNextElement(const char* buffer) { switch(buffer[0]) { case PARSED_ELEMENT_VERTEX: switch(buffer[1]) { case PARSED_ELEMENT_TEXTURE: readTexCoord(buffer); break; case PARSED_ELEMENT_NORMAL: readNormal(buffer); break; default: readVertex(buffer); } break; case PARSED_ELEMENT_FACE: readFace(buffer); break; //ignore case PARSED_ELEMENT_SMOOTH: case PARSED_ELEMENT_COMMENT: case PARSED_ELEMENT_MATERIAL: default: //printf("%s",buffer); break; } }
void ObjLoader::readFaces(ifstream &in, char strLine[]) { while(!in.eof() && type_==string("f")) { readFace(in,strLine); in >> type_; } }
void ObjLoader::decode(char* buf) { switch (buf[0]) { case '#': break; case 'v': readVertex(buf); break; case 'f': readFace(buf); break; default: break; } }
vector<Objet3D> ObjParser::readFile (const char * filename, vector<Objet3D> pObjets) { FILE* fichier; char ligne[255]; objets = pObjets; cptFaces = 0; cptObjects = 0; vObj = new Objet3D(); //Un objet par fichier vObj->setNom(filename); fichier = fopen(filename, "r"); while(!feof(fichier)) { ligne[0] = '\0'; fscanf(fichier, "%s", ligne); if(strcmp((const char*)ligne, (char*)"v") == 0) readVertex(fichier); if(strcmp((const char*)ligne, (char*)"vn") == 0) readVertexNormal(fichier); if(strcmp((const char*)ligne, (char*)"o") == 0) readObject(fichier); if(strcmp((const char*)ligne, (char*)"f") == 0) readFace(fichier); if(strcmp((const char*)ligne, (char*)"mtllib") == 0) { readMaterialLibrary(fichier); char mtlfilename[50]; sprintf(mtlfilename, ".\\ressources\\%s", nomMtlLib); readMtlFile(mtlfilename); } if(strcmp((const char*)ligne, (char*)"usemtl") == 0) readMaterialUsed(fichier); } //ASCH 02/08/15 - Insère le dernier objet lu en mémoire. insertObject(); cptFaces = 0; fclose(fichier); return objets; }
void Object3D::record(const QString &line) { if(line.at(0) == 'v' && line.at(1) == ' ') // v ... ... ... readlVertices(get_corret_line(line)); else if(line.at(0) == 'v' && line.at(1) == 't') // vt ... ... readTexturCord(get_corret_line(line)); else if(line.at(0) == 'v' && line.at(1) == 'n') // vn readNormals(get_corret_line(line)); else if(line.at(0) == 'v' && line.at(1) == 'p') // vp readSpaceVert(get_corret_line(line)); else if(line.at(0) == 'f') // f readFace(get_corret_line(line)); else if(line.at(0) == 'm') // mtl readMtl(get_corret_line(line)); else if(line.at(0) == 'u') readUseMtl(get_corret_line(line)); }
// TODO "usemtl filename" void ObjModel::read(const std::string& filename) { auto* file = std::fopen(filename.c_str(), "r"); if (!file) { throw std::runtime_error(std::string("can't find file: ") + filename); } char buffer[100]; while (std::fgets(buffer, 100, file)) { if (buffer[0] == 'v' && buffer[1] == ' ') { mVertices.push_back(readVertexCoord(buffer)); } else if (buffer[0] == 'v' && buffer[1] == 'n') { mVertices.push_back(readVertexNormal(buffer)); } else if (buffer[0] == 'v' && buffer[1] == 't') { mTextureCoords.push_back(readTextureCoords(buffer)); } else if (buffer[0] == 'f' && buffer[1] == ' ') { mFaces.push_back(readFace(buffer)); } } std::fclose(file); }
int Model::readObj(string filename) { ifstream stream(filename); if (stream.is_open()) { string line, chunk; while (stream >> chunk) { getline(stream, line); if (chunk == "v") readVertex(line); else if (chunk == "vn") readNormal(line); else if (chunk == "vt") readTexture(line); else if (chunk == "f") readFace(line); } // If we have normals or texture coordinates, we need to rearrange everything to avoid multiple indices. // TODO: Do this without blowing up the size of the v/n/t buffers. if (nBuffer.size() > 0 || tBuffer.size() > 0) { vector<glm::vec4> vBuffer2; vector<glm::vec3> nBuffer2; vector<glm::vec2> tBuffer2; for (unsigned int i = 0; i < viBuffer.size(); i++) { vBuffer2.push_back(vBuffer[viBuffer[i]]); if (niBuffer.size() > 0) nBuffer2.push_back(nBuffer[niBuffer[i]]); if (tiBuffer.size() > 0) tBuffer2.push_back(tBuffer[tiBuffer[i]]); } vBuffer = vBuffer2; nBuffer = nBuffer2; tBuffer = tBuffer2; } stream.close(); return 0; }
iMesh * FileExplorer::OBJFileExplorer::readMesh() { std::unique_ptr<iMesh> objectMesh(new iMesh); while (it!=sourcefile.end()) { if (*it == 'v') { it++; if (*it == ' ') { glm::vec3 v = parse3dVector(); this->v.push_back(v); } else if(*it == 't') { it++; glm::vec2 vt = parse2dVector(); this->vt.push_back(vt); } else if (*it == 'n') { it++; glm::vec3 vn = parse3dVector(); this->vn.push_back(vn); } } else if (*it == '#') { it = std::find(it, sourcefile.end(), '\n'); } else if (*it == 'f') { objectMesh->faces.push_back(readFace()); } } return objectMesh.get(); }
int readObj (FILE * fp, objObj obj, nameIndex * mtlIndex) { char line[255]; enum dataType t; float v[3]; int i; int vertexCount = 0; int texcoordCount = 0; int normalCount = 0; int faceCount = 0; int currentMaterialIndex = -1; while (!readLinePlus (fp, line, &t)) { switch (t) { case (T_V): if (vertexCount >= obj.nbVertex) { fprintf (stderr, "Problem with vertices Count\n"); return 1; } sscanf (line, "%f %f %f", &v[0], &v[1], &v[2]); for (i = 0; i < 3; i++) obj.vertexList[vertexCount].coords[i] = v[i]; vertexCount++; break; case (T_VN): if (normalCount >= obj.nbNormal) { fprintf (stderr, "Problem with normals Count\n"); return 1; } sscanf (line, "%f %f %f", &v[0], &v[1], &v[2]); for (i = 0; i < 3; i++) obj.normalList[normalCount].coords[i] = v[i]; normalCount++; break; case (T_VT): if (texcoordCount >= obj.nbTexcoord) { fprintf (stderr, "Problem with texcoords Count\n"); return 1; } sscanf (line, "%f %f %f", &v[0], &v[1], &v[2]); for (i = 0; i < 3; i++) obj.texcoordList[texcoordCount].coords[i] = v[i]; texcoordCount++; break; case (T_USEMTL): if (lookupIndex (mtlIndex, &(obj.nbMaterial), obj.nbMaterial, line, 0, ¤tMaterialIndex)) { fprintf (stderr, "Problem with material count\n"); return 1; } break; case (T_F): if (faceCount >= obj.nbFace) { fprintf (stderr, "Problem with faces Count\n"); return 1; } if (readFace (line, &(obj.faceList[faceCount]), currentMaterialIndex)) return 1; faceCount++; break; default: continue; } } return 0; }
Mesh loadMeshFromObj(const char *filename, float scale) { printf("Attempting to load mesh->from %s\n", filename); std::ifstream filehandle; filehandle.open(filename, std::ios::in); if(filehandle.fail()) { printf("Could not open file.\n"); return Mesh(); } std::vector<std::list<sVertexIndex> > existingVertexTable; std::vector<sVertexIndex> vertexTable; std::vector<Mesh::sFace> faceTable; std::vector<sVec3> positionTable; std::vector<sVec3> normalTable; std::vector<sVec2> texcoordTable; std::string line; std::string name(filename); int sg = 0; clock_t start, end; start = clock(); printf("Reading data... "); while( filehandle.good() && !filehandle.eof() ) { std::getline(filehandle, line); if(line[0] == 'v') { if(line[1] == 't') readTexcoord(line, texcoordTable); else if(line[1] == 'n') readNormal(line, normalTable); else readPosition(line, positionTable, scale); } else if(line[0] == 'f') readFace(line, vertexTable, existingVertexTable, faceTable, sg); else if(line[0] == 's') readSG(line, sg); } Mesh m; fillMesh( m, name, vertexTable, faceTable, positionTable, normalTable, texcoordTable); printf("done!\n"); printf("total vertex count %i\n", vertexTable.size()); printf("total face count %i\n", faceTable.size()); end = clock(); double cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC; printf("Time taken %3.3fs \n", cpu_time_used); return m; }
std::vector<Mesh> loadMeshesFromObj(const char *filename, float scale) { printf("Attempting to load mesh->from %s\n", filename); std::ifstream filehandle; filehandle.open(filename, std::ios::in); std::vector<Mesh> meshes; if(filehandle.fail()) { printf("Could not open file.\n"); return meshes; } std::vector<std::list<sVertexIndex> > existingVertexTable; std::vector<sVertexIndex> vertexTable; std::vector<Mesh::sFace> faceTable; std::vector<sVec3> positionTable; std::vector<sVec3> normalTable; std::vector<sVec2> texcoordTable; std::string line; std::string name; std::string material; int sg = 0; int count = 0; clock_t start, end; start = clock(); printf("Reading data... "); while( filehandle.good() && !filehandle.eof() ) { std::getline(filehandle, line); if(line[0] == 'v') { if(line[1] == 't') readTexcoord(line, texcoordTable); else if(line[1] == 'n') readNormal(line, normalTable); else readPosition(line, positionTable, scale); } else if(line[0] == 'f') readFace(line, vertexTable, existingVertexTable, faceTable, sg); else if(line[0] == 's') readSG(line, sg); else if(line[0] == 'g') { readG(line, name); } else if(line[0] == 'u') { char str[32]; char mtl[128]; int success = sscanf(line.c_str(), "%s %s", str, mtl); if(success && strcmp(str, "usemtl") == 0) { if(count > 0) { meshes.push_back(Mesh()); fillMesh( meshes[count-1], name, vertexTable, faceTable, positionTable, normalTable, texcoordTable); meshes[count-1].material = material; vertexTable.clear(); faceTable.clear(); existingVertexTable.clear(); } ++count; if(success > 1) material = std::string(mtl); } } } if(count > 0) { meshes.push_back(Mesh()); fillMesh( meshes[count-1], name, vertexTable, faceTable, positionTable, normalTable, texcoordTable); meshes[count-1].material = material; } printf("done!\n"); //printf("total vertex count %i\n", vertexTable.size()); //printf("total face count %i\n", faceTable.size()); end = clock(); double cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC; printf("Time taken %3.3fs \n", cpu_time_used); //printf("meshes.size() = %i\n", meshes.size()); return meshes; }
void ParseOBJ::processCommand(const Command command) { switch (command) { case VERTEX: maybeReadWhitespace(); vertexArray.append(readVector3()); // Consume anything else on this line readUntilNewline(); break; case TEXCOORD: maybeReadWhitespace(); texCoord0Array.append(readVector2()); if (m_objOptions.texCoord1Mode == ParseOBJ::Options::UNPACK_FROM_TEXCOORD0_Z) { float w = readFloat(); Vector2 texCoord1; texCoord1.x = floor(w / (2.0f * 2048.0f)) / 2048.0f; texCoord1.y = (w - 2.0f * 2048.0f * floor(w / (2.0f * 2048.0f))) / 2048.0f; texCoord1Array.append(texCoord1); } else if (m_objOptions.texCoord1Mode == ParseOBJ::Options::TEXCOORD0_ZW) { texCoord1Array.append(readVector2()); } // Consume anything else on this line readUntilNewline(); break; case NORMAL: maybeReadWhitespace(); normalArray.append(readVector3()); // Consume anything else on this line readUntilNewline(); break; case FACE: readFace(); // Faces consume newlines by themselves break; case GROUP: { // Change group const String& groupName = readName(); shared_ptr<Group>& g = groupTable.getCreate(groupName); if (isNull(g)) { // Newly created g = Group::create(); g->name = groupName; } m_currentGroup = g; } // Consume anything else on this line readUntilNewline(); break; case USEMTL: { // Change the mesh within the group const String& materialName = readName(); m_currentMaterial = getMaterial(materialName); // Force re-obtaining or creating of the appropriate mesh m_currentMesh.reset(); } // Consume anything else on this line readUntilNewline(); break; case MTLLIB: { // Specify material library String mtlFilename = readName(); mtlArray.append(mtlFilename); mtlFilename = FilePath::concat(m_basePath, mtlFilename); TextInput ti2(mtlFilename); m_currentMaterialLibrary.parse(ti2); } // Consume anything else on this line readUntilNewline(); break; case UNKNOWN: // Nothing to do readUntilNewline(); break; } }
Mesh::Mesh( const std::string& filename ) { // Read file into memory std::ifstream file( filename.c_str(), std::ios::in | std::ios::ate ); if ( !file.is_open() ) throw FileException(); unsigned int fileLen = (unsigned int)file.tellg(); file.seekg( 0, std::ios::beg ); std::vector<char> buf( fileLen ); file.read( &buf[0], fileLen ); file.close(); // Data int approxMem = 295 + fileLen / 1024 * 11; std::vector<Vec3> vectors; vectors.reserve( approxMem ); std::vector<Vec3> normals; normals.reserve( approxMem ); std::vector<Vec2> texcoords; texcoords.reserve( approxMem ); vertices.reserve( approxMem ); // Parser state bool inComment = false; int mode = MODE_NONE; Vec3 v3; face f; // Parse for ( unsigned int i = 0; i < fileLen; i++ ) { // Ignore comment lines if ( buf[i] == '#' ) { inComment = true; continue; } else if ( inComment && buf[i] != '\n' ) { continue; } else if ( inComment && buf[i] == '\n' ) { inComment = false; continue; } // Find a command if ( mode == MODE_NONE && !IS_SPACING( buf[i] ) ) { if ( buf[i] == 'f' ) mode = MODE_FACE; else if ( buf[i] == 'v' ) { if ( IS_SPACING( buf[i+1] ) ) mode = MODE_VERTEX; else if ( buf[i+1] == 'n' ) mode = MODE_NORMAL; else if ( buf[i+1] == 't' ) mode = MODE_TEXTURE; i++; } else mode = MODE_UNKNOWN; } else if ( mode != MODE_NONE ) { switch ( mode ) { case MODE_UNKNOWN: if ( buf[i] == '\n' ) mode = MODE_NONE; break; case MODE_VERTEX: i += readVector( &buf[i], v3 ); vectors.push_back( v3 ); mode = MODE_NONE; break; case MODE_NORMAL: i += readVector( &buf[i], v3 ); normals.push_back( v3 ); mode = MODE_NONE; break; case MODE_TEXTURE: i += readVector( &buf[i], v3 ); texcoords.push_back( Vec2( v3.X, v3.Y ) ); mode = MODE_NONE; break; case MODE_FACE: i += readFace( &buf[i], f ); Vertex vertex = { vectors[f.v1 - 1], texcoords[f.t1 - 1], normals[f.n1 - 1] }; vertices.push_back( vertex ); vertex.Pos = vectors[f.v2 - 1]; vertex.Tex = texcoords[f.t2 - 1]; vertex.Normal = normals[f.n2 - 1]; vertices.push_back( vertex ); vertex.Pos = vectors[f.v3 - 1]; vertex.Tex = texcoords[f.t3 - 1]; vertex.Normal = normals[f.n3 - 1]; vertices.push_back( vertex ); mode = MODE_NONE; break; } } } }
Model::Model(char* objPath, GLfloat* diffuseColor, GLfloat* specularColor, GLfloat* emissiveColor, GLfloat* shininess) { // Cria o stream que lerá o objeto fstream reader = fstream(); // Abre o arquivo no modo de leitura reader.open(objPath, fstream::in); // Verifica se o arquivo foi aberto corretamente if (!reader.is_open()) { throw ("Failed to load"); } // Salva os dados do material do modelo if (verifyRGB(diffuseColor) && verifyRGB(specularColor) && verifyRGB(emissiveColor)) { Model::diffuseColor = diffuseColor; Model::specularColor = specularColor; Model::emissiveColor = emissiveColor; } // Salva dado sobre o brilho do modelo if (verifyShininess(shininess)) { Model::shininess = shininess; } // Buffer que salva cada linha char buff[256]; // Varre enquanto não chega ao fim do arquivo while (!reader.eof()) { // Obtem uma linha do stream reader.getline(buff, sizeof(buff)); if (strlen(buff) >= 2 && strncmp("v ", buff, 2) == 0) // Verifica se é uma linha de vertice { // Salva o ponto criado no vetor de vertices vertices.push_back(readPoint(buff)); } else if (strlen(buff) >= 3 && strncmp("vn ", buff, 3) == 0) // Verifica se é uma linha de normal { // Salva o ponto criado no vetor de normais normals.push_back(readPoint(buff)); } else if (strlen(buff) >= 3 && strncmp("vt ", buff, 3) == 0) // Verifica se é uma linha de testura { // Salva o ponto criado no vetor de normais textures.push_back(readCoord(buff)); } else if (strlen(buff) >= 2 && strncmp("f ", buff, 2) == 0) // Verifica se é uma linha de face { // Salva a face criada no vetor de faces da classe faces.push_back(readFace(buff, vertices, normals, textures)); } } // Verifica se existem faces no modelo if (faces.size() == 0) { throw ("Invalid obj"); } // Verifica se existem normais no modelo, se não, calcula normais if (faces[0].normals.size() == 0) { // Calucla as normais dos vertices calculateVerticesNormals(); } }