diff options
Diffstat (limited to 'klippy/extras/exclude_object.py')
-rw-r--r-- | klippy/extras/exclude_object.py | 156 |
1 files changed, 88 insertions, 68 deletions
diff --git a/klippy/extras/exclude_object.py b/klippy/extras/exclude_object.py index c80dd000..3043e8dd 100644 --- a/klippy/extras/exclude_object.py +++ b/klippy/extras/exclude_object.py @@ -8,64 +8,74 @@ import logging import json + class ExcludeObject: def __init__(self, config): self.printer = config.get_printer() - self.gcode = self.printer.lookup_object('gcode') - self.gcode_move = self.printer.load_object(config, 'gcode_move') - self.printer.register_event_handler('klippy:connect', - self._handle_connect) - self.printer.register_event_handler("virtual_sdcard:reset_file", - self._reset_file) + self.gcode = self.printer.lookup_object("gcode") + self.gcode_move = self.printer.load_object(config, "gcode_move") + self.printer.register_event_handler("klippy:connect", self._handle_connect) + self.printer.register_event_handler( + "virtual_sdcard:reset_file", self._reset_file + ) self.next_transform = None - self.last_position_extruded = [0., 0., 0., 0.] - self.last_position_excluded = [0., 0., 0., 0.] + self.last_position_extruded = [0.0, 0.0, 0.0, 0.0] + self.last_position_excluded = [0.0, 0.0, 0.0, 0.0] self._reset_state() self.gcode.register_command( - 'EXCLUDE_OBJECT_START', self.cmd_EXCLUDE_OBJECT_START, - desc=self.cmd_EXCLUDE_OBJECT_START_help) + "EXCLUDE_OBJECT_START", + self.cmd_EXCLUDE_OBJECT_START, + desc=self.cmd_EXCLUDE_OBJECT_START_help, + ) self.gcode.register_command( - 'EXCLUDE_OBJECT_END', self.cmd_EXCLUDE_OBJECT_END, - desc=self.cmd_EXCLUDE_OBJECT_END_help) + "EXCLUDE_OBJECT_END", + self.cmd_EXCLUDE_OBJECT_END, + desc=self.cmd_EXCLUDE_OBJECT_END_help, + ) self.gcode.register_command( - 'EXCLUDE_OBJECT', self.cmd_EXCLUDE_OBJECT, - desc=self.cmd_EXCLUDE_OBJECT_help) + "EXCLUDE_OBJECT", self.cmd_EXCLUDE_OBJECT, desc=self.cmd_EXCLUDE_OBJECT_help + ) self.gcode.register_command( - 'EXCLUDE_OBJECT_DEFINE', self.cmd_EXCLUDE_OBJECT_DEFINE, - desc=self.cmd_EXCLUDE_OBJECT_DEFINE_help) + "EXCLUDE_OBJECT_DEFINE", + self.cmd_EXCLUDE_OBJECT_DEFINE, + desc=self.cmd_EXCLUDE_OBJECT_DEFINE_help, + ) def _register_transform(self): if self.next_transform is None: - tuning_tower = self.printer.lookup_object('tuning_tower') + tuning_tower = self.printer.lookup_object("tuning_tower") if tuning_tower.is_active(): - logging.info('The ExcludeObject move transform is not being ' - 'loaded due to Tuning tower being Active') + logging.info( + "The ExcludeObject move transform is not being " + "loaded due to Tuning tower being Active" + ) return - self.next_transform = self.gcode_move.set_move_transform(self, - force=True) + self.next_transform = self.gcode_move.set_move_transform(self, force=True) self.extrusion_offsets = {} self.max_position_extruded = 0 self.max_position_excluded = 0 self.extruder_adj = 0 self.initial_extrusion_moves = 5 - self.last_position = [0., 0., 0., 0.] + self.last_position = [0.0, 0.0, 0.0, 0.0] self.get_position() self.last_position_extruded[:] = self.last_position self.last_position_excluded[:] = self.last_position def _handle_connect(self): - self.toolhead = self.printer.lookup_object('toolhead') + self.toolhead = self.printer.lookup_object("toolhead") def _unregister_transform(self): if self.next_transform: - tuning_tower = self.printer.lookup_object('tuning_tower') + tuning_tower = self.printer.lookup_object("tuning_tower") if tuning_tower.is_active(): - logging.error('The Exclude Object move transform was not ' - 'unregistered because it is not at the head of the ' - 'transform chain.') + logging.error( + "The Exclude Object move transform was not " + "unregistered because it is not at the head of the " + "transform chain." + ) return self.gcode_move.set_move_transform(self.next_transform, force=True) @@ -86,10 +96,10 @@ class ExcludeObject: ename = self.toolhead.get_extruder().get_name() offset = self.extrusion_offsets.get(ename) if offset is None: - offset = [0.] * num_coord + offset = [0.0] * num_coord self.extrusion_offsets[ename] = offset if len(offset) < num_coord: - offset.extend([0.] * (len(num_coord) - len(offset))) + offset.extend([0.0] * (len(num_coord) - len(offset))) return offset def get_position(self): @@ -102,8 +112,7 @@ class ExcludeObject: def _normal_move(self, newpos, speed): offset = self._get_extrusion_offsets(len(newpos)) - if self.initial_extrusion_moves > 0 and \ - self.last_position[3] != newpos[3]: + if self.initial_extrusion_moves > 0 and self.last_position[3] != newpos[3]: # Since the transform is not loaded until there is a request to # exclude an object, the transform needs to track a few extrusions # to get the state of the extruder @@ -120,9 +129,10 @@ class ExcludeObject: # Ideally, there will be Z and E moves right away to adjust any offsets # before moving away from the last position. Any remaining corrections # will be made on the firs XY move. - if (offset[0] != 0 or offset[1] != 0) and \ - (newpos[0] != self.last_position_excluded[0] or \ - newpos[1] != self.last_position_excluded[1]): + if (offset[0] != 0 or offset[1] != 0) and ( + newpos[0] != self.last_position_excluded[0] + or newpos[1] != self.last_position_excluded[1] + ): for i in range(len(newpos)): if i != 3: offset[i] = 0 @@ -132,8 +142,7 @@ class ExcludeObject: if offset[2] != 0 and newpos[2] != self.last_position_excluded[2]: offset[2] = 0 - if self.extruder_adj != 0 and \ - newpos[3] != self.last_position_excluded[3]: + if self.extruder_adj != 0 and newpos[3] != self.last_position_excluded[3]: offset[3] += self.extruder_adj self.extruder_adj = 0 @@ -161,21 +170,25 @@ class ExcludeObject: # This adjustment value is used to compensate for any retraction # differences between the last object printed and excluded one. - self.extruder_adj = self.max_position_excluded \ - - self.last_position_excluded[3] \ + self.extruder_adj = ( + self.max_position_excluded + - self.last_position_excluded[3] - (self.max_position_extruded - self.last_position_extruded[3]) + ) self._normal_move(newpos, speed) def _test_in_excluded_region(self): # Inside cancelled object - return self.current_object in self.excluded_objects \ + return ( + self.current_object in self.excluded_objects and self.initial_extrusion_moves == 0 + ) def get_status(self, eventtime=None): status = { "objects": self.objects, "excluded_objects": self.excluded_objects, - "current_object": self.current_object + "current_object": self.current_object, } return status @@ -194,34 +207,40 @@ class ExcludeObject: else: self._normal_move(newpos, speed) - cmd_EXCLUDE_OBJECT_START_help = "Marks the beginning the current object" \ - " as labeled" + cmd_EXCLUDE_OBJECT_START_help = ( + "Marks the beginning the current object" " as labeled" + ) + def cmd_EXCLUDE_OBJECT_START(self, gcmd): - name = gcmd.get('NAME').upper() + name = gcmd.get("NAME").upper() if not any(obj["name"] == name for obj in self.objects): self._add_object_definition({"name": name}) self.current_object = name self.was_excluded_at_start = self._test_in_excluded_region() cmd_EXCLUDE_OBJECT_END_help = "Marks the end the current object" + def cmd_EXCLUDE_OBJECT_END(self, gcmd): if self.current_object == None and self.next_transform: - gcmd.respond_info("EXCLUDE_OBJECT_END called, but no object is" - " currently active") + gcmd.respond_info( + "EXCLUDE_OBJECT_END called, but no object is" " currently active" + ) return - name = gcmd.get('NAME', default=None) + name = gcmd.get("NAME", default=None) if name != None and name.upper() != self.current_object: - gcmd.respond_info("EXCLUDE_OBJECT_END NAME=%s does not match the" - " current object NAME=%s" % - (name.upper(), self.current_object)) + gcmd.respond_info( + "EXCLUDE_OBJECT_END NAME=%s does not match the" + " current object NAME=%s" % (name.upper(), self.current_object) + ) self.current_object = None cmd_EXCLUDE_OBJECT_help = "Cancel moves inside a specified objects" + def cmd_EXCLUDE_OBJECT(self, gcmd): - reset = gcmd.get('RESET', None) - current = gcmd.get('CURRENT', None) - name = gcmd.get('NAME', '').upper() + reset = gcmd.get("RESET", None) + current = gcmd.get("CURRENT", None) + name = gcmd.get("NAME", "").upper() if reset: if name: @@ -236,7 +255,7 @@ class ExcludeObject: elif current: if not self.current_object: - raise self.gcode.error('There is no current object to cancel') + raise self.gcode.error("There is no current object to cancel") else: self._exclude_object(self.current_object) @@ -245,27 +264,28 @@ class ExcludeObject: self._list_excluded_objects(gcmd) cmd_EXCLUDE_OBJECT_DEFINE_help = "Provides a summary of an object" + def cmd_EXCLUDE_OBJECT_DEFINE(self, gcmd): - reset = gcmd.get('RESET', None) - name = gcmd.get('NAME', '').upper() + reset = gcmd.get("RESET", None) + name = gcmd.get("NAME", "").upper() if reset: self._reset_file() elif name: parameters = gcmd.get_command_parameters().copy() - parameters.pop('NAME') - center = parameters.pop('CENTER', None) - polygon = parameters.pop('POLYGON', None) + parameters.pop("NAME") + center = parameters.pop("CENTER", None) + polygon = parameters.pop("POLYGON", None) obj = {"name": name.upper()} obj.update(parameters) if center != None: - obj['center'] = json.loads('[%s]' % center) + obj["center"] = json.loads("[%s]" % center) if polygon != None: - obj['polygon'] = json.loads(polygon) + obj["polygon"] = json.loads(polygon) self._add_object_definition(obj) @@ -273,32 +293,32 @@ class ExcludeObject: self._list_objects(gcmd) def _add_object_definition(self, definition): - self.objects = sorted(self.objects + [definition], - key=lambda o: o["name"]) + self.objects = sorted(self.objects + [definition], key=lambda o: o["name"]) def _exclude_object(self, name): self._register_transform() - self.gcode.respond_info('Excluding object {}'.format(name.upper())) + self.gcode.respond_info("Excluding object {}".format(name.upper())) if name not in self.excluded_objects: self.excluded_objects = sorted(self.excluded_objects + [name]) def _unexclude_object(self, name): - self.gcode.respond_info('Unexcluding object {}'.format(name.upper())) + self.gcode.respond_info("Unexcluding object {}".format(name.upper())) if name in self.excluded_objects: excluded_objects = list(self.excluded_objects) excluded_objects.remove(name) self.excluded_objects = sorted(excluded_objects) def _list_objects(self, gcmd): - if gcmd.get('JSON', None) is not None: + if gcmd.get("JSON", None) is not None: object_list = json.dumps(self.objects) else: - object_list = " ".join(obj['name'] for obj in self.objects) - gcmd.respond_info('Known objects: {}'.format(object_list)) + object_list = " ".join(obj["name"] for obj in self.objects) + gcmd.respond_info("Known objects: {}".format(object_list)) def _list_excluded_objects(self, gcmd): object_list = " ".join(self.excluded_objects) - gcmd.respond_info('Excluded objects: {}'.format(object_list)) + gcmd.respond_info("Excluded objects: {}".format(object_list)) + def load_config(config): return ExcludeObject(config) |