//
// File: obj_mesh.cc
//
// (C) 2006-2008 Toby Breckon / Helmut Cantzler
//
// Licensed under the terms of the Lesser General Public License.
//
#include "obj_mesh.h"
int OBJMesh::read(FILE *f, int (*updateProgress)(int pos),
void (*setTotal)(int size))
{
list<Triangle*> *shapeTriangles;
list<Vertex*> *shapeVertices;
vector<Vertex*> vertexIndex;
vector<int> faceIndices;
Triangle *tri;
Vertex *v;
char type;
int p;
float x, y, z;
fseek(f, 0, SEEK_END);
(*setTotal)(ftell(f));
fseek(f, 0, SEEK_SET);
shapeTriangles = new list<Triangle*>;
shapeVertices = new list<Vertex*>;
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, "OBJ file format error: v");
return 1;
}
v = new Vertex(x,y,z);
addVertex(v);
// save in a vector for the triangles and shape
vertexIndex.push_back(v);
}
break;
case 'f': // Polygon with n vertices
faceIndices.clear();
// read vertex indices of the current face until end of line
do
{
if (fscanf(f," %d", &p) != 1)
break;
faceIndices.push_back(p);
do // Reads till next space
{ type=fgetc(f); }
while (type != EOF && type != ' ' && type != '\n');
}
while (type != '\n');
// build normal triangle
if (faceIndices.size() == 3)
{
if (faceIndices[0] < 1 || faceIndices[1] < 1 || faceIndices[2] < 1 ||
faceIndices[0] > verNr || faceIndices[1] > verNr || faceIndices[2] > verNr)
{
FILE_ERROR(f, "OBJ file format error: wrong vertex index");
return 2;
}
tri = new Triangle(vertexIndex[ faceIndices[0]-1 ], vertexIndex[ faceIndices[1]-1 ],
vertexIndex[ faceIndices[2]-1 ]);
addTriangle(tri);
shapeTriangles->push_back(tri);
}
// build triangles from polygons
if (faceIndices.size() > 3)
{
for (p=1; p < faceIndices.size()-1; p++)
{
if (faceIndices[0] < 1 || faceIndices[p] < 1 || faceIndices[p+1] < 1 ||
faceIndices[0] > verNr || faceIndices[p] > verNr || faceIndices[p+1] > verNr)
{
FILE_ERROR(f, "OBJ file format error: wrong vertex index");
return 2;
}
tri = new Triangle(vertexIndex[ faceIndices[0]-1 ], vertexIndex[ faceIndices[p]-1 ],
vertexIndex[ faceIndices[p+1]-1 ], POLYGON_TRIANGLE);
addTriangle(tri);
shapeTriangles->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 ((*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 OBJMesh::write(FILE *f, const char *comment)
{
int n;
list<Triangle*>::iterator it;
list<Vertex*>::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++)
{
calcOriginalCoordinates(*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);
}