mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-06 14:37:29 -06:00
Merge branch 'main' into fix_postprocessing_script_folders
This commit is contained in:
commit
7ddd1037a6
7255 changed files with 322095 additions and 328534 deletions
|
@ -19,7 +19,7 @@ UM.Dialog
|
|||
height: 500 * screenScaleFactor
|
||||
minimumWidth: 400 * screenScaleFactor
|
||||
minimumHeight: 250 * screenScaleFactor
|
||||
|
||||
backgroundColor: UM.Theme.getColor("main_background")
|
||||
onVisibleChanged:
|
||||
{
|
||||
// Whenever the window is closed (either via the "Close" button or the X on the window frame), we want to update it in the stack.
|
||||
|
@ -286,6 +286,7 @@ UM.Dialog
|
|||
{
|
||||
id: definitionsModel
|
||||
containerId: manager.selectedScriptDefinitionId
|
||||
onContainerIdChanged: definitionsModel.setAllVisible(true)
|
||||
showAll: true
|
||||
}
|
||||
|
||||
|
|
|
@ -4,10 +4,12 @@
|
|||
# Modified: November 16, 2018 by Joshua Pope-Lewis
|
||||
|
||||
# Description: This plugin shows custom messages about your print on the Status bar...
|
||||
# Please look at the 3 options
|
||||
# Please look at the 5 options
|
||||
# - Scrolling (SCROLL_LONG_FILENAMES) if enabled in Marlin and you aren't printing a small item select this option.
|
||||
# - Name: By default it will use the name generated by Cura (EG: TT_Test_Cube) - Type a custom name in here
|
||||
# - Start Num: Choose which number you prefer for the initial layer, 0 or 1
|
||||
# - Max Layer: Enabling this will show how many layers are in the entire print (EG: Layer 1 of 265!)
|
||||
# - Add prefix 'Printing': Enabling this will add the prefix 'Printing'
|
||||
|
||||
from ..Script import Script
|
||||
from UM.Application import Application
|
||||
|
@ -53,23 +55,30 @@ class DisplayFilenameAndLayerOnLCD(Script):
|
|||
"description": "Display how many layers are in the entire print on status bar?",
|
||||
"type": "bool",
|
||||
"default_value": true
|
||||
},
|
||||
"addPrefixPrinting":
|
||||
{
|
||||
"label": "Add prefix 'Printing'?",
|
||||
"description": "This will add the prefix 'Printing'",
|
||||
"type": "bool",
|
||||
"default_value": true
|
||||
}
|
||||
}
|
||||
}"""
|
||||
|
||||
def execute(self, data):
|
||||
max_layer = 0
|
||||
lcd_text = "M117 "
|
||||
if self.getSettingValueByKey("name") != "":
|
||||
name = self.getSettingValueByKey("name")
|
||||
else:
|
||||
name = Application.getInstance().getPrintInformation().jobName
|
||||
if self.getSettingValueByKey("addPrefixPrinting"):
|
||||
lcd_text += "Printing "
|
||||
if not self.getSettingValueByKey("scroll"):
|
||||
if self.getSettingValueByKey("maxlayer"):
|
||||
lcd_text = "M117 Layer "
|
||||
else:
|
||||
lcd_text = "M117 Printing Layer "
|
||||
lcd_text += "Layer "
|
||||
else:
|
||||
lcd_text = "M117 Printing " + name + " - Layer "
|
||||
lcd_text += name + " - Layer "
|
||||
i = self.getSettingValueByKey("startNum")
|
||||
for layer in data:
|
||||
display_text = lcd_text + str(i)
|
||||
|
|
|
@ -24,20 +24,29 @@ class FilamentChange(Script):
|
|||
"version": 2,
|
||||
"settings":
|
||||
{
|
||||
"enabled":
|
||||
{
|
||||
"label": "Enable",
|
||||
"description": "Uncheck to temporarily disable this feature.",
|
||||
"type": "bool",
|
||||
"default_value": true
|
||||
},
|
||||
"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"
|
||||
"default_value": "1",
|
||||
"enabled": "enabled"
|
||||
},
|
||||
"firmware_config":
|
||||
{
|
||||
"label": "Use Firmware Configuration",
|
||||
"description": "Use the settings in your firmware, or customise the parameters of the filament change here.",
|
||||
"type": "bool",
|
||||
"default_value": false
|
||||
"default_value": false,
|
||||
"enabled": "enabled"
|
||||
},
|
||||
"initial_retract":
|
||||
{
|
||||
|
@ -46,7 +55,7 @@ class FilamentChange(Script):
|
|||
"unit": "mm",
|
||||
"type": "float",
|
||||
"default_value": 30.0,
|
||||
"enabled": "not firmware_config"
|
||||
"enabled": "enabled and not firmware_config"
|
||||
},
|
||||
"later_retract":
|
||||
{
|
||||
|
@ -55,7 +64,7 @@ class FilamentChange(Script):
|
|||
"unit": "mm",
|
||||
"type": "float",
|
||||
"default_value": 300.0,
|
||||
"enabled": "not firmware_config"
|
||||
"enabled": "enabled and not firmware_config"
|
||||
},
|
||||
"x_position":
|
||||
{
|
||||
|
@ -64,7 +73,7 @@ class FilamentChange(Script):
|
|||
"unit": "mm",
|
||||
"type": "float",
|
||||
"default_value": 0,
|
||||
"enabled": "not firmware_config"
|
||||
"enabled": "enabled and not firmware_config"
|
||||
},
|
||||
"y_position":
|
||||
{
|
||||
|
@ -73,7 +82,7 @@ class FilamentChange(Script):
|
|||
"unit": "mm",
|
||||
"type": "float",
|
||||
"default_value": 0,
|
||||
"enabled": "not firmware_config"
|
||||
"enabled": "enabled and not firmware_config"
|
||||
},
|
||||
"z_position":
|
||||
{
|
||||
|
@ -82,7 +91,8 @@ class FilamentChange(Script):
|
|||
"unit": "mm",
|
||||
"type": "float",
|
||||
"default_value": 0,
|
||||
"minimum_value": 0
|
||||
"minimum_value": 0,
|
||||
"enabled": "enabled"
|
||||
},
|
||||
"retract_method":
|
||||
{
|
||||
|
@ -92,7 +102,7 @@ class FilamentChange(Script):
|
|||
"options": {"U": "Marlin (M600 U)", "L": "Reprap (M600 L)"},
|
||||
"default_value": "U",
|
||||
"value": "\\\"L\\\" if machine_gcode_flavor==\\\"RepRap (RepRap)\\\" else \\\"U\\\"",
|
||||
"enabled": "not firmware_config"
|
||||
"enabled": "enabled and not firmware_config"
|
||||
},
|
||||
"machine_gcode_flavor":
|
||||
{
|
||||
|
@ -113,6 +123,40 @@ class FilamentChange(Script):
|
|||
},
|
||||
"default_value": "RepRap (Marlin/Sprinter)",
|
||||
"enabled": "false"
|
||||
},
|
||||
"enable_before_macro":
|
||||
{
|
||||
"label": "Enable G-code Before",
|
||||
"description": "Use this to insert a custom G-code macro before the filament change happens",
|
||||
"type": "bool",
|
||||
"default_value": false,
|
||||
"enabled": "enabled"
|
||||
},
|
||||
"before_macro":
|
||||
{
|
||||
"label": "G-code Before",
|
||||
"description": "Any custom G-code to run before the filament change happens, for example, M300 S1000 P10000 for a long beep.",
|
||||
"unit": "",
|
||||
"type": "str",
|
||||
"default_value": "M300 S1000 P10000",
|
||||
"enabled": "enabled and enable_before_macro"
|
||||
},
|
||||
"enable_after_macro":
|
||||
{
|
||||
"label": "Enable G-code After",
|
||||
"description": "Use this to insert a custom G-code macro after the filament change",
|
||||
"type": "bool",
|
||||
"default_value": false,
|
||||
"enabled": "enabled"
|
||||
},
|
||||
"after_macro":
|
||||
{
|
||||
"label": "G-code After",
|
||||
"description": "Any custom G-code to run after the filament has been changed right before continuing the print, for example, you can add a sequence to purge filament and wipe the nozzle.",
|
||||
"unit": "",
|
||||
"type": "str",
|
||||
"default_value": "M300 S440 P500",
|
||||
"enabled": "enabled and enable_after_macro"
|
||||
}
|
||||
}
|
||||
}"""
|
||||
|
@ -134,6 +178,7 @@ class FilamentChange(Script):
|
|||
:param data: A list of layers of g-code.
|
||||
:return: A similar list, with filament change commands inserted.
|
||||
"""
|
||||
enabled = self.getSettingValueByKey("enabled")
|
||||
layer_nums = self.getSettingValueByKey("layer_number")
|
||||
initial_retract = self.getSettingValueByKey("initial_retract")
|
||||
later_retract = self.getSettingValueByKey("later_retract")
|
||||
|
@ -141,8 +186,20 @@ class FilamentChange(Script):
|
|||
y_pos = self.getSettingValueByKey("y_position")
|
||||
z_pos = self.getSettingValueByKey("z_position")
|
||||
firmware_config = self.getSettingValueByKey("firmware_config")
|
||||
enable_before_macro = self.getSettingValueByKey("enable_before_macro")
|
||||
before_macro = self.getSettingValueByKey("before_macro")
|
||||
enable_after_macro = self.getSettingValueByKey("enable_after_macro")
|
||||
after_macro = self.getSettingValueByKey("after_macro")
|
||||
|
||||
color_change = "M600"
|
||||
if not enabled:
|
||||
return data
|
||||
|
||||
color_change = ";BEGIN FilamentChange plugin\n"
|
||||
|
||||
if enable_before_macro:
|
||||
color_change = color_change + before_macro + "\n"
|
||||
|
||||
color_change = color_change + "M600\n"
|
||||
|
||||
if not firmware_config:
|
||||
if initial_retract is not None and initial_retract > 0.:
|
||||
|
@ -163,7 +220,10 @@ class FilamentChange(Script):
|
|||
if z_pos is not None and z_pos > 0.:
|
||||
color_change = color_change + (" Z%.2f" % z_pos)
|
||||
|
||||
color_change = color_change + " ; Generated by FilamentChange plugin\n"
|
||||
if enable_after_macro:
|
||||
color_change = color_change + after_macro + "\n"
|
||||
|
||||
color_change = color_change + ";END FilamentChange plugin\n"
|
||||
|
||||
layer_targets = layer_nums.split(",")
|
||||
if len(layer_targets) > 0:
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
# Copyright (c) 2021 Ultimaker B.V.
|
||||
# Copyright (c) 2023 UltiMaker
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from ..Script import Script
|
||||
# Revised by GregValiant 10-17-2022
|
||||
# Changed "extrude" line to before the nozzle moves back to the print (if not Repetier or Griffin).
|
||||
# Add M104 option for Resume temperature
|
||||
|
||||
from ..Script import Script
|
||||
import re
|
||||
from UM.Application import Application #To get the current printer's settings.
|
||||
from UM.Logger import Logger
|
||||
|
||||
|
@ -26,7 +30,7 @@ class PauseAtHeight(Script):
|
|||
"description": "Whether to pause at a certain height or at a certain layer.",
|
||||
"type": "enum",
|
||||
"options": {"height": "Height", "layer_no": "Layer Number"},
|
||||
"default_value": "height"
|
||||
"default_value": "layer_no"
|
||||
},
|
||||
"pause_height":
|
||||
{
|
||||
|
@ -42,7 +46,7 @@ class PauseAtHeight(Script):
|
|||
"pause_layer":
|
||||
{
|
||||
"label": "Pause Layer",
|
||||
"description": "At what layer should the pause occur?",
|
||||
"description": "Enter the Number of the LAST layer you want to finish prior to the pause. Note that 0 is the first layer printed.",
|
||||
"type": "int",
|
||||
"value": "math.floor((pause_height - 0.27) / 0.1) + 1",
|
||||
"minimum_value": "0",
|
||||
|
@ -58,16 +62,25 @@ class PauseAtHeight(Script):
|
|||
"default_value": "marlin",
|
||||
"value": "\\\"griffin\\\" if machine_gcode_flavor==\\\"Griffin\\\" else \\\"reprap\\\" if machine_gcode_flavor==\\\"RepRap (RepRap)\\\" else \\\"repetier\\\" if machine_gcode_flavor==\\\"Repetier\\\" else \\\"bq\\\" if \\\"BQ\\\" in machine_name or \\\"Flying Bear Ghost 4S\\\" in machine_name else \\\"marlin\\\""
|
||||
},
|
||||
"hold_steppers_on":
|
||||
{
|
||||
"label": "Keep motors engaged",
|
||||
"description": "Keep the steppers engaged to allow change of filament without moving the head. Applying too much force will move the head/bed anyway",
|
||||
"type": "bool",
|
||||
"default_value": false,
|
||||
"enabled": "pause_method != \\\"griffin\\\""
|
||||
},
|
||||
"disarm_timeout":
|
||||
{
|
||||
"label": "Disarm timeout",
|
||||
"description": "After this time steppers are going to disarm (meaning that they can easily lose their positions). Set this to 0 if you don't want to set any duration.",
|
||||
"description": "After this time steppers are going to disarm (meaning that they can easily lose their positions). Set this to 0 if you don't want to set any duration and disarm immediately.",
|
||||
"type": "int",
|
||||
"value": "0",
|
||||
"minimum_value": "0",
|
||||
"minimum_value_warning": "0",
|
||||
"maximum_value_warning": "1800",
|
||||
"unit": "s"
|
||||
"unit": "s",
|
||||
"enabled": "not hold_steppers_on"
|
||||
},
|
||||
"head_park_enabled":
|
||||
{
|
||||
|
@ -147,6 +160,14 @@ class PauseAtHeight(Script):
|
|||
"type": "bool",
|
||||
"default_value": false
|
||||
},
|
||||
"standby_wait_for_temperature_enabled":
|
||||
{
|
||||
"label": "Use M109 for standby temperature? (M104 when false)",
|
||||
"description": "Wait for hot end after Resume? (If your standby temperature is lower than the Printing temperature CHECK and use M109",
|
||||
"type": "bool",
|
||||
"default_value": true,
|
||||
"enabled": "pause_method not in [\\\"griffin\\\", \\\"repetier\\\"]"
|
||||
},
|
||||
"standby_temperature":
|
||||
{
|
||||
"label": "Standby Temperature",
|
||||
|
@ -192,17 +213,33 @@ class PauseAtHeight(Script):
|
|||
"default_value": "RepRap (Marlin/Sprinter)",
|
||||
"enabled": false
|
||||
},
|
||||
"beep_at_pause":
|
||||
{
|
||||
"label": "Beep at pause",
|
||||
"description": "Make a beep when pausing",
|
||||
"type": "bool",
|
||||
"default_value": false
|
||||
},
|
||||
"beep_length":
|
||||
{
|
||||
"label": "Beep length",
|
||||
"description": "How much should the beep last",
|
||||
"type": "int",
|
||||
"default_value": "1000",
|
||||
"unit": "ms",
|
||||
"enabled": "beep_at_pause"
|
||||
},
|
||||
"custom_gcode_before_pause":
|
||||
{
|
||||
"label": "G-code Before Pause",
|
||||
"description": "Any custom g-code to run before the pause, for example, M300 S440 P200 to beep.",
|
||||
"description": "Custom g-code to run before the pause. EX: M300 to beep. Use a comma to separate multiple commands. EX: M400,M300,M117 Pause",
|
||||
"type": "str",
|
||||
"default_value": ""
|
||||
},
|
||||
"custom_gcode_after_pause":
|
||||
{
|
||||
"label": "G-code After Pause",
|
||||
"description": "Any custom g-code to run after the pause, for example, M300 S440 P200 to beep.",
|
||||
"description": "Custom g-code to run after the pause. Use a comma to separate multiple commands. EX: M204 X8 Y8,M106 S0,M117 Resume",
|
||||
"type": "str",
|
||||
"default_value": ""
|
||||
}
|
||||
|
@ -242,6 +279,7 @@ class PauseAtHeight(Script):
|
|||
pause_at = self.getSettingValueByKey("pause_at")
|
||||
pause_height = self.getSettingValueByKey("pause_height")
|
||||
pause_layer = self.getSettingValueByKey("pause_layer")
|
||||
hold_steppers_on = self.getSettingValueByKey("hold_steppers_on")
|
||||
disarm_timeout = self.getSettingValueByKey("disarm_timeout")
|
||||
retraction_amount = self.getSettingValueByKey("retraction_amount")
|
||||
retraction_speed = self.getSettingValueByKey("retraction_speed")
|
||||
|
@ -253,13 +291,16 @@ class PauseAtHeight(Script):
|
|||
move_z = self.getSettingValueByKey("head_move_z")
|
||||
layers_started = False
|
||||
redo_layer = self.getSettingValueByKey("redo_layer")
|
||||
standby_wait_for_temperature_enabled = self.getSettingValueByKey("standby_wait_for_temperature_enabled")
|
||||
standby_temperature = self.getSettingValueByKey("standby_temperature")
|
||||
firmware_retract = Application.getInstance().getGlobalContainerStack().getProperty("machine_firmware_retract", "value")
|
||||
control_temperatures = Application.getInstance().getGlobalContainerStack().getProperty("machine_nozzle_temp_enabled", "value")
|
||||
initial_layer_height = Application.getInstance().getGlobalContainerStack().getProperty("layer_height_0", "value")
|
||||
display_text = self.getSettingValueByKey("display_text")
|
||||
gcode_before = self.getSettingValueByKey("custom_gcode_before_pause")
|
||||
gcode_after = self.getSettingValueByKey("custom_gcode_after_pause")
|
||||
gcode_before = re.sub("\\s*,\\s*", "\n", self.getSettingValueByKey("custom_gcode_before_pause"))
|
||||
gcode_after = re.sub("\\s*,\\s*", "\n", self.getSettingValueByKey("custom_gcode_after_pause"))
|
||||
beep_at_pause = self.getSettingValueByKey("beep_at_pause")
|
||||
beep_length = self.getSettingValueByKey("beep_length")
|
||||
|
||||
pause_method = self.getSettingValueByKey("pause_method")
|
||||
pause_command = {
|
||||
|
@ -437,8 +478,16 @@ class PauseAtHeight(Script):
|
|||
prepend_gcode += "M117 " + display_text + "\n"
|
||||
|
||||
# Set the disarm timeout
|
||||
if disarm_timeout > 0:
|
||||
prepend_gcode += self.putValue(M = 18, S = disarm_timeout) + " ; Set the disarm timeout\n"
|
||||
if pause_method != "griffin":
|
||||
if hold_steppers_on:
|
||||
prepend_gcode += self.putValue(M = 84, S = 3600) + " ; Keep steppers engaged for 1h\n"
|
||||
elif disarm_timeout > 0:
|
||||
prepend_gcode += self.putValue(M = 84, S = disarm_timeout) + " ; Set the disarm timeout\n"
|
||||
|
||||
# Beep at pause
|
||||
if beep_at_pause:
|
||||
prepend_gcode += self.putValue(M = 300, S = 440, P = beep_length) + " ; Beep\n"
|
||||
|
||||
|
||||
# Set a custom GCODE section before pause
|
||||
if gcode_before:
|
||||
|
@ -447,7 +496,7 @@ class PauseAtHeight(Script):
|
|||
# Wait till the user continues printing
|
||||
prepend_gcode += pause_command + " ; Do the actual pause\n"
|
||||
|
||||
# Set a custom GCODE section before pause
|
||||
# Set a custom GCODE section after pause
|
||||
if gcode_after:
|
||||
prepend_gcode += gcode_after + "\n"
|
||||
|
||||
|
@ -495,19 +544,23 @@ class PauseAtHeight(Script):
|
|||
elif pause_method != "griffin":
|
||||
if control_temperatures:
|
||||
# Set extruder resume temperature
|
||||
prepend_gcode += self.putValue(M = 109, S = int(target_temperature.get(current_t, 0))) + " ; resume temperature\n"
|
||||
if standby_wait_for_temperature_enabled:
|
||||
WFT_numeric = 109
|
||||
Temp_resume_Text = " ; WAIT for resume temperature\n"
|
||||
else:
|
||||
WFT_numeric = 104
|
||||
Temp_resume_Text = " ; resume temperature\n"
|
||||
|
||||
prepend_gcode += self.putValue(M=WFT_numeric,
|
||||
S=int(target_temperature.get(current_t, 0))) + Temp_resume_Text
|
||||
|
||||
if extrude_amount != 0: # Need to prime after the pause.
|
||||
# Push the filament back.
|
||||
if retraction_amount != 0:
|
||||
prepend_gcode += self.putValue(G = 1, E = retraction_amount, F = retraction_speed * 60) + "\n"
|
||||
if extrude_speed == 0:
|
||||
extrude_speed = 25
|
||||
|
||||
# Prime the material.
|
||||
prepend_gcode += self.putValue(G = 1, E = extrude_amount, F = extrude_speed * 60) + "; Extra extrude after the unpause\n"
|
||||
|
||||
# And retract again to make the movements back to the starting position.
|
||||
if retraction_amount != 0:
|
||||
prepend_gcode += self.putValue(G = 1, E = -retraction_amount, F = retraction_speed * 60) + "\n"
|
||||
if extrude_amount != 0:
|
||||
prepend_gcode += self.putValue(G=1, E=extrude_amount, F=extrude_speed * 60) + "\n"
|
||||
|
||||
# Move the head back
|
||||
if park_enabled:
|
||||
|
@ -521,8 +574,6 @@ class PauseAtHeight(Script):
|
|||
retraction_count = 1 if control_temperatures else 3 #Retract more if we don't control the temperature.
|
||||
for i in range(retraction_count):
|
||||
prepend_gcode += self.putValue(G = 11) + "\n"
|
||||
else:
|
||||
prepend_gcode += self.putValue(G = 1, E = retraction_amount, F = retraction_speed * 60) + "\n"
|
||||
|
||||
if current_extrusion_f != 0:
|
||||
prepend_gcode += self.putValue(G = 1, F = current_extrusion_f) + " ; restore extrusion feedrate\n"
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
# Copyright (c) 2019 Ultimaker B.V.
|
||||
# Copyright (c) 2023 UltiMaker B.V.
|
||||
# The PostProcessingPlugin is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
import math
|
||||
|
||||
from ..Script import Script
|
||||
|
||||
from UM.Application import Application # To get current absolute/relative setting.
|
||||
from UM.Math.Vector import Vector
|
||||
|
||||
from typing import List, Tuple
|
||||
|
||||
|
||||
class RetractContinue(Script):
|
||||
"""Continues retracting during all travel moves."""
|
||||
|
||||
def getSettingDataString(self):
|
||||
def getSettingDataString(self) -> str:
|
||||
return """{
|
||||
"name": "Retract Continue",
|
||||
"key": "RetractContinue",
|
||||
|
@ -27,58 +30,90 @@ class RetractContinue(Script):
|
|||
}
|
||||
}"""
|
||||
|
||||
def execute(self, data):
|
||||
current_e = 0
|
||||
current_x = 0
|
||||
current_y = 0
|
||||
current_z = 0
|
||||
def _getTravelMove(self, travel_move: str, default_pos: Vector) -> Tuple[Vector, float]:
|
||||
travel = Vector(
|
||||
self.getValue(travel_move, "X", default_pos.x),
|
||||
self.getValue(travel_move, "Y", default_pos.y),
|
||||
self.getValue(travel_move, "Z", default_pos.z)
|
||||
)
|
||||
f = self.getValue(travel_move, "F", -1.0)
|
||||
return travel, f
|
||||
|
||||
def _travelMoveString(self, travel: Vector, f: float, e: float) -> str:
|
||||
# Note that only G1 moves are written, since extrusion is included.
|
||||
if f <= 0.0:
|
||||
return f"G1 X{travel.x:.5f} Y{travel.y:.5f} Z{travel.z:.5f} E{e:.5f}"
|
||||
else:
|
||||
return f"G1 F{f:.5f} X{travel.x:.5f} Y{travel.y:.5f} Z{travel.z:.5f} E{e:.5f}"
|
||||
|
||||
def execute(self, data: List[str]) -> List[str]:
|
||||
current_e = 0.0
|
||||
to_compensate = 0 # Used when extrusion mode is relative.
|
||||
is_active = False # Whether retract-continue is in effect.
|
||||
|
||||
current_pos = Vector(0.0, 0.0, 0.0)
|
||||
last_pos = Vector(0.0, 0.0, 0.0)
|
||||
|
||||
extra_retraction_speed = self.getSettingValueByKey("extra_retraction_speed")
|
||||
relative_extrusion = Application.getInstance().getGlobalContainerStack().getProperty(
|
||||
"relative_extrusion", "value"
|
||||
)
|
||||
|
||||
for layer_number, layer in enumerate(data):
|
||||
lines = layer.split("\n")
|
||||
for line_number, line in enumerate(lines):
|
||||
if self.getValue(line, "G") in {0, 1}: # Track X,Y,Z location.
|
||||
current_x = self.getValue(line, "X", current_x)
|
||||
current_y = self.getValue(line, "Y", current_y)
|
||||
current_z = self.getValue(line, "Z", current_z)
|
||||
if self.getValue(line, "G") == 1:
|
||||
if not self.getValue(line, "E"): # Either None or 0: Not a retraction then.
|
||||
continue
|
||||
new_e = self.getValue(line, "E")
|
||||
if new_e - current_e >= -0.0001: # Not a retraction. Account for floating point rounding errors.
|
||||
current_e = new_e
|
||||
continue
|
||||
# A retracted travel move may consist of multiple commands, due to combing.
|
||||
# This continues retracting over all of these moves and only unretracts at the end.
|
||||
delta_line = 1
|
||||
dx = current_x # Track the difference in X for this move only to compute the length of the travel.
|
||||
dy = current_y
|
||||
dz = current_z
|
||||
while line_number + delta_line < len(lines) and self.getValue(lines[line_number + delta_line], "G") != 1:
|
||||
travel_move = lines[line_number + delta_line]
|
||||
if self.getValue(travel_move, "G") != 0:
|
||||
delta_line += 1
|
||||
continue
|
||||
travel_x = self.getValue(travel_move, "X", dx)
|
||||
travel_y = self.getValue(travel_move, "Y", dy)
|
||||
travel_z = self.getValue(travel_move, "Z", dz)
|
||||
f = self.getValue(travel_move, "F", "no f")
|
||||
length = math.sqrt((travel_x - dx) * (travel_x - dx) + (travel_y - dy) * (travel_y - dy) + (travel_z - dz) * (travel_z - dz)) # Length of the travel move.
|
||||
new_e -= length * extra_retraction_speed # New retraction is by ratio of this travel move.
|
||||
if f == "no f":
|
||||
new_travel_move = "G1 X{travel_x} Y{travel_y} Z{travel_z} E{new_e}".format(travel_x = travel_x, travel_y = travel_y, travel_z = travel_z, new_e = new_e)
|
||||
else:
|
||||
new_travel_move = "G1 F{f} X{travel_x} Y{travel_y} Z{travel_z} E{new_e}".format(f = f, travel_x = travel_x, travel_y = travel_y, travel_z = travel_z, new_e = new_e)
|
||||
lines[line_number + delta_line] = new_travel_move
|
||||
|
||||
delta_line += 1
|
||||
dx = travel_x
|
||||
dy = travel_y
|
||||
dz = travel_z
|
||||
# Focus on move-type lines.
|
||||
code_g = self.getValue(line, "G")
|
||||
if code_g not in [0, 1]:
|
||||
continue
|
||||
|
||||
current_e = new_e
|
||||
# Track X,Y,Z location.
|
||||
last_pos = last_pos.set(current_pos.x, current_pos.y, current_pos.z)
|
||||
current_pos = current_pos.set(
|
||||
self.getValue(line, "X", current_pos.x),
|
||||
self.getValue(line, "Y", current_pos.y),
|
||||
self.getValue(line, "Z", current_pos.z)
|
||||
)
|
||||
|
||||
# Track extrusion 'axis' position.
|
||||
last_e = current_e
|
||||
e_value = self.getValue(line, "E")
|
||||
if e_value:
|
||||
current_e = (current_e if relative_extrusion else 0) + e_value
|
||||
|
||||
# Handle lines: Detect retractions and compensate relative if G1, potential retract-continue if G0.
|
||||
if code_g == 1:
|
||||
if last_e > (current_e + 0.0001): # Account for floating point inaccuracies.
|
||||
|
||||
# There is a retraction, each following G0 command needs to continue the retraction.
|
||||
is_active = True
|
||||
continue
|
||||
|
||||
elif relative_extrusion and is_active:
|
||||
|
||||
# If 'relative', the first G1 command after the total retraction will have to compensate more.
|
||||
travel, f = self._getTravelMove(lines[line_number], current_pos)
|
||||
lines[line_number] = self._travelMoveString(travel, f, to_compensate + e_value)
|
||||
to_compensate = 0.0
|
||||
|
||||
# There is no retraction (see continue in the retract-clause) and everything else has been handled.
|
||||
is_active = False
|
||||
|
||||
elif code_g == 0:
|
||||
if not is_active:
|
||||
continue
|
||||
|
||||
# The retract-continue is active, so each G0 until the next extrusion needs to continue retraction.
|
||||
travel, f = self._getTravelMove(lines[line_number], current_pos)
|
||||
travel_length = (current_pos - last_pos).length()
|
||||
extra_retract = travel_length * extra_retraction_speed
|
||||
new_e = (0 if relative_extrusion else current_e) - extra_retract
|
||||
to_compensate += extra_retract
|
||||
current_e -= extra_retract
|
||||
lines[line_number] = self._travelMoveString(travel, f, new_e)
|
||||
|
||||
new_layer = "\n".join(lines)
|
||||
data[layer_number] = new_layer
|
||||
|
||||
return data
|
||||
return data
|
||||
|
|
|
@ -432,7 +432,7 @@ class Stretcher:
|
|||
"""
|
||||
dist_palp = self.line_width # Palpation distance to seek for a wall
|
||||
mrot = np.array([[0, -1], [1, 0]]) # Rotation matrix for a quarter turn
|
||||
for i in range(len(orig_seq)):
|
||||
for i, _ in enumerate(orig_seq):
|
||||
ibeg = i # Index of the first point of the segment
|
||||
iend = i + 1 # Index of the last point of the segment
|
||||
if iend == len(orig_seq):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue