Browse Source

Merge pull request #6315 from Ultimaker/CURA-6755_add_retract_continue_script

Add retract-continue script
Jaime van Kessel 5 years ago
parent
commit
8c893caf9f
1 changed files with 75 additions and 0 deletions
  1. 75 0
      plugins/PostProcessingPlugin/scripts/RetractContinue.py

+ 75 - 0
plugins/PostProcessingPlugin/scripts/RetractContinue.py

@@ -0,0 +1,75 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# The PostProcessingPlugin is released under the terms of the AGPLv3 or higher.
+
+import math
+
+from ..Script import Script
+
+##  Continues retracting during all travel moves.
+class RetractContinue(Script):
+    def getSettingDataString(self):
+        return """{
+            "name": "Retract Continue",
+            "key": "RetractContinue",
+            "metadata": {},
+            "version": 2,
+            "settings":
+            {
+                "extra_retraction_speed":
+                {
+                    "label": "Extra Retraction Ratio",
+                    "description": "How much does it retract during the travel move, by ratio of the travel length.",
+                    "type": "float",
+                    "default_value": 0.05
+                }
+            }
+        }"""
+
+    def execute(self, data):
+        current_e = 0
+        current_x = 0
+        current_y = 0
+        extra_retraction_speed = self.getSettingValueByKey("extra_retraction_speed")
+
+        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 location.
+                    current_x = self.getValue(line, "X", current_x)
+                    current_y = self.getValue(line, "Y", current_y)
+                if self.getValue(line, "G") == 1:
+                    if self.getValue(line, "E"):
+                        new_e = self.getValue(line, "E")
+                        if new_e >= current_e:  # Not a retraction.
+                            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
+                        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)
+                            f = self.getValue(travel_move, "F", "no f")
+                            length = math.sqrt((travel_x - dx) * (travel_x - dx) + (travel_y - dy) * (travel_y - dy))  # 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} E{new_e}".format(travel_x = travel_x, travel_y = travel_y, new_e = new_e)
+                            else:
+                                new_travel_move = "G1 F{f} X{travel_x} Y{travel_y} E{new_e}".format(f = f, travel_x = travel_x, travel_y = travel_y, new_e = new_e)
+                            lines[line_number + delta_line] = new_travel_move
+
+                            delta_line += 1
+                            dx = travel_x
+                            dy = travel_y
+
+                        current_e = new_e
+
+            new_layer = "\n".join(lines)
+            data[layer_number] = new_layer
+
+        return data