mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-04-23 06:09:38 +08:00

checked: this code only checks for support type and adhesion type and make them lowercase CURA-11048
208 lines
9.9 KiB
Python
208 lines
9.9 KiB
Python
# 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
|
|
from UM.Logger import Logger
|
|
|
|
if TYPE_CHECKING:
|
|
from cura.CuraApplication import CuraApplication
|
|
from cura.Settings.CuraContainerStack import CuraContainerStack
|
|
|
|
|
|
#
|
|
# This class contains all Cura-related custom functions that can be used in formulas. Some functions requires
|
|
# information such as the currently active machine, so this is made into a class instead of standalone functions.
|
|
#
|
|
class CuraFormulaFunctions:
|
|
|
|
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
|
|
try:
|
|
extruder_stack = global_stack.extruderList[int(extruder_position)]
|
|
except IndexError:
|
|
if extruder_position != 0:
|
|
Logger.log("w", "Value for %s of extruder %s was requested, but that extruder is not available. Returning the result from extruder 0 instead" % (property_key, extruder_position))
|
|
# This fixes a very specific fringe case; If a profile was created for a custom printer and one of the
|
|
# extruder settings has been set to non zero and the profile is loaded for a machine that has only a single extruder
|
|
# it would cause all kinds of issues (and eventually a crash).
|
|
# See https://github.com/Ultimaker/Cura/issues/5535
|
|
return self.getValueInExtruder(0, property_key, context)
|
|
Logger.log("w", "Value for %s of extruder %s was requested, but that extruder is not available. " % (property_key, extruder_position))
|
|
return None
|
|
|
|
value = extruder_stack.getRawProperty(property_key, "value", context = context)
|
|
if isinstance(value, SettingFunction):
|
|
value = value(extruder_stack, context = context)
|
|
|
|
if isinstance(value, str):
|
|
value = value.lower()
|
|
|
|
return value
|
|
|
|
def _getActiveExtruders(self, context: Optional["PropertyEvaluationContext"] = None) -> List[str]:
|
|
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
|
|
result.append(extruder)
|
|
|
|
return result
|
|
|
|
# Gets all extruder values as a list for the given property.
|
|
def getValuesInAllExtruders(self, property_key: str,
|
|
context: Optional["PropertyEvaluationContext"] = None) -> List[Any]:
|
|
global_stack = self._application.getMachineManager().activeMachine
|
|
|
|
result = []
|
|
for extruder in self._getActiveExtruders(context):
|
|
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 first extruder that adheres to a specific (boolean) property, like 'material_is_support_material'.
|
|
def getAnyExtruderPositionWithOrDefault(self, filter_key: str,
|
|
context: Optional["PropertyEvaluationContext"] = None) -> str:
|
|
for extruder in self._getActiveExtruders(context):
|
|
value = extruder.getRawProperty(filter_key, "value", context=context)
|
|
if value is None or not value:
|
|
continue
|
|
return str(extruder.position)
|
|
|
|
# Get the first extruder with material that adheres to a specific (boolean) property, like 'material_is_support_material'.
|
|
def getExtruderPositionWithMaterial(self, filter_key: str,
|
|
context: Optional["PropertyEvaluationContext"] = None) -> str:
|
|
for extruder in self._getActiveExtruders(context):
|
|
material_container = extruder.material
|
|
value = material_container.getProperty(filter_key, "value", context)
|
|
if value is not None:
|
|
return str(extruder.position)
|
|
return self.getDefaultExtruderPosition()
|
|
|
|
# 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
|
|
try:
|
|
extruder_stack = global_stack.extruderList[extruder_position]
|
|
except IndexError:
|
|
Logger.log("w", "Unable to find extruder on in index %s", extruder_position)
|
|
else:
|
|
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)
|
|
|
|
# Gets the value for the given setting key starting from the given container index.
|
|
def getValueFromContainerAtIndex(self, property_key: str, container_index: int,
|
|
context: Optional["PropertyEvaluationContext"] = None) -> Any:
|
|
machine_manager = self._application.getMachineManager()
|
|
global_stack = machine_manager.activeMachine
|
|
|
|
context = self.createContextForDefaultValueEvaluation(global_stack)
|
|
context.context["evaluate_from_container_index"] = container_index
|
|
|
|
return global_stack.getProperty(property_key, "value", context = context)
|
|
|
|
# Gets the extruder value for the given setting key starting from the given container index.
|
|
def getValueFromContainerAtIndexInExtruder(self, extruder_position: int, property_key: str, container_index: int,
|
|
context: Optional["PropertyEvaluationContext"] = None) -> Any:
|
|
machine_manager = self._application.getMachineManager()
|
|
global_stack = machine_manager.activeMachine
|
|
|
|
if extruder_position == -1:
|
|
extruder_position = int(machine_manager.defaultExtruderPosition)
|
|
|
|
global_stack = machine_manager.activeMachine
|
|
try:
|
|
extruder_stack = global_stack.extruderList[int(extruder_position)]
|
|
except IndexError:
|
|
Logger.log("w", "Value for %s of extruder %s was requested, but that extruder is not available. " % (property_key, extruder_position))
|
|
return None
|
|
|
|
context = self.createContextForDefaultValueEvaluation(extruder_stack)
|
|
context.context["evaluate_from_container_index"] = container_index
|
|
|
|
return self.getValueInExtruder(extruder_position, property_key, 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
|