From c4a1bd2fd3a87bc68ca7e4d9b8ecb4404319c498 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 10 Jun 2016 16:13:47 +0200 Subject: [PATCH 1/6] Automatically use global- or extruder- containerstack CURA-1585 --- cura/MachineManagerModel.py | 116 ++++++++++++++++++++---------------- 1 file changed, 66 insertions(+), 50 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 0e7230fb79..f5661320ec 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -18,16 +18,25 @@ class MachineManagerModel(QObject): def __init__(self, parent = None): super().__init__(parent) + self._active_container_stack = None self._global_container_stack = None + Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged) self._global_stack_valid = None self._onGlobalContainerChanged() + ExtruderManager.ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderStackChanged) + self._onActiveExtruderStackChanged() + ## When the global container is changed, active material probably needs to be updated. self.globalContainerChanged.connect(self.activeMaterialChanged) self.globalContainerChanged.connect(self.activeVariantChanged) self.globalContainerChanged.connect(self.activeQualityChanged) + self.globalContainerChanged.connect(self.activeStackChanged) + self.globalValueChanged.connect(self.activeStackChanged) + ExtruderManager.ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeStackChanged) + self._empty_variant_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_variant")[0] self._empty_material_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_material")[0] self._empty_quality_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_quality")[0] @@ -45,6 +54,7 @@ class MachineManagerModel(QObject): activeMaterialChanged = pyqtSignal() activeVariantChanged = pyqtSignal() activeQualityChanged = pyqtSignal() + activeStackChanged = pyqtSignal() globalValueChanged = pyqtSignal() # Emitted whenever a value inside global container is changed. globalValidationChanged = pyqtSignal() # Emitted whenever a validation inside global container is changed. @@ -63,12 +73,12 @@ class MachineManagerModel(QObject): self.globalValueChanged.emit() if property_name == "validationState": if self._global_stack_valid: - changed_validation_state = self._global_container_stack.getProperty(key, property_name) + changed_validation_state = self._active_container_stack.getProperty(key, property_name) if changed_validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError): self._global_stack_valid = False self.globalValidationChanged.emit() else: - new_validation_state = self._checkStackForErrors(self._global_container_stack) + new_validation_state = self._checkStackForErrors(self._active_container_stack) if new_validation_state: self._global_stack_valid = True self.globalValidationChanged.emit() @@ -87,6 +97,11 @@ class MachineManagerModel(QObject): self._global_container_stack.propertyChanged.connect(self._onGlobalPropertyChanged) self._global_stack_valid = not self._checkStackForErrors(self._global_container_stack) + def _onActiveExtruderStackChanged(self): + self._active_container_stack = ExtruderManager.ExtruderManager.getInstance().getActiveExtruderStack() + if not self._active_container_stack: + self._active_container_stack = self._global_container_stack + def _onInstanceContainersChanged(self, container): container_type = container.getMetaDataEntry("type") if container_type == "material": @@ -183,18 +198,19 @@ class MachineManagerModel(QObject): ## Remove all instances from the top instanceContainer (effectively removing all user-changed settings) @pyqtSlot() def clearUserSettings(self): - if not self._global_container_stack: + if not self._active_container_stack: return - user_settings = self._global_container_stack.getTop() + + user_settings = self._active_container_stack.getTop() user_settings.clear() ## Check if the global_container has instances in the user container - @pyqtProperty(bool, notify = globalValueChanged) + @pyqtProperty(bool, notify = activeStackChanged) def hasUserSettings(self): - if not self._global_container_stack: + if not self._active_container_stack: return - user_settings = self._global_container_stack.getTop().findInstances(**{}) + user_settings = self._active_container_stack.getTop().findInstances(**{}) return len(user_settings) != 0 ## Check if the global profile does not contain error states @@ -206,8 +222,8 @@ class MachineManagerModel(QObject): @pyqtProperty(str, notify = globalContainerChanged) def activeUserProfileId(self): - if self._global_container_stack: - return self._global_container_stack.getTop().getId() + if self._active_container_stack: + return self._active_container_stack.getTop().getId() return "" @@ -227,8 +243,8 @@ class MachineManagerModel(QObject): @pyqtProperty(str, notify = activeMaterialChanged) def activeMaterialName(self): - if self._global_container_stack: - material = self._global_container_stack.findContainer({"type":"material"}) + if self._active_container_stack: + material = self._active_container_stack.findContainer({"type":"material"}) if material: return material.getName() @@ -236,8 +252,8 @@ class MachineManagerModel(QObject): @pyqtProperty(str, notify=activeMaterialChanged) def activeMaterialId(self): - if self._global_container_stack: - material = self._global_container_stack.findContainer({"type": "material"}) + if self._active_container_stack: + material = self._active_container_stack.findContainer({"type": "material"}) if material: return material.getId() @@ -245,16 +261,16 @@ class MachineManagerModel(QObject): @pyqtProperty(str, notify=activeQualityChanged) def activeQualityName(self): - if self._global_container_stack: - quality = self._global_container_stack.findContainer({"type": "quality"}) + if self._active_container_stack: + quality = self._active_container_stack.findContainer({"type": "quality"}) if quality: return quality.getName() return "" @pyqtProperty(str, notify=activeQualityChanged) def activeQualityId(self): - if self._global_container_stack: - quality = self._global_container_stack.findContainer({"type": "quality"}) + if self._active_container_stack: + quality = self._active_container_stack.findContainer({"type": "quality"}) if quality: return quality.getId() return "" @@ -262,8 +278,8 @@ class MachineManagerModel(QObject): ## Check if a container is read_only @pyqtSlot(str, result = bool) def isReadOnly(self, container_id): - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=container_id) - if not containers or not self._global_container_stack: + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id) + if not containers or not self._active_container_stack: return True return containers[0].isReadOnly() @@ -278,9 +294,9 @@ class MachineManagerModel(QObject): @pyqtSlot(str, result=str) def duplicateContainer(self, container_id): - if not self._global_container_stack: + if not self._active_container_stack: return "" - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=container_id) + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id) if containers: new_name = self._createUniqueName("quality", "", containers[0].getName(), catalog.i18nc("@label", "Custom profile")) @@ -331,7 +347,7 @@ class MachineManagerModel(QObject): @pyqtSlot(str) def removeQualityContainer(self, container_id): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id) - if not containers or not self._global_container_stack: + if not containers or not self._active_container_stack: return # If the container that is being removed is the currently active container, set another machine as the active container @@ -349,10 +365,10 @@ class MachineManagerModel(QObject): @pyqtSlot() def updateQualityContainerFromUserContainer(self): - if not self._global_container_stack: + if not self._active_container_stack: return - user_settings = self._global_container_stack.getTop() - quality = self._global_container_stack.findContainer({"type": "quality"}) + user_settings = self._active_container_stack.getTop() + quality = self._active_container_stack.findContainer({"type": "quality"}) for key in user_settings.getAllKeys(): quality.setProperty(key, "value", user_settings.getProperty(key, "value")) self.clearUserSettings() # As all users settings are noq a quality, remove them. @@ -360,45 +376,45 @@ class MachineManagerModel(QObject): @pyqtSlot(str) def setActiveMaterial(self, material_id): - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=material_id) - if not containers or not self._global_container_stack: + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = material_id) + if not containers or not self._active_container_stack: return - old_material = self._global_container_stack.findContainer({"type":"material"}) + old_material = self._active_container_stack.findContainer({"type":"material"}) if old_material: - material_index = self._global_container_stack.getContainerIndex(old_material) - self._global_container_stack.replaceContainer(material_index, containers[0]) + material_index = self._active_container_stack.getContainerIndex(old_material) + self._active_container_stack.replaceContainer(material_index, containers[0]) - self.setActiveQuality(self._updateQualityContainer(self._global_container_stack.getBottom(), containers[0]).id) + self.setActiveQuality(self._updateQualityContainer(self._active_container_stack.getBottom(), containers[0]).id) @pyqtSlot(str) def setActiveVariant(self, variant_id): - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=variant_id) - if not containers or not self._global_container_stack: + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = variant_id) + if not containers or not self._active_container_stack: return - old_variant = self._global_container_stack.findContainer({"type": "variant"}) + old_variant = self._active_container_stack.findContainer({"type": "variant"}) if old_variant: - variant_index = self._global_container_stack.getContainerIndex(old_variant) - self._global_container_stack.replaceContainer(variant_index, containers[0]) + variant_index = self._active_container_stack.getContainerIndex(old_variant) + self._active_container_stack.replaceContainer(variant_index, containers[0]) - self.setActiveMaterial(self._updateMaterialContainer(self._global_container_stack.getBottom(), containers[0]).id) + self.setActiveMaterial(self._updateMaterialContainer(self._active_container_stack.getBottom(), containers[0]).id) @pyqtSlot(str) def setActiveQuality(self, quality_id): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = quality_id) - if not containers or not self._global_container_stack: + if not containers or not self._active_container_stack: return - old_quality = self._global_container_stack.findContainer({"type": "quality"}) + old_quality = self._active_container_stack.findContainer({"type": "quality"}) if old_quality: - quality_index = self._global_container_stack.getContainerIndex(old_quality) - self._global_container_stack.replaceContainer(quality_index, containers[0]) + quality_index = self._active_container_stack.getContainerIndex(old_quality) + self._active_container_stack.replaceContainer(quality_index, containers[0]) @pyqtProperty(str, notify = activeVariantChanged) def activeVariantName(self): - if self._global_container_stack: - variant = self._global_container_stack.findContainer({"type": "variant"}) + if self._active_container_stack: + variant = self._active_container_stack.findContainer({"type": "variant"}) if variant: return variant.getName() @@ -406,8 +422,8 @@ class MachineManagerModel(QObject): @pyqtProperty(str, notify = activeVariantChanged) def activeVariantId(self): - if self._global_container_stack: - variant = self._global_container_stack.findContainer({"type": "variant"}) + if self._active_container_stack: + variant = self._active_container_stack.findContainer({"type": "variant"}) if variant: return variant.getId() @@ -415,7 +431,7 @@ class MachineManagerModel(QObject): @pyqtProperty(str, notify = globalContainerChanged) def activeDefinitionId(self): - if self._global_container_stack: + if self._active_container_stack: definition = self._global_container_stack.getBottom() if definition: return definition.id @@ -449,15 +465,15 @@ class MachineManagerModel(QObject): @pyqtProperty(bool, notify = globalContainerChanged) def hasMaterials(self): - if self._global_container_stack: - return bool(self._global_container_stack.getMetaDataEntry("has_materials", False)) + if self._active_container_stack: + return bool(self._active_container_stack.getMetaDataEntry("has_materials", False)) return False @pyqtProperty(bool, notify = globalContainerChanged) def hasVariants(self): - if self._global_container_stack: - return bool(self._global_container_stack.getMetaDataEntry("has_variants", False)) + if self._active_container_stack: + return bool(self._active_container_stack.getMetaDataEntry("has_variants", False)) return False From 57dfc2ae7959943a66ea06a46ff72716eb4569f5 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 10 Jun 2016 16:37:43 +0200 Subject: [PATCH 2/6] Change active containerstack when the global containerstack is changed CURA-1585 --- cura/MachineManagerModel.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index f5661320ec..0104b343f4 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -26,6 +26,7 @@ class MachineManagerModel(QObject): self._onGlobalContainerChanged() ExtruderManager.ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderStackChanged) + self.globalContainerChanged.connect(self._onActiveExtruderStackChanged) self._onActiveExtruderStackChanged() ## When the global container is changed, active material probably needs to be updated. From e150b1887eb9d8337a130fa40de6b2e063a508ec Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 10 Jun 2016 16:50:11 +0200 Subject: [PATCH 3/6] Update active variant, material and quality id when switching extruders CURA-1585 --- cura/MachineManagerModel.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 0104b343f4..321f5af486 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -33,6 +33,9 @@ class MachineManagerModel(QObject): self.globalContainerChanged.connect(self.activeMaterialChanged) self.globalContainerChanged.connect(self.activeVariantChanged) self.globalContainerChanged.connect(self.activeQualityChanged) + ExtruderManager.ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeMaterialChanged) + ExtruderManager.ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeVariantChanged) + ExtruderManager.ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeQualityChanged) self.globalContainerChanged.connect(self.activeStackChanged) self.globalValueChanged.connect(self.activeStackChanged) @@ -221,7 +224,7 @@ class MachineManagerModel(QObject): def isGlobalStackValid(self): return self._global_stack_valid - @pyqtProperty(str, notify = globalContainerChanged) + @pyqtProperty(str, notify = activeStackChanged) def activeUserProfileId(self): if self._active_container_stack: return self._active_container_stack.getTop().getId() From 9626cddf3490e11d3cb4bd62bd44837bd7a9f52c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 10 Jun 2016 16:53:59 +0200 Subject: [PATCH 4/6] Extruder trains are now correctly saved --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 3ff0b4a008..393f1e5634 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -283,7 +283,7 @@ class CuraApplication(QtApplication): path = None if not stack_type or stack_type == "machine": path = Resources.getStoragePath(self.ResourceTypes.MachineStack, file_name) - elif stack_type == "extruder": + elif stack_type == "extruder_train": path = Resources.getStoragePath(self.ResourceTypes.ExtruderStack, file_name) if path: with SaveFile(path, "wt", -1, "utf-8") as f: From 8c43d4c4cb03e2733dcd24e558a6a043ff7231a6 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 10 Jun 2016 17:04:25 +0200 Subject: [PATCH 5/6] Quality is now set for extruder, regardless if the machine has machine specific qualities --- cura/ExtruderManager.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 72b6086e26..123388296b 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -18,7 +18,7 @@ class ExtruderManager(QObject): ## Notify when the user switches the currently active extruder. activeExtruderChanged = pyqtSignal() - ## Registers listeners and such to listen to changes to the extruders. + ## Registers listeners and such to listen to chafnges to the extruders. def __init__(self, parent = None): super().__init__(parent) self._extruder_trains = { } #Per machine, a dictionary of extruder container stack IDs. @@ -169,19 +169,19 @@ class ExtruderManager(QObject): #Find a quality to use for this extruder. quality = container_registry.getEmptyInstanceContainer() - if machine_definition.getMetaDataEntry("has_machine_quality"): - #First add any quality. Later, overwrite with preference if the preference is valid. - qualities = container_registry.findInstanceContainers(type = "quality") - if len(qualities) >= 1: - quality = qualities[0] - preferred_quality_id = machine_definition.getMetaDataEntry("preferred_quality") - if preferred_quality_id: - preferred_quality = container_registry.findInstanceContainers(id = preferred_quality_id.lower(), type = "quality") - if len(preferred_quality) >= 1: - quality = preferred_quality[0] - else: - UM.Logger.log("w", "The preferred quality \"%s\" of machine %s doesn't exist or is not a quality profile.", preferred_quality_id, machine_id) - #And leave it at the default quality. + + #First add any quality. Later, overwrite with preference if the preference is valid. + qualities = container_registry.findInstanceContainers(type = "quality") + if len(qualities) >= 1: + quality = qualities[0] + preferred_quality_id = machine_definition.getMetaDataEntry("preferred_quality") + if preferred_quality_id: + preferred_quality = container_registry.findInstanceContainers(id = preferred_quality_id.lower(), type = "quality") + if len(preferred_quality) >= 1: + quality = preferred_quality[0] + else: + UM.Logger.log("w", "The preferred quality \"%s\" of machine %s doesn't exist or is not a quality profile.", preferred_quality_id, machine_id) + #And leave it at the default quality. container_stack.addContainer(quality) user_profile = container_registry.findInstanceContainers(id = extruder_stack_id + "_current_settings") From cc17c2897806b4333191ab4c9d6b7ccf149f66ca Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 10 Jun 2016 17:26:09 +0200 Subject: [PATCH 6/6] Fixed global stack not being set as next stack for extruder trains --- cura/ExtruderManager.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 123388296b..84c3028c72 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -99,6 +99,10 @@ class ExtruderManager(QObject): extruder_trains = container_registry.findContainerStacks(type = "extruder_train", machine = machine_definition.getId()) for extruder_train in extruder_trains: self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train + + ## Ensure that the extruder train stacks are linked to global stack. + extruder_train.setNextStack(UM.Application.getInstance().getGlobalContainerStack()) + if extruder_trains: self.extrudersChanged.emit(machine_definition)