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 0afd1e5cd1..81d0b087ee 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. @@ -769,8 +784,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. @@ -793,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() @@ -814,9 +837,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}) 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() 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; 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