Browse Source

Merge pull request #15739 from Ultimaker/CURA-10643_filter_extruder_by_material_prop

[CURA-10643] filter extruder by material prop
Remco Burema 1 year ago
parent
commit
d7b76e991e

+ 1 - 0
cura/CuraApplication.py

@@ -408,6 +408,7 @@ class CuraApplication(QtApplication):
 
         SettingFunction.registerOperator("extruderValue", self._cura_formula_functions.getValueInExtruder)
         SettingFunction.registerOperator("extruderValues", self._cura_formula_functions.getValuesInAllExtruders)
+        SettingFunction.registerOperator("anyExtruderNrWithOrDefault", self._cura_formula_functions.getAnyExtruderPositionWithOrDefault)
         SettingFunction.registerOperator("resolveOrValue", self._cura_formula_functions.getResolveOrValue)
         SettingFunction.registerOperator("defaultExtruderPosition", self._cura_formula_functions.getDefaultExtruderPosition)
         SettingFunction.registerOperator("valueFromContainer", self._cura_formula_functions.getValueFromContainerAtIndex)

+ 21 - 3
cura/Settings/CuraFormulaFunctions.py

@@ -58,9 +58,7 @@ class CuraFormulaFunctions:
 
         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]:
+    def _getActiveExtruders(self, context: Optional["PropertyEvaluationContext"] = None) -> List[str]:
         machine_manager = self._application.getMachineManager()
         extruder_manager = self._application.getExtruderManager()
 
@@ -73,7 +71,17 @@ class CuraFormulaFunctions:
             # 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:
@@ -89,6 +97,16 @@ class CuraFormulaFunctions:
 
         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)
+        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()

+ 2 - 1
docs/profiles/getting_a_setting_value.md

@@ -54,8 +54,9 @@ There are also a few extra things that can be used in these expressions:
 * The function `extruderValue(extruder, key)` will evaluate a particular setting for a particular extruder.
 * The function `resolveOrValue(key)` will perform the full setting evaluation as described in this document for the current context (so if this setting is being evaluated for the second extruder it would perform it as if coming from the second extruder).
 * The function `defaultExtruderPosition()` will get the first extruder that is not disabled. For instance, if a printer has three extruders but the first is disabled, this would return `1` to indicate the second extruder (0-indexed).
+* The function `anyExtruderNrWithOrDefault(key)` will filter the list of extruders on the key, and then give the first index for which it is true, or if none of them are, the default one as specified by the 'default extruder position' function above. 
 * The function `valueFromContainer(key, index)` will get a setting value from the global stack, but skip the first few containers in that stack. It will skip until it reaches a particular index in the container stack.
-* The function `valueFromExtruderContainer(key, index)` will get a setting value from the current extruder stack, but skip the first few containers in that stack. It will skip until it reaches a particular index in the container stack.
+* The function `extruderValueFromContainer(key, index)` will get a setting value from the current extruder stack, but skip the first few containers in that stack. It will skip until it reaches a particular index in the container stack.
 
 CuraEngine
 ----

+ 1 - 1
resources/definitions/fdmprinter.def.json

@@ -4490,7 +4490,7 @@
                     "type": "extruder",
                     "default_value": "0",
                     "enabled": "(support_enable or support_meshes_present) and extruders_enabled_count > 1",
-                    "value": "[*map(lambda x: str(x).lower() == 'true', (extruderValues('support_enable') and extruderValues('material_is_support_material')))].index(True) if any([*map(lambda x: str(x).lower() == 'true', (extruderValues('support_enable') and extruderValues('material_is_support_material')))]) else int(defaultExtruderPosition())",
+                    "value": "int(defaultExtruderPosition())",
                     "settable_per_mesh": false,
                     "settable_per_extruder": false,
                     "children":