diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 43c11c26f0..0edef9857c 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -103,6 +103,7 @@ class CuraApplication(QtApplication): SettingFunction.registerOperator("extruderValues", cura.Settings.ExtruderManager.getExtruderValues) SettingFunction.registerOperator("extruderValue", cura.Settings.ExtruderManager.getExtruderValue) + SettingFunction.registerOperator("resolveOrValue", cura.Settings.ExtruderManager.getResolveOrValue) ## Add the 4 types of profiles to storage. Resources.addStorageType(self.ResourceTypes.QualityInstanceContainer, "quality") diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index cb5dcd070b..776cb8ed21 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -433,9 +433,16 @@ class ContainerManager(QObject): def clearUserContainers(self): self._machine_manager.blurSettings.emit() + send_emits_containers = [] + # Go through global and extruder stacks and clear their topmost container (the user settings). for stack in cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): - stack.getTop().clear() + container = stack.getTop() + container.clear() + send_emits_containers.append(container) + + for container in send_emits_containers: + container.sendPostponedEmits() ## Create quality changes containers from the user containers in the active stacks. # diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 3c5ec74f0e..87c2eecd19 100644 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -347,7 +347,7 @@ class ExtruderManager(QObject): for extruder in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()): value = extruder.getRawProperty(key, "value") - if not value: + if value is None: continue if isinstance(value, UM.Settings.SettingFunction): @@ -392,3 +392,29 @@ class ExtruderManager(QObject): value = UM.Application.getInstance().getGlobalContainerStack().getProperty(key, "value") return value + + ## Get the resolve value or value for a given key + # + # This is the effective value for a given key, it is used for values in the global stack. + # This is exposed to SettingFunction to use in value functions. + # \param key The key of the setting to get the value of. + # + # \return The effective value + @staticmethod + def getResolveOrValue(key): + global_stack = UM.Application.getInstance().getGlobalContainerStack() + + resolved_value = global_stack.getProperty(key, "resolve") + if resolved_value is not None: + user_container = global_stack.findContainer({"type": "user"}) + quality_changes_container = global_stack.findContainer({"type": "quality_changes"}) + if user_container.hasProperty(key, "value") or quality_changes_container.hasProperty(key, "value"): + # Normal case + value = global_stack.getProperty(key, "value") + else: + # We have a resolved value and we're using it because of no user and quality_changes value + value = resolved_value + else: + value = global_stack.getRawProperty(key, "value") + + return value diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 202b597ad7..c8a940b83b 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -358,7 +358,8 @@ class MachineManager(QObject): if self._global_container_stack.getTop().findInstances(): return True - for stack in ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()): + stacks = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())) + for stack in stacks: if stack.getTop().findInstances(): return True @@ -371,10 +372,19 @@ class MachineManager(QObject): if not self._global_container_stack: return - self._global_container_stack.getTop().removeInstance(key) + send_emits_containers = [] + + top_container = self._global_container_stack.getTop() + top_container.removeInstance(key, postpone_emit=True) + send_emits_containers.append(top_container) for stack in ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()): - stack.getTop().removeInstance(key) + container = stack.getTop() + container.removeInstance(key, postpone_emit=True) + send_emits_containers.append(container) + + for container in send_emits_containers: + container.sendPostponedEmits() ## Check if the global profile does not contain error states # Note that the _active_stack_valid is cached due to performance issues diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 61625159e1..ad9211fae3 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -691,7 +691,7 @@ "description": "Width of a single prime tower line.", "type": "float", "unit": "mm", - "enabled": "prime_tower_enable", + "enabled": "resolveOrValue('prime_tower_enable')", "default_value": 0.4, "value": "line_width", "minimum_value": "0.0001", @@ -1540,7 +1540,7 @@ "description": "The speed at which the prime tower is printed. Printing the prime tower slower can make it more stable when the adhesion between the different filaments is suboptimal.", "type": "float", "unit": "mm/s", - "enabled": "prime_tower_enable", + "enabled": "resolveOrValue('prime_tower_enable')", "default_value": 60, "value": "speed_print", "minimum_value": "0.1", @@ -1814,7 +1814,7 @@ "maximum_value_warning": "10000", "default_value": 3000, "value": "acceleration_print", - "enabled": "prime_tower_enable and acceleration_enabled", + "enabled": "resolveOrValue('prime_tower_enable') and acceleration_enabled", "settable_per_mesh": false } } @@ -2035,7 +2035,7 @@ "maximum_value_warning": "50", "default_value": 20, "value": "jerk_print", - "enabled": "prime_tower_enable and jerk_enabled", + "enabled": "resolveOrValue('prime_tower_enable') and jerk_enabled", "settable_per_mesh": false } } @@ -3345,9 +3345,9 @@ "description": "The width of the prime tower.", "type": "float", "unit": "mm", - "enabled": "prime_tower_enable", + "enabled": "resolveOrValue('prime_tower_enable')", "default_value": 15, - "value": "15 if prime_tower_enable else 0", + "value": "15 if resolveOrValue('prime_tower_enable') else 0", "minimum_value": "0", "maximum_value": "min(0.5 * machine_width, 0.5 * machine_depth)", "maximum_value_warning": "20", @@ -3360,7 +3360,7 @@ "description": "The x coordinate of the position of the prime tower.", "type": "float", "unit": "mm", - "enabled": "prime_tower_enable", + "enabled": "resolveOrValue('prime_tower_enable')", "default_value": 200, "minimum_value_warning": "-1000", "maximum_value_warning": "1000", @@ -3375,7 +3375,7 @@ "description": "The y coordinate of the position of the prime tower.", "type": "float", "unit": "mm", - "enabled": "prime_tower_enable", + "enabled": "resolveOrValue('prime_tower_enable')", "default_value": 200, "minimum_value_warning": "-1000", "maximum_value_warning": "1000", @@ -3390,7 +3390,7 @@ "description": "Flow compensation: the amount of material extruded is multiplied by this value.", "type": "float", "unit": "%", - "enabled": "prime_tower_enable", + "enabled": "resolveOrValue('prime_tower_enable')", "default_value": 100, "minimum_value": "0.0001", "minimum_value_warning": "50", @@ -3403,7 +3403,7 @@ "label": "Wipe Nozzle on Prime Tower", "description": "After printing the prime tower with one nozzle, wipe the oozed material from the other nozzle off on the prime tower.", "type": "bool", - "enabled": "prime_tower_enable", + "enabled": "resolveOrValue('prime_tower_enable')", "default_value": false, "settable_per_mesh": false, "settable_per_extruder": false