You are here: Home / Community / Workshops / 2008 - Fribourg / Content / Shakespeare / Effect / bin / interp / interp.py

interp.py

# last updated 29-Jul-2009 -- dmreagan

from Tkinter import *
from gui import BaseGui
from ies import IES
import glob ,copy
#import re, regex
import re
from Dialog import Dialog
from os import getcwd
import filedlg
import string
from interpDlg import *

class Interp( BaseGui ):

#----------------------------------------------------------------------
    def __init__(self, parent=None, dir = None):
        BaseGui.__init__(self, parent)
        self.master.title( "Instrument interpolator")
        self.family = StringVar()
        self.family.set("sf50")
        self.familyPath = StringVar()
        self.curdir = getcwd()
        if dir == None:
            self.familyPath.set(self.curdir)
        else:
            self.familyPath.set(dir)
        self.fname = StringVar()
        self.fFiles = []
        self.lights = {}
        self.pattern = { 'fbi': 0, 'fhd':1, 'fbo':2,
                         'cbi': 3, 'chd':4, 'cbo':5,
                         'pbi': 6, 'phd':7, 'pbo':8 }
        self.canvas.bind('<Button-1>', self.MakePlot)
        self.canvasCleared = 1 # true!
        self.cross = 0
        self.candela = 0
        self.vAngle = 0



#----------------------------------------------------------------------
    def New(self):
        # function for new button
        retry = 1;
        NewDialog(self.familyPath, self.family)
        while retry :
            retry = self.LoadFamily()

#----------------------------------------------------------------------
    def Open(self):
        fileDlg = filedlg.LoadFileDialog(self, "Load File",
                                         "*[0-9]*[0-9][0-9][0-9].ies")
        fileDlg.cwd = self.familyPath.get()
        if fileDlg.Show() != 1:
            fileDlg.DialogCleanup()
            return
        fname = fileDlg.GetFileName()
        path = self.familyPath.get()
        fileDlg.DialogCleanup()

        l = re.match(path+'/', fname)

        if l > 0:
            self.fname.set( fname[l.end():])

        i = re.search("-[0-9]*[0-9][0-9][0-9].ies", self.fname.get())
        self.family.set( self.fname.get()[0:i.start()] )

        self.LoadIESFile( self.familyPath.get() + '/' +self.fname.get())


    def LoadIESFile(self, lightFile):
        self.light = IES( lightFile )
        keylist = self.light.data['head'].keys()

        retry = 1
        while retry:
            retry = self.LoadFamily()

        if 'position' not in keylist:
            return
        if self.light != None:
            self.master.title( "Instrument interpolator: " + self.fname.get())
            l = string.split( self.light.data['head']['position'])
            x = eval( l[1] )
            y = eval( l[2] )
            align = l[3]

            if align != self.alignment:
                self.moveCanvas()

            self.SetCross(x,y)
            self.Interpolate(x,y)
            self.UpdateLegend()
#----------------------------------------------------------------------
    def Save(self):
        if self.canvasCleared:
            d = Dialog(self, title = "Error",
                   text = 'There is nothing to save',
                   default = 0,
                   bitmap="error",
                   strings=("OK", None) )
            return
        pattern = (self.family.get() + '-[0-9][0-9][0-9].ies')
        files = glob.glob(self.familyPath.get() + '/' + pattern)
        number = "-000"
        if len(files) == 0:
            number = "-000"
        else:
            pat = re.compile('-[0-9][0-9][0-9]')
            for x in files:
                mo = pat.search(x)
                if mo.end() >= 0:
                    a,b = mo.start(), mo.end()
                    print x, a, b
                    newnumber = string.atoi(x[a:b])
                    print newnumber
                    if string.atoi(number) >=  newnumber:
                        number = "%d" % (newnumber -1 )
                        number = string.zfill(number,4)
        # family and familyPath are StringVars, fname is a string
        #if len(self.fname.get()) == 0:
        self.fname.set( self.family.get() +  number + '.ies')
        if len(self.fname.get()) > 0:
            SaveDialog(self.familyPath, self.fname)
            self.light.writefile(self.familyPath.get() + "/" +
                                 self.fname.get())
            self.master.title( "Instrument interpolator: " + self.fname.get())



#----------------------------------------------------------------------
    def LoadFamily(self):
        pattern = (self.familyPath.get() +
                   '/'+ self.family.get() + '[cpf][bh][ido].ies')
        files = glob.glob(pattern)
        if len(files) == 9:
            del self.fFiles[0:]
            for x in files:
                self.fFiles.append(x)

            self.DrawFamily()
            return 0
        else:
            d = Dialog(self, title = "Error",
                   text = ('There must be 9 files in the family "'
                           + self.family.get() + '"'),
                   default = 0,
                   bitmap="error",
                   strings=("retry","cancel"))

            if d.num == 0:
                PathDialog(self.familyPath)
                return 1
            else:
                return 0

#----------------------------------------------------------------------
    def DrawFamily(self):
        # make a list of lights
        for key in self.lights.keys(): del self.lights[key]
        for x in self.fFiles:
            for y in self.pattern.keys(): # look for patterns
        #if regex.search(y,x) > 0:  # if match place in light list
                if re.search(y,x) > 0:  # if match place in light list
                    self.lights[self.pattern[y]] =  IES(x)

        # Once the lights are listed find the maximum vertical angle and
        # the maximum candela value.
        self.candela = 0
        self.vAngle = 0
        for x in self.lights.values(): # get max values
            cd, va  = x.maxCandela(), x.maxVertAngle()
            if (self.candela < cd): self.candela = cd
            if (self.vAngle < va): self.vAngle = va
        # Now that we have this information we can fill the canvas
        i = 0
        for x in self.lights.keys():
            self.fillCanvas(self.lights[x], self.canvases[x],
                            self.vAngle, self.candela, x)
            i = i + 1

#----------------------------------------------------------------------
    def fillCanvas(self, light, canvas, maxVAngle, maxCandela, tag):
        lastx = 0
        lasty = 0

        width = eval(canvas['width'])
        height = eval(canvas['height'])
        max = light.maxCandela()
        halfmax = max * 0.5
        tenthmax = max * 0.1
        zeromax = 0

        canvas.delete(tag)

        for k in range(0, eval(light.data['vAngles']) - 1):
            x = eval(light.data['vertAngle'][k])
            y = eval(light.data['candela']['0'][k])
            j = int(height - (height*y)/float(maxCandela))
            i = int( (x*width)/float(maxVAngle) )
            if tag == 'bigPlot':
                if y <= halfmax:
                    canvas.create_line(0,j, i,j, tags=tag, fill="#800")
                    canvas.create_line(i,j, i,height, tags = tag, fill="#800")
                    halfmax = -1
                if y <= tenthmax:
                    canvas.create_line(0,j, i,j, tags=tag, fill="#060")
                    canvas.create_line(i,j, i,height, tags = tag, fill="#060")
                    tenthmax = -1
                if y <= zeromax:
                    canvas.create_line(0,j, i,j, tags=tag, fill="#008")
                    canvas.create_line(i,j, i,height, tags = tag, fill="#008")
                    zeromax = -1

            if tag== 'bigPlot':
                canvas.create_line(lastx, lasty, i, j, width=2, tags=tag)
            else:
                canvas.create_line(lastx, lasty, i, j, tags=tag)
            lastx = i
            lasty = j

#----------------------------------------------------------------------
    def SetCross(self, x, y):  # Sets the cross hairs
        if self.cross != 0:
            self.canvas.delete('target')
            self.cross = 0

        self.canvas.create_line(x, y-5, x, y+5, tags='target')
        self.canvas.create_line(x-5,y,x+5,y, tags='target')
        self.cross = 1
#----------------------------------------------------------------------
    def MakePlot(self, event):
        x = event.x
        y = event.y

        if len(self.lights.keys()) != 0:
            self.SetCross(x,y)
            self.Interpolate(x,y)
            self.UpdateLegend()
        else:
          Dialog(self, title = "Error",
                   text = 'Use "New" or "Open" to insert family files',
                   default = 0,
                   bitmap="error",
                   strings=("OK", None))
#----------------------------------------------------------------------
    def Interpolate(self, x, y):
        width = eval(self.canvas['width'])
        height = eval(self.canvas['height'])

        scaley = y/float(height)
        midpoint = width/2.0
        if x < midpoint:
            scalex = x/midpoint
        else:
            scalex = (x -  midpoint)/(width - midpoint)

        if self.alignment == 'Top':
            if x < midpoint:
                self.light = self.InterpNewLight(scalex,scaley,
                                                    self.lights[0],
                                                    self.lights[1],
                                                    self.lights[3],
                                                    self.lights[4])
            else:
                self.light = self.InterpNewLight(scalex,scaley,
                                                    self.lights[1],
                                                    self.lights[2],
                                                    self.lights[4],
                                                    self.lights[5])
        else:
            if x < midpoint:
                self.light = self.InterpNewLight(scalex,scaley,
                                                    self.lights[3],
                                                    self.lights[4],
                                                    self.lights[6],
                                                    self.lights[7])
            else:
                self.light = self.InterpNewLight(scalex,scaley,
                                                    self.lights[4],
                                                    self.lights[5],
                                                    self.lights[7],
                                                    self.lights[8])

        self.light.data['head']['position'] = ("<position> %d %d %s\n" %
                                               (x , y, self.alignment) )

        self.fillCanvas(self.light, self.canvas,
                        self.vAngle, self.candela, 'bigPlot')
        self.canvasCleared = 0
#----------------------------------------------------------------------
    def InterpNewLight(self, sx, sy, l1, l2, l3, l4):
        newLight = copy.deepcopy(l1)

        ax, bx, ay, by  = 1 - sx, sx, 1 - sy,  sy


        for i in range(0, len(l1.data['candela']['0'])):
            val = ( ay * (ax * eval(l1.data['candela']['0'][i]) +
                          bx * eval(l2.data['candela']['0'][i]) ) +
                    by * (ax * eval(l3.data['candela']['0'][i]) +
                          bx * eval(l4.data['candela']['0'][i])))
            newLight.data['candela']['0'][i] =  "%d" % val

        return newLight
#----------------------------------------------------------------------
    def moveCanvas(self):
        self.canvas.delete('target')
        self.canvas.delete('bigPlot')
        self.maxCdLabel.config(text="Max Cd: ")
        self.bafaLabel.config(text="BA/FA: ")
        self.baLabel.config(text="B/A: ")
        self.faLabel.config(text="F/A: ")
        self.caLabel.config(text="C/A: ")
        BaseGui.moveCanvas(self)
        self.canvasCleared = 1
#----------------------------------------------------------------------
    def UpdateLegend(self):
        vals = self.light.maxCdBeamFieldCutoff()
        bafa = vals[1]/vals[2]
        self.maxCdLabel.config(text="Max Cd:\n %d" % vals[0])
        self.bafaLabel.config(text="BA/FA: %1.2f" % bafa)
        self.baLabel.config(text="B/A: %.2f" % (vals[1] * 2))
        self.faLabel.config(text="F/A: %.2f" % (vals[2] * 2))
        self.caLabel.config(text="C/A: %.2f" % (vals[3] * 2))


if __name__ == '__main__': Interp(None, "/dream_scratch/kuzimmer/shakespeare/lights").mainloop()
by AMcneil last modified Feb 29, 2016 12:25 PM