diff --git a/plater.py b/plater.py index cabee4f..c1f6af8 100755 --- a/plater.py +++ b/plater.py @@ -1,69 +1,73 @@ #!/usr/bin/env python -import wx,time,random,threading,os,math -import stltool - +import wx +import time +import random +import threading +import os +import math import sys +import stltool -glview=False +glview = False if "-nogl" not in sys.argv: try: import stlview - glview=True + glview = True except: pass def evalme(s): - return eval(s[s.find("(")+1:s.find(")")]) + return eval(s[s.find("(") + 1:s.find(")")]) + class stlwrap: - def __init__(self,obj,name=None): - self.obj=obj - self.name=name + def __init__(self, obj, name=None): + self.obj = obj + self.name = name if name is None: - self.name=obj.name - + self.name = obj.name + def __repr__(self): return self.name - + class showstl(wx.Window): - def __init__(self,parent,size,pos): - wx.Window.__init__(self,parent,size=size,pos=pos) - #self.SetBackgroundColour((0,0,0)) - #wx.FutureCall(200,self.paint) - self.i=0 - self.parent=parent - self.previ=0 - self.Bind(wx.EVT_MOUSEWHEEL,self.rot) - self.Bind(wx.EVT_MOUSE_EVENTS,self.move) - self.Bind(wx.EVT_PAINT,self.repaint) + def __init__(self, parent, size, pos): + wx.Window.__init__(self, parent, size=size, pos=pos) + #self.SetBackgroundColour((0, 0, 0)) + #wx.FutureCall(200, self.paint) + self.i = 0 + self.parent = parent + self.previ = 0 + self.Bind(wx.EVT_MOUSEWHEEL, self.rot) + self.Bind(wx.EVT_MOUSE_EVENTS, self.move) + self.Bind(wx.EVT_PAINT, self.repaint) self.Bind(wx.EVT_KEY_DOWN, self.keypress) - #self.s=stltool.stl("sphere.stl").scale([2,1,1]) - self.triggered=0 - self.initpos=None - self.prevsel=-1 + #self.s = stltool.stl("sphere.stl").scale([2, 1, 1]) + self.triggered = 0 + self.initpos = None + self.prevsel = -1 - def drawmodel(self,m,scale): - m.bitmap=wx.EmptyBitmap(800,800,32) - dc=wx.MemoryDC() + def drawmodel(self, m, scale): + m.bitmap = wx.EmptyBitmap(800, 800, 32) + dc = wx.MemoryDC() dc.SelectObject(m.bitmap) - dc.SetBackground(wx.Brush((0,0,0,0))) - dc.SetBrush(wx.Brush((0,0,0,255))) - #dc.DrawRectangle(-1,-1,10000,10000) - dc.SetBrush(wx.Brush(wx.Colour(128,255,128))) - dc.SetPen(wx.Pen(wx.Colour(128,128,128))) - #m.offsets=[10,10,0] - #print m.offsets,m.dims - for i in m.facets:#random.sample(m.facets,min(100000,len(m.facets))): - dc.DrawPolygon([wx.Point(400+scale*p[0],(400-scale*p[1])) for p in i[1]]) + dc.SetBackground(wx.Brush((0, 0, 0, 0))) + dc.SetBrush(wx.Brush((0, 0, 0, 255))) + #dc.DrawRectangle(-1, -1, 10000, 10000) + dc.SetBrush(wx.Brush(wx.Colour(128, 255, 128))) + dc.SetPen(wx.Pen(wx.Colour(128, 128, 128))) + #m.offsets = [10, 10, 0] + #print m.offsets, m.dims + for i in m.facets: # random.sample(m.facets, min(100000, len(m.facets))): + dc.DrawPolygon([wx.Point(400 + scale * p[0], (400 - scale * p[1])) for p in i[1]]) #if(time.time()-t)>5: # break dc.SelectObject(wx.NullBitmap) - m.bitmap.SetMask(wx.Mask(m.bitmap,wx.Colour(0,0,0,255))) - - + m.bitmap.SetMask(wx.Mask(m.bitmap, wx.Colour(0, 0, 0, 255))) + def move_shape(self, delta): """moves shape (selected in l, which is list ListBox of shapes) by an offset specified in tuple delta. @@ -106,7 +110,7 @@ class showstl(wx.Window): del dc else: event.Skip() - + def rotate_shape(self, angle): """rotates acive shape positive angle is clockwise @@ -146,133 +150,134 @@ class showstl(wx.Window): event.Skip() def rotateafter(self): - if(self.i!=self.previ): - i=self.parent.l.GetSelection() + if(self.i != self.previ): + i = self.parent.l.GetSelection() if i != wx.NOT_FOUND: - #o=self.models[self.l.GetItemText(i)].offsets - self.parent.models[self.parent.l.GetString(i)].rot-=5*(self.i-self.previ) - #self.models[self.l.GetItemText(i)].offsets=o - self.previ=self.i + #o = self.models[self.l.GetItemText(i)].offsets + self.parent.models[self.parent.l.GetString(i)].rot -= 5 * (self.i - self.previ) + #self.models[self.l.GetItemText(i)].offsets = o + self.previ = self.i self.Refresh() def cr(self): time.sleep(0.01) wx.CallAfter(self.rotateafter) - self.triggered=0 - + self.triggered = 0 + def rot(self, event): - z=event.GetWheelRotation() - s=self.parent.l.GetSelection() - if self.prevsel!=s: - self.i=0 - self.prevsel=s + z = event.GetWheelRotation() + s = self.parent.l.GetSelection() + if self.prevsel != s: + self.i = 0 + self.prevsel = s if z < 0: self.rotate_shape(-1) else: self.rotate_shape(1) - - def repaint(self,event): - dc=wx.PaintDC(self) + + def repaint(self, event): + dc = wx.PaintDC(self) self.paint(dc=dc) - - def paint(self,coord1="x",coord2="y",dc=None): - coords={"x":0,"y":1,"z":2} + + def paint(self, coord1="x", coord2="y", dc=None): + coords = {"x": 0, "y": 1, "z": 2} if dc is None: - dc=wx.ClientDC(self) - offset=[0,0] - scale=2 - dc.SetPen(wx.Pen(wx.Colour(100,100,100))) + dc = wx.ClientDC(self) + offset = [0, 0] + scale = 2 + dc.SetPen(wx.Pen(wx.Colour(100, 100, 100))) for i in xrange(20): - dc.DrawLine(0,i*scale*10,400,i*scale*10) - dc.DrawLine(i*scale*10,0,i*scale*10,400) - dc.SetPen(wx.Pen(wx.Colour(0,0,0))) + dc.DrawLine(0, i * scale * 10, 400, i * scale * 10) + dc.DrawLine(i * scale * 10, 0, i * scale * 10, 400) + dc.SetPen(wx.Pen(wx.Colour(0, 0, 0))) for i in xrange(4): - dc.DrawLine(0,i*scale*50,400,i*scale*50) - dc.DrawLine(i*scale*50,0,i*scale*50,400) - dc.SetBrush(wx.Brush(wx.Colour(128,255,128))) - dc.SetPen(wx.Pen(wx.Colour(128,128,128))) - t=time.time() - dcs=wx.MemoryDC() + dc.DrawLine(0, i * scale * 50, 400, i * scale * 50) + dc.DrawLine(i * scale * 50, 0, i * scale * 50, 400) + dc.SetBrush(wx.Brush(wx.Colour(128, 255, 128))) + dc.SetPen(wx.Pen(wx.Colour(128, 128, 128))) + t = time.time() + dcs = wx.MemoryDC() for m in self.parent.models.values(): - b=m.bitmap + b = m.bitmap #print b - im=b.ConvertToImage() + im = b.ConvertToImage() #print im - imgc = wx.Point( im.GetWidth()/2,im.GetHeight()/2 ) + imgc = wx.Point(im.GetWidth() / 2, im.GetHeight() / 2) #print math.radians(5*(self.i-self.previ)) - im= im.Rotate( math.radians(m.rot), imgc, 0) - bm=wx.BitmapFromImage(im) + im = im.Rotate(math.radians(m.rot), imgc, 0) + bm = wx.BitmapFromImage(im) dcs.SelectObject(bm) - bsz=bm.GetSize() - dc.Blit(scale*m.offsets[0]-bsz[0]/2,400-(scale*m.offsets[1]+bsz[1]/2),bsz[0],bsz[1],dcs,0,0,useMask=1) - #for i in m.facets:#random.sample(m.facets,min(100000,len(m.facets))): - # dc.DrawPolygon([wx.Point(offset[0]+scale*m.offsets[0]+scale*p[0],400-(offset[1]+scale*m.offsets[1]+scale*p[1])) for p in i[1]]) + bsz = bm.GetSize() + dc.Blit(scale * m.offsets[0] - bsz[0] / 2, 400 - (scale * m.offsets[1] + bsz[1] / 2), bsz[0], bsz[1], dcs, 0, 0, useMask=1) + #for i in m.facets:#random.sample(m.facets, min(100000, len(m.facets))): + # dc.DrawPolygon([wx.Point(offset[0]+scale*m.offsets[0]+scale*p[0], 400-(offset[1]+scale*m.offsets[1]+scale*p[1])) for p in i[1]]) #if(time.time()-t)>5: # break del dc #print time.time()-t #s.export() - + + class stlwin(wx.Frame): - def __init__(self,size=(800,580),callback=None,parent=None): - wx.Frame.__init__(self,parent,title="Plate building tool",size=size) - self.SetIcon(wx.Icon("plater.ico",wx.BITMAP_TYPE_ICO)) + def __init__(self, size=(800, 580), callback=None, parent=None): + wx.Frame.__init__(self, parent, title="Plate building tool", size=size) + self.SetIcon(wx.Icon("plater.ico", wx.BITMAP_TYPE_ICO)) self.mainsizer = wx.BoxSizer(wx.HORIZONTAL) - self.panel=wx.Panel(self,-1,size=(150,600),pos=(0,0)) - self.panel.SetBackgroundColour((10,10,10)) - self.l=wx.ListBox(self.panel,size=(300,180),pos=(0,30)) - self.cl=wx.Button(self.panel,label="Clear",pos=(0,205)) - self.lb=wx.Button(self.panel,label="Load",pos=(0,0)) + self.panel = wx.Panel(self, -1, size=(150, 600), pos=(0, 0)) + self.panel.SetBackgroundColour((10, 10, 10)) + self.l = wx.ListBox(self.panel, size=(300, 180), pos=(0, 30)) + self.cl = wx.Button(self.panel, label="Clear", pos=(0, 205)) + self.lb = wx.Button(self.panel, label="Load", pos=(0, 0)) if(callback is None): - self.eb=wx.Button(self.panel,label="Export",pos=(100,0)) - self.eb.Bind(wx.EVT_BUTTON,self.export) + self.eb = wx.Button(self.panel, label="Export", pos=(100, 0)) + self.eb.Bind(wx.EVT_BUTTON, self.export) else: - self.eb=wx.Button(self.panel,label="Done",pos=(100,0)) - self.eb.Bind(wx.EVT_BUTTON,lambda e:self.done(e,callback)) - self.eb=wx.Button(self.panel,label="Cancel",pos=(200,0)) - self.eb.Bind(wx.EVT_BUTTON,lambda e:self.Destroy()) - self.sb=wx.Button(self.panel,label="Snap to Z=0",pos=(00,255)) - self.cb=wx.Button(self.panel,label="Put at 100,100",pos=(0,280)) - self.db=wx.Button(self.panel,label="Delete",pos=(0,305)) - self.ab=wx.Button(self.panel,label="Auto",pos=(0,330)) - self.cl.Bind(wx.EVT_BUTTON,self.clear) - self.lb.Bind(wx.EVT_BUTTON,self.right) - self.sb.Bind(wx.EVT_BUTTON,self.snap) - self.cb.Bind(wx.EVT_BUTTON,self.center) - self.db.Bind(wx.EVT_BUTTON,self.delete) - self.ab.Bind(wx.EVT_BUTTON,self.autoplate) - self.basedir="." - self.models={} - self.SetBackgroundColour((10,10,10)) + self.eb = wx.Button(self.panel, label="Done", pos=(100, 0)) + self.eb.Bind(wx.EVT_BUTTON, lambda e: self.done(e, callback)) + self.eb = wx.Button(self.panel, label="Cancel", pos=(200, 0)) + self.eb.Bind(wx.EVT_BUTTON, lambda e: self.Destroy()) + self.sb = wx.Button(self.panel, label="Snap to Z = 0", pos=(00, 255)) + self.cb = wx.Button(self.panel, label="Put at 100, 100", pos=(0, 280)) + self.db = wx.Button(self.panel, label="Delete", pos=(0, 305)) + self.ab = wx.Button(self.panel, label="Auto", pos=(0, 330)) + self.cl.Bind(wx.EVT_BUTTON, self.clear) + self.lb.Bind(wx.EVT_BUTTON, self.right) + self.sb.Bind(wx.EVT_BUTTON, self.snap) + self.cb.Bind(wx.EVT_BUTTON, self.center) + self.db.Bind(wx.EVT_BUTTON, self.delete) + self.ab.Bind(wx.EVT_BUTTON, self.autoplate) + self.basedir = "." + self.models = {} + self.SetBackgroundColour((10, 10, 10)) self.mainsizer.Add(self.panel) #self.mainsizer.AddSpacer(10) if glview: - self.s=stlview.TestGlPanel(self,(580,580)) + self.s = stlview.TestGlPanel(self, (580, 580)) else: - self.s=showstl(self,(580,580),(0,0)) + self.s = showstl(self, (580, 580), (0, 0)) self.mainsizer.Add(self.s, 1, wx.EXPAND) self.SetSizer(self.mainsizer) #self.mainsizer.Fit(self) self.Layout() - + #self.SetClientSize(size) - - def autoplate(self,event): + + def autoplate(self, event): print "Autoplating" separation = 2 - bedsize = [200,200,100] - cursor = [0,0,0] + bedsize = [200, 200, 100] + cursor = [0, 0, 0] newrow = 0 - max = [0,0] + max = [0, 0] for i in self.models: - self.models[i].offsets[2]=-1.0*self.models[i].dims[4] + self.models[i].offsets[2] = -1.0 * self.models[i].dims[4] x = abs(self.models[i].dims[0] - self.models[i].dims[1]) y = abs(self.models[i].dims[2] - self.models[i].dims[3]) - centre = [x/2, y/2] + centre = [x / 2, y / 2] centreoffset = [self.models[i].dims[0] + centre[0], self.models[i].dims[2] + centre[1]] - if (cursor[0]+x+separation) >= bedsize[0]: + if (cursor[0] + x + separation) >= bedsize[0]: cursor[0] = 0 - cursor[1] += newrow+separation + cursor[1] += newrow + separation newrow = 0 if (newrow == 0) or (newrow < y): newrow = y @@ -280,103 +285,100 @@ class stlwin(wx.Frame): # Good job, it confused the hell out of me. self.models[i].offsets[0] = cursor[0] + centre[0] - centreoffset[0] self.models[i].offsets[1] = cursor[1] + centre[1] - centreoffset[1] - if (max[0] == 0) or (max[0] < (cursor[0]+x)): - max[0] = cursor[0]+x - if (max[1] == 0) or (max[1] < (cursor[1]+x)): - max[1] = cursor[1]+x - cursor[0] += x+separation - if (cursor[1]+y) >= bedsize[1]: + if (max[0] == 0) or (max[0] < (cursor[0] + x)): + max[0] = cursor[0] + x + if (max[1] == 0) or (max[1] < (cursor[1] + x)): + max[1] = cursor[1] + x + cursor[0] += x + separation + if (cursor[1] + y) >= bedsize[1]: print "Bed full, sorry sir :(" self.Refresh() return - centreoffset = [(bedsize[0]-max[0])/2,(bedsize[1]-max[1])/2] + centreoffset = [(bedsize[0] - max[0]) / 2, (bedsize[1] - max[1]) / 2] for i in self.models: self.models[i].offsets[0] += centreoffset[0] self.models[i].offsets[1] += centreoffset[1] self.Refresh() - - - def clear(self,event): - result = wx.MessageBox('Are you sure you want to clear the grid? All unsaved changes will be lost.', 'Clear the grid?', + + def clear(self, event): + result = wx.MessageBox('Are you sure you want to clear the grid? All unsaved changes will be lost.', 'Clear the grid?', wx.YES_NO | wx.ICON_QUESTION) if (result == 2): - self.models={} + self.models = {} self.l.Clear() self.Refresh() - - def center(self,event): - i=self.l.GetSelection() + + def center(self, event): + i = self.l.GetSelection() if i != -1: - m=self.models[self.l.GetString(i)] - m.offsets=[100,100,m.offsets[2]] + m = self.models[self.l.GetString(i)] + m.offsets = [100, 100, m.offsets[2]] self.Refresh() - def snap(self,event): - i=self.l.GetSelection() + def snap(self, event): + i = self.l.GetSelection() if i != -1: - m=self.models[self.l.GetString(i)] - m.offsets[2]=-1.0*min(m.facetsminz)[0] + m = self.models[self.l.GetString(i)] + m.offsets[2] = -1.0 * min(m.facetsminz)[0] #print m.offsets[2] self.Refresh() - def delete(self,event): - i=self.l.GetSelection() + def delete(self, event): + i = self.l.GetSelection() if i != -1: del self.models[self.l.GetString(i)] self.l.Delete(i) - self.l.Select(self.l.GetCount()-1) + self.l.Select(self.l.GetCount() - 1) self.Refresh() - def done(self,event,cb): - import os,time + def done(self, event, cb): try: os.mkdir("tempstl") except: pass - name="tempstl/"+str(int(time.time())%10000)+".stl" + name = "tempstl/" + str(int(time.time()) % 10000) + ".stl" self.writefiles(name) if cb is not None: cb(name) self.Destroy() - - - def export(self,event): - dlg=wx.FileDialog(self,"Pick file to save to",self.basedir,style=wx.FD_SAVE) + + def export(self, event): + dlg = wx.FileDialog(self, "Pick file to save to", self.basedir, style=wx.FD_SAVE) dlg.SetWildcard("STL files (;*.stl;)") if(dlg.ShowModal() == wx.ID_OK): - name=dlg.GetPath() + name = dlg.GetPath() self.writefiles(name) - - def writefiles(self,name): - sf=open(name.replace(".","_")+".scad","w") - facets=[] + + def writefiles(self, name): + sf = open(name.replace(".", "_") + ".scad", "w") + facets = [] for i in self.models.values(): - - r=i.rot - o=i.offsets - sf.write('translate([%s,%s,%s]) rotate([0,0,%s]) import_stl("%s");\n'%(str(o[0]),str(o[1]),str(o[2]),r,os.path.split(i.filename)[1])) + + r = i.rot + o = i.offsets + sf.write('translate([%s, %s, %s]) rotate([0, 0, %s]) import_stl("%s");\n' % (str(o[0]), str(o[1]), str(o[2]), r, os.path.split(i.filename)[1])) if r != 0: - i=i.rotate([0,0,r]) - if o != [0,0,0]: - i=i.translate([o[0],o[1],o[2]]) - facets+=i.facets + i = i.rotate([0, 0, r]) + if o != [0, 0, 0]: + i = i.translate([o[0], o[1], o[2]]) + facets += i.facets sf.close() - stltool.emitstl(name,facets,"plater_export") - print "wrote ",name - - def right(self,event): - dlg=wx.FileDialog(self,"Pick file to load",self.basedir,style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST) + stltool.emitstl(name, facets, "plater_export") + print "wrote ", name + + def right(self, event): + dlg = wx.FileDialog(self, "Pick file to load", self.basedir, style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) dlg.SetWildcard("STL files (;*.stl;)|*.stl|OpenSCAD files (;*.scad;)|*.scad") if(dlg.ShowModal() == wx.ID_OK): - name=dlg.GetPath() + name = dlg.GetPath() if (name.lower().endswith(".stl")): - self.load_stl(event,name) + self.load_stl(event, name) elif (name.lower().endswith(".scad")): - self.load_scad(event,name) - - def load_scad(self,event,name): - lf=open(name) - s=[i.replace("\n","").replace("\r","").replace(";","") for i in lf if "stl" in i] + self.load_scad(event, name) + + def load_scad(self, event, name): + lf = open(name) + s = [i.replace("\n", "").replace("\r", "").replace(";", "") for i in lf if "stl" in i] lf.close() for i in s: @@ -390,76 +392,75 @@ class stlwin(wx.Frame): for part in parts: if 'import' in part: stl_file = evalme(part) - - newname=os.path.split(stl_file.lower())[1] - c=1 - while newname in self.models: - newname=os.path.split(stl_file.lower())[1] - newname=newname+"(%d)"%c - c+=1 - stl_path = os.path.join(os.path.split(name)[0:len(os.path.split(stl_file))-1]) - stl_full_path = os.path.join(stl_path[0],str(stl_file)) - self.load_stl_into_model(stl_full_path,stl_file,translate_list,rotate_list[2]) - def load_stl(self,event,name): + newname = os.path.split(stl_file.lower())[1] + c = 1 + while newname in self.models: + newname = os.path.split(stl_file.lower())[1] + newname = newname + "(%d)" % c + c += 1 + stl_path = os.path.join(os.path.split(name)[0:len(os.path.split(stl_file)) - 1]) + stl_full_path = os.path.join(stl_path[0], str(stl_file)) + self.load_stl_into_model(stl_full_path, stl_file, translate_list, rotate_list[2]) + + def load_stl(self, event, name): if not(os.path.exists(name)): return path = os.path.split(name)[0] - self.basedir=path - t=time.time() + self.basedir = path + t = time.time() #print name if name.lower().endswith(".stl"): #Filter out the path, just show the STL filename. - self.load_stl_into_model(name,name) + self.load_stl_into_model(name, name) self.Refresh() #print time.time()-t - def load_stl_into_model(self,path,name,offset=[0,0,0],rotation=0,scale=[1.0,1.0,1.0]): - newname=os.path.split(name.lower())[1] - c=1 + def load_stl_into_model(self, path, name, offset=[0, 0, 0], rotation=0, scale=[1.0, 1.0, 1.0]): + newname = os.path.split(name.lower())[1] + c = 1 while newname in self.models: - newname=os.path.split(name.lower())[1] - newname=newname+"(%d)"%c - c+=1 - self.models[newname]=stltool.stl(path) - self.models[newname].offsets=offset - self.models[newname].rot=rotation - self.models[newname].scale=scale - self.models[newname].filename=name - minx,miny,minz,maxx,maxy,maxz=(10000,10000,10000,0,0,0) + newname = os.path.split(name.lower())[1] + newname = newname + "(%d)" % c + c += 1 + self.models[newname] = stltool.stl(path) + self.models[newname].offsets = offset + self.models[newname].rot = rotation + self.models[newname].scale = scale + self.models[newname].filename = name + minx, miny, minz, maxx, maxy, maxz = (10000, 10000, 10000, 0, 0, 0) for i in self.models[newname].facets: for j in i[1]: - if j[0]maxx: - maxx=j[0] - if j[1]>maxy: - maxy=j[1] - if j[2]>maxz: - maxz=j[2] - self.models[newname].dims=[minx,maxx,miny,maxy,minz,maxz] - #if minx<0: - # self.models[newname].offsets[0]=-minx - #if miny<0: - # self.models[newname].offsets[1]=-miny - self.s.drawmodel(self.models[newname],2) - - #print time.time()-t + if j[0] < minx: + minx = j[0] + if j[1] < miny: + miny = j[1] + if j[2] < minz: + minz = j[2] + if j[0] > maxx: + maxx = j[0] + if j[1] > maxy: + maxy = j[1] + if j[2] > maxz: + maxz = j[2] + self.models[newname].dims = [minx, maxx, miny, maxy, minz, maxz] + #if minx < 0: + # self.models[newname].offsets[0] = -minx + #if miny < 0: + # self.models[newname].offsets[1] = -miny + self.s.drawmodel(self.models[newname], 2) + + #print time.time() - t self.l.Append(newname) - i=self.l.GetSelection() - if i==wx.NOT_FOUND: + i = self.l.GetSelection() + if i == wx.NOT_FOUND: self.l.Select(0) - - self.l.Select(self.l.GetCount()-1) - - + + self.l.Select(self.l.GetCount() - 1) + + if __name__ == '__main__': app = wx.App(False) main = stlwin() main.Show() app.MainLoop() - diff --git a/stlview.py b/stlview.py index f530b05..c8305d4 100644 --- a/stlview.py +++ b/stlview.py @@ -1,18 +1,19 @@ #!/usr/bin/python import os -import wx,math,stltool +import math +import stltool +import wx from wx import glcanvas import time import threading - + import pyglet pyglet.options['shadow_window'] = False pyglet.options['debug_gl'] = False -from pyglet import gl from pyglet.gl import * -class GLPanel(wx.Panel): +class GLPanel(wx.Panel): '''A simple class for using OpenGL with wxPython.''' def __init__(self, parent, id, pos=wx.DefaultPosition, @@ -24,9 +25,9 @@ class GLPanel(wx.Panel): #init gl canvas data self.GLinitialized = False - attribList = (glcanvas.WX_GL_RGBA, # RGBA - glcanvas.WX_GL_DOUBLEBUFFER, # Double Buffered - glcanvas.WX_GL_DEPTH_SIZE, 24) # 24 bit + attribList = (glcanvas.WX_GL_RGBA, # RGBA + glcanvas.WX_GL_DOUBLEBUFFER, # Double Buffered + glcanvas.WX_GL_DEPTH_SIZE, 24) # 24 bit # Create the canvas self.sizer = wx.BoxSizer(wx.HORIZONTAL) self.canvas = glcanvas.GLCanvas(self, attribList=attribList) @@ -34,7 +35,7 @@ class GLPanel(wx.Panel): self.SetSizer(self.sizer) #self.sizer.Fit(self) self.Layout() - + # bind events self.canvas.Bind(wx.EVT_ERASE_BACKGROUND, self.processEraseBackgroundEvent) self.canvas.Bind(wx.EVT_SIZE, self.processSizeEvent) @@ -56,7 +57,7 @@ class GLPanel(wx.Panel): #========================================================================== def processEraseBackgroundEvent(self, event): '''Process the erase background event.''' - pass # Do nothing, to avoid flashing on MSWin + pass # Do nothing, to avoid flashing on MSWin def processSizeEvent(self, event): '''Process the resize event.''' @@ -74,15 +75,15 @@ class GLPanel(wx.Panel): def processPaintEvent(self, event): '''Process the drawing event.''' self.canvas.SetCurrent() - + # This is a 'perfect' time to initialize OpenGL ... only if we need to if not self.GLinitialized: self.OnInitGL() self.GLinitialized = True - + self.OnDraw() event.Skip() - + def Destroy(self): #clean up the pyglet OpenGL context #self.pygletcontext.destroy() @@ -95,12 +96,12 @@ class GLPanel(wx.Panel): def OnInitGL(self): '''Initialize OpenGL for use in the window.''' #create a pyglet context for this panel - self.pmat=(GLdouble * 16)() - self.mvmat=(GLdouble * 16)() + self.pmat = (GLdouble * 16)() + self.mvmat = (GLdouble * 16)() self.pygletcontext = Context(current_context) self.pygletcontext.set_current() - self.dist=1000 - self.vpmat=None + self.dist = 1000 + self.vpmat = None #normal gl init glClearColor(0, 0, 0, 1) glColor3f(1, 0, 0) @@ -108,42 +109,40 @@ class GLPanel(wx.Panel): glEnable(GL_CULL_FACE) # Uncomment this line for a wireframe view #glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) - + # Simple light setup. On Windows GL_LIGHT0 is enabled by default, - # but this is not the case on Linux or Mac, so remember to always + # but this is not the case on Linux or Mac, so remember to always # include it. glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) glEnable(GL_LIGHT1) - + # Define a simple function to create ctypes arrays of floats: def vec(*args): return (GLfloat * len(args))(*args) - + glLightfv(GL_LIGHT0, GL_POSITION, vec(.5, .5, 1, 0)) glLightfv(GL_LIGHT0, GL_SPECULAR, vec(.5, .5, 1, 1)) glLightfv(GL_LIGHT0, GL_DIFFUSE, vec(1, 1, 1, 1)) glLightfv(GL_LIGHT1, GL_POSITION, vec(1, 0, .5, 0)) glLightfv(GL_LIGHT1, GL_DIFFUSE, vec(.5, .5, .5, 1)) glLightfv(GL_LIGHT1, GL_SPECULAR, vec(1, 1, 1, 1)) - + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, vec(0.5, 0, 0.3, 1)) glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, vec(1, 1, 1, 1)) glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 50) - glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, vec(0,0.1,0,0.9)) + glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, vec(0, 0.1, 0, 0.9)) #create objects to draw #self.create_objects() - - - + def OnReshape(self, width, height): '''Reshape the OpenGL viewport based on the dimensions of the window.''' - + if not self.GLinitialized: self.OnInitGL() self.GLinitialized = True - self.pmat=(GLdouble * 16)() - self.mvmat=(GLdouble * 16)() + self.pmat = (GLdouble * 16)() + self.mvmat = (GLdouble * 16)() glViewport(0, 0, width, height) glMatrixMode(GL_PROJECTION) glLoadIdentity() @@ -151,43 +150,43 @@ class GLPanel(wx.Panel): glMatrixMode(GL_MODELVIEW) glLoadIdentity() #pyglet stuff - self.vpmat=(GLint * 4)(0,0,*list(self.GetClientSize())) - glGetDoublev(GL_PROJECTION_MATRIX,self.pmat) - glGetDoublev(GL_MODELVIEW_MATRIX,self.mvmat) + self.vpmat = (GLint * 4)(0, 0, *list(self.GetClientSize())) + glGetDoublev(GL_PROJECTION_MATRIX, self.pmat) + glGetDoublev(GL_MODELVIEW_MATRIX, self.mvmat) #glMatrixMode(GL_PROJECTION) - - + # Wrap text to the width of the window if self.GLinitialized: self.pygletcontext.set_current() self.update_object_resize() - + def OnDraw(self, *args, **kwargs): """Draw the window.""" #clear the context self.canvas.SetCurrent() self.pygletcontext.set_current() - glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) #draw objects self.draw_objects() #update screen self.SwapBuffers() - + #========================================================================== # To be implemented by a sub class #========================================================================== def create_objects(self): '''create opengl objects when opengl is initialized''' pass - + def update_object_resize(self): '''called when the window recieves only if opengl is initialized''' pass - + def draw_objects(self): '''called in the middle of ondraw after the buffer has been cleared''' pass - + + class stlview(object): def __init__(self, facets, batch): # Create the vertex and normal arrays. @@ -200,234 +199,249 @@ class stlview(object): normals.extend(i[0]) # Create a list of triangle indices. - indices = range(3*len(facets))#[[3*i,3*i+1,3*i+2] for i in xrange(len(facets))] + indices = range(3 * len(facets)) # [[3*i,3*i+1,3*i+2] for i in xrange(len(facets))] #print indices[:10] - self.vertex_list = batch.add_indexed(len(vertices)//3, + self.vertex_list = batch.add_indexed(len(vertices) // 3, GL_TRIANGLES, - None,#group, + None, # group, indices, ('v3f/static', vertices), ('n3f/static', normals)) - + def delete(self): self.vertex_list.delete() -def vdiff(v,o): - return [x[0]-x[1] for x in zip(v,o)] - + +def vdiff(v, o): + return [x[0] - x[1] for x in zip(v, o)] + class gcview(object): def __init__(self, lines, batch, w=0.5, h=0.5): # Create the vertex and normal arrays. vertices = [] normals = [] - self.prev=[0.001,0.001,0.001,0.001] - self.fline=1 - self.vlists=[] - self.layers={} - t0=time.time() - lines=[self.transform(i) for i in lines] - lines=[i for i in lines if i is not None] - print "transformed lines in %fs"%(time.time()-t0) - t0=time.time() - layertemp={} - lasth=None - counter=0 - if len(lines)==0: + self.prev = [0.001, 0.001, 0.001, 0.001] + self.fline = 1 + self.vlists = [] + self.layers = {} + t0 = time.time() + lines = [self.transform(i) for i in lines] + lines = [i for i in lines if i is not None] + print "transformed lines in %fs" % (time.time() - t0) + t0 = time.time() + layertemp = {} + lasth = None + counter = 0 + if len(lines) == 0: return for i in lines: - counter+=1 + counter += 1 if i[0][2] not in layertemp: - layertemp[i[0][2]]=[[],[]] + layertemp[i[0][2]] = [[], []] if lasth is not None: - self.layers[lasth]=pyglet.graphics.Batch() - lt=layertemp[lasth][0] - indices = range(len(layertemp[lasth][0])//3)#[[3*i,3*i+1,3*i+2] for i in xrange(len(facets))] - self.vlists.append(self.layers[lasth].add_indexed(len(layertemp[lasth][0])//3, + self.layers[lasth] = pyglet.graphics.Batch() + lt = layertemp[lasth][0] + indices = range(len(layertemp[lasth][0]) // 3) # [[3*i,3*i+1,3*i+2] for i in xrange(len(facets))] + self.vlists.append(self.layers[lasth].add_indexed(len(layertemp[lasth][0]) // 3, GL_TRIANGLES, - None,#group, + None, # group, indices, ('v3f/static', layertemp[lasth][0]), ('n3f/static', layertemp[lasth][1]))) - - lasth=i[0][2] - - spoints,epoints,S,E=self.genline(i,h,w) - - verticestoadd=[[spoints[(j+1)%8],epoints[(j)%8],spoints[j],epoints[j],spoints[(j+1)%8],epoints[(j+1)%8]] for j in xrange(8)] - normalstoadd=[map(vdiff,v,[S,E,S,E,S,E]) for v in verticestoadd] - v1=[] - map(v1.extend,verticestoadd) - v2=[] - map(v2.extend,v1) - n1=[] - map(n1.extend,normalstoadd) - n2=[] - map(n2.extend,n1) - - layertemp[i[0][2]][0]+=v2 - vertices+=v2 - layertemp[i[0][2]][1]+=n2 - normals+=n2 - print "appended lines in %fs"%(time.time()-t0) - t0=time.time() - + + lasth = i[0][2] + + spoints, epoints, S, E = self.genline(i, h, w) + + verticestoadd = [[ + spoints[(j + 1) % 8], + epoints[(j) % 8], + spoints[j], + epoints[j], + spoints[(j + 1) % 8], + epoints[(j + 1) % 8] + ] for j in xrange(8)] + normalstoadd = [map(vdiff, v, [S, E, S, E, S, E]) for v in verticestoadd] + v1 = [] + map(v1.extend, verticestoadd) + v2 = [] + map(v2.extend, v1) + n1 = [] + map(n1.extend, normalstoadd) + n2 = [] + map(n2.extend, n1) + + layertemp[i[0][2]][0] += v2 + vertices += v2 + layertemp[i[0][2]][1] += n2 + normals += n2 + print "appended lines in %fs" % (time.time() - t0) + t0 = time.time() + # Create a list of triangle indices. - indices = range(3*16*len(lines))#[[3*i,3*i+1,3*i+2] for i in xrange(len(facets))] - self.vlists.append(batch.add_indexed(len(vertices)//3, + indices = range(3 * 16 * len(lines)) # [[3*i,3*i+1,3*i+2] for i in xrange(len(facets))] + self.vlists.append(batch.add_indexed(len(vertices) // 3, GL_TRIANGLES, - None,#group, + None, # group, indices, ('v3f/static', vertices), ('n3f/static', normals))) if lasth is not None: - self.layers[lasth]=pyglet.graphics.Batch() - indices = range(len(layertemp[lasth][0]))#[[3*i,3*i+1,3*i+2] for i in xrange(len(facets))] - self.vlists.append(self.layers[lasth].add_indexed(len(layertemp[lasth][0])//3, + self.layers[lasth] = pyglet.graphics.Batch() + indices = range(len(layertemp[lasth][0])) # [[3*i,3*i+1,3*i+2] for i in xrange(len(facets))] + self.vlists.append(self.layers[lasth].add_indexed(len(layertemp[lasth][0]) // 3, GL_TRIANGLES, - None,#group, + None, # group, indices, ('v3f/static', layertemp[lasth][0]), ('n3f/static', layertemp[lasth][1]))) - - - def genline(self,i,h,w): - S=i[0][:3] - E=i[1][:3] - v=map(lambda x,y:x-y,E,S) - vlen=math.sqrt(float(sum(map(lambda a:a*a, v[:3])))) - - if vlen==0: - vlen=0.01 - sq2=math.sqrt(2.0)/2.0 - htw=float(h)/w - d=w/2.0 - if i[1][3]==i[0][3]: - d=0.05 - points=[[d,0,0], - [sq2*d,sq2*d,0], - [0,d,0], - [-sq2*d,sq2*d,0], - [-d,0,0], - [-sq2*d,-sq2*d,0], - [0,-d,0], - [sq2*d,-sq2*d,0] - ] - axis=stltool.cross([0,0,1],v) - alen=math.sqrt(float(sum(map(lambda a:a*a, v[:3])))) - if alen>0: - axis=map(lambda m:m/alen,axis) - angle=math.acos(v[2]/vlen) - def vrot(v,axis,angle): - kxv=stltool.cross(axis,v) - kdv=sum(map(lambda x,y:x*y,axis,v)) - return map(lambda x,y,z:x*math.cos(angle)+y*math.sin(angle)+z*kdv*(1.0-math.cos(angle)),v,kxv,axis) - points=map(lambda x:vrot(x,axis,angle),points) - points=map(lambda x:[x[0],x[1],htw*x[2]],points) - - def vadd(v,o): - return map(sum,zip(v,o)) - spoints=map(lambda x:vadd(S,x),points) - epoints=map(lambda x:vadd(E,x),points) - return spoints,epoints,S,E - - def transform(self,line): - line=line.split(";")[0] - cur=self.prev[:] - if len(line)>0: + + def genline(self, i, h, w): + S = i[0][:3] + E = i[1][:3] + v = map(lambda x, y: x - y, E, S) + vlen = math.sqrt(float(sum(map(lambda a: a * a, v[:3])))) + + if vlen == 0: + vlen = 0.01 + sq2 = math.sqrt(2.0) / 2.0 + htw = float(h) / w + d = w / 2.0 + if i[1][3] == i[0][3]: + d = 0.05 + points = [[d, 0, 0], + [sq2 * d, sq2 * d, 0], + [0, d, 0], + [-sq2 * d, sq2 * d, 0], + [-d, 0, 0], + [-sq2 * d, -sq2 * d, 0], + [0, -d, 0], + [sq2 * d, -sq2 * d, 0] + ] + axis = stltool.cross([0, 0, 1], v) + alen = math.sqrt(float(sum(map(lambda a: a * a, v[:3])))) + if alen > 0: + axis = map(lambda m: m / alen, axis) + angle = math.acos(v[2] / vlen) + + def vrot(v, axis, angle): + kxv = stltool.cross(axis, v) + kdv = sum(map(lambda x, y: x * y, axis, v)) + return map(lambda x, y, z: x * math.cos(angle) + y * math.sin(angle) + z * kdv * (1.0 - math.cos(angle)), v, kxv, axis) + + points = map(lambda x: vrot(x, axis, angle), points) + points = map(lambda x: [x[0], x[1], htw * x[2]], points) + + def vadd(v, o): + return map(sum, zip(v, o)) + spoints = map(lambda x: vadd(S, x), points) + epoints = map(lambda x: vadd(E, x), points) + return spoints, epoints, S, E + + def transform(self, line): + line = line.split(";")[0] + cur = self.prev[:] + if len(line) > 0: if "G1" in line or "G0" in line or "G92" in line: if("X" in line): - cur[0]=float(line.split("X")[1].split(" ")[0]) + cur[0] = float(line.split("X")[1].split(" ")[0]) if("Y" in line): - cur[1]=float(line.split("Y")[1].split(" ")[0]) + cur[1] = float(line.split("Y")[1].split(" ")[0]) if("Z" in line): - cur[2]=float(line.split("Z")[1].split(" ")[0]) + cur[2] = float(line.split("Z")[1].split(" ")[0]) if("E" in line): - cur[3]=float(line.split("E")[1].split(" ")[0]) - if self.prev==cur: + cur[3] = float(line.split("E")[1].split(" ")[0]) + if self.prev == cur: return None if self.fline or "G92" in line: - self.prev=cur - self.fline=0 + self.prev = cur + self.fline = 0 return None else: - r=[self.prev,cur] - self.prev=cur + r = [self.prev, cur] + self.prev = cur return r - - + def delete(self): for i in self.vlists: i.delete() - self.vlists=[] + self.vlists = [] def trackball(p1x, p1y, p2x, p2y, r): - TRACKBALLSIZE=r + TRACKBALLSIZE = r #float a[3]; /* Axis of rotation */ #float phi; /* how much to rotate about axis */ #float p1[3], p2[3], d[3]; #float t; if (p1x == p2x and p1y == p2y): - return [0.0,0.0,0.0,1.0] + return [0.0, 0.0, 0.0, 1.0] - p1=[p1x,p1y,project_to_sphere(TRACKBALLSIZE,p1x,p1y)] - p2=[p2x,p2y,project_to_sphere(TRACKBALLSIZE,p2x,p2y)] - a=stltool.cross(p2,p1) - - d=map(lambda x,y:x-y,p1,p2) - t = math.sqrt(sum(map(lambda x:x*x, d))) / (2.0*TRACKBALLSIZE) + p1 = [p1x, p1y, project_to_sphere(TRACKBALLSIZE, p1x, p1y)] + p2 = [p2x, p2y, project_to_sphere(TRACKBALLSIZE, p2x, p2y)] + a = stltool.cross(p2, p1) - if (t > 1.0): t = 1.0 - if (t < -1.0): t = -1.0 + d = map(lambda x, y: x - y, p1, p2) + t = math.sqrt(sum(map(lambda x: x * x, d))) / (2.0 * TRACKBALLSIZE) + + if (t > 1.0): + t = 1.0 + if (t < -1.0): + t = -1.0 phi = 2.0 * math.asin(t) - return axis_to_quat(a,phi) + return axis_to_quat(a, phi) + def vec(*args): return (GLfloat * len(args))(*args) - -def axis_to_quat(a,phi): + + +def axis_to_quat(a, phi): #print a, phi - lena=math.sqrt(sum(map(lambda x:x*x, a))) - q=map(lambda x:x*(1/lena),a) - q=map(lambda x:x*math.sin(phi/2.0),q) - q.append(math.cos(phi/2.0)) + lena = math.sqrt(sum(map(lambda x: x * x, a))) + q = map(lambda x: x * (1 / lena), a) + q = map(lambda x: x * math.sin(phi / 2.0), q) + q.append(math.cos(phi / 2.0)) return q - + + def build_rotmatrix(q): - m=(GLdouble * 16)() + m = (GLdouble * 16)() m[0] = 1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2]) - m[1] = 2.0 * (q[0] * q[1] - q[2] * q[3]); - m[2] = 2.0 * (q[2] * q[0] + q[1] * q[3]); - m[3] = 0.0; + m[1] = 2.0 * (q[0] * q[1] - q[2] * q[3]) + m[2] = 2.0 * (q[2] * q[0] + q[1] * q[3]) + m[3] = 0.0 - m[4] = 2.0 * (q[0] * q[1] + q[2] * q[3]); - m[5]= 1.0 - 2.0 * (q[2] * q[2] + q[0] * q[0]); - m[6] = 2.0 * (q[1] * q[2] - q[0] * q[3]); - m[7] = 0.0; + m[4] = 2.0 * (q[0] * q[1] + q[2] * q[3]) + m[5] = 1.0 - 2.0 * (q[2] * q[2] + q[0] * q[0]) + m[6] = 2.0 * (q[1] * q[2] - q[0] * q[3]) + m[7] = 0.0 - m[8] = 2.0 * (q[2] * q[0] - q[1] * q[3]); - m[9] = 2.0 * (q[1] * q[2] + q[0] * q[3]); - m[10] = 1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0]); - m[11] = 0.0; + m[8] = 2.0 * (q[2] * q[0] - q[1] * q[3]) + m[9] = 2.0 * (q[1] * q[2] + q[0] * q[3]) + m[10] = 1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0]) + m[11] = 0.0 - m[12] = 0.0; - m[13] = 0.0; - m[14] = 0.0; - m[15] = 1.0; + m[12] = 0.0 + m[13] = 0.0 + m[14] = 0.0 + m[15] = 1.0 return m + def project_to_sphere(r, x, y): - d = math.sqrt(x*x + y*y) + d = math.sqrt(x * x + y * y) if (d < r * 0.70710678118654752440): - return math.sqrt(r*r - d*d) + return math.sqrt(r * r - d * d) else: t = r / 1.41421356237309504880 - return t*t / d - -def mulquat(q1,rq): + return t * t / d + + +def mulquat(q1, rq): return [q1[3] * rq[0] + q1[0] * rq[3] + q1[1] * rq[2] - q1[2] * rq[1], q1[3] * rq[1] + q1[1] * rq[3] + q1[2] * rq[0] - q1[0] * rq[2], q1[3] * rq[2] + q1[2] * rq[3] + q1[0] * rq[1] - q1[1] * rq[0], @@ -435,40 +449,39 @@ def mulquat(q1,rq): class TestGlPanel(GLPanel): - - def __init__(self, parent, size,id=wx.ID_ANY,): + + def __init__(self, parent, size, id=wx.ID_ANY): super(TestGlPanel, self).__init__(parent, id, wx.DefaultPosition, size, 0) - self.batches=[] - self.rot=0 - self.canvas.Bind(wx.EVT_MOUSE_EVENTS,self.move) - self.canvas.Bind(wx.EVT_LEFT_DCLICK,self.double) - self.initialized=1 - self.canvas.Bind(wx.EVT_MOUSEWHEEL,self.wheel) - self.parent=parent - self.initpos=None - self.dist=200 - self.bedsize=[200,200] - self.transv=[0, 0, -self.dist] - self.basequat=[0,0,0,1] + self.batches = [] + self.rot = 0 + self.canvas.Bind(wx.EVT_MOUSE_EVENTS, self.move) + self.canvas.Bind(wx.EVT_LEFT_DCLICK, self.double) + self.initialized = 1 + self.canvas.Bind(wx.EVT_MOUSEWHEEL, self.wheel) + self.parent = parent + self.initpos = None + self.dist = 200 + self.bedsize = [200, 200] + self.transv = [0, 0, -self.dist] + self.basequat = [0, 0, 0, 1] wx.CallAfter(self.forceresize) - self.mousepos=[0,0] - + self.mousepos = [0, 0] + def double(self, event): - p=event.GetPositionTuple() - sz=self.GetClientSize() - v=map(lambda m,w,b:b*m/w,p,sz,self.bedsize) - v[1]=self.bedsize[1]-v[1] - v+=[300] + p = event.GetPositionTuple() + sz = self.GetClientSize() + v = map(lambda m, w, b: b * m / w, p, sz, self.bedsize) + v[1] = self.bedsize[1] - v[1] + v += [300] print v - self.add_file("../prusa/metric-prusa/x-end-idler.stl",v) - - + self.add_file("../prusa/metric-prusa/x-end-idler.stl", v) + def forceresize(self): - self.SetClientSize((self.GetClientSize()[0],self.GetClientSize()[1]+1)) - self.SetClientSize((self.GetClientSize()[0],self.GetClientSize()[1]-1)) + self.SetClientSize((self.GetClientSize()[0], self.GetClientSize()[1] + 1)) + self.SetClientSize((self.GetClientSize()[0], self.GetClientSize()[1] - 1)) threading.Thread(target=self.update).start() - self.initialized=0 - + self.initialized = 0 + def move_shape(self, delta): """moves shape (selected in l, which is list ListBox of shapes) by an offset specified in tuple delta. @@ -497,8 +510,8 @@ class TestGlPanel(GLPanel): with shift move viewport """ if event.Dragging() and event.LeftIsDown(): - if self.initpos==None: - self.initpos=event.GetPositionTuple() + if self.initpos == None: + self.initpos = event.GetPositionTuple() else: if not event.ShiftDown(): currentpos = event.GetPositionTuple() @@ -507,70 +520,69 @@ class TestGlPanel(GLPanel): -(currentpos[1] - self.initpos[1]) ) self.move_shape(delta) - self.initpos=None + self.initpos = None return #print self.initpos - p1=self.initpos - self.initpos=None - p2=event.GetPositionTuple() - sz=self.GetClientSize() - p1x=(float(p1[0])-sz[0]/2)/(sz[0]/2) - p1y=-(float(p1[1])-sz[1]/2)/(sz[1]/2) - p2x=(float(p2[0])-sz[0]/2)/(sz[0]/2) - p2y=-(float(p2[1])-sz[1]/2)/(sz[1]/2) + p1 = self.initpos + self.initpos = None + p2 = event.GetPositionTuple() + sz = self.GetClientSize() + p1x = (float(p1[0]) - sz[0] / 2) / (sz[0] / 2) + p1y = -(float(p1[1]) - sz[1] / 2) / (sz[1] / 2) + p2x = (float(p2[0]) - sz[0] / 2) / (sz[0] / 2) + p2y = -(float(p2[1]) - sz[1] / 2) / (sz[1] / 2) #print p1x,p1y,p2x,p2y - quat=trackball(p1x, p1y, p2x, p2y, -self.transv[2]/250.0) + quat = trackball(p1x, p1y, p2x, p2y, -self.transv[2] / 250.0) if self.rot: - self.basequat=mulquat(self.basequat,quat) + self.basequat = mulquat(self.basequat, quat) #else: - glGetDoublev(GL_MODELVIEW_MATRIX,self.mvmat) - #self.basequat=quatx - mat=build_rotmatrix(self.basequat) + glGetDoublev(GL_MODELVIEW_MATRIX, self.mvmat) + #self.basequat = quatx + mat = build_rotmatrix(self.basequat) glLoadIdentity() - glTranslatef(self.transv[0],self.transv[1],0) - glTranslatef(0,0,self.transv[2]) + glTranslatef(self.transv[0], self.transv[1], 0) + glTranslatef(0, 0, self.transv[2]) glMultMatrixd(mat) - glGetDoublev(GL_MODELVIEW_MATRIX,self.mvmat) - self.rot=1 - + glGetDoublev(GL_MODELVIEW_MATRIX, self.mvmat) + self.rot = 1 + elif event.ButtonUp(wx.MOUSE_BTN_LEFT): if self.initpos is not None: - self.initpos=None + self.initpos = None elif event.ButtonUp(wx.MOUSE_BTN_RIGHT): if self.initpos is not None: - self.initpos=None - - + self.initpos = None + elif event.Dragging() and event.RightIsDown() and event.ShiftDown(): if self.initpos is None: - self.initpos=event.GetPositionTuple() + self.initpos = event.GetPositionTuple() else: - p1=self.initpos - p2=event.GetPositionTuple() - sz=self.GetClientSize() - p1=list(p1) - p2=list(p2) - p1[1]*=-1 - p2[1]*=-1 - - self.transv=map(lambda x,y,z,c:c-self.dist*(x-y)/z, list(p1)+[0], list(p2)+[0], list(sz)+[1], self.transv) - + p1 = self.initpos + p2 = event.GetPositionTuple() + sz = self.GetClientSize() + p1 = list(p1) + p2 = list(p2) + p1[1] *= -1 + p2[1] *= -1 + + self.transv = map(lambda x, y, z, c: c - self.dist * (x - y) / z, list(p1) + [0], list(p2) + [0], list(sz) + [1], self.transv) + glLoadIdentity() - glTranslatef(self.transv[0],self.transv[1],0) - glTranslatef(0,0,self.transv[2]) + glTranslatef(self.transv[0], self.transv[1], 0) + glTranslatef(0, 0, self.transv[2]) if(self.rot): glMultMatrixd(build_rotmatrix(self.basequat)) - glGetDoublev(GL_MODELVIEW_MATRIX,self.mvmat) - self.rot=1 - self.initpos=None + glGetDoublev(GL_MODELVIEW_MATRIX, self.mvmat) + self.rot = 1 + self.initpos = None else: #mouse is moving without a button press - p=event.GetPositionTuple() - sz=self.GetClientSize() - v=map(lambda m,w,b:b*m/w,p,sz,self.bedsize) - v[1]=self.bedsize[1]-v[1] - self.mousepos=v - + p = event.GetPositionTuple() + sz = self.GetClientSize() + v = map(lambda m, w, b: b * m / w, p, sz, self.bedsize) + v[1] = self.bedsize[1] - v[1] + self.mousepos = v + def rotate_shape(self, angle): """rotates acive shape positive angle is clockwise @@ -582,40 +594,40 @@ class TestGlPanel(GLPanel): model = self.parent.models[name] model.rot += angle - def wheel(self,event): + def wheel(self, event): """react to mouse wheel actions: rotate object with shift zoom viewport """ - z=event.GetWheelRotation() - angle=10 + z = event.GetWheelRotation() + angle = 10 if not event.ShiftDown(): - i=self.parent.l.GetSelection() - - if i<0: + i = self.parent.l.GetSelection() + + if i < 0: try: self.parent.setlayerindex(z) except: pass return - + if z > 0: - self.rotate_shape(angle/2) + self.rotate_shape(angle / 2) else: - self.rotate_shape(-angle/2) + self.rotate_shape(-angle / 2) return if z > 0: - self.transv[2]+=angle + self.transv[2] += angle else: - self.transv[2]-=angle - + self.transv[2] -= angle + glLoadIdentity() glTranslatef(*self.transv) if(self.rot): glMultMatrixd(build_rotmatrix(self.basequat)) - glGetDoublev(GL_MODELVIEW_MATRIX,self.mvmat) - self.rot=1 - + glGetDoublev(GL_MODELVIEW_MATRIX, self.mvmat) + self.rot = 1 + def keypress(self, event): """gets keypress events and moves/rotates acive shape""" keycode = event.GetKeyCode() @@ -644,67 +656,65 @@ class TestGlPanel(GLPanel): if keycode == 93: self.rotate_shape(angle) event.Skip() - + def update(self): while(1): - dt=0.05 + dt = 0.05 time.sleep(0.05) try: wx.CallAfter(self.Refresh) except: return - - def anim(self,obj): - g=50*9.8 - v=20 - dt=0.05 - basepos=obj.offsets[2] - obj.offsets[2]+=obj.animoffset - while obj.offsets[2]>-1: + + def anim(self, obj): + g = 50 * 9.8 + v = 20 + dt = 0.05 + basepos = obj.offsets[2] + obj.offsets[2] += obj.animoffset + while obj.offsets[2] > -1: time.sleep(dt) - obj.offsets[2]-=v*dt - v+=g*dt - if(obj.offsets[2]<0): - obj.scale[2]*=1-3*dt + obj.offsets[2] -= v * dt + v += g * dt + if(obj.offsets[2] < 0): + obj.scale[2] *= 1 - 3 * dt #return - v=v/4 - while obj.offsets[2] 0 and self.modelindex < len(mlk) - 1: + self.modelindex += 1 + if z < 0 and self.modelindex > 0: + self.modelindex -= 1 + m.curlayer = mlk[self.modelindex] + wx.CallAfter(self.SetTitle, "Gcode view, shift to move. Layer %d, Z = %f" % (self.modelindex, m.curlayer)) - - def setlayerindex(self,z): - m=self.models[""] - mlk=sorted(m.gc.layers.keys()) - if z>0 and self.modelindex0: - self.modelindex-=1 - m.curlayer=mlk[self.modelindex] - wx.CallAfter(self.SetTitle,"Gcode view, shift to move. Layer %d, Z=%f"%(self.modelindex,m.curlayer)) - def main(): app = wx.App(redirect=False) - frame = GCFrame(None, wx.ID_ANY, 'Gcode view, shift to move view, mousewheel to set layer', size=(400,400)) + frame = GCFrame(None, wx.ID_ANY, 'Gcode view, shift to move view, mousewheel to set layer', size=(400, 400)) frame.addfile(list(open("carriage dump_export.gcode"))) - #frame = wx.Frame(None, -1, "GL Window", size=(400,400)) + #frame = wx.Frame(None, -1, "GL Window", size=(400, 400)) #panel = TestGlPanel(frame) #frame.Show(True) #app.MainLoop() app.Destroy() - -if __name__=="__main__": + +if __name__ == "__main__": import cProfile print cProfile.run("main()")