Changeset - 941cfe1e1691
[Not reviewed]
default
0 4 0
drewp@bigasterisk.com - 18 years ago 2007-06-11 00:53:16
drewp@bigasterisk.com
lightsim now reads levels from dmxserver
4 files changed with 150 insertions and 87 deletions:
0 comments (0 inline, 0 general)
bin/dmxserver
Show inline comments
 
@@ -78,13 +78,16 @@ class XMLRPCServe(xmlrpc.XMLRPC):
 
        reactor.callLater(1,self.purgeclients)
 

	
 
        now=time.time()
 
        cids=self.clientlevels.keys()
 
        cids = self.lastseen.keys()
 
        for cid in cids:
 
            lastseen=self.lastseen[cid]
 
            if lastseen<now-purge_age:
 
            if lastseen < now - purge_age:
 
                print ("forgetting client %s (no activity for %s sec)" %
 
                       (cid,purge_age))
 
                del self.clientlevels[cid]
 
                try:
 
                    del self.clientlevels[cid]
 
                except KeyError:
 
                    pass
 
                del self.clientfreq[cid]
 
                del self.lastseen[cid]
 
        
 
@@ -167,18 +170,33 @@ class XMLRPCServe(xmlrpc.XMLRPC):
 
        if levellist!=self.clientlevels.get(cid,None):
 
            self.clientlevels[cid]=levellist
 
            self.clientschanged=1
 
            if cid not in self.lastseen:
 
                print "hello new client %s" % cid
 
                self.clientfreq[cid]=Updatefreq()
 
                
 
        self.trackClientFreq(cid)
 
        return "ok"
 

	
 
    def xmlrpc_currentlevels(self, cid):
 
        """get a list of levels we're currently sending out. All
 
        channels beyond the list you get back, they're at zero."""
 
        # if this is still too slow, it might help to return a single
 
        # pickled string
 
        self.trackClientFreq(cid)
 
        trunc = self.combinedlevels[:]
 
        i = len(trunc) - 1
 
        if i < 0:
 
            return []
 
        while trunc[i] == 0 and i >= 0:
 
            i -= 1
 
        if i < 0:
 
            return []
 
        trunc = trunc[:i+1]
 
        return trunc
 
    
 
    def trackClientFreq(self, cid):
 
        if cid not in self.lastseen:
 
            print "hello new client %s" % cid
 
            self.clientfreq[cid]=Updatefreq()
 
        self.lastseen[cid]=time.time()
 
        self.clientfreq[cid].update()
 
        return "ok"
 

	
 
    def xmlrpc_currentlevels(self):
 
        """get a list of levels we're currently sending out. All
 
        channels beyond the list you get back, they're at zero."""
 
        return self.combinedlevels
 
        
 

	
 
parser=OptionParser()
 
parser.add_option("-f","--fast-updates",action='store_true',
bin/lightsim
Show inline comments
 
@@ -12,9 +12,9 @@ log = logging.getLogger()
 
logging.basicConfig(format="%(asctime)s %(levelname)-5s %(name)s %(filename)s:%(lineno)d: %(message)s")
 
log.setLevel(logging.DEBUG)
 
import Tkinter as tk
 
from light9 import networking, Patch, showconfig, dmxclient
 
from light9 import networking, Patch, showconfig, dmxclient, updatefreq
 
from light9.namespaces import L9
 

	
 
from louie import dispatcher
 

	
 
try:
 
    from OpenGL import Tk as Togl
 
@@ -26,57 +26,81 @@ except ImportError:
 
  
 
from lightsim.openglsim import Surface
 

	
 

	
 

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

	
 
def poll(graph, serv):
 
    dmxLevels = serv.currentlevels(dmxclient._id)
 
    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
 

	
 
        try:
 
            chan = Patch.get_channel_uri(Patch.get_channel_name(i + 1))
 
        except KeyError:
 
            continue
 
        ogl.newLevels(levels=level)
 
    d.addCallback(received)
 
    return d
 

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

	
 
    print level
 
    ogl.newLevels(levels=level)
 

	
 
class StatusKeys(tk.Frame):
 
    # 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)
 
        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)
 
        else:
 
            row, lab = self.row[key]
 
            lab.config(text=value)
 

	
 
root = tk.Frame()
 
root.pack(expand=True, fill='both')
 
QuitButton = tk.Button(root, {'text':'Quit'})
 
QuitButton.bind('<ButtonRelease-1>', sys.exit)
 
QuitButton.pack()
 

	
 
filenames=['lightsim/skyline/bg.png',
 
           'lightsim/skyline/cyc-lo-red.png',
 
           'lightsim/skyline/cyc-lo-grn.png',
 
           ]
 
pollFreq = updatefreq.Updatefreq(samples=5)
 
graph = showconfig.getGraph()
 
filenames = []
 
for lyr in graph.objects(None, L9['previewLayer']):
 
    for p in graph.objects(lyr, L9['path']):
 
        filenames.append(str(p))
 

	
 
scales = {} # filename : scale
 
for f in filenames:
 
    scales[f] = tk.Scale(
 
        root, label=f, from_=0, to=1, res=.05, orient='horiz',
 
        command=lambda *args: ogl.newLevels(
 
          levels=dict([(f, s.get()) for f,s in scales.items()])))
 
    scales[f].pack()
 
ogl = Surface(root, filenames)
 
ogl = Surface(root, filenames, width=120, height=80, imgRescaleTo=128)
 
ogl.pack(side='top', expand=True, fill='both')
 

	
 
graph = showconfig.getGraph()
 
serv = Proxy(networking.dmxServerUrl())
 
LoopingCall(poll, graph, serv).start(1)
 
sk = StatusKeys(root)
 
sk.pack(side='top', fill='x')
 

	
 

	
 

	
 
root.winfo_toplevel().bind("<Control-Key-q>",lambda ev: reactor.stop)
 
root.winfo_toplevel().bind("<Destroy>",lambda ev: reactor.stop)
 
root.winfo_toplevel().protocol('WM_DELETE_WINDOW', reactor.stop)
 
serv = Proxy(networking.dmxServerUrl())
 
LoopingCall(poll, graph, serv, pollFreq).start(.1)
 

	
 
top = root.winfo_toplevel()
 
top.wm_title(dmxclient._id)
 
top.bind("<Control-Key-q>",lambda ev: reactor.stop)
 
top.bind("<Destroy>",lambda ev: reactor.stop)
 
top.protocol('WM_DELETE_WINDOW', reactor.stop)
 
tksupport.install(ogl, ms=20)
 
reactor.run()
 

	
 
if 0:
 
    import hotshot, hotshot.stats
 
    p = hotshot.Profile("/tmp/pro")
 
    p.runcall(reactor.run)
 
    p.close()
 
    hotshot.stats.load("/tmp/pro").sort_stats('time').print_stats()
 
else:
 
    reactor.run()
lightsim/openglsim.py
Show inline comments
 
@@ -6,7 +6,7 @@ import sys, time
 
import numarray as num
 
import Tkinter as tk
 
import Image
 

	
 
from louie import dispatcher
 
try:
 
    from OpenGL import Tk as Togl
 
    from OpenGL.GL import *
 
@@ -27,20 +27,24 @@ def xxxdrawWithAlpha(imgString, w, h, al
 
    glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, imgString)
 

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

	
 
        self.levels = {} # filename : brightness
 
  
 
        self.image = {} # filename : imgstr
 
        for filename in filenames:
 
            im = Image.open(filename)
 
            if self.imgRescaleTo:
 
                im.thumbnail((self.imgRescaleTo, self.imgRescaleTo))
 
            if imgRescaleTo:
 
                im.thumbnail((imgRescaleTo, imgRescaleTo))
 
            im = im.transpose(Image.FLIP_TOP_BOTTOM)
 
            self.imageWidth = im.size[0]
 
            self.imageHeight = im.size[1]
 
@@ -57,9 +61,35 @@ class Surface(Togl.Opengl):
 
        self.bind("<Configure>", self.configure)
 

	
 
    def configure(self, ev):
 
#        import pdb; pdb.set_trace()
 
        self.width, self.height = ev.width, ev.height
 
  
 
    def redraw(self, event=None):
 
        """you set self.levels to dict and call tkRedraw"""
 
        assert 'GL_ARB_imaging' in glGetString(GL_EXTENSIONS).split()
 
        start = time.time()
 
        
 
        glClearColor(0.0, 0.0, 0.0, 0)
 
        glClear( GL_COLOR_BUFFER_BIT |GL_ACCUM_BUFFER_BIT)
 
        glEnable(GL_BLEND)
 
        glBlendFunc(GL_SRC_ALPHA, GL_ONE) # add
 
        
 
#        l=glGenLists(1)
 
#        glNewList(l,GL_COMPILE)
 
#        glEndList()
 

	
 
        # drawing to glAccum might be good
 
        layerTimes = []
 
        for filename, mag in self.levels.items():
 
            #print "pic %s at %f" % (filename, mag)
 
            t = time.time()
 
            self.drawWithAlpha(self.image[filename],
 
                               self.imageWidth, self.imageHeight, mag)
 
            layerTimes.append(time.time() - t)
 

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

	
 
    def drawWithAlpha(self, imgString, w, h, alpha):
 
        """without opengl extensions"""
 
        if alpha == 0:
 
@@ -72,32 +102,23 @@ class Surface(Togl.Opengl):
 
            ar[:,3] *= alpha
 

	
 
        #print "  scl", time.time() - t
 

	
 
        # this might be a good way to scale the color channels too,
 
        # but the blend might take two steps. Anyway,
 
        # GL_CONSTANT_COLOR seems not to work, so i'm not exploring
 
        # this right now.
 
        #glBlendFunc(GL_CONSTANT_COLOR, GL_ONE)
 
        #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
 

	
 
    def redraw(self, event=None):
 
        """you set self.levels to dict and call tkRedraw"""
 
        assert 'GL_ARB_imaging' in glGetString(GL_EXTENSIONS).split()
 
    
 
        glClearColor(0.0, 0.0, 0.0, 0)
 
        glClear( GL_COLOR_BUFFER_BIT |GL_ACCUM_BUFFER_BIT)
 
        glEnable(GL_BLEND)
 
        glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA)
 
#        l=glGenLists(1)
 
#        glNewList(l,GL_COMPILE)
 
#        glEndList()
 

	
 
        # drawing to glAccum might be good
 
        for filename, mag in self.levels.items():
 
            #print "pic %s at %f" % (filename, mag)
 
            self.drawWithAlpha(self.image[filename],
 
                               self.imageWidth, self.imageHeight, mag)
 

	
 
    def newLevels(self, event=None, levels=None):
 
        self.levels = levels
 
        self.tkRedraw()
 
        if levels != self.levels:
 
            self.levels = levels
 
            self.tkRedraw()
 
  
 
def main():
 
    root = tk.Frame()
lightsim/skyline/layers.xcf
Show inline comments
 
binary diff not shown
0 comments (0 inline, 0 general)