diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 7a6537e7d2..0ffaca4992 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -41,7 +41,7 @@ class ExtruderManager(QObject): def __init__(self, parent = None): super().__init__(parent) self._extruder_trains = { } #Per machine, a dictionary of extruder container stack IDs. Only for separately defined extruders. - self._active_extruder_index = -1 + self._active_extruder_index = -1 # Indicates the index of the active extruder stack. -1 means no active extruder stack self._selected_object_extruders = [] Application.getInstance().globalContainerStackChanged.connect(self.__globalContainerStackChanged) self._global_container_stack_definition_id = None @@ -74,15 +74,18 @@ class ExtruderManager(QObject): except KeyError: return 0 + ## Gets a dict with the extruder stack ids with the extruder number as the key. + # The key "-1" indicates the global stack id. + # @pyqtProperty("QVariantMap", notify = extrudersChanged) def extruderIds(self): - map = {} + extruder_stack_ids = {} global_stack_id = Application.getInstance().getGlobalContainerStack().getId() - map["-1"] = global_stack_id + extruder_stack_ids["-1"] = global_stack_id if global_stack_id in self._extruder_trains: for position in self._extruder_trains[global_stack_id]: - map[position] = self._extruder_trains[global_stack_id][position].getId() - return map + extruder_stack_ids[position] = self._extruder_trains[global_stack_id][position].getId() + return extruder_stack_ids @pyqtSlot(str, result = str) def getQualityChangesIdByExtruderStackId(self, id: str) -> str: @@ -516,7 +519,8 @@ class ExtruderManager(QObject): result = [] machine_extruder_count = global_stack.getProperty("machine_extruder_count", "value") - if machine_extruder_count is 1: + # In case the printer is using one extruder, shouldn't exist active extruder stacks + if machine_extruder_count == 1: return result if global_stack and global_stack.getId() in self._extruder_trains: @@ -530,6 +534,16 @@ class ExtruderManager(QObject): if global_container_stack and global_container_stack.getBottom() and global_container_stack.getBottom().getId() != self._global_container_stack_definition_id: self._global_container_stack_definition_id = global_container_stack.getBottom().getId() self.globalContainerStackDefinitionChanged.emit() + + # If the global container changed, the number of extruders could be changed and so the active_extruder_index is updated + extruder_count = global_container_stack.getProperty("machine_extruder_count", "value") + if extruder_count > 1: + if self._active_extruder_index == -1: + self.setActiveExtruderIndex(0) + else: + if self._active_extruder_index != -1: + self.setActiveExtruderIndex(-1) + self.activeExtruderChanged.emit() self.resetSelectedObjectExtruders() diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 9ce288e0c0..69cebc26c0 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -545,6 +545,10 @@ class MachineManager(QObject): return result + ## Gets a dict with the active materials ids set in all extruder stacks and the global stack + # (when there is one extruder, the material is set in the global stack) + # + # \return The material ids in all stacks @pyqtProperty("QVariantMap", notify = activeMaterialChanged) def allActiveMaterialIds(self) -> Dict[str, str]: result = {} diff --git a/cura/Settings/ProfilesModel.py b/cura/Settings/ProfilesModel.py index 71426d40f4..c56a1c9f7a 100644 --- a/cura/Settings/ProfilesModel.py +++ b/cura/Settings/ProfilesModel.py @@ -98,16 +98,10 @@ class ProfilesModel(InstanceContainersModel): extruder_manager = ExtruderManager.getInstance() active_extruder = extruder_manager.getActiveExtruderStack() extruder_stacks = extruder_manager.getActiveExtruderStacks() - if extruder_stacks: - if multiple_extrusion: - # Place the active extruder at the front of the list. - if active_extruder in extruder_stacks: - extruder_stacks.remove(active_extruder) - extruder_stacks = [active_extruder] + extruder_stacks - else: - # The active extruder is the first in the list and only the active extruder is use to compute the usable qualities - active_extruder = None - extruder_stacks = [] + if multiple_extrusion: + # Place the active extruder at the front of the list. + extruder_stacks.remove(active_extruder) + extruder_stacks = [active_extruder] + extruder_stacks # Get a list of usable/available qualities for this machine and material qualities = QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack, diff --git a/cura/Settings/QualityAndUserProfilesModel.py b/cura/Settings/QualityAndUserProfilesModel.py index 6289bf15f1..1871cd4698 100644 --- a/cura/Settings/QualityAndUserProfilesModel.py +++ b/cura/Settings/QualityAndUserProfilesModel.py @@ -31,16 +31,10 @@ class QualityAndUserProfilesModel(ProfilesModel): extruder_manager = ExtruderManager.getInstance() active_extruder = extruder_manager.getActiveExtruderStack() extruder_stacks = extruder_manager.getActiveExtruderStacks() - if extruder_stacks: - if multiple_extrusion: - # Place the active extruder at the front of the list. - if active_extruder in extruder_stacks: - extruder_stacks.remove(active_extruder) - extruder_stacks = [active_extruder] + extruder_stacks - else: - # The active extruder is the first in the list and only the active extruder is use to compute the usable qualities - active_extruder = None - extruder_stacks = [] + if multiple_extrusion: + # Place the active extruder at the front of the list. + extruder_stacks.remove(active_extruder) + extruder_stacks = [active_extruder] + extruder_stacks # Fetch the list of useable qualities across all extruders. # The actual list of quality profiles come from the first extruder in the extruder list. @@ -53,6 +47,7 @@ class QualityAndUserProfilesModel(ProfilesModel): if multiple_extrusion: # If the printer has multiple extruders then quality changes related to the current extruder are kept filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set and + qc.getMetaDataEntry("extruder") is not None and qc.getMetaDataEntry("extruder") == active_extruder.definition.getMetaDataEntry("quality_definition") or qc.getMetaDataEntry("extruder") == active_extruder.definition.getId()] else: diff --git a/cura/Settings/UserProfilesModel.py b/cura/Settings/UserProfilesModel.py index 6df100fb09..3344c9e076 100644 --- a/cura/Settings/UserProfilesModel.py +++ b/cura/Settings/UserProfilesModel.py @@ -31,16 +31,10 @@ class UserProfilesModel(ProfilesModel): extruder_manager = ExtruderManager.getInstance() active_extruder = extruder_manager.getActiveExtruderStack() extruder_stacks = extruder_manager.getActiveExtruderStacks() - if extruder_stacks: - if multiple_extrusion: - # Place the active extruder at the front of the list. - if active_extruder in extruder_stacks: - extruder_stacks.remove(active_extruder) - extruder_stacks = [active_extruder] + extruder_stacks - else: - # The active extruder is the first in the list and only the active extruder is use to compute the usable qualities - active_extruder = None - extruder_stacks = [] + if multiple_extrusion: + # Place the active extruder at the front of the list. + extruder_stacks.remove(active_extruder) + extruder_stacks = [active_extruder] + extruder_stacks # Fetch the list of useable qualities across all extruders. # The actual list of quality profiles come from the first extruder in the extruder list. @@ -52,9 +46,13 @@ class UserProfilesModel(ProfilesModel): if multiple_extrusion: # If the printer has multiple extruders then quality changes related to the current extruder are kept - filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set and qc.getMetaDataEntry("extruder") == active_extruder.definition.getMetaDataEntry("quality_definition")] + filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set and + qc.getMetaDataEntry("extruder") is not None and + qc.getMetaDataEntry("extruder") == active_extruder.definition.getMetaDataEntry("quality_definition") or + qc.getMetaDataEntry("extruder") == active_extruder.definition.getId()] else: # If not, the quality changes of the global stack are selected - filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set and qc.getMetaDataEntry("extruder") is None] + filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set and + qc.getMetaDataEntry("extruder") is None] return filtered_quality_changes diff --git a/resources/extruders/ultimaker3_extended_extruder_left.def.json b/resources/extruders/ultimaker3_extended_extruder_left.def.json index 2fcf1d015a..2d81424bc6 100644 --- a/resources/extruders/ultimaker3_extended_extruder_left.def.json +++ b/resources/extruders/ultimaker3_extended_extruder_left.def.json @@ -5,7 +5,8 @@ "inherits": "fdmextruder", "metadata": { "machine": "ultimaker3_extended", - "position": "0" + "position": "0", + "quality_definition": "ultimaker3_extruder_left" }, "overrides": { diff --git a/resources/extruders/ultimaker3_extended_extruder_right.def.json b/resources/extruders/ultimaker3_extended_extruder_right.def.json index b60cc82dd7..7cdd5876c1 100644 --- a/resources/extruders/ultimaker3_extended_extruder_right.def.json +++ b/resources/extruders/ultimaker3_extended_extruder_right.def.json @@ -5,7 +5,8 @@ "inherits": "fdmextruder", "metadata": { "machine": "ultimaker3_extended", - "position": "1" + "position": "1", + "quality_definition": "ultimaker3_extruder_right" }, "overrides": { diff --git a/resources/extruders/ultimaker3_extruder_left.def.json b/resources/extruders/ultimaker3_extruder_left.def.json index 6f07718b63..9f5ed34692 100644 --- a/resources/extruders/ultimaker3_extruder_left.def.json +++ b/resources/extruders/ultimaker3_extruder_left.def.json @@ -5,7 +5,8 @@ "inherits": "fdmextruder", "metadata": { "machine": "ultimaker3", - "position": "0" + "position": "0", + "quality_definition": "ultimaker3_extruder_left" }, "overrides": { diff --git a/resources/extruders/ultimaker3_extruder_right.def.json b/resources/extruders/ultimaker3_extruder_right.def.json index bc51b0da4b..7298a552b7 100644 --- a/resources/extruders/ultimaker3_extruder_right.def.json +++ b/resources/extruders/ultimaker3_extruder_right.def.json @@ -5,7 +5,8 @@ "inherits": "fdmextruder", "metadata": { "machine": "ultimaker3", - "position": "1" + "position": "1", + "quality_definition": "ultimaker3_extruder_right" }, "overrides": { diff --git a/resources/qml/Menus/MaterialMenu.qml b/resources/qml/Menus/MaterialMenu.qml index c590726928..38dfca4edd 100644 --- a/resources/qml/Menus/MaterialMenu.qml +++ b/resources/qml/Menus/MaterialMenu.qml @@ -66,7 +66,15 @@ Menu checkable: true checked: model.id == Cura.MachineManager.allActiveMaterialIds[ExtruderManager.extruderIds[extruderIndex]] exclusiveGroup: group - onTriggered: Cura.MachineManager.setActiveMaterial(model.id) + onTriggered: + { + // This workaround is done because of the application menus for materials and variants for multiextrusion printers. + // The extruder menu would always act on the correspoding extruder only, instead of acting on the extruder selected in the UI. + var activeExtruderIndex = ExtruderManager.activeExtruderIndex; + ExtruderManager.setActiveExtruderIndex(extruderIndex); + Cura.MachineManager.setActiveMaterial(model.id); + ExtruderManager.setActiveExtruderIndex(activeExtruderIndex); + } } onObjectAdded: menu.insertItem(index, object) onObjectRemoved: menu.removeItem(object) @@ -101,7 +109,15 @@ Menu checkable: true checked: model.id == Cura.MachineManager.allActiveMaterialIds[ExtruderManager.extruderIds[extruderIndex]] exclusiveGroup: group - onTriggered: Cura.MachineManager.setActiveMaterial(model.id) + onTriggered: + { + // This workaround is done because of the application menus for materials and variants for multiextrusion printers. + // The extruder menu would always act on the correspoding extruder only, instead of acting on the extruder selected in the UI. + var activeExtruderIndex = ExtruderManager.activeExtruderIndex; + ExtruderManager.setActiveExtruderIndex(extruderIndex); + Cura.MachineManager.setActiveMaterial(model.id); + ExtruderManager.setActiveExtruderIndex(activeExtruderIndex); + } } onObjectAdded: brandMaterialsMenu.insertItem(index, object) onObjectRemoved: brandMaterialsMenu.removeItem(object)