Commit a81811c9 authored by Guillaume Seguin's avatar Guillaume Seguin

Refactor gcoder a little to precompute positions and extrusion status

parent 1003ab7a
...@@ -33,17 +33,17 @@ class Line(object): ...@@ -33,17 +33,17 @@ class Line(object):
f = None f = None
i = None i = None
j = None j = None
relative = False
relative_e = False
raw = None raw = None
split_raw = None split_raw = None
command = None command = None
is_move = False is_move = False
duration = None relative = False
relative_e = False
current_pos = None
extruding = None
def __init__(self, l): def __init__(self, l):
self.raw = l.lower() self.raw = l.lower()
...@@ -77,7 +77,7 @@ class Layer(object): ...@@ -77,7 +77,7 @@ class Layer(object):
def __init__(self, lines): def __init__(self, lines):
self.lines = lines self.lines = lines
def measure(self): def _preprocess(self, current_x, current_y, current_z):
xmin = float("inf") xmin = float("inf")
ymin = float("inf") ymin = float("inf")
zmin = 0 zmin = 0
...@@ -87,11 +87,9 @@ class Layer(object): ...@@ -87,11 +87,9 @@ class Layer(object):
relative = False relative = False
relative_e = False relative_e = False
current_x = 0
current_y = 0
current_z = 0
for line in self.lines: for line in self.lines:
if not line.is_move and line.command != "G92":
continue
if line.is_move: if line.is_move:
x = line.x x = line.x
y = line.y y = line.y
...@@ -109,20 +107,21 @@ class Layer(object): ...@@ -109,20 +107,21 @@ class Layer(object):
if y: if y:
ymin = min(ymin, y) ymin = min(ymin, y)
ymax = max(ymax, y) ymax = max(ymax, y)
if z: if z:
zmin = min(zmin, z) zmin = min(zmin, z)
zmax = max(zmax, z) zmax = max(zmax, z)
current_x = x or current_x current_x = x or current_x
current_y = y or current_y current_y = y or current_y
current_z = z or current_z current_z = z or current_z
elif line.command == "G92": else:
current_x = line.x or current_x current_x = line.x or current_x
current_y = line.y or current_y current_y = line.y or current_y
current_z = line.z or current_z current_z = line.z or current_z
return (xmin, xmax), (ymin, ymax), (zmin, zmax) line.current_pos = (current_x, current_y, current_z)
return (current_x, current_y, current_z), (xmin, xmax), (ymin, ymax), (zmin, zmax)
class GCode(object): class GCode(object):
...@@ -137,12 +136,25 @@ class GCode(object): ...@@ -137,12 +136,25 @@ class GCode(object):
relative = False relative = False
relative_e = False relative_e = False
filament_length = None
xmin = None
xmax = None
ymin = None
ymax = None
zmin = None
zmax = None
width = None
depth = None
height = None
def __init__(self,data): def __init__(self,data):
self.lines = [Line(l2) for l2 in self.lines = [Line(l2) for l2 in
(l.strip() for l in data) (l.strip() for l in data)
if l2] if l2]
self._preprocess() self._preprocess_lines()
self._preprocess_extrusion()
self._create_layers() self._create_layers()
self._preprocess_layers()
def __len__(self): def __len__(self):
return len(self.idxs) return len(self.idxs)
...@@ -157,7 +169,7 @@ class GCode(object): ...@@ -157,7 +169,7 @@ class GCode(object):
self.append_layer.lines.append(gline) self.append_layer.lines.append(gline)
self.idxs.append((self.append_layer_id, len(self.append_layer.lines))) self.idxs.append((self.append_layer_id, len(self.append_layer.lines)))
def _preprocess(self, lines = None): def _preprocess_lines(self, lines = None):
"""Checks for G20, G21, G90 and G91, sets imperial and relative flags""" """Checks for G20, G21, G90 and G91, sets imperial and relative flags"""
if not lines: if not lines:
lines = self.lines lines = self.lines
...@@ -188,6 +200,28 @@ class GCode(object): ...@@ -188,6 +200,28 @@ class GCode(object):
self.relative = relative self.relative = relative
self.relative_e = relative_e self.relative_e = relative_e
def _preprocess_extrusion(self):
total_e = 0
max_e = 0
cur_e = 0
for line in self.lines:
if line.e == None:
continue
if line.is_move:
if line.relative_e:
line.extruding = line.e != 0
total_e += line.e
else:
line.extruding = line.e != cur_e
total_e += line.e - cur_e
cur_e = line.e
max_e = max(max_e, total_e)
elif line.command == "G92":
cur_e = line.e
self.filament_length = max_e
# FIXME : looks like this needs to be tested with list Z on move # FIXME : looks like this needs to be tested with list Z on move
def _create_layers(self): def _create_layers(self):
layers = {} layers = {}
...@@ -252,7 +286,7 @@ class GCode(object): ...@@ -252,7 +286,7 @@ class GCode(object):
def num_layers(self): def num_layers(self):
return len(self.layers) return len(self.layers)
def measure(self): def _preprocess_layers(self):
xmin = float("inf") xmin = float("inf")
ymin = float("inf") ymin = float("inf")
zmin = 0 zmin = 0
...@@ -260,8 +294,12 @@ class GCode(object): ...@@ -260,8 +294,12 @@ class GCode(object):
ymax = float("-inf") ymax = float("-inf")
zmax = float("-inf") zmax = float("-inf")
for l in self.layers.values(): current_x = 0
(xm, xM), (ym, yM), (zm, zM) = l.measure() current_y = 0
current_z = 0
for l in self.all_layers:
(current_x, current_y, current_z), (xm, xM), (ym, yM), (zm, zM) = l._preprocess(current_x, current_y, current_z)
xmin = min(xm, xmin) xmin = min(xm, xmin)
xmax = max(xM, xmax) xmax = max(xM, xmax)
ymin = min(ym, ymin) ymin = min(ym, ymin)
...@@ -278,26 +316,6 @@ class GCode(object): ...@@ -278,26 +316,6 @@ class GCode(object):
self.width = xmax - xmin self.width = xmax - xmin
self.depth = ymax - ymin self.depth = ymax - ymin
self.height = zmax - zmin self.height = zmax - zmin
def filament_length(self):
total_e = 0
max_e = 0
cur_e = 0
for line in self.lines:
if line.e == None:
continue
if line.is_move:
if line.relative_e:
total_e += line.e
else:
total_e += line.e - cur_e
cur_e = line.e
max_e = max(max_e, total_e)
elif line.command == "G92":
cur_e = line.e
return max_e
def estimate_duration(self): def estimate_duration(self):
lastx = lasty = lastz = laste = lastf = 0.0 lastx = lasty = lastz = laste = lastf = 0.0
...@@ -365,13 +383,11 @@ def main(): ...@@ -365,13 +383,11 @@ def main():
gcode = GCode(open(sys.argv[1])) gcode = GCode(open(sys.argv[1]))
gcode.measure()
print "Dimensions:" print "Dimensions:"
print "\tX: %0.02f - %0.02f (%0.02f)" % (gcode.xmin,gcode.xmax,gcode.width) print "\tX: %0.02f - %0.02f (%0.02f)" % (gcode.xmin,gcode.xmax,gcode.width)
print "\tY: %0.02f - %0.02f (%0.02f)" % (gcode.ymin,gcode.ymax,gcode.depth) print "\tY: %0.02f - %0.02f (%0.02f)" % (gcode.ymin,gcode.ymax,gcode.depth)
print "\tZ: %0.02f - %0.02f (%0.02f)" % (gcode.zmin,gcode.zmax,gcode.height) print "\tZ: %0.02f - %0.02f (%0.02f)" % (gcode.zmin,gcode.zmax,gcode.height)
print "Filament used: %0.02fmm" % gcode.filament_length() print "Filament used: %0.02fmm" % gcode.filament_length
print "Number of layers: %d" % gcode.num_layers() print "Number of layers: %d" % gcode.num_layers()
print "Estimated duration: %s" % gcode.estimate_duration() print "Estimated duration: %s" % gcode.estimate_duration()
......
...@@ -1311,8 +1311,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1311,8 +1311,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def loadviz(self): def loadviz(self):
gcode = self.fgcode gcode = self.fgcode
gcode.measure() print gcode.filament_length, _("mm of filament used in this print\n")
print gcode.filament_length(), _("mm of filament used in this print\n")
print _("the print goes from %f mm to %f mm in X\nand is %f mm wide\n") % (gcode.xmin, gcode.xmax, gcode.width) print _("the print goes from %f mm to %f mm in X\nand is %f mm wide\n") % (gcode.xmin, gcode.xmax, gcode.width)
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)
......
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