FilamentChange.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. # Copyright (c) 2019 Ultimaker B.V.
  2. # The PostProcessingPlugin is released under the terms of the AGPLv3 or higher.
  3. from typing import Optional, Tuple
  4. from UM.Logger import Logger
  5. from ..Script import Script
  6. class FilamentChange(Script):
  7. _layer_keyword = ";LAYER:"
  8. def __init__(self):
  9. super().__init__()
  10. def getSettingDataString(self):
  11. return """{
  12. "name":"Filament Change",
  13. "key": "FilamentChange",
  14. "metadata": {},
  15. "version": 2,
  16. "settings":
  17. {
  18. "layer_number":
  19. {
  20. "label": "Layer",
  21. "description": "At what layer should color change occur. This will be before the layer starts printing. Specify multiple color changes with a comma.",
  22. "unit": "",
  23. "type": "str",
  24. "default_value": "1"
  25. },
  26. "initial_retract":
  27. {
  28. "label": "Initial Retraction",
  29. "description": "Initial filament retraction distance. The filament will be retracted with this amount before moving the nozzle away from the ongoing print.",
  30. "unit": "mm",
  31. "type": "float",
  32. "default_value": 30.0
  33. },
  34. "later_retract":
  35. {
  36. "label": "Later Retraction Distance",
  37. "description": "Later filament retraction distance for removal. The filament will be retracted all the way out of the printer so that you can change the filament.",
  38. "unit": "mm",
  39. "type": "float",
  40. "default_value": 300.0
  41. },
  42. "x_position":
  43. {
  44. "label": "X Position",
  45. "description": "Extruder X position. The print head will move here for filament change.",
  46. "unit": "mm",
  47. "type": "float",
  48. "default_value": 0
  49. },
  50. "y_position":
  51. {
  52. "label": "Y Position",
  53. "description": "Extruder Y position. The print head will move here for filament change.",
  54. "unit": "mm",
  55. "type": "float",
  56. "default_value": 0
  57. }
  58. }
  59. }"""
  60. def execute(self, data: list):
  61. """data is a list. Each index contains a layer"""
  62. layer_nums = self.getSettingValueByKey("layer_number")
  63. initial_retract = self.getSettingValueByKey("initial_retract")
  64. later_retract = self.getSettingValueByKey("later_retract")
  65. x_pos = self.getSettingValueByKey("x_position")
  66. y_pos = self.getSettingValueByKey("y_position")
  67. color_change = "M600"
  68. if initial_retract is not None and initial_retract > 0.:
  69. color_change = color_change + (" E%.2f" % initial_retract)
  70. if later_retract is not None and later_retract > 0.:
  71. color_change = color_change + (" L%.2f" % later_retract)
  72. if x_pos is not None:
  73. color_change = color_change + (" X%.2f" % x_pos)
  74. if y_pos is not None:
  75. color_change = color_change + (" Y%.2f" % y_pos)
  76. color_change = color_change + " ; Generated by FilamentChange plugin"
  77. layer_targets = layer_nums.split(",")
  78. if len(layer_targets) > 0:
  79. for layer_num in layer_targets:
  80. layer_num = int(layer_num.strip())
  81. if layer_num <= len(data):
  82. index, layer_data = self._searchLayerData(data, layer_num - 1)
  83. if layer_data is None:
  84. Logger.log("e", "Could not found the layer")
  85. continue
  86. lines = layer_data.split("\n")
  87. lines.insert(2, color_change)
  88. final_line = "\n".join(lines)
  89. data[index] = final_line
  90. return data
  91. ## This method returns the data corresponding with the indicated layer number, looking in the gcode for
  92. # the occurrence of this layer number.
  93. def _searchLayerData(self, data: list, layer_num: int) -> Tuple[int, Optional[str]]:
  94. for index, layer_data in enumerate(data):
  95. first_line = layer_data.split("\n")[0]
  96. # The first line should contain the layer number at the beginning.
  97. if first_line[:len(self._layer_keyword)] == self._layer_keyword:
  98. # If found the layer that we are looking for, then return the data
  99. if first_line[len(self._layer_keyword):] == str(layer_num):
  100. return index, layer_data
  101. return 0, None