subcomplex in show_complex() + pan/zoom in ComplexViewer2D dev
authorDmitriy Morozov <dmitriy@mrzv.org>
Sun, 10 Jun 2012 11:26:38 -0700
branchdev
changeset 269 86a02dac0db2
parent 268 9b0da55e5df0
child 270 91c35fefb54e
subcomplex in show_complex() + pan/zoom in ComplexViewer2D
bindings/python/dionysus/__init__.py
bindings/python/dionysus/viewer/__init__.py
bindings/python/dionysus/viewer/complex2d.py
bindings/python/dionysus/viewer/complex3d.py
--- a/bindings/python/dionysus/__init__.py	Sat Jun 09 12:56:36 2012 -0700
+++ b/bindings/python/dionysus/__init__.py	Sun Jun 10 11:26:38 2012 -0700
@@ -35,6 +35,9 @@
 def vertex_dim_cmp(s1, s2):
     return cmp(s1.dimension(), s2.dimension()) or vertex_cmp(s1, s2)
 
+def dim_cmp(s1, s2):
+    return cmp(s1.dimension(), s2.dimension())
+
 def fill_alpha_complex(points, simplices):
     if   len(points[0]) == 2:           # 2D
         fill_alpha2D_complex(points, simplices)
@@ -64,4 +67,3 @@
 
 def read_points(filename):
     return [p for p in points_file(filename)]
-
--- a/bindings/python/dionysus/viewer/__init__.py	Sat Jun 09 12:56:36 2012 -0700
+++ b/bindings/python/dionysus/viewer/__init__.py	Sun Jun 10 11:26:38 2012 -0700
@@ -6,11 +6,11 @@
 
 _app = QtGui.QApplication([])
 
-def show_complex(points, complex = None, values = None, **kwargs):
+def show_complex(points, complex = None, values = None, subcomplex = None, **kwargs):
     if len(points[0]) == 2:
-        _show_complex_2D(points, complex, values, app = _app, **kwargs)
+        _show_complex_2D(points, complex, values, subcomplex, app = _app, **kwargs)
     if len(points[0]) == 3:
-        _show_complex_3D(points, complex, values, app = _app, **kwargs)
+        _show_complex_3D(points, complex, values, subcomplex, app = _app, **kwargs)
 
 def show_diagram(dgm, noise = 0):
     return _show_diagram(dgm, noise, _app)
--- a/bindings/python/dionysus/viewer/complex2d.py	Sat Jun 09 12:56:36 2012 -0700
+++ b/bindings/python/dionysus/viewer/complex2d.py	Sun Jun 10 11:26:38 2012 -0700
@@ -1,19 +1,24 @@
 from    PyQt4       import QtGui, QtCore
 from    dionysus    import Simplex
 
-class ComplexViewer(QtGui.QGraphicsView):
-    def __init__(self, points, complex = None, values = None):
+class ComplexViewer2D(QtGui.QGraphicsView):
+    def __init__(self, points, complex = None, values = None, subcomplex = None):
         super(QtGui.QGraphicsView, self).__init__()
+        self._pan = False
 
         self.points = points
         if complex:
-            self.complex = [s for s in complex]
+            complex = [s for s in complex]
         else:
             # Create vertex simplices if no complex provided
-            self.complex = [Simplex([i]) for i in xrange(len(self.points))]
+            complex = [Simplex([i]) for i in xrange(len(self.points))]
+
+        if not subcomplex:
+            subcomplex = []
 
         if not values:
             values = [0]*len(self.points)
+        self.values = values
         self.maxval, self.minval = max(values), min(values)
 
         self.setRenderHint(QtGui.QPainter.Antialiasing)
@@ -28,26 +33,8 @@
         radius = min(maxx - minx, maxy - miny)/100
         self.scene.setSceneRect(minx - 10*radius, miny - 10*radius, (maxx - minx) + 20*radius, (maxy - miny) + 20*radius)
 
-        self.complex.sort(lambda s1, s2: -cmp(s1.dimension(), s2.dimension()))
-        for s in self.complex:
-            vertices = [v for v in s.vertices]
-            if s.dimension() == 0:              # point
-                p = points[vertices[0]]
-                v = values[vertices[0]]
-                item = QtGui.QGraphicsEllipseItem(p[0] - radius/2,p[1] - radius/2,radius,radius)
-                color = self.colormap(v)
-                item.setBrush(QtGui.QBrush(color))
-                item.setPen(QtGui.QPen(color))
-            elif s.dimension() == 1:            # edge
-                p0 = points[vertices[0]]
-                p1 = points[vertices[1]]
-                item = QtGui.QGraphicsLineItem(p0[0], p0[1], p1[0], p1[1])
-            else:                               # higher-d simplex
-                pts = [QtCore.QPointF(points[v][0], points[v][1]) for v in vertices]
-                item = QtGui.QGraphicsPolygonItem(QtGui.QPolygonF(pts))
-                item.setBrush(QtCore.Qt.blue)
-
-            self.scene.addItem(item)
+        self.draw_complex(complex, radius, colormap = self.colormap)
+        self.draw_complex(subcomplex, 3*radius, colormap = lambda v: QtCore.Qt.green, line_color = QtCore.Qt.green)
 
         # Flip y-axis
         self.scale(1,-1)
@@ -56,6 +43,29 @@
         rect = self.scene.itemsBoundingRect()
         self.fitInView(rect, QtCore.Qt.KeepAspectRatio)
 
+    def draw_complex(self, complex, radius, colormap, line_color = QtCore.Qt.black):
+        complex.sort(lambda s1, s2: -cmp(s1.dimension(), s2.dimension()))
+        for s in complex:
+            vertices = [v for v in s.vertices]
+            if s.dimension() == 0:              # point
+                p = self.points[vertices[0]]
+                v = self.values[vertices[0]]
+                item = QtGui.QGraphicsEllipseItem(p[0] - radius/2,p[1] - radius/2,radius,radius)
+                color = colormap(v)
+                item.setBrush(QtGui.QBrush(color))
+                item.setPen(QtGui.QPen(color))
+            elif s.dimension() == 1:            # edge
+                p0 = self.points[vertices[0]]
+                p1 = self.points[vertices[1]]
+                item = QtGui.QGraphicsLineItem(p0[0], p0[1], p1[0], p1[1])
+                item.setPen(QtGui.QPen(line_color))
+            else:                               # higher-d simplex
+                pts = [QtCore.QPointF(self.points[v][0], self.points[v][1]) for v in vertices]
+                item = QtGui.QGraphicsPolygonItem(QtGui.QPolygonF(pts))
+                item.setBrush(QtCore.Qt.blue)
+
+            self.scene.addItem(item)
+
     def colormap(self, v):
         if self.maxval <= self.minval:
             t = 0
@@ -65,10 +75,43 @@
         c.setHsv(int(t*255), 255, 255)
         return c
 
-# TODO: cycle
-def show_complex_2D(points, complex = None, values = None, app = None):
+    def wheelEvent(self, event):
+        delta = 1 + float(event.delta())/100
+        if delta < 0:
+            event.ignore()
+            return
+        self.scale(delta, delta)
+        event.accept()
+
+    def mousePressEvent(self, event):
+        if event.button() == QtCore.Qt.RightButton:
+            self._pan = True
+            self._panStartX = event.x()
+            self._panStartY = event.y()
+            self.setCursor(QtCore.Qt.ClosedHandCursor)
+            event.accept()
+
+    def mouseReleaseEvent(self, event):
+        if event.button() == QtCore.Qt.RightButton:
+            self._pan = False
+            self.setCursor(QtCore.Qt.ArrowCursor)
+            event.accept()
+            return
+        event.ignore()
+
+    def mouseMoveEvent(self, event):
+        if self._pan:
+            self.horizontalScrollBar().setValue(self.horizontalScrollBar().value() - (event.x() - self._panStartX))
+            self.verticalScrollBar().setValue(self.verticalScrollBar().value() - (event.y() - self._panStartY))
+            self._panStartX = event.x()
+            self._panStartY = event.y()
+            event.accept()
+            return
+        event.ignore()
+
+def show_complex_2D(points, complex = None, values = None, subcomplex = None, app = None):
     #app = QtGui.QApplication([])
-    view = ComplexViewer(points, complex, values)
+    view = ComplexViewer2D(points, complex, values, subcomplex)
     view.show()
     view.raise_()
     app.exec_()
--- a/bindings/python/dionysus/viewer/complex3d.py	Sat Jun 09 12:56:36 2012 -0700
+++ b/bindings/python/dionysus/viewer/complex3d.py	Sun Jun 10 11:26:38 2012 -0700
@@ -5,7 +5,7 @@
 from    math        import sqrt
 
 class ComplexViewer3D(PyGLWidget):
-    def __init__(self, points, complex = None, values = None, point_size = 3.):
+    def __init__(self, points, complex = None, values = None, subcomplex = None, point_size = 3.):
         self.display_list = None
         PyGLWidget.__init__(self)
 
@@ -21,6 +21,11 @@
             # Create vertex simplices if no complex provided
             self.complex = [Simplex([i]) for i in xrange(len(self.points))]
 
+        if subcomplex:
+            self.subcomplex = subcomplex
+        else:
+            self.subcomplex = []
+
         self.values = values
         if not values:
             self.values = [0]*len(self.points)
@@ -52,20 +57,23 @@
     def make_display_list(self):
         self.display_list = glGenLists(1)
         glNewList(self.display_list, GL_COMPILE)
+        self.draw_complex(self.complex,    self.point_size,   2., self.colormap)
+        self.draw_complex(self.subcomplex, 2*self.point_size, 4., colormap = lambda v: (0,1.,0), line_color = (0,1.,0))
+        glEndList()
 
-        self.complex.sort(lambda s1, s2: -cmp(s1.dimension(), s2.dimension()))
-        for s in self.complex:
+
+    def draw_complex(self, complex, point_size, line_size, colormap, line_color = (0,0,1.)):
+        glPointSize(point_size)
+        glLineWidth(line_size)
+        complex.sort(lambda s1, s2: -cmp(s1.dimension(), s2.dimension()))
+        for s in complex:
             vertices = [v for v in s.vertices]
             if s.dimension() == 0:              # point
                 p = self.points[vertices[0]]
                 v = self.values[vertices[0]]
 
-                glPointSize(self.point_size)
                 c = self.colormap(v)
-                cr = float(c.red())/255
-                cg = float(c.green())/255
-                cb = float(c.blue())/255
-                glColor3f(cr, cg, cb)
+                glColor3f(*c)
                 glBegin(GL_POINTS)
                 glVertex3f(p[0],p[1],p[2])
                 glEnd()
@@ -73,7 +81,7 @@
                 p0 = self.points[vertices[0]]
                 p1 = self.points[vertices[1]]
 
-                glColor3f(0,0,1)
+                glColor3f(*line_color)
                 glBegin(GL_LINES)
                 glVertex3f(p0[0],p0[1],p0[2])
                 glVertex3f(p1[0],p1[1],p1[2])
@@ -90,8 +98,6 @@
                 glVertex3f(p2[0],p2[1],p2[2])
                 glEnd()
 
-        glEndList()
-
     def colormap(self, v):
         if self.maxval <= self.minval:
             t = 0
@@ -99,12 +105,14 @@
             t = (v - self.minval)/(self.maxval - self.minval)
         c = QtGui.QColor()
         c.setHsv(int(t*255), 255, 255)
-        return c
+        cr = float(c.red())/255
+        cg = float(c.green())/255
+        cb = float(c.blue())/255
+        return (cr,cg,cb)
 
-# TODO: cycle
-def show_complex_3D(points, complex = None, values = None, app = None, point_size = 3.):
+def show_complex_3D(points, complex = None, values = None, subcomplex = None, app = None, point_size = 3.):
     #app = QtGui.QApplication([])
-    view = ComplexViewer3D(points, complex, values, point_size)
+    view = ComplexViewer3D(points, complex, values, subcomplex, point_size)
     view.show()
     view.raise_()
     app.exec_()