// // File: obj_mesh.cc // // (C) 2006 Toby Breckon / Helmut Cantzler // // Licensed under the terms of the Lesser General Public License. // #include "obj_mesh.h" int OBJ_Mesh::read(FILE *f, int (*update_progress)(int pos), void (*set_total)(int size)) { list *shape_triangles; list *shape_vertices; vector vertex_index; Triangle *tri; Vertex *v; char type; int p1, p2, p3; float x, y, z; bool tri_parse_failure = FALSE; fseek(f, 0, SEEK_END); (*set_total)(ftell(f)); fseek(f, 0, SEEK_SET); shape_triangles = new list; shape_vertices = new list; while ((type=fgetc(f)) != EOF) { switch (type) { case '#': // Comment do // Reads till end of the line { type=fgetc(f); } while (type != EOF && type != '\n'); break; case 'v': // Vertex // check it is a vertex of "v" and not "vt" or "vn" type=fgetc(f); if (type == ' '){ if (fscanf(f,"%f %f %f\n",&x,&y,&z) != 3) { FILE_ERROR(f, "PMesh file format error: v"); return 3; } v = new Vertex(x,y,z); add_vertex(v); // save in a vector for the triangles and shape vertex_index.push_back(v); } break; case 'f': // Polygon with 3 vertices tri_parse_failure = FALSE; // get first vertex if (fscanf(f," %d", &p1) == 1) { do // Reads till next space { type=fgetc(f); } while (type != EOF && type != ' '); } else { tri_parse_failure = TRUE; } // get second vertex if (fscanf(f,"%d", &p2) == 1) { do // Reads till next space { type=fgetc(f); } while (type != EOF && type != ' '); } else { tri_parse_failure = TRUE; } // get third vertex if (fscanf(f,"%d", &p3) == 1) { do // Reads till next space { type=fgetc(f); // check we only have 3 vertices - i.e. it is a triangles if ((type != ' ') && (type != '\n') && (type != EOF)){ tri_parse_failure = TRUE; } } while (type != EOF && type != ' ' && type != '\n'); } else { tri_parse_failure = TRUE; } if (!(tri_parse_failure)) { if (p1 < 1 || p2 < 1 || p3 < 1 || p1 > ver_nr || p2 > ver_nr || p3 > ver_nr) { FILE_ERROR(f, "OBJ file format error: wrong vertex index"); return 2; } tri = new Triangle(vertex_index[p1-1], vertex_index[p2-1], vertex_index[p3-1]); add_triangle(tri); // save in a list for the shape shape_triangles->push_back(tri); } break; default: // skip lines starting with all all other chars do // Reads till end of the line { type=fgetc(f); } while (type != EOF && type != '\n'); break; } if ((*update_progress)(ftell(f))) return 90; } // copy the vertices of this shape over shape_vertices->insert(shape_vertices->begin(), vertex_index.begin(), vertex_index.end()); shapes->push_back(new Shape(shape_triangles, shape_vertices)); return 0; } void OBJ_Mesh::write(FILE *f, const char *comment) { int n; list::iterator it; list::iterator iv; Vertex v; fprintf(f, "# produced by mview OBJ exporter\n"); fprintf(f, "# %s\n", comment); fprintf(f, "\ng main\n"); n=0; // vertices for (iv=vertices->begin(); iv != vertices->end(); iv++) { calc_original_coordinates(*iv, &v); fprintf(f,"v %f %f %f\n", v.x(), v.y(), v.z()); (*iv)->number=++n; } // triangles for (it=triangles->begin(); it != triangles->end(); it++) fprintf(f,"f %d %d %d\n", (*it)->vertices[0]->number, (*it)->vertices[1]->number, (*it)->vertices[2]->number); }