Commit 2337cb12 authored by D1plo1d's avatar D1plo1d

Merge branch 'experimental' of github.com:kliment/Printrun into experimental

parents 313a51f3 b91265ee
...@@ -74,6 +74,7 @@ class printcore(): ...@@ -74,6 +74,7 @@ class printcore():
self.tempcb = None #impl (wholeline) self.tempcb = None #impl (wholeline)
self.recvcb = None #impl (wholeline) self.recvcb = None #impl (wholeline)
self.sendcb = None #impl (wholeline) self.sendcb = None #impl (wholeline)
self.preprintsendcb = None #impl (wholeline)
self.printsendcb = None #impl (wholeline) self.printsendcb = None #impl (wholeline)
self.layerchangecb = None #impl (wholeline) self.layerchangecb = None #impl (wholeline)
self.errorcb = None #impl (wholeline) self.errorcb = None #impl (wholeline)
...@@ -414,7 +415,9 @@ class printcore(): ...@@ -414,7 +415,9 @@ class printcore():
if self.startcb: if self.startcb:
#callback for printing started #callback for printing started
try: self.startcb(resuming) try: self.startcb(resuming)
except: pass except:
print "Print start callback failed with:"
traceback.print_exc(file = sys.stdout)
while self.printing and self.printer and self.online: while self.printing and self.printer and self.online:
self._sendnext() self._sendnext()
self.sentlines = {} self.sentlines = {}
...@@ -423,10 +426,12 @@ class printcore(): ...@@ -423,10 +426,12 @@ class printcore():
if self.endcb: if self.endcb:
#callback for printing done #callback for printing done
try: self.endcb() try: self.endcb()
except: pass except:
print "Print end callback failed with:"
traceback.print_exc(file = sys.stdout)
except: except:
print "Print thread died due to the following error:" print "Print thread died due to the following error:"
traceback.print_exc() traceback.print_exc(file = sys.stdout)
finally: finally:
self.print_thread = None self.print_thread = None
self._start_sender() self._start_sender()
...@@ -460,16 +465,23 @@ class printcore(): ...@@ -460,16 +465,23 @@ class printcore():
return return
if self.printing and self.queueindex < len(self.mainqueue): if self.printing and self.queueindex < len(self.mainqueue):
(layer, line) = self.mainqueue.idxs(self.queueindex) (layer, line) = self.mainqueue.idxs(self.queueindex)
gline = self.mainqueue.all_layers[layer].lines[line] gline = self.mainqueue.all_layers[layer][line]
if self.layerchangecb and self.queueindex > 0: if self.layerchangecb and self.queueindex > 0:
(prev_layer, prev_line) = self.mainqueue.idxs(self.queueindex - 1) (prev_layer, prev_line) = self.mainqueue.idxs(self.queueindex - 1)
if prev_layer != layer: if prev_layer != layer:
try: self.layerchangecb(layer) try: self.layerchangecb(layer)
except: traceback.print_exc() except: traceback.print_exc()
if self.preprintsendcb:
gline = self.preprintsendcb(gline)
if gline == None:
self.queueindex += 1
self.clear = True
return
tline = gline.raw tline = gline.raw
if tline.lstrip().startswith(";@"): # check for host command if tline.lstrip().startswith(";@"): # check for host command
self.processHostCommand(tline) self.processHostCommand(tline)
self.queueindex += 1 self.queueindex += 1
self.clear = True
return return
tline = tline.split(";")[0] tline = tline.split(";")[0]
......
...@@ -69,8 +69,9 @@ class GCodeAnalyzer(): ...@@ -69,8 +69,9 @@ class GCodeAnalyzer():
def Analyze(self, gcode): def Analyze(self, gcode):
gline = gcoder.Line(gcode) gline = gcoder.Line(gcode)
split_raw = gcoder.split(gline)
if gline.command.startswith(";@"): return # code is a host command if gline.command.startswith(";@"): return # code is a host command
gline.parse_coordinates(self.imperial) gcoder.parse_coordinates(gline, split_raw, self.imperial)
code_g = int(gline.command[1:]) if gline.command.startswith("G") else None code_g = int(gline.command[1:]) if gline.command.startswith("G") else None
code_m = int(gline.command[1:]) if gline.command.startswith("M") else None code_m = int(gline.command[1:]) if gline.command.startswith("M") else None
......
# This file is part of the Printrun suite.
#
# Printrun is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Printrun is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
import wx
from printrun import gviz
from printrun_utils import imagefile, install_locale
install_locale('pronterface')
class ExcluderWindow(gviz.GvizWindow):
def __init__(self, excluder, *args, **kwargs):
super(ExcluderWindow, self).__init__(*args, **kwargs)
self.SetTitle(_("Part excluder: draw rectangles where print instructions should be ignored"))
self.toolbar.AddLabelTool(128, " " + _("Reset selection"), wx.Image(imagefile('reset.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), shortHelp = _("Reset selection"), longHelp = "")
self.Bind(wx.EVT_TOOL, self.reset_selection, id = 128)
self.parent = excluder
self.p.paint_overlay = self.paint_selection
self.p.layerup()
def real_to_gcode(self, x, y):
return (x + self.p.build_dimensions[3],
self.p.build_dimensions[4] + self.p.build_dimensions[1] - y)
def gcode_to_real(self, x, y):
return (x - self.p.build_dimensions[3],
self.p.build_dimensions[1] - (y - self.p.build_dimensions[4]))
def mouse(self, event):
if event.ButtonUp(wx.MOUSE_BTN_LEFT) or event.ButtonUp(wx.MOUSE_BTN_RIGHT):
self.initpos = None
elif event.Dragging() and event.RightIsDown():
e = event.GetPositionTuple()
if not self.initpos or not hasattr(self, "basetrans"):
self.initpos = e
self.basetrans = self.p.translate
self.p.translate = [self.basetrans[0] + (e[0] - self.initpos[0]),
self.basetrans[1] + (e[1] - self.initpos[1])]
self.p.dirty = 1
wx.CallAfter(self.p.Refresh)
elif event.Dragging() and event.LeftIsDown():
x, y = event.GetPositionTuple()
if not hasattr(self, "basetrans"):
self.basetrans = self.p.translate
x = (x - self.basetrans[0]) / self.p.scale[0]
y = (y - self.basetrans[1]) / self.p.scale[1]
x, y = self.real_to_gcode(x, y)
if not self.initpos:
self.initpos = (x, y)
self.basetrans = self.p.translate
self.parent.rectangles.append((0, 0, 0, 0))
else:
pos = (x, y)
x0 = min(self.initpos[0], pos[0])
y0 = min(self.initpos[1], pos[1])
x1 = max(self.initpos[0], pos[0])
y1 = max(self.initpos[1], pos[1])
self.parent.rectangles[-1] = (x0, y0, x1, y1)
wx.CallAfter(self.p.Refresh)
else:
event.Skip()
def _line_scaler(self, orig):
x0, y0 = self.gcode_to_real(orig[0], orig[1])
x0 = self.p.scale[0]*x0 + self.p.translate[0]
y0 = self.p.scale[1]*y0 + self.p.translate[1]
x1, y1 = self.gcode_to_real(orig[2], orig[3])
x1 = self.p.scale[0]*x1 + self.p.translate[0]
y1 = self.p.scale[1]*y1 + self.p.translate[1]
width = max(x0, x1) - min(x0, x1) + 1
height = max(y0, y1) - min(y0, y1) + 1
return (min(x0, x1), min(y0, y1), width, height,)
def paint_selection(self, dc):
dc = wx.GCDC(dc)
dc.SetPen(wx.TRANSPARENT_PEN)
dc.DrawRectangleList([self._line_scaler(rect) for rect in self.parent.rectangles],
None, wx.Brush((200, 200, 200, 150)))
def reset_selection(self, event):
self.parent.rectangles = []
wx.CallAfter(self.p.Refresh)
class Excluder(object):
def __init__(self):
self.rectangles = []
self.window = None
def pop_window(self, gcode, *args, **kwargs):
if not self.window:
self.window = ExcluderWindow(self, *args, **kwargs)
self.window.p.addfile(gcode)
self.window.p.layerup()
self.window.Bind(wx.EVT_CLOSE, self.close_window)
self.window.Show()
else:
self.window.Show()
self.window.Raise()
def close_window(self, event = None):
if self.window:
self.window.Destroy()
self.window = None
if __name__ == '__main__':
import sys
gcode = gcoder.GCode(open(sys.argv[1]))
app = wx.App(False)
ex = Excluder()
ex.pop_window(gcode)
app.MainLoop()
...@@ -20,66 +20,67 @@ import math ...@@ -20,66 +20,67 @@ import math
import datetime import datetime
from array import array from array import array
gcode_parsed_args = ["x", "y", "e", "f", "z", "p", "i", "j", "s"] gcode_parsed_args = ["x", "y", "e", "f", "z", "i", "j"]
gcode_exp = re.compile("\([^\(\)]*\)|;.*|[/\*].*\n|[a-z][-+]?[0-9]*\.?[0-9]*") gcode_parsed_nonargs = ["g", "t", "m", "n"]
m114_exp = re.compile("\([^\(\)]*\)|[/\*].*\n|[A-Z]:?[-+]?[0-9]*\.?[0-9]*") to_parse = "".join(gcode_parsed_args + gcode_parsed_nonargs)
gcode_exp = re.compile("\([^\(\)]*\)|;.*|[/\*].*\n|([%s])([-+]?[0-9]*\.?[0-9]*)" % to_parse)
m114_exp = re.compile("\([^\(\)]*\)|[/\*].*\n|([XYZ]):?([-+]?[0-9]*\.?[0-9]*)")
specific_exp = "(?:\([^\(\)]*\))|(?:;.*)|(?:[/\*].*\n)|(%s[-+]?[0-9]*\.?[0-9]*)"
move_gcodes = ["G0", "G1", "G2", "G3"] move_gcodes = ["G0", "G1", "G2", "G3"]
class PyLine(object): class PyLine(object):
__slots__ = ('x','y','z','e','f','i','j','s','p', __slots__ = ('x','y','z','e','f','i','j',
'raw','split_raw', 'raw','split_raw',
'command','is_move', 'command','is_move',
'relative','relative_e', 'relative','relative_e',
'current_x', 'current_y', 'current_z', 'extruding', 'current_tool', 'current_x', 'current_y', 'current_z', 'extruding', 'current_tool',
'gcview_end_vertex') 'gcview_end_vertex')
def __init__(self, l):
self.raw = l
def __getattr__(self, name): def __getattr__(self, name):
return None return None
try: try:
import gcoder_line import gcoder_line
LineBase = gcoder_line.GLine Line = gcoder_line.GLine
except ImportError: except ImportError:
LineBase = PyLine Line = PyLine
class Line(LineBase): def find_specific_code(line, code):
exp = specific_exp % code
__slots__ = () bits = [bit for bit in re.findall(exp, line.raw) if bit]
if not bits: return None
def __init__(self, l): else: return float(bits[0][1:])
super(Line, self).__init__()
self.raw = l def S(line):
self.split_raw = gcode_exp.findall(self.raw.lower()) return find_specific_code(line, "S")
self.command = self.split_raw[0].upper() if not self.split_raw[0].startswith("n") else self.split_raw[1].upper()
self.is_move = self.command in move_gcodes def P(line):
return find_specific_code(line, "P")
def parse_coordinates(self, imperial = False, force = False):
# Not a G-line, we don't want to parse its arguments def split(line):
if not force and not self.command[0] == "G": split_raw = gcode_exp.findall(line.raw.lower())
return command = split_raw[0] if split_raw[0][0] != "n" else split_raw[1]
if imperial: line.command = command[0].upper() + command[1]
for bit in self.split_raw: line.is_move = line.command in move_gcodes
code = bit[0] return split_raw
if code in gcode_parsed_args and len(bit) > 1:
setattr(self, code, 25.4*float(bit[1:])) def parse_coordinates(line, split_raw, imperial = False, force = False):
else: # Not a G-line, we don't want to parse its arguments
for bit in self.split_raw: if not force and line.command[0] != "G":
code = bit[0] return
if code in gcode_parsed_args and len(bit) > 1: unit_factor = 25.4 if imperial else 1
setattr(self, code, float(bit[1:])) for bit in split_raw:
del self.split_raw code = bit[0]
if code not in gcode_parsed_nonargs and bit[1]:
def __repr__(self): setattr(line, code, unit_factor*float(bit[1]))
return self.raw
class Layer(object):
lines = None class Layer(list):
duration = None
def __init__(self, lines): __slots__ = ("duration")
self.lines = lines
def _preprocess(self, current_x, current_y, current_z): def _preprocess(self, current_x, current_y, current_z):
xmin = float("inf") xmin = float("inf")
...@@ -91,7 +92,7 @@ class Layer(object): ...@@ -91,7 +92,7 @@ class Layer(object):
relative = False relative = False
relative_e = False relative_e = False
for line in self.lines: for line in self:
if not line.is_move and line.command != "G92": if not line.is_move and line.command != "G92":
continue continue
if line.is_move: if line.is_move:
...@@ -178,9 +179,9 @@ class GCode(object): ...@@ -178,9 +179,9 @@ class GCode(object):
self.lines.append(gline) self.lines.append(gline)
self._preprocess_lines([gline]) self._preprocess_lines([gline])
self._preprocess_extrusion([gline]) self._preprocess_extrusion([gline])
self.append_layer.lines.append(gline) self.append_layer.append(gline)
self.layer_idxs.append(self.append_layer_id) self.layer_idxs.append(self.append_layer_id)
self.line_idxs.append(len(self.append_layer.lines)) self.line_idxs.append(len(self.append_layer))
return gline return gline
def _preprocess_lines(self, lines = None): def _preprocess_lines(self, lines = None):
...@@ -192,6 +193,9 @@ class GCode(object): ...@@ -192,6 +193,9 @@ class GCode(object):
relative_e = self.relative_e relative_e = self.relative_e
current_tool = self.current_tool current_tool = self.current_tool
for line in lines: for line in lines:
split_raw = split(line)
if not line.command:
continue
if line.is_move: if line.is_move:
line.relative = relative line.relative = relative
line.relative_e = relative_e line.relative_e = relative_e
...@@ -213,7 +217,7 @@ class GCode(object): ...@@ -213,7 +217,7 @@ class GCode(object):
elif line.command[0] == "T": elif line.command[0] == "T":
current_tool = int(line.command[1:]) current_tool = int(line.command[1:])
if line.command[0] == "G": if line.command[0] == "G":
line.parse_coordinates(imperial) parse_coordinates(line, split_raw, imperial)
self.imperial = imperial self.imperial = imperial
self.relative = relative self.relative = relative
self.relative_e = relative_e self.relative_e = relative_e
...@@ -283,7 +287,7 @@ class GCode(object): ...@@ -283,7 +287,7 @@ class GCode(object):
if cur_lines: if cur_lines:
all_layers.append(Layer(cur_lines)) all_layers.append(Layer(cur_lines))
old_lines = layers.pop(prev_z, []) old_lines = layers.get(prev_z, [])
old_lines += cur_lines old_lines += cur_lines
layers[prev_z] = old_lines layers[prev_z] = old_lines
...@@ -359,7 +363,7 @@ class GCode(object): ...@@ -359,7 +363,7 @@ class GCode(object):
# get device caps from firmware: max speed, acceleration/axis (including extruder) # get device caps from firmware: max speed, acceleration/axis (including extruder)
# calculate the maximum move duration accounting for above ;) # calculate the maximum move duration accounting for above ;)
for layer in self.all_layers: for layer in self.all_layers:
for line in layer.lines: for line in layer:
if line.command not in ["G1", "G0", "G4"]: if line.command not in ["G1", "G0", "G4"]:
continue continue
if line.command == "G4": if line.command == "G4":
...@@ -407,7 +411,8 @@ def main(): ...@@ -407,7 +411,8 @@ def main():
if len(sys.argv) < 2: if len(sys.argv) < 2:
print "usage: %s filename.gcode" % sys.argv[0] print "usage: %s filename.gcode" % sys.argv[0]
return return
print "Line object size:", sys.getsizeof(Line("G0 X0"))
gcode = GCode(open(sys.argv[1])) gcode = GCode(open(sys.argv[1]))
print "Dimensions:" print "Dimensions:"
......
--- printrun/gcoder_line.c 2013-06-15 16:08:53.260081109 +0200
+++ printrun/gcoder_line.c 2013-06-15 16:08:57.083439793 +0200
@@ -3945,2 +3945,4 @@ static int __Pyx_InitGlobals(void) {
+#include "gcoder_line_extra.h"
+
#if PY_MAJOR_VERSION < 3
@@ -4032,2 +4034,7 @@ PyMODINIT_FUNC PyInit_gcoder_line(void)
/*--- Execution code ---*/
+ nysets_heapdefs[0].type = &__pyx_type_8printrun_11gcoder_line_GLine;
+ if (PyDict_SetItemString(__pyx_d,
+ "_NyHeapDefs_",
+ PyCObject_FromVoidPtrAndDesc(&nysets_heapdefs, "NyHeapDef[] v1.0", 0)) < 0)
+{__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
...@@ -36,20 +36,18 @@ cdef enum BitPos: ...@@ -36,20 +36,18 @@ cdef enum BitPos:
pos_f = 1 << 4 pos_f = 1 << 4
pos_i = 1 << 5 pos_i = 1 << 5
pos_j = 1 << 6 pos_j = 1 << 6
pos_s = 1 << 7 pos_is_move = 1 << 7
pos_p = 1 << 8 pos_relative = 1 << 8
pos_is_move = 1 << 9 pos_relative_e = 1 << 9
pos_relative = 1 << 10 pos_extruding = 1 << 10
pos_relative_e = 1 << 11 pos_current_x = 1 << 11
pos_extruding = 1 << 12 pos_current_y = 1 << 12
pos_current_x = 1 << 13 pos_current_z = 1 << 13
pos_current_y = 1 << 14 pos_current_tool = 1 << 14
pos_current_z = 1 << 15 pos_raw = 1 << 15
pos_current_tool = 1 << 16 pos_command = 1 << 16
pos_raw = 1 << 17 pos_gcview_end_vertex = 1 << 17
pos_split_raw = 1 << 18 # WARNING: don't use bits 24 to 31 as we store current_tool there
pos_command = 1 << 19
pos_gcview_end_vertex = 1 << 20
cdef inline uint32_t has_var(uint32_t status, uint32_t pos): cdef inline uint32_t has_var(uint32_t status, uint32_t pos):
return status & pos return status & pos
...@@ -60,16 +58,14 @@ cdef inline uint32_t set_has_var(uint32_t status, uint32_t pos): ...@@ -60,16 +58,14 @@ cdef inline uint32_t set_has_var(uint32_t status, uint32_t pos):
cdef inline uint32_t unset_has_var(uint32_t status, uint32_t pos): cdef inline uint32_t unset_has_var(uint32_t status, uint32_t pos):
return status & ~pos return status & ~pos
cdef class GLine(object): cdef class GLine:
cdef char* _raw cdef char* _raw
cdef char* _command cdef char* _command
cdef object _split_raw cdef float _x, _y, _z, _e, _f, _i, _j
cdef float _x, _y, _z, _e, _f, _i, _j, _s, _p
cdef float _current_x, _current_y, _current_z cdef float _current_x, _current_y, _current_z
cdef uint32_t _gcview_end_vertex cdef uint32_t _gcview_end_vertex
cdef uint32_t _status cdef uint32_t _status
cdef char _current_tool
__slots__ = () __slots__ = ()
...@@ -78,6 +74,9 @@ cdef class GLine(object): ...@@ -78,6 +74,9 @@ cdef class GLine(object):
self._raw = NULL self._raw = NULL
self._command = NULL self._command = NULL
def __init__(self, line):
self.raw = line
def __dealloc__(self): def __dealloc__(self):
if self._raw != NULL: free(self._raw) if self._raw != NULL: free(self._raw)
if self._command != NULL: free(self._command) if self._command != NULL: free(self._command)
...@@ -131,20 +130,6 @@ cdef class GLine(object): ...@@ -131,20 +130,6 @@ cdef class GLine(object):
def __set__(self, value): def __set__(self, value):
self._j = value self._j = value
self._status = set_has_var(self._status, pos_j) self._status = set_has_var(self._status, pos_j)
property s:
def __get__(self):
if has_var(self._status, pos_s): return self._s
else: return None
def __set__(self, value):
self._s = value
self._status = set_has_var(self._status, pos_s)
property p:
def __get__(self):
if has_var(self._status, pos_p): return self._p
else: return None
def __set__(self, value):
self._p = value
self._status = set_has_var(self._status, pos_p)
property is_move: property is_move:
def __get__(self): def __get__(self):
if has_var(self._status, pos_is_move): return True if has_var(self._status, pos_is_move): return True
...@@ -196,10 +181,10 @@ cdef class GLine(object): ...@@ -196,10 +181,10 @@ cdef class GLine(object):
self._status = set_has_var(self._status, pos_current_z) self._status = set_has_var(self._status, pos_current_z)
property current_tool: property current_tool:
def __get__(self): def __get__(self):
if has_var(self._status, pos_current_tool): return self._current_tool if has_var(self._status, pos_current_tool): return self._status >> 24
else: return None else: return None
def __set__(self, value): def __set__(self, value):
self._current_tool = value self._status = (self._status & ((1 << 24) - 1)) | (value << 24)
self._status = set_has_var(self._status, pos_current_tool) self._status = set_has_var(self._status, pos_current_tool)
property gcview_end_vertex: property gcview_end_vertex:
def __get__(self): def __get__(self):
...@@ -208,20 +193,13 @@ cdef class GLine(object): ...@@ -208,20 +193,13 @@ cdef class GLine(object):
def __set__(self, value): def __set__(self, value):
self._gcview_end_vertex = value self._gcview_end_vertex = value
self._status = set_has_var(self._status, pos_gcview_end_vertex) self._status = set_has_var(self._status, pos_gcview_end_vertex)
property split_raw:
def __get__(self):
if has_var(self._status, pos_split_raw): return self._split_raw
else: return None
def __set__(self, value):
self._split_raw = value
self._status = set_has_var(self._status, pos_split_raw)
def __del__(self):
self._split_raw = None
property raw: property raw:
def __get__(self): def __get__(self):
if has_var(self._status, pos_raw): return self._raw if has_var(self._status, pos_raw): return self._raw
else: return None else: return None
def __set__(self, value): def __set__(self, value):
# WARNING: memory leak could happen here, as we don't do the following :
# if self._raw != NULL: free(self._raw)
self._raw = copy_string(value) self._raw = copy_string(value)
self._status = set_has_var(self._status, pos_raw) self._status = set_has_var(self._status, pos_raw)
property command: property command:
...@@ -229,5 +207,7 @@ cdef class GLine(object): ...@@ -229,5 +207,7 @@ cdef class GLine(object):
if has_var(self._status, pos_command): return self._command if has_var(self._status, pos_command): return self._command
else: return None else: return None
def __set__(self, value): def __set__(self, value):
# WARNING: memory leak could happen here, as we don't do the following :
# if self._command != NULL: free(self._command)
self._command = copy_string(value) self._command = copy_string(value)
self._status = set_has_var(self._status, pos_command) self._status = set_has_var(self._status, pos_command)
typedef int (*NyHeapDef_SizeGetter) (PyObject *obj);
typedef struct {
int flags; /* As yet, only 0 */
PyTypeObject *type; /* The type it regards */
NyHeapDef_SizeGetter size;
void *traverse;
void *relate;
void *resv3, *resv4, *resv5; /* Reserved for future bin. comp. */
} NyHeapDef;
int gline_size(struct __pyx_obj_8printrun_11gcoder_line_GLine *gline) {
int size = __pyx_type_8printrun_11gcoder_line_GLine.tp_basicsize;
if (gline->_raw != NULL)
size += strlen(gline->_raw) + 1;
if (gline->_command != NULL)
size += strlen(gline->_command) + 1;
return size;
}
static NyHeapDef nysets_heapdefs[] = {
{0, 0, (NyHeapDef_SizeGetter) gline_size},
};
/*
nysets_heapdefs[0].type = &__pyx_type_8printrun_11gcoder_line_GLine;
if (PyDict_SetItemString(__pyx_d,
"_NyHeapDefs_",
PyCObject_FromVoidPtrAndDesc(&nysets_heapdefs, "NyHeapDef[] v1.0", 0)) < 0)
{__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
*/
This diff is collapsed.
...@@ -266,7 +266,7 @@ class VizPane(wx.BoxSizer): ...@@ -266,7 +266,7 @@ class VizPane(wx.BoxSizer):
print "Falling back to 2D view, and here is the backtrace:" print "Falling back to 2D view, and here is the backtrace:"
traceback.print_exc() traceback.print_exc()
if use2dview: if use2dview:
root.gviz = gviz.gviz(parentpanel, (300, 300), root.gviz = gviz.Gviz(parentpanel, (300, 300),
build_dimensions = root.build_dimensions_list, build_dimensions = root.build_dimensions_list,
grid = (root.settings.preview_grid_step1, root.settings.preview_grid_step2), grid = (root.settings.preview_grid_step1, root.settings.preview_grid_step2),
extrusion_width = root.settings.preview_extrusion_width, extrusion_width = root.settings.preview_extrusion_width,
...@@ -288,7 +288,7 @@ class VizPane(wx.BoxSizer): ...@@ -288,7 +288,7 @@ class VizPane(wx.BoxSizer):
print "Falling back to 2D view, and here is the backtrace:" print "Falling back to 2D view, and here is the backtrace:"
traceback.print_exc() traceback.print_exc()
if not use3dview: if not use3dview:
root.gwindow = gviz.window([], root.gwindow = gviz.GvizWindow(
build_dimensions = root.build_dimensions_list, build_dimensions = root.build_dimensions_list,
grid = (root.settings.preview_grid_step1, root.settings.preview_grid_step2), grid = (root.settings.preview_grid_step1, root.settings.preview_grid_step2),
extrusion_width = root.settings.preview_extrusion_width, extrusion_width = root.settings.preview_extrusion_width,
......
...@@ -18,31 +18,33 @@ from collections import deque ...@@ -18,31 +18,33 @@ from collections import deque
import wx, time import wx, time
from printrun import gcoder from printrun import gcoder
from printrun_utils import imagefile from printrun_utils import imagefile, install_locale
install_locale('pronterface')
ID_ABOUT = 101 ID_ABOUT = 101
ID_EXIT = 110 ID_EXIT = 110
class window(wx.Frame): class GvizWindow(wx.Frame):
def __init__(self, f, size = (600, 600), build_dimensions = [200, 200, 100, 0, 0, 0], grid = (10, 50), extrusion_width = 0.5, bgcolor = "#000000"): 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) wx.Frame.__init__(self, None, title = _("Gcode view, shift to move view, mousewheel to set layer"), size = size)
self.CreateStatusBar(1); self.CreateStatusBar(1);
self.SetStatusText("Layer number and Z position show here when you scroll"); self.SetStatusText(_("Layer number and Z position show here when you scroll"))
panel = wx.Panel(self, -1) 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) 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) vbox = wx.BoxSizer(wx.VERTICAL)
toolbar = wx.ToolBar(panel, -1, style = wx.TB_HORIZONTAL | wx.NO_BORDER) 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(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.AddSimpleTool(2, wx.Image(imagefile('zoom_out.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), _("Zoom Out [-]"), '')
toolbar.AddSeparator() toolbar.AddSeparator()
toolbar.AddSimpleTool(3, wx.Image(imagefile('arrow_up.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Move Up a Layer [U]', '') 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.AddSimpleTool(4, wx.Image(imagefile('arrow_down.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), _("Move Down a Layer [D]"), '')
toolbar.AddSimpleTool(5, wx.Image(imagefile('reset.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Reset view', '') toolbar.AddLabelTool(5, " " + _("Reset view"), wx.Image(imagefile('reset.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), shortHelp = _("Reset view"), longHelp = '')
toolbar.AddSeparator() toolbar.AddSeparator()
#toolbar.AddSimpleTool(6, wx.Image(imagefile('inject.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Insert Code at start of this layer', '') #toolbar.AddSimpleTool(6, wx.Image(imagefile('inject.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), _("Insert Code at start of this layer"), '')
toolbar.Realize() toolbar.Realize()
self.toolbar = toolbar
vbox.Add(toolbar, 0, border = 5) vbox.Add(toolbar, 0, border = 5)
vbox.Add(self.p, 1, wx.EXPAND) vbox.Add(self.p, 1, wx.EXPAND)
panel.SetSizer(vbox) panel.SetSizer(vbox)
...@@ -54,7 +56,7 @@ class window(wx.Frame): ...@@ -54,7 +56,7 @@ class window(wx.Frame):
self.Bind(wx.EVT_TOOL, self.resetview, id = 5) self.Bind(wx.EVT_TOOL, self.resetview, id = 5)
#self.Bind(wx.EVT_TOOL, lambda x:self.p.inject(), id = 6) #self.Bind(wx.EVT_TOOL, lambda x:self.p.inject(), id = 6)
self.initpos = [0, 0] self.initpos = None
self.p.Bind(wx.EVT_KEY_DOWN, self.key) self.p.Bind(wx.EVT_KEY_DOWN, self.key)
self.Bind(wx.EVT_KEY_DOWN, self.key) self.Bind(wx.EVT_KEY_DOWN, self.key)
self.p.Bind(wx.EVT_MOUSEWHEEL, self.zoom) self.p.Bind(wx.EVT_MOUSEWHEEL, self.zoom)
...@@ -75,12 +77,12 @@ class window(wx.Frame): ...@@ -75,12 +77,12 @@ class window(wx.Frame):
self.p.zoom(0, 0, 1.0) self.p.zoom(0, 0, 1.0)
def mouse(self, event): def mouse(self, event):
if event.ButtonUp(wx.MOUSE_BTN_LEFT): if event.ButtonUp(wx.MOUSE_BTN_LEFT) or event.ButtonUp(wx.MOUSE_BTN_RIGHT):
if self.initpos is not None: if self.initpos is not None:
self.initpos = None self.initpos = None
elif event.Dragging(): elif event.Dragging():
e = event.GetPositionTuple() e = event.GetPositionTuple()
if self.initpos is None or not hasattr(self, "basetrans"): if self.initpos is None:
self.initpos = e self.initpos = e
self.basetrans = self.p.translate self.basetrans = self.p.translate
self.p.translate = [self.basetrans[0] + (e[0] - self.initpos[0]), self.p.translate = [self.basetrans[0] + (e[0] - self.initpos[0]),
...@@ -116,7 +118,7 @@ class window(wx.Frame): ...@@ -116,7 +118,7 @@ class window(wx.Frame):
if z > 0: self.p.zoom(event.GetX(), event.GetY(), 1.2) if z > 0: self.p.zoom(event.GetX(), event.GetY(), 1.2)
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 # Mark canvas as dirty when setting showall
_showall = 0 _showall = 0
...@@ -168,6 +170,7 @@ class gviz(wx.Panel): ...@@ -168,6 +170,7 @@ class gviz(wx.Panel):
self.bgcolor = wx.Colour() self.bgcolor = wx.Colour()
self.bgcolor.SetFromName(bgcolor) self.bgcolor.SetFromName(bgcolor)
self.blitmap = wx.EmptyBitmap(self.GetClientSize()[0], self.GetClientSize()[1], -1) self.blitmap = wx.EmptyBitmap(self.GetClientSize()[0], self.GetClientSize()[1], -1)
self.paint_overlay = None
def inject(self): def inject(self):
#import pdb; pdb.set_trace() #import pdb; pdb.set_trace()
...@@ -198,14 +201,14 @@ class gviz(wx.Panel): ...@@ -198,14 +201,14 @@ class gviz(wx.Panel):
def layerup(self): def layerup(self):
if self.layerindex + 1 < len(self.layers): if self.layerindex + 1 < len(self.layers):
self.layerindex += 1 self.layerindex += 1
self.parent.SetStatusText("Layer %d - Going Up - Z = %.03f mm" % (self.layerindex + 1, self.layers[self.layerindex]), 0) self.parent.SetStatusText(_("Layer %d - Going Up - Z = %.03f mm") % (self.layerindex + 1, self.layers[self.layerindex]), 0)
self.dirty = 1 self.dirty = 1
wx.CallAfter(self.Refresh) wx.CallAfter(self.Refresh)
def layerdown(self): def layerdown(self):
if self.layerindex > 0: if self.layerindex > 0:
self.layerindex -= 1 self.layerindex -= 1
self.parent.SetStatusText("Layer %d - Going Down - Z = %.03f mm" % (self.layerindex + 1, self.layers[self.layerindex]), 0) self.parent.SetStatusText(_("Layer %d - Going Down - Z = %.03f mm") % (self.layerindex + 1, self.layers[self.layerindex]), 0)
self.dirty = 1 self.dirty = 1
wx.CallAfter(self.Refresh) wx.CallAfter(self.Refresh)
...@@ -337,6 +340,8 @@ class gviz(wx.Panel): ...@@ -337,6 +340,8 @@ class gviz(wx.Panel):
dc.SetBackground(wx.Brush(self.bgcolor)) dc.SetBackground(wx.Brush(self.bgcolor))
dc.Clear() dc.Clear()
dc.DrawBitmap(self.blitmap, self.translate[0], self.translate[1]) dc.DrawBitmap(self.blitmap, self.translate[0], self.translate[1])
if self.paint_overlay:
self.paint_overlay(dc)
def addfile(self, gcode): def addfile(self, gcode):
self.clear() self.clear()
...@@ -474,6 +479,6 @@ class gviz(wx.Panel): ...@@ -474,6 +479,6 @@ class gviz(wx.Panel):
if __name__ == '__main__': if __name__ == '__main__':
import sys import sys
app = wx.App(False) app = wx.App(False)
main = window(open(sys.argv[1])) main = GvizWindow(open(sys.argv[1]))
main.Show() main.Show()
app.MainLoop() app.MainLoop()
...@@ -241,6 +241,7 @@ class GcodeModel(Model): ...@@ -241,6 +241,7 @@ class GcodeModel(Model):
color_tool0 = (1.0, 0.0, 0.0, 0.6) color_tool0 = (1.0, 0.0, 0.0, 0.6)
color_tool1 = (0.0, 0.0, 1.0, 0.6) color_tool1 = (0.0, 0.0, 1.0, 0.6)
color_printed = (0.2, 0.75, 0, 0.6) color_printed = (0.2, 0.75, 0, 0.6)
color_current = (0.6, 0.3, 0, 1)
use_vbos = True use_vbos = True
loaded = False loaded = False
...@@ -256,7 +257,7 @@ class GcodeModel(Model): ...@@ -256,7 +257,7 @@ class GcodeModel(Model):
prev_pos = (0, 0, 0) prev_pos = (0, 0, 0)
for layer_idx, layer in enumerate(model_data.all_layers): for layer_idx, layer in enumerate(model_data.all_layers):
for gline in layer.lines: for gline in layer:
if not gline.is_move: if not gline.is_move:
continue continue
vertex_list.append(prev_pos) vertex_list.append(prev_pos)
...@@ -337,33 +338,56 @@ class GcodeModel(Model): ...@@ -337,33 +338,56 @@ class GcodeModel(Model):
else: else:
glVertexPointer(3, GL_FLOAT, 0, self.vertex_buffer.ptr) glVertexPointer(3, GL_FLOAT, 0, self.vertex_buffer.ptr)
if mode_2d: self.vertex_color_buffer.bind()
glScale(1.0, 1.0, 0.0) # discard z coordinates if has_vbo:
start = self.layer_stops[self.num_layers_to_draw - 1] glColorPointer(4, GL_FLOAT, 0, None)
end = self.layer_stops[self.num_layers_to_draw] - start else:
else: # 3d glColorPointer(4, GL_FLOAT, 0, self.vertex_color_buffer.ptr)
start = 0
end = self.layer_stops[self.num_layers_to_draw] start = 0
if self.num_layers_to_draw <= self.max_layers:
end_prev_layer = self.layer_stops[self.num_layers_to_draw - 1]
else:
end_prev_layer = -1
end = self.layer_stops[min(self.num_layers_to_draw, self.max_layers)]
glDisableClientState(GL_COLOR_ARRAY) glDisableClientState(GL_COLOR_ARRAY)
glColor4f(*self.color_printed) glColor4f(*self.color_printed)
printed_end = min(self.printed_until, end) # Draw printed stuff until end or end_prev_layer
if start < printed_end: cur_end = min(self.printed_until, end)
glDrawArrays(GL_LINES, start, printed_end) if end_prev_layer >= 0:
cur_end = min(cur_end, end_prev_layer)
if cur_end >= 0:
glDrawArrays(GL_LINES, start, cur_end)
glEnableClientState(GL_COLOR_ARRAY) glEnableClientState(GL_COLOR_ARRAY)
self.vertex_color_buffer.bind() # Draw nonprinted stuff until end_prev_layer
if has_vbo: start = max(cur_end, 0)
glColorPointer(4, GL_FLOAT, 0, None) if end_prev_layer >= start:
else: glDrawArrays(GL_LINES, start, end_prev_layer - start)
glColorPointer(4, GL_FLOAT, 0, self.vertex_color_buffer.ptr) cur_end = end_prev_layer
glDisableClientState(GL_COLOR_ARRAY)
glColor4f(*self.color_current)
# Draw current layer
orig_linewidth = (GLfloat)()
glGetFloatv(GL_LINE_WIDTH, orig_linewidth)
glLineWidth(2.0)
if end_prev_layer >= 0 and end > end_prev_layer:
glDrawArrays(GL_LINES, end_prev_layer, end - end_prev_layer)
glLineWidth(orig_linewidth)
glEnableClientState(GL_COLOR_ARRAY)
# Draw non printed stuff until end (if not ending at a given layer)
start = max(self.printed_until, 0) start = max(self.printed_until, 0)
end = end - start end = end - start
if start >= 0 and end > 0: if end_prev_layer < 0 and end > 0:
glDrawArrays(GL_LINES, start, end) glDrawArrays(GL_LINES, start, end)
self.vertex_buffer.unbind() self.vertex_buffer.unbind()
......
...@@ -77,7 +77,7 @@ class RemainingTimeEstimator(object): ...@@ -77,7 +77,7 @@ class RemainingTimeEstimator(object):
if self.previous_layers_estimate > 0 and printtime > 0: if self.previous_layers_estimate > 0 and printtime > 0:
self.drift = printtime / self.previous_layers_estimate self.drift = printtime / self.previous_layers_estimate
self.current_layer_estimate = self.gcode.all_layers[layer].duration self.current_layer_estimate = self.gcode.all_layers[layer].duration
self.current_layer_lines = len(self.gcode.all_layers[layer].lines) self.current_layer_lines = len(self.gcode.all_layers[layer])
self.remaining_layers_estimate -= self.current_layer_estimate self.remaining_layers_estimate -= self.current_layer_estimate
self.last_idx = -1 self.last_idx = -1
self.last_estimate = None self.last_estimate = None
......
...@@ -462,7 +462,7 @@ class pronsole(cmd.Cmd): ...@@ -462,7 +462,7 @@ class pronsole(cmd.Cmd):
pass pass
for g in ['/dev/ttyUSB*', '/dev/ttyACM*', "/dev/tty.*", "/dev/cu.*", "/dev/rfcomm*"]: for g in ['/dev/ttyUSB*', '/dev/ttyACM*', "/dev/tty.*", "/dev/cu.*", "/dev/rfcomm*"]:
baselist+=glob.glob(g) baselist += glob.glob(g)
return filter(self._bluetoothSerialFilter, baselist) return filter(self._bluetoothSerialFilter, baselist)
def _bluetoothSerialFilter(self, serial): def _bluetoothSerialFilter(self, serial):
...@@ -1369,7 +1369,7 @@ class pronsole(cmd.Cmd): ...@@ -1369,7 +1369,7 @@ class pronsole(cmd.Cmd):
self.log(_("Loading sliced file.")) self.log(_("Loading sliced file."))
self.do_load(l[0].replace(".stl", "_export.gcode")) self.do_load(l[0].replace(".stl", "_export.gcode"))
except Exception, e: except Exception, e:
self.logError(_("Skeinforge execution failed: %s") % e) self.logError(_("Slicing failed: %s") % e)
def complete_skein(self, text, line, begidx, endidx): def complete_skein(self, text, line, begidx, endidx):
s = line.split() s = line.split()
......
This diff is collapsed.
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