from PyQGLViewer import *
from PyQt4 import QtGui, QtCore
import OpenGL.GL as ogl
from os.path import splitext; ext = lambda fn: splitext(fn)[1]
from points import Points, centerMinMax, reduceCMM
from edges import Edges
from triangles import Triangles
from spheres import Spheres
import povray
class VEFViewer(QGLViewer):
def __init__(self, parent = None):
super(VEFViewer, self).__init__(parent)
self.setStateFileName('.PyVEFViewer.xml')
def models(self):
for i in xrange(self.model_list.count()):
yield self.model_list.item(i)
def draw(self):
self.lights()
for mod in self.models():
mod.draw()
def drawWithNames(self):
for i,mod in enumerate(self.models()):
mod.drawWithNames(i)
def lights(self):
# Place light at camera position
cameraPos = self.camera().position()
pos = [cameraPos[0], cameraPos[1], cameraPos[2], 1.0]
ogl.glLightfv(ogl.GL_LIGHT1, ogl.GL_POSITION, pos)
def modelsContextMenu(self, position):
item = self.model_list.itemAt(position)
if item:
item.contextMenu(self.model_list.mapToGlobal(position))
self.updateGL()
def modelDoubleClicked(self, item):
item.toggleVisible()
self.updateGL()
def keyPressEvent(self, e):
if e.key() == QtCore.Qt.Key_O:
filename = QtGui.QFileDialog.getOpenFileName(self, 'Open file')
self.read_from_extension(str(filename))
self.normalize_view()
elif e.key() == QtCore.Qt.Key_P:
if self.camera().type() == Camera.ORTHOGRAPHIC:
self.camera().setType(Camera.PERSPECTIVE)
else:
self.camera().setType(Camera.ORTHOGRAPHIC)
self.updateGL()
elif e.key() == QtCore.Qt.Key_S:
self.save_povray()
else:
super(VEFViewer, self).keyPressEvent(e)
def init(self):
# Light setup
ogl.glDisable(ogl.GL_LIGHT0);
ogl.glEnable(ogl.GL_LIGHT1);
# Light default parameters
light_ambient = [1.0, 1.0, 1.0, 1.0]
light_specular = [1.0, 1.0, 1.0, 1.0]
light_diffuse = [1.0, 1.0, 1.0, 1.0]
ogl.glLightf( ogl.GL_LIGHT1, ogl.GL_SPOT_EXPONENT, 3.0)
ogl.glLightf( ogl.GL_LIGHT1, ogl.GL_SPOT_CUTOFF, 10.0)
ogl.glLightf( ogl.GL_LIGHT1, ogl.GL_CONSTANT_ATTENUATION, 0.1)
ogl.glLightf( ogl.GL_LIGHT1, ogl.GL_LINEAR_ATTENUATION, 0.3)
ogl.glLightf( ogl.GL_LIGHT1, ogl.GL_QUADRATIC_ATTENUATION, 0.3)
ogl.glLightfv(ogl.GL_LIGHT1, ogl.GL_AMBIENT, light_ambient)
ogl.glLightfv(ogl.GL_LIGHT1, ogl.GL_SPECULAR, light_specular)
ogl.glLightfv(ogl.GL_LIGHT1, ogl.GL_DIFFUSE, light_diffuse)
#def helpString(self):
# return helpstr
def save_povray(self):
filename = QtGui.QFileDialog.getSaveFileName(self, 'Save POV-Ray file', '.', 'POV-Ray files (*.pov)')
if not filename: return
pos = self.camera().position()
dir = self.camera().viewDirection()
up = self.camera().upVector()
right = self.camera().rightVector()
at = pos + dir
with open(filename, 'w') as f:
f.write('#include "colors.inc"\n')
f.write('background { rgb 1 }\n')
f.write(povray.camera(pos, at))
f.write(povray.spotlight(pos, at))
for m in self.models():
if m.visible: m.save_povray(f)
def read_points(self, points):
for pts in points:
self.model_list.addItem(Points(pts, self.model_list))
def read_edges(self, edges):
for edg in edges:
self.model_list.addItem(Edges(edg, self.model_list))
def read_triangles(self, triangles):
for tri in triangles:
self.model_list.addItem(Triangles(tri, self.model_list))
def read_spheres(self, spheres):
for sph in spheres:
self.model_list.addItem(Spheres(sph, self.model_list))
def read_from_extension(self, fn):
fn0 = fn.split(':')[0]
if ext(fn0) == '.vrt' or ext(fn0) == '.pts':
self.read_points([fn])
elif ext(fn0) == '.edg':
self.read_edges([fn])
elif ext(fn0) == '.stl':
self.read_triangles([fn])
elif ext(fn0) == '.sph':
self.read_spheres([fn])
else:
return False
return True
def set_list(self, model_list):
self.model_list = model_list
self.model_list.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.model_list.customContextMenuRequested.connect(self.modelsContextMenu)
self.model_list.itemDoubleClicked.connect(self.modelDoubleClicked)
def normalize_view(self):
self.scene_parameters()
self.setSceneBoundingBox(Vec(self.min.x, self.min.y, self.min.z), \
Vec(self.max.x, self.max.y, self.max.z))
self.setSceneCenter(Vec(self.center.x, self.center.y, self.center.z))
def show_entire_scene(self):
self.camera().showEntireScene()
def scene_parameters(self):
self.center, self.min, self.max = reduceCMM((mod.center, mod.min, mod.max) for mod in self.models())