Changeset - f69ba5ac17c5
[Not reviewed]
default
0 2 0
drewp@bigasterisk.com - 16 years ago 2008-09-01 05:36:24
drewp@bigasterisk.com
qt version of lightsim now works
2 files changed with 75 insertions and 68 deletions:
0 comments (0 inline, 0 general)
bin/lightsim
Show inline comments
 
#!/usr/bin/python
 

	
 
from __future__ import division
 
import run_local
 
import xmlrpclib, sys, logging
 
import sys, logging
 

	
 
sys.path.append("lib")
 
import qt4reactor
 
qt4reactor.install()
 

	
 
from rdflib import Literal, URIRef
 
from twisted.internet import reactor
 
from twisted.internet.task import LoopingCall
 
from twisted.web.xmlrpc import Proxy
 
from louie import dispatcher
 
from PyQt4 import QtCore, QtGui, QtOpenGL
 
from PyQt4.QtGui import QWidget, QLabel, QVBoxLayout, QHBoxLayout, QMainWindow
 
from OpenGL.GL import *
 
from OpenGL.GLU import *
 

	
 
from light9 import networking, Patch, showconfig, dmxclient, updatefreq, prof
 
from light9.namespaces import L9
 
from lightsim.openglsim import Surface
 

	
 
log = logging.getLogger()
 
logging.basicConfig(format="%(asctime)s %(levelname)-5s %(name)s %(filename)s:%(lineno)d: %(message)s")
 
log.setLevel(logging.DEBUG)
 

	
 
def filenamesForChan(graph, chan):
 
    for lyr in graph.objects(chan, L9['previewLayer']):
 
        for imgPath in graph.objects(lyr, L9['path']):
 
            yield imgPath
 

	
 
_lastLevels = None
 
def poll(graph, serv, pollFreq, oglSurface):
 
    pollFreq.update()
 
    dispatcher.send("status", key="pollFreq", value=str(pollFreq))
 
    d = serv.callRemote("currentlevels", dmxclient._id)
 
    def received(dmxLevels):
 
        global _lastLevels
 
        if dmxLevels == _lastLevels:
 
            return
 
        _lastLevels = dmxLevels
 
        level = {} # filename : level
 
        for i, lev in enumerate(dmxLevels):
 
            if lev == 0:
 
                continue
 

	
 
            try:
 
                chan = Patch.get_channel_uri(Patch.get_channel_name(i + 1))
 
            except KeyError:
 
                continue
 

	
 
            for lyr in graph.objects(chan, L9['previewLayer']):
 
                for imgPath in graph.objects(lyr, L9['path']):
 
                    level[str(imgPath)] = lev
 
            for imgPath in filenamesForChan(graph, chan):
 
                level[str(imgPath)] = lev
 

	
 
        oglSurface.newLevels(levels=level)
 
    d.addCallback(received)
 
    return d
 

	
 
class StatusKeys(object):
 
    # watch out- this might be an accidental redo of what curvecalc
 
    # has. Or, maybe CC should use this obj
 
    def __init__(self, master):
 
        tk.Frame.__init__(self, master)
 
class StatusKeys(QWidget):
 
    """listens for dispatcher signal 'status' and displays the key/value args"""
 
    def __init__(self, parent):
 
        QWidget.__init__(self)
 
        self.layout = QVBoxLayout()
 
        self.setLayout(self.layout)
 
        self.row = {} # key name : (Frame, value Label)
 
        dispatcher.connect(self.status, "status")
 
        self.row = {} # key name : (Frame, value Label)
 
        
 
    def status(self, key, value):
 
        if key not in self.row:
 
            f = tk.Frame(self)
 
            f.pack(side='top')
 
            tk.Label(f, text=key, font="arial 8").pack(side='left')
 
            l = tk.Label(f, text=value, font="arial 8")
 
            l.pack(side='left')
 
            self.row[key] = (f, l)
 
            row = QWidget()
 
            self.layout.addWidget(row)
 
            cols = QHBoxLayout()
 
            row.setLayout(cols)
 
            lab1 = QLabel(key)
 
            lab2 = QLabel(value)
 
            cols.addWidget(lab1)
 
            cols.addWidget(lab2)
 
            self.row[key] = lab2
 
        else:
 
            row, lab = self.row[key]
 
            lab.config(text=value)
 

	
 
            lab = self.row[key]
 
            lab.setText(value)
 

	
 

	
 
class Window(QtGui.QMainWindow):
 
class Window(QMainWindow):
 
    def __init__(self, filenames):
 
        QtGui.QMainWindow.__init__(self, None)
 
        QMainWindow.__init__(self, None)
 
        self.setWindowTitle(dmxclient._id)
 

	
 
        self.w = QtGui.QWidget()
 
        self.setCentralWidget(self.w)
 
        w = QWidget()
 
        self.setCentralWidget(w)
 
        mainLayout = QVBoxLayout()
 
        w.setLayout(mainLayout)
 
        
 
        self.glWidget = Surface(self, filenames,
 
                                width=120*3, height=80*3,
 
                                imgRescaleTo=128)
 
        self.glWidget = Surface(self, filenames, imgRescaleTo=128*2)
 

	
 
        mainLayout.addWidget(self.glWidget)
 

	
 
        status = StatusKeys(mainLayout)
 
        mainLayout.addWidget(status)      
 

	
 
        self.glWidget.newLevels(levels={
 
            "lightsim/skyline/front-left.png" : .4,
 
            "lightsim/skyline/front-right.png" : .8})
 

	
 
        mainLayout = QtGui.QHBoxLayout()
 
        mainLayout.addWidget(self.glWidget)
 
        self.w.setLayout(mainLayout)
 

	
 
        self.setWindowTitle(dmxclient._id)
 
def requiredImages(graph):
 
    """filenames that we'll need to show, based on a config structure
 
    like this:
 
      ch:frontLeft a :Channel;
 
         :previewLayer [ :path "lightsim/skyline/front-left.png" ] .
 
    """
 
    filenames = []
 
    for lyr in graph.objects(None, L9['previewLayer']):
 
        for p in graph.objects(lyr, L9['path']):
 
            filenames.append(str(p))
 
    return filenames
 

	
 
if __name__ == '__main__':
 
    app = reactor.qApp
 

	
 
    graph = showconfig.getGraph()
 
    filenames = []
 
    for lyr in graph.objects(None, L9['previewLayer']):
 
        for p in graph.objects(lyr, L9['path']):
 
            filenames.append(str(p))
 
    filenames.append("lightsim/skyline/front-left.png") # test
 
    filenames.append("lightsim/skyline/front-right.png") # test
 

	
 
    window = Window(filenames)
 
    window = Window(requiredImages(graph))
 
    window.show()
 

	
 
    serv = Proxy(networking.dmxServerUrl())
 
    pollFreq = updatefreq.Updatefreq(samples=5)
 
    LoopingCall(poll, graph, serv, pollFreq, window.glWidget).start(.1)
 
    pollFreq = updatefreq.Updatefreq()
 
    LoopingCall(poll, graph, serv, pollFreq, window.glWidget).start(.05)
 

	
 
    reactor.run()
 

	
 

	
 
######################################################
 
#sk = StatusKeys(root)
 
#sk.pack(side='top', fill='x')
 
#prof.run(reactor.run, profile=False)
lightsim/openglsim.py
Show inline comments
 
@@ -5,62 +5,58 @@ from __future__ import division
 
import sys, time
 
import numarray as num
 
import Tkinter as tk
 
import Image
 
from louie import dispatcher
 

	
 
from PyQt4 import QtCore, QtOpenGL
 
from PyQt4.QtCore import QSize
 
from PyQt4.QtOpenGL import QGLWidget
 
from OpenGL.GL import *
 

	
 
def xxxdrawWithAlpha(imgString, w, h, alpha):
 
    # this one should be faster because GL does the alpha adjust, but
 
    # i don't think it works yet
 
    
 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
 
    
 
    glClear(GL_COLOR_BUFFER_BIT)
 
    #glBlendColor(1, 1, 1, mag) # needs ARB_imaging
 
    glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, imgString)
 

	
 
class Surface(QtOpenGL.QGLWidget):
 
class Surface(QGLWidget):
 
    """widget that adds multiple image files together with adjustable scales"""
 
    def __init__(self, parent, filenames, width=512, height=270,
 
                 imgRescaleTo=None):
 
    def __init__(self, parent, filenames, imgRescaleTo=None):
 
        """
 
        imgRescaleTo can be a length of pixels to reduce all the input
 
        images into. Try 64 for a low res drawing.
 
        """
 
        QtOpenGL.QGLWidget.__init__(self, parent)
 
        QGLWidget.__init__(self, parent)
 

	
 
        self.levels = {} # filename : brightness
 
  
 
        self.image = {} # filename : imgstr
 
        for filename in filenames:
 
            print "open", filename
 
            im = Image.open(filename)
 
            self.origImageSize = im.size[0], im.size[1]
 
            if imgRescaleTo:
 
                im.thumbnail((imgRescaleTo, imgRescaleTo))
 
            im = im.transpose(Image.FLIP_TOP_BOTTOM)
 
            self.imageWidth = im.size[0]
 
            self.imageHeight = im.size[1]
 
            self.image[filename] = im.convert("RGBA").tostring()
 
  
 
        #self.set_centerpoint(0, 0, 0)
 

	
 
    def initializeGL(self): 
 
        glDisable(GL_CULL_FACE)
 
        glShadeModel(GL_FLAT)
 
        print 'GL_ARB_imaging', 'GL_ARB_imaging' in glGetString(GL_EXTENSIONS)
 
        import OpenGL
 
        print OpenGL.__version__
 
       
 
#    def minimumSizeHint(self):
 
#        return QtCore.QSize(512, 512)
 

	
 
#    def sizeHint(self):
 
#        return QtCore.QSize(512, 512)
 
    def sizeHint(self):
 
        return QSize(*self.origImageSize)
 

	
 
    def paintGL(self):
 
        """you set self.levels to dict and call tkRedraw"""
 
        assert 'GL_ARB_imaging' in glGetString(GL_EXTENSIONS).split()
 
        start = time.time()
 
        
 
@@ -72,26 +68,29 @@ class Surface(QtOpenGL.QGLWidget):
 
#        l=glGenLists(1)
 
#        glNewList(l,GL_COMPILE)
 
#        glEndList()
 

	
 
        # drawing to glAccum might be good
 
        layerTimes = []
 
        layers = 0
 
        for filename, mag in self.levels.items():
 
            t = time.time()
 
            self.drawWithAlpha(self.image[filename],
 
                               self.imageWidth, self.imageHeight, mag)
 
            layers += self.drawWithAlpha(self.image[filename],
 
                                         self.imageWidth, self.imageHeight, mag)
 
            layerTimes.append(time.time() - t)
 

	
 
        dispatcher.send("status", key="visibleLayers", value=str(layers))
 

	
 
        dispatcher.send("status", key="redraw",
 
                        value="%.1fms" % ((time.time() - start) * 1000))
 
        
 

	
 
    def drawWithAlpha(self, imgString, w, h, alpha):
 
        """without opengl extensions"""
 
        """without opengl extensions. Returns number of layers drawn"""
 
        if alpha == 0:
 
            return
 
            return 0
 
        t = time.time()
 
        ar = num.reshape(num.fromstring(imgString, dtype='uint8'),
 
                         (w * h, 4))
 
        #print "  tonum", time.time() - t
 
        if alpha != 1:
 
            ar[:,3] *= alpha
 
@@ -106,12 +105,13 @@ class Surface(QtOpenGL.QGLWidget):
 
        #glBlendColor(.8, .5, .5, .5)
 

	
 
        glPixelZoom(self.width() / w, self.height() / h)
 
        glDrawPixels(w, h,
 
                     GL_RGBA, GL_UNSIGNED_BYTE, ar.tostring())
 
        #print "  draw", time.time() - t
 
        return 1
 

	
 
    def newLevels(self, event=None, levels=None):
 
        if levels != self.levels:
 
            self.levels = levels
 
            self.updateGL()
 

	
0 comments (0 inline, 0 general)