VEFViewer.h
author Dmitriy Morozov <dmitriy@mrzv.org>
Tue, 21 Jul 2009 09:57:31 -0700
changeset 16 bff3d7c294ff
parent 13 554df9494fd2
permissions -rw-r--r--
Fixed lights and spheres according to Martin's instructions

#ifndef __VEFVIEWER_H__
#define __VEFVIEWER_H__

#include <QGLViewer/qglviewer.h>
#include <QFileDialog>
#include <QListWidgetItem>
#include <QMenu>
#include <QColorDialog>
#include <QKeyEvent>

class VEFViewer: public QGLViewer
{
	Q_OBJECT
		
	public:
		VEFViewer(QWidget* parent);
		void addFile(QString s);
		void setModelList(QListWidget* l);
		
		void updateMinMax(float x, float y, float z);
		void init();
		
	protected:
		virtual void draw();
		virtual QString helpString() const;
		virtual void keyPressEvent(QKeyEvent *e);

		virtual void drawWithNames();
		virtual void postSelection(const QPoint& point);

	private:
		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;

		qglviewer::Vec min, max, center;
		unsigned int vertex_count;

	public slots:
		void listItemDoubleClicked(QListWidgetItem* item);
		void customContextMenuRequested(const QPoint& pos);
};

class QDisplayListLWI: public QObject, public QListWidgetItem
{
	Q_OBJECT

	public:
		QDisplayListLWI(QString name, QColor color):
			QListWidgetItem(name), color_(color), visible_(false)
		{ toggleVisible(); }
		GLuint getDisplayList() const	{ return display_list_; }
		~QDisplayListLWI()				{ destroy(); }

		virtual void draw() const;
		virtual void drawWithNames(int offset) const =0;
		virtual int numElements() const =0;
		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);
			visible->setChecked(isVisible());
			
			QAction* color = m.addAction("Pick color");
			connect(color, SIGNAL(triggered()), this, SLOT(changeColor()));
		}
		
		bool isVisible() const			{ return visible_; }

	public slots:
		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; }

	protected:
		GLuint display_list_;
		bool visible_;
		QColor color_;

	private:
		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 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;
class QFacesLWI: public QDisplayListLWI
{
	Q_OBJECT
		
	public:
		QFacesLWI(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* wireframe_action = m.addAction("Wireframe");
			connect(wireframe_action, SIGNAL(triggered()), this, SLOT(toggleWireframe()));
			wireframe_action->setCheckable(true);
			wireframe_action->setChecked(isWireframe());
		}
		bool isWireframe() const	{ return isWireframe_; }

	public slots:
		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,
                      float& x1, float& y1, float& z1,
                      float& x2, float& y2, float& z2);
		qglviewer::Vec computeNormal(qglviewer::Vec v0, qglviewer::Vec v1, qglviewer::Vec v2) const;
		void drawTriangles(GLenum mode) const;

		typedef 	std::vector<Triangle>		TrianglesContainer;
		TrianglesContainer triangles_;

		bool isWireframe_;
		GLuint wireframe_display_list_;
		int highlighted_;

		QString filename_;
		VEFViewer* viewer_;
};

class QEdgesLWI: public QDisplayListLWI
{
	public:
		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
{
	public:
		Triangle(float nxx, float nyy, float nzz,
				 float xx0, float yy0, float zz0,
				 float xx1, float yy1, float zz1,
				 float xx2, float yy2, float zz2):
			nx(nxx), ny(nyy), nz(nzz),
			x0(xx0), y0(yy0), z0(zz0),
			x1(xx1), y1(yy1), z1(zz1),
			x2(xx2), y2(yy2), z2(zz2)
		{}

		Triangle(const Triangle& other):
			nx(other.nx), ny(other.ny), nz(other.nz),
			x0(other.x0), y0(other.y0), z0(other.z0),
			x1(other.x1), y1(other.y1), z1(other.z1),
			x2(other.x2), y2(other.y2), z2(other.z2)
		{}

		void operator=(const Triangle& other)
		{
			nx = other.nx; ny = other.ny; nz = other.nz;
			x0 = other.x0; y0 = other.y0; z0 = other.z0;
			x1 = other.x1; y1 = other.y1; z1 = other.z1;
			x2 = other.x2; y2 = other.y2; z2 = other.z2;
		}

		float nx, ny, nz;
		float x0, y0, z0;
		float x1, y1, z1;
		float x2, y2, z2;
};


#endif // __VEFVIEWER_H__