Speed up various parts of gcoder GCode processing
parent
b1113f06a5
commit
f15b0cdabb
185
gcoder.py
185
gcoder.py
|
@ -28,108 +28,45 @@ def get_coordinate_value(axis, parts):
|
||||||
def hypot3d(X1, Y1, Z1, X2 = 0.0, Y2 = 0.0, Z2 = 0.0):
|
def hypot3d(X1, Y1, Z1, X2 = 0.0, Y2 = 0.0, Z2 = 0.0):
|
||||||
return math.hypot(X2-X1, math.hypot(Y2-Y1, Z2-Z1))
|
return math.hypot(X2-X1, math.hypot(Y2-Y1, Z2-Z1))
|
||||||
|
|
||||||
|
gcode_parsed_args = ["x", "y", "e", "f", "z", "p"]
|
||||||
|
|
||||||
class Line(object):
|
class Line(object):
|
||||||
def __init__(self,l):
|
|
||||||
self._x = None
|
|
||||||
self._y = None
|
|
||||||
self._z = None
|
|
||||||
self.e = None
|
|
||||||
self.f = 0
|
|
||||||
|
|
||||||
self.regex = re.compile("[-]?\d+[.]?\d*")
|
|
||||||
self.raw = l.upper().lstrip()
|
|
||||||
self.imperial = False
|
|
||||||
self.relative = False
|
|
||||||
self.relative_e = False
|
|
||||||
|
|
||||||
if ";" in self.raw:
|
|
||||||
self.raw = self.raw.split(";")[0]
|
|
||||||
|
|
||||||
self._parse_coordinates()
|
|
||||||
|
|
||||||
def _to_mm(self,v):
|
|
||||||
if v and self.imperial:
|
|
||||||
return v*25.4
|
|
||||||
return v
|
|
||||||
|
|
||||||
def _getx(self):
|
|
||||||
return self._to_mm(self._x)
|
|
||||||
|
|
||||||
def _setx(self,v):
|
|
||||||
self._x = v
|
|
||||||
|
|
||||||
def _gety(self):
|
x = None
|
||||||
return self._to_mm(self._y)
|
y = None
|
||||||
|
z = None
|
||||||
def _sety(self,v):
|
e = None
|
||||||
self._y = v
|
f = None
|
||||||
|
|
||||||
def _getz(self):
|
|
||||||
return self._to_mm(self._z)
|
|
||||||
|
|
||||||
def _setz(self,v):
|
|
||||||
self._z = v
|
|
||||||
|
|
||||||
def _gete(self):
|
|
||||||
return self._to_mm(self._e)
|
|
||||||
|
|
||||||
def _sete(self,v):
|
|
||||||
self._e = v
|
|
||||||
|
|
||||||
x = property(_getx,_setx)
|
|
||||||
y = property(_gety,_sety)
|
|
||||||
z = property(_getz,_setz)
|
|
||||||
e = property(_gete,_sete)
|
|
||||||
|
|
||||||
|
relative = False
|
||||||
def command(self):
|
relative_e = False
|
||||||
try:
|
|
||||||
return self.raw.split(" ")[0]
|
|
||||||
except:
|
|
||||||
return ""
|
|
||||||
|
|
||||||
def _get_float(self,which):
|
|
||||||
try:
|
|
||||||
return float(self.regex.findall(self.raw.split(which)[1])[0])
|
|
||||||
except:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _parse_coordinates(self):
|
|
||||||
try:
|
|
||||||
if "X" in self.raw:
|
|
||||||
self._x = self._get_float("X")
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
raw = None
|
||||||
if "Y" in self.raw:
|
split_raw = None
|
||||||
self._y = self._get_float("Y")
|
|
||||||
except:
|
command = None
|
||||||
pass
|
is_move = False
|
||||||
|
|
||||||
try:
|
def __init__(self, l):
|
||||||
if "Z" in self.raw:
|
self.raw = l.lower()
|
||||||
self._z = self._get_float("Z")
|
if ";" in self.raw:
|
||||||
except:
|
self.raw = self.raw.split(";")[0].rstrip()
|
||||||
pass
|
self.split_raw = self.raw.split(" ")
|
||||||
|
self.command = self.split_raw[0].upper()
|
||||||
try:
|
self.is_move = self.command in ["G0", "G1"]
|
||||||
if "E" in self.raw:
|
|
||||||
self.e = self._get_float("E")
|
def parse_coordinates(self, imperial):
|
||||||
except:
|
if imperial:
|
||||||
pass
|
for bit in self.split_raw:
|
||||||
|
code = bit[0]
|
||||||
try:
|
if code in gcode_parsed_args and len(bit) > 1:
|
||||||
if "F" in self.raw:
|
setattr(self, code, 25.4*float(bit[1:]))
|
||||||
self.f = self._get_float("F")
|
else:
|
||||||
except:
|
for bit in self.split_raw:
|
||||||
pass
|
code = bit[0]
|
||||||
|
if code in gcode_parsed_args and len(bit) > 1:
|
||||||
|
setattr(self, code, float(bit[1:]))
|
||||||
def is_move(self):
|
|
||||||
return self.command() and ("G1" in self.raw or "G0" in self.raw)
|
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.raw
|
return self.raw
|
||||||
|
|
||||||
|
@ -153,12 +90,12 @@ class Layer(object):
|
||||||
current_z = 0
|
current_z = 0
|
||||||
|
|
||||||
for line in self.lines:
|
for line in self.lines:
|
||||||
if line.command() == "G92":
|
if line.command == "G92":
|
||||||
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
|
||||||
|
|
||||||
if line.is_move():
|
if line.is_move:
|
||||||
x = line.x
|
x = line.x
|
||||||
y = line.y
|
y = line.y
|
||||||
z = line.z
|
z = line.z
|
||||||
|
@ -188,7 +125,9 @@ class Layer(object):
|
||||||
|
|
||||||
class GCode(object):
|
class GCode(object):
|
||||||
def __init__(self,data):
|
def __init__(self,data):
|
||||||
self.lines = [Line(i) for i in data]
|
self.lines = [Line(l2) for l2 in
|
||||||
|
(l.strip() for l in data)
|
||||||
|
if l2 and not l2.startswith(";")]
|
||||||
self._preprocess()
|
self._preprocess()
|
||||||
self._create_layers()
|
self._create_layers()
|
||||||
|
|
||||||
|
@ -198,24 +137,24 @@ class GCode(object):
|
||||||
relative = False
|
relative = False
|
||||||
relative_e = False
|
relative_e = False
|
||||||
for line in self.lines:
|
for line in self.lines:
|
||||||
if line.command() == "G20":
|
if line.command == "G20":
|
||||||
imperial = True
|
imperial = True
|
||||||
elif line.command() == "G21":
|
elif line.command == "G21":
|
||||||
imperial = False
|
imperial = False
|
||||||
elif line.command() == "G90":
|
elif line.command == "G90":
|
||||||
relative = False
|
relative = False
|
||||||
relative_e = False
|
relative_e = False
|
||||||
elif line.command() == "G91":
|
elif line.command == "G91":
|
||||||
relative = True
|
relative = True
|
||||||
relative_e = True
|
relative_e = True
|
||||||
elif line.command() == "M82":
|
elif line.command == "M82":
|
||||||
relative_e = False
|
relative_e = False
|
||||||
elif line.command() == "M83":
|
elif line.command == "M83":
|
||||||
relative_e = True
|
relative_e = True
|
||||||
elif line.is_move():
|
elif line.is_move:
|
||||||
line.imperial = imperial
|
|
||||||
line.relative = relative
|
line.relative = relative
|
||||||
line.relative_e = relative_e
|
line.relative_e = relative_e
|
||||||
|
line.parse_coordinates(imperial)
|
||||||
|
|
||||||
def _create_layers(self):
|
def _create_layers(self):
|
||||||
self.layers = []
|
self.layers = []
|
||||||
|
@ -227,9 +166,9 @@ class GCode(object):
|
||||||
|
|
||||||
temp_layers = {}
|
temp_layers = {}
|
||||||
for line in self.lines:
|
for line in self.lines:
|
||||||
if line.command() == "G92" and line.z != None:
|
if line.command == "G92" and line.z != None:
|
||||||
cur_z = line.z
|
cur_z = line.z
|
||||||
elif line.is_move():
|
elif line.is_move:
|
||||||
if line.z != None:
|
if line.z != None:
|
||||||
if line.relative:
|
if line.relative:
|
||||||
cur_z += line.z
|
cur_z += line.z
|
||||||
|
@ -263,17 +202,15 @@ class GCode(object):
|
||||||
cur_lines = temp_layers[idx]
|
cur_lines = temp_layers[idx]
|
||||||
has_movement = False
|
has_movement = False
|
||||||
for l in cur_lines:
|
for l in cur_lines:
|
||||||
if l.is_move() and l.e != None:
|
if l.is_move and l.e != None:
|
||||||
has_movement = True
|
has_movement = True
|
||||||
break
|
break
|
||||||
|
|
||||||
if has_movement:
|
if has_movement:
|
||||||
self.layers.append(Layer(cur_lines))
|
self.layers.append(Layer(cur_lines))
|
||||||
|
|
||||||
|
|
||||||
def num_layers(self):
|
def num_layers(self):
|
||||||
return len(self.layers)
|
return len(self.layers)
|
||||||
|
|
||||||
|
|
||||||
def measure(self):
|
def measure(self):
|
||||||
xmin = float("inf")
|
xmin = float("inf")
|
||||||
|
@ -284,13 +221,13 @@ class GCode(object):
|
||||||
zmax = float("-inf")
|
zmax = float("-inf")
|
||||||
|
|
||||||
for l in self.layers:
|
for l in self.layers:
|
||||||
xd, yd, zd = l.measure()
|
(xm, xM), (ym, yM), (zm, zM) = l.measure()
|
||||||
xmin = min(xd[0], xmin)
|
xmin = min(xm, xmin)
|
||||||
xmax = max(xd[1], xmax)
|
xmax = max(xM, xmax)
|
||||||
ymin = min(yd[0], ymin)
|
ymin = min(ym, ymin)
|
||||||
ymax = max(yd[1], ymax)
|
ymax = max(yM, ymax)
|
||||||
zmin = min(zd[0], zmin)
|
zmin = min(zm, zmin)
|
||||||
zmax = max(zd[1], zmax)
|
zmax = max(zM, zmax)
|
||||||
|
|
||||||
self.xmin = xmin
|
self.xmin = xmin
|
||||||
self.xmax = xmax
|
self.xmax = xmax
|
||||||
|
@ -309,9 +246,9 @@ class GCode(object):
|
||||||
for line in self.lines:
|
for line in self.lines:
|
||||||
if line.e == None:
|
if line.e == None:
|
||||||
continue
|
continue
|
||||||
if line.command() == "G92":
|
if line.command == "G92":
|
||||||
cur_e = line.e
|
cur_e = line.e
|
||||||
elif line.is_move():
|
elif line.is_move:
|
||||||
if line.relative_e:
|
if line.relative_e:
|
||||||
total_e += line.e
|
total_e += line.e
|
||||||
else:
|
else:
|
||||||
|
@ -397,7 +334,7 @@ def main():
|
||||||
# gcode = GCode(d)
|
# gcode = GCode(d)
|
||||||
d = list(open(sys.argv[1]))
|
d = list(open(sys.argv[1]))
|
||||||
gcode = GCode(d)
|
gcode = GCode(d)
|
||||||
|
|
||||||
gcode.measure()
|
gcode.measure()
|
||||||
|
|
||||||
print "Dimensions:"
|
print "Dimensions:"
|
||||||
|
|
Loading…
Reference in New Issue