Newer
Older
Import / research / 3d-z-maps / mview-0.3.3 / mview / vtk_mesh.cpp
//
//    File: vtk_mesh.cc
//
//    (C) 2006-2008 Toby Breckon
//
//    Licensed under the terms of the Lesser General Public License.
//

#include <string.h>

#include "vtk_mesh.h"

int VTKMesh::read(FILE *f, int (*updateProgress)(int pos),
		  void (*setTotal)(int size))
{
  list<Triangle*> *shapeTriangles;
  list<Vertex*> *shapeVertices;
  vector<Vertex*> vertexIndex;
  Triangle *tri;
  Vertex *v;
  char buffer[21];
  int vertexCount = 0;
  int polygonCount = 0;
  int tmp, p1, p2, p3;
  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*>;
	
	// skip first two lines
	
	while (fgetc(f) != '\n') // Reads all of the 1st line
    ;
	while (fgetc(f) != '\n') // Reads all of the 2nd line
    ;
	
	// process rest of file
	
  while ((fscanf(f,"%20s ", buffer) != 0) && (!(feof(f))))
  {
		
		if (strcasecmp(buffer, "BINARY") == 0)
		{
			// check file is ASCII
			FILE_ERROR(f, "VTK file format error: VTK ASCII support only.");
		  return 3;
		} 
		else if (strcasecmp(buffer, "DATASET") == 0)
		{
			// check DATASET is type POLYDATA	
		  if ((fscanf(f,"%20s ", buffer) != 1) || 
				 (strcasecmp(buffer, "POLYDATA") != 0)) 
			{
				FILE_ERROR(f, "VTK file format error: POLYDATA data set support only.");
		  	return 3;
			}
		} 
		else if (strcasecmp(buffer, "POINTS") == 0)
		{
			// get points
			
			if (fscanf(f,"%d float", &vertexCount) != 1)
			{
				FILE_ERROR(f, "VTK file format error: vertex/point count");
	  		return 3;
			}
			
			for (int i = 1; i <= vertexCount; i++)
			{
				if ((fscanf(f,"%f %f %f",&x,&y,&z) != 3) && (!(feof(f))))
				{
	  			FILE_ERROR(f, "VTK file format error: vertex value");
	  			return 3;
				}
      	v = new Vertex(x,y,z);
      	addVertex(v);
      	// save in a vector for the edges and shape
      	vertexIndex.push_back(v);

      	if ((*updateProgress)(ftell(f)))
					return 90;
			}
		} 
		else if (strcasecmp(buffer, "POLYGONS") == 0)
		{
			// get polygons
			if (fscanf(f,"%d %d", &polygonCount, &tmp) != 2)
			{
				FILE_ERROR(f, "VTK file format error: polygon count");
	  		return 3;
			}
			
			while (fgetc(f) != '\n') // Reads all of the line
    		;
			
			for (int i=0; i < polygonCount; i++) /* Reads the triangles */
      {
				if (fscanf(f,"3 %d %d %d\n",&p1,&p2,&p3) == 3)
				{
					if ((p1 >= vertexCount) || (p2 >= vertexCount) || (p3 >= vertexCount)){
						FILE_ERROR(f, "VTK file format error: vertex index out of range");
			  		return 8;
		  		} else {
						tri = new Triangle(vertexIndex[p1], vertexIndex[p2], vertexIndex[p3]);
						addTriangle(tri);
						// save in a list for the shape
						shapeTriangles->push_back(tri);
					}
				} else {
					// ignore polygons of > 3 vertices
				}
				
				if ((*updateProgress)(ftell(f)))
					return 90;
      }
		} 
		else 
		{
			// ignore everything else in file
		}
	}
		
	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 VTKMesh::write(FILE *f, const char *comment)
{
  int n;
  list<Triangle*>::iterator it;
  list<Vertex*>::iterator iv;
  Vertex v;

  fprintf(f, "# vtk DataFile Version 2.0\n");
  fprintf(f, "Generated by mview VTK exporter : %s\n", comment);
  fprintf(f, "ASCII\n");
	fprintf(f, "DATASET POLYDATA\n");

	
  n=0;    // vertices
	fprintf(f, "POINTS %i float\n", vertices->size());
  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;
    }

  // triangles
	fprintf(f, "POLYGONS %i %i\n", triangles->size(), triangles->size() * 4);
  for (it=triangles->begin(); it != triangles->end(); it++)
    fprintf(f,"3 %d %d %d\n", ((*it)->vertices[0]->number) -1 ,
	    ((*it)->vertices[1]->number) -1, ((*it)->vertices[2]->number) -1);
}