//
// File: vrml1_mesh.cc
//
// (C) 2000-2008 Helmut Cantzler
//
// Licensed under the terms of the Lesser General Public License.
//
#include <string.h>
#include "vrml1_mesh.h"
int Vrml1Mesh::read(FILE *f, int (*updateProgress)(int pos),
void (*setTotal)(int size))
{
char s1[101], s2[21];
fseek(f, 0, SEEK_END);
(*setTotal)(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<Triangle*> *shapeTriangles;
list<Vertex*> *shapeVertices;
vector<Vertex*> *vertexIndex;
Triangle *tri;
Vertex *v;
int res, shapeNr, textNo, p1, p2, p3, end;
float x, y, z;
shapeTriangles = new list<Triangle*>;
shapeVertices = new list<Vertex*>;
shapeNr=0;
do
{
textNo=0;
vertexIndex = new vector<Vertex*>;
// look for vertices (points)
do
{
res=fscanf(f,"%100s",s1);
}
while (res != EOF && strcasecmp(s1,"Coordinate3") != 0);
if ((*updateProgress)(ftell(f)))
return 90;
if (strcasecmp(s1,"Coordinate3") == 0)
{
shapeNr++;
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);
addVertex(v);
// save in a vector for the triangles and shape
vertexIndex->push_back(v);
if ((*updateProgress)(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((*vertexIndex)[p1],
(*vertexIndex)[p2],
(*vertexIndex)[p3]);
addTriangle(tri);
shapeTriangles->push_back(tri);
}
else
// no end (-1) => seek to end (-1)
while (end != -1 && res == 1)
res=fscanf(f,"%d,",&end);
if ((*updateProgress)(ftell(f)))
return 90;
}
}
}
// copy the vertices of this shape over
shapeVertices->insert(shapeVertices->end(),
vertexIndex->begin(), vertexIndex->end());
delete vertexIndex;
}
while (res != EOF);
shapes->push_back(new Shape(shapeTriangles, shapeVertices));
return 0;
}
void Vrml1Mesh::write(FILE *f, const char *comment)
{
int n;
list<Triangle*>::iterator it;
list<Vertex*>::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())
{
calcOriginalCoordinates(*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++)
{
calcOriginalCoordinates(*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");
}