diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index 742d1872cb5..eeb4d957573 100755 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -166,6 +166,7 @@ def _onSceneChangeTimerFinished(self): if active_extruder_changed is not None: node.callDecoration("getActiveExtruderChangedSignal").disconnect(self._updateDisallowedAreasAndRebuild) node.decoratorsChanged.disconnect(self._updateNodeListeners) + self._updateUsedExtruders() self.rebuild() self._scene_objects = new_scene_objects @@ -202,7 +203,7 @@ def _updateNodeListeners(self, node: SceneNode): per_mesh_stack.propertyChanged.connect(self._onSettingPropertyChanged) active_extruder_changed = node.callDecoration("getActiveExtruderChangedSignal") if active_extruder_changed is not None: - active_extruder_changed.connect(self._updateDisallowedAreasAndRebuild) + active_extruder_changed.connect(self._nodeActiveExtruderChanged) def setWidth(self, width: float) -> None: self._width = width @@ -687,6 +688,7 @@ def _onStackChangeTimerFinished(self) -> None: self._depth = self._global_container_stack.getProperty("machine_depth", "value") self._shape = self._global_container_stack.getProperty("machine_shape", "value") + self._updateUsedExtruders() self._updateDisallowedAreas() self._updateRaftThickness() self._extra_z_clearance = self._calculateExtraZClearance(ExtruderManager.getInstance().getUsedExtruderStacks()) @@ -713,6 +715,7 @@ def _onSettingChangeTimerFinished(self) -> None: update_disallowed_areas = False update_raft_thickness = False update_extra_z_clearance = True + update_used_extruders = False for setting_key in self._changed_settings_since_last_rebuild: if setting_key in ["print_sequence", "support_mesh", "infill_mesh", "cutting_mesh", "anti_overhang_mesh"]: @@ -746,12 +749,17 @@ def _onSettingChangeTimerFinished(self) -> None: if setting_key in self._raft_settings: update_raft_thickness = True + update_used_extruders = True if setting_key in self._extra_z_settings: update_extra_z_clearance = True if setting_key in self._limit_to_extruder_settings: update_disallowed_areas = True + update_used_extruders = True + + if setting_key in self._extruder_settings: + update_used_extruders = True rebuild_me = update_extra_z_clearance or update_disallowed_areas or update_raft_thickness @@ -765,6 +773,9 @@ def _onSettingChangeTimerFinished(self) -> None: if update_extra_z_clearance: self._extra_z_clearance = self._calculateExtraZClearance(ExtruderManager.getInstance().getUsedExtruderStacks()) + if update_used_extruders: + self._updateUsedExtruders() + if rebuild_me: self.rebuild() @@ -791,6 +802,22 @@ def _updateMachineSizeProperties(self) -> None: self._depth = self._global_container_stack.getProperty("machine_depth", "value") self._shape = self._global_container_stack.getProperty("machine_shape", "value") + def _updateUsedExtruders(self): + Logger.info("Updating used extruders") + global_container_stack = self._application.getGlobalContainerStack() + if not global_container_stack: + return + used_extruders = ExtruderManager.getInstance().getUsedExtruderStacks() + for extruder in global_container_stack.extruderList: + used = extruder in used_extruders + Logger.info(f"- {extruder.getId()}: {used}") + changed = (used == extruder.getProperty("extruder_used", "value")) + extruder.setProperty("extruder_used", "value", used) + + def _nodeActiveExtruderChanged(self): + self._updateDisallowedAreasAndRebuild() + self._updateUsedExtruders() + def _updateDisallowedAreasAndRebuild(self): """Calls :py:meth:`cura.BuildVolume._updateDisallowedAreas` and makes sure the changes appear in the scene. diff --git a/cura/Settings/CuraFormulaFunctions.py b/cura/Settings/CuraFormulaFunctions.py index 93a4de28ec4..30d30317988 100644 --- a/cura/Settings/CuraFormulaFunctions.py +++ b/cura/Settings/CuraFormulaFunctions.py @@ -67,16 +67,19 @@ def _getActiveExtruders(self, context: Optional["PropertyEvaluationContext"] = N global_stack = machine_manager.activeMachine - result = [] + enabled_extruders = [] + used_extruders = [] 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) + enabled_extruders.append(extruder) + if extruder.getProperty("extruder_used", "value"): + used_extruders.append(extruder) - return result + return used_extruders if used_extruders else enabled_extruders # Gets all extruder values as a list for the given property. def getValuesInAllExtruders(self, property_key: str, diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 571d5012126..758481ed12c 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -289,6 +289,17 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, + "extruder_used": + { + "default_value": true, + "description": "Is this extruder used for printing. This setting is controlled by Cura automatically.", + "label": "Extruder Used", + "settable_globally": false, + "settable_per_extruder": true, + "settable_per_mesh": false, + "settable_per_meshgroup": false, + "type": "bool" + }, "machine_nozzle_tip_outer_diameter": { "label": "Outer Nozzle Diameter", @@ -2482,7 +2493,8 @@ "maximum_value_warning": "285", "enabled": "machine_heated_build_volume", "settable_per_mesh": false, - "settable_per_extruder": false + "settable_per_extruder": false, + "depends_on_settings": ["extruder_used"] }, "material_print_temperature": { @@ -2595,7 +2607,8 @@ "enabled": "machine_heated_bed and machine_gcode_flavor != \"UltiGCode\"", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false + "settable_per_meshgroup": false, + "depends_on_settings": ["extruder_used"] }, "material_bed_temperature_layer_0": {