123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- # Copyright (c) 2019 Ultimaker B.V.
- # The PostProcessingPlugin is released under the terms of the AGPLv3 or higher.
- from typing import Optional, Tuple
- from UM.Logger import Logger
- from ..Script import Script
- class FilamentChange(Script):
- _layer_keyword = ";LAYER:"
- def __init__(self):
- super().__init__()
- def getSettingDataString(self):
- return """{
- "name":"Filament Change",
- "key": "FilamentChange",
- "metadata": {},
- "version": 2,
- "settings":
- {
- "layer_number":
- {
- "label": "Layer",
- "description": "At what layer should color change occur. This will be before the layer starts printing. Specify multiple color changes with a comma.",
- "unit": "",
- "type": "str",
- "default_value": "1"
- },
- "initial_retract":
- {
- "label": "Initial Retraction",
- "description": "Initial filament retraction distance. The filament will be retracted with this amount before moving the nozzle away from the ongoing print.",
- "unit": "mm",
- "type": "float",
- "default_value": 30.0
- },
- "later_retract":
- {
- "label": "Later Retraction Distance",
- "description": "Later filament retraction distance for removal. The filament will be retracted all the way out of the printer so that you can change the filament.",
- "unit": "mm",
- "type": "float",
- "default_value": 300.0
- },
- "x_position":
- {
- "label": "X Position",
- "description": "Extruder X position. The print head will move here for filament change.",
- "unit": "mm",
- "type": "float",
- "default_value": 0
- },
- "y_position":
- {
- "label": "Y Position",
- "description": "Extruder Y position. The print head will move here for filament change.",
- "unit": "mm",
- "type": "float",
- "default_value": 0
- }
- }
- }"""
- def execute(self, data: list):
- """data is a list. Each index contains a layer"""
- layer_nums = self.getSettingValueByKey("layer_number")
- initial_retract = self.getSettingValueByKey("initial_retract")
- later_retract = self.getSettingValueByKey("later_retract")
- x_pos = self.getSettingValueByKey("x_position")
- y_pos = self.getSettingValueByKey("y_position")
- color_change = "M600"
- if initial_retract is not None and initial_retract > 0.:
- color_change = color_change + (" E%.2f" % initial_retract)
- if later_retract is not None and later_retract > 0.:
- color_change = color_change + (" L%.2f" % later_retract)
- if x_pos is not None:
- color_change = color_change + (" X%.2f" % x_pos)
- if y_pos is not None:
- color_change = color_change + (" Y%.2f" % y_pos)
- color_change = color_change + " ; Generated by FilamentChange plugin"
- layer_targets = layer_nums.split(",")
- if len(layer_targets) > 0:
- for layer_num in layer_targets:
- layer_num = int(layer_num.strip())
- if layer_num <= len(data):
- index, layer_data = self._searchLayerData(data, layer_num - 1)
- if layer_data is None:
- Logger.log("e", "Could not found the layer")
- continue
- lines = layer_data.split("\n")
- lines.insert(2, color_change)
- final_line = "\n".join(lines)
- data[index] = final_line
- return data
- ## This method returns the data corresponding with the indicated layer number, looking in the gcode for
- # the occurrence of this layer number.
- def _searchLayerData(self, data: list, layer_num: int) -> Tuple[int, Optional[str]]:
- for index, layer_data in enumerate(data):
- first_line = layer_data.split("\n")[0]
- # The first line should contain the layer number at the beginning.
- if first_line[:len(self._layer_keyword)] == self._layer_keyword:
- # If found the layer that we are looking for, then return the data
- if first_line[len(self._layer_keyword):] == str(layer_num):
- return index, layer_data
- return 0, None
|