--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile Sat Mar 05 14:59:46 2011 -0800
@@ -0,0 +1,2 @@
+ui_PyVEFViewer.py: viewerInterface.ui
+ pyuic4 $< > $@
--- a/PyVEFViewer.py Thu Mar 03 12:58:47 2011 -0800
+++ b/PyVEFViewer.py Sat Mar 05 14:59:46 2011 -0800
@@ -1,26 +1,26 @@
-#!/usr/bin/env python2
-
-from PyQt4.QtGui import *
from PyQGLViewer import *
+from PyQt4 import QtGui, QtCore
import OpenGL.GL as ogl
from points import Points, centerMinMax, reduceCMM
-from opster import command, dispatch
class VEFViewer(QGLViewer):
- def __init__(self):
- QGLViewer.__init__(self)
+ def __init__(self, parent = None):
+ super(VEFViewer, self).__init__(parent)
self.setStateFileName('.PyVEFViewer.xml')
- self.models = []
+
+ 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:
+ for mod in self.models():
mod.draw()
def drawWithNames(self):
- for i,mod in enumerate(self.models):
+ for i,mod in enumerate(self.models()):
mod.drawWithNames(i)
def lights(self):
@@ -34,12 +34,20 @@
light_spot_dir1 = (camera_dir.x, camera_dir.y, camera_dir.z);
ogl.glLightfv(ogl.GL_LIGHT1, ogl.GL_POSITION, light_pos1);
+ def modelsContextMenu(self, position):
+ item = self.model_list.itemAt(position)
+ if item:
+ item.contextMenu(self.model_list.mapToGlobal(position))
+
+ def modelDoubleClicked(self, item):
+ item.toggleVisible()
+ self.updateGL()
def init(self):
# ogl.glMaterialf(ogl.GL_FRONT_AND_BACK, ogl.GL_SHININESS, 50.0)
# specular_color = [ 0.8, 0.8, 0.8, 1.0 ]
# ogl.glMaterialfv(ogl.GL_FRONT_AND_BACK, ogl.GL_SPECULAR, specular_color)
- self.restoreStateFromFile()
+ # self.restoreStateFromFile()
# self.help()
ogl.glShadeModel(ogl.GL_SMOOTH);
@@ -57,31 +65,24 @@
def read_points(self, points):
for pts in points:
- self.models.append(Points(pts))
+ self.model_list.addItem(Points(pts, self.model_list))
+ def read_edges(self, edges):
+ pass
+ def read_triangles(self, triangles):
+ pass
+
+ 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.centerScene()
+ 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))
-
- def centerScene(self):
- self.center, self.min, self.max = reduceCMM((mod.center, mod.min, mod.max) for mod in self.models)
+ self.setSceneCenter(Vec(self.center.x, self.center.y, self.center.z))
-@command(usage = '%name [options]')
-def main(points = ('p', [], 'files with points'), # TODO: add completer for filenames
- edges = ('e', [], 'files with edges'),
- triangles = ('t', [], 'files with triangles')):
- qapp = QApplication([])
- viewer = VEFViewer()
- viewer.setWindowTitle("PyVEFViewer")
- viewer.show()
-
- viewer.read_points(points)
- #viewer.read_edges(edges)
- #viewer.read_triangles(triangles)
- viewer.normalize_view()
-
- qapp.exec_()
-
-if __name__ == '__main__':
- main()
+ def scene_parameters(self):
+ self.center, self.min, self.max = reduceCMM((mod.center, mod.min, mod.max) for mod in self.models())
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/VEFViewer.py Sat Mar 05 14:59:46 2011 -0800
@@ -0,0 +1,31 @@
+#!/usr/bin/env python2
+
+import ui_PyVEFViewer as ui
+from opster import command, dispatch
+
+class VEFViewerWindow(ui.QtGui.QDialog):
+ def __init__(self, parent = None):
+ super(VEFViewerWindow, self).__init__(parent)
+
+ self.ui = ui.Ui_Dialog()
+ self.ui.setupUi(self)
+
+@command(usage = '%name [options]')
+def main(points = ('p', [], 'files with points'), # TODO: add completer for filenames
+ edges = ('e', [], 'files with edges'),
+ triangles = ('t', [], 'files with triangles')):
+
+ qapp = ui.QtGui.QApplication([])
+ win = VEFViewerWindow()
+ win.show()
+
+ win.ui.viewer.set_list(win.ui.modelList)
+ win.ui.viewer.read_points(points)
+ win.ui.viewer.read_edges(edges)
+ win.ui.viewer.read_triangles(triangles)
+ win.ui.viewer.normalize_view()
+
+ qapp.exec_()
+
+if __name__ == '__main__':
+ main()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ViewerItem.py Sat Mar 05 14:59:46 2011 -0800
@@ -0,0 +1,18 @@
+from PyQt4 import QtGui, QtCore
+
+class ViewerItem(QtGui.QListWidgetItem):
+ def __init__(self, name, parent = None):
+ super(ViewerItem, self).__init__(name, parent, QtGui.QListWidgetItem.UserType)
+
+ def toggleVisible(self):
+ self.visible = not self.visible
+ self.setChecked()
+
+ def setChecked(self):
+ if self.visible:
+ self.setCheckState(QtCore.Qt.Checked)
+ else:
+ self.setCheckState(QtCore.Qt.Unchecked)
+
+ def contextMenu(self, position):
+ pass
--- a/points.py Thu Mar 03 12:58:47 2011 -0800
+++ b/points.py Sat Mar 05 14:59:46 2011 -0800
@@ -1,7 +1,8 @@
from OpenGL.GL import glGenLists, glNewList, GL_COMPILE, glEndList, glCallList, \
glBegin, glEnd, GL_POINTS, glVertex3f, glColor3f, \
glEnable, glDisable, GL_LIGHTING
-
+from PyQt4 import QtGui, QtCore
+from ViewerItem import ViewerItem
class Point(object):
__slots__ = ('x','y','z')
@@ -33,15 +34,19 @@
return Point((max(self.x, p.x), max(self.y, p.y), max(self.z, p.z)))
-class Points(object):
- def __init__(self, filename):
+class Points(ViewerItem):
+ def __init__(self, filename, parent = None):
+ super(Points, self).__init__(filename, parent)
+
self.points = []
with open(filename) as f:
for line in f:
if line.startswith('#'): continue
self.points.append(Point(map(float, line.split())))
self.create_display_list()
- self.color = (255, 0, 255)
+ self.color = QtGui.QColor(255, 0, 255)
+ self.visible = True
+ self.setChecked()
self.center, self.min, self.max = centerMinMax(self.points)
def create_display_list(self):
@@ -53,8 +58,18 @@
glEnd()
glEndList()
+ def contextMenu(self, position):
+ menu = QtGui.QMenu()
+ colorAction = menu.addAction("Color")
+ action = menu.exec_(position)
+ if action == colorAction:
+ color = QtGui.QColorDialog.getColor(self.color)
+ if color.isValid():
+ self.color = color
+
def draw(self):
- r,g,b = self.color
+ if not self.visible: return
+ r,g,b,a = self.color.getRgb()
glColor3f(r,g,b)
glDisable(GL_LIGHTING)
glCallList(self.display_list)
@@ -71,7 +86,7 @@
center += p
min = p.min(min)
max = p.max(max)
- center /= count
+ if count: center /= count
return center, min, max
@@ -83,6 +98,6 @@
center += c
min_ = min.min(min_)
max_ = max.max(max_)
- center /= count
+ if count: center /= count
- return center, min, max
+ return center, min_, max_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/viewerInterface.ui Sat Mar 05 14:59:46 2011 -0800
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>945</width>
+ <height>667</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>PyVEFViewer</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>9</number>
+ </property>
+ <item>
+ <widget class="QSplitter" name="splitter">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <widget class="QListWidget" name="modelList">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::CustomContextMenu</enum>
+ </property>
+ </widget>
+ <widget class="VEFViewer" name="viewer" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>VEFViewer</class>
+ <extends>QWidget</extends>
+ <header>PyVEFViewer</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>