From e82b2c0f80c0621b7c1c8afbccc293689ae76ccc Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 13 Oct 2016 20:54:26 +0200 Subject: [PATCH 1/7] Add support for global quality profiles Instead of using one of the extruder profiles as global quality, use proper global qualities. Contributes to CURA-2646 --- cura/QualityManager.py | 7 ++++--- cura/Settings/MachineManager.py | 9 +++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/cura/QualityManager.py b/cura/QualityManager.py index 09e9d283ed..7354bfbb4f 100644 --- a/cura/QualityManager.py +++ b/cura/QualityManager.py @@ -82,8 +82,9 @@ class QualityManager: # \param material_containers (Optional) \type{List[ContainerInstance]} If nothing is specified then # the current set of selected materials is used. # \return the matching quality container \type{ContainerInstance} - def findQualityByQualityType(self, quality_type, machine_definition=None, material_containers=None): - criteria = {"type": "quality"} + def findQualityByQualityType(self, quality_type, machine_definition=None, material_containers=None, **kwargs): + criteria = kwargs + criteria["type"] = "quality" if quality_type: criteria["quality_type"] = quality_type result = self._getFilteredContainersForStack(machine_definition, material_containers, **criteria) @@ -218,7 +219,7 @@ class QualityManager: result = [] for container in containers: # If the machine specifies we should filter by material, exclude containers that do not match any active material. - if filter_by_material and container.getMetaDataEntry("material") not in material_ids: + if filter_by_material and container.getMetaDataEntry("material") not in material_ids and not "global_quality" in kwargs: continue result.append(container) return result diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 326a011562..359aea4268 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -769,8 +769,13 @@ class MachineManager(QObject): if extruder_stacks: # Add an extra entry for the global stack. - result.append({"stack": global_container_stack, "quality": result[0]["quality"], - "quality_changes": empty_quality_changes}) + global_quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [], global_quality = "True") + + if not global_quality: + global_quality = self._empty_quality_container + + result.append({"stack": global_container_stack, "quality": global_quality, "quality_changes": empty_quality_changes}) + return result ## Determine the quality and quality changes settings for the current machine for a quality changes name. From e1dafc82887c50ed046e3f1fefc1ad48564ce36f Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 18 Oct 2016 13:23:07 +0200 Subject: [PATCH 2/7] Also properly set global profile when changing quality_changes profiles Contributes to CURA-2652 --- cura/Settings/MachineManager.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 359aea4268..d33bf636d3 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -819,9 +819,10 @@ class MachineManager(QObject): result.append({"stack": stack, "quality": quality, "quality_changes": quality_changes}) if extruder_stacks: - # Duplicate the quality from the 1st extruder into the global stack. If anyone - # then looks in the global stack, they should get a reasonable view. - result.append({"stack": global_container_stack, "quality": result[0]["quality"], "quality_changes": global_quality_changes}) + global_quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material], global_quality = "True") + if not global_quality: + global_quality = self._empty_quality_container + result.append({"stack": global_container_stack, "quality": global_quality, "quality_changes": global_quality_changes}) else: result.append({"stack": global_container_stack, "quality": global_quality, "quality_changes": global_quality_changes}) From 78ac4ef999b9bf4d9f011a9f7efa8a13dc1d8309 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 18 Oct 2016 13:26:55 +0200 Subject: [PATCH 3/7] Set the global variant and material to empty for multi-extrusion machines For multi-extrusion machines, we do not want variant or material profiles in the stack, because these are extruder specific and may cause wrong values to be used for extruders that did not specify a value in the extruder. Contributes to CURA-2652 --- cura/Settings/MachineManager.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index d33bf636d3..ab3701c1eb 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -225,11 +225,26 @@ class MachineManager(QObject): self._global_container_stack.nameChanged.connect(self._onMachineNameChanged) self._global_container_stack.containersChanged.connect(self._onInstanceContainersChanged) self._global_container_stack.propertyChanged.connect(self._onPropertyChanged) - material = self._global_container_stack.findContainer({"type": "material"}) - material.nameChanged.connect(self._onMaterialNameChanged) - quality = self._global_container_stack.findContainer({"type": "quality"}) - quality.nameChanged.connect(self._onQualityNameChanged) + if self._global_container_stack.getProperty("machine_extruder_count", "value") > 1: + # For multi-extrusion machines, we do not want variant or material profiles in the stack, + # because these are extruder specific and may cause wrong values to be used for extruders + # that did not specify a value in the extruder. + global_variant = self._global_container_stack.findContainer(type = "variant") + if global_variant != self._empty_variant_container: + self._global_container_stack.replaceContainer(self._global_container_stack.getContainerIndex(global_variant), self._empty_variant_container) + + global_material = self._global_container_stack.findContainer(type = "material") + if global_material != self._empty_material_container: + self._global_container_stack.replaceContainer(self._global_container_stack.getContainerIndex(global_material), self._empty_material_container) + + else: + material = self._global_container_stack.findContainer({"type": "material"}) + material.nameChanged.connect(self._onMaterialNameChanged) + + quality = self._global_container_stack.findContainer({"type": "quality"}) + quality.nameChanged.connect(self._onQualityNameChanged) + def _onActiveExtruderStackChanged(self): self.blurSettings.emit() # Ensure no-one has focus. From 2c2bf7823f773c0dcea7342d8598b71989228866 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 18 Oct 2016 15:21:11 +0200 Subject: [PATCH 4/7] Account for empty material when switching quality changes Contributes to CURA-2652 --- cura/Settings/MachineManager.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index ab3701c1eb..8ba711a5c0 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -813,7 +813,10 @@ class MachineManager(QObject): # For the global stack, find a quality which matches the quality_type in # the quality changes profile and also satisfies any material constraints. quality_type = global_quality_changes.getMetaDataEntry("quality_type") - global_quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material]) + if global_container_stack.getProperty("machine_extruder_count", "value") > 1: + global_quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [], global_quality = True) + else: + global_quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material]) # Find the values for each extruder. extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks() From 588f49fa5f31802bd643916e1a918235e6cfa9a3 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 24 Oct 2016 11:19:49 +0200 Subject: [PATCH 5/7] Add global profiles for UM3 so this can be tested without dependencies Contributes to CURA-2652 --- .../ultimaker3/um3_global_Draft_Quality.inst.cfg | 13 +++++++++++++ .../ultimaker3/um3_global_Fast_Quality.inst.cfg | 13 +++++++++++++ .../ultimaker3/um3_global_High_Quality.inst.cfg | 13 +++++++++++++ .../ultimaker3/um3_global_Normal_Quality.inst.cfg | 13 +++++++++++++ 4 files changed, 52 insertions(+) create mode 100644 resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg create mode 100644 resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg create mode 100644 resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg create mode 100644 resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg diff --git a/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg new file mode 100644 index 0000000000..96e25c6ad8 --- /dev/null +++ b/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg @@ -0,0 +1,13 @@ +[general] +version = 2 +name = Draft Quality +definition = ultimaker3 + +[metadata] +type = quality +quality_type = draft +global_quality = True +weight = -2 + +[values] +layer_height = 0.2 diff --git a/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg new file mode 100644 index 0000000000..6b1c3c4208 --- /dev/null +++ b/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg @@ -0,0 +1,13 @@ +[general] +version = 2 +name = Fast Quality +definition = ultimaker3 + +[metadata] +type = quality +quality_type = fast +global_quality = True +weight = -1 + +[values] +layer_height = 0.15 diff --git a/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg new file mode 100644 index 0000000000..af0741ff88 --- /dev/null +++ b/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg @@ -0,0 +1,13 @@ +[general] +version = 2 +name = High Quality +definition = ultimaker3 + +[metadata] +type = quality +quality_type = high +global_quality = True +weight = 0 + +[values] +layer_height = 0.06 diff --git a/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg new file mode 100644 index 0000000000..a875b0f1ce --- /dev/null +++ b/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg @@ -0,0 +1,13 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker3 + +[metadata] +type = quality +quality_type = normal +global_quality = True +weight = 0 + +[values] +layer_height = 0.1 From bdaa4a5a6dde66f152d2012625ca42fb881a7058 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 24 Oct 2016 17:04:30 +0200 Subject: [PATCH 6/7] Add a method to get overrides for a specified (extruder)stack Since the main getOverrides method only accounts for the active extruder and we sometimes need to check other extruders in case of limit_to_extruder. Contributes to CURA-2752 --- cura/Settings/SettingInheritanceManager.py | 29 +++++++++++++++++----- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/cura/Settings/SettingInheritanceManager.py b/cura/Settings/SettingInheritanceManager.py index b110febd87..68891c7f4f 100644 --- a/cura/Settings/SettingInheritanceManager.py +++ b/cura/Settings/SettingInheritanceManager.py @@ -38,6 +38,22 @@ class SettingInheritanceManager(QObject): result.append(key) return result + @pyqtSlot(str, str, result = "QStringList") + def getOverridesForExtruder(self, key, extruder): + extruder = cura.Settings.ExtruderManager.getInstance().getExtruderStack(extruder) + if not extruder: + return [] + + definitions = self._global_container_stack.getBottom().findDefinitions(key=key) + if not definitions: + return + result = [] + for key in definitions[0].getAllKeys(): + if self._settingIsOverwritingInheritance(key, extruder): + result.append(key) + + return result + @pyqtSlot(str) def manualRemoveOverride(self, key): if key in self._settings_with_inheritance_warning: @@ -115,22 +131,23 @@ class SettingInheritanceManager(QObject): return self._settings_with_inheritance_warning ## Check if a setting has an inheritance function that is overwritten - def _settingIsOverwritingInheritance(self, key): + def _settingIsOverwritingInheritance(self, key, stack = None): has_setting_function = False - stack = self._active_container_stack + if not stack: + stack = self._active_container_stack containers = [] ## Check if the setting has a user state. If not, it is never overwritten. - has_user_state = self._active_container_stack.getProperty(key, "state") == UM.Settings.InstanceState.User + has_user_state = stack.getProperty(key, "state") == UM.Settings.InstanceState.User if not has_user_state: return False ## If a setting is not enabled, don't label it as overwritten (It's never visible anyway). - if not self._active_container_stack.getProperty(key, "enabled"): + if not stack.getProperty(key, "enabled"): return False ## Also check if the top container is not a setting function (this happens if the inheritance is restored). - if isinstance(self._active_container_stack.getTop().getProperty(key, "value"), UM.Settings.SettingFunction): + if isinstance(stack.getTop().getProperty(key, "value"), UM.Settings.SettingFunction): return False ## Mash all containers for all the stacks together. @@ -186,4 +203,4 @@ class SettingInheritanceManager(QObject): @staticmethod def createSettingInheritanceManager(engine=None, script_engine=None): - return SettingInheritanceManager() \ No newline at end of file + return SettingInheritanceManager() From 8ce81fec9f0e11c2416eeff6b5da3a587380deb0 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 24 Oct 2016 17:06:48 +0200 Subject: [PATCH 7/7] Expand logic for showing the inherit button in SettingItem Hide it if the revert button is visible and make the overrides check limit_to_extruder in addition to the active stack. Contributes to CURA-2752 --- resources/qml/Settings/SettingItem.qml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index f399e7fe04..f7040976d5 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -194,10 +194,27 @@ Item { // Inherit button needs to be visible if; // - User made changes that override any loaded settings // - This setting item uses inherit button at all + // - The revert button is not visible. // - The type of the value of any deeper container is an "object" (eg; is a function) visible: { - return showInheritButton && Cura.SettingInheritanceManager.settingsWithInheritanceWarning.indexOf(definition.key) >= 0; + if(!base.showInheritButton) + { + return false; + } + + if(revertButton.visible) + { + // The revert button already indicates there is a custom value for this setting, making this button superfluous. + return false; + } + + if(globalPropertyProvider.properties.limit_to_extruder == null || globalPropertyProvider.properties.limit_to_extruder == -1) + { + return Cura.SettingInheritanceManager.settingsWithInheritanceWarning.indexOf(definition.key) >= 0; + } + + return Cura.SettingInheritanceManager.getOverridesForExtruder(definition.key, globalPropertyProvider.properties.limit_to_extruder).indexOf(definition.key) >= 0; } height: parent.height;