Duane Johnson 2011-11-11 10:23:52 -06:00
commit c113e2bffc
3 changed files with 224 additions and 103 deletions

112
gviz.py
View File

@ -58,12 +58,14 @@ class gviz(wx.Panel):
self.size=size
self.bedsize=bedsize
self.grid=grid
self.lastpos=[0,0,0,0,0]
self.lastpos=[0,0,0,0,0,0,0]
self.hilightpos=self.lastpos[:]
self.Bind(wx.EVT_PAINT,self.paint)
self.Bind(wx.EVT_SIZE,lambda *e:(wx.CallAfter(self.repaint),wx.CallAfter(self.Refresh)))
self.lines={}
self.pens={}
self.arcs={}
self.arcpens={}
self.layers=[]
self.layerindex=0
self.filament_width=extrusion_width # set it to 0 to disable scaling lines with zoom
@ -71,17 +73,19 @@ class gviz(wx.Panel):
penwidth = max(1.0,self.filament_width*((self.scale[0]+self.scale[1])/2.0))
self.translate=[0.0,0.0]
self.mainpen=wx.Pen(wx.Colour(0,0,0),penwidth)
self.arcpen=wx.Pen(wx.Colour(255,0,0),penwidth)
self.travelpen=wx.Pen(wx.Colour(10,80,80),penwidth)
self.hlpen=wx.Pen(wx.Colour(200,50,50),penwidth)
self.fades=[wx.Pen(wx.Colour(250-0.6**i*100,250-0.6**i*100,200-0.4**i*50),penwidth) for i in xrange(6)]
self.penslist=[self.mainpen,self.travelpen,self.hlpen]+self.fades
self.showall=0
self.hilight=[]
self.hilightarcs=[]
self.dirty=1
self.blitmap=wx.EmptyBitmap(self.GetClientSize()[0],self.GetClientSize()[1],-1)
def clear(self):
self.lastpos=[0,0,0,0,0]
self.lastpos=[0,0,0,0,0,0,0]
self.lines={}
self.pens={}
self.layers=[]
@ -143,27 +147,48 @@ class gviz(wx.Panel):
dc.SetBrush(wx.Brush((0,255,0)))
if len(self.layers):
dc.DrawRectangle(self.size[0]-14,(1.0-(1.0*(self.layerindex+1))/len(self.layers))*self.size[1],13,self.size[1]-1)
def scaler(x):
return (self.scale[0]*x[0]+self.translate[0],
self.scale[1]*x[1]+self.translate[1],
self.scale[0]*x[2]+self.translate[0],
self.scale[1]*x[3]+self.translate[1],)
def _drawlines(lines,pens):
def _scaler(x):
return (self.scale[0]*x[0]+self.translate[0],
self.scale[1]*x[1]+self.translate[1],
self.scale[0]*x[2]+self.translate[0],
self.scale[1]*x[3]+self.translate[1],)
scaled_lines = map(_scaler,lines)
dc.DrawLineList(scaled_lines, pens)
def _drawarcs(arcs,pens):
def _scaler(x):
return (self.scale[0]*x[0]+self.translate[0],
self.scale[1]*x[1]+self.translate[1],
self.scale[0]*x[2]+self.translate[0],
self.scale[1]*x[3]+self.translate[1],
self.scale[0]*x[4]+self.translate[0],
self.scale[1]*x[5]+self.translate[1],)
scaled_arcs = map(_scaler,arcs)
for i in range(len(scaled_arcs)):
dc.SetPen(pens[i] if type(pens).__name__ == 'list' else pens)
dc.SetBrush(wx.TRANSPARENT_BRUSH)
dc.DrawArc(*scaled_arcs[i])
if self.showall:
l=[]
for i in self.layers:
dc.DrawLineList(l,self.fades[0])
l=map(scaler,self.lines[i])
dc.DrawLineList(l,self.pens[i])
_drawlines(self.lines[i], self.pens[i])
_drawarcs(self.arcs[i], self.arcpens[i])
return
if self.layerindex<len(self.layers) and self.layers[self.layerindex] in self.lines.keys():
for layer_i in xrange(max(0,self.layerindex-6),self.layerindex):
#print i, self.layerindex, self.layerindex-i
l=map(scaler,self.lines[self.layers[layer_i]])
dc.DrawLineList(l,self.fades[self.layerindex-layer_i-1])
l=map(scaler,self.lines[self.layers[self.layerindex]])
dc.DrawLineList(l,self.pens[self.layers[self.layerindex]])
l=map(scaler,self.hilight)
dc.DrawLineList(l,self.hlpen)
_drawlines(self.lines[self.layers[layer_i]], self.fades[self.layerindex-layer_i-1])
_drawarcs(self.arcs[self.layers[layer_i]], self.fades[self.layerindex-layer_i-1])
_drawlines(self.lines[self.layers[self.layerindex]], self.pens[self.layers[self.layerindex]])
_drawarcs(self.arcs[self.layers[self.layerindex]], self.arcpens[self.layers[self.layerindex]])
_drawlines(self.hilight, self.hlpen)
_drawarcs(self.hilightarcs, self.hlpen)
dc.SelectObject(wx.NullBitmap)
def paint(self,event):
@ -178,8 +203,11 @@ class gviz(wx.Panel):
def addgcode(self,gcode="M105",hilight=0):
gcode=gcode.split("*")[0]
gcode=gcode.split(";")[0]
if "g1" in gcode.lower():
gcode=gcode.lower().split()
gcode = gcode.lower().strip().split()
if len(gcode) == 0:
return
def _readgcode():
target=self.lastpos[:]
if hilight:
target=self.hilightpos[:]
@ -194,23 +222,53 @@ class gviz(wx.Panel):
target[3]=float(i[1:])
elif i[0]=="f":
target[4]=float(i[1:])
#draw line
elif i[0]=="i":
target[5]=float(i[1:])
elif i[0]=="j":
target[6]=float(i[1:])
if not hilight:
if not target[2] in self.lines.keys():
self.lines[target[2]]=[]
self.pens[target[2]]=[]
self.arcs[target[2]]=[]
self.arcpens[target[2]]=[]
self.layers+=[target[2]]
self.lines[target[2]]+=[(self.lastpos[0],self.bedsize[1]-self.lastpos[1],target[0],self.bedsize[1]-target[1])]
if target[3] != self.lastpos[3]:
self.pens[target[2]]+=[self.mainpen]
else:
self.pens[target[2]]+=[self.travelpen]
self.lastpos=target
return target
def _y(y):
return self.bedsize[1]-y
start_pos = self.hilightpos[:] if hilight else self.lastpos[:]
if gcode[0] == "g1":
target = _readgcode()
line = [ start_pos[0], _y(start_pos[1]), target[0], _y(target[1]) ]
if not hilight:
self.lines[ target[2] ] += [line]
self.pens[ target[2] ] += [self.mainpen if target[3] != self.lastpos[3] else self.travelpen]
self.lastpos = target
else:
self.hilight+=[(self.hilightpos[0],self.bedsize[1]-self.hilightpos[1],target[0],self.bedsize[1]-target[1])]
self.hilightpos=target
self.dirty=1
self.hilight += line
self.hilightpos = target
self.dirty = 1
if gcode[0] in [ "g2", "g3" ]:
target = _readgcode()
arc = []
arc += [ start_pos[0], _y(start_pos[1]) ]
arc += [ target[0], _y(target[1]) ]
arc += [ start_pos[0] + target[5], _y(start_pos[1] + target[6]) ] # center
if gcode[0] == "g2": # clockwise, reverse endpoints
arc[0], arc[1], arc[2], arc[3] = arc[2], arc[3], arc[0], arc[1]
if not hilight:
self.arcs[ target[2] ] += [arc]
self.arcpens[ target[2] ] += [self.arcpen]
self.lastpos = target
else:
self.hilightarcs += arc
self.hilightpos = target
self.dirty = 1
if __name__ == '__main__':
app = wx.App(False)

190
plater.py
View File

@ -2,6 +2,12 @@
import wx,time,random,threading,os,math
import stltool
def translate(l): return l
def rotate(l): return l
def import_stl(s): return s
class stlwrap:
def __init__(self,obj,name=None):
self.obj=obj
@ -16,12 +22,16 @@ class stlwrap:
class showstl(wx.Window):
def __init__(self,parent,size,pos):
wx.Window.__init__(self,parent,size=size,pos=pos)
self.l=wx.ListBox(self,size=(300,130),pos=(0,size[1]-130))
self.l=wx.ListBox(self,size=(300,180),pos=(0,size[1]-180))
self.cl=wx.Button(self,label="Clear",pos=(300,size[1]-180))
self.lb=wx.Button(self,label="Load",pos=(300,size[1]-155))
self.eb=wx.Button(self,label="Export",pos=(300,size[1]-130))
self.sb=wx.Button(self,label="Snap to Z=0",pos=(300,size[1]-105))
self.cb=wx.Button(self,label="Put at 100,100",pos=(300,size[1]-80))
self.db=wx.Button(self,label="Delete",pos=(300,size[1]-55))
self.ab=wx.Button(self,label="Auto",pos=(300,size[1]-30))
self.cl.Bind(wx.EVT_BUTTON,self.clear)
self.lb.Bind(wx.EVT_BUTTON,self.right)
self.eb.Bind(wx.EVT_BUTTON,self.export)
self.sb.Bind(wx.EVT_BUTTON,self.snap)
self.cb.Bind(wx.EVT_BUTTON,self.center)
@ -123,79 +133,117 @@ class showstl(wx.Window):
self.models[i].offsets[0] += centreoffset[0]
self.models[i].offsets[1] += centreoffset[1]
self.Refresh()
def right(self,event):
dlg=wx.FileDialog(self,"Open file to print",self.basedir,style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
dlg.SetWildcard("STL files (;*.stl;)")
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()
if not(os.path.exists(name)):
return
path = os.path.split(name)[0]
self.basedir=path
t=time.time()
#print name
if name.lower().endswith(".stl"):
#Filter out the path, just show the STL filename.
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(name)
self.models[newname].offsets=[0,0,0]
self.models[newname].rot=0
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]<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.models[newname].bitmap=wx.EmptyBitmap(800,800,32)
dc=wx.MemoryDC()
dc.SelectObject(self.models[newname].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=self.models[newname]
#m.offsets=[10,10,0]
print m.offsets,m.dims
scale=2
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)))
#print time.time()-t
self.l.Append(newname)
i=self.l.GetSelection()
if i==wx.NOT_FOUND:
self.l.Select(0)
if (name.lower().endswith(".stl")):
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]
lf.close()
for i in s:
parts = i.split()
translate_list = eval(parts[0])
rotate_list = eval(parts[1])
stl_file = eval(parts[2])
self.l.Select(self.l.GetCount()-1)
self.Refresh()
#print time.time()-t
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()
#print name
if name.lower().endswith(".stl"):
#Filter out the path, just show the STL filename.
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):
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].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]<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.models[newname].bitmap=wx.EmptyBitmap(800,800,32)
dc=wx.MemoryDC()
dc.SelectObject(self.models[newname].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=self.models[newname]
#m.offsets=[10,10,0]
print m.offsets,m.dims
scale=2
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)))
#print time.time()-t
self.l.Append(newname)
i=self.l.GetSelection()
if i==wx.NOT_FOUND:
self.l.Select(0)
self.l.Select(self.l.GetCount()-1)
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.l.Clear()
self.Refresh()
def move(self,event):
if event.ButtonUp(wx.MOUSE_BTN_LEFT):
if(self.initpos is not None):
@ -297,11 +345,11 @@ class showstl(wx.Window):
#s.export()
class stlwin(wx.Frame):
def __init__(self,size=(400,530)):
def __init__(self,size=(400,580)):
wx.Frame.__init__(self,None,title="Right-click to add a file",size=size)
self.SetIcon(wx.Icon("plater.ico",wx.BITMAP_TYPE_ICO))
self.SetClientSize(size)
self.s=showstl(self,(400,530),(0,0))
self.s=showstl(self,(400,580),(0,0))
if __name__ == '__main__':
app = wx.App(False)

View File

@ -642,12 +642,16 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
if 0.3*rr+0.59*gg+0.11*bb < 60:
b.SetForegroundColour("#ffffff")
except:
b=wx.Button(self.panel,-1,"")
b.Freeze()
b=wx.StaticText(self.panel,-1,"",size=(72,20),style=wx.ALIGN_CENTRE+wx.ST_NO_AUTORESIZE) #+wx.SIMPLE_BORDER
#b.Freeze()
b.Disable()
b.custombutton=i
b.properties=btndef
b.Bind(wx.EVT_BUTTON,self.procbutton)
b.Bind(wx.EVT_MOUSE_EVENTS,self.editbutton)
if btndef is not None:
b.Bind(wx.EVT_BUTTON,self.procbutton)
b.Bind(wx.EVT_MOUSE_EVENTS,self.editbutton)
else:
b.Bind(wx.EVT_BUTTON,lambda e:e.Skip())
self.custombuttonbuttons.append(b)
if i<4:
ubs.Add(b)
@ -802,18 +806,24 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
if hasattr(obj,"custombutton"):
self.dragging = wx.Button(self.panel,-1,obj.GetLabel())
self.dragging.SetBackgroundColour(obj.GetBackgroundColour())
self.dragging.SetForegroundColour(obj.GetForegroundColour())
self.dragging.sourcebutton = obj
self.dragging.Raise()
self.dragging.Disable()
self.dragging.SetPosition(self.panel.ScreenToClient(scrpos))
for b in self.custombuttonbuttons:
if b.IsFrozen(): b.Thaw()
#if b.IsFrozen(): b.Thaw()
if b.properties is None:
b.Enable()
# b.SetStyle(wx.ALIGN_CENTRE+wx.ST_NO_AUTORESIZE+wx.SIMPLE_BORDER)
self.last_drag_dest = obj
self.dragging.label = obj.s_label = obj.GetLabel()
self.dragging.bgc = obj.s_bgc = obj.GetBackgroundColour()
self.dragging.fgc = obj.s_fgc = obj.GetForegroundColour()
else:
# dragging in progress
self.dragging.SetPosition(self.panel.ScreenToClient(scrpos))
wx.CallAfter(self.dragging.Refresh)
btns = self.custombuttonbuttons
dst = None
src = self.dragging.sourcebutton
@ -841,16 +851,21 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
if dst is not self.last_drag_dest:
if self.last_drag_dest is not None:
self.last_drag_dest.SetBackgroundColour(self.last_drag_dest.s_bgc)
self.last_drag_dest.SetForegroundColour(self.last_drag_dest.s_fgc)
self.last_drag_dest.SetLabel(self.last_drag_dest.s_label)
if dst is not None and dst is not src:
dst.s_bgc = dst.GetBackgroundColour()
dst.s_fgc = dst.GetForegroundColour()
dst.s_label = dst.GetLabel()
src.SetBackgroundColour(dst.GetBackgroundColour())
src.SetForegroundColour(dst.GetForegroundColour())
src.SetLabel(dst.GetLabel())
dst.SetBackgroundColour(drg.bgc)
dst.SetForegroundColour(drg.fgc)
dst.SetLabel(drg.label)
else:
src.SetBackgroundColour(drg.bgc)
src.SetForegroundColour(drg.fgc)
src.SetLabel(drg.label)
self.last_drag_dest = dst
elif hasattr(self,"dragging") and not e.ButtonIsDown(wx.MOUSE_BTN_LEFT):