From f2e054b449e343f3d99bb0e38f5649eae8500ccf Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 11 Oct 2016 11:01:14 +0200 Subject: [PATCH 1/7] Fix the active quality id activeQualityId and activeQualityName were not referencing the same profile. activeMaterialName seems to have the correct one. CURA-2271 --- cura/Settings/MachineManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 46c1ec09b7..7508fc6952 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -475,11 +475,11 @@ class MachineManager(QObject): @pyqtProperty(str, notify=activeQualityChanged) def activeQualityId(self): - if self._global_container_stack: + if self._active_container_stack and self._global_container_stack: quality = self._global_container_stack.findContainer({"type": "quality_changes"}) if quality and quality != self._empty_quality_changes_container: return quality.getId() - quality = self._global_container_stack.findContainer({"type": "quality"}) + quality = self._active_container_stack.findContainer({"type": "quality"}) if quality: return quality.getId() return "" From e31253084057fd56c699fa7e3413ef39a5eff1b1 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 11 Oct 2016 12:34:29 +0200 Subject: [PATCH 2/7] Fix errors on profiles page for unsupported material combinations CURA-2271 --- cura/Settings/QualitySettingsModel.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cura/Settings/QualitySettingsModel.py b/cura/Settings/QualitySettingsModel.py index 638a53e4b8..eb59c7597f 100644 --- a/cura/Settings/QualitySettingsModel.py +++ b/cura/Settings/QualitySettingsModel.py @@ -120,7 +120,11 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): quality_container = quality_container[0] quality_type = quality_container.getMetaDataEntry("quality_type") - definition_id = quality_container.getDefinition().getId() + definition = quality_container.getDefinition() + if definition: + definition_id = definition.getId() + else: + definition_id = "empty_quality" criteria = {"type": "quality", "quality_type": quality_type, "definition": definition_id} @@ -136,9 +140,9 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): new_criteria.pop("extruder") containers = self._container_registry.findInstanceContainers(**new_criteria) - if not containers: + if not containers and "material" in criteria: # Try again, this time without material - criteria.pop("material") + criteria.pop("material", None) containers = self._container_registry.findInstanceContainers(**criteria) if not containers: @@ -147,7 +151,7 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): containers = self._container_registry.findInstanceContainers(**criteria) if not containers: - UM.Logger.log("Could not find any quality containers matching the search criteria %s" % str(criteria)) + UM.Logger.log("w", "Could not find any quality containers matching the search criteria %s" % str(criteria)) return if quality_changes_container: From 95fabbaf6d9522cf05804a143cbbb67a87171535 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 11 Oct 2016 15:20:13 +0200 Subject: [PATCH 3/7] Don't allow creating profiles based on empty_profile ...because empty_profile has no quality_type CURA-2271 --- resources/qml/Actions.qml | 2 +- resources/qml/Preferences/ProfilesPage.qml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index 3ee8630183..300a9056d4 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -137,7 +137,7 @@ Item Action { id: addProfileAction; - enabled: Cura.MachineManager.isActiveStackValid && Cura.MachineManager.hasUserSettings + enabled: Cura.MachineManager.isActiveStackValid && Cura.MachineManager.hasUserSettings && Cura.MachineManager.activeQualityId != "empty_quality" text: catalog.i18nc("@action:inmenu menubar:profile","&Create profile from current settings..."); } diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 42c055486a..238b5f022b 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -62,7 +62,7 @@ UM.ManagementPage Button { text: catalog.i18nc("@label", "Create") - enabled: base.canCreateProfile() + enabled: base.canCreateProfile() && Cura.MachineManager.activeQualityId != "empty_quality" visible: base.canCreateProfile() iconName: "list-add"; @@ -78,7 +78,7 @@ UM.ManagementPage Button { text: catalog.i18nc("@label", "Duplicate") - enabled: ! base.canCreateProfile() + enabled: ! base.canCreateProfile() && Cura.MachineManager.activeQualityId != "empty_quality" visible: ! base.canCreateProfile() iconName: "list-add"; From 34630fa646f13f683b4778fbbe1a2be688e1fadf Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 11 Oct 2016 16:36:32 +0200 Subject: [PATCH 4/7] Also show the "unsupported" warning when a custom profile is selected ...by making sure we're looking at the quality container (not quality_changes) of the active extruder/stack CURA-2271 --- cura/Settings/MachineManager.py | 15 +++++++++++++++ resources/qml/SidebarHeader.qml | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 7508fc6952..6c038a2ee7 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -492,6 +492,21 @@ class MachineManager(QObject): return quality.getMetaDataEntry("quality_type") return "" + ## Get the Quality ID associated with the currently active extruder + # Note that this only returns the "quality", not the "quality_changes" + # \returns QualityID (string) if found, empty string otherwise + # \sa activeQualityId() + # \todo Ideally, this method would be named activeQualityId(), and the other one + # would be named something like activeQualityOrQualityChanges() for consistency + @pyqtProperty(str, notify = activeQualityChanged) + def activeQualityContainerId(self): + # We're using the active stack instead of the global stack in case the list of qualities differs per extruder + if self._active_container_stack: + quality = self._active_container_stack.findContainer(type = "quality") + if quality: + return quality.getId() + return "" + @pyqtProperty(str, notify = activeQualityChanged) def activeQualityChangesId(self): if self._global_container_stack: diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 3e36cfbaa0..e8f4aa8e47 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -244,7 +244,7 @@ Column } } - property var valueWarning: Cura.MachineManager.activeQualityId == "empty_quality" + property var valueWarning: Cura.MachineManager.activeQualityContainerId == "empty_quality" enabled: !extrudersList.visible || base.currentExtruderIndex > -1 From ef3e8dc4fa186e308c71ec2edb37e5ae1cb593ee Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Wed, 12 Oct 2016 11:31:18 +0200 Subject: [PATCH 5/7] Make sure that the activeQualityChanged signal is emitted when the _active_container_stack changes. CURA-2271 --- cura/Settings/MachineManager.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 6c038a2ee7..2ec0d69bdd 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -223,6 +223,9 @@ class MachineManager(QObject): def _onActiveExtruderStackChanged(self): self.blurSettings.emit() # Ensure no-one has focus. + + old_active_container_stack = self._active_container_stack + if self._active_container_stack and self._active_container_stack != self._global_container_stack: self._active_container_stack.containersChanged.disconnect(self._onInstanceContainersChanged) self._active_container_stack.propertyChanged.disconnect(self._onPropertyChanged) @@ -232,8 +235,16 @@ class MachineManager(QObject): self._active_container_stack.propertyChanged.connect(self._onPropertyChanged) else: self._active_container_stack = self._global_container_stack + + old_active_stack_valid = self._active_stack_valid self._active_stack_valid = not self._checkStackForErrors(self._active_container_stack) - self.activeStackValidationChanged.emit() + if old_active_stack_valid != self._active_stack_valid: + self.activeStackValidationChanged.emit() + + if old_active_container_stack != self._active_container_stack: + # Many methods and properties related to the active quality actually depend + # on _active_container_stack. If it changes, then the properties change. + self.activeQualityChanged.emit() def _onInstanceContainersChanged(self, container): container_type = container.getMetaDataEntry("type") From f60146ad26102cf98c60b34f9bd65a684c3c1c28 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 12 Oct 2016 11:59:54 +0200 Subject: [PATCH 6/7] Active quality ID is selected from active stack instead of global CURA-2624 --- cura/Settings/MachineManager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 46c1ec09b7..fb30ff42a8 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -475,11 +475,11 @@ class MachineManager(QObject): @pyqtProperty(str, notify=activeQualityChanged) def activeQualityId(self): - if self._global_container_stack: - quality = self._global_container_stack.findContainer({"type": "quality_changes"}) + if self._active_container_stack: + quality = self._active_container_stack.findContainer({"type": "quality_changes"}) if quality and quality != self._empty_quality_changes_container: return quality.getId() - quality = self._global_container_stack.findContainer({"type": "quality"}) + quality = self._active_container_stack.findContainer({"type": "quality"}) if quality: return quality.getId() return "" From 3f6877d2ec8f2df42ccac8f6488a5cb2a385e53b Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 12 Oct 2016 13:58:09 +0200 Subject: [PATCH 7/7] Keep per object extruder when switching machines. CURA-2533 --- cura/Settings/SettingOverrideDecorator.py | 9 +++++++++ .../PerObjectSettingsTool/PerObjectSettingsTool.py | 13 +++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/cura/Settings/SettingOverrideDecorator.py b/cura/Settings/SettingOverrideDecorator.py index 8c10542069..a8cfcd8d80 100644 --- a/cura/Settings/SettingOverrideDecorator.py +++ b/cura/Settings/SettingOverrideDecorator.py @@ -61,6 +61,15 @@ class SettingOverrideDecorator(SceneNodeDecorator): def getActiveExtruder(self): return self._extruder_stack + ## Gets the currently active extruders position + # + # \return An extruder's position, or None if no position info is available. + def getActiveExtruderPosition(self): + containers = ContainerRegistry.getInstance().findContainers(id = self.getActiveExtruder()) + if containers: + container_stack = containers[0] + return container_stack.getMetaDataEntry("position", default=None) + def _onSettingChanged(self, instance, property_name): # Reminder: 'property' is a built-in function if property_name == "value": # Only reslice if the value has changed. Application.getInstance().getBackend().forceSlice() diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py index a90bb4b6d0..5834a5c606 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py @@ -84,11 +84,20 @@ class PerObjectSettingsTool(Tool): default_stack = ExtruderManager.getInstance().getExtruderStack(0) if default_stack: default_stack_id = default_stack.getId() - else: default_stack_id = global_container_stack.getId() + else: + default_stack_id = global_container_stack.getId() root_node = Application.getInstance().getController().getScene().getRoot() for node in DepthFirstIterator(root_node): - node.callDecoration("setActiveExtruder", default_stack_id) + new_stack_id = default_stack_id + # Get position of old extruder stack for this node + old_extruder_pos = node.callDecoration("getActiveExtruderPosition") + if old_extruder_pos is not None: + # Fetch current (new) extruder stack at position + new_stack = ExtruderManager.getInstance().getExtruderStack(old_extruder_pos) + if new_stack: + new_stack_id = new_stack.getId() + node.callDecoration("setActiveExtruder", new_stack_id) self._updateEnabled()