// // File: vrml1_mesh.cc // // (C) 2000-2006 Helmut Cantzler // // Licensed under the terms of the Lesser General Public License. // #include "vrml1_mesh.h" int Vrml1_Mesh::read(FILE *f, int (*update_progress)(int pos), void (*set_total)(int size)) { char s1[101], s2[21]; fseek(f, 0, SEEK_END); (*set_total)(ftell(f)); fseek(f, 0, SEEK_SET); if (fscanf(f,"%100s %20s", s1, s2) != 2) // Read header { FILE_ERROR(f, "VRML header format error"); return 2; } while (fgetc(f) != '\n') // Reads till end of the line ; // check header if (strcasecmp(s1,"#VRML") != 0 || strcasecmp(s2,"V1.0") != 0) { FILE_ERROR(f, "VRML1 header format error"); return 3; } list *shape_triangles; list *shape_vertices; vector *vertex_index; Triangle *tri; Vertex *v; int res, shape_nr, text_no, p1, p2, p3, end; float x, y, z; shape_triangles = new list; shape_vertices = new list; shape_nr=0; do { text_no=0; vertex_index = new vector; // look for vertices (points) do { res=fscanf(f,"%100s",s1); } while (res != EOF && strcasecmp(s1,"Coordinate3") != 0); if ((*update_progress)(ftell(f))) return 90; if (strcasecmp(s1,"Coordinate3") == 0) { shape_nr++; fscanf(f,"%100s",s1); while (strcasecmp(s1,"point") != 0 && strcasecmp(s1,"}") != 0) fscanf(f,"%100s",s1); if (strcasecmp(s1,"point") == 0) { while (fgetc(f) != '[') // Reads till begin of points ; while (fscanf(f,"%f",&x) == 1) { if (fscanf(f,"%f %f%*c",&y,&z) != 2) { FILE_ERROR(f, "VRML file format error: v"); return 4; } 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; } } } // look for triangles (faces) while (res != EOF && strcasecmp(s1,"IndexedFaceSet") != 0) res=fscanf(f,"%100s",s1); if (strcasecmp(s1,"IndexedFaceSet") == 0) { fscanf(f,"%100s",s1); while (strcasecmp(s1,"coordIndex") != 0 && strcasecmp(s1,"}") != 0) fscanf(f,"%100s",s1); if (strcasecmp(s1,"coordIndex") == 0) { while (fgetc(f) != '[') // Reads till begin of triangles ; while (fscanf(f,"%d%*c",&p1) == 1) { if (fscanf(f,"%d%*c %d%*c",&p2,&p3) != 2) { FILE_ERROR(f, "VRML file format error: t"); return 5; } fscanf(f,"%d%*c",&end); if (end == -1) { // number of points is 3 => ok tri=new Triangle((*vertex_index)[p1], (*vertex_index)[p2], (*vertex_index)[p3]); add_triangle(tri); shape_triangles->push_back(tri); } else // no end (-1) => seek to end (-1) while (end != -1 && res == 1) res=fscanf(f,"%d,",&end); if ((*update_progress)(ftell(f))) return 90; } } } // copy the vertices of this shape over shape_vertices->insert(shape_vertices->end(), vertex_index->begin(), vertex_index->end()); delete vertex_index; } while (res != EOF); shapes->push_back(new Shape(shape_triangles, shape_vertices)); return 0; } void Vrml1_Mesh::write(FILE *f, const char *comment) { int n; list::iterator it; list::iterator iv; Vertex v; fprintf(f,"#VRML V1.0 ascii\n"); fprintf(f,"# %s\n", comment); fprintf(f,"Separator {\n"); fprintf(f,"\tMaterial {\n"); fprintf(f,"\t\tambientColor 0.2 0.2 0.2\n"); fprintf(f,"\t\tdiffuseColor 1.0 1.0 1.0\n"); fprintf(f,"\t}\n"); fprintf(f,"\tCoordinate3 {\n"); fprintf(f,"\t\t point [\n"); n=0; iv=vertices->begin(); // vertices if (iv != vertices->end()) { calc_original_coordinates(*iv, &v); fprintf(f,"\t\t\t%f %f %f", v.x(), v.y(), v.z()); (*iv)->number=n; for (iv++; iv != vertices->end(); iv++) { calc_original_coordinates(*iv, &v); fprintf(f,",\n\t\t\t%f %f %f", v.x(), v.y(), v.z()); n++; (*iv)->number=n; } } fprintf(f," ]\n\t}\n"); fprintf(f,"\tIndexedFaceSet {\n"); fprintf(f,"\t\t coordIndex [\n"); it=triangles->begin(); // triangles if (it != triangles->end()) { fprintf(f,"\t\t\t%d, %d, %d, -1", (*it)->vertices[0]->number, (*it)->vertices[1]->number, (*it)->vertices[2]->number); for (it++; it != triangles->end(); it++) fprintf(f,",\n\t\t\t%d, %d, %d, -1", (*it)->vertices[0]->number, (*it)->vertices[1]->number, (*it)->vertices[2]->number); } fprintf(f," ]\n\t}\n}\n"); }