Integrate plating into pronterface UI

master
Kliment Yanev 2011-11-18 09:52:16 +01:00
parent 9669cd4337
commit 0afcc88bd4
5 changed files with 123 additions and 74 deletions

View File

@ -159,8 +159,8 @@ class showstl(wx.Window):
#s.export() #s.export()
class stlwin(wx.Frame): class stlwin(wx.Frame):
def __init__(self,size=(800,580)): def __init__(self,size=(800,580),callback=None,parent=None):
wx.Frame.__init__(self,None,title="Plate building tool",size=size) wx.Frame.__init__(self,parent,title="Plate building tool",size=size)
self.SetIcon(wx.Icon("plater.ico",wx.BITMAP_TYPE_ICO)) self.SetIcon(wx.Icon("plater.ico",wx.BITMAP_TYPE_ICO))
self.mainsizer = wx.BoxSizer(wx.HORIZONTAL) self.mainsizer = wx.BoxSizer(wx.HORIZONTAL)
self.panel=wx.Panel(self,-1,size=(150,600),pos=(0,0)) self.panel=wx.Panel(self,-1,size=(150,600),pos=(0,0))
@ -168,14 +168,20 @@ class stlwin(wx.Frame):
self.l=wx.ListBox(self.panel,size=(300,180),pos=(0,30)) self.l=wx.ListBox(self.panel,size=(300,180),pos=(0,30))
self.cl=wx.Button(self.panel,label="Clear",pos=(0,205)) self.cl=wx.Button(self.panel,label="Clear",pos=(0,205))
self.lb=wx.Button(self.panel,label="Load",pos=(0,0)) self.lb=wx.Button(self.panel,label="Load",pos=(0,0))
self.eb=wx.Button(self.panel,label="Export",pos=(100,0)) if(callback is None):
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,self.Destroy)
self.sb=wx.Button(self.panel,label="Snap to Z=0",pos=(00,255)) 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.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.db=wx.Button(self.panel,label="Delete",pos=(0,305))
self.ab=wx.Button(self.panel,label="Auto",pos=(0,330)) self.ab=wx.Button(self.panel,label="Auto",pos=(0,330))
self.cl.Bind(wx.EVT_BUTTON,self.clear) self.cl.Bind(wx.EVT_BUTTON,self.clear)
self.lb.Bind(wx.EVT_BUTTON,self.right) 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.sb.Bind(wx.EVT_BUTTON,self.snap)
self.cb.Bind(wx.EVT_BUTTON,self.center) self.cb.Bind(wx.EVT_BUTTON,self.center)
self.db.Bind(wx.EVT_BUTTON,self.delete) self.db.Bind(wx.EVT_BUTTON,self.delete)
@ -266,28 +272,43 @@ class stlwin(wx.Frame):
self.l.Select(self.l.GetCount()-1) self.l.Select(self.l.GetCount()-1)
self.Refresh() self.Refresh()
def done(self,event,cb):
import os,time
try:
os.mkdir("tempstl")
except:
pass
name="tempstl/"+str(int(time.time())%10000)+".stl"
self.writefiles(name)
if cb is not None:
cb(name)
self.Destroy()
def export(self,event): def export(self,event):
dlg=wx.FileDialog(self,"Pick file to save to",self.basedir,style=wx.FD_SAVE) dlg=wx.FileDialog(self,"Pick file to save to",self.basedir,style=wx.FD_SAVE)
dlg.SetWildcard("STL files (;*.stl;)") dlg.SetWildcard("STL files (;*.stl;)")
if(dlg.ShowModal() == wx.ID_OK): if(dlg.ShowModal() == wx.ID_OK):
name=dlg.GetPath() name=dlg.GetPath()
sf=open(name.replace(".","_")+".scad","w") self.writefiles(name)
facets=[] def writefiles(self,name):
for i in self.models.values(): sf=open(name.replace(".","_")+".scad","w")
facets=[]
r=i.rot for i in self.models.values():
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
sf.close()
stltool.emitstl(name,facets,"plater_export")
print "wrote ",name
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
sf.close()
stltool.emitstl(name,facets,"plater_export")
print "wrote ",name
def right(self,event): def right(self,event):
dlg=wx.FileDialog(self,"Pick file to load",self.basedir,style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST) 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") dlg.SetWildcard("STL files (;*.stl;)|*.stl|OpenSCAD files (;*.scad;)|*.scad")

View File

@ -153,6 +153,9 @@ class Settings:
self.xy_feedrate = 3000 self.xy_feedrate = 3000
self.z_feedrate = 200 self.z_feedrate = 200
self.e_feedrate = 300 self.e_feedrate = 300
self.slicecommand="python skeinforge/skeinforge_application/skeinforge_utilities/skeinforge_craft.py $s"
self.sliceoptscommand="python skeinforge/skeinforge_application/skeinforge.py"
def _set(self,key,value): def _set(self,key,value):
try: try:
value = getattr(self,"_%s_alias"%key)()[value] value = getattr(self,"_%s_alias"%key)()[value]
@ -1070,6 +1073,9 @@ class pronsole(cmd.Cmd):
print "monitor - Reports temperature and SD print status (if SD printing) every 5 seconds" print "monitor - Reports temperature and SD print status (if SD printing) every 5 seconds"
print "monitor 2 - Reports temperature and SD print status (if SD printing) every 2 seconds" print "monitor 2 - Reports temperature and SD print status (if SD printing) every 2 seconds"
def expandcommand(self,c):
return c.replace("$python",sys.executable)
def do_skein(self,l): def do_skein(self,l):
l=l.split() l=l.split()
if len(l)==0: if len(l)==0:
@ -1083,27 +1089,16 @@ class pronsole(cmd.Cmd):
if not(os.path.exists(l[0])): if not(os.path.exists(l[0])):
print "File not found!" print "File not found!"
return return
if not os.path.exists("skeinforge"):
print "Skeinforge not found. \nPlease copy Skeinforge into a directory named \"skeinforge\" in the same directory as this file."
return
if not os.path.exists("skeinforge/__init__.py"):
f=open("skeinforge/__init__.py","w")
f.close()
try: try:
from skeinforge.skeinforge_application.skeinforge_utilities import skeinforge_craft import shlex
from skeinforge.skeinforge_application import skeinforge
if(settings): if(settings):
param = "skeinforge/skeinforge_application/skeinforge.py" param = self.expandcommand(self.settings.sliceoptscommand).encode()
print "Entering skeinforge settings: ",sys.executable," ",param print "Entering skeinforge settings: ",param
subprocess.call([sys.executable,param]) subprocess.call(shlex.split(param))
else: else:
if(len(l)>1): param = self.expandcommand(self.settings.slicecommand).replace("$s",l[0]).replace("$o",l[0].replace(".stl","_export.gcode").replace(".STL","_export.gcode")).encode()
if(l[1] == "view"): print "Slicing: ",param
skeinforge_craft.writeOutput(l[0],True) subprocess.call(shlex.split(param))
else:
skeinforge_craft.writeOutput(l[0],False)
else:
skeinforge_craft.writeOutput(l[0],False)
print "Loading skeined file." print "Loading skeined file."
self.do_load(l[0].replace(".stl","_export.gcode")) self.do_load(l[0].replace(".stl","_export.gcode"))
except Exception,e: except Exception,e:

View File

@ -14,11 +14,12 @@ try:
except: except:
print _("WX is not installed. This program requires WX to run.") print _("WX is not installed. This program requires WX to run.")
raise raise
import printcore, sys, glob, time, threading, traceback, StringIO, gviz, traceback, cStringIO import printcore, sys, glob, time, threading, traceback, gviz, traceback, cStringIO, subprocess
try: try:
os.chdir(os.path.split(__file__)[0]) os.chdir(os.path.split(__file__)[0])
except: except:
pass pass
StringIO=cStringIO
thread=threading.Thread thread=threading.Thread
winsize=(800,500) winsize=(800,500)
@ -71,6 +72,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.statuscheck=False self.statuscheck=False
self.tempreport="" self.tempreport=""
self.monitor=0 self.monitor=0
self.skeinp=None
self.monitor_interval=3 self.monitor_interval=3
self.paused=False self.paused=False
xcol=(245,245,108) xcol=(245,245,108)
@ -110,6 +112,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.popwindow() self.popwindow()
self.t=Tee(self.catchprint) self.t=Tee(self.catchprint)
self.stdout=sys.stdout self.stdout=sys.stdout
self.skeining=0
self.mini=False self.mini=False
self.p.sendcb=self.sentcb self.p.sendcb=self.sentcb
self.p.startcb=self.startcb self.p.startcb=self.startcb
@ -305,12 +308,12 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.Bind(wx.EVT_MENU, self.new_macro, self.macros_menu.Append(-1, _("<&New...>"))) self.Bind(wx.EVT_MENU, self.new_macro, self.macros_menu.Append(-1, _("<&New...>")))
self.Bind(wx.EVT_MENU, lambda *e:options(self), m.Append(-1,_("&Options"),_(" Options dialog"))) self.Bind(wx.EVT_MENU, lambda *e:options(self), m.Append(-1,_("&Options"),_(" Options dialog")))
self.Bind(wx.EVT_MENU, lambda x:threading.Thread(target=lambda :self.do_skein("set")).start(), m.Append(-1,_("SFACT Settings"),_(" Adjust SFACT settings"))) self.Bind(wx.EVT_MENU, lambda x:threading.Thread(target=lambda :self.do_skein("set")).start(), m.Append(-1,_("Slicing Settings"),_(" Adjust slicing settings")))
try: #try:
from SkeinforgeQuickEditDialog import SkeinforgeQuickEditDialog # from SkeinforgeQuickEditDialog import SkeinforgeQuickEditDialog
self.Bind(wx.EVT_MENU, lambda *e:SkeinforgeQuickEditDialog(self), m.Append(-1,_("SFACT Quick Settings"),_(" Quickly adjust SFACT settings for active profile"))) # self.Bind(wx.EVT_MENU, lambda *e:SkeinforgeQuickEditDialog(self), m.Append(-1,_("SFACT Quick Settings"),_(" Quickly adjust SFACT settings for active profile")))
except: #except:
pass # pass
self.menustrip.Append(m,_("&Settings")) self.menustrip.Append(m,_("&Settings"))
self.update_macros_menu() self.update_macros_menu()
@ -447,7 +450,6 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
# elif e.GetWheelRotation()<0: # elif e.GetWheelRotation()<0:
# self.do_settemp(str(max(0,self.hsetpoint-1))) # self.do_settemp(str(max(0,self.hsetpoint-1)))
#self.tgauge.Bind(wx.EVT_MOUSEWHEEL,scroll_setpoint) #self.tgauge.Bind(wx.EVT_MOUSEWHEEL,scroll_setpoint)
uts.Add((10,-1)) uts.Add((10,-1))
self.monitorbox=wx.CheckBox(self.panel,-1,"",pos=(450,37)) self.monitorbox=wx.CheckBox(self.panel,-1,"",pos=(450,37))
uts.Add((15,-1)) uts.Add((15,-1))
@ -465,14 +467,14 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.loadbtn=wx.Button(self.panel,-1,_("Load file"),pos=(0,40)) self.loadbtn=wx.Button(self.panel,-1,_("Load file"),pos=(0,40))
self.loadbtn.Bind(wx.EVT_BUTTON,self.loadfile) self.loadbtn.Bind(wx.EVT_BUTTON,self.loadfile)
ubs.Add(self.loadbtn) ubs.Add(self.loadbtn)
self.uploadbtn=wx.Button(self.panel,-1,_("SD Upload"),pos=(90,40)) self.platebtn=wx.Button(self.panel,-1,_("Compose"),pos=(90,40))
self.uploadbtn.Bind(wx.EVT_BUTTON,self.upload) self.platebtn.Bind(wx.EVT_BUTTON,self.plate)
self.printerControls.append(self.uploadbtn) #self.printerControls.append(self.uploadbtn)
ubs.Add(self.uploadbtn) ubs.Add(self.platebtn)
self.sdprintbtn=wx.Button(self.panel,-1,_("SD Print"),pos=(180,40)) self.sdbtn=wx.Button(self.panel,-1,_("SD"),pos=(180,40),size=(-1,-1))
self.sdprintbtn.Bind(wx.EVT_BUTTON,self.sdprintfile) self.sdbtn.Bind(wx.EVT_BUTTON,self.sdmenu)
self.printerControls.append(self.sdprintbtn) self.printerControls.append(self.sdbtn)
ubs.Add(self.sdprintbtn) ubs.Add(self.sdbtn)
self.printbtn=wx.Button(self.panel,-1,_("Print"),pos=(270,40)) self.printbtn=wx.Button(self.panel,-1,_("Print"),pos=(270,40))
self.printbtn.Bind(wx.EVT_BUTTON,self.printfile) self.printbtn.Bind(wx.EVT_BUTTON,self.printfile)
self.printbtn.Disable() self.printbtn.Disable()
@ -606,6 +608,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.zfeedc.SetBackgroundColour((180,255,180)) self.zfeedc.SetBackgroundColour((180,255,180))
self.zfeedc.SetForegroundColour("black") self.zfeedc.SetForegroundColour("black")
# lls.Add((10,0),pos=(0,11),span=(1,1)) # lls.Add((10,0),pos=(0,11),span=(1,1))
self.gviz=gviz.gviz(self.panel,(300,300), self.gviz=gviz.gviz(self.panel,(300,300),
bedsize=(self.settings.bed_size_x,self.settings.bed_size_y), bedsize=(self.settings.bed_size_x,self.settings.bed_size_y),
grid=(self.settings.preview_grid_step1,self.settings.preview_grid_step2), grid=(self.settings.preview_grid_step1,self.settings.preview_grid_step2),
@ -636,6 +639,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.status.SetStatusText(_("Not connected to printer.")) self.status.SetStatusText(_("Not connected to printer."))
self.panel.Bind(wx.EVT_MOUSE_EVENTS,self.editbutton) self.panel.Bind(wx.EVT_MOUSE_EVENTS,self.editbutton)
self.Bind(wx.EVT_CLOSE, self.kill) self.Bind(wx.EVT_CLOSE, self.kill)
self.topsizer.Layout() self.topsizer.Layout()
self.topsizer.Fit(self) self.topsizer.Fit(self)
@ -648,6 +652,24 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
#uts.Layout() #uts.Layout()
self.cbuttons_reload() self.cbuttons_reload()
def plate(self,e):
import plater
print "plate function activated"
plater.stlwin(size=(800,580),callback=self.platecb,parent=self).Show()
def platecb(self,name):
print "plated: "+name
self.loadfile(None,name)
def sdmenu(self,e):
obj = e.GetEventObject()
popupmenu=wx.Menu()
item = popupmenu.Append(-1,_("SD Upload"))
self.Bind(wx.EVT_MENU,self.upload)
item = popupmenu.Append(-1,_("SD Print"))
self.Bind(wx.EVT_MENU,self.sdprintfile)
self.panel.PopupMenu(popupmenu, obj.GetPosition())
def htemp_change(self,event): def htemp_change(self,event):
if self.hsetpoint > 0: if self.hsetpoint > 0:
self.do_settemp("") self.do_settemp("")
@ -1196,11 +1218,20 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
def skein_func(self): def skein_func(self):
try: try:
from skeinforge.skeinforge_application.skeinforge_utilities import skeinforge_craft import shlex
from skeinforge.skeinforge_application import skeinforge param = self.expandcommand(self.settings.slicecommand).replace("$s",self.filename).replace("$o",self.filename.replace(".stl","_export.gcode").replace(".STL","_export.gcode")).encode()
from skeinforge.fabmetheus_utilities import settings print shlex.split(param)
skeinforge_craft.writeOutput(self.filename,False) print "Slicing: ",param
#print len(self.cout.getvalue().split()) self.cancelskein=0
#p=subprocess.Popen(param,shell=True,bufsize=10,stderr=subprocess.STDOUT,stdout=subprocess.PIPE,close_fds=True)
pararray=shlex.split(param)
#print pararray
self.skeinp=subprocess.Popen(pararray,stderr=subprocess.STDOUT,stdout=subprocess.PIPE)
while True:
o = self.skeinp.stdout.read(1)
if o == '' and self.skeinp.poll() != None: break
sys.stdout.write(o)
self.skeinp.wait()
self.stopsf=1 self.stopsf=1
except: except:
print _("Skeinforge execution failed.") print _("Skeinforge execution failed.")
@ -1210,7 +1241,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
def skein_monitor(self): def skein_monitor(self):
while(not self.stopsf): while(not self.stopsf):
try: try:
wx.CallAfter(self.status.SetStatusText,_("Skeining..."))#+self.cout.getvalue().split("\n")[-1]) wx.CallAfter(self.status.SetStatusText,_("Slicing..."))#+self.cout.getvalue().split("\n")[-1])
except: except:
pass pass
time.sleep(0.1) time.sleep(0.1)
@ -1230,22 +1261,24 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
threading.Thread(target=self.loadviz).start() threading.Thread(target=self.loadviz).start()
except: except:
self.filename=fn self.filename=fn
wx.CallAfter(self.loadbtn.SetLabel,_("Load File"))
wx.CallAfter(self.status.SetStatusText,_("Slicing cancelled."))
def skein(self,filename): def skein(self,filename):
print _("Skeining ") + filename wx.CallAfter(self.loadbtn.SetLabel,_("Cancel"))
if not os.path.exists("skeinforge"): print _("Slicing ") + filename
print _("Skeinforge not found. \nPlease copy Skeinforge into a directory named \"skeinforge\" in the same directory as this file.")
return
if not os.path.exists("skeinforge/__init__.py"):
f=open("skeinforge/__init__.py","w")
f.close()
self.cout=StringIO.StringIO() self.cout=StringIO.StringIO()
self.filename=filename self.filename=filename
self.stopsf=0 self.stopsf=0
self.skeining=1
thread(target=self.skein_func).start() thread(target=self.skein_func).start()
thread(target=self.skein_monitor).start() thread(target=self.skein_monitor).start()
def loadfile(self,event,filename=None): def loadfile(self,event,filename=None):
if self.skeining and self.skeinp is not None:
self.skeinp.terminate()
return
basedir=self.settings.last_file_path basedir=self.settings.last_file_path
if not os.path.exists(basedir): if not os.path.exists(basedir):
basedir = "." basedir = "."

View File

@ -38,9 +38,8 @@ class XYButtons(BufferedCanvas):
self.moveCallback = moveCallback self.moveCallback = moveCallback
self.cornerCallback = cornerCallback self.cornerCallback = cornerCallback
self.enabled = False self.enabled = False
BufferedCanvas.__init__(self, parent, ID) BufferedCanvas.__init__(self, parent, ID)
self.SetSize(self.bg_bmp.GetSize()) self.SetSize(self.bg_bmp.GetSize())
# Set up mouse and keyboard event capture # Set up mouse and keyboard event capture
@ -192,8 +191,9 @@ class XYButtons(BufferedCanvas):
gc = wx.GraphicsContext.Create(dc) gc = wx.GraphicsContext.Create(dc)
center = wx.Point(XYButtons.center[0], XYButtons.center[1]) center = wx.Point(XYButtons.center[0], XYButtons.center[1])
w, h = (self.bg_bmp.GetWidth(), self.bg_bmp.GetHeight()) if self.bg_bmp:
gc.DrawBitmap(self.bg_bmp, 0, 0, w, h) w, h = (self.bg_bmp.GetWidth(), self.bg_bmp.GetHeight())
gc.DrawBitmap(self.bg_bmp, 0, 0, w, h)
if self.enabled: if self.enabled:
# Brush and pen for grey overlay when mouse hovers over # Brush and pen for grey overlay when mouse hovers over
@ -327,4 +327,4 @@ class XYButtons(BufferedCanvas):
def OnLeaveWindow(self, evt): def OnLeaveWindow(self, evt):
self.quadrant = None self.quadrant = None
self.concentric = None self.concentric = None
self.update() self.update()

View File

@ -75,9 +75,9 @@ class ZButtons(BufferedCanvas):
def draw(self, dc, w, h): def draw(self, dc, w, h):
dc.Clear() dc.Clear()
gc = wx.GraphicsContext.Create(dc) gc = wx.GraphicsContext.Create(dc)
w, h = (self.bg_bmp.GetWidth(), self.bg_bmp.GetHeight()) if self.bg_bmp:
w, h = (self.bg_bmp.GetWidth(), self.bg_bmp.GetHeight())
gc.DrawBitmap(self.bg_bmp, 0, 0, w, h) gc.DrawBitmap(self.bg_bmp, 0, 0, w, h)
if self.enabled: if self.enabled:
# Draw label overlays # Draw label overlays