improved output formatting

This commit is contained in:
lars 2012-11-16 16:11:49 +00:00
parent 9447c747b5
commit 27b5a9d8a5

View file

@ -50,10 +50,14 @@ class GCodeFilter(object):
if self.update_position(line): if self.update_position(line):
result = [] result = []
handler = LineHandler(line) handler = LineHandler(line)
for pos in self.transform_position(): positions = list(self.transform_position())
changed_axes = self.target_pos.get_changed_axes(pos) if not positions:
yield handler.get_line(pos, changed_axes) yield handler.get_line(None, None)
self.target_pos.update(pos) else:
for pos in positions:
changed_axes = self.target_pos.get_changed_axes(pos)
yield handler.get_line(pos, changed_axes)
self.target_pos.update(pos)
else: else:
# no coordinate given # no coordinate given
yield line yield line
@ -63,12 +67,12 @@ class PositionHandler(object):
def __init__(self): def __init__(self):
self.pos = tuple([0] * len(AXIS)) self.pos = tuple([0] * len(AXIS))
self.pos_stack = [tuple(self.pos)] self.stack = [tuple(self.pos)]
def push(self, position): def push(self, position):
self.pos_stack.insert(0, tuple(position)) self.stack.insert(0, tuple(position))
if len(self.pos_stack) > 10: if len(self.stack) > 10:
self.pos_stack.pop(-1) self.stack.pop(-1)
def update(self, position): def update(self, position):
new_pos = tuple(position) new_pos = tuple(position)
@ -106,20 +110,32 @@ class LineHandler(object):
return token return token
def get_line(self, position, axes): def get_line(self, position, axes):
result = [] if position is None:
self._processed = [] # remove all coordinates from the line
self._position = position # (e.g. for a modal switch ("G0 X..") outside of a crop space)
self._axes = axes line = re.sub(AXIS_REGEX, "", self.line, re.I)
line = re.sub(AXIS_REGEX, self.replace_value, self.line, re.I) for i in range(10):
if not self._processed: line = line.replace(" ", " ")
# no axis definition if line.strip():
line = self.line return line.rstrip() + self._suffix
else:
# invalid line - skip it
return None
else: else:
# at least one axis was defined result = []
for i, axis in axes: self._processed = []
if not i in self._processed: self._position = position
line += " %s%s" % (axis, str(position[i])) self._axes = axes
return line + self._suffix line = re.sub(AXIS_REGEX, self.replace_value, self.line, re.I)
if not self._processed:
# no axis definition
line = self.line
else:
# at least one axis was defined
for i, axis in axes:
if not i in self._processed:
line += " %s%s" % (axis, str(position[i]))
return line + self._suffix
class ShiftFilter(GCodeFilter): class ShiftFilter(GCodeFilter):
@ -170,7 +186,7 @@ class DensifyFilter(GCodeFilter):
return tuple(target) return tuple(target)
def transform_position(self): def transform_position(self):
stack = self.source_pos.pos_stack stack = self.source_pos.stack
if (len(stack) > 2) and self.is_inside(stack[0]) and \ if (len(stack) > 2) and self.is_inside(stack[0]) and \
self.is_inside(stack[1]) and \ self.is_inside(stack[1]) and \
self._densify_is_valid(stack[0], stack[1]): self._densify_is_valid(stack[0], stack[1]):
@ -207,29 +223,33 @@ class DensifyFilter(GCodeFilter):
class CropFilter(GCodeFilter): class CropFilter(GCodeFilter):
def transform_position(self): def transform_position(self):
is_inside = self.is_inside(self.pos) stack = self.source_pos.stack
was_inside = self.pos_stack[1] is_inside = self.is_inside(stack[0])
was_inside = (len(stack) < 2) or self.is_inside(stack[1])
result = None result = None
if is_inside and was_inside: if is_inside and was_inside:
# inside -> inside # inside -> inside
yield self.pos yield stack[0]
elif not is_inside and not was_inside: elif not is_inside and not was_inside:
# outside -> outside # outside -> outside
pass pass
else: else:
# outside -> inside OR inside -> outside # outside -> inside OR inside -> outside
border_pos = self._recurse_border_position(self._previous_position, if len(stack) >= 2:
pos, self.is_inside) border_pos = self._recurse_border_position(stack[1], stack[0])
# the border position is always the first step # adapt the precision to the precision of the input
yield border_pos border_pos = tuple([value.quantize(template)
for value, template in zip(border_pos, stack[0])])
# the border position is always the first step
yield border_pos
# omit the current position if we are outside # omit the current position if we are outside
if is_inside: if is_inside:
yield self.pos yield stack[0]
def _recurse_border_position(self, p1, p2, depth_limit=20): def _recurse_border_position(self, p1, p2, depth_limit=20):
""" simple and stupid: bisections between p1 and p2 """ simple and stupid: bisections between p1 and p2
""" """
p_middle = tuple([0.5 * (axis1 + axis2) p_middle = tuple([d(0.5) * (axis1 + axis2)
for axis1, axis2 in zip(p1, p2)]) for axis1, axis2 in zip(p1, p2)])
if depth_limit < 0: if depth_limit < 0:
return p_middle return p_middle
@ -286,5 +306,7 @@ if __name__ == "__main__":
sys.exit(1) sys.exit(1)
for line in infile.readlines(): for line in infile.readlines():
for out_line in gcode_filter.get_processed_lines(line): for out_line in gcode_filter.get_processed_lines(line):
outfile.write(out_line) # omit empty lines
if not out_line is None:
outfile.write(out_line)