From 87555a38c42ca343afccf8c09ff06cd1407ddb54 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 25 May 2018 21:40:30 +0200 Subject: [PATCH 01/44] Fix text rendering in the ConfigurationMenu --- resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 1 + .../qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index be8c8bcb45..6f0130d5ca 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -92,6 +92,7 @@ Rectangle anchors.verticalCenter: buildplateIcon.verticalCenter anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").height / 2) text: configuration.buildplateConfiguration + renderType: Text.NativeRendering color: textColor } } diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml index ca1b666e69..97b5bee745 100644 --- a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -26,6 +26,7 @@ Column { id: extruderLabel text: catalog.i18nc("@label:extruder label", "Extruder") + renderType: Text.NativeRendering elide: Text.ElideRight anchors.left: parent.left font: UM.Theme.getFont("default") @@ -59,6 +60,7 @@ Column id: extruderNumberText anchors.centerIn: parent text: printCoreConfiguration.position + 1 + renderType: Text.NativeRendering font: UM.Theme.getFont("default") color: mainColor } @@ -69,6 +71,7 @@ Column { id: materialLabel text: printCoreConfiguration.material.name + renderType: Text.NativeRendering elide: Text.ElideRight width: parent.width font: UM.Theme.getFont("default_bold") @@ -79,6 +82,7 @@ Column { id: printCoreTypeLabel text: printCoreConfiguration.hotendID + renderType: Text.NativeRendering elide: Text.ElideRight width: parent.width font: UM.Theme.getFont("default") From 94813d9e0d10076f6b13a779cb48e1e570670ebb Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 25 May 2018 21:40:57 +0200 Subject: [PATCH 02/44] Fix untranslatable text --- resources/qml/Menus/ConfigurationMenu/SyncButton.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml index 078acb65b2..3099d684c1 100644 --- a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml +++ b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml @@ -13,7 +13,7 @@ Button id: base property var outputDevice: null property var matched: updateOnSync() - text: matched == true ? "Yes" : "No" + text: matched == true ? catalog.i18nc("@label:extruder label", "Yes") : catalog.i18nc("@label:extruder label", "No") width: parent.width height: parent.height From ac1dfcf15d913ed25a582d82e34921d4322145da Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 28 May 2018 22:52:49 +0200 Subject: [PATCH 03/44] Make headers non-transparent --- plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml b/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml index 229ab5afb3..b4219d53bf 100644 --- a/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml +++ b/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml @@ -31,8 +31,9 @@ Item frameVisible: false selectionMode: 0 model: packageData.supported_configs - headerDelegate: Item + headerDelegate: Rectangle { + color: UM.Theme.getColor("sidebar") height: UM.Theme.getSize("toolbox_chart_row").height Label { From 8a6996e920d6dde3a98fddf4a80ee078a24db385 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 29 May 2018 09:32:06 +0200 Subject: [PATCH 04/44] If an object does not have a convex hull, it does not crash the ArrangeObjectsJob --- cura/Arranging/ArrangeObjectsJob.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cura/Arranging/ArrangeObjectsJob.py b/cura/Arranging/ArrangeObjectsJob.py index 01a91a3c22..08fd1985a9 100644 --- a/cura/Arranging/ArrangeObjectsJob.py +++ b/cura/Arranging/ArrangeObjectsJob.py @@ -43,6 +43,9 @@ class ArrangeObjectsJob(Job): nodes_arr = [] # fill with (size, node, offset_shape_arr, hull_shape_arr) for node in self._nodes: offset_shape_arr, hull_shape_arr = ShapeArray.fromNode(node, min_offset = self._min_offset) + if offset_shape_arr is None: + Logger.log("w", "Node [%s] could not be converted to an array for arranging...", str(node)) + continue nodes_arr.append((offset_shape_arr.arr.shape[0] * offset_shape_arr.arr.shape[1], node, offset_shape_arr, hull_shape_arr)) # Sort the nodes with the biggest area first. From 9627eb0fc101616d94073450a0e31b3c309af021 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 29 May 2018 10:45:44 +0200 Subject: [PATCH 05/44] Only exclude explicitly specified materials in the "exclude_materials" field CURA-5344 --- cura/Machines/MaterialManager.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 8b74596667..ff666f392d 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -291,9 +291,10 @@ class MaterialManager(QObject): material_id_metadata_dict = dict() for node in nodes_to_check: if node is not None: + # Only exclude the materials that are explicitly specified in the "exclude_materials" field. + # Do not exclude other materials that are of the same type. for material_id, node in node.material_map.items(): - fallback_id = self.getFallbackMaterialIdByMaterialType(node.metadata["material"]) - if fallback_id in machine_exclude_materials: + if material_id in machine_exclude_materials: Logger.log("d", "Exclude material [%s] for machine [%s]", material_id, machine_definition.getId()) continue From 1c3bae3fe478e6e30df7be4bdce76729224c66bd Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 29 May 2018 10:52:04 +0200 Subject: [PATCH 06/44] Show keep/discard dialog upon material change if there are user changes CURA-5417 --- cura/Settings/MachineManager.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 78f462d8e9..44f9f04740 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1331,6 +1331,10 @@ class MachineManager(QObject): self._setMaterial(position, container_node) self._updateQualityWithMaterial() + # See if we need to show the Discard or Keep changes screen + if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1: + self._application.discardOrKeepProfileChanges() + @pyqtSlot(str, str) def setVariantByName(self, position: str, variant_name: str) -> None: machine_definition_id = self._global_container_stack.definition.id From 77feb95191317a6e7bf077127a6a4d3293f67955 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 29 May 2018 11:05:55 +0200 Subject: [PATCH 07/44] Don't crash when failing to reload file Now it shows a message that it failed to load the file. --- cura/CuraApplication.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 5db616ab3b..ed4336a9a0 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -1500,11 +1500,15 @@ class CuraApplication(QtApplication): def _reloadMeshFinished(self, job): # TODO; This needs to be fixed properly. We now make the assumption that we only load a single mesh! - mesh_data = job.getResult()[0].getMeshData() - if mesh_data: - job._node.setMeshData(mesh_data) - else: + job_result = job.getResult() + if len(job_result) == 0: + Logger.log("e", "Reloading the mesh failed.") + return + mesh_data = job_result[0].getMeshData() + if not mesh_data: Logger.log("w", "Could not find a mesh in reloaded node.") + return + job._node.setMeshData(mesh_data) def _openFile(self, filename): self.readLocalFile(QUrl.fromLocalFile(filename)) From 373555fa4a16eafbec5e9986d1f88d837af204d1 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Wed, 28 Feb 2018 16:26:11 +0100 Subject: [PATCH 08/44] settings for infill support --- resources/definitions/fdmprinter.def.json | 24 +++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index fc8395a8dc..4ab08d2f24 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1807,6 +1807,30 @@ "limit_to_extruder": "infill_extruder_nr", "settable_per_mesh": true }, + "infill_support_enabled": + { + "label": "Infill Support", + "description": "Print infill structures only where tops of the model should be supported. Enabling this reduces print time and material usage, but leads to ununiform object strength.", + "type": "bool", + "default_value": false, + "enabled": "infill_sparse_density > 0", + "limit_to_extruder": "infill_extruder_nr", + "settable_per_mesh": true + }, + "infill_support_angle": + { + "label": "Infill Overhang Angle", + "description": "The minimum angle of internal overhangs for which infill is added. At a value of 0° objects are totally filled with infill, 90° will not provide any infill.", + "unit": "°", + "type": "float", + "minimum_value": "0", + "minimum_value_warning": "2", + "maximum_value": "90", + "default_value": 40, + "enabled": "infill_sparse_density > 0 and infill_support_enabled", + "limit_to_extruder": "infill_extruder_nr", + "settable_per_mesh": true + }, "skin_preshrink": { "label": "Skin Removal Width", From ab2503834bda73e51ce4950d91f5739f5ae9bdd2 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 29 May 2018 11:31:13 +0200 Subject: [PATCH 09/44] Remove Hollow Out Objects setting It has been replaced by Infill Support. Contributes to issue CURA-5108. --- resources/definitions/fdmprinter.def.json | 8 -------- 1 file changed, 8 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 4ab08d2f24..292748433e 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -5942,14 +5942,6 @@ "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": true }, - "infill_hollow": - { - "label": "Hollow Out Objects", - "description": "Remove all infill and make the inside of the object eligible for support.", - "type": "bool", - "default_value": false, - "settable_per_mesh": true - }, "magic_fuzzy_skin_enabled": { "label": "Fuzzy Skin", From db16a6275f43ce9a51326ea9ddcaa80f8ab3a4c9 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 29 May 2018 11:51:54 +0200 Subject: [PATCH 10/44] Add version upgrade for infill_hollow -> infill_support The functionality is more or less the same, so in an attempt to keep people's profiles as similar as possible we translate this setting to the newer implementation. --- .../VersionUpgrade33to34/VersionUpgrade33to34.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py b/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py index 17abace547..16f17c5e36 100644 --- a/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py +++ b/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py @@ -6,6 +6,9 @@ import io #To serialise the preference files afterwards. from UM.VersionUpgrade import VersionUpgrade #We're inheriting from this. +_renamed_settings = { + "infill_hollow": "infill_support_enabled" +} ## Upgrades configurations from the state they were in at version 3.3 to the # state they should be in at version 3.4. @@ -38,6 +41,13 @@ class VersionUpgrade33to34(VersionUpgrade): # Update version number. parser["general"]["version"] = "4" + #Renamed settings. + if "values" in parser: + for original, replacement in _renamed_settings.items(): + if original in parser["value"]: + parser["value"][replacement] = parser["value"][original] + del parser["value"][original] + result = io.StringIO() parser.write(result) - return [filename], [result.getvalue()] + return [filename], [result.getvalue()] \ No newline at end of file From 0d89240bca0c57ac7d6d6486fca9ecc35248fce1 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 29 May 2018 11:57:14 +0200 Subject: [PATCH 11/44] Copy support angle to infill support angle if used for hollow infill This keeps the new profile as close to the profile in the previous version as possible. Contributes to issue CURA-5108. --- .../VersionUpgrade33to34/VersionUpgrade33to34.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py b/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py index 16f17c5e36..e2241fd195 100644 --- a/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py +++ b/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py @@ -41,12 +41,16 @@ class VersionUpgrade33to34(VersionUpgrade): # Update version number. parser["general"]["version"] = "4" - #Renamed settings. if "values" in parser: + #If infill_hollow was enabled and the overhang angle was adjusted, copy that overhang angle to the new infill support angle. + if "infill_hollow" in parser["values"] and parser["values"]["infill_hollow"] and "support_angle" in parser["values"]: + parser["values"]["infill_support_angle"] = parser["values"]["support_angle"] + + #Renamed settings. for original, replacement in _renamed_settings.items(): - if original in parser["value"]: - parser["value"][replacement] = parser["value"][original] - del parser["value"][original] + if original in parser["values"]: + parser["values"][replacement] = parser["values"][original] + del parser["values"][original] result = io.StringIO() parser.write(result) From 3614da0f9d33a69b5ef904999f1ba50d96bdf3d1 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 29 May 2018 13:22:59 +0200 Subject: [PATCH 12/44] Replace infill_hollow by infill_support_enabled It's not the exact same functionality, but very similar and equally expert. Contributes to issue CURA-5108. --- resources/setting_visibility/expert.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/setting_visibility/expert.cfg b/resources/setting_visibility/expert.cfg index 6d6b84883c..be0950ec6f 100644 --- a/resources/setting_visibility/expert.cfg +++ b/resources/setting_visibility/expert.cfg @@ -87,6 +87,7 @@ gradual_infill_steps gradual_infill_step_height infill_before_walls min_infill_area +infill_support_enabled skin_preshrink top_skin_preshrink bottom_skin_preshrink @@ -369,7 +370,6 @@ spaghetti_infill_extra_volume support_conical_enabled support_conical_angle support_conical_min_width -infill_hollow magic_fuzzy_skin_enabled magic_fuzzy_skin_thickness magic_fuzzy_skin_point_density From 7cf2832183d7cdd5550aac83012119e69b58c495 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 29 May 2018 13:43:08 +0200 Subject: [PATCH 13/44] Fix quality_group is None check in _setQualityGroup() CURA-5423 --- cura/Settings/MachineManager.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 44f9f04740..84ffc8aaf4 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1032,6 +1032,10 @@ class MachineManager(QObject): self.activeQualityChangesGroupChanged.emit() def _setQualityGroup(self, quality_group, empty_quality_changes: bool = True) -> None: + if quality_group is None: + self._setEmptyQuality() + return + if quality_group.node_for_global.getContainer() is None: return for node in quality_group.nodes_for_extruders.values(): @@ -1042,10 +1046,6 @@ class MachineManager(QObject): if empty_quality_changes: self._current_quality_changes_group = None - if quality_group is None: - self._setEmptyQuality() - return - # Set quality and quality_changes for the GlobalStack self._global_container_stack.quality = quality_group.node_for_global.getContainer() if empty_quality_changes: From fed0a015eefd87c4ca0cf63c78cffe249dcc7b91 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 29 May 2018 15:56:00 +0200 Subject: [PATCH 14/44] Clear is_user_specified_job_name flag when setting a project file name CURA-5280 --- cura/PrintInformation.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index 2c9f6511fa..9239dec8b7 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -329,6 +329,8 @@ class PrintInformation(QObject): baseNameChanged = pyqtSignal() def setBaseName(self, base_name: str, is_project_file: bool = False): + self._is_user_specified_job_name = False + # Ensure that we don't use entire path but only filename name = os.path.basename(base_name) From b46a08f566b573dee767d1216fc9c340e350e02b Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Tue, 29 May 2018 18:15:16 +0200 Subject: [PATCH 15/44] Add Reft and Right side aligned action buttons to the message box CURA-4952 --- cura/CuraApplication.py | 2 +- .../FirmwareUpdateCheckerJob.py | 14 ++++++++++++-- plugins/SliceInfoPlugin/SliceInfo.py | 5 +++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index ed4336a9a0..34b6b5cde1 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -452,7 +452,7 @@ class CuraApplication(QtApplication): ## A reusable dialogbox # - showMessageBox = pyqtSignal(str, str, str, str, str, int, int, arguments = ["title", "footer", "text", "informativeText", "detailedText", "buttons", "icon"]) + showMessageBox = pyqtSignal(str, str, str, str, int, int, arguments = ["title", "text", "informativeText", "detailedText", "buttons", "icon"]) def messageBox(self, title, text, informativeText = "", detailedText = "", buttons = QMessageBox.Ok, icon = QMessageBox.NoIcon, callback = None, callback_arguments = []): self._message_box_callback = callback diff --git a/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py b/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py index 19b77c1181..089d1847ed 100644 --- a/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py +++ b/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py @@ -75,9 +75,19 @@ class FirmwareUpdateCheckerJob(Job): machine_name=machine_name), title=i18n_catalog.i18nc( "@info:title The %s gets replaced with the printer name.", - "New %s firmware available") % machine_name, - footer = footer_message) + "New %s firmware available") % machine_name) + message.addAction("download", + i18n_catalog.i18nc("@action:button", "How to update"), + "[no_icon]", + "[no_description]", + button_style=Message.ActionButtonStyle.LINK, + button_align=Message.ActionButtonStyle.BUTTON_ALIGN_LEFT) + + + # If we do this in a cool way, the download url should be available in the JSON file + if self._set_download_url_callback: + self._set_download_url_callback("https://ultimaker.com/en/resources/20500-upgrade-firmware") message.actionTriggered.connect(self._callback) message.show() diff --git a/plugins/SliceInfoPlugin/SliceInfo.py b/plugins/SliceInfoPlugin/SliceInfo.py index 82e07da464..b0525bdbfa 100755 --- a/plugins/SliceInfoPlugin/SliceInfo.py +++ b/plugins/SliceInfoPlugin/SliceInfo.py @@ -46,10 +46,11 @@ class SliceInfo(QObject, Extension): dismissable = False, title = catalog.i18nc("@info:title", "Collecting Data")) - self.send_slice_info_message.addAction("Dismiss", name = catalog.i18nc("@action:button", "Allow"), icon = None, - description = catalog.i18nc("@action:tooltip", "Allow Cura to send anonymized usage statistics to help prioritize future improvements to Cura. Some of your preferences and settings are sent, the Cura version and a hash of the models you're slicing.")) self.send_slice_info_message.addAction("MoreInfo", name = catalog.i18nc("@action:button", "More info"), icon = None, description = catalog.i18nc("@action:tooltip", "See more information on what data Cura sends."), button_style = Message.ActionButtonStyle.LINK) + + self.send_slice_info_message.addAction("Dismiss", name = catalog.i18nc("@action:button", "Allow"), icon = None, + description = catalog.i18nc("@action:tooltip", "Allow Cura to send anonymized usage statistics to help prioritize future improvements to Cura. Some of your preferences and settings are sent, the Cura version and a hash of the models you're slicing.")) self.send_slice_info_message.actionTriggered.connect(self.messageActionTriggered) self.send_slice_info_message.show() From 4d6753a1f163d78a9fe61756c94d22e674887a46 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Tue, 29 May 2018 18:33:38 +0200 Subject: [PATCH 16/44] remove unused code lines in firmware checker CURA-4952 --- plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py b/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py index 089d1847ed..ce4fb8c92f 100644 --- a/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py +++ b/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py @@ -64,11 +64,6 @@ class FirmwareUpdateCheckerJob(Job): if (checked_version != "") and (checked_version != current_version): Logger.log("i", "SHOWING FIRMWARE UPDATE MESSAGE") - footer_text = i18n_catalog.i18nc("@action:info", "Read more on how to update printer firmware") - footer_link = "?url=https://ultimaker.com/en/resources/23129-updating-the-firmware?utm_source=cura&utm_medium=software&utm_campaign=hw-update" - - footer_message = footer_text + " " + footer_link - message = Message(i18n_catalog.i18nc( "@info Don't translate {machine_name}, since it gets replaced by a printer name!", "New features are available for your {machine_name}! It is recommended to update the firmware on your printer.").format( From 80d4989843f4c629a562d9816cabeaa276e2a110 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 30 May 2018 09:03:34 +0200 Subject: [PATCH 17/44] Show keep/discard user settings dialog upon variant change CURA-5417 --- cura/Settings/MachineManager.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 84ffc8aaf4..5c87b6ffba 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1350,6 +1350,10 @@ class MachineManager(QObject): self._updateMaterialWithVariant(position) self._updateQualityWithMaterial() + # See if we need to show the Discard or Keep changes screen + if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1: + self._application.discardOrKeepProfileChanges() + @pyqtSlot(str) def setQualityGroupByQualityType(self, quality_type: str) -> None: if self._global_container_stack is None: From 13b3e4afa5c00ab3baab0570d318467f50fdf688 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 29 May 2018 16:34:36 +0200 Subject: [PATCH 18/44] CURA-5357 Drag & dribble multiple packages like a plugable trickle, yo Also improved interfacing with `CuraVersion.py` --- plugins/Toolbox/src/Toolbox.py | 62 ++++++++++++++++++++-------------- resources/qml/Cura.qml | 15 ++++---- 2 files changed, 46 insertions(+), 31 deletions(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index e540bce523..b9e7f8f94d 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -28,7 +28,8 @@ i18n_catalog = i18nCatalog("cura") ## The Toolbox class is responsible of communicating with the server through the API class Toolbox(QObject, Extension): - DEFAULT_PACKAGES_API_ROOT = "https://api.ultimaker.com" + DEFAULT_CLOUD_API_ROOT = "https://api.ultimaker.com" + DEFAULT_CLOUD_API_VERSION = 1 def __init__(self, parent=None) -> None: super().__init__(parent) @@ -37,16 +38,10 @@ class Toolbox(QObject, Extension): self._package_manager = None self._plugin_registry = Application.getInstance().getPluginRegistry() - self._sdk_version = self._getPackagesVersion() - - self._cloud_api_version = 1 - self._cloud_api_root = self._getPackagesApiRoot() - - self._api_url = "{cloud_api_root}/cura-packages/v{cloud_api_version}/cura/v{sdk_version}".format( - cloud_api_root = self._cloud_api_root, - cloud_api_version = self._cloud_api_version, - sdk_version = self._sdk_version - ) + self._sdk_version = None + self._cloud_api_version = None + self._cloud_api_root = None + self._api_url = None # Network: self._get_packages_request = None @@ -67,12 +62,7 @@ class Toolbox(QObject, Extension): ) ) ] - self._request_urls = { - "authors": QUrl("{base_url}/authors".format(base_url = self._api_url)), - "packages": QUrl("{base_url}/packages".format(base_url = self._api_url)), - "plugins_showcase": QUrl("{base_url}/showcase".format(base_url = self._api_url)), - "materials_showcase": QUrl("{base_url}/showcase".format(base_url = self._api_url)) - } + self._request_urls = {} self._to_update = [] # Package_ids that are waiting to be updated # Data: @@ -164,22 +154,44 @@ class Toolbox(QObject, Extension): # this is initialized. Therefore, we wait until the application is ready. def _onAppInitialized(self) -> None: self._package_manager = Application.getInstance().getCuraPackageManager() + self._sdk_version = self._getSDKVersion() + self._cloud_api_version = self._getCloudAPIVersion() + self._cloud_api_root = self._getCloudAPIRoot() + self._api_url = "{cloud_api_root}/cura-packages/v{cloud_api_version}/cura/v{sdk_version}".format( + cloud_api_root=self._cloud_api_root, + cloud_api_version=self._cloud_api_version, + sdk_version=self._sdk_version + ) + self._request_urls = { + "authors": QUrl("{base_url}/authors".format(base_url=self._api_url)), + "packages": QUrl("{base_url}/packages".format(base_url=self._api_url)), + "plugins_showcase": QUrl("{base_url}/showcase".format(base_url=self._api_url)), + "materials_showcase": QUrl("{base_url}/showcase".format(base_url=self._api_url)) + } # Get the API root for the packages API depending on Cura version settings. - def _getPackagesApiRoot(self) -> str: + def _getCloudAPIRoot(self) -> str: if not hasattr(cura, "CuraVersion"): - return self.DEFAULT_PACKAGES_API_ROOT - if not hasattr(cura.CuraVersion, "CuraPackagesApiRoot"): - return self.DEFAULT_PACKAGES_API_ROOT - return cura.CuraVersion.CuraPackagesApiRoot + return self.DEFAULT_CLOUD_API_ROOT + if not hasattr(cura.CuraVersion, "CuraCloudAPIRoot"): + return self.DEFAULT_CLOUD_API_ROOT + return cura.CuraVersion.CuraCloudAPIRoot + + # Get the cloud API version from CuraVersion + def _getCloudAPIVersion(self) -> int: + if not hasattr(cura, "CuraVersion"): + return self.DEFAULT_CLOUD_API_VERSION + if not hasattr(cura.CuraVersion, "CuraCloudAPIVersion"): + return self.DEFAULT_CLOUD_API_VERSION + return cura.CuraVersion.CuraCloudAPIVersion # Get the packages version depending on Cura version settings. - def _getPackagesVersion(self) -> int: + def _getSDKVersion(self) -> int: if not hasattr(cura, "CuraVersion"): return self._plugin_registry.APIVersion - if not hasattr(cura.CuraVersion, "CuraPackagesVersion"): + if not hasattr(cura.CuraVersion, "CuraSDKVersion"): return self._plugin_registry.APIVersion - return cura.CuraVersion.CuraPackagesVersion + return cura.CuraVersion.CuraSDKVersion @pyqtSlot() def browsePackages(self) -> None: diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index e1cc4f6e45..b8f289278c 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -323,10 +323,11 @@ UM.MainWindow { if (drop.urls.length > 0) { - // As the drop area also supports plugins, first check if it's a plugin that was dropped. - if (drop.urls.length == 1) + + var nonPackages = []; + for (var i = 0; i < drop.urls.length; i++) { - var filename = drop.urls[0]; + var filename = drop.urls[i]; if (filename.endsWith(".curapackage")) { // Try to install plugin & close. @@ -334,11 +335,13 @@ UM.MainWindow packageInstallDialog.text = catalog.i18nc("@label", "This package will be installed after restarting."); packageInstallDialog.icon = StandardIcon.Information; packageInstallDialog.open(); - return; + } + else + { + others.push(filename); } } - - openDialog.handleOpenFileUrls(drop.urls); + openDialog.handleOpenFileUrls(nonPackages); } } } From 9223122fc8af07bf209eb85a947e351e0d617262 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 30 May 2018 09:13:25 +0200 Subject: [PATCH 19/44] Add CuraCloudAPIRoot into CuraVersion.py.in and CMakeLists.txt CURA-5357 --- CMakeLists.txt | 2 ++ cura/CuraVersion.py.in | 1 + 2 files changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 96efd68a2f..079b44890a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,8 @@ endif() set(CURA_VERSION "master" CACHE STRING "Version name of Cura") set(CURA_BUILDTYPE "" CACHE STRING "Build type of Cura, eg. 'PPA'") set(CURA_PACKAGES_VERSION "" CACHE STRING "Packages version of Cura") +set(CURA_CLOUD_API_ROOT "" CACHE STRING "Alternative cloud API root of Cura") + configure_file(${CMAKE_SOURCE_DIR}/cura.desktop.in ${CMAKE_BINARY_DIR}/cura.desktop @ONLY) configure_file(cura/CuraVersion.py.in CuraVersion.py @ONLY) diff --git a/cura/CuraVersion.py.in b/cura/CuraVersion.py.in index f45a24cae9..3077ad5441 100644 --- a/cura/CuraVersion.py.in +++ b/cura/CuraVersion.py.in @@ -5,3 +5,4 @@ CuraVersion = "@CURA_VERSION@" CuraBuildType = "@CURA_BUILDTYPE@" CuraDebugMode = True if "@_cura_debugmode@" == "ON" else False CuraPackagesVersion = "@CURA_PACKAGES_VERSION@" +CuraCloudAPIRoot = "@CURA_CLOUD_API_ROOT@" From fae9bc838b4a9cb8d293b3785db5f5da4ce290c0 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 30 May 2018 09:18:43 +0200 Subject: [PATCH 20/44] Update CURA_* setups in CuraVersion.py.in and CMakeLists.txt CURA-5357 --- CMakeLists.txt | 5 +++-- cura/CuraVersion.py.in | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 079b44890a..9e9bf4b538 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,8 +19,9 @@ endif() set(CURA_VERSION "master" CACHE STRING "Version name of Cura") set(CURA_BUILDTYPE "" CACHE STRING "Build type of Cura, eg. 'PPA'") -set(CURA_PACKAGES_VERSION "" CACHE STRING "Packages version of Cura") -set(CURA_CLOUD_API_ROOT "" CACHE STRING "Alternative cloud API root of Cura") +set(CURA_SDK_VERSION "" CACHE STRING "SDK version of Cura") +set(CURA_CLOUD_API_ROOT "" CACHE STRING "Alternative Cura cloud API root") +set(CURA_CLOUD_API_VERSION "" CACHE STRING "Alternative Cura cloud API version") configure_file(${CMAKE_SOURCE_DIR}/cura.desktop.in ${CMAKE_BINARY_DIR}/cura.desktop @ONLY) configure_file(cura/CuraVersion.py.in CuraVersion.py @ONLY) diff --git a/cura/CuraVersion.py.in b/cura/CuraVersion.py.in index 3077ad5441..226b2183f2 100644 --- a/cura/CuraVersion.py.in +++ b/cura/CuraVersion.py.in @@ -4,5 +4,6 @@ CuraVersion = "@CURA_VERSION@" CuraBuildType = "@CURA_BUILDTYPE@" CuraDebugMode = True if "@_cura_debugmode@" == "ON" else False -CuraPackagesVersion = "@CURA_PACKAGES_VERSION@" +CuraSDKVersion = "@CURA_SDK_VERSION@" CuraCloudAPIRoot = "@CURA_CLOUD_API_ROOT@" +CuraCloudAPIVersion = "@CURA_CLOUD_API_VERSION@" From f1bb0e58e725d884a1d56cf5d7eeffff3372d388 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 30 May 2018 09:20:00 +0200 Subject: [PATCH 21/44] Do not use CuraVersion data if strings are empty CURA-5357 --- plugins/Toolbox/src/Toolbox.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index b9e7f8f94d..b019dfccbe 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -175,6 +175,8 @@ class Toolbox(QObject, Extension): return self.DEFAULT_CLOUD_API_ROOT if not hasattr(cura.CuraVersion, "CuraCloudAPIRoot"): return self.DEFAULT_CLOUD_API_ROOT + if not cura.CuraVersion.CuraCloudAPIRoot: + return self.DEFAULT_CLOUD_API_ROOT return cura.CuraVersion.CuraCloudAPIRoot # Get the cloud API version from CuraVersion @@ -183,6 +185,8 @@ class Toolbox(QObject, Extension): return self.DEFAULT_CLOUD_API_VERSION if not hasattr(cura.CuraVersion, "CuraCloudAPIVersion"): return self.DEFAULT_CLOUD_API_VERSION + if not cura.CuraVersion.CuraCloudAPIVersion: + return self.DEFAULT_CLOUD_API_VERSION return cura.CuraVersion.CuraCloudAPIVersion # Get the packages version depending on Cura version settings. @@ -191,6 +195,8 @@ class Toolbox(QObject, Extension): return self._plugin_registry.APIVersion if not hasattr(cura.CuraVersion, "CuraSDKVersion"): return self._plugin_registry.APIVersion + if not cura.CuraVersion.CuraSDKVersion: + return self._plugin_registry.APIVersion return cura.CuraVersion.CuraSDKVersion @pyqtSlot() From 3395610b677e8be30f116a411e722a910b86a30a Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 30 May 2018 09:44:33 +0200 Subject: [PATCH 22/44] CURA-5357 fix boo boo, rename variable --- resources/qml/Cura.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index b8f289278c..dce106e219 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -338,7 +338,7 @@ UM.MainWindow } else { - others.push(filename); + nonPackages.push(filename); } } openDialog.handleOpenFileUrls(nonPackages); From 6ea5924c95f8b8a2d6521d35df3568b146c5f73f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 30 May 2018 10:35:50 +0200 Subject: [PATCH 23/44] Remove Try Multiple Line Thicknesses setting This setting is now always enabled, hard-coded in the engine. --- resources/definitions/fdmprinter.def.json | 8 -------- 1 file changed, 8 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index b3932de827..5ad478bfc3 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -6678,14 +6678,6 @@ "type": "float", "enabled": "bridge_settings_enabled and bridge_enable_more_layers", "settable_per_mesh": true - }, - "wall_try_line_thickness": - { - "label": "Try Multiple Line Thicknesses", - "description": "When creating inner walls, try various line thicknesses to fit the wall lines better in narrow spaces. This reduces or increases the inner wall line width by up to 0.01mm.", - "default_value": false, - "type": "bool", - "settable_per_mesh": true } } }, From ed0a0dd7651d90c271b87b05e87427253a2d0583 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 30 May 2018 10:58:19 +0200 Subject: [PATCH 24/44] Fix multiply object in a rare case that an object is just too big --- cura/MultiplyObjectsJob.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cura/MultiplyObjectsJob.py b/cura/MultiplyObjectsJob.py index 46f7f56f8a..af24036eeb 100644 --- a/cura/MultiplyObjectsJob.py +++ b/cura/MultiplyObjectsJob.py @@ -1,6 +1,8 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +import copy + from UM.Job import Job from UM.Operations.GroupedOperation import GroupedOperation from UM.Message import Message @@ -64,6 +66,8 @@ class MultiplyObjectsJob(Job): # We do place the nodes one by one, as we want to yield in between. if not node_too_big: new_node, solution_found = arranger.findNodePlacement(current_node, offset_shape_arr, hull_shape_arr) + else: + new_node = copy.deepcopy(node) if node_too_big or not solution_found: found_solution_for_all = False new_location = new_node.getPosition() From 86d4f0583cccb869978084a67c6093267c2356fc Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 30 May 2018 13:15:32 +0200 Subject: [PATCH 25/44] Make showing of support density image dependent on support pattern Because that's what it's actually depending on. Contributes to issue CURA-4513. --- resources/definitions/fdmprinter.def.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 5ad478bfc3..25fe841ee4 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -5812,7 +5812,7 @@ "description": "The file location of an image of which the brightness values determine the minimal density at the corresponding location in the support.", "type": "str", "default_value": "", - "enabled": "infill_pattern == 'cross' or infill_pattern == 'cross_3d'", + "enabled": "support_pattern == 'cross' or support_pattern == 'cross_3d'", "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true From 00fe18008586fb33aeed1df9dc684f5f5d35d113 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 30 May 2018 16:29:55 +0200 Subject: [PATCH 26/44] Hide Toolbox Showcase & Materials for 3.4 --- plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml | 4 ++++ plugins/Toolbox/resources/qml/ToolboxHeader.qml | 3 +++ 2 files changed, 7 insertions(+) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml index 170fd10fc7..69e508cd55 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml @@ -18,6 +18,8 @@ ScrollView spacing: UM.Theme.getSize("default_margin").height padding: UM.Theme.getSize("wide_margin").height height: childrenRect.height + 2 * padding + + /* Hide for 3.4 ToolboxDownloadsShowcase { id: showcase @@ -29,6 +31,8 @@ ScrollView width: parent.width height: UM.Theme.getSize("default_lining").height } + */ + ToolboxDownloadsGrid { id: allPlugins diff --git a/plugins/Toolbox/resources/qml/ToolboxHeader.qml b/plugins/Toolbox/resources/qml/ToolboxHeader.qml index 88495e3f63..ee4241beaf 100644 --- a/plugins/Toolbox/resources/qml/ToolboxHeader.qml +++ b/plugins/Toolbox/resources/qml/ToolboxHeader.qml @@ -33,6 +33,8 @@ Item toolbox.viewPage = "overview" } } + + /* Hide for 3.4 ToolboxTabButton { text: catalog.i18nc("@title:tab", "Materials") @@ -45,6 +47,7 @@ Item toolbox.viewPage = "overview" } } + */ } ToolboxTabButton { From a468fc2cc4a42778c137b11029b8dfb3bfc8032c Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 31 May 2018 12:21:51 +0200 Subject: [PATCH 27/44] Only load loading.gif when needed Toolbox crashes on Mac OS X due to reaching the max limit of file handlers. This seems to be caused by the loading the "loading.gif" animation image. Probably because many widgets are created and each of them has an animation image, and Qt (5.8?) seems to load everything at the same time. --- plugins/Toolbox/resources/qml/ToolboxProgressButton.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml b/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml index b598bd96d0..2744e40ec9 100644 --- a/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml +++ b/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml @@ -150,7 +150,7 @@ Item { id: loader visible: active - source: "../images/loading.gif" + source: visible ? "../images/loading.gif" : "" width: UM.Theme.getSize("toolbox_loader").width height: UM.Theme.getSize("toolbox_loader").height anchors.right: button.left From a8173344a3f61f9a13c6e9f678810d2d783d1183 Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 31 May 2018 14:45:57 +0200 Subject: [PATCH 28/44] Hidden materials --- plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml | 2 ++ plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml index e1ffc6326c..05186b961d 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml @@ -12,6 +12,7 @@ Column height: childrenRect.height width: parent.width spacing: UM.Theme.getSize("default_margin").height + /* Hidden for 3.4 Label { id: heading @@ -20,6 +21,7 @@ Column color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("medium") } + */ GridLayout { id: grid diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml index 9d916182f6..bb0f6fe346 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml @@ -65,6 +65,7 @@ ScrollView } } } + /* Hidden in 3.4 Label { visible: toolbox.materialsInstalledModel.items.length > 0 @@ -102,5 +103,6 @@ ScrollView } } } + */ } } From 3fefdad14be57092abdae453e4685a9476f9995b Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 31 May 2018 15:22:49 +0200 Subject: [PATCH 29/44] Round margins CURA-5435 --- plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml index 78c970659c..ebd4d979f6 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml @@ -40,9 +40,9 @@ Item Column { id: pluginInfo - topPadding: UM.Theme.getSize("default_margin").height / 2 + topPadding: Math.floor(UM.Theme.getSize("default_margin").height / 2) property var color: model.type === "plugin" && !isEnabled ? UM.Theme.getColor("lining") : UM.Theme.getColor("text") - width: tileRow.width - (authorInfo.width + pluginActions.width + 2 * tileRow.spacing + ((disableButton.visible) ? disableButton.width + tileRow.spacing : 0)) + width: Math.floor(tileRow.width - (authorInfo.width + pluginActions.width + 2 * tileRow.spacing + ((disableButton.visible) ? disableButton.width + tileRow.spacing : 0))) Label { text: model.name From 30cbdfed6952df393f2390cff1f42cc06ea7d7c2 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 31 May 2018 14:50:29 +0200 Subject: [PATCH 30/44] Make sure that file extensions are always lowered CURA-5367 --- cura/CuraApplication.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 34b6b5cde1..e416196775 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -1572,10 +1572,11 @@ class CuraApplication(QtApplication): f = file.toLocalFile() extension = os.path.splitext(f)[1] + extension = extension.lower() filename = os.path.basename(f) if len(self._currently_loading_files) > 0: # If a non-slicable file is already being loaded, we prevent loading of any further non-slicable files - if extension.lower() in self._non_sliceable_extensions: + if extension in self._non_sliceable_extensions: message = Message( self._i18n_catalog.i18nc("@info:status", "Only one G-code file can be loaded at a time. Skipped importing {0}", @@ -1584,7 +1585,8 @@ class CuraApplication(QtApplication): return # If file being loaded is non-slicable file, then prevent loading of any other files extension = os.path.splitext(self._currently_loading_files[0])[1] - if extension.lower() in self._non_sliceable_extensions: + extension = extension.lower() + if extension in self._non_sliceable_extensions: message = Message( self._i18n_catalog.i18nc("@info:status", "Can't open any other file if G-code is loading. Skipped importing {0}", From bb313c45a9465d4097b3b4d3a31ed6f99ceca278 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 31 May 2018 16:25:56 +0200 Subject: [PATCH 31/44] Set job name to "unnamed" if user types in nothing CURA-5367 --- resources/qml/JobSpecs.qml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml index f9ce286706..6cd9999db7 100644 --- a/resources/qml/JobSpecs.qml +++ b/resources/qml/JobSpecs.qml @@ -81,10 +81,9 @@ Item { text: PrintInformation.jobName horizontalAlignment: TextInput.AlignRight onEditingFinished: { - PrintInformation.setJobName(text, true); - if (printJobTextfield.text != ''){ - printJobTextfield.focus = false; - } + text = text == "" ? "unnamed" : text; + PrintInformation.setJobName(printJobTextfield.text, true); + printJobTextfield.focus = false; } validator: RegExpValidator { regExp: /^[^\\ \/ \*\?\|\[\]]*$/ From bc1fa5c3f9b361ca7f0c764eea5dab7b56fbb9df Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 1 Jun 2018 09:38:37 +0200 Subject: [PATCH 32/44] CURA-5435 Attempt to fix "wobbly" text --- plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml index ebd4d979f6..b16564fdd2 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml @@ -16,7 +16,7 @@ Item { color: UM.Theme.getColor("lining") width: parent.width - height: UM.Theme.getSize("default_lining").height + height: Math.floor(UM.Theme.getSize("default_lining").height) anchors.bottom: parent.bottom } Row @@ -47,7 +47,7 @@ Item { text: model.name width: parent.width - height: UM.Theme.getSize("toolbox_property_label").height + height: Math.floor(UM.Theme.getSize("toolbox_property_label").height) wrapMode: Text.WordWrap font: UM.Theme.getFont("default_bold") color: pluginInfo.color @@ -81,7 +81,7 @@ Item } } width: parent.width - height: UM.Theme.getSize("toolbox_property_label").height + height: Math.floor(UM.Theme.getSize("toolbox_property_label").height) wrapMode: Text.WordWrap verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignLeft From 9b5369a5b1b3b27bd9bdc5b393797980caa2a459 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 1 Jun 2018 09:38:45 +0200 Subject: [PATCH 33/44] Revert "CURA-5435 Attempt to fix "wobbly" text" This reverts commit bc1fa5c3f9b361ca7f0c764eea5dab7b56fbb9df. --- plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml index b16564fdd2..ebd4d979f6 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml @@ -16,7 +16,7 @@ Item { color: UM.Theme.getColor("lining") width: parent.width - height: Math.floor(UM.Theme.getSize("default_lining").height) + height: UM.Theme.getSize("default_lining").height anchors.bottom: parent.bottom } Row @@ -47,7 +47,7 @@ Item { text: model.name width: parent.width - height: Math.floor(UM.Theme.getSize("toolbox_property_label").height) + height: UM.Theme.getSize("toolbox_property_label").height wrapMode: Text.WordWrap font: UM.Theme.getFont("default_bold") color: pluginInfo.color @@ -81,7 +81,7 @@ Item } } width: parent.width - height: Math.floor(UM.Theme.getSize("toolbox_property_label").height) + height: UM.Theme.getSize("toolbox_property_label").height wrapMode: Text.WordWrap verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignLeft From cca51cb74b8befea5cab8d078587d06c1b952bcc Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 1 Jun 2018 09:39:04 +0200 Subject: [PATCH 34/44] Revert "Revert "CURA-5435 Attempt to fix "wobbly" text"" This reverts commit 9b5369a5b1b3b27bd9bdc5b393797980caa2a459. --- plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml index ebd4d979f6..b16564fdd2 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml @@ -16,7 +16,7 @@ Item { color: UM.Theme.getColor("lining") width: parent.width - height: UM.Theme.getSize("default_lining").height + height: Math.floor(UM.Theme.getSize("default_lining").height) anchors.bottom: parent.bottom } Row @@ -47,7 +47,7 @@ Item { text: model.name width: parent.width - height: UM.Theme.getSize("toolbox_property_label").height + height: Math.floor(UM.Theme.getSize("toolbox_property_label").height) wrapMode: Text.WordWrap font: UM.Theme.getFont("default_bold") color: pluginInfo.color @@ -81,7 +81,7 @@ Item } } width: parent.width - height: UM.Theme.getSize("toolbox_property_label").height + height: Math.floor(UM.Theme.getSize("toolbox_property_label").height) wrapMode: Text.WordWrap verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignLeft From a4b46be2c58ce6641b3ac2f21f400a32ae84efd9 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 1 Jun 2018 12:58:08 +0200 Subject: [PATCH 35/44] CURA-5427 Force the material models to update when the machine changes and so when the extruder stack changes. - What happen was that when the extruder model needed to update, the material model was not updated correctly and so when changing a material, the node was incorrect. --- cura/Machines/Models/BaseMaterialsModel.py | 6 +++++- resources/qml/Menus/MaterialMenu.qml | 3 +-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/cura/Machines/Models/BaseMaterialsModel.py b/cura/Machines/Models/BaseMaterialsModel.py index 0a1337feeb..4759c8b5b0 100644 --- a/cura/Machines/Models/BaseMaterialsModel.py +++ b/cura/Machines/Models/BaseMaterialsModel.py @@ -39,6 +39,8 @@ class BaseMaterialsModel(ListModel): self._extruder_position = 0 self._extruder_stack = None + # Update the stack and the model data when the machine changes + self._machine_manager.globalContainerChanged.connect(self._updateExtruderStack) def _updateExtruderStack(self): global_stack = self._machine_manager.activeMachine @@ -50,9 +52,11 @@ class BaseMaterialsModel(ListModel): self._extruder_stack = global_stack.extruders.get(str(self._extruder_position)) if self._extruder_stack is not None: self._extruder_stack.pyqtContainersChanged.connect(self._update) + # Force update the model when the extruder stack changes + self._update() def setExtruderPosition(self, position: int): - if self._extruder_position != position: + if self._extruder_stack is None or self._extruder_position != position: self._extruder_position = position self._updateExtruderStack() self.extruderPositionChanged.emit() diff --git a/resources/qml/Menus/MaterialMenu.qml b/resources/qml/Menus/MaterialMenu.qml index d81e0c86c3..64b3130724 100644 --- a/resources/qml/Menus/MaterialMenu.qml +++ b/resources/qml/Menus/MaterialMenu.qml @@ -63,8 +63,7 @@ Menu exclusiveGroup: group onTriggered: { - var activeExtruderIndex = Cura.ExtruderManager.activeExtruderIndex; - Cura.MachineManager.setMaterial(activeExtruderIndex, model.container_node); + Cura.MachineManager.setMaterial(extruderIndex, model.container_node); } } onObjectAdded: brandMaterialsMenu.insertItem(index, object) From 85560abca308dce140671e4c5a3364ea1507207c Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 1 Jun 2018 13:26:14 +0200 Subject: [PATCH 36/44] CURA-5439 Show the keep or discard changes dialog also when the user applies a configuration using the Sync button. --- cura/Settings/MachineManager.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 5c87b6ffba..723bf91d0d 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1280,6 +1280,10 @@ class MachineManager(QObject): self._global_container_stack.variant = self._empty_variant_container self._updateQualityWithMaterial() + # See if we need to show the Discard or Keep changes screen + if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1: + self._application.discardOrKeepProfileChanges() + ## Find all container stacks that has the pair 'key = value' in its metadata and replaces the value with 'new_value' def replaceContainersMetadata(self, key: str, value: str, new_value: str) -> None: machines = ContainerRegistry.getInstance().findContainerStacks(type = "machine") From a0263676e1305c2cc4b778ed5cfb7215e938705a Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 1 Jun 2018 13:36:50 +0200 Subject: [PATCH 37/44] The prepare button slices, so it should be a slice button --- resources/qml/SaveButton.qml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/resources/qml/SaveButton.qml b/resources/qml/SaveButton.qml index 0369f492b4..77537b0af2 100644 --- a/resources/qml/SaveButton.qml +++ b/resources/qml/SaveButton.qml @@ -100,8 +100,8 @@ Item { if (saveToButton.enabled) { saveToButton.clicked(); } - // prepare button - if (prepareButton.enabled) { + // slice button + if (sliceButton.enabled) { sliceOrStopSlicing(); } } @@ -131,7 +131,7 @@ Item { Row { id: additionalComponentsRow anchors.top: parent.top - anchors.right: saveToButton.visible ? saveToButton.left : (prepareButton.visible ? prepareButton.left : parent.right) + anchors.right: saveToButton.visible ? saveToButton.left : (sliceButton.visible ? sliceButton.left : parent.right) anchors.rightMargin: UM.Theme.getSize("default_margin").width spacing: UM.Theme.getSize("default_margin").width @@ -159,14 +159,14 @@ Item { onPreferenceChanged: { var autoSlice = UM.Preferences.getValue("general/auto_slice"); - prepareButton.autoSlice = autoSlice; + sliceButton.autoSlice = autoSlice; saveToButton.autoSlice = autoSlice; } } - // Prepare button, only shows if auto_slice is off + // Slice button, only shows if auto_slice is off Button { - id: prepareButton + id: sliceButton tooltip: [1, 5].indexOf(base.backendState) != -1 ? catalog.i18nc("@info:tooltip","Slice current printjob") : catalog.i18nc("@info:tooltip","Cancel slicing process") // 1 = not started, 2 = Processing @@ -180,7 +180,7 @@ Item { anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width // 1 = not started, 4 = error, 5 = disabled - text: [1, 4, 5].indexOf(base.backendState) != -1 ? catalog.i18nc("@label:Printjob", "Prepare") : catalog.i18nc("@label:Printjob", "Cancel") + text: [1, 4, 5].indexOf(base.backendState) != -1 ? catalog.i18nc("@label:Printjob", "Slice") : catalog.i18nc("@label:Printjob", "Cancel") onClicked: { sliceOrStopSlicing(); From 2fbcc2212386c52f18dfb9ba0fbc16e36238b8aa Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 1 Jun 2018 14:02:32 +0200 Subject: [PATCH 38/44] Fix adding printers due to unused 'parent' parameter The 'parent' parameter was unused, so I removed it. But I didn't remove all things that called it, apparently. I just removed some. I didn't try the stackbuilder. Contributes to issue CURA-5330. --- cura/Settings/CuraContainerStack.py | 4 ++-- cura/Settings/CuraStackBuilder.py | 7 +++---- cura/Settings/ExtruderStack.py | 4 ++-- cura/Settings/GlobalStack.py | 4 ++-- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/cura/Settings/CuraContainerStack.py b/cura/Settings/CuraContainerStack.py index 308a91bc76..e1f89eb725 100755 --- a/cura/Settings/CuraContainerStack.py +++ b/cura/Settings/CuraContainerStack.py @@ -39,8 +39,8 @@ from . import Exceptions # This also means that operations on the stack that modifies the container ordering is prohibited and # will raise an exception. class CuraContainerStack(ContainerStack): - def __init__(self, container_id: str, *args, **kwargs): - super().__init__(container_id, *args, **kwargs) + def __init__(self, container_id: str): + super().__init__(container_id) self._container_registry = ContainerRegistry.getInstance() diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index 640489adb3..da8315b3d2 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -99,8 +99,7 @@ class CuraStackBuilder: position = position, variant_container = extruder_variant_container, material_container = material_container, - quality_container = application.empty_quality_container, - global_stack = new_global_stack, + quality_container = application.empty_quality_container ) new_extruder.setNextStack(new_global_stack) new_global_stack.addExtruder(new_extruder) @@ -139,11 +138,11 @@ class CuraStackBuilder: @classmethod def createExtruderStack(cls, new_stack_id: str, extruder_definition: DefinitionContainerInterface, machine_definition_id: str, position: int, - variant_container, material_container, quality_container, global_stack) -> ExtruderStack: + variant_container, material_container, quality_container) -> ExtruderStack: from cura.CuraApplication import CuraApplication application = CuraApplication.getInstance() - stack = ExtruderStack(new_stack_id, parent = global_stack) + stack = ExtruderStack(new_stack_id) stack.setName(extruder_definition.getName()) stack.setDefinition(extruder_definition) diff --git a/cura/Settings/ExtruderStack.py b/cura/Settings/ExtruderStack.py index 5e944b401f..b3f7d529a2 100644 --- a/cura/Settings/ExtruderStack.py +++ b/cura/Settings/ExtruderStack.py @@ -25,8 +25,8 @@ if TYPE_CHECKING: # # class ExtruderStack(CuraContainerStack): - def __init__(self, container_id: str, *args, **kwargs): - super().__init__(container_id, *args, **kwargs) + def __init__(self, container_id: str): + super().__init__(container_id) self.addMetaDataEntry("type", "extruder_train") # For backward compatibility diff --git a/cura/Settings/GlobalStack.py b/cura/Settings/GlobalStack.py index f76ac1ab3f..6d300954c2 100755 --- a/cura/Settings/GlobalStack.py +++ b/cura/Settings/GlobalStack.py @@ -23,8 +23,8 @@ from .CuraContainerStack import CuraContainerStack ## Represents the Global or Machine stack and its related containers. # class GlobalStack(CuraContainerStack): - def __init__(self, container_id: str, *args, **kwargs): - super().__init__(container_id, *args, **kwargs) + def __init__(self, container_id: str): + super().__init__(container_id) self.addMetaDataEntry("type", "machine") # For backward compatibility From 74ba10444e48b303df057520c693d899c6b5dc00 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 1 Jun 2018 14:31:52 +0200 Subject: [PATCH 39/44] CURA-5357 Prevent uninstall of plugins that are not-yet-installed --- cura/CuraPackageManager.py | 3 +++ .../resources/qml/ToolboxInstalledTileActions.qml | 12 +++++++++++- plugins/Toolbox/src/PackagesModel.py | 6 ++++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index bc2e020037..096bfc9065 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -158,14 +158,17 @@ class CuraPackageManager(QObject): # Add bundled plugins if package_id in self._bundled_package_dict: package_info = self._bundled_package_dict[package_id]["package_info"] + package_info["is_installed"] = True # Add installed plugins if package_id in self._installed_package_dict: package_info = self._installed_package_dict[package_id]["package_info"] + package_info["is_installed"] = True # Add to install plugins if package_id in self._to_install_package_dict: package_info = self._to_install_package_dict[package_id]["package_info"] + package_info["is_installed"] = False if package_info is None: continue diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml index 0ae738b71d..b0aecfc9a2 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml @@ -13,6 +13,16 @@ Column width: UM.Theme.getSize("toolbox_action_button").width spacing: UM.Theme.getSize("narrow_margin").height + Label + { + visible: !model.is_installed + text: catalog.i18nc("@label", "Will install upon restarting") + color: UM.Theme.getColor("lining") + font: UM.Theme.getFont("default") + wrapMode: Text.WordWrap + width: parent.width + } + ToolboxProgressButton { id: updateButton @@ -39,7 +49,7 @@ Column { id: removeButton text: canDowngrade ? catalog.i18nc("@action:button", "Downgrade") : catalog.i18nc("@action:button", "Uninstall") - visible: !model.is_bundled + visible: !model.is_bundled && model.is_installed enabled: !toolbox.isDownloading style: ButtonStyle { diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py index 5ec3eba1d8..2a3b169e87 100644 --- a/plugins/Toolbox/src/PackagesModel.py +++ b/plugins/Toolbox/src/PackagesModel.py @@ -29,8 +29,9 @@ class PackagesModel(ListModel): self.addRoleName(Qt.UserRole + 12, "last_updated") self.addRoleName(Qt.UserRole + 13, "is_bundled") self.addRoleName(Qt.UserRole + 14, "is_enabled") - self.addRoleName(Qt.UserRole + 15, "has_configs") - self.addRoleName(Qt.UserRole + 16, "supported_configs") + self.addRoleName(Qt.UserRole + 15, "is_installed") # Scheduled pkgs are included in the model but should not be marked as actually installed + self.addRoleName(Qt.UserRole + 16, "has_configs") + self.addRoleName(Qt.UserRole + 17, "supported_configs") # List of filters for queries. The result is the union of the each list of results. self._filter = {} # type: Dict[str, str] @@ -73,6 +74,7 @@ class PackagesModel(ListModel): "last_updated": package["last_updated"] if "last_updated" in package else None, "is_bundled": package["is_bundled"] if "is_bundled" in package else False, "is_enabled": package["is_enabled"] if "is_enabled" in package else False, + "is_installed": package["is_installed"] if "is_installed" in package else False, "has_configs": has_configs, "supported_configs": configs_model }) From 4922988e7daa0ccd2cf6e070d55fca1a3ccbd99c Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Mon, 4 Jun 2018 11:11:02 +0200 Subject: [PATCH 40/44] Added .3mf extension to the MimeType CURA-5367 --- plugins/3MFReader/ThreeMFReader.py | 10 ---------- plugins/3MFReader/__init__.py | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/plugins/3MFReader/ThreeMFReader.py b/plugins/3MFReader/ThreeMFReader.py index 9eec09b202..6c2fb9a59d 100755 --- a/plugins/3MFReader/ThreeMFReader.py +++ b/plugins/3MFReader/ThreeMFReader.py @@ -15,7 +15,6 @@ from UM.Math.Vector import Vector from UM.Mesh.MeshBuilder import MeshBuilder from UM.Mesh.MeshReader import MeshReader from UM.Scene.GroupDecorator import GroupDecorator -from UM.MimeTypeDatabase import MimeTypeDatabase, MimeType from cura.Settings.ExtruderManager import ExtruderManager from cura.Scene.CuraSceneNode import CuraSceneNode @@ -26,15 +25,6 @@ from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch MYPY = False - -MimeTypeDatabase.addMimeType( - MimeType( - name = "application/x-cura-project-file", - comment = "Cura Project File", - suffixes = ["curaproject.3mf"] - ) -) - try: if not MYPY: import xml.etree.cElementTree as ET diff --git a/plugins/3MFReader/__init__.py b/plugins/3MFReader/__init__.py index 9da54586a3..304cd8ef65 100644 --- a/plugins/3MFReader/__init__.py +++ b/plugins/3MFReader/__init__.py @@ -13,8 +13,24 @@ from . import ThreeMFWorkspaceReader from UM.i18n import i18nCatalog from UM.Platform import Platform +from UM.MimeTypeDatabase import MimeTypeDatabase, MimeType catalog = i18nCatalog("cura") +MimeTypeDatabase.addMimeType( + MimeType( + name = "application/x-cura-project-file", + comment = "Cura Project File", + suffixes = ["curaproject.3mf"] + ) +) +MimeTypeDatabase.addMimeType( + MimeType( + name = "application/x-cura-project-file", + comment = "Cura Project File", + suffixes = ["3mf"] + ) +) + def getMetaData() -> Dict: # Workarround for osx not supporting double file extensions correctly. if Platform.isOSX(): From 14294936c544abcb8bcfb779cca561d6afc85018 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Mon, 4 Jun 2018 11:39:37 +0200 Subject: [PATCH 41/44] CURA-5434 reversed the role of offset_shape_arr and hull_shape_arr, to fix one-at-a-time arranging --- cura/Arranging/Arrange.py | 14 ++++++++------ cura/Arranging/ArrangeObjectsJob.py | 6 +++--- cura/MultiplyObjectsJob.py | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/cura/Arranging/Arrange.py b/cura/Arranging/Arrange.py index 1027b39199..21ed45dbf1 100644 --- a/cura/Arranging/Arrange.py +++ b/cura/Arranging/Arrange.py @@ -3,6 +3,7 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Logger import Logger +from UM.Math.Polygon import Polygon from UM.Math.Vector import Vector from cura.Arranging.ShapeArray import ShapeArray from cura.Scene import ZOffsetDecorator @@ -45,7 +46,7 @@ class Arrange: # \param scene_root Root for finding all scene nodes # \param fixed_nodes Scene nodes to be placed @classmethod - def create(cls, scene_root = None, fixed_nodes = None, scale = 0.5, x = 350, y = 250): + def create(cls, scene_root = None, fixed_nodes = None, scale = 0.5, x = 350, y = 250, min_offset = 8): arranger = Arrange(x, y, x // 2, y // 2, scale = scale) arranger.centerFirst() @@ -58,9 +59,10 @@ class Arrange: # Place all objects fixed nodes for fixed_node in fixed_nodes: - vertices = fixed_node.callDecoration("getConvexHull") + vertices = fixed_node.callDecoration("getConvexHullHead") or fixed_node.callDecoration("getConvexHull") if not vertices: continue + vertices = vertices.getMinkowskiHull(Polygon.approximatedCircle(min_offset)) points = copy.deepcopy(vertices._points) shape_arr = ShapeArray.fromPolygon(points, scale = scale) arranger.place(0, 0, shape_arr) @@ -81,12 +83,12 @@ class Arrange: ## Find placement for a node (using offset shape) and place it (using hull shape) # return the nodes that should be placed # \param node - # \param offset_shape_arr ShapeArray with offset, used to find location - # \param hull_shape_arr ShapeArray without offset, for placing the shape + # \param offset_shape_arr ShapeArray with offset, for placing the shape + # \param hull_shape_arr ShapeArray without offset, used to find location def findNodePlacement(self, node, offset_shape_arr, hull_shape_arr, step = 1): new_node = copy.deepcopy(node) best_spot = self.bestSpot( - offset_shape_arr, start_prio = self._last_priority, step = step) + hull_shape_arr, start_prio = self._last_priority, step = step) x, y = best_spot.x, best_spot.y # Save the last priority. @@ -102,7 +104,7 @@ class Arrange: if x is not None: # We could find a place new_node.setPosition(Vector(x, center_y, y)) found_spot = True - self.place(x, y, hull_shape_arr) # place the object in arranger + self.place(x, y, offset_shape_arr) # place the object in arranger else: Logger.log("d", "Could not find spot!"), found_spot = False diff --git a/cura/Arranging/ArrangeObjectsJob.py b/cura/Arranging/ArrangeObjectsJob.py index 08fd1985a9..5e982582fd 100644 --- a/cura/Arranging/ArrangeObjectsJob.py +++ b/cura/Arranging/ArrangeObjectsJob.py @@ -37,7 +37,7 @@ class ArrangeObjectsJob(Job): machine_width = global_container_stack.getProperty("machine_width", "value") machine_depth = global_container_stack.getProperty("machine_depth", "value") - arranger = Arrange.create(x = machine_width, y = machine_depth, fixed_nodes = self._fixed_nodes) + arranger = Arrange.create(x = machine_width, y = machine_depth, fixed_nodes = self._fixed_nodes, min_offset = self._min_offset) # Collect nodes to be placed nodes_arr = [] # fill with (size, node, offset_shape_arr, hull_shape_arr) @@ -66,7 +66,7 @@ class ArrangeObjectsJob(Job): start_priority = last_priority else: start_priority = 0 - best_spot = arranger.bestSpot(offset_shape_arr, start_prio=start_priority) + best_spot = arranger.bestSpot(hull_shape_arr, start_prio = start_priority) x, y = best_spot.x, best_spot.y node.removeDecorator(ZOffsetDecorator) if node.getBoundingBox(): @@ -77,7 +77,7 @@ class ArrangeObjectsJob(Job): last_size = size last_priority = best_spot.priority - arranger.place(x, y, hull_shape_arr) # take place before the next one + arranger.place(x, y, offset_shape_arr) # take place before the next one grouped_operation.addOperation(TranslateOperation(node, Vector(x, center_y, y), set_position = True)) else: Logger.log("d", "Arrange all: could not find spot!") diff --git a/cura/MultiplyObjectsJob.py b/cura/MultiplyObjectsJob.py index af24036eeb..57db7734e7 100644 --- a/cura/MultiplyObjectsJob.py +++ b/cura/MultiplyObjectsJob.py @@ -38,7 +38,7 @@ class MultiplyObjectsJob(Job): root = scene.getRoot() scale = 0.5 - arranger = Arrange.create(x = machine_width, y = machine_depth, scene_root = root, scale = scale) + arranger = Arrange.create(x = machine_width, y = machine_depth, scene_root = root, scale = scale, min_offset = self._min_offset) processed_nodes = [] nodes = [] From a9095f2b778cffb6d2f5049f8638010cc1c0b651 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Mon, 4 Jun 2018 11:46:51 +0200 Subject: [PATCH 42/44] After command "Undo" the project name was empty CURA-5367 --- cura/PrintInformation.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index 9239dec8b7..d17720228f 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -357,11 +357,12 @@ class PrintInformation(QObject): data = mime_type.stripExtension(name) except: Logger.log("w", "Unsupported Mime Type Database file extension") + data = 'unnamed' if data is not None and check_name is not None: self._base_name = data else: - self._base_name = '' + self._base_name = 'unnamed' self._updateJobName() From 79d6a9a614ec67d66833cfa75238dff626661450 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Mon, 4 Jun 2018 12:53:13 +0200 Subject: [PATCH 43/44] CURA-5434 fixed arrange to all build plates by reversing hull_shape and offset_shape --- cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py b/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py index 252cef4e65..6abc553a4b 100644 --- a/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py +++ b/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py @@ -110,7 +110,7 @@ class ArrangeObjectsAllBuildPlatesJob(Job): arrange_array.add() arranger = arrange_array.get(current_build_plate_number) - best_spot = arranger.bestSpot(offset_shape_arr, start_prio=start_priority) + best_spot = arranger.bestSpot(hull_shape_arr, start_prio=start_priority) x, y = best_spot.x, best_spot.y node.removeDecorator(ZOffsetDecorator) if node.getBoundingBox(): @@ -118,7 +118,7 @@ class ArrangeObjectsAllBuildPlatesJob(Job): else: center_y = 0 if x is not None: # We could find a place - arranger.place(x, y, hull_shape_arr) # place the object in the arranger + arranger.place(x, y, offset_shape_arr) # place the object in the arranger node.callDecoration("setBuildPlateNumber", current_build_plate_number) grouped_operation.addOperation(TranslateOperation(node, Vector(x, center_y, y), set_position = True)) From e518d07f5a5ca2a56fed51b6862c60bdd9d36963 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 4 Jun 2018 13:22:08 +0200 Subject: [PATCH 44/44] No need to give parent to ExtruderStack --- cura/Settings/CuraContainerRegistry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 6d8ed7c037..f5036078be 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -475,7 +475,7 @@ class CuraContainerRegistry(ContainerRegistry): extruder_definition = extruder_definitions[0] unique_name = self.uniqueName(machine.getName() + " " + new_extruder_id) if create_new_ids else machine.getName() + " " + new_extruder_id - extruder_stack = ExtruderStack.ExtruderStack(unique_name, parent = machine) + extruder_stack = ExtruderStack.ExtruderStack(unique_name) extruder_stack.setName(extruder_definition.getName()) extruder_stack.setDefinition(extruder_definition) extruder_stack.addMetaDataEntry("position", extruder_definition.getMetaDataEntry("position"))