From dcd782418f79d9e20c5b930673f98f4b9891898d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 8 Oct 2019 13:40:12 +0200 Subject: [PATCH 01/26] Add UMS5 intent profiles Ultimaker's marketing department is so far unable to explain why users of the Ultimaker S5 would want to print more accurately. So we wait with adding these until they have their story straight. Contributes to issue CURA-6864. --- ...um_s5_aa0.4_ABS_Draft_Print_Quick.inst.cfg | 34 +++++++++++++++++++ ..._s5_aa0.4_ABS_Fast_Print_Accurate.inst.cfg | 34 +++++++++++++++++++ ...aa0.4_ABS_Normal_Quality_Accurate.inst.cfg | 34 +++++++++++++++++++ ...um_s5_aa0.4_PLA_Draft_Print_Quick.inst.cfg | 34 +++++++++++++++++++ ..._s5_aa0.4_PLA_Fast_Print_Accurate.inst.cfg | 34 +++++++++++++++++++ ...aa0.4_PLA_Normal_Quality_Accurate.inst.cfg | 34 +++++++++++++++++++ ...m_s5_aa0.4_TPLA_Draft_Print_Quick.inst.cfg | 34 +++++++++++++++++++ ...s5_aa0.4_TPLA_Fast_Print_Accurate.inst.cfg | 34 +++++++++++++++++++ ...a0.4_TPLA_Normal_Quality_Accurate.inst.cfg | 34 +++++++++++++++++++ 9 files changed, 306 insertions(+) create mode 100644 resources/intent/um_s5_aa0.4_ABS_Draft_Print_Quick.inst.cfg create mode 100644 resources/intent/um_s5_aa0.4_ABS_Fast_Print_Accurate.inst.cfg create mode 100644 resources/intent/um_s5_aa0.4_ABS_Normal_Quality_Accurate.inst.cfg create mode 100644 resources/intent/um_s5_aa0.4_PLA_Draft_Print_Quick.inst.cfg create mode 100644 resources/intent/um_s5_aa0.4_PLA_Fast_Print_Accurate.inst.cfg create mode 100644 resources/intent/um_s5_aa0.4_PLA_Normal_Quality_Accurate.inst.cfg create mode 100644 resources/intent/um_s5_aa0.4_TPLA_Draft_Print_Quick.inst.cfg create mode 100644 resources/intent/um_s5_aa0.4_TPLA_Fast_Print_Accurate.inst.cfg create mode 100644 resources/intent/um_s5_aa0.4_TPLA_Normal_Quality_Accurate.inst.cfg diff --git a/resources/intent/um_s5_aa0.4_ABS_Draft_Print_Quick.inst.cfg b/resources/intent/um_s5_aa0.4_ABS_Draft_Print_Quick.inst.cfg new file mode 100644 index 0000000000..f627fbf74b --- /dev/null +++ b/resources/intent/um_s5_aa0.4_ABS_Draft_Print_Quick.inst.cfg @@ -0,0 +1,34 @@ +[general] +version = 4 +name = Quick +definition = ultimaker_s5 + +[metadata] +setting_version = 10 +type = intent +intent_category = smooth +quality_type = draft +material = generic_abs +variant = AA 0.4 + +[values] +speed_infill = =speed_print +speed_topbottom = =speed_print +speed_wall = =speed_print +speed_wall_0 = =speed_wall +speed_wall_x = =speed_wall +speed_layer_0 = 20 +top_bottom_thickness = =wall_thickness +wall_thickness = =line_width * 2 +fill_perimeter_gaps = nowhere +infill_sparse_density = 15 +infill_line_width = =line_width +jerk_print = 30 +jerk_infill = =jerk_print +jerk_topbottom = =jerk_print +jerk_wall = =jerk_print +jerk_wall_0 = =jerk_wall +jerk_wall_x = =jerk_wall +jerk_layer_0 = 5 +line_width = =machine_nozzle_size +wall_line_width_x = =line_width diff --git a/resources/intent/um_s5_aa0.4_ABS_Fast_Print_Accurate.inst.cfg b/resources/intent/um_s5_aa0.4_ABS_Fast_Print_Accurate.inst.cfg new file mode 100644 index 0000000000..be622d6cfe --- /dev/null +++ b/resources/intent/um_s5_aa0.4_ABS_Fast_Print_Accurate.inst.cfg @@ -0,0 +1,34 @@ +[general] +version = 4 +name = Accurate +definition = ultimaker_s5 + +[metadata] +setting_version = 10 +type = intent +intent_category = engineering +quality_type = fast +material = generic_abs +variant = AA 0.4 + +[values] +infill_line_width = =line_width +jerk_print = 30 +jerk_infill = =jerk_print +jerk_topbottom = =jerk_print +jerk_wall = =jerk_print +jerk_wall_0 = =jerk_wall +jerk_wall_x = =jerk_wall +jerk_layer_0 = 5 +line_width = =machine_nozzle_size +speed_print = 30 +speed_infill = =speed_print +speed_layer_0 = 20 +speed_topbottom = =speed_print +speed_wall = =speed_print +speed_wall_0 = =speed_wall +speed_wall_x = =speed_wall +top_bottom_thickness = =wall_thickness +wall_line_width_x = =line_width +wall_thickness = =line_width * 3 +xy_offset = =- layer_height * 0.2 diff --git a/resources/intent/um_s5_aa0.4_ABS_Normal_Quality_Accurate.inst.cfg b/resources/intent/um_s5_aa0.4_ABS_Normal_Quality_Accurate.inst.cfg new file mode 100644 index 0000000000..352c26d312 --- /dev/null +++ b/resources/intent/um_s5_aa0.4_ABS_Normal_Quality_Accurate.inst.cfg @@ -0,0 +1,34 @@ +[general] +version = 4 +name = Accurate +definition = ultimaker_s5 + +[metadata] +setting_version = 10 +type = intent +intent_category = engineering +quality_type = normal +material = generic_abs +variant = AA 0.4 + +[values] +infill_line_width = =line_width +jerk_print = 30 +jerk_infill = =jerk_print +jerk_topbottom = =jerk_print +jerk_wall = =jerk_print +jerk_wall_0 = =jerk_wall +jerk_wall_x = =jerk_wall +jerk_layer_0 = 5 +line_width = =machine_nozzle_size +speed_print = 30 +speed_infill = =speed_print +speed_layer_0 = 20 +speed_topbottom = =speed_print +speed_wall = =speed_print +speed_wall_0 = =speed_wall +speed_wall_x = =speed_wall +top_bottom_thickness = =wall_thickness +wall_line_width_x = =line_width +wall_thickness = =line_width * 3 +xy_offset = =- layer_height * 0.2 diff --git a/resources/intent/um_s5_aa0.4_PLA_Draft_Print_Quick.inst.cfg b/resources/intent/um_s5_aa0.4_PLA_Draft_Print_Quick.inst.cfg new file mode 100644 index 0000000000..553a68201d --- /dev/null +++ b/resources/intent/um_s5_aa0.4_PLA_Draft_Print_Quick.inst.cfg @@ -0,0 +1,34 @@ +[general] +version = 4 +name = Quick +definition = ultimaker_s5 + +[metadata] +setting_version = 10 +type = intent +intent_category = smooth +quality_type = draft +material = generic_pla +variant = AA 0.4 + +[values] +speed_infill = =speed_print +speed_topbottom = =speed_print +speed_wall = =speed_print +speed_wall_0 = =speed_wall +speed_wall_x = =speed_wall +speed_layer_0 = 20 +top_bottom_thickness = =wall_thickness +wall_thickness = =line_width * 2 +fill_perimeter_gaps = nowhere +infill_sparse_density = 15 +infill_line_width = =line_width +jerk_print = 30 +jerk_infill = =jerk_print +jerk_topbottom = =jerk_print +jerk_wall = =jerk_print +jerk_wall_0 = =jerk_wall +jerk_wall_x = =jerk_wall +jerk_layer_0 = 5 +line_width = =machine_nozzle_size +wall_line_width_x = =line_width diff --git a/resources/intent/um_s5_aa0.4_PLA_Fast_Print_Accurate.inst.cfg b/resources/intent/um_s5_aa0.4_PLA_Fast_Print_Accurate.inst.cfg new file mode 100644 index 0000000000..0943bb2032 --- /dev/null +++ b/resources/intent/um_s5_aa0.4_PLA_Fast_Print_Accurate.inst.cfg @@ -0,0 +1,34 @@ +[general] +version = 4 +name = Accurate +definition = ultimaker_s5 + +[metadata] +setting_version = 10 +type = intent +intent_category = engineering +quality_type = fast +material = generic_pla +variant = AA 0.4 + +[values] +infill_line_width = =line_width +jerk_print = 30 +jerk_infill = =jerk_print +jerk_topbottom = =jerk_print +jerk_wall = =jerk_print +jerk_wall_0 = =jerk_wall +jerk_wall_x = =jerk_wall +jerk_layer_0 = 5 +line_width = =machine_nozzle_size +speed_print = 30 +speed_infill = =speed_print +speed_layer_0 = 20 +speed_topbottom = =speed_print +speed_wall = =speed_print +speed_wall_0 = =speed_wall +speed_wall_x = =speed_wall +top_bottom_thickness = =wall_thickness +wall_line_width_x = =line_width +wall_thickness = =line_width * 3 +xy_offset = =- layer_height * 0.2 diff --git a/resources/intent/um_s5_aa0.4_PLA_Normal_Quality_Accurate.inst.cfg b/resources/intent/um_s5_aa0.4_PLA_Normal_Quality_Accurate.inst.cfg new file mode 100644 index 0000000000..053b849aff --- /dev/null +++ b/resources/intent/um_s5_aa0.4_PLA_Normal_Quality_Accurate.inst.cfg @@ -0,0 +1,34 @@ +[general] +version = 4 +name = Accurate +definition = ultimaker_s5 + +[metadata] +setting_version = 10 +type = intent +intent_category = engineering +quality_type = normal +material = generic_pla +variant = AA 0.4 + +[values] +infill_line_width = =line_width +jerk_print = 30 +jerk_infill = =jerk_print +jerk_topbottom = =jerk_print +jerk_wall = =jerk_print +jerk_wall_0 = =jerk_wall +jerk_wall_x = =jerk_wall +jerk_layer_0 = 5 +line_width = =machine_nozzle_size +speed_print = 30 +speed_infill = =speed_print +speed_layer_0 = 20 +speed_topbottom = =speed_print +speed_wall = =speed_print +speed_wall_0 = =speed_wall +speed_wall_x = =speed_wall +top_bottom_thickness = =wall_thickness +wall_line_width_x = =line_width +wall_thickness = =line_width * 3 +xy_offset = =- layer_height * 0.2 diff --git a/resources/intent/um_s5_aa0.4_TPLA_Draft_Print_Quick.inst.cfg b/resources/intent/um_s5_aa0.4_TPLA_Draft_Print_Quick.inst.cfg new file mode 100644 index 0000000000..458b283dd8 --- /dev/null +++ b/resources/intent/um_s5_aa0.4_TPLA_Draft_Print_Quick.inst.cfg @@ -0,0 +1,34 @@ +[general] +version = 4 +name = Quick +definition = ultimaker_s5 + +[metadata] +setting_version = 10 +type = intent +intent_category = smooth +quality_type = draft +material = generic_tough_pla +variant = AA 0.4 + +[values] +speed_infill = =speed_print +speed_topbottom = =speed_print +speed_wall = =speed_print +speed_wall_0 = =speed_wall +speed_wall_x = =speed_wall +speed_layer_0 = 20 +top_bottom_thickness = =wall_thickness +wall_thickness = =line_width * 2 +fill_perimeter_gaps = nowhere +infill_sparse_density = 15 +infill_line_width = =line_width +jerk_print = 30 +jerk_infill = =jerk_print +jerk_topbottom = =jerk_print +jerk_wall = =jerk_print +jerk_wall_0 = =jerk_wall +jerk_wall_x = =jerk_wall +jerk_layer_0 = 5 +line_width = =machine_nozzle_size +wall_line_width_x = =line_width diff --git a/resources/intent/um_s5_aa0.4_TPLA_Fast_Print_Accurate.inst.cfg b/resources/intent/um_s5_aa0.4_TPLA_Fast_Print_Accurate.inst.cfg new file mode 100644 index 0000000000..d19ad53fae --- /dev/null +++ b/resources/intent/um_s5_aa0.4_TPLA_Fast_Print_Accurate.inst.cfg @@ -0,0 +1,34 @@ +[general] +version = 4 +name = Accurate +definition = ultimaker_s5 + +[metadata] +setting_version = 10 +type = intent +intent_category = engineering +quality_type = fast +material = generic_tough_pla +variant = AA 0.4 + +[values] +infill_line_width = =line_width +jerk_print = 30 +jerk_infill = =jerk_print +jerk_topbottom = =jerk_print +jerk_wall = =jerk_print +jerk_wall_0 = =jerk_wall +jerk_wall_x = =jerk_wall +jerk_layer_0 = 5 +line_width = =machine_nozzle_size +speed_print = 30 +speed_infill = =speed_print +speed_layer_0 = 20 +speed_topbottom = =speed_print +speed_wall = =speed_print +speed_wall_0 = =speed_wall +speed_wall_x = =speed_wall +top_bottom_thickness = =wall_thickness +wall_line_width_x = =line_width +wall_thickness = =line_width * 3 +xy_offset = =- layer_height * 0.2 diff --git a/resources/intent/um_s5_aa0.4_TPLA_Normal_Quality_Accurate.inst.cfg b/resources/intent/um_s5_aa0.4_TPLA_Normal_Quality_Accurate.inst.cfg new file mode 100644 index 0000000000..23d8b1e39b --- /dev/null +++ b/resources/intent/um_s5_aa0.4_TPLA_Normal_Quality_Accurate.inst.cfg @@ -0,0 +1,34 @@ +[general] +version = 4 +name = Accurate +definition = ultimaker_s5 + +[metadata] +setting_version = 10 +type = intent +intent_category = engineering +quality_type = normal +material = generic_tough_pla +variant = AA 0.4 + +[values] +infill_line_width = =line_width +jerk_print = 30 +jerk_infill = =jerk_print +jerk_topbottom = =jerk_print +jerk_wall = =jerk_print +jerk_wall_0 = =jerk_wall +jerk_wall_x = =jerk_wall +jerk_layer_0 = 5 +line_width = =machine_nozzle_size +speed_print = 30 +speed_infill = =speed_print +speed_layer_0 = 20 +speed_topbottom = =speed_print +speed_wall = =speed_print +speed_wall_0 = =speed_wall +speed_wall_x = =speed_wall +top_bottom_thickness = =wall_thickness +wall_line_width_x = =line_width +wall_thickness = =line_width * 3 +xy_offset = =- layer_height * 0.2 From 902b9f278eda41b35509af128f10152a5eb1a93d Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Wed, 9 Oct 2019 12:01:16 +0200 Subject: [PATCH 02/26] Add tooltips for view orientation buttons. --- resources/qml/ViewOrientationControls.qml | 30 +++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/resources/qml/ViewOrientationControls.qml b/resources/qml/ViewOrientationControls.qml index 5750e935f4..de594ac008 100644 --- a/resources/qml/ViewOrientationControls.qml +++ b/resources/qml/ViewOrientationControls.qml @@ -20,29 +20,59 @@ Row { iconSource: UM.Theme.getIcon("view_3d") onClicked: Cura.Actions.view3DCamera.trigger() + + UM.TooltipArea + { + anchors.fill: parent + text: catalog.i18nc("@info:tooltip", "3D View") + } } ViewOrientationButton { iconSource: UM.Theme.getIcon("view_front") onClicked: Cura.Actions.viewFrontCamera.trigger() + + UM.TooltipArea + { + anchors.fill: parent + text: catalog.i18nc("@info:tooltip", "Front View") + } } ViewOrientationButton { iconSource: UM.Theme.getIcon("view_top") onClicked: Cura.Actions.viewTopCamera.trigger() + + UM.TooltipArea + { + anchors.fill: parent + text: catalog.i18nc("@info:tooltip", "Top View") + } } ViewOrientationButton { iconSource: UM.Theme.getIcon("view_left") onClicked: Cura.Actions.viewLeftSideCamera.trigger() + + UM.TooltipArea + { + anchors.fill: parent + text: catalog.i18nc("@info:tooltip", "Left View") + } } ViewOrientationButton { iconSource: UM.Theme.getIcon("view_right") onClicked: Cura.Actions.viewRightSideCamera.trigger() + + UM.TooltipArea + { + anchors.fill: parent + text: catalog.i18nc("@info:tooltip", "Right View") + } } } From 25db711adc2878248a3273ecf91cebdbe04f5fd7 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Thu, 10 Oct 2019 12:57:27 +0200 Subject: [PATCH 03/26] Fix tooltips absorbed mouseclicks for view-buttons. --- resources/qml/ViewOrientationControls.qml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/resources/qml/ViewOrientationControls.qml b/resources/qml/ViewOrientationControls.qml index de594ac008..97f2bb9400 100644 --- a/resources/qml/ViewOrientationControls.qml +++ b/resources/qml/ViewOrientationControls.qml @@ -25,6 +25,7 @@ Row { anchors.fill: parent text: catalog.i18nc("@info:tooltip", "3D View") + acceptedButtons: Qt.NoButton } } @@ -37,6 +38,7 @@ Row { anchors.fill: parent text: catalog.i18nc("@info:tooltip", "Front View") + acceptedButtons: Qt.NoButton } } @@ -49,6 +51,7 @@ Row { anchors.fill: parent text: catalog.i18nc("@info:tooltip", "Top View") + acceptedButtons: Qt.NoButton } } @@ -61,6 +64,7 @@ Row { anchors.fill: parent text: catalog.i18nc("@info:tooltip", "Left View") + acceptedButtons: Qt.NoButton } } @@ -73,6 +77,7 @@ Row { anchors.fill: parent text: catalog.i18nc("@info:tooltip", "Right View") + acceptedButtons: Qt.NoButton } } } From c8d65e86f18b89264050a4b51b7246842bbc22be Mon Sep 17 00:00:00 2001 From: Nino van Hooff Date: Thu, 10 Oct 2019 15:36:14 +0200 Subject: [PATCH 04/26] Truncate/elide/ellipsize the material name in Preferences if it doesn't fit it's parent CURA-6862 --- resources/qml/Preferences/Materials/MaterialsDetailsPanel.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/qml/Preferences/Materials/MaterialsDetailsPanel.qml b/resources/qml/Preferences/Materials/MaterialsDetailsPanel.qml index b54af103fe..e821dfb955 100644 --- a/resources/qml/Preferences/Materials/MaterialsDetailsPanel.qml +++ b/resources/qml/Preferences/Materials/MaterialsDetailsPanel.qml @@ -64,8 +64,10 @@ Item height: childrenRect.height Label { + width: parent.width text: materialProperties.name font: UM.Theme.getFont("large_bold") + elide: Text.ElideRight } } From 4277ede64f56bcbcb1e8dc9a411f7b9a7727bdf6 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Mon, 14 Oct 2019 01:01:19 +0200 Subject: [PATCH 05/26] Fix 1/2 of the duplication material bug. The material is added multiple times to the variant nodes, and overwriting it with the eventual right one was going wrong. This does not solve it entirely (because the less specific one still ends up selected _initially_ because it gets added first, and the order can't be guaranteed. part of CURA-6863 --- cura/Machines/VariantNode.py | 11 +++++------ resources/qml/Preferences/Materials/MaterialsList.qml | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/cura/Machines/VariantNode.py b/cura/Machines/VariantNode.py index fa0c61bd3d..a9a6608d27 100644 --- a/cura/Machines/VariantNode.py +++ b/cura/Machines/VariantNode.py @@ -1,6 +1,5 @@ # Copyright (c) 2019 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. - from typing import Optional, TYPE_CHECKING from UM.Logger import Logger @@ -111,18 +110,18 @@ class VariantNode(ContainerNode): if base_file not in self.materials: # Completely new base file. Always better than not having a file as long as it matches our set-up. if material_definition != "fdmprinter" and material_definition != self.machine.container_id: return - material_variant = container.getMetaDataEntry("variant_name", "empty") - if material_variant != "empty" and material_variant != self.variant_name: + material_variant = container.getMetaDataEntry("variant_name") + if material_variant is not None and material_variant != self.variant_name: return else: # We already have this base profile. Replace the base profile if the new one is more specific. new_definition = container.getMetaDataEntry("definition") if new_definition == "fdmprinter": return # Just as unspecific or worse. - if new_definition != self.machine.container_id: + material_variant = container.getMetaDataEntry("variant_name") + if new_definition != self.machine.container_id or material_variant != self.variant_name: return # Doesn't match this set-up. original_metadata = ContainerRegistry.getInstance().findContainersMetadata(id = self.materials[base_file].container_id)[0] - original_variant = original_metadata.get("variant_name", "empty") - if original_variant != "empty" or container.getMetaDataEntry("variant_name", "empty") == "empty": + if "variant_name" in original_metadata or material_variant is not None: return # Original was already specific or just as unspecific as the new one. if "empty_material" in self.materials: diff --git a/resources/qml/Preferences/Materials/MaterialsList.qml b/resources/qml/Preferences/Materials/MaterialsList.qml index 96f6730029..8b82a87820 100644 --- a/resources/qml/Preferences/Materials/MaterialsList.qml +++ b/resources/qml/Preferences/Materials/MaterialsList.qml @@ -114,7 +114,7 @@ Item if (base.toActivateNewMaterial) { var position = Cura.ExtruderManager.activeExtruderIndex - Cura.MachineManager.setMaterial(position, base.currentItem.container_node) + Cura.MachineManager.setMaterialById(position, base.newRootMaterialIdToSwitchTo) } base.newRootMaterialIdToSwitchTo = "" base.toActivateNewMaterial = false From 09dc6ae44aece0c3b4c33d98c87a1e767eb83a4d Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Mon, 14 Oct 2019 01:03:41 +0200 Subject: [PATCH 06/26] Scouting: Try not to spam signals or errors as much. nominally part of CURA-6863 --- cura/PrinterOutput/Models/ExtruderConfigurationModel.py | 7 ++++--- .../qml/Preferences/Materials/MaterialsTypeSection.qml | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cura/PrinterOutput/Models/ExtruderConfigurationModel.py b/cura/PrinterOutput/Models/ExtruderConfigurationModel.py index 04a3c95afd..4a1cf4916f 100644 --- a/cura/PrinterOutput/Models/ExtruderConfigurationModel.py +++ b/cura/PrinterOutput/Models/ExtruderConfigurationModel.py @@ -25,9 +25,10 @@ class ExtruderConfigurationModel(QObject): return self._position def setMaterial(self, material: Optional[MaterialOutputModel]) -> None: - if self._material != material: - self._material = material - self.extruderConfigurationChanged.emit() + if material is None or self._material == material: + return + self._material = material + self.extruderConfigurationChanged.emit() @pyqtProperty(QObject, fset = setMaterial, notify = extruderConfigurationChanged) def activeMaterial(self) -> Optional[MaterialOutputModel]: diff --git a/resources/qml/Preferences/Materials/MaterialsTypeSection.qml b/resources/qml/Preferences/Materials/MaterialsTypeSection.qml index 2c1e2128e1..3c36e12651 100644 --- a/resources/qml/Preferences/Materials/MaterialsTypeSection.qml +++ b/resources/qml/Preferences/Materials/MaterialsTypeSection.qml @@ -21,6 +21,7 @@ Item property var colorsModel: materialType != null ? materialType.colors: null height: childrenRect.height width: parent.width + anchors.left: parent.left Rectangle { id: material_type_header_background From 26a7de5a27d795c229a3a3b09fb0d87ad62176e0 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Mon, 14 Oct 2019 11:02:58 +0200 Subject: [PATCH 07/26] Fix boolean check. part of CURA-6863 --- cura/Machines/VariantNode.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Machines/VariantNode.py b/cura/Machines/VariantNode.py index a9a6608d27..2fdc847a0a 100644 --- a/cura/Machines/VariantNode.py +++ b/cura/Machines/VariantNode.py @@ -121,7 +121,7 @@ class VariantNode(ContainerNode): if new_definition != self.machine.container_id or material_variant != self.variant_name: return # Doesn't match this set-up. original_metadata = ContainerRegistry.getInstance().findContainersMetadata(id = self.materials[base_file].container_id)[0] - if "variant_name" in original_metadata or material_variant is not None: + if "variant_name" in original_metadata or material_variant is None: return # Original was already specific or just as unspecific as the new one. if "empty_material" in self.materials: From c147174668ffeb6b5af7b05ffd494361db923fc1 Mon Sep 17 00:00:00 2001 From: Nino van Hooff Date: Mon, 14 Oct 2019 11:04:28 +0200 Subject: [PATCH 08/26] Limit profile name to 70% of available width for CustomPrintSetup This leaves 30% for the variant detail info CURA-6862 --- .../Custom/CustomPrintSetup.qml | 122 +++++++++++------- 1 file changed, 77 insertions(+), 45 deletions(-) diff --git a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml index 2698089d0c..b72341a4d6 100644 --- a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml @@ -4,6 +4,7 @@ import QtQuick 2.10 import QtQuick.Controls 2.3 import QtQuick.Controls 1.4 as OldControls +import QtQuick.Layouts 1.3 import UM 1.3 as UM import Cura 1.6 as Cura @@ -66,7 +67,6 @@ Item { id: intentSelection onClicked: menu.opened ? menu.close() : menu.open() - text: generateActiveQualityText() anchors.right: parent.right width: UM.Theme.getSize("print_setup_big_item").width @@ -75,18 +75,85 @@ Item baselineOffset: null // If we don't do this, there is a binding loop. WHich is a bit weird, since we override the contentItem anyway... - contentItem: Label + + contentItem: RowLayout { - id: textLabel - text: intentSelection.text - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") + spacing: 0 anchors.left: parent.left + anchors.right: customisedSettings.left anchors.leftMargin: UM.Theme.getSize("default_margin").width - anchors.verticalCenter: intentSelection.verticalCenter - height: contentHeight - verticalAlignment: Text.AlignVCenter - renderType: Text.NativeRendering + + + + Label + { + id: textLabel + text: qualityName() + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + anchors.verticalCenter: intentSelection.verticalCenter + Layout.margins: 0 + Layout.maximumWidth: parent.width * 0.7 + height: contentHeight + verticalAlignment: Text.AlignVCenter + renderType: Text.NativeRendering + elide: Text.ElideRight + + function qualityName() { + var resultMap = Cura.MachineManager.activeQualityDisplayNameMap + return resultMap["main"] + } + } + + Label + { + text: activeQualityDetailText() + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text_detail") + anchors.verticalCenter: intentSelection.verticalCenter + Layout.margins: 0 + Layout.fillWidth: true + + height: contentHeight + verticalAlignment: Text.AlignVCenter + renderType: Text.NativeRendering + elide: Text.ElideRight + + function activeQualityDetailText() + { + var resultMap = Cura.MachineManager.activeQualityDisplayNameMap + var resultSuffix = resultMap["suffix"] + var result = "" + + if (Cura.MachineManager.isActiveQualityExperimental) + { + resultSuffix += " (Experimental)" + } + + if (Cura.MachineManager.isActiveQualitySupported) + { + if (Cura.MachineManager.activeQualityLayerHeight > 0) + { + if (resultSuffix) + { + result += " - " + } + if (resultSuffix) + { + result += resultSuffix + } + result += " - " + result += Cura.MachineManager.activeQualityLayerHeight + "mm" + } + } + + return result + } + } + + + + } background: Rectangle @@ -98,41 +165,6 @@ Item color: UM.Theme.getColor("main_background") } - function generateActiveQualityText() - { - var resultMap = Cura.MachineManager.activeQualityDisplayNameMap - var resultMain = resultMap["main"] - var resultSuffix = resultMap["suffix"] - var result = "" - - if (Cura.MachineManager.isActiveQualityExperimental) - { - resultSuffix += " (Experimental)" - } - - if (Cura.MachineManager.isActiveQualitySupported) - { - if (Cura.MachineManager.activeQualityLayerHeight > 0) - { - result = resultMain - if (resultSuffix) - { - result += " - " - } - result += "" - if (resultSuffix) - { - result += resultSuffix - } - result += " - " - result += Cura.MachineManager.activeQualityLayerHeight + "mm" - result += "" - } - } - - return result - } - UM.SimpleButton { id: customisedSettings From 279d5671d8a7ff53477a6b9fb002d3f8d1b183a3 Mon Sep 17 00:00:00 2001 From: Nino van Hooff Date: Mon, 14 Oct 2019 12:14:31 +0200 Subject: [PATCH 09/26] Cleanup CustomPrintSetup.qml CURA-6862 --- .../PrintSetupSelector/Custom/CustomPrintSetup.qml | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml index b72341a4d6..cf27d6d023 100644 --- a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml @@ -91,7 +91,6 @@ Item text: qualityName() font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") - anchors.verticalCenter: intentSelection.verticalCenter Layout.margins: 0 Layout.maximumWidth: parent.width * 0.7 height: contentHeight @@ -110,7 +109,6 @@ Item text: activeQualityDetailText() font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_detail") - anchors.verticalCenter: intentSelection.verticalCenter Layout.margins: 0 Layout.fillWidth: true @@ -136,11 +134,7 @@ Item { if (resultSuffix) { - result += " - " - } - if (resultSuffix) - { - result += resultSuffix + result += " - " + resultSuffix } result += " - " result += Cura.MachineManager.activeQualityLayerHeight + "mm" @@ -150,10 +144,6 @@ Item return result } } - - - - } background: Rectangle From dd8f6dc10e7b9ab6d263d168ef389d1eed44b7f0 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 14 Oct 2019 12:22:15 +0200 Subject: [PATCH 10/26] Fix ContainerTree reacting to duplicating materials CURA-6863 --- cura/Machines/Models/MaterialManagementModel.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cura/Machines/Models/MaterialManagementModel.py b/cura/Machines/Models/MaterialManagementModel.py index b4f3bb9889..6f6f3906b8 100644 --- a/cura/Machines/Models/MaterialManagementModel.py +++ b/cura/Machines/Models/MaterialManagementModel.py @@ -128,6 +128,20 @@ class MaterialManagementModel(QObject): new_container.getMetaData().update(new_metadata) new_containers.append(new_container) + # CURA-6863: Nodes in ContainerTree will be updated upon ContainerAdded signals, one at a time. It will use the + # best fit material container at the time it sees one. For example, if you duplicate and get generic_pva #2, + # if the node update function sees the containers in the following order: + # + # - generic_pva #2 + # - generic_pva #2_um3_aa04 + # + # It will first use "generic_pva #2" because that's the best fit it has ever seen, and later "generic_pva #2_um3_aa04" + # once it sees that. Because things run in the Qt event loop, they don't happen at the same time. This means if + # between those two events, the ContainerTree will have nodes that contain invalid data. + # + # This sort fixes the problem by emitting the most specific containers first. + new_containers = sorted(new_containers, key = lambda x: x.getId(), reverse = True) + for container_to_add in new_containers: container_to_add.setDirty(True) container_registry.addContainer(container_to_add) From cc64fb0a936b250e37f96bc798d5ebadf6ef29b0 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 14 Oct 2019 14:15:03 +0200 Subject: [PATCH 11/26] Fix variant handling in VariantNode CURA-6863 --- cura/Machines/VariantNode.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cura/Machines/VariantNode.py b/cura/Machines/VariantNode.py index c1297651bd..ef8981a3c2 100644 --- a/cura/Machines/VariantNode.py +++ b/cura/Machines/VariantNode.py @@ -6,9 +6,13 @@ from UM.Logger import Logger from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.Interfaces import ContainerInterface from UM.Signal import Signal + +from cura.Settings.cura_empty_instance_containers import empty_variant_container from cura.Machines.ContainerNode import ContainerNode from cura.Machines.MaterialNode import MaterialNode + import UM.FlameProfiler + if TYPE_CHECKING: from typing import Dict from cura.Machines.MachineNode import MachineNode @@ -110,8 +114,8 @@ class VariantNode(ContainerNode): if base_file not in self.materials: # Completely new base file. Always better than not having a file as long as it matches our set-up. if material_definition != "fdmprinter" and material_definition != self.machine.container_id: return - material_variant = container.getMetaDataEntry("variant_name") - if material_variant is not None and material_variant != self.variant_name: + material_variant = container.getMetaDataEntry("variant_name", empty_variant_container.getName()) + if material_variant != self.variant_name: return else: # We already have this base profile. Replace the base profile if the new one is more specific. new_definition = container.getMetaDataEntry("definition") From 577365cf968a78767a8b45f843f924e8e221191a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 15 Oct 2019 08:19:32 +0200 Subject: [PATCH 12/26] Fx containerAdded handling in VariantNode CURA-6889 --- cura/Machines/VariantNode.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cura/Machines/VariantNode.py b/cura/Machines/VariantNode.py index 27e359afb1..efe15dbec2 100644 --- a/cura/Machines/VariantNode.py +++ b/cura/Machines/VariantNode.py @@ -101,6 +101,14 @@ class VariantNode(ContainerNode): def _materialAdded(self, container: ContainerInterface) -> None: if container.getMetaDataEntry("type") != "material": return # Not interested. + if not ContainerRegistry.getInstance().findContainersMetadata(id = container.getId()): + # CURA-6889 + # containerAdded and removed signals may be triggered in the next event cycle. If a container gets added + # and removed in the same event cycle, in the next cycle, the connections should just ignore the signals. + # The check here makes sure that the container in the signal still exists. + Logger.log("d", "Got container added signal for container [%s] but it no longer exists, do nothing.", + container.getId()) + return if not self.machine.has_materials: return # We won't add any materials. material_definition = container.getMetaDataEntry("definition") From 84080b675b7b5ac1377fc1ec287eb2bb59b75529 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 15 Oct 2019 08:29:53 +0200 Subject: [PATCH 13/26] Fix tests --- tests/Machines/TestVariantNode.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/Machines/TestVariantNode.py b/tests/Machines/TestVariantNode.py index 71257bd972..4e58069be3 100644 --- a/tests/Machines/TestVariantNode.py +++ b/tests/Machines/TestVariantNode.py @@ -104,10 +104,11 @@ def test_variantNodeInit_excludedMaterial(container_registry, machine_node): def test_materialAdded(container_registry, machine_node, metadata, material_result_list): variant_node = createVariantNode("machine_1", machine_node, container_registry) machine_node.exclude_materials = ["material_3"] - with patch("cura.Machines.VariantNode.MaterialNode"): # We're not testing the material node here, so patch it out. - with patch.dict(metadata_dict, metadata): - mocked_container = createMockedInstanceContainer() - variant_node._materialAdded(mocked_container) + with patch("UM.Settings.ContainerRegistry.ContainerRegistry.getInstance", MagicMock(return_value = container_registry)): + with patch("cura.Machines.VariantNode.MaterialNode"): # We're not testing the material node here, so patch it out. + with patch.dict(metadata_dict, metadata): + mocked_container = createMockedInstanceContainer() + variant_node._materialAdded(mocked_container) assert len(material_result_list) == len(variant_node.materials) for name in material_result_list: From ca21268a121f2d26312156e287d3a3b2874ab031 Mon Sep 17 00:00:00 2001 From: Nino van Hooff Date: Tue, 15 Oct 2019 10:26:52 +0200 Subject: [PATCH 14/26] Elide the profile text in the middle for the PrintSetupSelector. This makes sure that at least some part of the name and some part of the variant details (qualityy, diameter) is visible CURA-6862 --- resources/qml/IconWithText.qml | 1 + resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml | 1 + 2 files changed, 2 insertions(+) diff --git a/resources/qml/IconWithText.qml b/resources/qml/IconWithText.qml index 24b6dc7fe2..b9fe873b25 100644 --- a/resources/qml/IconWithText.qml +++ b/resources/qml/IconWithText.qml @@ -19,6 +19,7 @@ Item property alias color: label.color property alias text: label.text property alias font: label.font + property alias elide: label.elide property real margin: UM.Theme.getSize("narrow_margin").width // These properties can be used in combination with layouts. diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml index a23b87fdbe..1a15980693 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml @@ -37,6 +37,7 @@ RowLayout return "" } font: UM.Theme.getFont("medium") + elide: Text.ElideMiddle UM.SettingPropertyProvider { From 71701f15cf9c271d9f77a2055e710fc4417cb503 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Tue, 15 Oct 2019 11:38:51 +0200 Subject: [PATCH 15/26] Remove function to reintroduce binding. Also force max width to integer value and comment why there is a plain value like 0.7 in the code. part of CURA-6862 --- .../qml/PrintSetupSelector/Custom/CustomPrintSetup.qml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml index cf27d6d023..b559aa711c 100644 --- a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml @@ -88,20 +88,15 @@ Item Label { id: textLabel - text: qualityName() + text: Cura.MachineManager.activeQualityDisplayNameMap["main"] font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") Layout.margins: 0 - Layout.maximumWidth: parent.width * 0.7 + Layout.maximumWidth: Math.floor(parent.width * 0.7) // Always leave >= 30% for the rest of the row. height: contentHeight verticalAlignment: Text.AlignVCenter renderType: Text.NativeRendering elide: Text.ElideRight - - function qualityName() { - var resultMap = Cura.MachineManager.activeQualityDisplayNameMap - return resultMap["main"] - } } Label From 36aab5d56bda56a7edb3c1ea4156a693f33d7f26 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 15 Oct 2019 13:04:20 +0200 Subject: [PATCH 16/26] Fix removeMaterials() and optimization CURA-6886 --- .../Models/MaterialManagementModel.py | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/cura/Machines/Models/MaterialManagementModel.py b/cura/Machines/Models/MaterialManagementModel.py index b4f3bb9889..a494e35c89 100644 --- a/cura/Machines/Models/MaterialManagementModel.py +++ b/cura/Machines/Models/MaterialManagementModel.py @@ -8,6 +8,7 @@ import uuid # To generate new GUIDs for new materials. from UM.i18n import i18nCatalog from UM.Logger import Logger +from UM.Signal import postponeSignals, CompressTechnique import cura.CuraApplication # Imported like this to prevent circular imports. from cura.Machines.ContainerTree import ContainerTree @@ -73,8 +74,20 @@ class MaterialManagementModel(QObject): def removeMaterial(self, material_node: "MaterialNode") -> None: container_registry = CuraContainerRegistry.getInstance() materials_this_base_file = container_registry.findContainersMetadata(base_file = material_node.base_file) - for material_metadata in materials_this_base_file: - container_registry.removeContainer(material_metadata["id"]) + + # The material containers belonging to the same material file are supposed to work together. This postponeSignals() + # does two things: + # - optimizing the signal emitting. + # - making sure that the signals will only be emitted after all the material containers have been removed. + with postponeSignals(container_registry.containerRemoved, compress = CompressTechnique.CompressPerParameterValue): + # CURA-6886: Some containers may not have been loaded. If remove one material container, its material file + # will be removed. If later we remove a sub-material container which hasn't been loaded previously, it will + # crash because removeContainer() requires to load the container first, but the material file was already + # gone. + for material_metadata in materials_this_base_file: + container_registry.findInstanceContainers(id = material_metadata["id"]) + for material_metadata in materials_this_base_file: + container_registry.removeContainer(material_metadata["id"]) ## Creates a duplicate of a material with the same GUID and base_file # metadata. @@ -128,15 +141,17 @@ class MaterialManagementModel(QObject): new_container.getMetaData().update(new_metadata) new_containers.append(new_container) - for container_to_add in new_containers: - container_to_add.setDirty(True) - container_registry.addContainer(container_to_add) + # Optimization. Serving the same purpose as the postponeSignals() in removeMaterial() + with postponeSignals(container_registry.containerAdded, compress=CompressTechnique.CompressPerParameterValue): + for container_to_add in new_containers: + container_to_add.setDirty(True) + container_registry.addContainer(container_to_add) - # If the duplicated material was favorite then the new material should also be added to the favorites. - favorites_set = set(application.getPreferences().getValue("cura/favorite_materials").split(";")) - if base_file in favorites_set: - favorites_set.add(new_base_id) - application.getPreferences().setValue("cura/favorite_materials", ";".join(favorites_set)) + # If the duplicated material was favorite then the new material should also be added to the favorites. + favorites_set = set(application.getPreferences().getValue("cura/favorite_materials").split(";")) + if base_file in favorites_set: + favorites_set.add(new_base_id) + application.getPreferences().setValue("cura/favorite_materials", ";".join(favorites_set)) return new_base_id From e5450a449cd32f98387082ddc4aac31a0a4890a2 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 15 Oct 2019 13:27:29 +0200 Subject: [PATCH 17/26] IntentManager should take into account disabled extruders CURA-6891 --- cura/Settings/IntentManager.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cura/Settings/IntentManager.py b/cura/Settings/IntentManager.py index 9f9d174ffa..c1d59fb84a 100644 --- a/cura/Settings/IntentManager.py +++ b/cura/Settings/IntentManager.py @@ -78,6 +78,8 @@ class IntentManager(QObject): final_intent_ids = set() # type: Set[str] current_definition_id = global_stack.definition.getId() for extruder_stack in global_stack.extruderList: + if not extruder_stack.isEnabled: + continue nozzle_name = extruder_stack.variant.getMetaDataEntry("name") material_id = extruder_stack.material.getMetaDataEntry("base_file") final_intent_ids |= {metadata["id"] for metadata in self.intentMetadatas(current_definition_id, nozzle_name, material_id) if metadata.get("quality_type") in available_quality_types} @@ -104,6 +106,8 @@ class IntentManager(QObject): current_definition_id = global_stack.definition.getId() final_intent_categories = set() # type: Set[str] for extruder_stack in global_stack.extruderList: + if not extruder_stack.isEnabled: + continue nozzle_name = extruder_stack.variant.getMetaDataEntry("name") material_id = extruder_stack.material.getMetaDataEntry("base_file") final_intent_categories.update(self.intentCategories(current_definition_id, nozzle_name, material_id)) From fe8b7a48e6c4e7d4dc05d21f417a9968bef73cb3 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 15 Oct 2019 14:22:38 +0200 Subject: [PATCH 18/26] Fix QualityManagementModel update CURA-6883 --- cura/Machines/Models/QualityManagementModel.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cura/Machines/Models/QualityManagementModel.py b/cura/Machines/Models/QualityManagementModel.py index 1d30b1753e..d5a35d8eab 100644 --- a/cura/Machines/Models/QualityManagementModel.py +++ b/cura/Machines/Models/QualityManagementModel.py @@ -54,6 +54,10 @@ class QualityManagementModel(ListModel): self._extruder_manager = application.getExtruderManager() self._machine_manager.globalContainerChanged.connect(self._update) + self._machine_manager.activeQualityGroupChanged.connect(self._update) + self._machine_manager.activeStackChanged.connect(self._update) + self._machine_manager.extruderChanged.connect(self._update) + container_registry.containerAdded.connect(self._qualityChangesListChanged) container_registry.containerRemoved.connect(self._qualityChangesListChanged) container_registry.containerMetaDataChanged.connect(self._qualityChangesListChanged) From 845cab557317f5bc200c2b16e786634566839c3e Mon Sep 17 00:00:00 2001 From: Nino van Hooff Date: Tue, 15 Oct 2019 14:37:37 +0200 Subject: [PATCH 19/26] Clarified comment for duplicating materials --- cura/Machines/Models/MaterialManagementModel.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/Machines/Models/MaterialManagementModel.py b/cura/Machines/Models/MaterialManagementModel.py index a494e35c89..8a143f46b2 100644 --- a/cura/Machines/Models/MaterialManagementModel.py +++ b/cura/Machines/Models/MaterialManagementModel.py @@ -141,7 +141,8 @@ class MaterialManagementModel(QObject): new_container.getMetaData().update(new_metadata) new_containers.append(new_container) - # Optimization. Serving the same purpose as the postponeSignals() in removeMaterial() + # postpone the signals emitted when duplicating materials. This is easier on the event loop; changes the + # behavior to be like a transaction. Prevents concurrency issues. with postponeSignals(container_registry.containerAdded, compress=CompressTechnique.CompressPerParameterValue): for container_to_add in new_containers: container_to_add.setDirty(True) From 59fa73448a8a7551405ac4676b75a7c30ff15576 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 15 Oct 2019 14:06:30 +0200 Subject: [PATCH 20/26] Fix material diameter change CURA-6868 --- cura/Settings/MachineManager.py | 10 +++++----- resources/qml/Preferences/Materials/MaterialsView.qml | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index dec433e8f8..35f3268cce 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1322,7 +1322,8 @@ class MachineManager(QObject): # changed. # \param position The extruder stack to update. If provided with None, all # extruder stacks will be updated. - def updateMaterialWithVariant(self, position: Optional[str]) -> None: + @pyqtSlot() + def updateMaterialWithVariant(self, position: Optional[str] = None) -> None: if self._global_container_stack is None: return if position is None: @@ -1353,10 +1354,9 @@ class MachineManager(QObject): self._setMaterial(position_item, new_material) else: # The current material is not available, find the preferred one. - if position is not None: - approximate_material_diameter = int(self._global_container_stack.extruderList[int(position_item)].getApproximateMaterialDiameter()) - material_node = nozzle_node.preferredMaterial(approximate_material_diameter) - self._setMaterial(position_item, material_node) + approximate_material_diameter = int(self._global_container_stack.extruderList[int(position_item)].getApproximateMaterialDiameter()) + material_node = nozzle_node.preferredMaterial(approximate_material_diameter) + self._setMaterial(position_item, material_node) ## Given a printer definition name, select the right machine instance. In case it doesn't exist, create a new # instance with the same network key. diff --git a/resources/qml/Preferences/Materials/MaterialsView.qml b/resources/qml/Preferences/Materials/MaterialsView.qml index 6d5a8119c5..8a5ec79d53 100644 --- a/resources/qml/Preferences/Materials/MaterialsView.qml +++ b/resources/qml/Preferences/Materials/MaterialsView.qml @@ -111,6 +111,8 @@ TabView { base.setMetaDataEntry("approximate_diameter", old_approximate_diameter_value, getApproximateDiameter(new_diameter_value).toString()); base.setMetaDataEntry("properties/diameter", properties.diameter, new_diameter_value); + // CURA-6868 Make sure to update the extruder to user a diameter-compatible material. + Cura.MachineManager.updateMaterialWithVariant() base.resetSelectedMaterial() } From c875252b53443d18ccd14dbe747e8561fb58c637 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 15 Oct 2019 13:24:09 +0200 Subject: [PATCH 21/26] Fix some mistakes indicated by PyCharm's linting --- plugins/PostProcessingPlugin/scripts/PauseAtHeight.py | 6 ++++-- plugins/USBPrinting/USBPrinterOutputDevice.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py b/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py index 3a25b7781a..499214a0e9 100644 --- a/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py +++ b/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py @@ -162,6 +162,8 @@ class PauseAtHeight(Script): # use offset to calculate the current height: = - layer_0_z = 0 current_z = 0 + current_height = 0 + current_layer = 0 current_extrusion_f = 0 got_first_g_cmd_on_layer_0 = False current_t = 0 #Tracks the current extruder for tracking the target temperature. @@ -263,8 +265,8 @@ class PauseAtHeight(Script): # the nozzle) x, y = self.getNextXY(layer) prev_lines = prev_layer.split("\n") - for line in prev_lines: - new_e = self.getValue(line, 'E', current_e) + for lin in prev_lines: + new_e = self.getValue(lin, "E", current_e) if new_e != current_e: current_e = new_e break diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index e32e4c8745..4930835f58 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -328,7 +328,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice): def _setFirmwareName(self, name): new_name = re.findall(r"FIRMWARE_NAME:(.*);", str(name)) - if new_name: + if new_name: self._firmware_name = new_name[0] Logger.log("i", "USB output device Firmware name: %s", self._firmware_name) else: From f93f26444b181ec520ae7918cfcf0e68272a579a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 15 Oct 2019 15:33:41 +0200 Subject: [PATCH 22/26] Revert "Fix QualityManagementModel update" This reverts commit fe8b7a48e6c4e7d4dc05d21f417a9968bef73cb3. This commit caused Cura to crash when creating a custom quality profile. Contributes to issue CURA-6883. --- cura/Machines/Models/QualityManagementModel.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cura/Machines/Models/QualityManagementModel.py b/cura/Machines/Models/QualityManagementModel.py index d5a35d8eab..1d30b1753e 100644 --- a/cura/Machines/Models/QualityManagementModel.py +++ b/cura/Machines/Models/QualityManagementModel.py @@ -54,10 +54,6 @@ class QualityManagementModel(ListModel): self._extruder_manager = application.getExtruderManager() self._machine_manager.globalContainerChanged.connect(self._update) - self._machine_manager.activeQualityGroupChanged.connect(self._update) - self._machine_manager.activeStackChanged.connect(self._update) - self._machine_manager.extruderChanged.connect(self._update) - container_registry.containerAdded.connect(self._qualityChangesListChanged) container_registry.containerRemoved.connect(self._qualityChangesListChanged) container_registry.containerMetaDataChanged.connect(self._qualityChangesListChanged) From d350c9e3d9e4991b656226ed11c26010e31608a4 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 15 Oct 2019 15:34:14 +0200 Subject: [PATCH 23/26] Update quality and intent models when extruders get changed CURA-6894 --- cura/Machines/Models/IntentCategoryModel.py | 12 +++++++++++- .../Models/QualityProfilesDropDownMenuModel.py | 3 +++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/cura/Machines/Models/IntentCategoryModel.py b/cura/Machines/Models/IntentCategoryModel.py index c436f94421..d7d1ee2710 100644 --- a/cura/Machines/Models/IntentCategoryModel.py +++ b/cura/Machines/Models/IntentCategoryModel.py @@ -46,9 +46,19 @@ class IntentCategoryModel(ListModel): self.addRoleName(self.WeightRole, "weight") self.addRoleName(self.QualitiesRole, "qualities") + application = cura.CuraApplication.CuraApplication.getInstance() + ContainerRegistry.getInstance().containerAdded.connect(self._onContainerChange) ContainerRegistry.getInstance().containerRemoved.connect(self._onContainerChange) - cura.CuraApplication.CuraApplication.getInstance().getMachineManager().activeStackChanged.connect(self.update) + + machine_manager = application.getMachineManager() + machine_manager.globalContainerChanged.connect(self.update) + machine_manager.activeQualityGroupChanged.connect(self.update) + machine_manager.activeStackChanged.connect(self.update) + machine_manager.extruderChanged.connect(self.update) + + extruder_manager = application.getExtruderManager() + extruder_manager.extrudersChanged.connect(self.update) self.update() diff --git a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py index 9bf1cc08a8..92ea0c205f 100644 --- a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py +++ b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py @@ -43,6 +43,9 @@ class QualityProfilesDropDownMenuModel(ListModel): machine_manager.activeStackChanged.connect(self._onChange) machine_manager.extruderChanged.connect(self._onChange) + extruder_manager = application.getExtruderManager() + extruder_manager.extrudersChanged.connect(self._onChange) + self._layer_height_unit = "" # This is cached self._update_timer = QTimer() # type: QTimer From ae6f0eb77e555c62e1c71253582e373b1c3c8dfe Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 15 Oct 2019 15:53:27 +0200 Subject: [PATCH 24/26] Re-fix quality model update CURA-6883 --- .../Machines/Models/QualityManagementModel.py | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/cura/Machines/Models/QualityManagementModel.py b/cura/Machines/Models/QualityManagementModel.py index 1d30b1753e..3b503edcf0 100644 --- a/cura/Machines/Models/QualityManagementModel.py +++ b/cura/Machines/Models/QualityManagementModel.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. from typing import Any, cast, Dict, Optional, TYPE_CHECKING -from PyQt5.QtCore import pyqtSlot, QObject, Qt +from PyQt5.QtCore import pyqtSlot, QObject, Qt, QTimer from UM.Logger import Logger from UM.Qt.ListModel import ListModel @@ -51,14 +51,27 @@ class QualityManagementModel(ListModel): application = cura.CuraApplication.CuraApplication.getInstance() container_registry = application.getContainerRegistry() self._machine_manager = application.getMachineManager() - self._extruder_manager = application.getExtruderManager() + self._machine_manager.activeQualityGroupChanged.connect(self._onChange) + self._machine_manager.activeStackChanged.connect(self._onChange) + self._machine_manager.extruderChanged.connect(self._onChange) + self._machine_manager.globalContainerChanged.connect(self._onChange) + + self._extruder_manager = application.getExtruderManager() + self._extruder_manager.extrudersChanged.connect(self._onChange) - self._machine_manager.globalContainerChanged.connect(self._update) container_registry.containerAdded.connect(self._qualityChangesListChanged) container_registry.containerRemoved.connect(self._qualityChangesListChanged) container_registry.containerMetaDataChanged.connect(self._qualityChangesListChanged) - self._update() + self._update_timer = QTimer() + self._update_timer.setInterval(100) + self._update_timer.setSingleShot(True) + self._update_timer.timeout.connect(self._update) + + self._onChange() + + def _onChange(self) -> None: + self._update_timer.start() ## Deletes a custom profile. It will be gone forever. # \param quality_changes_group The quality changes group representing the From ac8a7d4aeb65fe93c5984dfeb9e8405ead34cc76 Mon Sep 17 00:00:00 2001 From: Nino van Hooff Date: Wed, 16 Oct 2019 09:44:09 +0200 Subject: [PATCH 25/26] Add whitespace between plugin name and licence string in license dialog --- plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml b/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml index 40b22c268d..f7edde1fff 100644 --- a/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml +++ b/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml @@ -30,7 +30,7 @@ UM.Dialog anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - text: licenseDialog.pluginName + catalog.i18nc("@label", "This plugin contains a license.\nYou need to accept this license to install this plugin.\nDo you agree with the terms below?") + text: licenseDialog.pluginName + ": " + catalog.i18nc("@label", "This plugin contains a license.\nYou need to accept this license to install this plugin.\nDo you agree with the terms below?") wrapMode: Text.Wrap renderType: Text.NativeRendering } From 86ff7443cfc5643e3dfc2ad036ca7d838862bf7d Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 16 Oct 2019 10:21:48 +0200 Subject: [PATCH 26/26] Fix QML undefined errors --- resources/qml/Menus/MaterialMenu.qml | 18 +++++++++++++++--- resources/qml/Menus/NozzleMenu.qml | 8 ++++++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/resources/qml/Menus/MaterialMenu.qml b/resources/qml/Menus/MaterialMenu.qml index 9720c81879..edc5ee1e0d 100644 --- a/resources/qml/Menus/MaterialMenu.qml +++ b/resources/qml/Menus/MaterialMenu.qml @@ -14,7 +14,11 @@ Menu property int extruderIndex: 0 property string currentRootMaterialId: Cura.MachineManager.currentRootMaterialId[extruderIndex] - property string activeMaterialId: Cura.MachineManager.activeMachine.extruderList[extruderIndex].material.id + property string activeMaterialId: + { + var extruder = Cura.MachineManager.activeMachine.extruderList[extruderIndex] + return (extruder === undefined) ? "" : extruder.material.id + } property bool updateModels: true Cura.FavoriteMaterialsModel { @@ -73,7 +77,11 @@ Menu { text: model.name checkable: true - enabled: Cura.MachineManager.activeMachine.extruderList[extruderIndex].isEnabled + enabled: + { + var extruder = Cura.MachineManager.activeMachine.extruderList[extruderIndex] + return (extruder === undefined) ? false : extruder.isEnabled + } checked: model.root_material_id === menu.currentRootMaterialId exclusiveGroup: group onTriggered: Cura.MachineManager.setMaterial(extruderIndex, model.container_node) @@ -112,7 +120,11 @@ Menu { text: model.name checkable: true - enabled: Cura.MachineManager.activeMachine.extruderList[extruderIndex].isEnabled + enabled: + { + var extruder = Cura.MachineManager.activeMachine.extruderList[extruderIndex] + return (extruder === undefined) ? false : extruder.isEnabled + } checked: model.id === menu.activeMaterialId exclusiveGroup: group onTriggered: Cura.MachineManager.setMaterial(extruderIndex, model.container_node) diff --git a/resources/qml/Menus/NozzleMenu.qml b/resources/qml/Menus/NozzleMenu.qml index a291f125eb..2734e40489 100644 --- a/resources/qml/Menus/NozzleMenu.qml +++ b/resources/qml/Menus/NozzleMenu.qml @@ -29,10 +29,14 @@ Menu checkable: true checked: { var extruder = Cura.MachineManager.activeMachine.extruderList[extruderIndex] - return extruder.variant.name == model.hotend_name + return (extruder === undefined) ? false : (extruder.variant.name == model.hotend_name) } exclusiveGroup: group - enabled: Cura.MachineManager.activeMachine.extruderList[extruderIndex].isEnabled + enabled: + { + var extruder = Cura.MachineManager.activeMachine.extruderList[extruderIndex] + return (extruder === undefined) ? false : extruder.isEnabled + } onTriggered: { Cura.MachineManager.setVariant(menu.extruderIndex, model.container_node); }