Merge branch 'experimental' into HEAD

Conflicts:
	printrun/gviz.py
master
Guillaume Seguin 2013-05-18 11:14:50 +02:00
commit e29dd70efe
13 changed files with 310 additions and 137 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@
*.swp
*.bak
uploads
.DS_Store

View File

@ -25,9 +25,19 @@ You can run Printrun directly from source, as there are no packages available ye
`sudo apt-get install python-serial python-wxgtk2.8 python-pyglet`
### Fedora 15 and newer
### Fedora 17 and newer
You can run Printrun directly from source, as there are no packages available yet. Fetch and install the dependencies using
You can install Printrun from official packages. Install the whole package using
`sudo yum install printrun`
Or get only apps you need by
`sudo yum install pronsole` or `pronterface` or `plater`
Adding `--enablerepo updates-testing` option to `yum` might give you newer packages (but also not very tested).
You can also run Printrun directly from source, if the packages are too old for you anyway, or you have Fedora 15 or 16. Fetch and install the dependencies using
`sudo yum install pyserial wxpython pyglet`

View File

@ -461,12 +461,12 @@ if __name__ == '__main__':
try:
if statusreport:
p.loud = False
sys.stdout.write("Progress: 00.0%")
sys.stdout.write("Progress: 00.0%\r")
sys.stdout.flush()
while p.printing:
time.sleep(1)
if statusreport:
sys.stdout.write("%02.1f%%\r" % (100 * float(p.queueindex) / len(p.mainqueue),) )
sys.stdout.write("Progress: %02.1f%%\r" % (100 * float(p.queueindex) / len(p.mainqueue),) )
sys.stdout.flush()
p.disconnect()
sys.exit(0)

View File

@ -77,7 +77,7 @@ class BufferedCanvas(wx.Panel):
## General methods
##
def draw(self, dc):
def draw(self, dc, w, h):
"""
Stub: called when the canvas needs to be re-drawn.
"""

View File

@ -47,10 +47,13 @@ class Line(object):
if ";" in self.raw:
self.raw = self.raw.split(";")[0].rstrip()
self.split_raw = self.raw.split(" ")
self.command = self.split_raw[0].upper()
self.command = self.split_raw[0].upper() if not self.split_raw[0].startswith("n") else self.split_raw[1]
self.is_move = self.command in ["G0", "G1"]
def parse_coordinates(self, imperial):
# Not a G-line, we don't want to parse its arguments
if not self.command[0] == "G":
return
if imperial:
for bit in self.split_raw:
code = bit[0]

View File

@ -23,14 +23,13 @@ class Graph(BufferedCanvas):
'''A class to show a Graph with Pronterface.'''
def __init__(self, parent, id, pos = wx.DefaultPosition,
size = wx.DefaultSize, style = 0):
size = wx.Size(150, 80), style = 0):
# Forcing a no full repaint to stop flickering
style = style | wx.NO_FULL_REPAINT_ON_RESIZE
#call super function
#super(Graph, self).__init__(parent, id, pos, size, style)
BufferedCanvas.__init__(self, parent, id)
super(Graph, self).__init__(parent, id, pos, size, style)
#BufferedCanvas.__init__(self, parent, id)
self.SetSize(wx.Size(150, 80))
self.extruder0temps = [0]
self.extruder0targettemps = [0]
@ -80,8 +79,7 @@ class Graph(BufferedCanvas):
#b = gc.CreateLinearGradientBrush(0, 0, w, h, col1, col2)
gc.SetPen(wx.Pen(wx.Colour(255, 0, 0, 0), 4))
#gc.SetBrush(gc.CreateBrush(wx.Brush(wx.Colour(245, 245, 255, 252))))
#gc.SetBrush(b)
gc.SetBrush(gc.CreateBrush(wx.Brush(wx.Colour(0, 0, 0, 0))))
gc.DrawRectangle(0, 0, self.width, self.height)
#gc.SetBrush(wx.Brush(wx.Colour(245, 245, 255, 52)))

View File

@ -26,6 +26,7 @@ from printrun import gviz
from printrun.xybuttons import XYButtons
from printrun.zbuttons import ZButtons
from printrun.graph import Graph
from printrun.pronterface_widgets import TempGauge
def make_button(parent, label, callback, tooltip, container = None, size = wx.DefaultSize, style = 0):
button = wx.Button(parent, -1, label, style = style, size = size)
@ -56,9 +57,9 @@ class LeftPane(wx.GridBagSizer):
def __init__(self, root):
super(LeftPane, self).__init__()
llts = wx.BoxSizer(wx.HORIZONTAL)
self.Add(llts, pos = (0, 0), span = (1, 9))
self.Add(llts, pos = (0, 0), span = (1, 6))
self.xyzsizer = XYZControlsSizer(root)
self.Add(self.xyzsizer, pos = (1, 0), span = (1, 8), flag = wx.ALIGN_CENTER)
self.Add(self.xyzsizer, pos = (1, 0), span = (1, 6), flag = wx.ALIGN_CENTER)
for i in root.cpbuttons:
btn = make_button(root.panel, i.label, root.procbutton, i.tooltip, style = wx.BU_EXACTFIT)
@ -84,7 +85,7 @@ class LeftPane(wx.GridBagSizer):
root.monitorbox = wx.CheckBox(root.panel,-1, _("Watch"))
root.monitorbox.SetToolTip(wx.ToolTip("Monitor Temperatures in Graph"))
self.Add(root.monitorbox, pos = (2, 6))
self.Add(root.monitorbox, pos = (3, 5))
root.monitorbox.Bind(wx.EVT_CHECKBOX, root.setmonitor)
self.Add(wx.StaticText(root.panel,-1, _("Heat:")), pos = (2, 0), span = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT)
@ -164,9 +165,31 @@ class LeftPane(wx.GridBagSizer):
root.zfeedc.SetBackgroundColour((180, 255, 180))
root.zfeedc.SetForegroundColour("black")
if root.display_gauges:
root.hottgauge = TempGauge(root.panel, size = (-1, 24), title = _("Heater:"), maxval = 300)
self.Add(root.hottgauge, pos = (6, 0), span = (1, 6), flag = wx.EXPAND)
root.bedtgauge = TempGauge(root.panel, size = (-1, 24), title = _("Bed:"), maxval = 150)
self.Add(root.bedtgauge, pos = (7, 0), span = (1, 6), flag = wx.EXPAND)
def hotendgauge_scroll_setpoint(e):
rot = e.GetWheelRotation()
if rot > 0:
root.do_settemp(str(root.hsetpoint + 1))
elif rot < 0:
root.do_settemp(str(max(0, root.hsetpoint - 1)))
def bedgauge_scroll_setpoint(e):
rot = e.GetWheelRotation()
if rot > 0:
root.do_settemp(str(root.bsetpoint + 1))
elif rot < 0:
root.do_settemp(str(max(0, root.bsetpoint - 1)))
root.hottgauge.Bind(wx.EVT_MOUSEWHEEL, hotendgauge_scroll_setpoint)
root.bedtgauge.Bind(wx.EVT_MOUSEWHEEL, bedgauge_scroll_setpoint)
self.Add(root.tempdisp, pos = (8, 0), span = (1, 6))
else:
self.Add(root.tempdisp, pos = (6, 0), span = (1, 6))
root.graph = Graph(root.panel, wx.ID_ANY)
self.Add(root.graph, pos = (3, 5), span = (3, 3))
self.Add(root.tempdisp, pos = (6, 0), span = (1, 9))
self.Add(root.graph, pos = (4, 5), span = (2, 1))
class VizPane(wx.BoxSizer):
@ -199,6 +222,7 @@ class LogPane(wx.BoxSizer):
super(LogPane, self).__init__(wx.VERTICAL)
root.lowerrsizer = self
root.logbox = wx.TextCtrl(root.panel, style = wx.TE_MULTILINE, size = (350,-1))
root.logbox.SetMinSize((100,-1))
root.logbox.SetEditable(0)
self.Add(root.logbox, 1, wx.EXPAND)
lbrs = wx.BoxSizer(wx.HORIZONTAL)
@ -223,7 +247,7 @@ class MainToolbar(wx.BoxSizer):
root.serialport = wx.ComboBox(root.panel, -1,
choices = root.scanserial(),
style = wx.CB_DROPDOWN, size = (150, 25))
style = wx.CB_DROPDOWN, size = (-1, 25))
root.serialport.SetToolTip(wx.ToolTip("Select Port Printer is connected to"))
root.rescanports()
self.Add(root.serialport)
@ -263,10 +287,10 @@ class MainWindow(wx.Frame):
self.mainsizer = wx.BoxSizer(wx.VERTICAL)
self.uppersizer = MainToolbar(self)
self.lowersizer = wx.BoxSizer(wx.HORIZONTAL)
self.lowersizer.Add(LeftPane(self))
self.lowersizer.Add(LeftPane(self), 0)
self.lowersizer.Add(VizPane(self), 1, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL)
self.lowersizer.Add(LogPane(self), 0, wx.EXPAND)
self.mainsizer.Add(self.uppersizer)
self.lowersizer.Add(LogPane(self), 1, wx.EXPAND)
self.mainsizer.Add(self.uppersizer, 0)
self.mainsizer.Add(self.lowersizer, 1, wx.EXPAND)
self.panel.SetSizer(self.mainsizer)
self.status = self.CreateStatusBar()
@ -276,6 +300,12 @@ class MainWindow(wx.Frame):
self.mainsizer.Layout()
self.mainsizer.Fit(self)
# This prevents resizing below a reasonnable value
# We sum the lowersizer (left pane / viz / log) min size
# the toolbar height and the statusbar/menubar sizes
minsize = self.lowersizer.GetMinSize() # lower pane
minsize[1] += self.uppersizer.GetMinSize()[1] # toolbar height
self.SetMinSize(self.ClientToWindowSize(minsize)) # client to window
# disable all printer controls until we connect to a printer
self.pausebtn.Disable()

View File

@ -44,8 +44,8 @@ class window(wx.Frame):
vbox.Add(self.p, 1, wx.EXPAND)
panel.SetSizer(vbox)
self.SetMinSize(self.ClientToWindowSize(vbox.GetMinSize()))
self.Bind(wx.EVT_TOOL, lambda x:self.p.zoom(200, 200, 1.2), id = 1)
self.Bind(wx.EVT_TOOL, lambda x:self.p.zoom(200, 200, 1/1.2), id = 2)
self.Bind(wx.EVT_TOOL, lambda x:self.p.zoom(-1, -1, 1.2), id = 1)
self.Bind(wx.EVT_TOOL, lambda x:self.p.zoom(-1, -1, 1/1.2), id = 2)
self.Bind(wx.EVT_TOOL, lambda x:self.p.layerup(), id = 3)
self.Bind(wx.EVT_TOOL, lambda x:self.p.layerdown(), id = 4)
self.Bind(wx.EVT_TOOL, self.resetview, id = 5)
@ -123,6 +123,17 @@ class window(wx.Frame):
elif z < 0: self.p.zoom(event.GetX(), event.GetY(), 1/1.2)
class gviz(wx.Panel):
# Mark canvas as dirty when setting showall
_showall = 0
def _get_showall(self):
return self._showall
def _set_showall(self, showall):
if showall != self._showall:
self.dirty = 1
self._showall = showall
showall = property(_get_showall, _set_showall)
def __init__(self, parent, size = (200, 200), build_dimensions = [200, 200, 100, 0, 0, 0], grid = (10, 50), extrusion_width = 0.5):
wx.Panel.__init__(self, parent, -1, size = size)
self.SetMinSize((150, 150))
@ -202,18 +213,18 @@ class gviz(wx.Panel):
pass
def resize(self, event):
oldwidth, oldheight = max(1.0, self.size[0]), max(1.0, self.size[1])
oldside = min(oldwidth, oldheight)
newwidth, newheight = self.GetClientSizeTuple()
newwidth, newheight = [max(1.0, newwidth), max(1.0, newheight)]
newside = min(newwidth, newheight)
oldside = max(1.0, min(self.size))
self.size = self.GetClientSizeTuple()
newside = max(1.0, min(self.size))
self.basescale = 2*[min(float(self.size[0])/self.build_dimensions[0],
float(self.size[1])/self.build_dimensions[1])]
zoomratio = float(newside) / oldside
print newwidth, newheight
print zoomratio
self.size = self.GetClientSize()
wx.CallAfter(self.zoom, 0, 0, zoomratio)
def zoom(self, x, y, factor):
if x == -1 and y == -1:
side = min(self.size)
x = y = side / 2
self.scale = [s * factor for s in self.scale]
self.translate = [ x - (x-self.translate[0]) * factor,
@ -291,14 +302,18 @@ class gviz(wx.Panel):
def paint(self, event):
dc = wx.PaintDC(self)
if self.dirty:
self.repaint()
self.dirty = 0
self.repaint()
dc.DrawBitmap(self.blitmap, 0, 0)
def addfile(self, gcode):
self.clear()
self.add_parsed_gcodes(gcode.lines)
# FIXME : there's code duplication going on there, we should factor it (but
# the reason addgcode is not factored as a add_parsed_gcodes([gline]) is
# because when loading a file there's no hilight, so it simply lets us not
# do the if hilight: all the time for nothing when loading a lot of lines
def add_parsed_gcodes(self, lines):
def _y(y):
return self.build_dimensions[1] - (y - self.build_dimensions[4])
@ -312,10 +327,19 @@ class gviz(wx.Panel):
target = self.lastpos[:]
target[5] = 0.0
target[6] = 0.0
if gline.x != None: target[0] = gline.x
if gline.y != None: target[1] = gline.y
if gline.z != None: target[2] = gline.z
if gline.e != None: target[3] = gline.e
if gline.relative:
if gline.x != None: target[0] += gline.x
if gline.y != None: target[1] += gline.y
if gline.z != None: target[2] += gline.z
else:
if gline.x != None: target[0] = gline.x
if gline.y != None: target[1] = gline.y
if gline.z != None: target[2] = gline.z
if gline.e != None:
if gline.relative_e:
target[3] += gline.e
else:
target[3] = gline.e
if gline.f != None: target[4] = gline.f
if gline.i != None: target[5] = gline.i
if gline.j != None: target[6] = gline.j
@ -330,100 +354,88 @@ class gviz(wx.Panel):
start_pos = self.lastpos[:]
if gline.command in ["G0", "G1"]:
line = [ _x(start_pos[0]), _y(start_pos[1]), _x(target[0]), _y(target[1]) ]
self.lines[z].append(line)
self.lines[z].append((_x(start_pos[0]), _y(start_pos[1]), _x(target[0]), _y(target[1])))
self.pens[z].append(self.mainpen if target[3] != self.lastpos[3] else self.travelpen)
self.lastpos = target
self.dirty = 1
if gline.command in ["G2", "G3"]:
elif gline.command in ["G2", "G3"]:
# startpos, endpos, arc center
arc = [_x(start_pos[0]), _y(start_pos[1]),
_x(target[0]), _y(target[1]),
_x(start_pos[0] + target[5]), _y(start_pos[1] + target[6]) ] # center
_x(start_pos[0] + target[5]), _y(start_pos[1] + target[6])]
# FIXME : verify this works : why not reverse endpoints 4, 5
if gline.command == "G2": # clockwise, reverse endpoints
arc[0], arc[1], arc[2], arc[3] = arc[2], arc[3], arc[0], arc[1]
self.arcs[z].append(arc)
self.arcpens[z].append(self.arcpen)
self.lastpos = target
self.dirty = 1
self.lastpos = target
self.dirty = 1
self.Refresh()
def addgcode(self, gcode = "M105", hilight = 0):
gcode = gcode.split("*")[0]
gcode = gcode.split(";")[0]
gcode = gcode.lower().strip().split()
gcode = gcode.lower().strip()
if not gcode:
return
if gcode[0][0] == 'n': # not sure what this check is for ?
gcode.pop(0)
def _readgcode():
target = self.lastpos[:]
target[5]=0.0
target[6]=0.0
if hilight:
target = self.hilightpos[:]
for i in gcode:
if i[0]=="x":
target[0]=float(i[1:])
elif i[0]=="y":
target[1]=float(i[1:])
elif i[0]=="z":
target[2]=float(i[1:])
elif i[0]=="e":
target[3]=float(i[1:])
elif i[0]=="f":
target[4]=float(i[1:])
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]]
return target
gline = gcoder.Line(gcode)
gline.parse_coordinates(False)
def _y(y):
return self.build_dimensions[1]-(y-self.build_dimensions[4])
return self.build_dimensions[1] - (y - self.build_dimensions[4])
def _x(x):
return x-self.build_dimensions[3]
return x - self.build_dimensions[3]
start_pos = self.hilightpos[:] if hilight else self.lastpos[:]
if gcode[0] in [ "g0", "g1" ]:
target = _readgcode()
line = [ _x(start_pos[0]), _y(start_pos[1]), _x(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 += [line]
self.hilightpos = target
self.dirty = 1
if gline.command not in ["G0", "G1", "G2", "G3"]:
return
target = self.hilightpos[:] if hilight else self.lastpos[:]
target[5] = 0.0
target[6] = 0.0
if gline.x != None: target[0] = gline.x
if gline.y != None: target[1] = gline.y
if gline.z != None: target[2] = gline.z
if gline.e != None: target[3] = gline.e
if gline.f != None: target[4] = gline.f
if gline.i != None: target[5] = gline.i
if gline.j != None: target[6] = gline.j
if gcode[0] in [ "g2", "g3" ]:
target = _readgcode()
arc = []
arc += [ _x(start_pos[0]), _y(start_pos[1]) ]
arc += [ _x(target[0]), _y(target[1]) ]
arc += [ _x(start_pos[0] + target[5]), _y(start_pos[1] + target[6]) ] # center
if gcode[0] == "g2": # clockwise, reverse endpoints
z = target[2]
if not hilight and z not in self.layers:
self.lines[z] = []
self.pens[z] = []
self.arcs[z] = []
self.arcpens[z] = []
self.layers.append(z)
if gline.command in ["G0", "G1"]:
line = [_x(start_pos[0]), _y(start_pos[1]), _x(target[0]), _y(target[1])]
if not hilight:
self.lines[z].append((_x(start_pos[0]), _y(start_pos[1]), _x(target[0]), _y(target[1])))
self.pens[z].append(self.mainpen if target[3] != self.lastpos[3] else self.travelpen)
else:
self.hilight.append(line)
elif gline.command in ["G2", "G3"]:
# startpos, endpos, arc center
arc = [_x(start_pos[0]), _y(start_pos[1]),
_x(target[0]), _y(target[1]),
_x(start_pos[0] + target[5]), _y(start_pos[1] + target[6])]
if gline.command == "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
self.arcs[z].append(arc)
self.arcpens[z].append(self.arcpen)
else:
self.hilightarcs += [arc]
self.hilightpos = target
self.dirty = 1
self.hilightarcs.append(arc)
if not hilight:
self.lastpos = target
else:
self.hilightpos = target
self.dirty = 1
self.Refresh()
if __name__ == '__main__':
import sys

View File

@ -211,6 +211,113 @@ class ButtonEdit(wx.Dialog):
if self.name.GetValue()=="":
self.name.SetValue(macro)
class TempGauge(wx.Panel):
def __init__(self, parent, size = (200, 22), title = "", maxval = 240, gaugeColour = None):
wx.Panel.__init__(self, parent,-1, size = size)
self.Bind(wx.EVT_PAINT, self.paint)
self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
self.width, self.height = size
self.title = title
self.max = maxval
self.gaugeColour = gaugeColour
self.value = 0
self.setpoint = 0
self.recalc()
def recalc(self):
mmax = max(int(self.setpoint*1.05), self.max)
self.scale = float(self.width-2)/float(mmax)
self.ypt = max(16, int(self.scale*max(self.setpoint, self.max/6)))
def SetValue(self, value):
self.value = value
wx.CallAfter(self.Refresh)
def SetTarget(self, value):
self.setpoint = value
wx.CallAfter(self.Refresh)
def interpolatedColour(self, val, vmin, vmid, vmax, cmin, cmid, cmax):
if val < vmin: return cmin
if val > vmax: return cmax
if val <= vmid:
lo, hi, val, valhi = cmin, cmid, val-vmin, vmid-vmin
else:
lo, hi, val, valhi = cmid, cmax, val-vmid, vmax-vmid
vv = float(val)/valhi
rgb = lo.Red()+(hi.Red()-lo.Red())*vv, lo.Green()+(hi.Green()-lo.Green())*vv, lo.Blue()+(hi.Blue()-lo.Blue())*vv
rgb = map(lambda x:x*0.8, rgb)
return wx.Colour(*map(int, rgb))
def paint(self, ev):
self.width, self.height = self.GetClientSizeTuple()
self.recalc()
x0, y0, x1, y1, xE, yE = 1, 1, self.ypt+1, 1, self.width+1-2, 20
dc = wx.PaintDC(self)
dc.SetBackground(wx.Brush((255, 255, 255)))
dc.Clear()
cold, medium, hot = wx.Colour(0, 167, 223), wx.Colour(239, 233, 119), wx.Colour(210, 50.100)
gauge1, gauge2 = wx.Colour(255, 255, 210), (self.gaugeColour or wx.Colour(234, 82, 0))
shadow1, shadow2 = wx.Colour(110, 110, 110), wx.Colour(255, 255, 255)
gc = wx.GraphicsContext.Create(dc)
# draw shadow first
# corners
gc.SetBrush(gc.CreateRadialGradientBrush(xE-7, 9, xE-7, 9, 8, shadow1, shadow2))
gc.DrawRectangle(xE-7, 1, 8, 8)
gc.SetBrush(gc.CreateRadialGradientBrush(xE-7, 17, xE-7, 17, 8, shadow1, shadow2))
gc.DrawRectangle(xE-7, 17, 8, 8)
gc.SetBrush(gc.CreateRadialGradientBrush(x0+6, 17, x0+6, 17, 8, shadow1, shadow2))
gc.DrawRectangle(0, 17, x0+6, 8)
# edges
gc.SetBrush(gc.CreateLinearGradientBrush(xE-6, 0, xE+1, 0, shadow1, shadow2))
gc.DrawRectangle(xE-7, 9, 8, 8)
gc.SetBrush(gc.CreateLinearGradientBrush(x0, yE-2, x0, yE+5, shadow1, shadow2))
gc.DrawRectangle(x0+6, yE-2, xE-12, 7)
# draw gauge background
gc.SetBrush(gc.CreateLinearGradientBrush(x0, y0, x1+1, y1, cold, medium))
gc.DrawRoundedRectangle(x0, y0, x1+4, yE, 6)
gc.SetBrush(gc.CreateLinearGradientBrush(x1-2, y1, xE, y1, medium, hot))
gc.DrawRoundedRectangle(x1-2, y1, xE-x1, yE, 6)
# draw gauge
width = 12
w1 = y0+9-width/2
w2 = w1+width
value = x0+max(10, min(self.width+1-2, int(self.value*self.scale)))
#gc.SetBrush(gc.CreateLinearGradientBrush(x0, y0+3, x0, y0+15, gauge1, gauge2))
#gc.SetBrush(gc.CreateLinearGradientBrush(0, 3, 0, 15, wx.Colour(255, 255, 255), wx.Colour(255, 90, 32)))
gc.SetBrush(gc.CreateLinearGradientBrush(x0, y0+3, x0, y0+15, gauge1, self.interpolatedColour(value, x0, x1, xE, cold, medium, hot)))
val_path = gc.CreatePath()
val_path.MoveToPoint(x0, w1)
val_path.AddLineToPoint(value, w1)
val_path.AddLineToPoint(value+2, w1+width/4)
val_path.AddLineToPoint(value+2, w2-width/4)
val_path.AddLineToPoint(value, w2)
#val_path.AddLineToPoint(value-4, 10)
val_path.AddLineToPoint(x0, w2)
gc.DrawPath(val_path)
# draw setpoint markers
setpoint = x0+max(10, int(self.setpoint*self.scale))
gc.SetBrush(gc.CreateBrush(wx.Brush(wx.Colour(0, 0, 0))))
setp_path = gc.CreatePath()
setp_path.MoveToPoint(setpoint-4, y0)
setp_path.AddLineToPoint(setpoint+4, y0)
setp_path.AddLineToPoint(setpoint, y0+5)
setp_path.MoveToPoint(setpoint-4, yE)
setp_path.AddLineToPoint(setpoint+4, yE)
setp_path.AddLineToPoint(setpoint, yE-5)
gc.DrawPath(setp_path)
# draw readout
text = u"T\u00B0 %u/%u"%(self.value, self.setpoint)
#gc.SetFont(gc.CreateFont(wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD), wx.WHITE))
#gc.DrawText(text, 29,-2)
gc.SetFont(gc.CreateFont(wx.Font(10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD), wx.WHITE))
gc.DrawText(self.title, x0+19, y0+4)
gc.DrawText(text, x0+119, y0+4)
gc.SetFont(gc.CreateFont(wx.Font(10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)))
gc.DrawText(self.title, x0+18, y0+3)
gc.DrawText(text, x0+118, y0+3)
class SpecialButton(object):
label = None

View File

@ -60,8 +60,7 @@ class XYButtons(BufferedCanvas):
self.bgcolor.SetFromName(bgcolor)
self.bgcolormask = wx.Colour(self.bgcolor.Red(), self.bgcolor.Green(), self.bgcolor.Blue(), 128)
BufferedCanvas.__init__(self, parent, ID)
self.SetSize(self.bg_bmp.GetSize())
BufferedCanvas.__init__(self, parent, ID, size=self.bg_bmp.GetSize())
# Set up mouse and keyboard event capture
self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)

View File

@ -46,9 +46,7 @@ class ZButtons(BufferedCanvas):
self.bgcolor.SetFromName(bgcolor)
self.bgcolormask = wx.Colour(self.bgcolor.Red(), self.bgcolor.Green(), self.bgcolor.Blue(), 128)
BufferedCanvas.__init__(self, parent, ID)
self.SetSize(wx.Size(59, 244))
BufferedCanvas.__init__(self, parent, ID, size=wx.Size(59, 244))
# Set up mouse and keyboard event capture
self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)

View File

@ -1207,12 +1207,12 @@ class pronsole(cmd.Cmd):
self.log("home e - set extruder position to zero (Using G92)")
self.log("home xyze - homes all axes and zeroes the extruder (Using G28 and G92)")
def parse_cmdline(self, args):
parser = argparse.ArgumentParser(description = 'Printrun 3D printer interface')
def add_cmdline_arguments(self, parser):
parser.add_argument('-c','--conf','--config', help = _("load this file on startup instead of .pronsolerc ; you may chain config files, if so settings auto-save will use the last specified file"), action = "append", default = [])
parser.add_argument('-e','--execute', help = _("executes command after configuration/.pronsolerc is loaded ; macros/settings from these commands are not autosaved"), action = "append", default = [])
parser.add_argument('filename', nargs='?', help = _("file to load"))
args = parser.parse_args()
def process_cmdline_arguments(self, args):
for config in args.conf:
self.load_rc(config)
if not self.rc_loaded:
@ -1224,6 +1224,12 @@ class pronsole(cmd.Cmd):
if args.filename:
self.do_load(args.filename)
def parse_cmdline(self, args):
parser = argparse.ArgumentParser(description = 'Printrun 3D printer interface')
self.add_cmdline_arguments(parser)
args = parser.parse_args()
self.process_cmdline_arguments(args)
# We replace this function, defined in cmd.py .
# It's default behavior with reagrds to Ctr-C
# and Ctr-D doesn't make much sense...

View File

@ -198,15 +198,23 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if self.filename is not None:
self.do_load(self.filename)
def add_cmdline_arguments(self, parser):
pronsole.pronsole.add_cmdline_arguments(self, parser)
parser.add_argument('-g','--gauges', help = _("display graphical temperature gauges in addition to the temperatures graph"), action = "store_true")
def process_cmdline_arguments(self, args):
pronsole.pronsole.process_cmdline_arguments(self, args)
self.display_gauges = args.gauges
def startcb(self):
self.starttime = time.time()
print "Print Started at: " + format_time(self.starttime)
def endcb(self):
if self.p.queueindex == 0:
print "Print ended at: " + format_time(time.time())
print_duration = int(time.time () - self.starttime + self.extra_print_time)
print "and took: " + format_duration(print_duration)
print _("Print ended at: %(end_time)s and took %(duration)s") % {"end_time": format_time(time.time()),
"duration": format_duration(print_duration)}
wx.CallAfter(self.pausebtn.Disable)
wx.CallAfter(self.printbtn.SetLabel, _("Print"))
@ -239,7 +247,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if "G1" in line:
if "Z" in line:
try:
layer = float(line.split("Z")[1].split()[0])
layer = float(line.split("Z")[1].split()[0].split("*")[0])
if layer != self.curlayer:
self.curlayer = layer
self.gviz.hilight = []
@ -256,6 +264,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if "S" in line:
try:
temp = float(line.split("S")[1].split("*")[0])
if self.display_gauges: wx.CallAfter(self.hottgauge.SetTarget, temp)
wx.CallAfter(self.graph.SetExtruder0TargetTemperature, temp)
except:
pass
@ -267,6 +276,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if "S" in line:
try:
temp = float(line.split("S")[1].split("*")[0])
if self.display_gauges: wx.CallAfter(self.bedtgauge.SetTarget, temp)
wx.CallAfter(self.graph.SetBedTargetTemperature, temp)
except:
pass
@ -293,6 +303,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def setbedgui(self, f):
self.bsetpoint = f
if self.display_gauges: self.bedtgauge.SetTarget(int(f))
wx.CallAfter(self.graph.SetBedTargetTemperature, int(f))
if f>0:
wx.CallAfter(self.btemp.SetValue, str(f))
@ -312,6 +323,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def sethotendgui(self, f):
self.hsetpoint = f
if self.display_gauges: self.hottgauge.SetTarget(int(f))
wx.CallAfter(self.graph.SetExtruder0TargetTemperature, int(f))
if f > 0:
wx.CallAfter(self.htemp.SetValue, str(f))
@ -591,7 +603,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
wx.CallAfter(self.btemp.SetInsertionPoint, 0)
def showwin(self, event):
if(self.f is not None):
if self.f is not None:
self.gwindow.Show(True)
self.gwindow.SetToolTip(wx.ToolTip("Mousewheel zooms the display\nShift / Mousewheel scrolls layers"))
self.gwindow.Raise()
@ -1015,8 +1027,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
try:
self.logbox.AppendText(text)
except:
print "attempted to write invalid text to console"
pass
print _("Attempted to write invalid text to console, which could be due to an invalid baudrate")
def setloud(self,e):
self.p.loud=e.IsChecked()
@ -1034,15 +1045,22 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def clearOutput(self, e):
self.logbox.Clear()
def update_tempdisplay(self):
try:
hotend_temp = parse_temperature_report(self.tempreport, "T:")
wx.CallAfter(self.graph.SetExtruder0Temperature, hotend_temp)
if self.display_gauges: wx.CallAfter(self.hottgauge.SetValue, hotend_temp)
bed_temp = parse_temperature_report(self.tempreport, "B:")
wx.CallAfter(self.graph.SetBedTemperature, bed_temp)
if self.display_gauges: wx.CallAfter(self.bedtgauge.SetValue, bed_temp)
except:
traceback.print_exc()
def statuschecker(self):
while self.statuscheck:
string = ""
wx.CallAfter(self.tempdisp.SetLabel, self.tempreport.strip().replace("ok ", ""))
try:
wx.CallAfter(self.graph.SetExtruder0Temperature, parse_temperature_report(self.tempreport, "T:"))
wx.CallAfter(self.graph.SetBedTemperature, parse_temperature_report(self.tempreport, "B:"))
except:
pass
self.update_tempdisplay()
fractioncomplete = 0.0
if self.sdprinting:
fractioncomplete = float(self.percentdone / 100.0)
@ -1103,11 +1121,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if "T:" in l:
self.tempreport = l
wx.CallAfter(self.tempdisp.SetLabel, self.tempreport.strip().replace("ok ", ""))
try:
wx.CallAfter(self.graph.SetExtruder0Temperature, parse_temperature_report(self.tempreport, "T:"))
wx.CallAfter(self.graph.SetBedTemperature, parse_temperature_report(self.tempreport, "B:"))
except:
traceback.print_exc()
self.update_tempdisplay()
tstring = l.rstrip()
#print tstring
if (tstring!="ok") and (tstring!="wait") and ("ok T:" not in tstring) and (not self.p.loud):
@ -1286,15 +1300,10 @@ class PronterWindow(MainWindow, pronsole.pronsole):
print _("the print goes from %f mm to %f mm in Y\nand is %f mm wide\n") % (gcode.ymin, gcode.ymax, gcode.depth)
print _("the print goes from %f mm to %f mm in Z\nand is %f mm high\n") % (gcode.zmin, gcode.zmax, gcode.height)
print _("Estimated duration (pessimistic): "), gcode.estimate_duration()
#import time
#t0 = time.time()
self.gviz.clear()
self.gwindow.p.clear()
self.gviz.addfile(self.f)
#print "generated 2d view in %f s"%(time.time()-t0)
#t0 = time.time()
self.gwindow.p.addfile(self.f)
#print "generated 3d view in %f s"%(time.time()-t0)
self.gviz.addfile(gcode)
self.gwindow.p.addfile(gcode)
self.gviz.showall = 1
wx.CallAfter(self.gviz.Refresh)
@ -1516,5 +1525,5 @@ if __name__ == '__main__':
main.Show()
try:
app.MainLoop()
except:
except KeyboardInterrupt:
pass