#!/usr/bin/env python # Copyright (C) 2006 David Griffiths # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. from gpy import * from math import * from fpformat import * from threading import * from copy import * from Tkinter import * import tkMessageBox import tkFileDialog import tkFont import osc import os import time oscport = 4005 # set global apperance options default_font = ("Courier",8,"normal") default_relief = FLAT col_bg2 = "#cc4e00" col_active = "#bfda00" col_bg = "#000000" default_patternwidth = 400 default_w = 400 default_h = 200 ######################################################################### class GPView: def __init__(self,master,command,mmbcommand,rmbcommand,fgcol="white",bgcol="grey",textcol="black"): self.width = 300 self.height = 300 self.centrex=self.width/2 self.centrey=self.width/2 self.funcdist=13.0 self.widget = Canvas(master, width=self.width, height=self.height, bg=bgcol,highlightthickness=1, highlightbackground=col_bg) self.widget.bind(sequence="", func=command) self.widget.bind(sequence="", func=mmbcommand) self.widget.bind(sequence="", func=rmbcommand) def draw_tree(self,tree): self.widget.delete(ALL) self._draw_tree(tree.root,0.0,math.pi*2.0,0.0) def _draw_tree(self,node,start,end,depth): linefromx=self.centrex+(sin(start+(end-start)/2.0)*depth*self.funcdist) linefromy=self.centrey+(cos(start+(end-start)/2.0)*depth*self.funcdist) if len(node.args)>0: angleperarg=(end-start)/len(node.args) for i in range(len(node.args)): childstart=start+angleperarg*float(i) childend=childstart+angleperarg linetox=self.centrex+(sin(childstart+(childend-childstart)/2.0)*(depth+1)*self.funcdist) linetoy=self.centrey+(cos(childstart+(childend-childstart)/2.0)*(depth+1)*self.funcdist) self.widget.create_line(linefromx,linefromy,linetox,linetoy) self._draw_tree(node.args[i],childstart,childend,depth+1) if node.nodetype=="function": halfwidth=((len(node.name)*5)/2)+2 self.widget.create_rectangle(linefromx-halfwidth,linefromy-5,linefromx+halfwidth,linefromy+4,fill="grey") self.widget.create_text(linefromx,linefromy,text=node.name,font=default_font) if node.nodetype=="terminal": self.widget.create_rectangle(linefromx-12,linefromy-5,linefromx+12,linefromy+4,fill="grey") self.widget.create_text(linefromx,linefromy,text=fix(node.value,2),font=default_font) ####################################################################### class GP: def __init__(self): # entry 0 is the default terminal table = [terminal(0,1000), \ function("*",2,FloatType,[FloatType,FloatType]), \ function("+",2,FloatType,[FloatType,FloatType]), \ function("-",2,FloatType,[FloatType,FloatType]), \ function("/",2,FloatType,[FloatType,FloatType]), \ function("%",2,FloatType,[FloatType,FloatType]), \ function("sin",1,FloatType), \ function("cos",1,FloatType), \ function("time",0,FloatType)] self.tree = tree(table,5) def render(self,tid): pass ######################################################################### class App: def __init__(self): self.root = Tk() self.root.protocol("WM_DELETE_WINDOW", self.exitcallback) self.root.title("fastbreeder") self.top = Frame(self.root) self.top.pack() self.view=[] self.gp=[] self.mutationrate=2 self.selected=0 menu = Menu(self.root, font=default_font, relief=default_relief) self.root.config(menu=menu) filemenu = Menu(self.root, font=default_font, relief=default_relief) menu.add_cascade(label="file", menu=filemenu) filemenu.add_command(label = "load", command=self.load) filemenu.add_command(label = "save", command=self.save) self.gp.append(GP()) self.view.append(GPView(self.top,self.select0,self.reset,self.audition0)) self.view[0].widget.grid(column=0, row=0) self.gp.append(GP()) self.view.append(GPView(self.top,self.select1,self.reset,self.audition1)) self.view[1].widget.grid(column=0, row=1) self.gp.append(GP()) self.view.append(GPView(self.top,self.select2,self.reset,self.audition2)) self.view[2].widget.grid(column=1, row=0) self.gp.append(GP()) self.view.append(GPView(self.top,self.select3,self.reset,self.audition3)) self.view[3].widget.grid(column=1, row=1) self.update() def update(self): self.view[0].draw_tree(self.gp[0].tree) self.view[1].draw_tree(self.gp[1].tree) self.view[2].draw_tree(self.gp[2].tree) self.view[3].draw_tree(self.gp[3].tree) def _helper(self,select,id1,id2,id3): self.selected = select self.gp[id1]=deepcopy(self.gp[select]) self.gp[id1].render(id1) self.gp[id2]=deepcopy(self.gp[select]) self.gp[id2].render(id2) self.gp[id3]=deepcopy(self.gp[select]) self.gp[id3].render(id3) self.gp[id1].tree.mutate(self.mutationrate) self.gp[id2].tree.mutate(self.mutationrate) self.gp[id3].tree.mutate(self.mutationrate) osc.Message("/synth",[self.gp[select].tree.code()]).sendlocal(oscport) #osc.Message("/synth",["(sin time )"]).sendlocal(oscport) def select0(self,event): self._helper(0,1,2,3) self.update() def select1(self,event): self._helper(1,0,2,3) self.update() def select2(self,event): self._helper(2,0,1,3) self.update() def select3(self,event): self._helper(3,0,1,2) self.update() def audition0(self,event): osc.Message("/synth",[self.gp[0].tree.code()]).sendlocal(oscport) def audition1(self,event): osc.Message("/synth",[self.gp[1].tree.code()]).sendlocal(oscport) def audition2(self,event): osc.Message("/synth",[self.gp[2].tree.code()]).sendlocal(oscport) def audition3(self,event): osc.Message("/synth",[self.gp[3].tree.code()]).sendlocal(oscport) def reset(self,event): self.gp[0].tree.randomise(5) self.gp[1].tree.randomise(5) self.gp[2].tree.randomise(5) self.gp[3].tree.randomise(5) self.update() def load(self): filename = tkFileDialog.askopenfilename() patch = open(filename,"r") print(filename) code = patch.read() self.gp[0].tree.build(code) self.gp[1].tree.build(code) self.gp[2].tree.build(code) self.gp[3].tree.build(code) patch.close() self.update() def save(self): filename = tkFileDialog.asksaveasfilename() patch = open(filename,"w") patch.write(self.gp[self.selected].tree.code()) patch.close() def exitcallback(self): if tkMessageBox.askokcancel("Quit", "Do you really wish to quit?"): self.root.destroy() os.popen("killall -9 fastbreederserver") def startserver(): if not os.fork(): os.popen("killall fastbreederserver") os.popen("fastbreederserver "+str(oscport)) sys.exit() time.sleep(1); # wait for server to come up ######################################################################### startserver() app=App() app.root.mainloop() ######################################################################## #print(t.code()) #print("----------------------------------------") #t.mutate(10) #print(t.code())