VEFViewer.cpp
author morozov@geomdm.geomagic.com
Mon, 12 Jun 2006 10:46:00 -0400
changeset 1 9ac2dc8d1e24
parent 0 1168ca87fd4e
child 2 f3516f064329
permissions -rw-r--r--
Reads and displays vertices, edges, and faces

#include "VEFViewer.h"
#include <QtDebug>
#include <cstdio>

VEFViewer::VEFViewer(QWidget* parent): QGLViewer(parent)
{
	restoreStateFromFile();
}

void VEFViewer::init()
{
	setBackgroundColor(QColor(0xAA, 0xAA, 0xAA));
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
}

void VEFViewer::addFile(QString s)
{
	GLuint display_list;
	
	QFileInfo fi(s);
	QString ext = fi.suffix();

	if (ext == "vrt")
		readVertexFile(s);
	else if (ext == "edg")
		readEdgeFile(s);
	else if (ext == "stl")
		readSTLFile(s);
	else
		return;
	
	setSceneBoundingBox(min, max);
	setSceneCenter(center);
	camera()->centerScene();
	camera()->showEntireScene();

	std::cout << "Min: " << min << std::endl;
	std::cout << "Max: " << max << std::endl;
	std::cout << "Center: " << center << std::endl;
}

// Draws a spiral
void VEFViewer::draw()
{
	const GLfloat light_pos0[4] = {center.x, center.y, center.z, 1.0};
	glLightfv(GL_LIGHT0, GL_POSITION, light_pos0);
		
	for (int i = 0; i < modelList->count(); i++)
	{
		QDisplayListLWI* dl = static_cast<QDisplayListLWI*>(modelList->item(i));
		dl->display();
	}
}

QString VEFViewer::helpString() const
{
  QString text("<h2>VEFViewer</h2>");
  text += "Displays vertices (vrt), edges (edg), and face (stl) files.";
  return text;
}

void VEFViewer::keyPressEvent(QKeyEvent* e) 
{
	const Qt::KeyboardModifiers modifiers = e->modifiers();

	bool handled = false;
	if ((e->key() == Qt::Key_O) && (modifiers == Qt::NoButton))
	{
		QString s = QFileDialog::getOpenFileName(this, "Choose file to open", ".", "3D data (*.vrt *.edg *.stl)");
		if (!s.isNull())
			addFile(s);
	}

	if (!handled)
		QGLViewer::keyPressEvent(e);
}

void VEFViewer::readVertexFile(QString s)
{
	FILE* file;
	if ((file = fopen(s.toLocal8Bit().data(), "r")) == NULL)
	{
		qDebug() << "Could not open file " << s << " for reading";
		return;
	}

	QFileInfo fi(s);
	modelList->addItem(new QVerticesLWI(fi.baseName(), file, this));
	fclose(file);
}

void VEFViewer::readEdgeFile(QString s)
{
	FILE* file;
	if ((file = fopen(s.toLocal8Bit().data(), "r")) == NULL)
	{
		qDebug() << "Could not open file " << s << " for reading";
		return;
	}

	QFileInfo fi(s);
	modelList->addItem(new QEdgesLWI(fi.baseName(), file, this));
	fclose(file);
}

void VEFViewer::readSTLFile(QString s)
{
	FILE* file;
	if ((file = fopen(s.toLocal8Bit().data(), "r")) == NULL)
	{
		qDebug() << "Could not open file " << s << " for reading";
		return;
	}

	QFileInfo fi(s);
	modelList->addItem(new QFacesLWI(fi.baseName(), file, this));
	fclose(file);
}


void VEFViewer::updateMinMax(float x, float y, float z)
{
	if (x < min.x)	min.x = x;
	if (y < min.y)	min.y = y;
	if (z < min.z)	min.z = z;
	
	if (x > max.x)	max.x = x;
	if (y > max.y)	max.y = y;
	if (z > max.z)	max.z = z;

	updateWeightedCenter(x, y, z);
}

void VEFViewer::updateWeightedCenter(float x, float y, float z)
{
	vertex_count++;
	center.x = float(vertex_count - 1)/vertex_count * center.x + x/vertex_count;
	center.y = float(vertex_count - 1)/vertex_count * center.y + y/vertex_count;
	center.z = float(vertex_count - 1)/vertex_count * center.z + z/vertex_count;
}


// QVertices
void QVerticesLWI::display() const
{
	glColor3f(.5, .65, .65);
	glCallList(display_list);
}

QVerticesLWI::QVerticesLWI(QString name, FILE* file, VEFViewer* v): 
	QDisplayListLWI(name)
{
	display_list = glGenLists(1);
	glNewList(display_list, GL_COMPILE);
	glBegin(GL_POINTS);
	
		float x,y,z;
		int result = fscanf(file, "%f %f %f", &x, &y, &z);
		while(result != EOF)
		{
			glVertex3f(x,y,z);
			v->updateMinMax(x,y,z);
			result = fscanf(file, "%f %f %f", &x, &y, &z);
		}

	glEnd();
	glEndList();
}


// QFaces
void QFacesLWI::display() const
{
	glColor3f(0., .4, .6);
	glCallList(display_list);
}

QFacesLWI::QFacesLWI(QString name, FILE* file, VEFViewer* v):
	QDisplayListLWI(name)
{
	display_list = glGenLists(1);
	glNewList(display_list, GL_COMPILE);
	glBegin(GL_TRIANGLES);
	
		float nx,ny,nz;
		float x0,y0,z0;
		float x1,y1,z1;
		float x2,y2,z2;

		int result = readFacet(file, nx,ny,nz, x0,y0,z0, x1,y1,z1, x2,y2,z2);
		while(result != EOF)
		{
			glNormal3f(nx,ny,nz);
			
			glVertex3f(x0,y0,z0);
			glVertex3f(x1,y1,z1);
			glVertex3f(x2,y2,z2);

#if 0
			std::cout << "Adding triangle" << std::endl;
			std::cout << nx << " " << ny << " " << nz << std::endl;
			std::cout << x0 << " " << y0 << " " << z0 << std::endl;
			std::cout << x1 << " " << y1 << " " << z1 << std::endl;
			std::cout << x2 << " " << y2 << " " << z2 << std::endl;
#endif
			
			v->updateMinMax(x0,y0,z0);
			v->updateMinMax(x1,y1,z1);
			v->updateMinMax(x2,y2,z2);

			result = readFacet(file, nx,ny,nz, x0,y0,z0, x1,y1,z1, x2,y2,z2);
		}

	glEnd();
	glEndList();
}

int QFacesLWI::readFacet(FILE* file,
						  float& nx, float& ny, float& nz, 
						  float& x0, float& y0, float& z0,
						  float& x1, float& y1, float& z1,
						  float& x2, float& y2, float& z2)
{
	
		
	int result = fscanf(file, "%*s %*s %f %f %f", &nx, &ny, &nz);
		result = fscanf(file, "%*s %*s");
		result = fscanf(file, "%*s %f %f %f", &x0, &y0, &z0);
		result = fscanf(file, "%*s %f %f %f", &x1, &y1, &z1);
		result = fscanf(file, "%*s %f %f %f", &x2, &y2, &z2);
		result = fscanf(file, "%*s");
		result = fscanf(file, "%*s");
	return result;
}

// QEdges
void QEdgesLWI::display() const
{
	glColor3f(.6, .2, .6);
	glCallList(display_list);
}

QEdgesLWI::QEdgesLWI(QString name, FILE* file, VEFViewer* v):
	QDisplayListLWI(name)
{
	display_list = glGenLists(1);
	glNewList(display_list, GL_COMPILE);
	glBegin(GL_LINES);
	
		float nx,ny,nz;
		float x0,y0,z0;
		float x1,y1,z1;

		int result = readEdge(file, x0,y0,z0, x1,y1,z1);
		while(result != EOF)
		{
			glVertex3f(x0,y0,z0);
			glVertex3f(x1,y1,z1);

			v->updateMinMax(x0,y0,z0);
			v->updateMinMax(x1,y1,z1);

			result = readEdge(file, x0,y0,z0, x1,y1,z1);
		}

	glEnd();
	glEndList();
}

int QEdgesLWI::readEdge  (FILE* file,
						  float& x0, float& y0, float& z0,
						  float& x1, float& y1, float& z1)
{
	int result = fscanf(file, "%f %f %f", &x0, &y0, &z0);
		result = fscanf(file, "%f %f %f", &x1, &y1, &z1);

	std::cout << x0 << ' ' << y0 << ' ' << z0 << std::endl;
	std::cout << x1 << ' ' << y1 << ' ' << z1 << std::endl;
	return result;
}