bool ofxOBJModel::load(string path) { bHasNormals = false; bHasTexCoords = false; filePath = path; path = ofToDataPath(path, true); string line; for(int i = 0; i < meshes.size(); i++) { delete meshes[i]; } meshes.clear(); ObjMesh *currMesh = NULL; // this is a list of all points // that we can drop after parsing vector<ofPoint> points; vector<ofPoint> normals; vector<ofPoint> texCoords; // obj file format vertexes are 1-indexed points.push_back(ofPoint()); normals.push_back(ofPoint()); texCoords.push_back(ofPoint()); ifstream myfile (path.c_str()); if (myfile.is_open()) { while (! myfile.eof()) { getline (myfile,line); // parse the obj format here. // // the only things we're interested in is // lines beginning with 'g' - this says start of new object // lines beginning with 'v ' - coordinate of a vertex // lines beginning with 'vn ' - vertex normals -- todo // lines beginning with 'vt ' - texcoords (either 2 or 3 values) -- todo // lines beginning with 'f ' - specifies a face of a shape // we take each number before the slash as the index // of the vertex to join up to create a face. if(line.find("g ")==0) { // new object definition currMesh = new ObjMesh(line.substr(2)); meshes.push_back(currMesh); } else if(line.find("v ")==0) { // new vertex points.push_back(parseCoords(line)); } else if(line.find("vn ")==0) { bHasNormals = true; normals.push_back(parseCoords(line)); } else if(line.find("vt ")==0) { bHasTexCoords = true; texCoords.push_back(parseCoords(line)); } else if(line.find("f ")==0) { // face definition if(currMesh!=NULL) { line = line.substr(2); // lop off "f " vector<string> indices = split(line, ' '); // remove any texcoords (/xxx's) ObjFace *face = new ObjFace(); for(int i = 0; i < indices.size(); i++) { vector<string> parts = ofSplitString(indices[i], "/"); // first index is always a point face->points.push_back(points[atoi(parts[0].c_str())]); if(parts.size()==2) { face->texCoords.push_back(texCoords[atoi(parts[1].c_str())]); } else if(parts.size()==3) { face->normals.push_back(normals[atoi(parts[2].c_str())]); if(parts[1]!="") { face->texCoords.push_back(texCoords[atoi(parts[1].c_str())]); } } } currMesh->addFace(face); } } } myfile.close(); //#define NORMALIZE_TEXCOORDS #ifdef NORMALIZE_TEXCOORDS ofPoint pmin(FLT_MAX, FLT_MAX); ofPoint pmax(FLT_MIN, FLT_MIN); for(int i = 0; i < texCoords.size(); i++) { if(texCoords[i].x<pmin.x) pmin.x = texCoords[i].x; if(texCoords[i].y<pmin.y) pmin.y = texCoords[i].y; if(texCoords[i].x>pmax.x) pmax.x = texCoords[i].x; if(texCoords[i].y>pmax.y) pmax.y = texCoords[i].y; } for(int k = 0; k < meshes.size(); k++) for(int i = 0; i < meshes[k]->faces.size(); i++) for(int j = 0; j < meshes[k]->faces[i]->texCoords.size(); j++) { ofPoint p = meshes[k]->faces[i]->texCoords[j]; p.x = ofMap(p.x, pmin.x, pmax.x, 0, 1); p.y = ofMap(p.y, pmin.y, pmax.y, 0, 1); meshes[k]->faces[i]->texCoords[j] = p; } #endif loadVbo(); ofLog(OF_LOG_NOTICE, "Successfully loaded %s\n-----\nVertices: %d\nMeshes: %d\nNormals: %d\nTexCoords: %d\n", path.c_str(), points.size(), meshes.size(), normals.size(), texCoords.size()); return true; } else { ofLog(OF_LOG_ERROR, "Couldn't find the OBJ file %s\n", path.c_str()); return false; } }
bool ofxOBJModel::load(string path) { filePath = path; path = ofToDataPath(path, true); string line; for(int i = 0; i < meshes.size(); i++) { delete meshes[i]; } meshes.clear(); ObjMesh *currMesh = NULL; // this is a list of all points // that we can drop after parsing vector<ofPoint> points; // obj file format vertexes are 1-indexed points.push_back(ofPoint()); ifstream myfile (path.c_str()); if (myfile.is_open()) { while (! myfile.eof()) { getline (myfile,line); // parse the obj format here. // // the only things we're interested in is // lines beginning with 'g' - this says start of new object // lines beginning with 'v ' - coordinate of a vertex // lines beginning with 'f ' - specifies a face of a shape // we take each number before the slash as the index // of the vertex to join up to create a face. if(line.find("g ")==0) { // new object definition currMesh = new ObjMesh(line.substr(2)); meshes.push_back(currMesh); } else if(line.find("v ")==0) { // new vertex points.push_back(parseVertex(line)); } else if(line.find("f ")==0) { // face definition if(currMesh!=NULL) { line = line.substr(2); // lop off "f " vector<string> indices = split(line, ' '); // remove any texcoords (/xxx's) for(int i = 0; i < indices.size(); i++) { int slashPos = indices[i].find("/"); if(slashPos!=-1) { indices[i] = indices[i].substr(0, slashPos); } } ObjFace *face = new ObjFace(); for(int i = 0; i < indices.size(); i++) { face->points.push_back(points[atoi(indices[i].c_str())]); } currMesh->addFace(face); } } } myfile.close(); printf("Successfully loaded %s\n-----\nVertices: %d\nMeshes: %d\n", path.c_str(), points.size(), meshes.size()); return true; } else { printf("Couldn't find the OBJ file %s\n", path.c_str()); return false; } }