Browse Source

Add settings-function to get an extruder based on a property.

We wanted to select an extruder based on wether or not it has support-material, so that the user doesn't have to think about selecting a support extruder any more and in most cases, can't forget anymore either. The formula present in fdmprinter to do that was not only an unreadable nightmare, but also very slow. We decided to pull most of that functionality into the settings-function machinery instead (but just a bit more generic so other properties can be selected, not just 'material_is_support_material').

done as part of finishing off CURA-10643
Remco Burema 1 year ago
parent
commit
68231c957d

+ 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()

+ 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(anyExtruderNrWithOrDefault('material_is_support_material'))",
                     "settable_per_mesh": false,
                     "settable_per_extruder": false,
                     "children":