Merged in color picker into master branch
authorDmitriy Morozov <morozov@cs.duke.edu>
Mon, 07 Aug 2006 10:39:15 -0400
changeset 10 240ec9bb3d92
parent 9 b16a476ef46d (diff)
parent 6 8752e612ec07 (current diff)
child 11 b4cd9b9d6ca5
Merged in color picker into master branch
README
VEFViewer.cpp
VEFViewer.h
--- a/README	Sat Jul 29 23:25:10 2006 -0400
+++ b/README	Mon Aug 07 10:39:15 2006 -0400
@@ -1,6 +1,6 @@
 VEFViewer is written by Dmitriy Morozov <morozov@cs.duke.edu>.
 
-It uses libQGLViewer, and therefore is licensed under GPL.
+It uses Qt4, libQGLViewer, and is licensed under GPL.
 
 To build (on Linux):
 qmake
--- a/VEFViewer.cpp	Sat Jul 29 23:25:10 2006 -0400
+++ b/VEFViewer.cpp	Mon Aug 07 10:39:15 2006 -0400
@@ -1,6 +1,7 @@
 #include "VEFViewer.h"
 #include <QtDebug>
 #include <cstdio>
+#include "sphere.h"
 
 VEFViewer::VEFViewer(QWidget* parent): QGLViewer(parent)
 {
@@ -64,7 +65,6 @@
 	std::cout << "Center: " << center << std::endl;
 }
 
-// Draws a spiral
 void VEFViewer::draw()
 {
 	// GL_LIGHT0
@@ -167,46 +167,19 @@
 		QGLViewer::keyPressEvent(e);
 }
 
-void VEFViewer::readVertexFile(QString s)
+void VEFViewer::readVertexFile(const 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);
+	modelList->addItem(new QVerticesLWI(s, this));
 }
 
-void VEFViewer::readEdgeFile(QString s)
+void VEFViewer::readEdgeFile(const 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);
+	modelList->addItem(new QEdgesLWI(s, this));
 }
 
-void VEFViewer::readSTLFile(QString s)
+void VEFViewer::readSTLFile(const 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);
+	modelList->addItem(new QFacesLWI(s, this));
 }
 
 
@@ -237,11 +210,22 @@
 {
 	if (!isVisible()) return;
 		
-	glColor3f(color.redF(), color.greenF(), color.blueF());
-	glCallList(display_list);
+	glColor3f(color_.redF(), color_.greenF(), color_.blueF());
+	glCallList(display_list_);
 }
 
 // QVertices
+void QVerticesLWI::draw() const
+{
+	if (!isVisible()) return;
+
+	glColor3f(color_.redF(), color_.greenF(), color_.blueF());
+	if (!isSphere())
+		glCallList(display_list_);
+	else
+		glCallList(sphere_display_list_);
+	
+}
 void QVerticesLWI::drawWithNames(int offset) const
 {}
 int QVerticesLWI::numElements() const
@@ -249,24 +233,63 @@
 void QVerticesLWI::highlight(int selected)
 {}
 
-QVerticesLWI::QVerticesLWI(QString name, FILE* file, VEFViewer* v): 
-	QDisplayListLWI(name, QColor::fromRgbF(.5, .65, .65))
+QVerticesLWI::QVerticesLWI(QString fname, VEFViewer* v): 
+	QDisplayListLWI(fname, QColor::fromRgbF(.5, .65, .65)), isSphere_(false), viewer_(v)
+{
+	filename_ = fname;
+	QFileInfo fi(filename_);
+	setText(fi.baseName());
+	init();
+}
+
+void QVerticesLWI::init()
 {
-	display_list = glGenLists(1);
-	glNewList(display_list, GL_COMPILE);
+	FILE* file;
+	if ((file = fopen(filename_.toLocal8Bit().data(), "r")) == NULL)
+	{
+		qDebug() << "Could not open file " << filename_ << " for reading";
+		return;
+	}
+
+	// Read in vertices
+	Point p;
+	int result = fscanf(file, "%f %f %f", &p.x, &p.y, &p.z);
+	while(result != EOF)
+	{
+		vertices_.push_back(p);
+		viewer_->updateMinMax(p.x,p.y,p.z);
+		result = fscanf(file, "%f %f %f", &p.x, &p.y, &p.z);
+	}
+
+	// Create display list of points
+	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);
-		}
-
+		for (VertexContainer::const_iterator cur = vertices_.begin(); cur != vertices_.end(); ++cur)
+			glVertex3f(cur->x,cur->y,cur->z);
 	glEnd();
 	glEndList();
+
+	// Create display list of spheres
+	sphere_display_list_ = glGenLists(1);
+	glNewList(sphere_display_list_, GL_COMPILE);
+	for (VertexContainer::const_iterator cur = vertices_.begin(); cur != vertices_.end(); ++cur)
+	{
+		XYZ c;
+		c.x = cur->x; c.y = cur->y; c.z = cur->z;
+		CreateSphere(c, .01, 6);
+	}
+	glEnd();
+	glEndList();
+
+	fclose(file);
+}
+
+void QVerticesLWI::destroy()
+{
+	vertices_.clear();
+	glDeleteLists(sphere_display_list_, 1);
+	QDisplayListLWI::destroy();
 }
 
 
@@ -276,11 +299,11 @@
 	if (!isVisible()) return;
 
 	// Draw selected
-	if (highlighted >= 0)
+	if (highlighted_ >= 0)
 	{
-		glColor3f(color.light(200).redF(), color.light(200).greenF(), color.light(200).blueF());
+		glColor3f(color_.light(200).redF(), color_.light(200).greenF(), color_.light(200).blueF());
 		glBegin(GL_TRIANGLES);
-			const Triangle& t = triangles[highlighted];
+			const Triangle& t = triangles_[highlighted_];
 			glNormal3f(t.nx, t.ny, t.nz);
 			glVertex3f(t.x0, t.y0, t.z0);
 			glVertex3f(t.x1, t.y1, t.z1);
@@ -291,23 +314,24 @@
 	// Draw the object
 	if (!isWireframe())	
     {
-		glColor3f(color.light(150).redF(), color.light(150).greenF(), color.light(150).blueF());
-		glCallList(display_list);
+		glColor3f(color_.light(150).redF(), color_.light(150).greenF(), color_.light(150).blueF());
+		glCallList(display_list_);
     }
 	else
     {
-		glColor3f(color.redF(), color.greenF(), color.blueF());
-		glCallList(wireframe_display_list);
+		glColor3f(color_.redF(), color_.greenF(), color_.blueF());
+		glCallList(wireframe_display_list_);
     }
 }
 
 void QFacesLWI::drawWithNames(int offset) const
 {
 	if (!isVisible()) return;
+	if (isWireframe()) return;
 		
-	for (int i = 0; i < triangles.size(); i++)
+	for (int i = 0; i < triangles_.size(); i++)
 	{
-		const Triangle& t = triangles[i];
+		const Triangle& t = triangles_[i];
 		glPushName(offset + i);
 		glBegin(GL_TRIANGLES);
 		glVertex3f(t.x0, t.y0, t.z0);
@@ -319,16 +343,37 @@
 }
 
 int QFacesLWI::numElements() const
-{ return triangles.size(); }
+{ return triangles_.size(); }
 
 void QFacesLWI::highlight(int selected)
 {
-	highlighted = selected;
+	highlighted_ = selected;
+	if (highlighted_ < 0) return;
+
+	const Triangle& t = triangles_[highlighted_];
+	std::cout << "Highlighted: (" << t.x0 << " " << t.y0 << " " << t.z0 << std::endl;
+	std::cout << "              " << t.x1 << " " << t.y1 << " " << t.z1 << std::endl;
+	std::cout << "              " << t.x2 << " " << t.y2 << " " << t.z2 << ")" << std::endl;
 }
 
-QFacesLWI::QFacesLWI(QString name, FILE* file, VEFViewer* v):
-	QDisplayListLWI(name, QColor::fromRgbF(0,.4,.6)), highlighted(-1), isWireframe_(false)
+QFacesLWI::QFacesLWI(QString fname, VEFViewer* v):
+	QDisplayListLWI(fname, QColor::fromRgbF(0,.4,.6)), highlighted_(-1), isWireframe_(false), viewer_(v)
 {
+	filename_ = fname;
+	QFileInfo fi(filename_);
+	setText(fi.baseName());
+	init();
+}
+
+void QFacesLWI::init()
+{
+	FILE* file;
+	if ((file = fopen(filename_.toLocal8Bit().data(), "r")) == NULL)
+	{
+		qDebug() << "Could not open file " << filename_ << " for reading";
+		return;
+	}
+
 	float nx,ny,nz;			// not used
 	float x0,y0,z0;
 	float x1,y1,z1;
@@ -341,34 +386,41 @@
 		qglviewer::Vec n = computeNormal(qglviewer::Vec(x0,y0,z0), 
 										 qglviewer::Vec(x1,y1,z1), 
 										 qglviewer::Vec(x2,y2,z2)); 
-		triangles.push_back(Triangle(n.x,n.y,n.z, x0,y0,z0, x1,y1,z1, x2,y2,z2));
+		triangles_.push_back(Triangle(n.x,n.y,n.z, x0,y0,z0, x1,y1,z1, x2,y2,z2));
 
-		v->updateMinMax(x0,y0,z0);
-		v->updateMinMax(x1,y1,z1);
-		v->updateMinMax(x2,y2,z2);
+		viewer_->updateMinMax(x0,y0,z0);
+		viewer_->updateMinMax(x1,y1,z1);
+		viewer_->updateMinMax(x2,y2,z2);
 
 		result = readFacet(file, nx,ny,nz, x0,y0,z0, x1,y1,z1, x2,y2,z2);
 	}
+	fclose(file);
 	
-	std::cout << "Triangles read: " << triangles.size() << std::endl;
+	std::cout << "Triangles read: " << triangles_.size() << std::endl;
 	
 	// Create triangles display list
-	display_list = glGenLists(1);
-	glNewList(display_list, GL_COMPILE);
+	display_list_ = glGenLists(1);
+	glNewList(display_list_, GL_COMPILE);
 	drawTriangles(GL_TRIANGLES);
 	glEndList();
 
 	// Create wireframe display list
-	wireframe_display_list = glGenLists(1);
-	glNewList(wireframe_display_list, GL_COMPILE);
+	wireframe_display_list_ = glGenLists(1);
+	glNewList(wireframe_display_list_, GL_COMPILE);
 	drawTriangles(GL_LINE_LOOP);
 	glEndList();
+}
 
+void QFacesLWI::destroy()
+{
+	triangles_.clear();
+	glDeleteLists(wireframe_display_list_, 1);
+	QDisplayListLWI::destroy();
 }
 
 void QFacesLWI::drawTriangles(GLenum mode) const
 {
-	for (TrianglesContainer::const_iterator cur = triangles.begin(); cur != triangles.end(); ++cur)
+	for (TrianglesContainer::const_iterator cur = triangles_.begin(); cur != triangles_.end(); ++cur)
 	{
 		glBegin(mode);
 		glNormal3f(cur->nx,cur->ny,cur->nz);
@@ -413,11 +465,26 @@
 void QEdgesLWI::highlight(int selected)
 {}
 
-QEdgesLWI::QEdgesLWI(QString name, FILE* file, VEFViewer* v):
-	QDisplayListLWI(name, QColor::fromRgbF(.6,.2,.6))
+QEdgesLWI::QEdgesLWI(QString fname, VEFViewer* v):
+	QDisplayListLWI(fname, QColor::fromRgbF(.6,.2,.6)), viewer_(v)
 {
-	display_list = glGenLists(1);
-	glNewList(display_list, GL_COMPILE);
+	filename_ = fname;
+	QFileInfo fi(filename_);
+	setText(fi.baseName());
+	init();
+}
+
+void QEdgesLWI::init()
+{
+	FILE* file;
+	if ((file = fopen(filename_.toLocal8Bit().data(), "r")) == NULL)
+	{
+		qDebug() << "Could not open file " << filename_ << " for reading";
+		return;
+	}
+
+	display_list_ = glGenLists(1);
+	glNewList(display_list_, GL_COMPILE);
 	glBegin(GL_LINES);
 	
 		float nx,ny,nz;
@@ -430,14 +497,16 @@
 			glVertex3f(x0,y0,z0);
 			glVertex3f(x1,y1,z1);
 
-			v->updateMinMax(x0,y0,z0);
-			v->updateMinMax(x1,y1,z1);
+			viewer_->updateMinMax(x0,y0,z0);
+			viewer_->updateMinMax(x1,y1,z1);
 
 			result = readEdge(file, x0,y0,z0, x1,y1,z1);
 		}
 
 	glEnd();
 	glEndList();
+
+	fclose(file);
 }
 
 int QEdgesLWI::readEdge  (FILE* file,
--- a/VEFViewer.h	Sat Jul 29 23:25:10 2006 -0400
+++ b/VEFViewer.h	Mon Aug 07 10:39:15 2006 -0400
@@ -28,9 +28,9 @@
 		virtual void postSelection(const QPoint& point);
 
 	private:
-		void readVertexFile(QString s);
-		void readEdgeFile(QString s);
-		void readSTLFile(QString s);
+		void readVertexFile(const QString& s);
+		void readEdgeFile(const QString& s);
+		void readSTLFile(const QString& s);
 		void updateWeightedCenter(float x, float y, float z);
 		
 		QListWidget* modelList;
@@ -48,11 +48,11 @@
 	Q_OBJECT
 
 	public:
-		QDisplayListLWI(QString name, QColor color_):
-			QListWidgetItem(name), color(color_), visible(false)
+		QDisplayListLWI(QString name, QColor color):
+			QListWidgetItem(name), color_(color), visible_(false)
 		{ toggleVisible(); }
-		GLuint getDisplayList() const	{ return display_list; }
-		~QDisplayListLWI()				{ glDeleteLists(display_list, 1); }
+		GLuint getDisplayList() const	{ return display_list_; }
+		~QDisplayListLWI()				{ destroy(); }
 
 		virtual void draw() const;
 		virtual void drawWithNames(int offset) const =0;
@@ -60,6 +60,8 @@
 		virtual void highlight(int selected) =0;
 		virtual void setupMenu(QMenu& m) const
 		{
+			QAction* reload = m.addAction("Reload");
+			connect(reload, SIGNAL(triggered()), this, SLOT(reload()));
 			QAction* visible = m.addAction("Visible");
 			connect(visible, SIGNAL(triggered()), this, SLOT(toggleVisible()));
 			visible->setCheckable(true);
@@ -69,31 +71,65 @@
 			connect(color, SIGNAL(triggered()), this, SLOT(changeColor()));
 		}
 		
-		bool isVisible() const			{ return visible; }
+		bool isVisible() const			{ return visible_; }
 
 	public slots:
-		void setVisible(bool vis = true)	{ visible = !vis; adjustFont(); }
-		void toggleVisible()				{ visible = !visible; adjustFont(); }
+		void setVisible(bool vis = true)	{ visible_ = !vis; adjustFont(); }
+		void toggleVisible()				{ visible_ = !visible_; adjustFont(); }
+		virtual void reload()				{ destroy(); init(); }
+		virtual void init() =0;
+		virtual void destroy()				{ glDeleteLists(display_list_, 1); }
 		void changeColor()					
-		{ QColor nw = QColorDialog::getColor(color); if (nw.isValid()) color = nw; }
+		{ QColor nw = QColorDialog::getColor(color_); if (nw.isValid()) color_ = nw; }
 
 	protected:
-		GLuint display_list;
-		bool visible;
-		QColor color;
+		GLuint display_list_;
+		bool visible_;
+		QColor color_;
 
 	private:
-		void adjustFont()				{ QFont f; if (visible)	f.setBold(true); setFont(f); }
+		void adjustFont()				{ QFont f; if (visible_) f.setBold(true); setFont(f); }
 				
 };
 
+struct Point { float x,y,z; };
 class QVerticesLWI: public QDisplayListLWI
 {
+	Q_OBJECT
+		
 	public:
-		QVerticesLWI(QString name, FILE* file, VEFViewer* v);
+		QVerticesLWI(QString fname, VEFViewer* v);
+		virtual void draw() const;
 		virtual void drawWithNames(int offset) const;
 		virtual int numElements() const;
 		virtual void highlight(int selected);
+		virtual void setupMenu(QMenu& m) const
+		{
+			QDisplayListLWI::setupMenu(m);
+			
+			QAction* sphere_action= m.addAction("Sphere");
+			connect(sphere_action, SIGNAL(triggered()), this, SLOT(toggleSphere()));
+			sphere_action->setCheckable(true);
+			sphere_action->setChecked(isSphere());
+		}
+		
+		bool isSphere() const	{ return isSphere_; }
+	
+	public slots:
+		void toggleSphere()		{ isSphere_ = !isSphere_; }
+
+	private:
+		void init();
+		void destroy();
+
+		bool isSphere_;
+		GLuint sphere_display_list_;
+
+		typedef 	std::vector<Point>		VertexContainer;
+		VertexContainer vertices_;
+
+		QString filename_;
+		VEFViewer* viewer_;
 };
 
 class Triangle;
@@ -102,7 +138,7 @@
 	Q_OBJECT
 		
 	public:
-		QFacesLWI(QString name, FILE* file, VEFViewer* v);
+		QFacesLWI(QString fname, VEFViewer* v);
 		virtual void draw() const;
 		virtual void drawWithNames(int offset) const;
 		virtual int numElements() const;
@@ -122,6 +158,9 @@
 		void toggleWireframe()		{ isWireframe_ = !isWireframe_; }
 		
 	private:
+		void init();
+		void destroy();
+
 		int readFacet(FILE* file,
 					  float& nx, float& ny, float& nz,
                       float& x0, float& y0, float& z0,
@@ -131,25 +170,33 @@
 		void drawTriangles(GLenum mode) const;
 
 		typedef 	std::vector<Triangle>		TrianglesContainer;
-		TrianglesContainer triangles;
+		TrianglesContainer triangles_;
 
 		bool isWireframe_;
-		GLuint wireframe_display_list;
-		int highlighted;
+		GLuint wireframe_display_list_;
+		int highlighted_;
+
+		QString filename_;
+		VEFViewer* viewer_;
 };
 
 class QEdgesLWI: public QDisplayListLWI
 {
 	public:
-		QEdgesLWI(QString name, FILE* file, VEFViewer* v);
+		QEdgesLWI(QString fname, VEFViewer* v);
 		virtual void drawWithNames(int offset) const;
 		virtual int numElements() const;
 		virtual void highlight(int selected);
 
 	private:
+		virtual void init();
+
 		int readEdge (FILE* file,
                       float& x0, float& y0, float& z0,
                       float& x1, float& y1, float& z1);
+
+		QString filename_;
+		VEFViewer* viewer_;
 };
 
 class Triangle
--- a/VEFViewer.pro	Sat Jul 29 23:25:10 2006 -0400
+++ b/VEFViewer.pro	Mon Aug 07 10:39:15 2006 -0400
@@ -2,8 +2,8 @@
 TARGET   = VEFViewer
 CONFIG  += qt opengl warn_on release thread
 
-HEADERS  = VEFViewer.h
-SOURCES  = VEFViewer.cpp main.cpp
+HEADERS  = VEFViewer.h sphere.h
+SOURCES  = VEFViewer.cpp sphere.cpp main.cpp
 FORMS   *= viewerInterface.Qt4.ui
 
 # The rest of this configuration file is pretty complex since it tries to automatically
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphere.cpp	Mon Aug 07 10:39:15 2006 -0400
@@ -0,0 +1,53 @@
+#include "sphere.h"
+#include <cmath>
+
+void CreateSphere(XYZ c,double r,int n)
+{
+	int i,j;
+	double theta1,theta2,theta3;
+	XYZ e,p;
+
+	if (r < 0)
+		r = -r;
+	if (n < 0)
+		n = -n;
+	if (n < 4 || r <= 0) {
+		glBegin(GL_POINTS);
+		glVertex3f(c.x,c.y,c.z);
+		glEnd();
+		return;
+	}
+
+	for (j=0;j<n/2;j++) {
+		theta1 = j * TWOPI / n - PID2;
+		theta2 = (j + 1) * TWOPI / n - PID2;
+
+		glBegin(GL_QUAD_STRIP);
+		for (i=0;i<=n;i++) {
+			theta3 = i * TWOPI / n;
+
+			e.x = cos(theta2) * cos(theta3);
+			e.y = sin(theta2);
+			e.z = cos(theta2) * sin(theta3);
+			p.x = c.x + r * e.x;
+			p.y = c.y + r * e.y;
+			p.z = c.z + r * e.z;
+
+			glNormal3f(e.x,e.y,e.z);
+			glTexCoord2f(i/(double)n,2*(j+1)/(double)n);
+			glVertex3f(p.x,p.y,p.z);
+
+			e.x = cos(theta1) * cos(theta3);
+			e.y = sin(theta1);
+			e.z = cos(theta1) * sin(theta3);
+			p.x = c.x + r * e.x;
+			p.y = c.y + r * e.y;
+			p.z = c.z + r * e.z;
+
+			glNormal3f(e.x,e.y,e.z);
+			glTexCoord2f(i/(double)n,2*j/(double)n);
+			glVertex3f(p.x,p.y,p.z);
+		}
+		glEnd();
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphere.h	Mon Aug 07 10:39:15 2006 -0400
@@ -0,0 +1,22 @@
+/*
+	Create a sphere centered at c, with radius r, and precision n
+	Draw a point for zero radius spheres
+
+	Code by Paul Bourke	<http://astronomy.swin.edu.au/~pbourke/opengl/sphere/>
+*/
+
+#include <GL/gl.h>
+
+const double TWOPI = 2*3.14;
+const double PID2 = 3.14/2;
+
+struct XYZ
+{
+	XYZ(GLfloat xx = 0, GLfloat yy = 0, GLfloat zz = 0):
+		x(xx), y(yy), z(zz)
+	{}
+	
+	GLfloat x,y,z;
+};
+
+void CreateSphere(XYZ c,double r,int n);