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()
class stlwin(wx.Frame):
def __init__(self,size=(800,580)):
wx.Frame.__init__(self,None,title="Plate building tool",size=size)
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))
@ -168,14 +168,20 @@ class stlwin(wx.Frame):
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.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.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.eb.Bind(wx.EVT_BUTTON,self.export)
self.sb.Bind(wx.EVT_BUTTON,self.snap)
self.cb.Bind(wx.EVT_BUTTON,self.center)
self.db.Bind(wx.EVT_BUTTON,self.delete)
@ -266,28 +272,43 @@ class stlwin(wx.Frame):
self.l.Select(self.l.GetCount()-1)
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):
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()
sf=open(name.replace(".","_")+".scad","w")
self.writefiles(name)
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]))
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 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]))
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):
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")

View File

@ -153,6 +153,9 @@ class Settings:
self.xy_feedrate = 3000
self.z_feedrate = 200
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):
try:
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 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):
l=l.split()
if len(l)==0:
@ -1083,27 +1089,16 @@ class pronsole(cmd.Cmd):
if not(os.path.exists(l[0])):
print "File not found!"
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:
from skeinforge.skeinforge_application.skeinforge_utilities import skeinforge_craft
from skeinforge.skeinforge_application import skeinforge
import shlex
if(settings):
param = "skeinforge/skeinforge_application/skeinforge.py"
print "Entering skeinforge settings: ",sys.executable," ",param
subprocess.call([sys.executable,param])
param = self.expandcommand(self.settings.sliceoptscommand).encode()
print "Entering skeinforge settings: ",param
subprocess.call(shlex.split(param))
else:
if(len(l)>1):
if(l[1] == "view"):
skeinforge_craft.writeOutput(l[0],True)
else:
skeinforge_craft.writeOutput(l[0],False)
else:
skeinforge_craft.writeOutput(l[0],False)
param = self.expandcommand(self.settings.slicecommand).replace("$s",l[0]).replace("$o",l[0].replace(".stl","_export.gcode").replace(".STL","_export.gcode")).encode()
print "Slicing: ",param
subprocess.call(shlex.split(param))
print "Loading skeined file."
self.do_load(l[0].replace(".stl","_export.gcode"))
except Exception,e:

View File

@ -14,11 +14,12 @@ try:
except:
print _("WX is not installed. This program requires WX to run.")
raise
import printcore, sys, glob, time, threading, traceback, StringIO, gviz, traceback, cStringIO
import printcore, sys, glob, time, threading, traceback, gviz, traceback, cStringIO, subprocess
try:
os.chdir(os.path.split(__file__)[0])
except:
pass
StringIO=cStringIO
thread=threading.Thread
winsize=(800,500)
@ -71,6 +72,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.statuscheck=False
self.tempreport=""
self.monitor=0
self.skeinp=None
self.monitor_interval=3
self.paused=False
xcol=(245,245,108)
@ -110,6 +112,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.popwindow()
self.t=Tee(self.catchprint)
self.stdout=sys.stdout
self.skeining=0
self.mini=False
self.p.sendcb=self.sentcb
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, 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")))
try:
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")))
except:
pass
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:
# 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")))
#except:
# pass
self.menustrip.Append(m,_("&Settings"))
self.update_macros_menu()
@ -447,7 +450,6 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
# elif e.GetWheelRotation()<0:
# self.do_settemp(str(max(0,self.hsetpoint-1)))
#self.tgauge.Bind(wx.EVT_MOUSEWHEEL,scroll_setpoint)
uts.Add((10,-1))
self.monitorbox=wx.CheckBox(self.panel,-1,"",pos=(450,37))
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.Bind(wx.EVT_BUTTON,self.loadfile)
ubs.Add(self.loadbtn)
self.uploadbtn=wx.Button(self.panel,-1,_("SD Upload"),pos=(90,40))
self.uploadbtn.Bind(wx.EVT_BUTTON,self.upload)
self.printerControls.append(self.uploadbtn)
ubs.Add(self.uploadbtn)
self.sdprintbtn=wx.Button(self.panel,-1,_("SD Print"),pos=(180,40))
self.sdprintbtn.Bind(wx.EVT_BUTTON,self.sdprintfile)
self.printerControls.append(self.sdprintbtn)
ubs.Add(self.sdprintbtn)
self.platebtn=wx.Button(self.panel,-1,_("Compose"),pos=(90,40))
self.platebtn.Bind(wx.EVT_BUTTON,self.plate)
#self.printerControls.append(self.uploadbtn)
ubs.Add(self.platebtn)
self.sdbtn=wx.Button(self.panel,-1,_("SD"),pos=(180,40),size=(-1,-1))
self.sdbtn.Bind(wx.EVT_BUTTON,self.sdmenu)
self.printerControls.append(self.sdbtn)
ubs.Add(self.sdbtn)
self.printbtn=wx.Button(self.panel,-1,_("Print"),pos=(270,40))
self.printbtn.Bind(wx.EVT_BUTTON,self.printfile)
self.printbtn.Disable()
@ -606,6 +608,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.zfeedc.SetBackgroundColour((180,255,180))
self.zfeedc.SetForegroundColour("black")
# lls.Add((10,0),pos=(0,11),span=(1,1))
self.gviz=gviz.gviz(self.panel,(300,300),
bedsize=(self.settings.bed_size_x,self.settings.bed_size_y),
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.panel.Bind(wx.EVT_MOUSE_EVENTS,self.editbutton)
self.Bind(wx.EVT_CLOSE, self.kill)
self.topsizer.Layout()
self.topsizer.Fit(self)
@ -648,6 +652,24 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
#uts.Layout()
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):
if self.hsetpoint > 0:
self.do_settemp("")
@ -1196,11 +1218,20 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
def skein_func(self):
try:
from skeinforge.skeinforge_application.skeinforge_utilities import skeinforge_craft
from skeinforge.skeinforge_application import skeinforge
from skeinforge.fabmetheus_utilities import settings
skeinforge_craft.writeOutput(self.filename,False)
#print len(self.cout.getvalue().split())
import shlex
param = self.expandcommand(self.settings.slicecommand).replace("$s",self.filename).replace("$o",self.filename.replace(".stl","_export.gcode").replace(".STL","_export.gcode")).encode()
print shlex.split(param)
print "Slicing: ",param
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
except:
print _("Skeinforge execution failed.")
@ -1210,7 +1241,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
def skein_monitor(self):
while(not self.stopsf):
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:
pass
time.sleep(0.1)
@ -1230,22 +1261,24 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
threading.Thread(target=self.loadviz).start()
except:
self.filename=fn
wx.CallAfter(self.loadbtn.SetLabel,_("Load File"))
wx.CallAfter(self.status.SetStatusText,_("Slicing cancelled."))
def skein(self,filename):
print _("Skeining ") + filename
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()
wx.CallAfter(self.loadbtn.SetLabel,_("Cancel"))
print _("Slicing ") + filename
self.cout=StringIO.StringIO()
self.filename=filename
self.stopsf=0
self.skeining=1
thread(target=self.skein_func).start()
thread(target=self.skein_monitor).start()
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
if not os.path.exists(basedir):
basedir = "."

View File

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

View File

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