Commit 02dccd6a authored by D1plo1d's avatar D1plo1d

Merge branch 'master' of github.com:kliment/Printrun

parents 558e0839 9181adba
......@@ -386,6 +386,8 @@ class GCode(object):
# then calculate the time taken to complete the remaining distance
currenttravel = math.hypot(x - lastx, y - lasty)
if currenttravel == 0 and line.e != None:
currenttravel = abs(line.e) if line.relative_e else abs(line.e - laste)
if f == lastf: # Feedrate hasn't changed, no acceleration/decceleration planned
moveduration = currenttravel / f if f != 0 else 0.
else:
......
......@@ -32,6 +32,8 @@ from .gl.panel import wxGLPanel
from .gl.trackball import trackball, mulquat, build_rotmatrix
from .gl.libtatlin import actors
from .gviz import GvizBaseFrame
from printrun_utils import imagefile, install_locale
install_locale('pronterface')
......@@ -55,6 +57,9 @@ class GcodeViewPanel(wxGLPanel):
self.basequat = [0, 0, 0, 1]
self.mousepos = [0, 0]
def setlayercb(self, layer):
pass
def create_objects(self):
'''create opengl objects when opengl is initialized'''
for obj in self.parent.objects:
......@@ -157,6 +162,7 @@ class GcodeViewPanel(wxGLPanel):
# max_layers + 1 means visualizing all layers with the same color
new_layer = min(max_layers + 1, current_layer + 1)
self.parent.model.num_layers_to_draw = new_layer
self.parent.setlayercb(new_layer)
wx.CallAfter(self.Refresh)
def layerdown(self):
......@@ -165,6 +171,7 @@ class GcodeViewPanel(wxGLPanel):
current_layer = self.parent.model.num_layers_to_draw
new_layer = max(1, current_layer - 1)
self.parent.model.num_layers_to_draw = new_layer
self.parent.setlayercb(new_layer)
wx.CallAfter(self.Refresh)
def wheel(self, event):
......@@ -293,13 +300,16 @@ class GcodeViewMainWrapper(object):
self.objects[-1].model = None
wx.CallAfter(self.Refresh)
class GcodeViewFrame(wx.Frame):
class GcodeViewFrame(GvizBaseFrame):
'''A simple class for using OpenGL with wxPython.'''
def __init__(self, parent, ID, title, build_dimensions, objects = None,
pos = wx.DefaultPosition, size = wx.DefaultSize,
style = wx.DEFAULT_FRAME_STYLE):
super(GcodeViewFrame, self).__init__(parent, ID, title, pos, size, style)
panel, vbox = self.create_base_ui()
self.refresh_timer = wx.CallLater(100, self.Refresh)
self.p = self # Hack for backwards compatibility with gviz API
self.clonefrom = objects
......@@ -309,23 +319,13 @@ class GcodeViewFrame(wx.Frame):
else:
self.model = None
self.objects = [GCObject(self.platform), GCObject(None)]
panel = wx.Panel(self, -1)
self.toolbar.AddLabelTool(6, " " + _("Fit to plate"), wx.Image(imagefile('fit.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), shortHelp = _("Fit to plate [F]"), longHelp = '')
self.toolbar.Realize()
self.glpanel = GcodeViewPanel(panel, build_dimensions = build_dimensions,
realparent = self)
vbox = wx.BoxSizer(wx.VERTICAL)
toolbar = wx.ToolBar(panel, -1, style = wx.TB_HORIZONTAL | wx.NO_BORDER | wx.TB_HORZ_TEXT)
toolbar.AddSimpleTool(1, wx.Image(imagefile('zoom_in.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), _("Zoom In [+]"), '')
toolbar.AddSimpleTool(2, wx.Image(imagefile('zoom_out.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), _("Zoom Out [-]"), '')
toolbar.AddSeparator()
toolbar.AddSimpleTool(3, wx.Image(imagefile('arrow_up.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), _("Move Up a Layer [U]"), '')
toolbar.AddSimpleTool(4, wx.Image(imagefile('arrow_down.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), _("Move Down a Layer [D]"), '')
toolbar.AddLabelTool(5, " " + _("Reset view"), wx.Image(imagefile('reset.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), shortHelp = _("Reset view [R]"), longHelp = '')
toolbar.AddLabelTool(6, " " + _("Fit to plate"), wx.Image(imagefile('fit.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), shortHelp = _("Fit to plate [F]"), longHelp = '')
toolbar.Realize()
self.toolbar = toolbar
vbox.Add(toolbar, 0, border = 5)
vbox.Add(self.glpanel, 1, wx.EXPAND)
panel.SetSizer(vbox)
vbox.Add(self.glpanel, 1, flag = wx.EXPAND)
self.Bind(wx.EVT_TOOL, lambda x: self.glpanel.zoom_to_center(1.2), id = 1)
self.Bind(wx.EVT_TOOL, lambda x: self.glpanel.zoom_to_center(1/1.2), id = 2)
self.Bind(wx.EVT_TOOL, lambda x: self.glpanel.layerup(), id = 3)
......@@ -333,6 +333,12 @@ class GcodeViewFrame(wx.Frame):
self.Bind(wx.EVT_TOOL, lambda x: self.glpanel.resetview(), id = 5)
self.Bind(wx.EVT_TOOL, lambda x: self.glpanel.fit(), id = 6)
def process_slider(self, event):
new_layer = self.layerslider.GetValue()
new_layer = min(self.model.max_layers + 1, new_layer)
new_layer = max(1, new_layer)
self.model.num_layers_to_draw = new_layer
wx.CallAfter(self.Refresh)
def set_current_gline(self, gline):
if gline.is_move and self.model and self.model.loaded:
......@@ -348,6 +354,8 @@ class GcodeViewFrame(wx.Frame):
if gcode:
self.model.load_data(gcode)
self.objects[-1].model = self.model
self.layerslider.SetRange(1, self.model.max_layers + 1)
self.layerslider.SetValue(self.model.max_layers + 1)
wx.CallAfter(self.Refresh)
def clear(self):
......
......@@ -345,9 +345,18 @@ class LogPane(wx.BoxSizer):
def MainToolbar(root, parentpanel = None, use_wrapsizer = False):
if not parentpanel: parentpanel = root.panel
if root.settings.lockbox:
root.locker = wx.CheckBox(parentpanel, label = _("Lock") + " ")
root.locker.Bind(wx.EVT_CHECKBOX, root.lock)
root.locker.SetToolTip(wx.ToolTip(_("Lock graphical interface")))
glob = wx.BoxSizer(wx.HORIZONTAL)
origpanel = parentpanel
parentpanel = root.newPanel(parentpanel)
glob.Add(parentpanel, 1, flag = wx.EXPAND)
glob.Add(root.locker, 0)
ToolbarSizer = wx.WrapSizer if use_wrapsizer and wx.VERSION > (2, 9) else wx.BoxSizer
self = ToolbarSizer(wx.HORIZONTAL)
if not parentpanel: parentpanel = root.panel
root.rescanbtn = make_sized_button(parentpanel, _("Port"), root.rescanports, _("Communication Settings\nClick to rescan ports"))
self.Add(root.rescanbtn, 0, wx.TOP|wx.LEFT, 0)
......@@ -380,7 +389,11 @@ def MainToolbar(root, parentpanel = None, use_wrapsizer = False):
root.pausebtn = make_sized_button(parentpanel, _("Pause"), root.pause, _("Pause Current Print"), self)
root.offbtn = make_sized_button(parentpanel, _("Off"), root.off, _("Turn printer off"), self)
root.printerControls.append(root.offbtn)
return self
if root.settings.lockbox:
parentpanel.SetSizer(self)
return glob
else:
return self
class MainWindow(wx.Frame):
......@@ -389,10 +402,13 @@ class MainWindow(wx.Frame):
# this list will contain all controls that should be only enabled
# when we're connected to a printer
self.printerControls = []
self.panel = wx.Panel(self, -1, size = kwargs["size"])
self.panels = []
def newPanel(self, parent):
def newPanel(self, parent, add_to_list = True):
panel = wx.Panel(parent)
panel.SetBackgroundColour(self.settings.bgcolor)
if add_to_list: self.panels.append(panel)
return panel
def createTabbedGui(self):
......@@ -469,7 +485,7 @@ class MainWindow(wx.Frame):
def createGui(self, compact = False):
self.mainsizer = wx.BoxSizer(wx.VERTICAL)
self.lowersizer = wx.BoxSizer(wx.HORIZONTAL)
upperpanel = self.newPanel(self.panel)
upperpanel = self.newPanel(self.panel, False)
self.uppersizer = MainToolbar(self, upperpanel)
lowerpanel = self.newPanel(self.panel)
upperpanel.SetSizer(self.uppersizer)
......
......@@ -21,33 +21,60 @@ from printrun import gcoder
from printrun_utils import imagefile, install_locale
install_locale('pronterface')
class GvizBaseFrame(wx.Frame):
def create_base_ui(self):
self.CreateStatusBar(1)
self.SetStatusText(_("Layer number and Z position show here when you scroll"))
hpanel = wx.Panel(self, -1)
hbox = wx.BoxSizer(wx.HORIZONTAL)
panel = wx.Panel(hpanel, -1)
vbox = wx.BoxSizer(wx.VERTICAL)
vbox = wx.BoxSizer(wx.VERTICAL)
self.toolbar = wx.ToolBar(panel, -1, style = wx.TB_HORIZONTAL | wx.NO_BORDER | wx.TB_HORZ_TEXT)
self.toolbar.AddSimpleTool(1, wx.Image(imagefile('zoom_in.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), _("Zoom In [+]"), '')
self.toolbar.AddSimpleTool(2, wx.Image(imagefile('zoom_out.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), _("Zoom Out [-]"), '')
self.toolbar.AddSeparator()
self.toolbar.AddSimpleTool(3, wx.Image(imagefile('arrow_up.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), _("Move Up a Layer [U]"), '')
self.toolbar.AddSimpleTool(4, wx.Image(imagefile('arrow_down.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), _("Move Down a Layer [D]"), '')
self.toolbar.AddLabelTool(5, " " + _("Reset view"), wx.Image(imagefile('reset.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), shortHelp = _("Reset view"), longHelp = '')
vbox.Add(self.toolbar, 0, border = 5)
panel.SetSizer(vbox)
hbox.Add(panel, 1, flag = wx.EXPAND)
self.layerslider = wx.Slider(hpanel, style = wx.SL_VERTICAL | wx.SL_AUTOTICKS | wx.SL_LEFT | wx.SL_INVERSE)
self.layerslider.Bind(wx.EVT_SCROLL, self.process_slider)
hbox.Add(self.layerslider, 0, border = 5, flag = wx.LEFT | wx.EXPAND)
hpanel.SetSizer(hbox)
return panel, vbox
def setlayercb(self, layer):
self.layerslider.SetValue(layer)
def process_slider(self, event):
raise NotImplementedError
ID_ABOUT = 101
ID_EXIT = 110
class GvizWindow(wx.Frame):
class GvizWindow(GvizBaseFrame):
def __init__(self, f = None, size = (600, 600), build_dimensions = [200, 200, 100, 0, 0, 0], grid = (10, 50), extrusion_width = 0.5, bgcolor = "#000000"):
wx.Frame.__init__(self, None, title = _("Gcode view, shift to move view, mousewheel to set layer"), size = size)
self.CreateStatusBar(1);
self.SetStatusText(_("Layer number and Z position show here when you scroll"))
super(GvizWindow, self).__init__(None, title = _("Gcode view, shift to move view, mousewheel to set layer"), size = size)
panel, vbox = self.create_base_ui()
panel = wx.Panel(self, -1)
self.p = Gviz(panel, size = size, build_dimensions = build_dimensions, grid = grid, extrusion_width = extrusion_width, bgcolor = bgcolor, realparent = self)
vbox = wx.BoxSizer(wx.VERTICAL)
toolbar = wx.ToolBar(panel, -1, style = wx.TB_HORIZONTAL | wx.NO_BORDER | wx.TB_HORZ_TEXT)
toolbar.AddSimpleTool(1, wx.Image(imagefile('zoom_in.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), _("Zoom In [+]"), '')
toolbar.AddSimpleTool(2, wx.Image(imagefile('zoom_out.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), _("Zoom Out [-]"), '')
toolbar.AddSeparator()
toolbar.AddSimpleTool(3, wx.Image(imagefile('arrow_up.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), _("Move Up a Layer [U]"), '')
toolbar.AddSimpleTool(4, wx.Image(imagefile('arrow_down.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), _("Move Down a Layer [D]"), '')
toolbar.AddLabelTool(5, " " + _("Reset view"), wx.Image(imagefile('reset.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), shortHelp = _("Reset view"), longHelp = '')
toolbar.AddSeparator()
#toolbar.AddSimpleTool(6, wx.Image(imagefile('inject.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), _("Insert Code at start of this layer"), '')
toolbar.Realize()
self.toolbar = toolbar
vbox.Add(toolbar, 0, border = 5)
self.toolbar.AddSeparator()
#self.toolbar.AddSimpleTool(6, wx.Image(imagefile('inject.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), _("Insert Code at start of this layer"), '')
self.toolbar.Realize()
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(-1, -1, 1.2), id = 1)
self.Bind(wx.EVT_TOOL, lambda x:self.p.zoom(-1, -1, 1/1.2), id = 2)
......@@ -71,6 +98,12 @@ class GvizWindow(wx.Frame):
def set_current_gline(self, gline):
return
def process_slider(self, event):
self.p.layerindex = self.layerslider.GetValue()
self.SetStatusText(_("Layer %d - Going Up - Z = %.03f mm") % (self.p.layerindex + 1, self.p.layers[self.p.layerindex]), 0)
self.p.dirty = 1
wx.CallAfter(self.p.Refresh)
def resetview(self, event):
self.p.translate = [0.0, 0.0]
self.p.scale = self.p.basescale
......@@ -203,6 +236,7 @@ class Gviz(wx.Panel):
self.layerindex += 1
self.parent.SetStatusText(_("Layer %d - Going Up - Z = %.03f mm") % (self.layerindex + 1, self.layers[self.layerindex]), 0)
self.dirty = 1
self.parent.setlayercb(self.layerindex)
wx.CallAfter(self.Refresh)
def layerdown(self):
......@@ -210,6 +244,7 @@ class Gviz(wx.Panel):
self.layerindex -= 1
self.parent.SetStatusText(_("Layer %d - Going Down - Z = %.03f mm") % (self.layerindex + 1, self.layers[self.layerindex]), 0)
self.dirty = 1
self.parent.setlayercb(self.layerindex)
wx.CallAfter(self.Refresh)
def setlayer(self, layer):
......@@ -346,6 +381,10 @@ class Gviz(wx.Panel):
def addfile(self, gcode):
self.clear()
self.add_parsed_gcodes(gcode.lines)
max_layers = len(self.layers)
if hasattr(self.parent, "layerslider"):
self.parent.layerslider.SetRange(0, max_layers - 1)
self.parent.layerslider.SetValue(0)
# 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
......
......@@ -1426,11 +1426,16 @@ class pronsole(cmd.Cmd):
def off(self, ignore = None):
if self.p.online:
if self.p.printing: self.pause(None)
self.onecmd("M84; motors off")
self.onecmd("M104 S0; extruder off")
self.onecmd("M140 S0; heatbed off")
self.onecmd("M107; fan off")
self.onecmd("M81; power supply off")
self.log(_("; Motors off"))
self.onecmd("M84")
self.log(_("; Extruder off"))
self.onecmd("M104 S0")
self.log(_("; Heatbed off"))
self.onecmd("M140 S0")
self.log(_("; Fan off"))
self.onecmd("M107")
self.log(_("; Power supply off"))
self.onecmd("M81")
else:
self.logError(_("Printer is not online. Unable to turn it off."))
......
......@@ -183,6 +183,9 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def _set_fgcode(self, value):
self._fgcode = value
self.excluder = None
self.excluder_e = None
self.excluder_z_abs = None
self.excluder_z_rel = None
fgcode = property(_get_fgcode, _set_fgcode)
def __init__(self, filename = None, size = winsize):
......@@ -199,6 +202,8 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.settings._add(ComboSetting("mainviz", "2D", ["2D", "3D", "None"], _("Main visualization"), _("Select visualization for main window."), "UI"))
self.settings._add(BooleanSetting("tempgraph", True, _("Display temperature graph"), _("Display time-lapse temperature graph"), "UI"))
self.settings._add(BooleanSetting("tempgauges", False, _("Display temperature gauges"), _("Display graphical gauges for temperatures visualization"), "UI"))
self.settings._add(BooleanSetting("lockbox", False, _("Display interface lock checkbox"), _("Display a checkbox that, when check, locks most of Pronterface"), "UI"))
self.settings._add(BooleanSetting("lockonstart", False, _("Lock interface upon print start"), _("If lock checkbox is enabled, lock the interface when starting a print"), "UI"))
self.settings._add(HiddenSetting("last_bed_temperature", 0.0))
self.settings._add(HiddenSetting("last_file_path", ""))
self.settings._add(HiddenSetting("last_temperature", 0.0))
......@@ -217,7 +222,6 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.SetIcon(wx.Icon(sys.executable, wx.BITMAP_TYPE_ICO))
else:
self.SetIcon(wx.Icon(pixmapfile("P-face.ico"), wx.BITMAP_TYPE_ICO))
self.panel = wx.Panel(self,-1, size = size)
self.statuscheck = False
self.status_thread = None
......@@ -341,6 +345,8 @@ class PronterWindow(MainWindow, pronsole.pronsole):
else:
print _("Print started at: %s") % format_time(self.starttime)
self.compute_eta = RemainingTimeEstimator(self.fgcode)
if self.settings.lockbox and self.settings.lockonstart:
wx.CallAfter(self.lock, force = True)
def endcb(self):
if self.p.queueindex == 0:
......@@ -360,19 +366,22 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def online(self):
print _("Printer is now online.")
wx.CallAfter(self.online_gui)
def online_gui(self):
self.connectbtn.SetLabel(_("Disconnect"))
self.connectbtn.SetToolTip(wx.ToolTip("Disconnect from the printer"))
self.connectbtn.Bind(wx.EVT_BUTTON, self.disconnect)
for i in self.printerControls:
wx.CallAfter(i.Enable)
i.Enable()
# Enable XYButtons and ZButtons
wx.CallAfter(self.xyb.enable)
wx.CallAfter(self.zb.enable)
self.xyb.enable()
self.zb.enable()
if self.filename:
wx.CallAfter(self.printbtn.Enable)
self.printbtn.Enable()
def layer_change_cb(self, newlayer):
if self.compute_eta:
......@@ -411,8 +420,6 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def is_excluded_move(self, gline):
if not gline.is_move or not self.excluder or not self.excluder.rectangles:
return False
if gline.x == None and gline.y == None:
return False
for (x0, y0, x1, y1) in self.excluder.rectangles:
if x0 <= gline.current_x <= x1 and y0 <= gline.current_y <= y1:
return True
......@@ -422,14 +429,39 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if not self.is_excluded_move(gline):
return gline
else:
# Check if next move will be excluded too and if it will emit an absolute E set
if next_gline != None and self.is_excluded_move(next_gline) and next_gline.e != None and not next_gline.relative_e:
return None # nothing to do: next move will set absolute E if needed
else: # else, check if this is an extrusion move with non relative E and replace it
if gline.e != None and not gline.relative_e:
return gcoder.Line("G92 E%.5f" % gline.e)
else: # or just do nothing
return None
if gline.z != None:
if gline.relative:
if self.excluder_z_abs != None:
self.excluder_z_abs += gline.z
elif self.excluder_z_rel != None:
self.excluder_z_rel += gline.z
else:
self.excluder_z_rel = gline.z
else:
self.excluder_z_rel = None
self.excluder_z_abs = gline.z
if gline.e != None and not gline.relative_e:
self.excluder_e = gline.e
# If next move won't be excluded, push the changes we have to do
if next_gline != None and not self.is_excluded_move(next_gline):
if self.excluder_e != None:
self.p.send_now("G92 E%.5f" % self.excluder_e)
self.excluder_e = None
if self.excluder_z_abs != None:
if gline.relative:
self.p.send_now("G90")
self.p.send_now("G1 Z.5f" % self.excluder_z_abs)
self.excluder_z_abs = None
if gline.relative:
self.p.send_now("G91")
if self.excluder_z_rel != None:
if not gline.relative:
self.p.send_now("G91")
self.p.send_now("G1 Z.5f" % self.excluder_z_rel)
self.excluder_z_rel = None
if not gline.relative:
self.p.send_now("G90")
return None
def printsentcb(self, gline):
if gline.is_move and hasattr(self.gwindow, "set_current_gline"):
......@@ -1745,6 +1777,18 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.paused = 0
dlg.Destroy()
def lock(self, event = None, force = None):
if force != None:
self.locker.SetValue(force)
if self.locker.GetValue():
print _("Locking interface.")
for panel in self.panels:
panel.Disable()
else:
print _("Unlocking interface.")
for panel in self.panels:
panel.Enable()
class PronterApp(wx.App):
mainwindow = None
......
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