mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-04-22 05:39:37 +08:00
118 lines
4.7 KiB
Python
118 lines
4.7 KiB
Python
# This PostProcessing Plugin script 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 |