Newer
Older
Import / research / 3d-z-maps / mview-0.3.3 / mview / geomview_mesh.cpp
//
//    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);
}