Просмотр исходного кода

Move Cura custom setting functions to a separate file

Lipu Fei 6 лет назад
Родитель
Сommit
7a681a2ae4

+ 12 - 4
cura/CuraApplication.py

@@ -107,6 +107,7 @@ from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisi
 from cura.Settings.ContainerManager import ContainerManager
 from cura.Settings.SidebarCustomMenuItemsModel import SidebarCustomMenuItemsModel
 import cura.Settings.cura_empty_instance_containers
+from cura.Settings.CustomSettingFunctions import CustomSettingFunctions
 
 from cura.ObjectsModel import ObjectsModel
 
@@ -174,6 +175,8 @@ class CuraApplication(QtApplication):
 
         self._single_instance = None
 
+        self._custom_setting_functions = None
+
         self._cura_package_manager = None
 
         self._machine_action_manager = None
@@ -317,6 +320,8 @@ class CuraApplication(QtApplication):
     # Adds custom property types, settings types, and extra operators (functions) that need to be registered in
     # SettingDefinition and SettingFunction.
     def __initializeSettingDefinitionsAndFunctions(self):
+        self._custom_setting_functions = CustomSettingFunctions(self)
+
         # Need to do this before ContainerRegistry tries to load the machines
         SettingDefinition.addSupportedProperty("settable_per_mesh", DefinitionPropertyType.Any, default = True, read_only = True)
         SettingDefinition.addSupportedProperty("settable_per_extruder", DefinitionPropertyType.Any, default = True, read_only = True)
@@ -337,10 +342,10 @@ class CuraApplication(QtApplication):
         SettingDefinition.addSettingType("optional_extruder", None, str, None)
         SettingDefinition.addSettingType("[int]", None, str, None)
 
-        SettingFunction.registerOperator("extruderValues", ExtruderManager.getExtruderValues)
-        SettingFunction.registerOperator("extruderValue", ExtruderManager.getExtruderValue)
-        SettingFunction.registerOperator("resolveOrValue", ExtruderManager.getResolveOrValue)
-        SettingFunction.registerOperator("defaultExtruderPosition", ExtruderManager.getDefaultExtruderPosition)
+        SettingFunction.registerOperator("extruderValue", self._custom_setting_functions.getValueInExtruder)
+        SettingFunction.registerOperator("extruderValues", self._custom_setting_functions.getValuesInAllExtruders)
+        SettingFunction.registerOperator("resolveOrValue", self._custom_setting_functions.getResolveOrValue)
+        SettingFunction.registerOperator("defaultExtruderPosition", self._custom_setting_functions.getDefaultExtruderPosition)
 
     # Adds all resources and container related resources.
     def __addAllResourcesAndContainerResources(self) -> None:
@@ -804,6 +809,9 @@ class CuraApplication(QtApplication):
     def getSettingVisibilityPresetsModel(self, *args) -> SettingVisibilityPresetsModel:
         return self._setting_visibility_presets_model
 
+    def getCustomSettingFunctions(self, *args) -> CustomSettingFunctions:
+        return self._custom_setting_functions
+
     def getMachineErrorChecker(self, *args) -> MachineErrorChecker:
         return self._machine_error_checker
 

+ 134 - 0
cura/Settings/CustomSettingFunctions.py

@@ -0,0 +1,134 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import Any, List, Optional, TYPE_CHECKING
+
+from UM.Settings.PropertyEvaluationContext import PropertyEvaluationContext
+from UM.Settings.SettingFunction import SettingFunction
+
+if TYPE_CHECKING:
+    from cura.CuraApplication import CuraApplication
+    from cura.Settings.CuraContainerStack import CuraContainerStack
+
+
+#
+# This class contains all Cura-related custom setting functions. Some functions requires information such as the
+# currently active machine, so this is made into a class instead of standalone functions.
+#
+class CustomSettingFunctions:
+
+    def __init__(self, application: "CuraApplication") -> None:
+        self._application = application
+
+    # ================
+    # Custom Functions
+    # ================
+
+    # Gets the default extruder position of the currently active machine.
+    def getDefaultExtruderPosition(self) -> str:
+        machine_manager = self._application.getMachineManager()
+        return machine_manager.defaultExtruderPosition
+
+    # Gets the given setting key from the given extruder position.
+    def getValueInExtruder(self, extruder_position: int, property_key: str,
+                           context: Optional["PropertyEvaluationContext"] = None) -> Any:
+        machine_manager = self._application.getMachineManager()
+
+        if extruder_position == -1:
+            extruder_position = int(machine_manager.defaultExtruderPosition)
+
+        global_stack = machine_manager.activeMachine
+        extruder_stack = global_stack.extruders[str(extruder_position)]
+
+        if extruder_stack:
+            value = extruder_stack.getRawProperty(property_key, "value", context = context)
+            if isinstance(value, SettingFunction):
+                value = value(extruder_stack, context = context)
+        else:
+            # Just a value from global.
+            value = global_stack.getProperty(property_key, "value", context = context)
+
+        return value
+
+    # Gets all extruder values as a list for the given property.
+    def getValuesInAllExtruders(self, property_key: str,
+                                context: Optional["PropertyEvaluationContext"] = None) -> List[Any]:
+        machine_manager = self._application.getMachineManager()
+        extruder_manager = self._application.getExtruderManager()
+
+        global_stack = machine_manager.activeMachine
+
+        result = []
+        for extruder in extruder_manager.getActiveExtruderStacks():
+            if not extruder.isEnabled:
+                continue
+            # only include values from extruders that are "active" for the current machine instance
+            if int(extruder.getMetaDataEntry("position")) >= global_stack.getProperty("machine_extruder_count", "value", context = context):
+                continue
+
+            value = extruder.getRawProperty(property_key, "value", context = context)
+
+            if value is None:
+                continue
+
+            if isinstance(value, SettingFunction):
+                value = value(extruder, context= context)
+
+            result.append(value)
+
+        if not result:
+            result.append(global_stack.getProperty(property_key, "value", context = context))
+
+        return result
+
+    # Get the resolve value or value for a given key.
+    def getResolveOrValue(self, property_key: str, context: Optional["PropertyEvaluationContext"] = None) -> Any:
+        machine_manager = self._application.getMachineManager()
+
+        global_stack = machine_manager.activeMachine
+        resolved_value = global_stack.getProperty(property_key, "value", context = context)
+
+        return resolved_value
+
+    # Gets the default setting value from given extruder position. The default value is what excludes the values in
+    # the user_changes container.
+    def getDefaultValueInExtruder(self, extruder_position: int, property_key: str) -> Any:
+        machine_manager = self._application.getMachineManager()
+
+        global_stack = machine_manager.activeMachine
+        extruder_stack = global_stack.extruders[str(extruder_position)]
+
+        context = self.createContextForDefaultValueEvaluation(extruder_stack)
+
+        return self.getValueInExtruder(extruder_position, property_key, context = context)
+
+    # Gets all default setting values as a list from all extruders of the currently active machine.
+    # The default values are those excluding the values in the user_changes container.
+    def getDefaultValuesInAllExtruders(self, property_key: str) -> List[Any]:
+        machine_manager = self._application.getMachineManager()
+
+        global_stack = machine_manager.activeMachine
+
+        context = self.createContextForDefaultValueEvaluation(global_stack)
+
+        return self.getValuesInAllExtruders(property_key, context = context)
+
+    # Gets the resolve value or value for a given key without looking the first container (user container).
+    def getDefaultResolveOrValue(self, property_key: str) -> Any:
+        machine_manager = self._application.getMachineManager()
+
+        global_stack = machine_manager.activeMachine
+
+        context = self.createContextForDefaultValueEvaluation(global_stack)
+        return self.getResolveOrValue(property_key, context = context)
+
+    # Creates a context for evaluating default values (skip the user_changes container).
+    def createContextForDefaultValueEvaluation(self, source_stack: "CuraContainerStack") -> "PropertyEvaluationContext":
+        context = PropertyEvaluationContext(source_stack)
+        context.context["evaluate_from_container_index"] = 1  # skip the user settings container
+        context.context["override_operators"] = {
+            "extruderValue": self.getDefaultValueInExtruder,
+            "extruderValues": self.getDefaultValuesInAllExtruders,
+            "resolveOrValue": self.getDefaultResolveOrValue,
+        }
+        return context

+ 2 - 160
cura/Settings/ExtruderManager.py

@@ -12,9 +12,7 @@ from UM.Scene.SceneNode import SceneNode
 from UM.Scene.Selection import Selection
 from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator
 from UM.Settings.ContainerRegistry import ContainerRegistry  # Finding containers by ID.
-from UM.Settings.SettingFunction import SettingFunction
 from UM.Settings.ContainerStack import ContainerStack
-from UM.Settings.PropertyEvaluationContext import PropertyEvaluationContext
 
 from typing import Any, cast, Dict, List, Optional, TYPE_CHECKING, Union
 
@@ -376,86 +374,6 @@ class ExtruderManager(QObject):
             extruder_definition = container_registry.findDefinitionContainers(id = expected_extruder_definition_0_id)[0]
             extruder_stack_0.definition = extruder_definition
 
-    ##  Get all extruder values for a certain setting.
-    #
-    #   This is exposed to SettingFunction so it can be used in value functions.
-    #
-    #   \param key The key of the setting to retrieve values for.
-    #
-    #   \return A list of values for all extruders. If an extruder does not have a value, it will not be in the list.
-    #           If no extruder has the value, the list will contain the global value.
-    @staticmethod
-    def getExtruderValues(key: str) -> List[Any]:
-        global_stack = cast(GlobalStack, cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()) #We know that there must be a global stack by the time you're requesting setting values.
-
-        result = []
-        for extruder in ExtruderManager.getInstance().getActiveExtruderStacks():
-            if not extruder.isEnabled:
-                continue
-            # only include values from extruders that are "active" for the current machine instance
-            if int(extruder.getMetaDataEntry("position")) >= global_stack.getProperty("machine_extruder_count", "value"):
-                continue
-
-            value = extruder.getRawProperty(key, "value")
-
-            if value is None:
-                continue
-
-            if isinstance(value, SettingFunction):
-                value = value(extruder)
-
-            result.append(value)
-
-        if not result:
-            result.append(global_stack.getProperty(key, "value"))
-
-        return result
-
-    ##  Get all extruder values for a certain setting. This function will skip the user settings container.
-    #
-    #   This is exposed to SettingFunction so it can be used in value functions.
-    #
-    #   \param key The key of the setting to retrieve values for.
-    #
-    #   \return A list of values for all extruders. If an extruder does not have a value, it will not be in the list.
-    #           If no extruder has the value, the list will contain the global value.
-    @staticmethod
-    def getDefaultExtruderValues(key: str) -> List[Any]:
-        global_stack = cast(GlobalStack, cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()) #We know that there must be a global stack by the time you're requesting setting values.
-        context = PropertyEvaluationContext(global_stack)
-        context.context["evaluate_from_container_index"] = 1  # skip the user settings container
-        context.context["override_operators"] = {
-            "extruderValue": ExtruderManager.getDefaultExtruderValue,
-            "extruderValues": ExtruderManager.getDefaultExtruderValues,
-            "resolveOrValue": ExtruderManager.getDefaultResolveOrValue
-        }
-
-        result = []
-        for extruder in ExtruderManager.getInstance().getActiveExtruderStacks():
-            # only include values from extruders that are "active" for the current machine instance
-            if int(extruder.getMetaDataEntry("position")) >= global_stack.getProperty("machine_extruder_count", "value", context = context):
-                continue
-
-            value = extruder.getRawProperty(key, "value", context = context)
-
-            if value is None:
-                continue
-
-            if isinstance(value, SettingFunction):
-                value = value(extruder, context = context)
-
-            result.append(value)
-
-        if not result:
-            result.append(global_stack.getProperty(key, "value", context = context))
-
-        return result
-
-    ##  Return the default extruder position from the machine manager
-    @staticmethod
-    def getDefaultExtruderPosition() -> str:
-        return cura.CuraApplication.CuraApplication.getInstance().getMachineManager().defaultExtruderPosition
-
     ##  Get all extruder values for a certain setting.
     #
     #   This is exposed to qml for display purposes
@@ -464,62 +382,8 @@ class ExtruderManager(QObject):
     #
     #   \return String representing the extruder values
     @pyqtSlot(str, result="QVariant")
-    def getInstanceExtruderValues(self, key) -> List:
-        return ExtruderManager.getExtruderValues(key)
-
-    ##  Get the value for a setting from a specific extruder.
-    #
-    #   This is exposed to SettingFunction to use in value functions.
-    #
-    #   \param extruder_index The index of the extruder to get the value from.
-    #   \param key The key of the setting to get the value of.
-    #
-    #   \return The value of the setting for the specified extruder or for the
-    #   global stack if not found.
-    @staticmethod
-    def getExtruderValue(extruder_index: int, key: str) -> Any:
-        if extruder_index == -1:
-            extruder_index = int(cura.CuraApplication.CuraApplication.getInstance().getMachineManager().defaultExtruderPosition)
-        extruder = ExtruderManager.getInstance().getExtruderStack(extruder_index)
-
-        if extruder:
-            value = extruder.getRawProperty(key, "value")
-            if isinstance(value, SettingFunction):
-                value = value(extruder)
-        else:
-            # Just a value from global.
-            value = cast(GlobalStack, cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()).getProperty(key, "value")
-
-        return value
-
-    ##  Get the default value from the given extruder. This function will skip the user settings container.
-    #
-    #   This is exposed to SettingFunction to use in value functions.
-    #
-    #   \param extruder_index The index of the extruder to get the value from.
-    #   \param key The key of the setting to get the value of.
-    #
-    #   \return The value of the setting for the specified extruder or for the
-    #   global stack if not found.
-    @staticmethod
-    def getDefaultExtruderValue(extruder_index: int, key: str) -> Any:
-        extruder = ExtruderManager.getInstance().getExtruderStack(extruder_index)
-        context = PropertyEvaluationContext(extruder)
-        context.context["evaluate_from_container_index"] = 1  # skip the user settings container
-        context.context["override_operators"] = {
-            "extruderValue": ExtruderManager.getDefaultExtruderValue,
-            "extruderValues": ExtruderManager.getDefaultExtruderValues,
-            "resolveOrValue": ExtruderManager.getDefaultResolveOrValue
-        }
-
-        if extruder:
-            value = extruder.getRawProperty(key, "value", context = context)
-            if isinstance(value, SettingFunction):
-                value = value(extruder, context = context)
-        else:  # Just a value from global.
-            value = cast(GlobalStack, cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()).getProperty(key, "value", context = context)
-
-        return value
+    def getInstanceExtruderValues(self, key: str) -> List:
+        return self._application.getCustomSettingFunctions().getValuesInAllExtruders(key)
 
     ##  Get the resolve value or value for a given key
     #
@@ -535,28 +399,6 @@ class ExtruderManager(QObject):
 
         return resolved_value
 
-    ##  Get the resolve value or value for a given key without looking the first container (user container)
-    #
-    #   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 getDefaultResolveOrValue(key: str) -> Any:
-        global_stack = cast(GlobalStack, cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack())
-        context = PropertyEvaluationContext(global_stack)
-        context.context["evaluate_from_container_index"] = 1  # skip the user settings container
-        context.context["override_operators"] = {
-            "extruderValue": ExtruderManager.getDefaultExtruderValue,
-            "extruderValues": ExtruderManager.getDefaultExtruderValues,
-            "resolveOrValue": ExtruderManager.getDefaultResolveOrValue
-        }
-
-        resolved_value = global_stack.getProperty(key, "value", context = context)
-
-        return resolved_value
-
     __instance = None   # type: ExtruderManager
 
     @classmethod

+ 13 - 13
cura/Settings/UserChangesModel.py

@@ -1,15 +1,17 @@
-from UM.Qt.ListModel import ListModel
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+import os
+from collections import OrderedDict
 
 from PyQt5.QtCore import pyqtSlot, Qt
+
 from UM.Application import Application
-from cura.Settings.ExtruderManager import ExtruderManager
 from UM.Settings.ContainerRegistry import ContainerRegistry
 from UM.i18n import i18nCatalog
 from UM.Settings.SettingFunction import SettingFunction
-from UM.Settings.PropertyEvaluationContext import PropertyEvaluationContext
 
-from collections import OrderedDict
-import os
+from UM.Qt.ListModel import ListModel
 
 
 class UserChangesModel(ListModel):
@@ -38,9 +40,13 @@ class UserChangesModel(ListModel):
         self._update()
 
     def _update(self):
+        application = Application.getInstance()
+        machine_manager = application.getMachineManager()
+        custom_setting_functions = application.getCustomSettingFunctions()
+
         item_dict = OrderedDict()
         item_list = []
-        global_stack = Application.getInstance().getGlobalContainerStack()
+        global_stack = machine_manager.activeMachine
         if not global_stack:
             return
 
@@ -71,13 +77,7 @@ class UserChangesModel(ListModel):
 
             # Override "getExtruderValue" with "getDefaultExtruderValue" so we can get the default values
             user_changes = containers.pop(0)
-            default_value_resolve_context = PropertyEvaluationContext(stack)
-            default_value_resolve_context.context["evaluate_from_container_index"] = 1  # skip the user settings container
-            default_value_resolve_context.context["override_operators"] = {
-                "extruderValue": ExtruderManager.getDefaultExtruderValue,
-                "extruderValues": ExtruderManager.getDefaultExtruderValues,
-                "resolveOrValue": ExtruderManager.getDefaultResolveOrValue
-            }
+            default_value_resolve_context = custom_setting_functions.createContextForDefaultValueEvaluation(stack)
 
             for setting_key in user_changes.getAllKeys():
                 original_value = None