From b0882d2ea5bc0c7143b08ac2e0c27e19da456a9b Mon Sep 17 00:00:00 2001 From: GregValiant <64202104+GregValiant@users.noreply.github.com> Date: Wed, 1 Oct 2025 07:13:53 -0400 Subject: [PATCH 1/7] Update ZHopOnTravel.py Z values were either 2 decimal places, or 16 decimal floats. This change alters all Z value changes to be rounded to 3 decimal places. This provides consistency throughout any script changes. --- plugins/PostProcessingPlugin/scripts/ZHopOnTravel.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/PostProcessingPlugin/scripts/ZHopOnTravel.py b/plugins/PostProcessingPlugin/scripts/ZHopOnTravel.py index 69cf3d1938..99deaf2dc1 100644 --- a/plugins/PostProcessingPlugin/scripts/ZHopOnTravel.py +++ b/plugins/PostProcessingPlugin/scripts/ZHopOnTravel.py @@ -316,7 +316,7 @@ class ZHopOnTravel(Script): if hop_start > 0: # For any lines that are XYZ moves right before layer change if " Z" in line: - lines[index] = lines[index].replace("Z" + str(self._cur_z), "Z" + str(self._cur_z + hop_height)) + lines[index] = lines[index].replace(f"Z{self._cur_z}", f"Z{round(self._cur_z + hop_height,3)}") # If there is no 'F' in the next line then add one at the Travel Speed so the z-hop speed doesn't carry over if not " F" in lines[index] and lines[index].startswith("G0"): lines[index] = lines[index].replace("G0", f"G0 F{speed_travel}") @@ -421,9 +421,9 @@ class ZHopOnTravel(Script): machine_height = Application.getInstance().getGlobalContainerStack().getProperty("machine_height", "value") if self._cur_z + hop_height < machine_height: - up_lines = f"G1 F{speed_zhop} Z{round(self._cur_z + hop_height,2)} ; Hop Up" + up_lines = f"G1 F{speed_zhop} Z{round(self._cur_z + hop_height,3)} ; Hop Up" else: - up_lines = f"G1 F{speed_zhop} Z{round(machine_height, 2)} ; Hop Up" + up_lines = f"G1 F{speed_zhop} Z{round(machine_height, 3)} ; Hop Up" if reset_type in [1, 9] and hop_retraction: # add retract only when necessary up_lines = f"G1 F{retract_speed} E{round(self._cur_e - retraction_amount, 5)} ; Retract\n" + up_lines self._cur_e = round(self._cur_e - retraction_amount, 5) From 63bbe5c7c6704a06f593f515b29095ae84b2c02b Mon Sep 17 00:00:00 2001 From: HellAholic Date: Thu, 2 Oct 2025 08:32:18 +0200 Subject: [PATCH 2/7] Apply suggestions from code review --- plugins/PostProcessingPlugin/scripts/ZHopOnTravel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/PostProcessingPlugin/scripts/ZHopOnTravel.py b/plugins/PostProcessingPlugin/scripts/ZHopOnTravel.py index 99deaf2dc1..1bbfe0afa5 100644 --- a/plugins/PostProcessingPlugin/scripts/ZHopOnTravel.py +++ b/plugins/PostProcessingPlugin/scripts/ZHopOnTravel.py @@ -316,7 +316,7 @@ class ZHopOnTravel(Script): if hop_start > 0: # For any lines that are XYZ moves right before layer change if " Z" in line: - lines[index] = lines[index].replace(f"Z{self._cur_z}", f"Z{round(self._cur_z + hop_height,3)}") + lines[index] = lines[index].replace(f"Z{self._cur_z}", f"Z{round(self._cur_z + hop_height, 3)}") # If there is no 'F' in the next line then add one at the Travel Speed so the z-hop speed doesn't carry over if not " F" in lines[index] and lines[index].startswith("G0"): lines[index] = lines[index].replace("G0", f"G0 F{speed_travel}") @@ -421,7 +421,7 @@ class ZHopOnTravel(Script): machine_height = Application.getInstance().getGlobalContainerStack().getProperty("machine_height", "value") if self._cur_z + hop_height < machine_height: - up_lines = f"G1 F{speed_zhop} Z{round(self._cur_z + hop_height,3)} ; Hop Up" + up_lines = f"G1 F{speed_zhop} Z{round(self._cur_z + hop_height, 3)} ; Hop Up" else: up_lines = f"G1 F{speed_zhop} Z{round(machine_height, 3)} ; Hop Up" if reset_type in [1, 9] and hop_retraction: # add retract only when necessary From 2f3d94b589112fc724f3c067df551de59cfe6c1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Fern=C3=A1ndez?= Date: Mon, 6 Oct 2025 13:06:11 +0200 Subject: [PATCH 3/7] fix: missing variable --- resources/definitions/anycubic_i3_mega_s.def.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/definitions/anycubic_i3_mega_s.def.json b/resources/definitions/anycubic_i3_mega_s.def.json index 6db0164241..c7c2dd1f4d 100644 --- a/resources/definitions/anycubic_i3_mega_s.def.json +++ b/resources/definitions/anycubic_i3_mega_s.def.json @@ -39,7 +39,7 @@ "machine_acceleration": { "value": 3000 }, "machine_center_is_zero": { "default_value": false }, "machine_depth": { "default_value": 210 }, - "machine_end_gcode": { "default_value": "M104 S0 ; Extruder off \nM140 S0 ; Heatbed off \nM107 ; Fan off \nG91 ; relative positioning \nG1 E-5 F300 ; retract a little \nG1 Z+10 E-5 ; X-20 Y-20 F{travel_xy_speed} ; lift print head \nG28 X0 Y0 ; homing \nG1 Y180 F2000 ; reset feedrate \nM84 ; disable stepper motors \nG90 ; absolute positioning \nM300 S440 P200 ; Make Print Completed Tones \nM300 S660 P250 ; beep \nM300 S880 P300 ; beep" }, + "machine_end_gcode": { "default_value": "M104 S0 ; Extruder off \nM140 S0 ; Heatbed off \nM107 ; Fan off \nG91 ; relative positioning \nG1 E-5 F300 ; retract a little \nG1 Z+10 E-5 ; X-20 Y-20 F{speed_travel} ; lift print head \nG28 X0 Y0 ; homing \nG1 Y180 F2000 ; reset feedrate \nM84 ; disable stepper motors \nG90 ; absolute positioning \nM300 S440 P200 ; Make Print Completed Tones \nM300 S660 P250 ; beep \nM300 S880 P300 ; beep" }, "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" }, "machine_heated_bed": { "default_value": true }, "machine_height": { "default_value": 205 }, From 1fe563d06f3e06b2b53c67d36c3d5b9a59bb1f32 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Tue, 7 Oct 2025 12:30:31 +0200 Subject: [PATCH 4/7] Note that an ungrouped object should be selected for painting CURA-12761 --- plugins/PaintTool/PaintTool.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/PaintTool/PaintTool.qml b/plugins/PaintTool/PaintTool.qml index 8548c3c14e..2f96bffd24 100644 --- a/plugins/PaintTool/PaintTool.qml +++ b/plugins/PaintTool/PaintTool.qml @@ -327,7 +327,7 @@ Item UM.Label { anchors.fill: parent - text: catalog.i18nc("@label", "Select a single model to start painting") + text: catalog.i18nc("@label", "Select a single ungrouped model to start painting") verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter } From 6d8b517c621e5700c7a9df77ba01b28a2ed809cb Mon Sep 17 00:00:00 2001 From: GregValiant <64202104+GregValiant@users.noreply.github.com> Date: Sat, 18 Oct 2025 21:30:47 -0400 Subject: [PATCH 5/7] Update PurgeLinesAndUnload.py Change the purge line height from a fixed 0.3 to a live value equal to the Initial Layer Height. This fixes a problem it was creating with the preview of a gcode file. --- .../scripts/PurgeLinesAndUnload.py | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/plugins/PostProcessingPlugin/scripts/PurgeLinesAndUnload.py b/plugins/PostProcessingPlugin/scripts/PurgeLinesAndUnload.py index 44c2b50f9e..c94c99ec11 100644 --- a/plugins/PostProcessingPlugin/scripts/PurgeLinesAndUnload.py +++ b/plugins/PostProcessingPlugin/scripts/PurgeLinesAndUnload.py @@ -486,9 +486,9 @@ class PurgeLinesAndUnload(Script): data[0] += "; [Purge Lines and Unload] 'Add Purge Lines' did not run because the assumed primary nozzle (T0) has tool offsets.\n" Message(title = "[Purge Lines and Unload]", text = "'Add Purge Lines' did not run because the assumed primary nozzle (T0) has tool offsets").show() return data - + self.purge_line_hgt = round(float(self.global_stack.getProperty("layer_height_0", "value")),2) def calculate_purge_volume(line_width, purge_length, volume_per_mm): - return round((line_width * 0.3 * purge_length) * 1.25 / volume_per_mm, 5) + return round((line_width * self.purge_line_hgt * purge_length) * 1.25 / volume_per_mm, 5) def adjust_for_prime_blob_gcode(retract_speed, retract_distance): """Generates G-code lines for prime blob adjustment.""" @@ -497,7 +497,7 @@ class PurgeLinesAndUnload(Script): "G92 E0 ; Reset extruder\n" ] return "\n".join(gcode_lines) - + purge_location = self.getSettingValueByKey("purge_line_location") purge_extrusion_full = True if self.getSettingValueByKey("purge_line_length") == "purge_full" else False purge_str = ";TYPE:CUSTOM----------[Purge Lines]\nG0 F600 Z2 ; Move up\nG92 E0 ; Reset extruder\n" @@ -511,7 +511,7 @@ class PurgeLinesAndUnload(Script): purge_str = purge_str.replace("Lines", "Lines at MinX") # Travel to the purge start purge_str += f"G0 F{self.speed_travel} X{self.machine_left + self.border_distance} Y{self.machine_front + 10} ; Move to start\n" - purge_str += f"G0 F600 Z0.3 ; Move down\n" + purge_str += f"G0 F600 Z{self.purge_line_hgt} ; Move down\n" if self.prime_blob_enable: purge_str += adjust_for_prime_blob_gcode(self.retract_speed, self.retract_dist) # Purge two lines @@ -522,7 +522,7 @@ class PurgeLinesAndUnload(Script): purge_str += f"G1 F{int(self.retract_speed)} E{round(purge_volume * 2 - self.retract_dist, 5)} ; Retract\n" if self.retraction_enable else "" purge_str += "G0 F600 Z8 ; Move Up\nG4 S1 ; Wait for 1 second\n" # Wipe - purge_str += f"G0 F{self.print_speed} X{self.machine_left + 3 + self.border_distance} Y{self.machine_front + 20} Z0.3 ; Slide over and down\n" + purge_str += f"G0 F{self.print_speed} X{self.machine_left + 3 + self.border_distance} Y{self.machine_front + 20} Z{self.purge_line_hgt} ; Slide over and down\n" purge_str += f"G0 X{self.machine_left + 3 + self.border_distance} Y{self.machine_front + 35} ; Wipe\n" self.end_purge_location = Position.LEFT_FRONT elif purge_location == Location.RIGHT: @@ -532,7 +532,7 @@ class PurgeLinesAndUnload(Script): purge_str = purge_str.replace("Lines", "Lines at MaxX") # Travel to the purge start purge_str += f"G0 F{self.speed_travel} X{self.machine_right - self.border_distance} ; Move\nG0 Y{self.machine_back - 10} ; Move\n" - purge_str += f"G0 F600 Z0.3 ; Move down\n" + purge_str += f"G0 F600 Z{self.purge_line_hgt} ; Move down\n" if self.prime_blob_enable: purge_str += adjust_for_prime_blob_gcode(self.retract_speed, self.retract_dist) # Purge two lines @@ -543,7 +543,7 @@ class PurgeLinesAndUnload(Script): purge_str += f"G1 F{int(self.retract_speed)} E{round(purge_volume * 2 - self.retract_dist, 5)} ; Retract\n" if self.retraction_enable else "" purge_str += "G0 F600 Z8 ; Move Up\nG4 S1 ; Wait for 1 second\n" # Wipe - purge_str += f"G0 F{self.print_speed} X{self.machine_right - 3 - self.border_distance} Y{self.machine_back - 20} Z0.3 ; Slide over and down\n" + purge_str += f"G0 F{self.print_speed} X{self.machine_right - 3 - self.border_distance} Y{self.machine_back - 20} Z{self.purge_line_hgt} ; Slide over and down\n" purge_str += f"G0 X{self.machine_right - 3 - self.border_distance} Y{self.machine_back - 35} ; Wipe\n" self.end_purge_location = Position.RIGHT_REAR elif purge_location == Location.FRONT: @@ -554,7 +554,7 @@ class PurgeLinesAndUnload(Script): purge_str = purge_str.replace("Lines", "Lines at MinY") # Travel to the purge start purge_str += f"G0 F{self.speed_travel} X{self.machine_left + 10} Y{self.machine_front + self.border_distance} ; Move to start\n" - purge_str += f"G0 F600 Z0.3 ; Move down\n" + purge_str += f"G0 F600 Z{self.purge_line_hgt} ; Move down\n" if self.prime_blob_enable: purge_str += adjust_for_prime_blob_gcode(self.retract_speed, self.retract_dist) # Purge two lines @@ -565,7 +565,7 @@ class PurgeLinesAndUnload(Script): purge_str += f"G1 F{int(self.retract_speed)} E{round(purge_volume * 2 - self.retract_dist, 5)} ; Retract\n" if self.retraction_enable else "" purge_str += "G0 F600 Z8 ; Move Up\nG4 S1 ; Wait for 1 second\n" # Wipe - purge_str += f"G0 F{self.print_speed} X{self.machine_left + 20} Y{self.machine_front + 3 + self.border_distance} Z0.3 ; Slide over and down\n" + purge_str += f"G0 F{self.print_speed} X{self.machine_left + 20} Y{self.machine_front + 3 + self.border_distance} Z{self.purge_line_hgt} ; Slide over and down\n" purge_str += f"G0 X{self.machine_left + 35} Y{self.machine_front + 3 + self.border_distance} ; Wipe\n" self.end_purge_location = Position.LEFT_FRONT elif purge_location == Location.REAR: @@ -577,7 +577,7 @@ class PurgeLinesAndUnload(Script): # Travel to the purge start purge_str += f"G0 F{self.speed_travel} Y{self.machine_back - self.border_distance} ; Ortho Move to back\n" purge_str += f"G0 X{self.machine_right - 10} ; Ortho move to start\n" - purge_str += f"G0 F600 Z0.3 ; Move down\n" + purge_str += f"G0 F600 Z{self.purge_line_hgt} ; Move down\n" if self.prime_blob_enable: purge_str += adjust_for_prime_blob_gcode(self.retract_speed, self.retract_dist) # Purge two lines @@ -588,7 +588,7 @@ class PurgeLinesAndUnload(Script): purge_str += f"G1 F{int(self.retract_speed)} E{round(purge_volume * 2 - self.retract_dist, 5)} ; Retract\n" if self.retraction_enable else "" purge_str += "G0 F600 Z8 ; Move Up\nG4 S1 ; Wait 1 second\n" # Wipe - purge_str += f"G0 F{self.print_speed} X{self.machine_right - 20} Y{self.machine_back - 3 - self.border_distance} Z0.3 ; Slide over and down\n" + purge_str += f"G0 F{self.print_speed} X{self.machine_right - 20} Y{self.machine_back - 3 - self.border_distance} Z{self.purge_line_hgt} ; Slide over and down\n" purge_str += f"G0 X{self.machine_right - 35} Y{self.machine_back - 3 - self.border_distance} ; Wipe\n" self.end_purge_location = Position.RIGHT_REAR # Some cartesian printers (BIBO, Weedo, MethodX, etc.) are Origin at Center @@ -600,7 +600,7 @@ class PurgeLinesAndUnload(Script): purge_volume = calculate_purge_volume(self.init_line_width, purge_len, self.mm3_per_mm) # Travel to the purge start purge_str += f"G0 F{self.speed_travel} X{self.machine_left + self.border_distance} Y{self.machine_front + 10} ; Move to start\n" - purge_str += f"G0 F600 Z0.3 ; Move down\n" + purge_str += f"G0 F600 Z{self.purge_line_hgt} ; Move down\n" if self.prime_blob_enable: purge_str += adjust_for_prime_blob_gcode(self.retract_speed, self.retract_dist) # Purge two lines @@ -611,7 +611,7 @@ class PurgeLinesAndUnload(Script): purge_str += f"G1 F{int(self.retract_speed)} E{round(purge_volume * 2 - self.retract_dist, 5)} ; Retract\n" if self.retraction_enable else "" purge_str += "G0 F600 Z8 ; Move Up\nG4 S1 ; Wait for 1 second\n" # Wipe - purge_str += f"G0 F{self.print_speed} X{self.machine_left + 3 + self.border_distance} Y{self.machine_front + 20} Z0.3 ; Slide over and down\n" + purge_str += f"G0 F{self.print_speed} X{self.machine_left + 3 + self.border_distance} Y{self.machine_front + 20} Z{self.purge_line_hgt} ; Slide over and down\n" purge_str += f"G0 X{self.machine_left + 3 + self.border_distance} Y{self.machine_front + 35} ; Wipe\n" self.end_purge_location = Position.LEFT_FRONT elif purge_location == Location.RIGHT: @@ -621,7 +621,7 @@ class PurgeLinesAndUnload(Script): purge_volume = calculate_purge_volume(self.init_line_width, purge_len, self.mm3_per_mm) # Travel to the purge start purge_str += f"G0 F{self.speed_travel} X{self.machine_right - self.border_distance} Z2 ; Move\nG0 Y{self.machine_back - 10} Z2 ; Move to start\n" - purge_str += f"G0 F600 Z0.3 ; Move down\n" + purge_str += f"G0 F600 Z{self.purge_line_hgt} ; Move down\n" if self.prime_blob_enable: purge_str += adjust_for_prime_blob_gcode(self.retract_speed, self.retract_dist) # Purge two lines @@ -632,7 +632,7 @@ class PurgeLinesAndUnload(Script): purge_str += f"G1 F{int(self.retract_speed)} E{round(purge_volume * 2 - self.retract_dist, 5)} ; Retract\n" if self.retraction_enable else "" purge_str += "G0 F600 Z8 ; Move Up\nG4 S1 ; Wait for 1 second\n" # Wipe - purge_str += f"G0 F{self.print_speed} X{self.machine_right - 3 - self.border_distance} Y{self.machine_back - 20} Z0.3 ; Slide over and down\n" + purge_str += f"G0 F{self.print_speed} X{self.machine_right - 3 - self.border_distance} Y{self.machine_back - 20} Z{self.purge_line_hgt} ; Slide over and down\n" purge_str += f"G0 X{self.machine_right - 3 - self.border_distance} Y{self.machine_back - 35} ; Wipe\n" self.end_purge_location = Position.RIGHT_REAR elif purge_location == Location.FRONT: @@ -642,7 +642,7 @@ class PurgeLinesAndUnload(Script): purge_volume = calculate_purge_volume(self.init_line_width, purge_len, self.mm3_per_mm) # Travel to the purge start purge_str += f"G0 F{self.speed_travel} X{self.machine_left + 10} Z2 ; Move\nG0 Y{self.machine_front + self.border_distance} Z2 ; Move to start\n" - purge_str += f"G0 F600 Z0.3 ; Move down\n" + purge_str += f"G0 F600 Z{self.purge_line_hgt} ; Move down\n" if self.prime_blob_enable: purge_str += adjust_for_prime_blob_gcode(self.retract_speed, self.retract_dist) # Purge two lines @@ -653,7 +653,7 @@ class PurgeLinesAndUnload(Script): purge_str += f"G1 F{int(self.retract_speed)} E{round(purge_volume * 2 - self.retract_dist, 5)} ; Retract\n" if self.retraction_enable else "" purge_str += "G0 F600 Z8 ; Move Up\nG4 S1 ; Wait for 1 second\n" # Wipe - purge_str += f"G0 F{self.print_speed} X{self.machine_left + 20} Y{self.machine_front + 3 + self.border_distance} Z0.3 ; Slide over and down\n" + purge_str += f"G0 F{self.print_speed} X{self.machine_left + 20} Y{self.machine_front + 3 + self.border_distance} Z{self.purge_line_hgt} ; Slide over and down\n" purge_str += f"G0 X{self.machine_left + 35} Y{self.machine_front + 3 + self.border_distance} ; Wipe\n" self.end_purge_location = Position.LEFT_FRONT elif purge_location == Location.REAR: @@ -664,7 +664,7 @@ class PurgeLinesAndUnload(Script): # Travel to the purge start purge_str += f"G0 F{self.speed_travel} Y{self.machine_back - self.border_distance} Z2; Ortho Move to back\n" purge_str += f"G0 X{self.machine_right - 10} Z2 ; Ortho Move to start\n" - purge_str += f"G0 F600 Z0.3 ; Move down\n" + purge_str += f"G0 F600 Z{self.purge_line_hgt} ; Move down\n" if self.prime_blob_enable: purge_str += adjust_for_prime_blob_gcode(self.retract_speed, self.retract_dist) # Purge two lines @@ -675,7 +675,7 @@ class PurgeLinesAndUnload(Script): purge_str += f"G1 F{int(self.retract_speed)} E{round(purge_volume * 2 - self.retract_dist, 5)} ; Retract\n" if self.retraction_enable else "" purge_str += "G0 F600 Z8 ; Move Up\nG4 S1 ; Wait for 1 second\n" # Wipe - purge_str += f"G0 F{self.print_speed} X{self.machine_right - 20} Y{self.machine_back - 3 - self.border_distance} Z0.3 ; Slide over and down\n" + purge_str += f"G0 F{self.print_speed} X{self.machine_right - 20} Y{self.machine_back - 3 - self.border_distance} Z{self.purge_line_hgt} ; Slide over and down\n" purge_str += f"G0 X{self.machine_right - 35} Y{self.machine_back - 3 - self.border_distance} ; Wipe\n" self.end_purge_location = Position.RIGHT_REAR # Elliptic printers with Origin at Center @@ -689,7 +689,7 @@ class PurgeLinesAndUnload(Script): if purge_location == Location.LEFT: # Travel to the purge start purge_str += f"G0 F{self.speed_travel} X-{round(radius_1 * .707, 2)} Y-{round(radius_1 * .707, 2)} ; Travel\n" - purge_str += f"G0 F600 Z0.3 ; Move down\n" + purge_str += f"G0 F600 Z{self.purge_line_hgt} ; Move down\n" # Purge two arcs purge_str += f"G2 F{self.print_speed} X-{round(radius_1 * .707, 2)} Y{round(radius_1 * .707, 2)} I{round(radius_1 * .707, 2)} J{round(radius_1 * .707, 2)} E{purge_volume} ; First Arc\n" purge_str += f"G0 X-{round((radius_1 - 3) * .707, 2)} Y{round((radius_1 - 3) * .707, 2)} ; Move Over\n" @@ -699,13 +699,13 @@ class PurgeLinesAndUnload(Script): purge_str += f"G1 F{int(self.retract_speed)} E{round((purge_volume * 2 + 1) - self.retract_dist, 5)} ; Retract\n" if self.retraction_enable else "" purge_str += "G0 F600 Z5 ; Move Up\nG4 S1 ; Wait 1 Second\n" # Wipe - purge_str += f"G0 F{self.print_speed} X-{round((radius_1 - 3) * .707 - 15, 2)} Z0.3 ; Slide Over\n" + purge_str += f"G0 F{self.print_speed} X-{round((radius_1 - 3) * .707 - 15, 2)} Z{self.purge_line_hgt} ; Slide Over\n" purge_str += f"G0 F{self.print_speed} X-{round((radius_1 - 3) * .707, 2)} ; Wipe\n" self.end_purge_location = Position.LEFT_FRONT elif purge_location == Location.RIGHT: # Travel to the purge start purge_str += f"G0 F{self.speed_travel} X{round(radius_1 * .707, 2)} Y-{round(radius_1 * .707, 2)} ; Travel\n" - purge_str += f"G0 F600 Z0.3 ; Move down\n" + purge_str += f"G0 F600 Z{self.purge_line_hgt} ; Move down\n" # Purge two arcs purge_str += f"G3 F{self.print_speed} X{round(radius_1 * .707, 2)} Y{round(radius_1 * .707, 2)} I-{round(radius_1 * .707, 2)} J{round(radius_1 * .707, 2)} E{purge_volume} ; First Arc\n" purge_str += f"G0 X{round((radius_1 - 3) * .707, 2)} Y{round((radius_1 - 3) * .707, 2)} ; Move Over\n" @@ -715,13 +715,13 @@ class PurgeLinesAndUnload(Script): purge_str += f"G1 F{int(self.retract_speed)} E{round((purge_volume * 2 + 1) - self.retract_dist, 5)} ; Retract\n" if self.retraction_enable else "" purge_str += "G0 F600 Z5 ; Move Up\nG4 S1 ; Wait 1 Second\n" # Wipe - purge_str += f"G0 F{self.print_speed} X{round((radius_1 - 3) * .707 - 15, 2)} Z0.3 ; Slide Over\n" + purge_str += f"G0 F{self.print_speed} X{round((radius_1 - 3) * .707 - 15, 2)} Z{self.purge_line_hgt} ; Slide Over\n" purge_str += f"G0 F{self.print_speed} X{round((radius_1 - 3) * .707, 2)} ; Wipe\n" self.end_purge_location = Position.RIGHT_REAR elif purge_location == Location.FRONT: # Travel to the purge start purge_str += f"G0 F{self.speed_travel} X-{round(radius_1 * .707, 2)} Y-{round(radius_1 * .707, 2)} ; Travel\n" - purge_str += f"G0 F600 Z0.3 ; Move down\n" + purge_str += f"G0 F600 Z{self.purge_line_hgt} ; Move down\n" # Purge two arcs purge_str += f"G3 F{self.print_speed} X{round(radius_1 * .707, 2)} Y-{round(radius_1 * .707, 2)} I{round(radius_1 * .707, 2)} J{round(radius_1 * .707, 2)} E{purge_volume} ; First Arc\n" purge_str += f"G0 X{round((radius_1 - 3) * .707, 2)} Y-{round((radius_1 - 3) * .707, 2)} ; Move Over\n" @@ -731,13 +731,13 @@ class PurgeLinesAndUnload(Script): purge_str += f"G1 F{int(self.retract_speed)} E{round((purge_volume * 2 + 1) - self.retract_dist, 5)} ; Retract\n" if self.retraction_enable else "" purge_str += "G0 F600 Z5 ; Move Up\nG4 S1 ; Wait 1 Second\n" # Wipe - purge_str += f"G0 F{self.print_speed} Y-{round((radius_1 - 3) * .707 - 15, 2)} Z0.3 ; Slide Over\n" + purge_str += f"G0 F{self.print_speed} Y-{round((radius_1 - 3) * .707 - 15, 2)} Z{self.purge_line_hgt} ; Slide Over\n" purge_str += f"G0 F{self.print_speed} Y-{round((radius_1 - 3) * .707, 2)} ; Wipe\n" self.end_purge_location = Position.LEFT_FRONT elif purge_location == Location.REAR: # Travel to the purge start purge_str += f"G0 F{self.speed_travel} X{round(radius_1 * .707, 2)} Y{round(radius_1 * .707, 2)} ; Travel\n" - purge_str += f"G0 F600 Z0.3 ; Move down\n" + purge_str += f"G0 F600 Z{self.purge_line_hgt} ; Move down\n" # Purge two arcs purge_str += f"G3 F{self.print_speed} X-{round(radius_1 * .707, 2)} Y{round(radius_1 * .707, 2)} I-{round(radius_1 * .707, 2)} J-{round(radius_1 * .707, 2)} E{purge_volume} ; First Arc\n" purge_str += f"G0 X-{round((radius_1 - 3) * .707, 2)} Y{round((radius_1 - 3) * .707, 2)} ; Move Over\n" @@ -747,7 +747,7 @@ class PurgeLinesAndUnload(Script): purge_str += f"G1 F{int(self.retract_speed)} E{round((purge_volume * 2 + 1) - self.retract_dist, 5)} ; Retract\n" if self.retraction_enable else "" purge_str += "G0 F600 Z5\nG4 S1 ; Wait 1 Second\n" # Wipe - purge_str += f"G0 F{self.print_speed} Y{round((radius_1 - 3) * .707 - 15, 2)} Z0.3 ; Slide Over\n" + purge_str += f"G0 F{self.print_speed} Y{round((radius_1 - 3) * .707 - 15, 2)} Z{self.purge_line_hgt} ; Slide Over\n" purge_str += f"G0 F{self.print_speed} Y{round((radius_1 - 3) * .707, 2)} ; Wipe\n" self.end_purge_location = Position.RIGHT_REAR From 36eb462bb7b7c31eecccf88c3fc99837ed9fded4 Mon Sep 17 00:00:00 2001 From: HellAholic Date: Sun, 19 Oct 2025 08:58:02 +0200 Subject: [PATCH 6/7] Remove trailing whitespace in PurgeLinesAndUnload.py --- plugins/PostProcessingPlugin/scripts/PurgeLinesAndUnload.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/PostProcessingPlugin/scripts/PurgeLinesAndUnload.py b/plugins/PostProcessingPlugin/scripts/PurgeLinesAndUnload.py index c94c99ec11..6345f951dd 100644 --- a/plugins/PostProcessingPlugin/scripts/PurgeLinesAndUnload.py +++ b/plugins/PostProcessingPlugin/scripts/PurgeLinesAndUnload.py @@ -497,7 +497,7 @@ class PurgeLinesAndUnload(Script): "G92 E0 ; Reset extruder\n" ] return "\n".join(gcode_lines) - + purge_location = self.getSettingValueByKey("purge_line_location") purge_extrusion_full = True if self.getSettingValueByKey("purge_line_length") == "purge_full" else False purge_str = ";TYPE:CUSTOM----------[Purge Lines]\nG0 F600 Z2 ; Move up\nG92 E0 ; Reset extruder\n" From d980d28300caf7317f41c33d3c59a7cb5df05b17 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Wed, 22 Oct 2025 17:20:04 +0200 Subject: [PATCH 7/7] Fix unit-test after merge. --- tests/conftest.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/conftest.py b/tests/conftest.py index 377a525ba7..6f69b5df53 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -21,6 +21,12 @@ from UM.Settings.ContainerRegistry import ContainerRegistry @pytest.fixture() def application() -> CuraApplication: app = MagicMock() + app.getInstance = MagicMock(return_value=app) + machine_manager = MagicMock() + extruder_changed_signal = MagicMock() + extruder_changed_signal.connect = MagicMock() + machine_manager.extruderChanged = extruder_changed_signal + app.getMachineManager = MagicMock(return_value=machine_manager) return app @pytest.fixture()