// // File: geomview_mesh.cc // // (C) 2000-2006 Helmut Cantzler // // Licensed under the terms of the Lesser General Public License. // #include "geomview_mesh.h" int Geomview_Mesh::read(FILE *f, int (*update_progress)(int pos), void (*set_total)(int size)) { list *shape_triangles; list *shape_vertices; vector vertex_index; int p1, p2, p3, i, v_nr, p_nr; float c1, c2, c3, c4; char nr; float x, y, z; Triangle *tri; Vertex *v; fseek(f, 0, SEEK_END); (*set_total)(ftell(f)); fseek(f, 0, SEEK_SET); while (fgetc(f) != '\n') // Reads all of the 1st line ; fscanf(f,"3\n"); // get optional // dimensionality value from header (i.e 3) if (fscanf(f,"%d %d", &v_nr, &p_nr) != 2) // Read vertices/polygons header // on failure try alternatives with OFF/COFF & vertices/polygons on same // first line { fseek(f, 0, SEEK_SET); if ((fscanf(f,"OFF %d %d", &v_nr, &p_nr) != 2) && (fscanf(f,"COFF %d %d", &v_nr, &p_nr) != 2)) // Read vertices/polygons header { FILE_ERROR(f, "Geomview (OFF) header format error: cannot get vertex/polygon count"); return 2; } } while (fgetc(f) != '\n') // Reads till end of the line ; shape_triangles = new list; shape_vertices = new list; for (i=0; i < v_nr; i++) // Reads the vertices { if (fscanf(f,"%f %f %f",&x,&y,&z) != 3) { FILE_ERROR(f, "Geomview (OFF) file format error: vertex list"); return 3; } while (fgetc(f) != '\n'); // Read till end of the line // to skip texture/colour values v = new Vertex(x,y,z); add_vertex(v); // save in a vector for the triangles and shape vertex_index.push_back(v); if ((*update_progress)(ftell(f))) return 90; } while ((0 < p_nr) && (!(feof(f)))) /* Reads the polygons to end of file or max polys.*/ { fscanf(f,"%c", &nr); switch (nr) { case '2': if (fscanf(f,"%d %d\n", &p1, &p2) != 2) { FILE_ERROR(f, "Geomview (OFF) file format error: polygon 2"); return 6; } add_edge(new Edge(vertex_index[p1], vertex_index[p2])); p_nr--; break; case '3': if (fscanf(f,"%d %d %d\n", &p1, &p2, &p3) != 3) { // if this fails then handle and ignore upto 4 colourspec values if ( (fscanf(f,"%d %d %d %f\n", &p1, &p2, &p3, &c1) != 4) && (fscanf(f,"%d %d %d %f %f\n", &p1, &p2, &p3, &c1, &c2) != 5) && (fscanf(f,"%d %d %d %f %f %f\n", &p1, &p2, &p3, &c1, &c2, &c3) != 6) && (fscanf(f,"%d %d %d %f %f %f %f\n", &p1, &p2, &p3, &c1, &c2, &c3, &c4) != 7) ) { FILE_ERROR(f, "Geomview file format error: polygon 3"); return 7; } } if ((p1 >= ver_nr) || (p2 >= ver_nr) || (p3 >= ver_nr)){ FILE_ERROR(f, "Geomview file format error: vertex index out of range"); return 8; } tri = new Triangle(vertex_index[p1], vertex_index[p2], vertex_index[p3]); add_triangle(tri); p_nr--; // save in a list for the shape shape_triangles->push_back(tri); break; case '#': // skip comments do { nr=fgetc(f); } while ((!(feof(f))) && nr != '\n'); break; case ' ': case '\t': case '\n': // skip leading whitespace characters break; default: // skip any lines that that we are not interested in // (i.e. don't begin with the cases above) // e.g. N vertex polygons of form "N v1 v2...vN" on the line do { nr=fgetc(f); } while ((!(feof(f))) && nr != '\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 Geomview_Mesh::write(FILE *f, const char *comment) { int n; list::iterator it; list::iterator iv; Vertex v; // header fprintf(f,"OFF\n%d %d 0\n", ver_nr, tri_nr); n=0; // vertices for (iv=vertices->begin(); iv != vertices->end(); iv++) { calc_original_coordinates(*iv, &v); fprintf(f,"%f %f %f\n", v.x(), v.y(), v.z()); (*iv)->number=n; n++; } for (it=triangles->begin(); it != triangles->end(); it++) fprintf(f,"3 %d %d %d\n", (*it)->vertices[0]->number, (*it)->vertices[1]->number, (*it)->vertices[2]->number); }