#!/usr/local/bin/python # # DO SOME ART!!! jch - April 2003 - twist.py # /usr/lib/python1.5/site-packages/OpenGL/Demo # This is statement is required by the build system to query build info if __name__ == '__build__': raise Exception import string __version__ = ' One ' __date__ = 'April 2003' __author__ = 'YON - jch@jch.com' # Tarn Weisner Burton ' # ======================================================================== # NURBS Playground # ======================================================================== # ported to Python 26-APR-2003 #include #include # #// Copyright YON - Jan C. Hardenbergh. Permission to copy is #// granted as long as this copyright and this URL are maintained: #// http://www.jch.com/~jch/NURBS/ # #// Primary reference Les Peigl - On NURBS: A Survey published #// in IEEE Computer Graphics and Applications (CG&A) January 1991. # #// http://www.cs.wpi.edu/~matt/courses/cs563/talks/nurbs.html # #// this is intended to explore NURBS - how they are evaluated. #// It is explicitly unoptimized. # #// the NURBCurve used as an example here is a circle inscribed #// in an equalateral triangle. I found it on page 374, #// Mathematical Elements for Computer Graphics, #// 2nd ed. David F. Rogers and J Alan Adams. McGraw Hill, 1990. import Numeric from Point import Point def B(i,k,t,knots): ret = 0 if k>0: n1 = (t-knots[i])*B(i,k-1,t,knots) d1 = knots[i+k] - knots[i] n2 = (knots[i+k+1] - t) * B(i+1,k-1,t,knots) d2 = knots[i+k+1] - knots[i+1] if d1 > 0.0001 or d1 < -0.0001: a = n1 / d1 else: a = 0 if d2 > 0.0001 or d2 < -0.0001: b = n2 / d2 else: b = 0 ret = a + b # print "B i = %d, k = %d, ret = %g, a = %g, b = %g\n"%(i,k,ret,a,b) else: if knots[i] <= t and t <= knots[i+1]: ret = 1 else: ret = 0 return ret def C(t, order, points, weights, knots): c = Point([0,0,0]) rational = 0 i = 0 while i < len(points): b = B(i, order, t, knots) p = points[i] * (b * weights[i]) c = c + p rational = rational + b*weights[i] i = i + 1 return c * (1.0/rational) def close(x,y,px,py): tol = 4 tx = x - px if tx < -tol or tx > tol: return 0 ty = y - py if ty < -tol or ty > tol: return 0 return 1 # ======================================================================== # Based on some code from the GL Extrusion # ======================================================================== from OpenGL.GL import * from OpenGL.Tk import * from OpenGL.GLE import * from Tkinter import * import sys, os, time, string import LinearAlgebra from tkFileDialog import * from Mass import Mass from Spring import Spring from Physics import Physics # ======================================================================== # ======================================================================== # ======================================================================== class MyApp(Frame): def initLights(self): glMaterialfv(GL_FRONT, GL_AMBIENT, [0.2, 0.2, 0.2, 1.0]) glMaterialfv(GL_FRONT, GL_DIFFUSE, [0.8, 0.8, 0.8, 1.0]) glMaterialfv(GL_FRONT, GL_SPECULAR, [1.0, 0.0, 1.0, 1.0]) glMaterialfv(GL_FRONT, GL_SHININESS, 10.0) glLightfv(GL_LIGHT0, GL_AMBIENT, [0.2, 0.1, 0.1, 1.0]) glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.8, 0.8, 0.8, 1.0]) glLightfv(GL_LIGHT0, GL_SPECULAR, [1.0, 1.0, 1.0, 1.0]) glLightfv(GL_LIGHT0, GL_POSITION, [1.0, 1.0, 1.0, 0.0]); glLightfv(GL_LIGHT1, GL_AMBIENT, [0.1, 0, 0.2, 1.0]) glLightfv(GL_LIGHT1, GL_DIFFUSE, [0.7, 0.7, 0.7, 1.0]) glLightfv(GL_LIGHT1, GL_SPECULAR, [1.0, 1.0, 1.0, 1.0]) glLightfv(GL_LIGHT1, GL_POSITION, [-1.0, 0, 0, 0.0]); # glLightModelfv(GL_LIGHT_MODEL_AMBIENT, [0.2, 0.2, 0.2, 1.0]) glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) glEnable(GL_LIGHT1) glCullFace(GL_BACK) glEnable(GL_CULL_FACE) def evaluate(self,maxt,steps): order = 2 self.path = [] self.twists = [] twist = self.startTwist self.startTwist += 15 self.dangle = 240/self.strokes self.colors = [] for i in range(steps+1): t = i*(maxt*0.999/steps) c = C(t, order, self.controlPoints, self.weights, self.knots) # c.Print() self.path = self.path + [[c[0],c[1],c[2]]] self.twists = self.twists + [twist-i*self.dangle] self.colors = self.twists + [[1,1,1]] def initTrusions(self): # do 6 tubes. So, we want 6 points at a radius of 1.0 that form a hexagon # and we want to start at the mid point between two of those and we want to # step around 240 degrees. So, the centers are # [1,0], [.5,RAD3/2], [-.5,RAD3/2], [-1, 0], [-.5,-RAD3/2], [.5,-RAD3/2] # we want to star at the midpoint of two of these [0,RAD3/2] # all of those * 2 rad3 = 1.732 self.contour = [[0,rad3]] self.normals = [[1,0]] hc = [[-1,rad3], [-2, 0], [-1,-rad3], [1,-rad3], [2,0], [1,rad3]] count = 24 nSteps = count*2/3 angle = 0.0 step = 0 for i in range(6): step = 0 while step < nSteps: angle = angle + 6.28/(count) self.contour.append([hc[i][0]+math.cos(angle),hc[i][1]+math.sin(angle)]) self.normals.append([math.cos(angle),math.sin(angle)]) step += 1 angle -= 3.14 # main ************************************************** self.path = [[0,0,0]] self.drawControlPoints = 0 # def NURBSEval(): zScale = -8 unscaledPoints = [Point([0,0*zScale,0]), Point([0.4,0.1*zScale,0.1]), Point([.5,0.2*zScale,.5]), Point([0,0.3*zScale,0.8]), Point([-.5,0.4*zScale,.5]), Point([-0.7,0.5*zScale,0.2]), Point([0,0.6*zScale,0])] bigScale = 20 self.controlPoints = [] for cp in unscaledPoints: self.controlPoints = self.controlPoints + [cp*bigScale] self.knots = [0,0,0,1,2,3,4,5,5,5] self.maxtparam = 5 self.strokes = 10 self.weights = [1,1,1,1,1,1,1] self.startTwist = 0 self.dangle = 24 self.evaluate(self.maxtparam,self.maxtparam*self.strokes) self.quad = gluNewQuadric() gluQuadricOrientation (self.quad,GLU_OUTSIDE) def initPath(self): unscaledPath = [Point([1,0,0]), Point([0.707,0,-0.707]), Point([0,0,-1]), Point([-0.707,0,-0.707]), Point([-1,0,0]), Point([-0.707,0,0.707]), Point([0,0,1]), Point([0.707,0,0.707]), Point([1,0,0])] pathScale = 5 self.pathPoints = [] for pp in unscaledPath: self.pathPoints = self.pathPoints + [pp*pathScale] self.pathKnots = [0,0,0,1,2,3,4,5,6,7,7,7] self.maxpparam = 7 self.pathWeights = [1,1,1,1,1,1,1,1,1,1] self.drawPath = 0 self.pathPosition = 0 self.pathIncr = 0.1 def initPhysics(self, velocities): # timeStep, oversample, gravity, viscosity self.system = Physics(0.2, 4, self.graveness, self.stiffness) # 0.15 * len(self.controlPoints) weight = 0.9 for cpm in self.controlPoints: self.system.insertMass(Mass(weight, cpm)) weight -= 0.1 self.system.masses[0].fixed = 1 for mm in range(len(velocities)): self.system.masses[mm].v.Assign(velocities[mm]) # connect the masses with springs for i in range(len(self.system.masses)-1): self.system.insertSpring(Spring(self.system.masses[i], self.system.masses[i+1], k=self.springStrength, damping=0.0)) def setupView(self): width = self.gl.winfo_width() height = self.gl.winfo_height() aspect = 2*float(width)/float(height) viewMatrix = glGetFloatv(GL_MODELVIEW_MATRIX) zNear = -100 zFar = 0 for i in range(len(self.controlPoints)): cp = self.controlPoints[i] vertex = Numeric.array([cp[0], cp[1], cp[2], 1.0]) npcPoint = Numeric.matrixmultiply(vertex,viewMatrix) # print npcPoint if npcPoint[2] > zNear: zNear = npcPoint[2] if npcPoint[2] - 5 < zFar: zFar = npcPoint[2] + 5 zNear = zNear zFar = zFar if zNear > -1: zNear = -1 # print "near %g, far %g"%(zNear, zFar) glMatrixMode(GL_PROJECTION) gluPerspective(90, aspect, zNear, zFar ) glMatrixMode(GL_MODELVIEW) def redraw(self, o): self.setupView() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) gleSetJoinStyle(TUBE_CONTOUR_CLOSED | TUBE_NORM_EDGE | TUBE_JN_CAP | TUBE_JN_ANGLE ) glMaterialfv(GL_FRONT, GL_AMBIENT, [0.3, 0.4, 0.5, 1.0]) glMaterialfv(GL_FRONT, GL_DIFFUSE, [0.8, 0.8, 0.8, 1.0]) if self.drawControlPoints == 0: gleTwistExtrusion(self.contour, self.normals, [0,0,1], self.path, self.colors, self.twists) glPushMatrix() cp = self.path[1] glTranslated(cp[0], cp[1], cp[2]) gluSphere (self.quad, 2.4, self.strokes, self.strokes) glPopMatrix() else: glMaterialfv(GL_FRONT, GL_AMBIENT, [0.6, 0.5, 0.4, 1.0]) glMaterialfv(GL_FRONT, GL_DIFFUSE, [0.8, 0.8, 0.8, 1.0]) contour = [[-1,-1],[1,-1],[0,1]] gleTwistExtrusion(contour, contour, [0,0,1], self.path, self.colors, self.twists) glMatrixMode(GL_MODELVIEW) for i in range(len(self.controlPoints)): glPushMatrix() cp = self.controlPoints[i] # cp.Print() if self.getHotControlPoint() - 1 == i: glMaterialfv(GL_FRONT, GL_AMBIENT, [0.5, 1, 0.8, 1.0]) glMaterialfv(GL_FRONT, GL_DIFFUSE, [0.5, 1, 0.8, 1.0]) else: glMaterialfv(GL_FRONT, GL_AMBIENT, [1, 0.5, 0.8, 1.0]) glMaterialfv(GL_FRONT, GL_DIFFUSE, [1, 0.5, 0.8, 1.0]) glTranslated(cp[0], cp[1], cp[2]) gluSphere (self.quad, 0.7, 8, 8) glPopMatrix() if self.drawPath > 0: for j in range(len(self.pathPoints)): glPushMatrix() pp = self.pathPoints[j] # cp.Print() if self.getHotPathPoint() - 1 == j: glMaterialfv(GL_FRONT, GL_AMBIENT, [0.4, 1, 0, 1.0]) glMaterialfv(GL_FRONT, GL_DIFFUSE, [0.4, 1, 0, 1.0]) else: glMaterialfv(GL_FRONT, GL_AMBIENT, [0, 0.8, 1, 1.0]) glMaterialfv(GL_FRONT, GL_DIFFUSE, [0, 0.8, 1, 1.0]) glTranslated(pp[0], pp[1], pp[2]) gluSphere (self.quad, 0.4, 4, 4) glPopMatrix() def save(self): newfile = asksaveasfilename(filetypes=[("twist paramters", "*.tws")]) if (newfile==None or newfile==""): return if os.path.splitext(newfile)[1] != '.tws': newfile = newfile + '.tws' paramfile = open(newfile, 'w') paramfile.write("# twisty parameters 0.1 "+time.strftime("%a, %d %b %Y %H:%M:%S GMT\n", time.gmtime(time.time()))) paramfile.write("\n") for cp in self.controlPoints: paramfile.write("cp %8.3f %8.3f %8.3f\n"%(cp[0], cp[1], cp[2])) paramfile.write("\n") paramfile.write("\n") for mm in range(len(self.system.masses)): # print "velocity %d\n"%(mm) paramfile.write("vec %8.3f %8.3f %8.3f\n"%( self.system.masses[mm].v[0], self.system.masses[mm].v[1], self.system.masses[mm].v[2])) # print self.system.masses[mm].v.Print() #vstring = vstring + " %g"%(self.system.masses[mm].v) paramfile.write("\n") kstring = "" for knot in self.knots: kstring = kstring + " %d"%(knot) kstring = kstring + " \n" paramfile.write(kstring) paramfile.write("\n") for pp in self.pathPoints: paramfile.write("cp %8.3f %8.3f %8.3f\n"%(pp[0], pp[1], pp[2])) paramfile.write("\n") #paramfile.write(self.knots.tostring()) kstring = "" for knot in self.pathKnots: kstring = kstring + " %d"%(knot) kstring = kstring + " \n" paramfile.write(kstring) paramfile.write(" %g\n"%(self.pathPosition)) paramfile.write(" %g\n"%(self.springStrength)) paramfile.write(" %g\n"%(self.graveness)) paramfile.write(" %g\n"%(self.stiffness)) paramfile.write(" %d\n"%(self.strokes)) paramfile.write(" %d\n"%(self.runlaps)) paramfile.write(" %g\n"%(self.pathIncr)) paramfile.write("\n") paramfile.close() print "Wrote parameter file "+newfile; def parseKnots(self, tokens): knots = [string.atoi(tokens[1])] ki = 2 while ki < len(tokens) - 1: knots = knots + [string.atoi(tokens[ki])] ki += 1 return knots def load(self): # d = FileDialog(master) # file = d.go() myPath = askopenfilename(filetypes=[("twist paramters", "*.tws")]) if (myPath==None or myPath==""): return lines = open(myPath, 'r').readlines() state = 0 knots = [] cPoints = [] weights = [] pknots = [] pPoints = [] pWeights = [] pathPosition = 0 vecstate = 0 vectors = [] for l in lines: tokens = string.split(l) first_word = tokens[0] if first_word[0] == '#': pass elif first_word == '': state = 1 elif first_word == 'cp' and state == 1: if len(tokens) == 4: cp = Point([string.atof(tokens[1]), string.atof(tokens[2]), string.atof(tokens[3])]) cPoints = cPoints + [cp] weights = weights + [1] else: print "bad control point " print tokens elif first_word == '' and state == 1: state = 2 elif first_word == '' and vecstate == 0: vecstate = 1 elif first_word == '' and vecstate == 1: vecstate = 2 elif first_word == 'vec' and vecstate == 1: if len(tokens) == 4: cp = Point([string.atof(tokens[1]), string.atof(tokens[2]), string.atof(tokens[3])]) vectors = vectors + [cp] else: print "bad vector " print tokens elif first_word == '' and state == 2: if tokens[len(tokens)-1] == '': knots = self.parseKnots(tokens) if len(knots) > 0: state = 3 else: print 'Bad pknotty' elif first_word == '' and state == 3: state = 4 elif first_word == 'cp' and state == 4: if len(tokens) == 4: cp = Point([string.atof(tokens[1]), string.atof(tokens[2]), string.atof(tokens[3])]) pPoints = pPoints + [cp] pWeights = pWeights + [1] else: print "bad path point " print tokens elif first_word == '' and state == 4: state = 5 elif first_word == '' and state == 5: if tokens[len(tokens)-1] == '': pKnots = self.parseKnots(tokens) if len(knots) > 0: state = 6 else: print 'Bad pknotty' elif first_word == '': pathPosition = string.atof(tokens[1]) elif first_word == '': springStrength = string.atof(tokens[1]) elif first_word == '': graveness = string.atof(tokens[1]) elif first_word == '': stiffness = string.atof(tokens[1]) elif first_word == '': strokes = string.atoi(tokens[1]) elif first_word == '': runlaps = string.atoi(tokens[1]) elif first_word == '': pathIncr = string.atof(tokens[1]) elif first_word == '' and state == 6: state = 7 elif first_word == '' and state == 3: state = 4 else: print tokens print 'Junk found state = %d'%(state) if state == 7: self.pathPoints = pPoints self.pathKnots = pKnots self.maxpparam = pKnots[-1] self.pathWeights = pWeights self.springStrength = springStrength self.graveness = graveness self.stiffness = stiffness self.strokes = strokes self.runlaps = runlaps self.pathIncr = pathIncr self.pathPosition = pathPosition state = 4 if state == 4: self.controlPoints = cPoints self.weights = weights self.knots = knots self.maxtparam = knots[-1] self.initPhysics(vectors) self.regen() else: print "failed to parse %s last state %d"%(myPath, state) def snap(self): self.SaveTo("snap.jpg") def SaveTo( self, filename, format="JPEG" ): """Snap current buffer to filename in format""" import Image # get PIL's functionality... width = self.gl.winfo_width() height = self.gl.winfo_height() glPixelStorei(GL_PACK_ALIGNMENT, 1) data = glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE) image = Image.fromstring( "RGB", (width, height), data ) image = image.transpose( Image.FLIP_TOP_BOTTOM) # print dir(image) image.save( filename, format, quality=100 ) print 'Snapshot image in %s'% (os.path.abspath( filename)) return image def resetView(self): self.gl.reset() self.gl.tkRedraw() # after_idle(callback, args...) def run(self): if self.animate == 0: self.animate = 1 # self.run.after(50,self.doTick) self.run.after_idle(self.doTick) self.runCount = self.runlaps for im in range(len(self.system.masses)): # self.controlPoints[im].Print() self.system.masses[im].setPosition(self.controlPoints[im]) else: self.animate = 0 def doTick(self): if self.recording > 0: self.frame += 1 self.SaveTo("frame%s.jpg"%(string.zfill("%d"%(self.frame),4))) if self.animate > 0: self.pathPosition += self.pathIncr if (self.pathPosition > self.maxpparam): self.pathPosition -= self.maxpparam #self.controlPoints[0].Assign( self.system.masses[0].setPosition( self.getPointOnPath(self.pathPosition)) self.system.step() for im in range(len(self.system.masses)): self.controlPoints[im].Assign(self.system.masses[im].getPosition()) # self.controlPoints[im].Print(); self.regen() self.runCount -= 1 if self.runCount > 0: self.run.after_idle(self.doTick) else: self.animate = 0 def getPointOnPath(self, pathPosition): c = C(pathPosition, 2, self.pathPoints, self.pathWeights, self.pathKnots) # self.pathPosition += 1 # if self.pathPosition >= len(self.pathPoints): # self.pathPosition = 0 # self.pathPoints[self.pathPosition]) return c def regen(self): self.evaluate(self.maxtparam,self.maxtparam*self.strokes) self.gl.tkRedraw() def pickPoint(self, x, y, points): width = self.gl.winfo_width() height = self.gl.winfo_height() viewMatrix = glGetFloatv(GL_MODELVIEW_MATRIX) projMatrix = glGetFloatv(GL_PROJECTION_MATRIX) # concat = Numeric.matrixmultiply(projMatrix,viewMatrix) concat = Numeric.matrixmultiply(viewMatrix,projMatrix) # ivy = LinearAlgebra.inverse(concat) for i in range(len(points)): cp = points[i] vertex = Numeric.array([cp[0], cp[1], cp[2], 1.0]) # print vertex npcPoint = Numeric.matrixmultiply(vertex,concat) if (npcPoint[3] < 0): continue px = npcPoint[0]/npcPoint[3]*width/2.0 + width/2.0 py = height/2 - npcPoint[1]/npcPoint[3]*height/2.0 # print px, py # print "got %d %d %d - t %d %d"%(i,x,y,px,py) if close(x,y,px,py): return i+1 # print "none %d %d"%(x,y) return 0 def setDragging(self, points, index): self.dragPoints = points self.dragging = index if index == 0: self.lastY = -1 self.gl.tkRedraw() def getDragging(self): return self.dragging def setHotControlPoint(self, index): self.hotControlPoint = index def getHotControlPoint(self): return self.hotControlPoint def setHotPathPoint(self, index): self.hotPathPoint = index def getHotPathPoint(self): return self.hotPathPoint def drag(self, x, y, points, hotIndex): if self.lastY == -1: self.lastX = x self.lastY = y else: tx = x - self.lastX ty = y - self.lastY ############################################## width = self.gl.winfo_width() height = self.gl.winfo_height() viewMatrix = glGetFloatv(GL_MODELVIEW_MATRIX) projMatrix = glGetFloatv(GL_PROJECTION_MATRIX) concat = Numeric.matrixmultiply(viewMatrix,projMatrix) cp = points[hotIndex] vertex = Numeric.array([cp[0], cp[1], cp[2], 1.0]) npcPoint = Numeric.matrixmultiply(vertex,concat) npcZ = npcPoint[2]/npcPoint[3] npcX = npcPoint[0]/npcPoint[3] + 2.0*tx/float(width) npcY = npcPoint[1]/npcPoint[3] - 2.0*ty/float(height) vertex = Numeric.array([npcX, npcY, npcZ, 1.0]) ivy = LinearAlgebra.inverse(concat) newcp = Numeric.matrixmultiply(vertex,ivy) cpz = newcp[2]/newcp[3] cpx = newcp[0]/newcp[3] cpy = newcp[1]/newcp[3] # print "new cp %g %g %g"%(cpx, cpy, cpz) points[hotIndex].Assign([cpx,cpy,cpz]) # points[index].Print() ############################################## self.lastX = x self.lastY = y self.gl.tkRedraw() def handleMotion(self, event): if self.getDragging(): self.drag(event.x,event.y,self.dragPoints, self.getDragging() - 1) else: self.setHotPathPoint(0) found = self.pickPoint(event.x,event.y, self.controlPoints) self.setHotControlPoint(found) if found > 0: self.gl.configure(cursor="crosshair") else: found = self.pickPoint(event.x,event.y, self.pathPoints) if found > 0: self.setHotPathPoint(found) self.gl.configure(cursor="plus") else: self.gl.configure(cursor="arrow") def handleCB1(self, event): if self.getDragging(): self.setDragging(0,0) else: if (self.getHotControlPoint() > 0): self.setDragging(self.controlPoints, self.getHotControlPoint()) elif (self.getHotPathPoint() > 0): self.setDragging(self.pathPoints, self.getHotPathPoint()) def ignore(self,event): pass def togp(self): if self.drawControlPoints == 0: self.drawControlPoints = 1 self.gl.bind("",self.handleMotion) self.gl.configure(cursor="hand1") self.drawPath = 1 else: self.drawControlPoints = 0 self.gl.bind("",self.ignore) self.gl.configure(cursor="arrow") self.drawPath = 0 self.gl.tkRedraw() def recBut(self): if self.recording: self.recording = 0 else: self.recording = 1 def incrBut(self): if self.incr: self.incr = 0 else: self.incr = 1 def sprBut(self): if self.incr: self.springStrength += 0.5 else: self.springStrength -= 0.5 for spring in self.system.springs: spring.SetSpringConstant(self.springStrength) print "new spring strength %g"%(self.springStrength) def gravBut(self): if self.incr: self.graveness += 0.1 else: self.graveness -= 0.1 self.system.SetGravity(self.graveness) print "new gravity %g"%(self.graveness) def stifBut(self): if self.incr: self.stiffness += 0.1 else: self.stiffness -= 0.1 self.system.SetViscosity(self.stiffness) print "new viscosity %g"%(self.stiffness) def fineBut(self): if self.incr: self.strokes += 5 else: self.strokes -= 5 print "new strokes %g"%(self.strokes) def runlapBut(self): if self.incr: self.runlaps *= 10 else: self.runlaps /= 10 if self.runlaps < 1: self.runlaps = 1 print "new runCount = %d"%(self.runlaps) def pstepBut(self): if self.incr: self.pathIncr += 0.02 else: self.pathIncr -= 0.02 print "new pathIncr %g"%(self.pathIncr) ############################################################################ def __init__(self): self.f = Frame() self.f.pack() self.gl = Opengl(width = 400, height = 400, double = 1, depth = 1) self.gl.redraw = self.redraw self.gl.autospin_allowed = 1 self.gl.pack(side = TOP, expand = YES, fill = BOTH) self.gl.set_background(255,205,245) # self.gl.set_centerpoint(0,-2,0) # self.gl.bind("",handleMotion) # self.gl.bind("", ignore) # self.gl.help() self.hotControlPoint = 0 self.hotPathPoint = 0 self.dragging = 0 self.animate = 0 self.recording = 0 self.frame = 0 self.springStrength = 5.4 self.graveness = 0.52 self.stiffness = 0.31 self.runlaps = 50 self.initLights() self.initTrusions() self.initPath() self.initPhysics([]) self.sv = Button(self.f, text="Save", command=self.save) self.sv.pack(side='left') self.ld = Button(self.f, text="Load", command=self.load) self.ld.pack(side='left') self.run = Button(self.f, text = 'Run', command = self.run) self.run.pack(side = 'left') self.record = Button(self.f, text = 'Record', command = self.recBut) self.record.pack(side = 'left') self.cp = Button(self.f, text = 'Points', command = self.togp) self.cp.pack(side = 'left') self.incr = Button(self.f, text = 'Incr', command = self.incrBut) self.incr.pack(side = 'left') self.runlap = Button(self.f, text = 'Steps', command = self.runlapBut) self.runlap.pack(side = 'left') self.pstep = Button(self.f, text = 'Path', command = self.pstepBut) self.pstep.pack(side = 'left') self.springy = Button(self.f, text = 'Springy', command = self.sprBut) self.springy.pack(side = 'left') self.grave = Button(self.f, text = 'Gravity', command = self.gravBut) self.grave.pack(side = 'left') self.stiff = Button(self.f, text = 'Viscosity', command = self.stifBut) self.stiff.pack(side = 'left') self.finer = Button(self.f, text = 'Fine', command = self.fineBut) self.finer.pack(side = 'left') self.b = Button(self.f, text="Snap", command=self.snap) self.b.pack(side='left') self.reset = Button(self.f, text = 'Reset', command = self.resetView) self.reset.pack(side = 'left') self.reg = Button(self.f, text = 'Regen', command = self.regen) self.reg.pack(side = 'left') # print self.f.config() # print "next" # print dir(self.f) self.gl.bind("",self.handleCB1) self.lastX = 0 self.lastY = -1 self.gl.mainloop() app = MyApp()