Triangles stored explicitly, selection, normals computed explicitly, lights under control
authorDmitriy Morozov <morozov@cs.duke.edu>
Mon, 12 Jun 2006 14:43:47 -0400
changeset 2 f3516f064329
parent 1 9ac2dc8d1e24
child 3 981001e95e19
Triangles stored explicitly, selection, normals computed explicitly, lights under control
VEFViewer.cpp
VEFViewer.h
--- a/VEFViewer.cpp	Mon Jun 12 10:46:00 2006 -0400
+++ b/VEFViewer.cpp	Mon Jun 12 14:43:47 2006 -0400
@@ -10,8 +10,27 @@
 void VEFViewer::init()
 {
 	setBackgroundColor(QColor(0xAA, 0xAA, 0xAA));
+
+	// Lights
 	glEnable(GL_LIGHTING);
-	glEnable(GL_LIGHT0);
+	glDisable(GL_LIGHT0);
+	glEnable(GL_LIGHT1);
+
+	GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
+	GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
+	GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+
+	glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
+	glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
+	glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
+	//glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 120.0);
+	//glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 3.0);
+
+	// Basic settings
+	glShadeModel(GL_FLAT);
+	glEnable(GL_NORMALIZE);
+	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+	glPointSize(2.0);
 }
 
 void VEFViewer::addFile(QString s)
@@ -43,16 +62,56 @@
 // Draws a spiral
 void VEFViewer::draw()
 {
+	// GL_LIGHT0
 	const GLfloat light_pos0[4] = {center.x, center.y, center.z, 1.0};
 	glLightfv(GL_LIGHT0, GL_POSITION, light_pos0);
-		
+
+	// GL_LIGHT1
+	qglviewer::Vec camera_pos = camera()->position();
+	qglviewer::Vec camera_dir = camera()->viewDirection();
+	const GLfloat light_pos1[4] = {camera_pos.x, camera_pos.y, camera_pos.z, 1.0};
+	const GLfloat light_spot_dir1[3] = {camera_dir.x, camera_dir.y, camera_dir.z};
+	glLightfv(GL_LIGHT1, GL_POSITION, light_pos1);
+	//glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, light_spot_dir1);
+	
 	for (int i = 0; i < modelList->count(); i++)
 	{
 		QDisplayListLWI* dl = static_cast<QDisplayListLWI*>(modelList->item(i));
-		dl->display();
+		dl->draw();
+	}
+
+	//drawLight(GL_LIGHT0);
+	//drawLight(GL_LIGHT1);
+}
+
+void VEFViewer::drawWithNames()
+{
+	int offset = 0;
+	for (int i = 0; i < modelList->count(); i++)
+	{
+		QDisplayListLWI* dl = static_cast<QDisplayListLWI*>(modelList->item(i));
+		dl->drawWithNames(offset);
+		offset += dl->numElements();
 	}
 }
 
+void VEFViewer::postSelection(const QPoint& point)
+{
+	int i;
+	int selected = selectedName();
+	QDisplayListLWI* dl;
+
+	for (i = 0; i < modelList->count(); i++)
+	{
+		dl = static_cast<QDisplayListLWI*>(modelList->item(i));
+		if (selected < dl->numElements())
+			break;
+		selected -= dl->numElements();
+	}
+	
+	dl->highlight(selected);
+}
+
 QString VEFViewer::helpString() const
 {
   QString text("<h2>VEFViewer</h2>");
@@ -142,11 +201,17 @@
 
 
 // QVertices
-void QVerticesLWI::display() const
+void QVerticesLWI::draw() const
 {
 	glColor3f(.5, .65, .65);
 	glCallList(display_list);
 }
+void QVerticesLWI::drawWithNames(int offset) const
+{}
+int QVerticesLWI::numElements() const
+{ return 0; }
+void QVerticesLWI::highlight(int selected)
+{}
 
 QVerticesLWI::QVerticesLWI(QString name, FILE* file, VEFViewer* v): 
 	QDisplayListLWI(name)
@@ -170,52 +235,98 @@
 
 
 // QFaces
-void QFacesLWI::display() const
+void QFacesLWI::draw() const
 {
+	// Draw selected
+	if (highlighted >= 0)
+	{
+	   	glColor3f(.9, .4, 0);
+		glBegin(GL_TRIANGLES);
+			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);
+			glVertex3f(t.x2, t.y2, t.z2);
+		glEnd();
+	}
+	
+	// Draw the object
 	glColor3f(0., .4, .6);
 	glCallList(display_list);
 }
 
+void QFacesLWI::drawWithNames(int offset) const
+{
+	for (int i = 0; i < triangles.size(); i++)
+	{
+		const Triangle& t = triangles[i];
+		glPushName(offset + i);
+		glBegin(GL_TRIANGLES);
+		glVertex3f(t.x0, t.y0, t.z0);
+		glVertex3f(t.x1, t.y1, t.z1);
+		glVertex3f(t.x2, t.y2, t.z2);
+		glEnd();
+		glPopName();
+	}
+}
+
+int QFacesLWI::numElements() const
+{ return triangles.size(); }
+
+void QFacesLWI::highlight(int selected)
+{
+	highlighted = selected;
+}
+
 QFacesLWI::QFacesLWI(QString name, FILE* file, VEFViewer* v):
-	QDisplayListLWI(name)
+	QDisplayListLWI(name), highlighted(-1)
 {
+	float nx,ny,nz;			// not used
+	float x0,y0,z0;
+	float x1,y1,z1;
+	float x2,y2,z2;
+	
+	// Read in the vector of Triangles
+	int result = readFacet(file, nx,ny,nz, x0,y0,z0, x1,y1,z1, x2,y2,z2);
+	while(result != EOF)
+	{
+		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));
+
+		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);
+	}
+	
+	std::cout << "Triangles read: " << triangles.size() << std::endl;
+	
+	// Create display list
 	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);
-		}
+	for (TrianglesContainer::const_iterator cur = triangles.begin(); cur != triangles.end(); ++cur)
+	{
+		glNormal3f(cur->nx,cur->ny,cur->nz);
+		glVertex3f(cur->x0,cur->y0,cur->z0);
+		glVertex3f(cur->x1,cur->y1,cur->z1);
+		glVertex3f(cur->x2,cur->y2,cur->z2);
+	}
 
 	glEnd();
 	glEndList();
 }
 
+qglviewer::Vec QFacesLWI::computeNormal(qglviewer::Vec v0, qglviewer::Vec v1, qglviewer::Vec v2) const
+{
+	qglviewer::Vec n = cross((v1 - v0), (v2 - v0));
+	return n;
+}
+
 int QFacesLWI::readFacet(FILE* file,
 						  float& nx, float& ny, float& nz, 
 						  float& x0, float& y0, float& z0,
@@ -223,23 +334,30 @@
 						  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");
+	int result;
+	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
+void QEdgesLWI::draw() const
 {
 	glColor3f(.6, .2, .6);
 	glCallList(display_list);
 }
+void QEdgesLWI::drawWithNames(int offset) const
+{}
+int QEdgesLWI::numElements() const
+{ return 0; }
+void QEdgesLWI::highlight(int selected)
+{}
 
 QEdgesLWI::QEdgesLWI(QString name, FILE* file, VEFViewer* v):
 	QDisplayListLWI(name)
@@ -275,8 +393,6 @@
 	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;
 }
 
--- a/VEFViewer.h	Mon Jun 12 10:46:00 2006 -0400
+++ b/VEFViewer.h	Mon Jun 12 14:43:47 2006 -0400
@@ -20,6 +20,9 @@
 		virtual QString helpString() const;
 		virtual void keyPressEvent(QKeyEvent *e);
 
+		virtual void drawWithNames();
+		virtual void postSelection(const QPoint& point);
+
 	private:
 		void readVertexFile(QString s);
 		void readEdgeFile(QString s);
@@ -41,7 +44,10 @@
 		GLuint getDisplayList() const	{ return display_list; }
 		~QDisplayListLWI()				{ glDeleteLists(display_list, 1); }
 
-		virtual void display() const =0;
+		virtual void draw() const =0;
+		virtual void drawWithNames(int offset) const =0;
+		virtual int numElements() const =0;
+		virtual void highlight(int selected) =0;
 
 	protected:
 		GLuint display_list;
@@ -52,14 +58,21 @@
 {
 	public:
 		QVerticesLWI(QString name, FILE* file, VEFViewer* v);
-		virtual void display() const;
+		virtual void draw() const;
+		virtual void drawWithNames(int offset) const;
+		virtual int numElements() const;
+		virtual void highlight(int selected);
 };
 
+class Triangle;
 class QFacesLWI: public QDisplayListLWI
 {
 	public:
 		QFacesLWI(QString name, FILE* file, VEFViewer* v);
-		virtual void display() const;
+		virtual void draw() const;
+		virtual void drawWithNames(int offset) const;
+		virtual int numElements() const;
+		virtual void highlight(int selected);
 
 	private:
 		int readFacet(FILE* file,
@@ -67,13 +80,22 @@
                       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;
+
+		typedef 	std::vector<Triangle>		TrianglesContainer;
+		TrianglesContainer triangles;
+
+		int highlighted;
 };
 
 class QEdgesLWI: public QDisplayListLWI
 {
 	public:
 		QEdgesLWI(QString name, FILE* file, VEFViewer* v);
-		virtual void display() const;
+		virtual void draw() const;
+		virtual void drawWithNames(int offset) const;
+		virtual int numElements() const;
+		virtual void highlight(int selected);
 
 	private:
 		int readEdge (FILE* file,
@@ -81,5 +103,39 @@
                       float& x1, float& y1, float& z1);
 };
 
+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__