#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;
}