From 50a7e8146fb984297d349dd3a0f9fe7c30e3af7d Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 24 Aug 2017 17:09:28 +0200 Subject: [PATCH] Add a dedicated stack class for per-object settings CURA-4186 Add a dedicated stack class PerObjectContainerStack for per-object settings to evaluate limit_to_extruder values correctly. --- cura/Settings/PerObjectContainerStack.py | 49 +++++++++++++++++++++++ cura/Settings/SettingOverrideDecorator.py | 4 +- 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 cura/Settings/PerObjectContainerStack.py diff --git a/cura/Settings/PerObjectContainerStack.py b/cura/Settings/PerObjectContainerStack.py new file mode 100644 index 0000000000..58b7e297e6 --- /dev/null +++ b/cura/Settings/PerObjectContainerStack.py @@ -0,0 +1,49 @@ +from typing import Any, Optional + +from UM.Decorators import override +from UM.Logger import Logger +from UM.Settings.Interfaces import PropertyEvaluationContext +from UM.Settings.ContainerStack import ContainerStack + + +class PerObjectContainerStack(ContainerStack): + + @override(ContainerStack) + def getProperty(self, key: str, property_name: str, context: Optional[PropertyEvaluationContext] = None) -> Any: + if context is None: + context = PropertyEvaluationContext() + context.pushContainer(self) + + # this import has to be here otherwise there will be a circular import loop + from cura.CuraApplication import CuraApplication + global_stack = CuraApplication.getInstance().getGlobalContainerStack() + + # Handle the "limit_to_extruder" property. + limit_to_extruder = super().getProperty(key, "limit_to_extruder", context) + if limit_to_extruder is not None: + limit_to_extruder = str(limit_to_extruder) + + # if this stack has the limit_to_extruder "not overriden", use the original limit_to_extruder as the current + # limit_to_extruder, so the values retrieved will be from the perspective of the original limit_to_extruder + # stack. + if limit_to_extruder == "-1": + if 'original_limit_to_extruder' in context.context: + limit_to_extruder = context.context['original_limit_to_extruder'] + + if limit_to_extruder is not None and limit_to_extruder != "-1" and limit_to_extruder in global_stack.extruders: + # set the original limit_to_extruder if this is the first stack that has a non-overriden limit_to_extruder + if 'original_limit_to_extruder' not in context.context: + context.context['original_limit_to_extruder'] = limit_to_extruder + + if super().getProperty(key, "settable_per_extruder", context): + result = global_stack.extruders[str(limit_to_extruder)].getProperty(key, property_name, context) + if result is not None: + context.popContainer() + return result + else: + Logger.log("e", "Setting {setting} has limit_to_extruder but is not settable per extruder!", setting = key) + + result = super().getProperty(key, property_name, context) + context.popContainer() + return result + diff --git a/cura/Settings/SettingOverrideDecorator.py b/cura/Settings/SettingOverrideDecorator.py index 503e0b2490..2a69353885 100644 --- a/cura/Settings/SettingOverrideDecorator.py +++ b/cura/Settings/SettingOverrideDecorator.py @@ -5,13 +5,13 @@ import copy from UM.Scene.SceneNodeDecorator import SceneNodeDecorator from UM.Signal import Signal, signalemitter -from UM.Settings.ContainerStack import ContainerStack from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Logger import Logger from UM.Application import Application +from cura.Settings.PerObjectContainerStack import PerObjectContainerStack from cura.Settings.ExtruderManager import ExtruderManager ## A decorator that adds a container stack to a Node. This stack should be queried for all settings regarding @@ -24,7 +24,7 @@ class SettingOverrideDecorator(SceneNodeDecorator): def __init__(self): super().__init__() - self._stack = ContainerStack(stack_id = id(self)) + self._stack = PerObjectContainerStack(stack_id = id(self)) self._stack.setDirty(False) # This stack does not need to be saved. self._stack.addContainer(InstanceContainer(container_id = "SettingOverrideInstanceContainer"))