PerObjectSettingsTool.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. # Copyright (c) 2016 Ultimaker B.V.
  2. # Uranium is released under the terms of the LGPLv3 or higher.
  3. from UM.Tool import Tool
  4. from UM.Scene.Selection import Selection
  5. from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
  6. from UM.Application import Application
  7. from UM.Preferences import Preferences
  8. from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator
  9. from cura.Settings.ExtruderManager import ExtruderManager
  10. from UM.Event import Event
  11. ## This tool allows the user to add & change settings per node in the scene.
  12. # The settings per object are kept in a ContainerStack, which is linked to a node by decorator.
  13. class PerObjectSettingsTool(Tool):
  14. def __init__(self):
  15. super().__init__()
  16. self._model = None
  17. self.setExposedProperties("SelectedObjectId", "ContainerID", "SelectedActiveExtruder")
  18. self._advanced_mode = False
  19. self._multi_extrusion = False
  20. self._single_model_selected = False
  21. Selection.selectionChanged.connect(self.propertyChanged)
  22. Preferences.getInstance().preferenceChanged.connect(self._onPreferenceChanged)
  23. self._onPreferenceChanged("cura/active_mode")
  24. Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged)
  25. self._onGlobalContainerChanged()
  26. Selection.selectionChanged.connect(self._updateEnabled)
  27. def event(self, event):
  28. super().event(event)
  29. if event.type == Event.MousePressEvent and self._controller.getToolsEnabled():
  30. self.operationStopped.emit(self)
  31. return False
  32. def getSelectedObjectId(self):
  33. selected_object = Selection.getSelectedObject(0)
  34. selected_object_id = id(selected_object)
  35. return selected_object_id
  36. def getContainerID(self):
  37. selected_object = Selection.getSelectedObject(0)
  38. try:
  39. return selected_object.callDecoration("getStack").getId()
  40. except AttributeError:
  41. return ""
  42. ## Gets the active extruder of the currently selected object.
  43. #
  44. # \return The active extruder of the currently selected object.
  45. def getSelectedActiveExtruder(self):
  46. selected_object = Selection.getSelectedObject(0)
  47. return selected_object.callDecoration("getActiveExtruder")
  48. ## Changes the active extruder of the currently selected object.
  49. #
  50. # \param extruder_stack_id The ID of the extruder to print the currently
  51. # selected object with.
  52. def setSelectedActiveExtruder(self, extruder_stack_id):
  53. selected_object = Selection.getSelectedObject(0)
  54. stack = selected_object.callDecoration("getStack") #Don't try to get the active extruder since it may be None anyway.
  55. if not stack:
  56. selected_object.addDecorator(SettingOverrideDecorator())
  57. selected_object.callDecoration("setActiveExtruder", extruder_stack_id)
  58. def _onPreferenceChanged(self, preference):
  59. if preference == "cura/active_mode":
  60. self._advanced_mode = Preferences.getInstance().getValue(preference) == 1
  61. self._updateEnabled()
  62. def _onGlobalContainerChanged(self):
  63. global_container_stack = Application.getInstance().getGlobalContainerStack()
  64. if global_container_stack:
  65. self._multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1
  66. # Ensure that all extruder data is reset
  67. if not self._multi_extrusion:
  68. default_stack_id = global_container_stack.getId()
  69. else:
  70. default_stack = ExtruderManager.getInstance().getExtruderStack(0)
  71. if default_stack:
  72. default_stack_id = default_stack.getId()
  73. else:
  74. default_stack_id = global_container_stack.getId()
  75. root_node = Application.getInstance().getController().getScene().getRoot()
  76. for node in DepthFirstIterator(root_node):
  77. new_stack_id = default_stack_id
  78. # Get position of old extruder stack for this node
  79. old_extruder_pos = node.callDecoration("getActiveExtruderPosition")
  80. if old_extruder_pos is not None:
  81. # Fetch current (new) extruder stack at position
  82. new_stack = ExtruderManager.getInstance().getExtruderStack(old_extruder_pos)
  83. if new_stack:
  84. new_stack_id = new_stack.getId()
  85. node.callDecoration("setActiveExtruder", new_stack_id)
  86. self._updateEnabled()
  87. def _updateEnabled(self):
  88. selected_objects = Selection.getAllSelectedObjects()
  89. if len(selected_objects)> 1:
  90. self._single_model_selected = False
  91. elif len(selected_objects) == 1 and selected_objects[0].callDecoration("isGroup"):
  92. self._single_model_selected = False # Group is selected, so tool needs to be disabled
  93. else:
  94. self._single_model_selected = True
  95. Application.getInstance().getController().toolEnabledChanged.emit(self._plugin_id, self._advanced_mode and self._single_model_selected)