//
// File: geomview_mesh.cc
//
// (C) 2000-2008 Helmut Cantzler
//
// Licensed under the terms of the Lesser General Public License.
//
#include "geomview_mesh.h"
int GeomviewMesh::read(FILE *f, int (*updateProgress)(int pos),
void (*setTotal)(int size))
{
list<Triangle*> *shapeTriangles;
list<Vertex*> *shapeVertices;
vector<Vertex*> vertexIndex;
int p1, p2, p3, i, vNr, pNr;
float c1, c2, c3, c4;
char nr;
float x, y, z;
Triangle *tri;
Vertex *v;
fseek(f, 0, SEEK_END);
(*setTotal)(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", &vNr, &pNr) != 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", &vNr, &pNr) != 2) &&
(fscanf(f,"COFF %d %d", &vNr, &pNr) != 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
;
shapeTriangles = new list<Triangle*>;
shapeVertices = new list<Vertex*>;
for (i=0; i < vNr; 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);
addVertex(v);
// save in a vector for the triangles and shape
vertexIndex.push_back(v);
if ((*updateProgress)(ftell(f)))
return 90;
}
while ((0 < pNr) && (!(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;
}
addEdge(new Edge(vertexIndex[p1], vertexIndex[p2]));
pNr--;
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 >= verNr) || (p2 >= verNr) || (p3 >= verNr)){
FILE_ERROR(f, "Geomview file format error: vertex index out of range");
return 8;
}
tri = new Triangle(vertexIndex[p1], vertexIndex[p2], vertexIndex[p3]);
addTriangle(tri);
pNr--;
// save in a list for the shape
shapeTriangles->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:
if (nr>'3' && nr<'9')
{ // N vertex polygons of form "N v1 v2...vN" on the line
int nPoints=nr-'0';
fscanf(f,"%d %d",&p1,&p3);
for (int i=2;i<nPoints;++i)
{
p2=p3;
fscanf(f," %d",&p3);
tri = new Triangle(vertexIndex[p1], vertexIndex[p2],vertexIndex[p3], POLYGON_TRIANGLE);
addTriangle(tri);
shapeTriangles->push_back(tri);
}
pNr--;
}
break;
}
if ((*updateProgress)(ftell(f)))
return 90;
}
// copy the vertices of this shape over
shapeVertices->insert(shapeVertices->begin(),
vertexIndex.begin(), vertexIndex.end());
shapes->push_back(new Shape(shapeTriangles, shapeVertices));
return 0;
}
void GeomviewMesh::write(FILE *f, const char *comment)
{
int n;
list<Triangle*>::iterator it;
list<Vertex*>::iterator iv;
Vertex v;
// header
fprintf(f,"OFF\n%d %d 0\n", verNr, triNr);
n=0; // vertices
for (iv=vertices->begin(); iv != vertices->end(); iv++)
{
calcOriginalCoordinates(*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);
}