Commit e29dd70e authored by Guillaume Seguin's avatar Guillaume Seguin

Merge branch 'experimental' into HEAD

Conflicts:
	printrun/gviz.py
parents 68c13162 7657b375
...@@ -3,3 +3,4 @@ ...@@ -3,3 +3,4 @@
*.swp *.swp
*.bak *.bak
uploads uploads
.DS_Store
...@@ -25,9 +25,19 @@ You can run Printrun directly from source, as there are no packages available ye ...@@ -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` `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` `sudo yum install pyserial wxpython pyglet`
......
...@@ -461,12 +461,12 @@ if __name__ == '__main__': ...@@ -461,12 +461,12 @@ if __name__ == '__main__':
try: try:
if statusreport: if statusreport:
p.loud = False p.loud = False
sys.stdout.write("Progress: 00.0%") sys.stdout.write("Progress: 00.0%\r")
sys.stdout.flush() sys.stdout.flush()
while p.printing: while p.printing:
time.sleep(1) time.sleep(1)
if statusreport: 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() sys.stdout.flush()
p.disconnect() p.disconnect()
sys.exit(0) sys.exit(0)
......
...@@ -77,7 +77,7 @@ class BufferedCanvas(wx.Panel): ...@@ -77,7 +77,7 @@ class BufferedCanvas(wx.Panel):
## General methods ## General methods
## ##
def draw(self, dc): def draw(self, dc, w, h):
""" """
Stub: called when the canvas needs to be re-drawn. Stub: called when the canvas needs to be re-drawn.
""" """
......
...@@ -47,10 +47,13 @@ class Line(object): ...@@ -47,10 +47,13 @@ class Line(object):
if ";" in self.raw: if ";" in self.raw:
self.raw = self.raw.split(";")[0].rstrip() self.raw = self.raw.split(";")[0].rstrip()
self.split_raw = self.raw.split(" ") 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"] self.is_move = self.command in ["G0", "G1"]
def parse_coordinates(self, imperial): 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: if imperial:
for bit in self.split_raw: for bit in self.split_raw:
code = bit[0] code = bit[0]
......
...@@ -23,14 +23,13 @@ class Graph(BufferedCanvas): ...@@ -23,14 +23,13 @@ class Graph(BufferedCanvas):
'''A class to show a Graph with Pronterface.''' '''A class to show a Graph with Pronterface.'''
def __init__(self, parent, id, pos = wx.DefaultPosition, 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 # Forcing a no full repaint to stop flickering
style = style | wx.NO_FULL_REPAINT_ON_RESIZE style = style | wx.NO_FULL_REPAINT_ON_RESIZE
#call super function #call super function
#super(Graph, self).__init__(parent, id, pos, size, style) super(Graph, self).__init__(parent, id, pos, size, style)
BufferedCanvas.__init__(self, parent, id) #BufferedCanvas.__init__(self, parent, id)
self.SetSize(wx.Size(150, 80))
self.extruder0temps = [0] self.extruder0temps = [0]
self.extruder0targettemps = [0] self.extruder0targettemps = [0]
...@@ -80,8 +79,7 @@ class Graph(BufferedCanvas): ...@@ -80,8 +79,7 @@ class Graph(BufferedCanvas):
#b = gc.CreateLinearGradientBrush(0, 0, w, h, col1, col2) #b = gc.CreateLinearGradientBrush(0, 0, w, h, col1, col2)
gc.SetPen(wx.Pen(wx.Colour(255, 0, 0, 0), 4)) 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(gc.CreateBrush(wx.Brush(wx.Colour(0, 0, 0, 0))))
#gc.SetBrush(b)
gc.DrawRectangle(0, 0, self.width, self.height) gc.DrawRectangle(0, 0, self.width, self.height)
#gc.SetBrush(wx.Brush(wx.Colour(245, 245, 255, 52))) #gc.SetBrush(wx.Brush(wx.Colour(245, 245, 255, 52)))
......
...@@ -26,6 +26,7 @@ from printrun import gviz ...@@ -26,6 +26,7 @@ from printrun import gviz
from printrun.xybuttons import XYButtons from printrun.xybuttons import XYButtons
from printrun.zbuttons import ZButtons from printrun.zbuttons import ZButtons
from printrun.graph import Graph 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): def make_button(parent, label, callback, tooltip, container = None, size = wx.DefaultSize, style = 0):
button = wx.Button(parent, -1, label, style = style, size = size) button = wx.Button(parent, -1, label, style = style, size = size)
...@@ -56,9 +57,9 @@ class LeftPane(wx.GridBagSizer): ...@@ -56,9 +57,9 @@ class LeftPane(wx.GridBagSizer):
def __init__(self, root): def __init__(self, root):
super(LeftPane, self).__init__() super(LeftPane, self).__init__()
llts = wx.BoxSizer(wx.HORIZONTAL) 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.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: for i in root.cpbuttons:
btn = make_button(root.panel, i.label, root.procbutton, i.tooltip, style = wx.BU_EXACTFIT) btn = make_button(root.panel, i.label, root.procbutton, i.tooltip, style = wx.BU_EXACTFIT)
...@@ -84,7 +85,7 @@ class LeftPane(wx.GridBagSizer): ...@@ -84,7 +85,7 @@ class LeftPane(wx.GridBagSizer):
root.monitorbox = wx.CheckBox(root.panel,-1, _("Watch")) root.monitorbox = wx.CheckBox(root.panel,-1, _("Watch"))
root.monitorbox.SetToolTip(wx.ToolTip("Monitor Temperatures in Graph")) 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) 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) 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): ...@@ -164,9 +165,31 @@ class LeftPane(wx.GridBagSizer):
root.zfeedc.SetBackgroundColour((180, 255, 180)) root.zfeedc.SetBackgroundColour((180, 255, 180))
root.zfeedc.SetForegroundColour("black") 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) root.graph = Graph(root.panel, wx.ID_ANY)
self.Add(root.graph, pos = (3, 5), span = (3, 3)) self.Add(root.graph, pos = (4, 5), span = (2, 1))
self.Add(root.tempdisp, pos = (6, 0), span = (1, 9))
class VizPane(wx.BoxSizer): class VizPane(wx.BoxSizer):
...@@ -199,6 +222,7 @@ class LogPane(wx.BoxSizer): ...@@ -199,6 +222,7 @@ class LogPane(wx.BoxSizer):
super(LogPane, self).__init__(wx.VERTICAL) super(LogPane, self).__init__(wx.VERTICAL)
root.lowerrsizer = self root.lowerrsizer = self
root.logbox = wx.TextCtrl(root.panel, style = wx.TE_MULTILINE, size = (350,-1)) root.logbox = wx.TextCtrl(root.panel, style = wx.TE_MULTILINE, size = (350,-1))
root.logbox.SetMinSize((100,-1))
root.logbox.SetEditable(0) root.logbox.SetEditable(0)
self.Add(root.logbox, 1, wx.EXPAND) self.Add(root.logbox, 1, wx.EXPAND)
lbrs = wx.BoxSizer(wx.HORIZONTAL) lbrs = wx.BoxSizer(wx.HORIZONTAL)
...@@ -223,7 +247,7 @@ class MainToolbar(wx.BoxSizer): ...@@ -223,7 +247,7 @@ class MainToolbar(wx.BoxSizer):
root.serialport = wx.ComboBox(root.panel, -1, root.serialport = wx.ComboBox(root.panel, -1,
choices = root.scanserial(), 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.serialport.SetToolTip(wx.ToolTip("Select Port Printer is connected to"))
root.rescanports() root.rescanports()
self.Add(root.serialport) self.Add(root.serialport)
...@@ -263,10 +287,10 @@ class MainWindow(wx.Frame): ...@@ -263,10 +287,10 @@ class MainWindow(wx.Frame):
self.mainsizer = wx.BoxSizer(wx.VERTICAL) self.mainsizer = wx.BoxSizer(wx.VERTICAL)
self.uppersizer = MainToolbar(self) self.uppersizer = MainToolbar(self)
self.lowersizer = wx.BoxSizer(wx.HORIZONTAL) 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(VizPane(self), 1, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL)
self.lowersizer.Add(LogPane(self), 0, wx.EXPAND) self.lowersizer.Add(LogPane(self), 1, wx.EXPAND)
self.mainsizer.Add(self.uppersizer) self.mainsizer.Add(self.uppersizer, 0)
self.mainsizer.Add(self.lowersizer, 1, wx.EXPAND) self.mainsizer.Add(self.lowersizer, 1, wx.EXPAND)
self.panel.SetSizer(self.mainsizer) self.panel.SetSizer(self.mainsizer)
self.status = self.CreateStatusBar() self.status = self.CreateStatusBar()
...@@ -276,6 +300,12 @@ class MainWindow(wx.Frame): ...@@ -276,6 +300,12 @@ class MainWindow(wx.Frame):
self.mainsizer.Layout() self.mainsizer.Layout()
self.mainsizer.Fit(self) 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 # disable all printer controls until we connect to a printer
self.pausebtn.Disable() self.pausebtn.Disable()
......
...@@ -44,8 +44,8 @@ class window(wx.Frame): ...@@ -44,8 +44,8 @@ class window(wx.Frame):
vbox.Add(self.p, 1, wx.EXPAND) vbox.Add(self.p, 1, wx.EXPAND)
panel.SetSizer(vbox) panel.SetSizer(vbox)
self.SetMinSize(self.ClientToWindowSize(vbox.GetMinSize())) 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(-1, -1, 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/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.layerup(), id = 3)
self.Bind(wx.EVT_TOOL, lambda x:self.p.layerdown(), id = 4) self.Bind(wx.EVT_TOOL, lambda x:self.p.layerdown(), id = 4)
self.Bind(wx.EVT_TOOL, self.resetview, id = 5) self.Bind(wx.EVT_TOOL, self.resetview, id = 5)
...@@ -123,6 +123,17 @@ class window(wx.Frame): ...@@ -123,6 +123,17 @@ class window(wx.Frame):
elif z < 0: self.p.zoom(event.GetX(), event.GetY(), 1/1.2) elif z < 0: self.p.zoom(event.GetX(), event.GetY(), 1/1.2)
class gviz(wx.Panel): 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): 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) wx.Panel.__init__(self, parent, -1, size = size)
self.SetMinSize((150, 150)) self.SetMinSize((150, 150))
...@@ -202,18 +213,18 @@ class gviz(wx.Panel): ...@@ -202,18 +213,18 @@ class gviz(wx.Panel):
pass pass
def resize(self, event): def resize(self, event):
oldwidth, oldheight = max(1.0, self.size[0]), max(1.0, self.size[1]) oldside = max(1.0, min(self.size))
oldside = min(oldwidth, oldheight) self.size = self.GetClientSizeTuple()
newwidth, newheight = self.GetClientSizeTuple() newside = max(1.0, min(self.size))
newwidth, newheight = [max(1.0, newwidth), max(1.0, newheight)] self.basescale = 2*[min(float(self.size[0])/self.build_dimensions[0],
newside = min(newwidth, newheight) float(self.size[1])/self.build_dimensions[1])]
zoomratio = float(newside) / oldside zoomratio = float(newside) / oldside
print newwidth, newheight
print zoomratio
self.size = self.GetClientSize()
wx.CallAfter(self.zoom, 0, 0, zoomratio) wx.CallAfter(self.zoom, 0, 0, zoomratio)
def zoom(self, x, y, factor): 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.scale = [s * factor for s in self.scale]
self.translate = [ x - (x-self.translate[0]) * factor, self.translate = [ x - (x-self.translate[0]) * factor,
...@@ -291,14 +302,18 @@ class gviz(wx.Panel): ...@@ -291,14 +302,18 @@ class gviz(wx.Panel):
def paint(self, event): def paint(self, event):
dc = wx.PaintDC(self) dc = wx.PaintDC(self)
if self.dirty: if self.dirty:
self.repaint()
self.dirty = 0 self.dirty = 0
self.repaint()
dc.DrawBitmap(self.blitmap, 0, 0) dc.DrawBitmap(self.blitmap, 0, 0)
def addfile(self, gcode): def addfile(self, gcode):
self.clear() self.clear()
self.add_parsed_gcodes(gcode.lines) 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 add_parsed_gcodes(self, lines):
def _y(y): def _y(y):
return self.build_dimensions[1] - (y - self.build_dimensions[4]) return self.build_dimensions[1] - (y - self.build_dimensions[4])
...@@ -312,10 +327,19 @@ class gviz(wx.Panel): ...@@ -312,10 +327,19 @@ class gviz(wx.Panel):
target = self.lastpos[:] target = self.lastpos[:]
target[5] = 0.0 target[5] = 0.0
target[6] = 0.0 target[6] = 0.0
if gline.x != None: target[0] = gline.x if gline.relative:
if gline.y != None: target[1] = gline.y if gline.x != None: target[0] += gline.x
if gline.z != None: target[2] = gline.z if gline.y != None: target[1] += gline.y
if gline.e != None: target[3] = gline.e 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.f != None: target[4] = gline.f
if gline.i != None: target[5] = gline.i if gline.i != None: target[5] = gline.i
if gline.j != None: target[6] = gline.j if gline.j != None: target[6] = gline.j
...@@ -330,100 +354,88 @@ class gviz(wx.Panel): ...@@ -330,100 +354,88 @@ class gviz(wx.Panel):
start_pos = self.lastpos[:] start_pos = self.lastpos[:]
if gline.command in ["G0", "G1"]: 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((_x(start_pos[0]), _y(start_pos[1]), _x(target[0]), _y(target[1])))
self.lines[z].append(line)
self.pens[z].append(self.mainpen if target[3] != self.lastpos[3] else self.travelpen) self.pens[z].append(self.mainpen if target[3] != self.lastpos[3] else self.travelpen)
self.lastpos = target elif gline.command in ["G2", "G3"]:
self.dirty = 1 # startpos, endpos, arc center
if gline.command in ["G2", "G3"]:
arc = [_x(start_pos[0]), _y(start_pos[1]), arc = [_x(start_pos[0]), _y(start_pos[1]),
_x(target[0]), _y(target[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 # FIXME : verify this works : why not reverse endpoints 4, 5
if gline.command == "G2": # clockwise, reverse endpoints if gline.command == "G2": # clockwise, reverse endpoints
arc[0], arc[1], arc[2], arc[3] = arc[2], arc[3], arc[0], arc[1] arc[0], arc[1], arc[2], arc[3] = arc[2], arc[3], arc[0], arc[1]
self.arcs[z].append(arc) self.arcs[z].append(arc)
self.arcpens[z].append(self.arcpen) 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): def addgcode(self, gcode = "M105", hilight = 0):
gcode = gcode.split("*")[0] gcode = gcode.split("*")[0]
gcode = gcode.split(";")[0] gcode = gcode.split(";")[0]
gcode = gcode.lower().strip().split() gcode = gcode.lower().strip()
if not gcode: if not gcode:
return return
if gcode[0][0] == 'n': # not sure what this check is for ? gline = gcoder.Line(gcode)
gcode.pop(0) gline.parse_coordinates(False)
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
def _y(y): 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): def _x(x):
return x-self.build_dimensions[3] return x - self.build_dimensions[3]
start_pos = self.hilightpos[:] if hilight else self.lastpos[:] start_pos = self.hilightpos[:] if hilight else self.lastpos[:]
if gcode[0] in [ "g0", "g1" ]: if gline.command not in ["G0", "G1", "G2", "G3"]:
target = _readgcode() return
line = [ _x(start_pos[0]), _y(start_pos[1]), _x(target[0]), _y(target[1]) ]
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
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: if not hilight:
self.lines[ target[2] ] += [line] self.lines[z].append((_x(start_pos[0]), _y(start_pos[1]), _x(target[0]), _y(target[1])))
self.pens[ target[2] ] += [self.mainpen if target[3] != self.lastpos[3] else self.travelpen] self.pens[z].append(self.mainpen if target[3] != self.lastpos[3] else self.travelpen)
self.lastpos = target
else: else:
self.hilight += [line] self.hilight.append(line)
self.hilightpos = target elif gline.command in ["G2", "G3"]:
self.dirty = 1 # startpos, endpos, arc center
arc = [_x(start_pos[0]), _y(start_pos[1]),
if gcode[0] in [ "g2", "g3" ]: _x(target[0]), _y(target[1]),
target = _readgcode() _x(start_pos[0] + target[5]), _y(start_pos[1] + target[6])]
arc = [] if gline.command == "G2": # clockwise, reverse endpoints
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
arc[0], arc[1], arc[2], arc[3] = arc[2], arc[3], arc[0], arc[1] arc[0], arc[1], arc[2], arc[3] = arc[2], arc[3], arc[0], arc[1]
if not hilight: self.arcs[z].append(arc)
self.arcs[ target[2] ] += [arc] self.arcpens[z].append(self.arcpen)
self.arcpens[ target[2] ] += [self.arcpen]
self.lastpos = target
else: else:
self.hilightarcs += [arc] self.hilightarcs.append(arc)
self.hilightpos = target
self.dirty = 1 if not hilight:
self.lastpos = target
else:
self.hilightpos = target
self.dirty = 1
self.Refresh()
if __name__ == '__main__': if __name__ == '__main__':
import sys import sys
......
...@@ -211,6 +211,113 @@ class ButtonEdit(wx.Dialog): ...@@ -211,6 +211,113 @@ class ButtonEdit(wx.Dialog):
if self.name.GetValue()=="": if self.name.GetValue()=="":
self.name.SetValue(macro) 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): class SpecialButton(object):
label = None label = None
......
...@@ -60,8 +60,7 @@ class XYButtons(BufferedCanvas): ...@@ -60,8 +60,7 @@ class XYButtons(BufferedCanvas):
self.bgcolor.SetFromName(bgcolor) self.bgcolor.SetFromName(bgcolor)
self.bgcolormask = wx.Colour(self.bgcolor.Red(), self.bgcolor.Green(), self.bgcolor.Blue(), 128) self.bgcolormask = wx.Colour(self.bgcolor.Red(), self.bgcolor.Green(), self.bgcolor.Blue(), 128)
BufferedCanvas.__init__(self, parent, ID) BufferedCanvas.__init__(self, parent, ID, size=self.bg_bmp.GetSize())
self.SetSize(self.bg_bmp.GetSize())
# Set up mouse and keyboard event capture # Set up mouse and keyboard event capture
self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
......
...@@ -46,9 +46,7 @@ class ZButtons(BufferedCanvas): ...@@ -46,9 +46,7 @@ class ZButtons(BufferedCanvas):
self.bgcolor.SetFromName(bgcolor) self.bgcolor.SetFromName(bgcolor)
self.bgcolormask = wx.Colour(self.bgcolor.Red(), self.bgcolor.Green(), self.bgcolor.Blue(), 128) self.bgcolormask = wx.Colour(self.bgcolor.Red(), self.bgcolor.Green(), self.bgcolor.Blue(), 128)
BufferedCanvas.__init__(self, parent, ID) BufferedCanvas.__init__(self, parent, ID, size=wx.Size(59, 244))
self.SetSize(wx.Size(59, 244))
# Set up mouse and keyboard event capture # Set up mouse and keyboard event capture
self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
......
...@@ -1207,12 +1207,12 @@ class pronsole(cmd.Cmd): ...@@ -1207,12 +1207,12 @@ class pronsole(cmd.Cmd):
self.log("home e - set extruder position to zero (Using G92)") 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)") self.log("home xyze - homes all axes and zeroes the extruder (Using G28 and G92)")
def parse_cmdline(self, args): def add_cmdline_arguments(self, parser):
parser = argparse.ArgumentParser(description = 'Printrun 3D printer interface')
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('-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('-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")) parser.add_argument('filename', nargs='?', help = _("file to load"))
args = parser.parse_args()
def process_cmdline_arguments(self, args):
for config in args.conf: for config in args.conf:
self.load_rc(config) self.load_rc(config)
if not self.rc_loaded: if not self.rc_loaded:
...@@ -1224,6 +1224,12 @@ class pronsole(cmd.Cmd): ...@@ -1224,6 +1224,12 @@ class pronsole(cmd.Cmd):
if args.filename: if args.filename:
self.do_load(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 . # We replace this function, defined in cmd.py .
# It's default behavior with reagrds to Ctr-C # It's default behavior with reagrds to Ctr-C
# and Ctr-D doesn't make much sense... # and Ctr-D doesn't make much sense...
......
...@@ -198,15 +198,23 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -198,15 +198,23 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if self.filename is not None: if self.filename is not None:
self.do_load(self.filename) 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): def startcb(self):
self.starttime = time.time() self.starttime = time.time()
print "Print Started at: " + format_time(self.starttime) print "Print Started at: " + format_time(self.starttime)
def endcb(self): def endcb(self):
if self.p.queueindex == 0: 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_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.pausebtn.Disable)
wx.CallAfter(self.printbtn.SetLabel, _("Print")) wx.CallAfter(self.printbtn.SetLabel, _("Print"))
...@@ -239,7 +247,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -239,7 +247,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if "G1" in line: if "G1" in line:
if "Z" in line: if "Z" in line:
try: try:
layer = float(line.split("Z")[1].split()[0]) layer = float(line.split("Z")[1].split()[0].split("*")[0])
if layer != self.curlayer: if layer != self.curlayer:
self.curlayer = layer self.curlayer = layer
self.gviz.hilight = [] self.gviz.hilight = []
...@@ -256,6 +264,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -256,6 +264,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if "S" in line: if "S" in line:
try: try:
temp = float(line.split("S")[1].split("*")[0]) temp = float(line.split("S")[1].split("*")[0])
if self.display_gauges: wx.CallAfter(self.hottgauge.SetTarget, temp)
wx.CallAfter(self.graph.SetExtruder0TargetTemperature, temp) wx.CallAfter(self.graph.SetExtruder0TargetTemperature, temp)
except: except:
pass pass
...@@ -267,6 +276,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -267,6 +276,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if "S" in line: if "S" in line:
try: try:
temp = float(line.split("S")[1].split("*")[0]) temp = float(line.split("S")[1].split("*")[0])
if self.display_gauges: wx.CallAfter(self.bedtgauge.SetTarget, temp)
wx.CallAfter(self.graph.SetBedTargetTemperature, temp) wx.CallAfter(self.graph.SetBedTargetTemperature, temp)
except: except:
pass pass
...@@ -293,6 +303,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -293,6 +303,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def setbedgui(self, f): def setbedgui(self, f):
self.bsetpoint = f self.bsetpoint = f
if self.display_gauges: self.bedtgauge.SetTarget(int(f))
wx.CallAfter(self.graph.SetBedTargetTemperature, int(f)) wx.CallAfter(self.graph.SetBedTargetTemperature, int(f))
if f>0: if f>0:
wx.CallAfter(self.btemp.SetValue, str(f)) wx.CallAfter(self.btemp.SetValue, str(f))
...@@ -312,6 +323,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -312,6 +323,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def sethotendgui(self, f): def sethotendgui(self, f):
self.hsetpoint = f self.hsetpoint = f
if self.display_gauges: self.hottgauge.SetTarget(int(f))
wx.CallAfter(self.graph.SetExtruder0TargetTemperature, int(f)) wx.CallAfter(self.graph.SetExtruder0TargetTemperature, int(f))
if f > 0: if f > 0:
wx.CallAfter(self.htemp.SetValue, str(f)) wx.CallAfter(self.htemp.SetValue, str(f))
...@@ -591,7 +603,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -591,7 +603,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
wx.CallAfter(self.btemp.SetInsertionPoint, 0) wx.CallAfter(self.btemp.SetInsertionPoint, 0)
def showwin(self, event): def showwin(self, event):
if(self.f is not None): if self.f is not None:
self.gwindow.Show(True) self.gwindow.Show(True)
self.gwindow.SetToolTip(wx.ToolTip("Mousewheel zooms the display\nShift / Mousewheel scrolls layers")) self.gwindow.SetToolTip(wx.ToolTip("Mousewheel zooms the display\nShift / Mousewheel scrolls layers"))
self.gwindow.Raise() self.gwindow.Raise()
...@@ -1015,8 +1027,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1015,8 +1027,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
try: try:
self.logbox.AppendText(text) self.logbox.AppendText(text)
except: except:
print "attempted to write invalid text to console" print _("Attempted to write invalid text to console, which could be due to an invalid baudrate")
pass
def setloud(self,e): def setloud(self,e):
self.p.loud=e.IsChecked() self.p.loud=e.IsChecked()
...@@ -1034,15 +1045,22 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1034,15 +1045,22 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def clearOutput(self, e): def clearOutput(self, e):
self.logbox.Clear() 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): def statuschecker(self):
while self.statuscheck: while self.statuscheck:
string = "" string = ""
wx.CallAfter(self.tempdisp.SetLabel, self.tempreport.strip().replace("ok ", "")) wx.CallAfter(self.tempdisp.SetLabel, self.tempreport.strip().replace("ok ", ""))
try: self.update_tempdisplay()
wx.CallAfter(self.graph.SetExtruder0Temperature, parse_temperature_report(self.tempreport, "T:"))
wx.CallAfter(self.graph.SetBedTemperature, parse_temperature_report(self.tempreport, "B:"))
except:
pass
fractioncomplete = 0.0 fractioncomplete = 0.0
if self.sdprinting: if self.sdprinting:
fractioncomplete = float(self.percentdone / 100.0) fractioncomplete = float(self.percentdone / 100.0)
...@@ -1103,11 +1121,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1103,11 +1121,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if "T:" in l: if "T:" in l:
self.tempreport = l self.tempreport = l
wx.CallAfter(self.tempdisp.SetLabel, self.tempreport.strip().replace("ok ", "")) wx.CallAfter(self.tempdisp.SetLabel, self.tempreport.strip().replace("ok ", ""))
try: self.update_tempdisplay()
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()
tstring = l.rstrip() tstring = l.rstrip()
#print tstring #print tstring
if (tstring!="ok") and (tstring!="wait") and ("ok T:" not in tstring) and (not self.p.loud): 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): ...@@ -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 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 _("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() print _("Estimated duration (pessimistic): "), gcode.estimate_duration()
#import time
#t0 = time.time()
self.gviz.clear() self.gviz.clear()
self.gwindow.p.clear() self.gwindow.p.clear()
self.gviz.addfile(self.f) self.gviz.addfile(gcode)
#print "generated 2d view in %f s"%(time.time()-t0) self.gwindow.p.addfile(gcode)
#t0 = time.time()
self.gwindow.p.addfile(self.f)
#print "generated 3d view in %f s"%(time.time()-t0)
self.gviz.showall = 1 self.gviz.showall = 1
wx.CallAfter(self.gviz.Refresh) wx.CallAfter(self.gviz.Refresh)
...@@ -1516,5 +1525,5 @@ if __name__ == '__main__': ...@@ -1516,5 +1525,5 @@ if __name__ == '__main__':
main.Show() main.Show()
try: try:
app.MainLoop() app.MainLoop()
except: except KeyboardInterrupt:
pass pass
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment