From e3edc79a3ecd3cd4a5806b7133a0996367b8049e Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 28 Sep 2017 13:21:03 +0200 Subject: [PATCH 01/10] modified some code to fix the multiple extrusion issues - CURA-4379 --- cura/Settings/QualityAndUserProfilesModel.py | 7 +++++-- cura/Settings/UserProfilesModel.py | 2 +- plugins/MachineSettingsAction/MachineSettingsAction.py | 2 +- resources/qml/SidebarHeader.qml | 4 ++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/cura/Settings/QualityAndUserProfilesModel.py b/cura/Settings/QualityAndUserProfilesModel.py index d0d0f2cae2..6289bf15f1 100644 --- a/cura/Settings/QualityAndUserProfilesModel.py +++ b/cura/Settings/QualityAndUserProfilesModel.py @@ -52,9 +52,12 @@ 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") == active_extruder.definition.getId()] + 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") 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 quality_list + filtered_quality_changes diff --git a/cura/Settings/UserProfilesModel.py b/cura/Settings/UserProfilesModel.py index b9c9bef89f..6df100fb09 100644 --- a/cura/Settings/UserProfilesModel.py +++ b/cura/Settings/UserProfilesModel.py @@ -52,7 +52,7 @@ 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.getId()] + 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")] 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] diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py index 3672066678..9f9c25c1a3 100755 --- a/plugins/MachineSettingsAction/MachineSettingsAction.py +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -176,7 +176,6 @@ class MachineSettingsAction(MachineAction): node.callDecoration("setActiveExtruder", extruder_manager.getExtruderStack(extruder_count - 1).getId()) definition_changes_container.setProperty("machine_extruder_count", "value", extruder_count) - self.forceUpdate() if extruder_count > 1: # Multiextrusion @@ -220,6 +219,7 @@ class MachineSettingsAction(MachineAction): machine_manager.setActiveVariant(extruder_variant_id) preferences.setValue("cura/choice_on_profile_override", choice_on_profile_override) + self.forceUpdate() @pyqtSlot() diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index a17c896ad6..c6ec190dad 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -94,8 +94,8 @@ Column onGlobalContainerChanged: { forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values. - var extruder_index = (machineExtruderCount.properties.value == 1) ? -1 : 0 - ExtruderManager.setActiveExtruderIndex(extruder_index); +// var extruder_index = (machineExtruderCount.properties.value == 1) ? -1 : 0 +// ExtruderManager.setActiveExtruderIndex(extruder_index); } } From 1b8766b953e88aac9e4b8d51732a601fc924757e Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Thu, 28 Sep 2017 16:00:16 +0200 Subject: [PATCH 02/10] CURA-4386 CURA-4379 change stack behaviours to fix crashes --- cura/Settings/ExtruderManager.py | 10 ++++++++-- cura/Settings/MachineManager.py | 10 +++++++--- .../MachineSettingsAction.py | 1 + resources/qml/Menus/MaterialMenu.qml | 20 ++----------------- resources/qml/SidebarHeader.qml | 16 +++++++++------ resources/qml/SidebarSimple.qml | 6 ++++++ 6 files changed, 34 insertions(+), 29 deletions(-) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index b16a88f1a9..7a6537e7d2 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 = 0 + self._active_extruder_index = -1 self._selected_object_extruders = [] Application.getInstance().globalContainerStackChanged.connect(self.__globalContainerStackChanged) self._global_container_stack_definition_id = None @@ -78,6 +78,7 @@ class ExtruderManager(QObject): def extruderIds(self): map = {} global_stack_id = Application.getInstance().getGlobalContainerStack().getId() + map["-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() @@ -513,11 +514,16 @@ class ExtruderManager(QObject): global_stack = Application.getInstance().getGlobalContainerStack() result = [] + machine_extruder_count = global_stack.getProperty("machine_extruder_count", "value") + + if machine_extruder_count is 1: + return result + if global_stack and global_stack.getId() in self._extruder_trains: for extruder in sorted(self._extruder_trains[global_stack.getId()]): result.append(self._extruder_trains[global_stack.getId()][extruder]) - return result[:global_stack.getProperty("machine_extruder_count", "value")] + return result[:machine_extruder_count] def __globalContainerStackChanged(self) -> None: global_container_stack = Application.getInstance().getGlobalContainerStack() diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 69f672ab0f..9ce288e0c0 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -271,7 +271,6 @@ class MachineManager(QObject): extruder_stack.containersChanged.disconnect(self._onInstanceContainersChanged) self._global_container_stack = Application.getInstance().getGlobalContainerStack() - self._active_container_stack = self._global_container_stack self.globalContainerChanged.emit() @@ -303,6 +302,9 @@ class MachineManager(QObject): quality = self._global_container_stack.quality quality.nameChanged.connect(self._onQualityNameChanged) + + self._active_container_stack = self._global_container_stack + self._error_check_timer.start() ## Update self._stacks_valid according to _checkStacksForErrors and emit if change. @@ -547,12 +549,14 @@ class MachineManager(QObject): def allActiveMaterialIds(self) -> Dict[str, str]: result = {} active_stacks = ExtruderManager.getInstance().getActiveExtruderStacks() - if active_stacks is not None: #If we have a global stack. + + result[self._global_container_stack.getId()] = self._global_container_stack.material.getId() + + if active_stacks is not None: # If we have extruder stacks for stack in active_stacks: material_container = stack.material if not material_container: continue - result[stack.getId()] = material_container.getId() return result diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py index 9f9c25c1a3..9912b091b2 100755 --- a/plugins/MachineSettingsAction/MachineSettingsAction.py +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -219,6 +219,7 @@ class MachineSettingsAction(MachineAction): machine_manager.setActiveVariant(extruder_variant_id) preferences.setValue("cura/choice_on_profile_override", choice_on_profile_override) + self.forceUpdate() diff --git a/resources/qml/Menus/MaterialMenu.qml b/resources/qml/Menus/MaterialMenu.qml index e167e65855..c590726928 100644 --- a/resources/qml/Menus/MaterialMenu.qml +++ b/resources/qml/Menus/MaterialMenu.qml @@ -39,11 +39,8 @@ Menu visible: printerConnected && Cura.MachineManager.printerOutputDevices[0].materialNames.length > extruderIndex onTriggered: { - var activeExtruderIndex = ExtruderManager.activeExtruderIndex; - ExtruderManager.setActiveExtruderIndex(extruderIndex); var materialId = Cura.MachineManager.printerOutputDevices[0].materialIds[extruderIndex]; var items = materialsModel.items; - // materialsModel.find cannot be used because we need to look inside the metadata property of items for(var i in items) { if (items[i]["metadata"]["GUID"] == materialId) @@ -52,7 +49,6 @@ Menu break; } } - ExtruderManager.setActiveExtruderIndex(activeExtruderIndex); } } @@ -70,13 +66,7 @@ Menu checkable: true checked: model.id == Cura.MachineManager.allActiveMaterialIds[ExtruderManager.extruderIds[extruderIndex]] exclusiveGroup: group - onTriggered: - { - var activeExtruderIndex = ExtruderManager.activeExtruderIndex; - ExtruderManager.setActiveExtruderIndex(extruderIndex); - Cura.MachineManager.setActiveMaterial(model.id); - ExtruderManager.setActiveExtruderIndex(activeExtruderIndex); - } + onTriggered: Cura.MachineManager.setActiveMaterial(model.id) } onObjectAdded: menu.insertItem(index, object) onObjectRemoved: menu.removeItem(object) @@ -111,13 +101,7 @@ Menu checkable: true checked: model.id == Cura.MachineManager.allActiveMaterialIds[ExtruderManager.extruderIds[extruderIndex]] exclusiveGroup: group - onTriggered: - { - var activeExtruderIndex = ExtruderManager.activeExtruderIndex; - ExtruderManager.setActiveExtruderIndex(extruderIndex); - Cura.MachineManager.setActiveMaterial(model.id); - ExtruderManager.setActiveExtruderIndex(activeExtruderIndex); - } + onTriggered: Cura.MachineManager.setActiveMaterial(model.id) } onObjectAdded: brandMaterialsMenu.insertItem(index, object) onObjectRemoved: brandMaterialsMenu.removeItem(object) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index c6ec190dad..be73ce57c2 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -91,12 +91,7 @@ Column Connections { target: Cura.MachineManager - onGlobalContainerChanged: - { - forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values. -// var extruder_index = (machineExtruderCount.properties.value == 1) ? -1 : 0 -// ExtruderManager.setActiveExtruderIndex(extruder_index); - } + onGlobalContainerChanged: forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values. } delegate: Button @@ -294,6 +289,15 @@ Column menu: MaterialMenu { extruderIndex: base.currentExtruderIndex } } + + Connections + { + target: Cura.MachineManager + onGlobalContainerChanged: + { + + } + } } // Print core row diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index d69a9a44a8..bdb0546e1b 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -68,6 +68,12 @@ Item onActiveQualityChanged: qualityModel.update() } + Connections + { + target: Cura.MachineManager + onActiveMaterialChanged: qualityModel.update() + } + ListModel { id: qualityModel From 61e65d5cb0527c6dce53e4bbebdda9f046c7c4e1 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 28 Sep 2017 16:14:58 +0200 Subject: [PATCH 03/10] Fixing code style - CURA-4386 CURA-4379 --- resources/qml/SidebarHeader.qml | 9 --------- resources/qml/SidebarSimple.qml | 5 ----- 2 files changed, 14 deletions(-) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index be73ce57c2..509939a913 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -289,15 +289,6 @@ Column menu: MaterialMenu { extruderIndex: base.currentExtruderIndex } } - - Connections - { - target: Cura.MachineManager - onGlobalContainerChanged: - { - - } - } } // Print core row diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index bdb0546e1b..8c1dec302b 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -66,11 +66,6 @@ Item { target: Cura.MachineManager onActiveQualityChanged: qualityModel.update() - } - - Connections - { - target: Cura.MachineManager onActiveMaterialChanged: qualityModel.update() } From afb83fac88c2488042b74394d2ad11136f0cce80 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 28 Sep 2017 18:02:39 +0200 Subject: [PATCH 04/10] Update the active extruder index when the global container changes. This fixes a problem when Cura starts with a single extruder printer but the user then choose a multiextruder printer - CURA-4386 Also added a quality definition in UM3E extruder with the ids of the UM3 extruders, so that the profiles for UM3 are also valid for UM3E and viceversa - CURA-4389 All are related issues with profiles and multiextruder printers --- cura/Settings/ExtruderManager.py | 10 +++++++++ cura/Settings/ProfilesModel.py | 14 ++++-------- cura/Settings/QualityAndUserProfilesModel.py | 15 +++++-------- cura/Settings/UserProfilesModel.py | 22 +++++++++---------- ...ultimaker3_extended_extruder_left.def.json | 3 ++- ...ltimaker3_extended_extruder_right.def.json | 3 ++- .../ultimaker3_extruder_left.def.json | 3 ++- .../ultimaker3_extruder_right.def.json | 3 ++- 8 files changed, 37 insertions(+), 36 deletions(-) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 7a6537e7d2..12277f9641 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -530,6 +530,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/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": { From f0e89b7e01b4e0005760b5fc04f90518057110f9 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 29 Sep 2017 09:40:54 +0200 Subject: [PATCH 05/10] Reverted a previous workaround that fixed errors when selecting material and variants in the application menus - CURA-4386 CURA-4379 --- resources/qml/Menus/MaterialMenu.qml | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) 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) From 1d61740d1a330da47fc0df70dc04de183fc4529b Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 29 Sep 2017 11:39:52 +0200 Subject: [PATCH 06/10] Added some comments to the code and minor changes - CURA-4386 CURA-4379 --- cura/Settings/ExtruderManager.py | 18 +++++++++++------- cura/Settings/MachineManager.py | 4 ++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 12277f9641..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: @@ -537,7 +541,7 @@ class ExtruderManager(QObject): if self._active_extruder_index == -1: self.setActiveExtruderIndex(0) else: - if self._active_extruder_index > -1: + if self._active_extruder_index != -1: self.setActiveExtruderIndex(-1) self.activeExtruderChanged.emit() 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 = {} From e868b972b50d9e1041651b0ee14760fe14c6c02a Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Thu, 28 Sep 2017 13:09:44 +0200 Subject: [PATCH 07/10] Implement the print job pause, resume and abort for Cura Connect CL-455 --- .../NetworkClusterPrinterOutputDevice.py | 20 ++++++- .../UM3NetworkPrinting/PrinterInfoBlock.qml | 55 ++++++++++--------- 2 files changed, 47 insertions(+), 28 deletions(-) diff --git a/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py b/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py index e8e33e8435..2a14b1d6dc 100644 --- a/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py +++ b/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py @@ -97,8 +97,8 @@ class NetworkClusterPrinterOutputDevice(NetworkPrinterOutputDevice.NetworkPrinte self._cluster_status_update_timer.setSingleShot(False) self._cluster_status_update_timer.timeout.connect(self._requestClusterStatus) - self._can_pause = False - self._can_abort = False + self._can_pause = True + self._can_abort = True self._can_pre_heat_bed = False self._cluster_size = int(properties.get(b"cluster_size", 0)) @@ -155,6 +155,22 @@ class NetworkClusterPrinterOutputDevice(NetworkPrinterOutputDevice.NetworkPrinte super().close() self._cluster_status_update_timer.stop() + def _setJobState(self, job_state): + if not self._selected_printer: + return + + selected_printer_uuid = self._printers_dict[self._selected_printer["unique_name"]]["uuid"] + if selected_printer_uuid not in self._print_job_by_printer_uuid: + return + + print_job_uuid = self._print_job_by_printer_uuid[selected_printer_uuid]["uuid"] + + url = QUrl(self._api_base_uri + "print_jobs/" + print_job_uuid + "/action") + put_request = QNetworkRequest(url) + put_request.setHeader(QNetworkRequest.ContentTypeHeader, "application/json") + data = '{"action": "' + job_state + '"}' + self._manager.put(put_request, data.encode()) + def _requestClusterStatus(self): # TODO: Handle timeout. We probably want to know if the cluster is still reachable or not. url = QUrl(self._api_base_uri + "print_jobs/") diff --git a/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml b/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml index 7fce36b6e3..e548c9e9d7 100644 --- a/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml +++ b/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml @@ -234,33 +234,36 @@ Rectangle if(printJob != null) { - if(printJob.status == "printing" || printJob.status == "post_print") + switch (printJob.status) { - return catalog.i18nc("@label:status", "Printing") - } - else if(printJob.status == "wait_for_configuration") - { - return catalog.i18nc("@label:status", "Reserved") - } - else if(printJob.status == "wait_cleanup") - { - return catalog.i18nc("@label:status", "Finished") - } - else if (printJob.status == "pre_print" || printJob.status == "sent_to_printer") - { - return catalog.i18nc("@label", "Preparing to print") - } - else if (printJob.configuration_changes_required != undefined && printJob.status == "queued") - { - return catalog.i18nc("@label:status", "Action required") - } - else if (printJob.Status == "aborted") - { - return catalog.i18nc("@label:status", "Print aborted") - } - else - { - return ""; + case "printing": + case "post_print": + return catalog.i18nc("@label:status", "Printing") + case "wait_for_configuration": + return catalog.i18nc("@label:status", "Reserved") + case "wait_cleanup": + return catalog.i18nc("@label:status", "Finished") + case "pre_print": + case "sent_to_printer": + return catalog.i18nc("@label", "Preparing to print") + case "queued": + if (printJob.configuration_changes_required != null && printJob.configuration_changes_required.length !== 0) + { + return catalog.i18nc("@label:status", "Action required"); + } + else + { + return ""; + } + case "pausing": + case "paused": + return catalog.i18nc("@label:status", "Paused"); + case "resuming": + return catalog.i18nc("@label:status", "Resuming"); + case "aborted": + return catalog.i18nc("@label:status", "Print aborted"); + default: + return ""; } } return catalog.i18nc("@label:status", "Available"); From 6d687d6f06b18b32238b4b059fbe92d984f71b16 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 29 Sep 2017 13:50:31 +0200 Subject: [PATCH 08/10] Re-enable changing of multi-extrusion machines to single extrusion CURA-4359 --- plugins/MachineSettingsAction/MachineSettingsAction.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py index 9912b091b2..62b3bb86c0 100755 --- a/plugins/MachineSettingsAction/MachineSettingsAction.py +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -112,13 +112,7 @@ class MachineSettingsAction(MachineAction): if not self._global_container_stack: return 0 - # If there is a printer that originally is multi-extruder, it's not allowed to change the number of extruders - # It's just allowed in case of Custom FDM printers - definition_container = self._global_container_stack.getBottom() - if definition_container.getId() == "custom": - return len(self._global_container_stack.getMetaDataEntry("machine_extruder_trains")) - return 0 - + return len(self._global_container_stack.getMetaDataEntry("machine_extruder_trains")) @pyqtSlot(int) def setMachineExtruderCount(self, extruder_count): From 3082038261c113d5b45f9ec7fc4b3fb305427ef3 Mon Sep 17 00:00:00 2001 From: "A.Sasin" Date: Fri, 29 Sep 2017 13:52:00 +0200 Subject: [PATCH 09/10] Fixed code style and machine default name is retrieved from machine definition CURA-4345 --- cura/Settings/CuraStackBuilder.py | 6 +++--- cura/Settings/MachineManager.py | 6 +++--- resources/qml/AddMachineDialog.qml | 3 +-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index 32d6cd3cd7..7a48b1657e 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -21,7 +21,7 @@ class CuraStackBuilder: # # \return The new global stack or None if an error occurred. @classmethod - def createMachine(cls, name: str, definition_id: str, default_name: str) -> Optional[GlobalStack]: + def createMachine(cls, name: str, definition_id: str) -> Optional[GlobalStack]: registry = ContainerRegistry.getInstance() definitions = registry.findDefinitionContainers(id = definition_id) if not definitions: @@ -29,7 +29,7 @@ class CuraStackBuilder: return None machine_definition = definitions[0] - generated_name = registry.createUniqueName("machine", "", default_name, machine_definition.name) + generated_name = registry.createUniqueName("machine", "", machine_definition.name, machine_definition.name) # Make sure the new name does not collide with any definition or (quality) profile # createUniqueName() only looks at other stacks, but not at definitions or quality profiles # Note that we don't go for uniqueName() immediately because that function matches with ignore_case set to true @@ -45,7 +45,7 @@ class CuraStackBuilder: ) # after creating a global stack can be set custom defined name - if(name != generated_name): + if name != generated_name: name = registry.createUniqueName("machine", "", name, machine_definition.name) if registry.findContainers(id = name): name = registry.uniqueName(name) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index ce9cdc7de7..4a321d0529 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -352,9 +352,9 @@ class MachineManager(QObject): if containers: Application.getInstance().setGlobalContainerStack(containers[0]) - @pyqtSlot(str, str, str) - def addMachine(self, name: str, definition_id: str, default_name: str) -> None: - new_stack = CuraStackBuilder.createMachine(name, definition_id, default_name) + @pyqtSlot(str, str) + def addMachine(self, name: str, definition_id: str) -> None: + new_stack = CuraStackBuilder.createMachine(name, definition_id) if new_stack: Application.getInstance().setGlobalContainerStack(new_stack) else: diff --git a/resources/qml/AddMachineDialog.qml b/resources/qml/AddMachineDialog.qml index 2a3e279bcc..109ea07695 100644 --- a/resources/qml/AddMachineDialog.qml +++ b/resources/qml/AddMachineDialog.qml @@ -217,8 +217,7 @@ UM.Dialog { base.visible = false var item = machineList.model.getItem(machineList.currentIndex); - var defaultName = (item != undefined) ? item.name : "" - Cura.MachineManager.addMachine(machineName.text, item.id, defaultName) + Cura.MachineManager.addMachine(machineName.text, item.id) base.machineAdded(item.id) // Emit signal that the user added a machine. } From 402617af1ea9dedfa53b68cd49c65c7628bd5486 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 29 Sep 2017 15:16:14 +0200 Subject: [PATCH 10/10] Loading extruder stack files also for single extruder printers - CURA-4379 --- plugins/3MFReader/ThreeMFWorkspaceReader.py | 79 ++++++++++----------- 1 file changed, 39 insertions(+), 40 deletions(-) diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index 647d731d46..38d925f8bc 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -693,54 +693,53 @@ class ThreeMFWorkspaceReader(WorkspaceReader): # -- # load extruder stack files - if extruder_count_from_global_stack > 1: - try: - for extruder_stack_file in extruder_stack_files: - container_id = self._stripFileToId(extruder_stack_file) - extruder_file_content = archive.open(extruder_stack_file, "r").read().decode("utf-8") + try: + for extruder_stack_file in extruder_stack_files: + container_id = self._stripFileToId(extruder_stack_file) + extruder_file_content = archive.open(extruder_stack_file, "r").read().decode("utf-8") - if self._resolve_strategies["machine"] == "override": - # deserialize new extruder stack over the current ones - stack = self._overrideExtruderStack(global_stack, extruder_file_content) + if self._resolve_strategies["machine"] == "override": + # deserialize new extruder stack over the current ones + stack = self._overrideExtruderStack(global_stack, extruder_file_content) - elif self._resolve_strategies["machine"] == "new": - new_id = extruder_stack_id_map[container_id] - stack = ExtruderStack(new_id) + elif self._resolve_strategies["machine"] == "new": + new_id = extruder_stack_id_map[container_id] + stack = ExtruderStack(new_id) - # HACK: the global stack can have a new name, so we need to make sure that this extruder stack - # references to the new name instead of the old one. Normally, this can be done after - # deserialize() by setting the metadata, but in the case of ExtruderStack, deserialize() - # also does addExtruder() to its machine stack, so we have to make sure that it's pointing - # to the right machine BEFORE deserialization. - extruder_config = configparser.ConfigParser() - extruder_config.read_string(extruder_file_content) - extruder_config.set("metadata", "machine", global_stack_id_new) - tmp_string_io = io.StringIO() - extruder_config.write(tmp_string_io) - extruder_file_content = tmp_string_io.getvalue() + # HACK: the global stack can have a new name, so we need to make sure that this extruder stack + # references to the new name instead of the old one. Normally, this can be done after + # deserialize() by setting the metadata, but in the case of ExtruderStack, deserialize() + # also does addExtruder() to its machine stack, so we have to make sure that it's pointing + # to the right machine BEFORE deserialization. + extruder_config = configparser.ConfigParser() + extruder_config.read_string(extruder_file_content) + extruder_config.set("metadata", "machine", global_stack_id_new) + tmp_string_io = io.StringIO() + extruder_config.write(tmp_string_io) + extruder_file_content = tmp_string_io.getvalue() - stack.deserialize(extruder_file_content) + stack.deserialize(extruder_file_content) - # Ensure a unique ID and name - stack._id = new_id + # Ensure a unique ID and name + stack._id = new_id - self._container_registry.addContainer(stack) - extruder_stacks_added.append(stack) - containers_added.append(stack) - else: - Logger.log("w", "Unknown resolve strategy: %s", self._resolve_strategies["machine"]) + self._container_registry.addContainer(stack) + extruder_stacks_added.append(stack) + containers_added.append(stack) + else: + Logger.log("w", "Unknown resolve strategy: %s", self._resolve_strategies["machine"]) - # Create a new definition_changes container if it was empty - if stack.definitionChanges == self._container_registry.getEmptyInstanceContainer(): - stack.setDefinitionChanges(CuraStackBuilder.createDefinitionChangesContainer(stack, stack._id + "_settings")) + # Create a new definition_changes container if it was empty + if stack.definitionChanges == self._container_registry.getEmptyInstanceContainer(): + stack.setDefinitionChanges(CuraStackBuilder.createDefinitionChangesContainer(stack, stack._id + "_settings")) - extruder_stacks.append(stack) - except: - Logger.logException("w", "We failed to serialize the stack. Trying to clean up.") - # Something went really wrong. Try to remove any data that we added. - for container in containers_added: - self._container_registry.removeContainer(container.getId()) - return + extruder_stacks.append(stack) + except: + Logger.logException("w", "We failed to serialize the stack. Trying to clean up.") + # Something went really wrong. Try to remove any data that we added. + for container in containers_added: + self._container_registry.removeContainer(container.getId()) + return # # Replacing the old containers if resolve is "new".