diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 0ac50c9e5e..342f6cb91d 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -278,6 +278,11 @@ class CuraApplication(QtApplication): # We need them to simplify the switching between materials. empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer() + empty_definition_changes_container = copy.deepcopy(empty_container) + empty_definition_changes_container.setMetaDataEntry("id", "empty_definition_changes") + empty_definition_changes_container.addMetaDataEntry("type", "definition_changes") + ContainerRegistry.getInstance().addContainer(empty_definition_changes_container) + empty_variant_container = copy.deepcopy(empty_container) empty_variant_container.setMetaDataEntry("id", "empty_variant") empty_variant_container.addMetaDataEntry("type", "variant") diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 05aed1f5e2..23799e34b1 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -3,6 +3,8 @@ #Type hinting. from typing import Union, List, Dict + +from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Signal import Signal from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QTimer @@ -74,6 +76,7 @@ class MachineManager(QObject): self._stacks_have_errors = None + self._empty_definition_changes_container = ContainerRegistry.getInstance().findContainers(id = "empty_definition_changes")[0] self._empty_variant_container = ContainerRegistry.getInstance().findContainers(id = "empty_variant")[0] self._empty_material_container = ContainerRegistry.getInstance().findContainers(id = "empty_material")[0] self._empty_quality_container = ContainerRegistry.getInstance().findContainers(id = "empty_quality")[0] @@ -1236,6 +1239,68 @@ class MachineManager(QObject): if containers: return containers[0].definition.getId() + ## Set the amount of extruders on the active machine (global stack) + # \param extruder_count int the number of extruders to set + def setActiveMachineExtruderCount(self, extruder_count): + extruder_manager = Application.getInstance().getExtruderManager() + + definition_changes_container = self._global_container_stack.definitionChanges + if not self._global_container_stack or definition_changes_container == self._empty_definition_changes_container: + return + + previous_extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value") + if extruder_count == previous_extruder_count: + return + + # reset all extruder number settings whose value is no longer valid + for setting_instance in self._global_container_stack.userChanges.findInstances(): + setting_key = setting_instance.definition.key + if not self._global_container_stack.getProperty(setting_key, "type") in ("extruder", "optional_extruder"): + continue + + old_value = int(self._global_container_stack.userChanges.getProperty(setting_key, "value")) + if old_value >= extruder_count: + self._global_container_stack.userChanges.removeInstance(setting_key) + Logger.log("d", "Reset [%s] because its old value [%s] is no longer valid ", setting_key, old_value) + + # Check to see if any objects are set to print with an extruder that will no longer exist + root_node = Application.getInstance().getController().getScene().getRoot() + for node in DepthFirstIterator(root_node): + if node.getMeshData(): + extruder_nr = node.callDecoration("getActiveExtruderPosition") + + if extruder_nr is not None and int(extruder_nr) > extruder_count - 1: + node.callDecoration("setActiveExtruder", extruder_manager.getExtruderStack(extruder_count - 1).getId()) + + definition_changes_container.setProperty("machine_extruder_count", "value", extruder_count) + + # Make sure one of the extruder stacks is active + extruder_manager.setActiveExtruderIndex(0) + + # Move settable_per_extruder values out of the global container + # After CURA-4482 this should not be the case anymore, but we still want to support older project files. + global_user_container = self._global_container_stack.getTop() + + # Make sure extruder_stacks exists + extruder_stacks = [] + + if previous_extruder_count == 1: + extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks() + global_user_container = self._global_container_stack.getTop() + + for setting_instance in global_user_container.findInstances(): + setting_key = setting_instance.definition.key + settable_per_extruder = self._global_container_stack.getProperty(setting_key, "settable_per_extruder") + + if settable_per_extruder: + limit_to_extruder = int(self._global_container_stack.getProperty(setting_key, "limit_to_extruder")) + extruder_stack = extruder_stacks[max(0, limit_to_extruder)] + extruder_stack.getTop().setProperty(setting_key, "value", global_user_container.getProperty(setting_key, "value")) + global_user_container.removeInstance(setting_key) + + # Signal that the global stack has changed + Application.getInstance().globalContainerStackChanged.emit() + @staticmethod def createMachineManager(): return MachineManager() diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py index 101ba54ed0..ae1c1663dd 100755 --- a/plugins/MachineSettingsAction/MachineSettingsAction.py +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -105,60 +105,9 @@ class MachineSettingsAction(MachineAction): @pyqtSlot(int) def setMachineExtruderCount(self, extruder_count): - extruder_manager = Application.getInstance().getExtruderManager() - - definition_changes_container = self._global_container_stack.definitionChanges - if not self._global_container_stack or definition_changes_container == self._empty_container: - return - - previous_extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value") - if extruder_count == previous_extruder_count: - return - - # reset all extruder number settings whose value is no longer valid - for setting_instance in self._global_container_stack.userChanges.findInstances(): - setting_key = setting_instance.definition.key - if not self._global_container_stack.getProperty(setting_key, "type") in ("extruder", "optional_extruder"): - continue - - old_value = int(self._global_container_stack.userChanges.getProperty(setting_key, "value")) - if old_value >= extruder_count: - self._global_container_stack.userChanges.removeInstance(setting_key) - Logger.log("d", "Reset [%s] because its old value [%s] is no longer valid ", setting_key, old_value) - - # Check to see if any objects are set to print with an extruder that will no longer exist - root_node = Application.getInstance().getController().getScene().getRoot() - for node in DepthFirstIterator(root_node): - if node.getMeshData(): - extruder_nr = node.callDecoration("getActiveExtruderPosition") - - if extruder_nr is not None and int(extruder_nr) > extruder_count - 1: - node.callDecoration("setActiveExtruder", extruder_manager.getExtruderStack(extruder_count - 1).getId()) - - definition_changes_container.setProperty("machine_extruder_count", "value", extruder_count) - - # Make sure one of the extruder stacks is active - extruder_manager.setActiveExtruderIndex(0) - - # Move settable_per_extruder values out of the global container - # After CURA-4482 this should not be the case anymore, but we still want to support older project files. - global_user_container = self._global_container_stack.getTop() - - if previous_extruder_count == 1: - extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks() - global_user_container = self._global_container_stack.getTop() - - for setting_instance in global_user_container.findInstances(): - setting_key = setting_instance.definition.key - settable_per_extruder = self._global_container_stack.getProperty(setting_key, "settable_per_extruder") - - if settable_per_extruder: - limit_to_extruder = int(self._global_container_stack.getProperty(setting_key, "limit_to_extruder")) - extruder_stack = extruder_stacks[max(0, limit_to_extruder)] - extruder_stack.getTop().setProperty(setting_key, "value", global_user_container.getProperty(setting_key, "value")) - global_user_container.removeInstance(setting_key) - - self.forceUpdate() + # Note: this method was in this class before, but since it's quite generic and other plugins also need it + # it was moved to the machine manager instead. Now this method just calls the machine manager. + Application.getInstance().getMachineManager().setActiveMachineExtruderCount(extruder_count) @pyqtSlot() def forceUpdate(self):