RetractContinue.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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. class RetractContinue(Script):
  6. """Continues retracting during all travel moves."""
  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. current_z = 0
  29. extra_retraction_speed = self.getSettingValueByKey("extra_retraction_speed")
  30. for layer_number, layer in enumerate(data):
  31. lines = layer.split("\n")
  32. for line_number, line in enumerate(lines):
  33. if self.getValue(line, "G") in {0, 1}: # Track X,Y,Z location.
  34. current_x = self.getValue(line, "X", current_x)
  35. current_y = self.getValue(line, "Y", current_y)
  36. current_z = self.getValue(line, "Z", current_z)
  37. if self.getValue(line, "G") == 1:
  38. if not self.getValue(line, "E"): # Either None or 0: Not a retraction then.
  39. continue
  40. new_e = self.getValue(line, "E")
  41. if new_e - current_e >= -0.0001: # Not a retraction. Account for floating point rounding errors.
  42. current_e = new_e
  43. continue
  44. # A retracted travel move may consist of multiple commands, due to combing.
  45. # This continues retracting over all of these moves and only unretracts at the end.
  46. delta_line = 1
  47. dx = current_x # Track the difference in X for this move only to compute the length of the travel.
  48. dy = current_y
  49. dz = current_z
  50. while line_number + delta_line < len(lines) and self.getValue(lines[line_number + delta_line], "G") != 1:
  51. travel_move = lines[line_number + delta_line]
  52. if self.getValue(travel_move, "G") != 0:
  53. delta_line += 1
  54. continue
  55. travel_x = self.getValue(travel_move, "X", dx)
  56. travel_y = self.getValue(travel_move, "Y", dy)
  57. travel_z = self.getValue(travel_move, "Z", dz)
  58. f = self.getValue(travel_move, "F", "no f")
  59. 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.
  60. new_e -= length * extra_retraction_speed # New retraction is by ratio of this travel move.
  61. if f == "no f":
  62. 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)
  63. else:
  64. 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)
  65. lines[line_number + delta_line] = new_travel_move
  66. delta_line += 1
  67. dx = travel_x
  68. dy = travel_y
  69. dz = travel_z
  70. current_e = new_e
  71. new_layer = "\n".join(lines)
  72. data[layer_number] = new_layer
  73. return data