RetractContinue.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. # Copyright (c) 2019 Ultimaker B.V.
  2. # The PostProcessingPlugin is released under the terms of the AGPLv3 or higher.
  3. import math
  4. from ..Script import Script
  5. ## Continues retracting during all travel moves.
  6. class RetractContinue(Script):
  7. def getSettingDataString(self):
  8. return """{
  9. "name": "Retract Continue",
  10. "key": "RetractContinue",
  11. "metadata": {},
  12. "version": 2,
  13. "settings":
  14. {
  15. "extra_retraction_speed":
  16. {
  17. "label": "Extra Retraction Ratio",
  18. "description": "How much does it retract during the travel move, by ratio of the travel length.",
  19. "type": "float",
  20. "default_value": 0.05
  21. }
  22. }
  23. }"""
  24. def execute(self, data):
  25. current_e = 0
  26. current_x = 0
  27. current_y = 0
  28. extra_retraction_speed = self.getSettingValueByKey("extra_retraction_speed")
  29. for layer_number, layer in enumerate(data):
  30. lines = layer.split("\n")
  31. for line_number, line in enumerate(lines):
  32. if self.getValue(line, "G") in {0, 1}: # Track X,Y location.
  33. current_x = self.getValue(line, "X", current_x)
  34. current_y = self.getValue(line, "Y", current_y)
  35. if self.getValue(line, "G") == 1:
  36. if self.getValue(line, "E"):
  37. new_e = self.getValue(line, "E")
  38. if new_e >= current_e: # Not a retraction.
  39. continue
  40. # A retracted travel move may consist of multiple commands, due to combing.
  41. # This continues retracting over all of these moves and only unretracts at the end.
  42. delta_line = 1
  43. dx = current_x # Track the difference in X for this move only to compute the length of the travel.
  44. dy = current_y
  45. while line_number + delta_line < len(lines) and self.getValue(lines[line_number + delta_line], "G") != 1:
  46. travel_move = lines[line_number + delta_line]
  47. if self.getValue(travel_move, "G") != 0:
  48. delta_line += 1
  49. continue
  50. travel_x = self.getValue(travel_move, "X", dx)
  51. travel_y = self.getValue(travel_move, "Y", dy)
  52. f = self.getValue(travel_move, "F", "no f")
  53. length = math.sqrt((travel_x - dx) * (travel_x - dx) + (travel_y - dy) * (travel_y - dy)) # Length of the travel move.
  54. new_e -= length * extra_retraction_speed # New retraction is by ratio of this travel move.
  55. if f == "no f":
  56. 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)
  57. else:
  58. 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)
  59. lines[line_number + delta_line] = new_travel_move
  60. delta_line += 1
  61. dx = travel_x
  62. dy = travel_y
  63. current_e = new_e
  64. new_layer = "\n".join(lines)
  65. data[layer_number] = new_layer
  66. return data