From 4c4e611629cba873d795b84159860de4c7bc7e07 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Wed, 29 Apr 2020 12:06:20 +0200 Subject: [PATCH 1/8] Fix x-ray error color. X-ray errors showed as green and translucent instead of read and solid. Now fixed. CURA-7407 --- plugins/SolidView/SolidView.py | 1 + plugins/XRayView/XRayView.py | 1 + resources/shaders/xray_composite.shader | 7 +++++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 09d27859b5..bfe803f224 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -149,6 +149,7 @@ class SolidView(View): theme = Application.getInstance().getTheme() self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb())) self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) + self._xray_composite_shader.setUniformValue("u_flat_error_color_mix", 0.) # Don't show flat error color in solid-view. renderer = self.getRenderer() if not self._composite_pass or not 'xray' in self._composite_pass.getLayerBindings(): diff --git a/plugins/XRayView/XRayView.py b/plugins/XRayView/XRayView.py index e12bd9b9ea..0144f4c176 100644 --- a/plugins/XRayView/XRayView.py +++ b/plugins/XRayView/XRayView.py @@ -93,6 +93,7 @@ class XRayView(CuraView): theme = Application.getInstance().getTheme() self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb())) self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) + self._xray_composite_shader.setUniformValue("u_flat_error_color_mix", 1.) # Show flat error color _only_ in xray-view. if not self._composite_pass: self._composite_pass = self.getRenderer().getRenderPass("composite") diff --git a/resources/shaders/xray_composite.shader b/resources/shaders/xray_composite.shader index c955d4fc18..6619b00544 100644 --- a/resources/shaders/xray_composite.shader +++ b/resources/shaders/xray_composite.shader @@ -30,6 +30,7 @@ fragment = uniform vec4 u_outline_color; uniform vec4 u_background_color; uniform float u_xray_error_strength; + uniform float u_flat_error_color_mix; const vec3 x_axis = vec3(1.0, 0.0, 0.0); const vec3 y_axis = vec3(0.0, 1.0, 0.0); @@ -73,7 +74,7 @@ fragment = float rest = mod(intersection_count + .01, 2.0); if (rest > 1.0 && rest < 1.5 && intersection_count < 49.0) { - result = vec4(shiftHue(layer0.rgb, hue_shift), result.a); + result = mix(vec4(shiftHue(layer0.rgb, hue_shift), result.a), vec4(1.,0.,0.,1.), u_flat_error_color_mix); } vec4 sum = vec4(0.0); @@ -122,6 +123,7 @@ fragment41core = uniform vec4 u_outline_color; uniform vec4 u_background_color; uniform float u_xray_error_strength; + uniform float u_flat_error_color_mix; const vec3 x_axis = vec3(1.0, 0.0, 0.0); const vec3 y_axis = vec3(0.0, 1.0, 0.0); @@ -166,7 +168,7 @@ fragment41core = float rest = mod(intersection_count + .01, 2.0); if (rest > 1.0 && rest < 1.5 && intersection_count < 49) { - result = vec4(shiftHue(layer0.rgb, hue_shift), result.a); + result = mix(vec4(shiftHue(layer0.rgb, hue_shift), result.a), vec4(1.,0.,0.,1.), u_flat_error_color_mix); } vec4 sum = vec4(0.0); @@ -196,6 +198,7 @@ u_layer2 = 2 u_background_color = [0.965, 0.965, 0.965, 1.0] u_outline_strength = 1.0 u_outline_color = [0.05, 0.66, 0.89, 1.0] +u_flat_error_color_mix = 0.5 [bindings] From 3604e75cce1eca8d150cbfa843a7f8d0083894f1 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Wed, 29 Apr 2020 13:02:48 +0200 Subject: [PATCH 2/8] CURA-7409 Update keep/discard dialog. --- .../qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml b/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml index a7701cf059..294a2474d6 100644 --- a/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml +++ b/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml @@ -113,14 +113,14 @@ UM.Dialog TableViewColumn { role: "original_value" - title: catalog.i18nc("@title:column", "Default") + title: Cura.MachineManager.activeQualityDisplayNameMap["main"] width: (tableView.width * 0.3) | 0 delegate: defaultDelegate } TableViewColumn { role: "user_value" - title: catalog.i18nc("@title:column", "Customized") + title: catalog.i18nc("@title:column", "Current changes") width: (tableView.width * 0.3) | 0 } section.property: "category" @@ -192,7 +192,7 @@ UM.Dialog Button { id: discardButton - text: catalog.i18nc("@action:button", "Discard"); + text: catalog.i18nc("@action:button", "Discard changes"); anchors.right: parent.right onClicked: { @@ -205,7 +205,7 @@ UM.Dialog Button { id: keepButton - text: catalog.i18nc("@action:button", "Keep"); + text: catalog.i18nc("@action:button", "Keep changes"); anchors.right: discardButton.left anchors.rightMargin: UM.Theme.getSize("default_margin").width onClicked: From 084e80bcda30dd62873966a50f9998672e92d367 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 29 Apr 2020 13:48:06 +0200 Subject: [PATCH 3/8] Only connect a cloud printer if it's the active one By splitting up the correctly setting of metadata and actually connecting, the distinction can be made. CURA-7055 --- .../src/Cloud/CloudOutputDeviceManager.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 65625df3bc..cae585ffa4 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -226,11 +226,11 @@ class CloudOutputDeviceManager: return new_machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key) + self._setOutputDeviceMetadata(device, new_machine) + if activate: CuraApplication.getInstance().getMachineManager().setActiveMachine(new_machine.getId()) - self._connectToOutputDevice(device, new_machine) - def _connectToActiveMachine(self) -> None: """Callback for when the active machine was changed by the user""" @@ -252,14 +252,17 @@ class CloudOutputDeviceManager: # Remove device if it is not meant for the active machine. output_device_manager.removeOutputDevice(device.key) - def _connectToOutputDevice(self, device: CloudOutputDevice, machine: GlobalStack) -> None: - """Connects to an output device and makes sure it is registered in the output device manager.""" - + def _setOutputDeviceMetadata(self, device: CloudOutputDevice, machine: GlobalStack): machine.setName(device.name) machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key) machine.setMetaDataEntry("group_name", device.name) machine.addConfiguredConnectionType(device.connectionType.value) + def _connectToOutputDevice(self, device: CloudOutputDevice, machine: GlobalStack) -> None: + """Connects to an output device and makes sure it is registered in the output device manager.""" + + self._setOutputDeviceMetadata(device, machine) + if not device.isConnected(): device.connect() From bf3d6c67d9001f02711ca7e7b45a1e848d53eb4e Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 29 Apr 2020 11:59:50 +0200 Subject: [PATCH 4/8] Check the bounding box before using it Some objects don't have a bounding box if they are improperly constructed by a plug-in. Fixes Sentry issue CURA-N3. --- plugins/ModelChecker/ModelChecker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/ModelChecker/ModelChecker.py b/plugins/ModelChecker/ModelChecker.py index 5472a96809..057ee14945 100644 --- a/plugins/ModelChecker/ModelChecker.py +++ b/plugins/ModelChecker/ModelChecker.py @@ -86,7 +86,7 @@ class ModelChecker(QObject, Extension): if material_shrinkage[node_extruder_position] > shrinkage_threshold: bbox = node.getBoundingBox() - if bbox.width >= warning_size_xy or bbox.depth >= warning_size_xy or bbox.height >= warning_size_z: + if bbox is not None and (bbox.width >= warning_size_xy or bbox.depth >= warning_size_xy or bbox.height >= warning_size_z): warning_nodes.append(node) self._caution_message.setText(catalog.i18nc( From dcac9b6a876656ccdc01718f95f319a69ecbfc3b Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 29 Apr 2020 13:52:29 +0200 Subject: [PATCH 5/8] Prevent a crash when retrying even though it completed in the meanwhile Fixes Sentry issue CURA-NA. --- plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py b/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py index d5de7fe10a..6aa341c0e5 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py @@ -125,7 +125,10 @@ class ToolPathUploader: if self._retries < self.MAX_RETRIES and status_code in self.RETRY_HTTP_CODES: self._retries += 1 Logger.log("i", "Retrying %s/%s request %s", self._retries, self.MAX_RETRIES, reply.url().toString()) - self._uploadChunk() + try: + self._uploadChunk() + except ValueError: # Asynchronously it could have completed in the meanwhile. + pass return # Http codes that are not to be retried are assumed to be errors. From abffb6c26ce5c47b896d34ab434ad3cd831f11be Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 29 Apr 2020 14:03:50 +0200 Subject: [PATCH 6/8] Don't crash when reading corrupt 3MF files Otherwise it would crash with a BadZipFile error. We should be robust against that. This will trigger a generic message that we couldn't read that file to the user, and put more information in the log. Fixes Sentry issue CURA-NH. --- plugins/3MFReader/ThreeMFWorkspaceReader.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index 82b73c66d9..f3c5a07f82 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -738,11 +738,15 @@ class ThreeMFWorkspaceReader(WorkspaceReader): @staticmethod def _loadMetadata(file_name: str) -> Dict[str, Dict[str, Any]]: - archive = zipfile.ZipFile(file_name, "r") + result = dict() + try: + archive = zipfile.ZipFile(file_name, "r") + except zipfile.BadZipFile: + Logger.logException("w", "Unable to retrieve metadata from {fname}: 3MF archive is corrupt.".format(fname = file_name)) + return result metadata_files = [name for name in archive.namelist() if name.endswith("plugin_metadata.json")] - result = dict() for metadata_file in metadata_files: try: From dfa021ab205faa6e2257f6c8bd49c7ef6ce6fa5d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 29 Apr 2020 14:10:07 +0200 Subject: [PATCH 7/8] Fix upgrade of preference if visible settings was not modified Oops. Small oversight. This could lead to the preferences file being erased completely. Found during work on Sentry issue CURA-NH. --- .../VersionUpgrade45to46/VersionUpgrade45to46.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade45to46/VersionUpgrade45to46.py b/plugins/VersionUpgrade/VersionUpgrade45to46/VersionUpgrade45to46.py index f62264c3e7..a399c79535 100644 --- a/plugins/VersionUpgrade/VersionUpgrade45to46/VersionUpgrade45to46.py +++ b/plugins/VersionUpgrade/VersionUpgrade45to46/VersionUpgrade45to46.py @@ -29,11 +29,12 @@ class VersionUpgrade45to46(VersionUpgrade): parser["metadata"]["setting_version"] = "12" # Remove deleted settings from the visible settings list. - visible_settings = set(parser["general"]["visible_settings"].split(";")) - for removed in _removed_settings: - if removed in visible_settings: - visible_settings.remove(removed) - parser["general"]["visible_settings"] = ";".join(visible_settings) + if "general" in parser and "visible_settings" in parser["general"]: + visible_settings = set(parser["general"]["visible_settings"].split(";")) + for removed in _removed_settings: + if removed in visible_settings: + visible_settings.remove(removed) + parser["general"]["visible_settings"] = ";".join(visible_settings) result = io.StringIO() parser.write(result) From 61e2cc1193623347367009f67efb8a5deef9fca4 Mon Sep 17 00:00:00 2001 From: Kostas Karmas Date: Wed, 29 Apr 2020 15:33:28 +0200 Subject: [PATCH 8/8] Fix missing type for result --- plugins/3MFReader/ThreeMFWorkspaceReader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index f3c5a07f82..74589b8335 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -738,7 +738,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader): @staticmethod def _loadMetadata(file_name: str) -> Dict[str, Dict[str, Any]]: - result = dict() + result = dict() # type: Dict[str, Dict[str, Any]] try: archive = zipfile.ZipFile(file_name, "r") except zipfile.BadZipFile: