From 3004b146ad06f3528be15330e9be31ecc9ad1068 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 5 Mar 2018 13:36:09 +0100 Subject: [PATCH 1/5] Fix: move createQualityChanges() to QualityManager CURA-4606 --- cura/Machines/QualityManager.py | 46 ++++++++++++++++++++++ cura/Settings/ContainerManager.py | 40 ------------------- resources/qml/Preferences/ProfilesPage.qml | 2 +- 3 files changed, 47 insertions(+), 41 deletions(-) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index dc9dba8c4b..a2871880f0 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -10,6 +10,8 @@ from UM.Logger import Logger from UM.Util import parseBool from UM.Settings.InstanceContainer import InstanceContainer +from cura.Settings.ExtruderStack import ExtruderStack + from .QualityGroup import QualityGroup from .QualityNode import QualityNode @@ -393,6 +395,50 @@ class QualityManager(QObject): new_id = self._container_registry.uniqueName(container.getId()) self._container_registry.addContainer(container.duplicate(new_id, new_name)) + ## Create quality changes containers from the user containers in the active stacks. + # + # This will go through the global and extruder stacks and create quality_changes containers from + # the user containers in each stack. These then replace the quality_changes containers in the + # stack and clear the user settings. + @pyqtSlot(str) + def createQualityChanges(self, base_name): + machine_manager = Application.getInstance().getMachineManager() + + global_stack = machine_manager.activeMachine + if not global_stack: + return + + active_quality_name = machine_manager.activeQualityOrQualityChangesName + if active_quality_name == "": + Logger.log("w", "No quality container found in stack %s, cannot create profile", global_stack.getId()) + return + + machine_manager.blurSettings.emit() + if base_name is None or base_name == "": + base_name = active_quality_name + unique_name = self._container_registry.uniqueName(base_name) + + # Go through the active stacks and create quality_changes containers from the user containers. + stack_list = [global_stack] + list(global_stack.extruders.values()) + for stack in stack_list: + user_container = stack.userChanges + quality_container = stack.quality + quality_changes_container = stack.qualityChanges + if not quality_container or not quality_changes_container: + Logger.log("w", "No quality or quality changes container found in stack %s, ignoring it", stack.getId()) + continue + + extruder_definition_id = None + if isinstance(stack, ExtruderStack): + extruder_definition_id = stack.definition.getId() + quality_type = quality_container.getMetaDataEntry("quality_type") + new_changes = self._createQualityChanges(quality_type, unique_name, global_stack, extruder_definition_id) + from cura.Settings.ContainerManager import ContainerManager + ContainerManager.getInstance()._performMerge(new_changes, quality_changes_container, clear_settings = False) + ContainerManager.getInstance()._performMerge(new_changes, user_container) + + self._container_registry.addContainer(new_changes) + # # Create a quality changes container with the given setup. # diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index b833e1f1e9..f910f0c0e2 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -341,46 +341,6 @@ class ContainerManager(QObject): for container in send_emits_containers: container.sendPostponedEmits() - ## Create quality changes containers from the user containers in the active stacks. - # - # This will go through the global and extruder stacks and create quality_changes containers from - # the user containers in each stack. These then replace the quality_changes containers in the - # stack and clear the user settings. - @pyqtSlot(str) - def createQualityChanges(self, base_name): - global_stack = Application.getInstance().getGlobalContainerStack() - if not global_stack: - return - - active_quality_name = self._machine_manager.activeQualityOrQualityChangesName - if active_quality_name == "": - Logger.log("w", "No quality container found in stack %s, cannot create profile", global_stack.getId()) - return - - self._machine_manager.blurSettings.emit() - if base_name is None or base_name == "": - base_name = active_quality_name - unique_name = self._container_registry.uniqueName(base_name) - - # Go through the active stacks and create quality_changes containers from the user containers. - for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): - user_container = stack.userChanges - quality_container = stack.quality - quality_changes_container = stack.qualityChanges - if not quality_container or not quality_changes_container: - Logger.log("w", "No quality or quality changes container found in stack %s, ignoring it", stack.getId()) - continue - - extruder_definition_id = None - if isinstance(stack, ExtruderStack): - extruder_definition_id = stack.definition.getId() - quality_type = quality_container.getMetaDataEntry("quality_type") - new_changes = self._createQualityChanges(quality_type, unique_name, global_stack, extruder_definition_id) - self._performMerge(new_changes, quality_changes_container, clear_settings = False) - self._performMerge(new_changes, user_container) - - self._container_registry.addContainer(new_changes) - ## Get a list of materials that have the same GUID as the reference material # # \param material_id \type{str} the id of the material for which to get the linked materials. diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index e9bbb4bc66..c604453190 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -175,7 +175,7 @@ Item { base.newQualityNameToSelect = newName; // We want to switch to the new profile once it's created base.toActivateNewQuality = true; - Cura.ContainerManager.createQualityChanges(newName); + base.qualityManager.createQualityChanges(newName); } } From 2de587a8c6361cfd61f6b99941823918dcf5531b Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 5 Mar 2018 15:32:46 +0100 Subject: [PATCH 2/5] Made some changes so the code also works with lower versions of Qt & pyQt --- resources/qml/Menus/BuildplateMenu.qml | 4 ++-- resources/qml/Menus/ContextMenu.qml | 2 +- resources/qml/Menus/MaterialMenu.qml | 2 +- resources/qml/Menus/NozzleMenu.qml | 2 +- resources/qml/Menus/ProfileMenu.qml | 2 +- resources/qml/Menus/ViewMenu.qml | 2 +- resources/qml/ObjectsList.qml | 4 ++-- resources/qml/Preferences/MachinesPage.qml | 2 +- resources/qml/Preferences/MaterialView.qml | 2 +- resources/qml/Preferences/MaterialsPage.qml | 2 +- resources/qml/Preferences/ProfileTab.qml | 2 +- resources/qml/Preferences/ProfilesPage.qml | 2 +- resources/qml/SidebarAdvanced.qml | 2 +- resources/qml/SidebarSimple.qml | 2 +- 14 files changed, 16 insertions(+), 16 deletions(-) diff --git a/resources/qml/Menus/BuildplateMenu.qml b/resources/qml/Menus/BuildplateMenu.qml index 0b67b37cc1..b924aa0879 100644 --- a/resources/qml/Menus/BuildplateMenu.qml +++ b/resources/qml/Menus/BuildplateMenu.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.8 +import QtQuick 2.7 import QtQuick.Controls 1.4 import UM 1.2 as UM @@ -12,7 +12,7 @@ Menu id: menu title: "Build plate" - property Cura.BuildPlateModel buildPlateModel: CuraApplication.getBuildPlateModel() + property var buildPlateModel: CuraApplication.getBuildPlateModel() Instantiator { diff --git a/resources/qml/Menus/ContextMenu.qml b/resources/qml/Menus/ContextMenu.qml index 656e94b336..83302f9463 100644 --- a/resources/qml/Menus/ContextMenu.qml +++ b/resources/qml/Menus/ContextMenu.qml @@ -15,7 +15,7 @@ Menu property bool shouldShowExtruders: machineExtruderCount.properties.value > 1; - property Cura.MultiBuildPlateModel multiBuildPlateModel: CuraApplication.getMultiBuildPlateModel() + property var multiBuildPlateModel: CuraApplication.getMultiBuildPlateModel() // Selection-related actions. MenuItem { action: Cura.Actions.centerSelection; } diff --git a/resources/qml/Menus/MaterialMenu.qml b/resources/qml/Menus/MaterialMenu.qml index 25fa221e9a..d81e0c86c3 100644 --- a/resources/qml/Menus/MaterialMenu.qml +++ b/resources/qml/Menus/MaterialMenu.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.8 +import QtQuick 2.7 import QtQuick.Controls 1.4 import UM 1.2 as UM diff --git a/resources/qml/Menus/NozzleMenu.qml b/resources/qml/Menus/NozzleMenu.qml index 0b961a5a11..43f3b79dd4 100644 --- a/resources/qml/Menus/NozzleMenu.qml +++ b/resources/qml/Menus/NozzleMenu.qml @@ -1,7 +1,7 @@ // Copyright (c) 2017 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.8 +import QtQuick 2.7 import QtQuick.Controls 1.4 import UM 1.2 as UM diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index 19461f6005..72cda13ca9 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.8 +import QtQuick 2.7 import QtQuick.Controls 1.4 import UM 1.2 as UM diff --git a/resources/qml/Menus/ViewMenu.qml b/resources/qml/Menus/ViewMenu.qml index fc0339e0c6..6bbb0b1e2e 100644 --- a/resources/qml/Menus/ViewMenu.qml +++ b/resources/qml/Menus/ViewMenu.qml @@ -13,7 +13,7 @@ Menu id: base enabled: !PrintInformation.preSliced - property Cura.MultiBuildPlateModel multiBuildPlateModel: CuraApplication.getMultiBuildPlateModel() + property var multiBuildPlateModel: CuraApplication.getMultiBuildPlateModel() // main views Instantiator diff --git a/resources/qml/ObjectsList.qml b/resources/qml/ObjectsList.qml index e7dd63ea05..8c8eaa16ae 100644 --- a/resources/qml/ObjectsList.qml +++ b/resources/qml/ObjectsList.qml @@ -31,9 +31,9 @@ Rectangle border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") - property bool collapsed: true; + property bool collapsed: true - property Cura.MultiBuildPlateModel multiBuildPlateModel: CuraApplication.getMultiBuildPlateModel() + property var multiBuildPlateModel: CuraApplication.getMultiBuildPlateModel() SystemPalette { id: palette } diff --git a/resources/qml/Preferences/MachinesPage.qml b/resources/qml/Preferences/MachinesPage.qml index 49a8d286a8..62e5ef98b4 100644 --- a/resources/qml/Preferences/MachinesPage.qml +++ b/resources/qml/Preferences/MachinesPage.qml @@ -1,7 +1,7 @@ // Copyright (c) 2016 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.8 +import QtQuick 2.7 import QtQuick.Controls 1.4 import QtQuick.Window 2.1 diff --git a/resources/qml/Preferences/MaterialView.qml b/resources/qml/Preferences/MaterialView.qml index 0016f211e7..c987880305 100644 --- a/resources/qml/Preferences/MaterialView.qml +++ b/resources/qml/Preferences/MaterialView.qml @@ -1,7 +1,7 @@ // Copyright (c) 2017 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.8 +import QtQuick 2.7 import QtQuick.Controls 1.4 import QtQuick.Dialogs 1.2 diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index a5bb2f9883..4a6d07df81 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Uranium is released under the terms of the LGPLv3 or higher. -import QtQuick 2.8 +import QtQuick 2.7 import QtQuick.Controls 1.4 import QtQuick.Layouts 1.3 import QtQuick.Dialogs 1.2 diff --git a/resources/qml/Preferences/ProfileTab.qml b/resources/qml/Preferences/ProfileTab.qml index dcabf012b7..40f725e092 100644 --- a/resources/qml/Preferences/ProfileTab.qml +++ b/resources/qml/Preferences/ProfileTab.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.8 +import QtQuick 2.7 import QtQuick.Controls 1.4 import UM 1.2 as UM diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index c604453190..3e10aca000 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Uranium is released under the terms of the LGPLv3 or higher. -import QtQuick 2.8 +import QtQuick 2.7 import QtQuick.Controls 1.4 import QtQuick.Layouts 1.3 import QtQuick.Dialogs 1.2 diff --git a/resources/qml/SidebarAdvanced.qml b/resources/qml/SidebarAdvanced.qml index ae77bc8d1b..ff5f545c80 100644 --- a/resources/qml/SidebarAdvanced.qml +++ b/resources/qml/SidebarAdvanced.qml @@ -1,7 +1,7 @@ // Copyright (c) 2015 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.8 +import QtQuick 2.7 import QtQuick.Controls 2.0 import "Settings" diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 1991a9fa57..cef6f38b4b 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.8 +import QtQuick 2.7 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import QtQuick.Layouts 1.3 From a35d4ae400855895a407038d2217e2a29a9b30b2 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Mon, 5 Mar 2018 16:43:58 +0100 Subject: [PATCH 3/5] Fix: After clicking "cancel" button while sending a print job the connection is disconnected CURA-4960 --- cura/PrinterOutput/NetworkedPrinterOutputDevice.py | 3 +++ plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py | 11 ++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index a7b7edc636..315b195e2a 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -219,6 +219,9 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): reply.uploadProgress.connect(onProgress) self._registerOnFinishedCallback(reply, onFinished) + + return reply + def postForm(self, target: str, header_data: str, body_data: bytes, onFinished: Optional[Callable[[Any, QNetworkReply], None]], onProgress: Callable = None) -> None: post_part = QHttpPart() post_part.setHeader(QNetworkRequest.ContentDispositionHeader, header_data) diff --git a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py index fa9abb8d4e..c0d538bb78 100644 --- a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py @@ -77,6 +77,9 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): self._cluster_size = int(properties.get(b"cluster_size", 0)) + self._latest_reply_handler = None + + def requestWrite(self, nodes, file_name=None, filter_by_machine=False, file_handler=None, **kwargs): self.writeStarted.emit(self) @@ -147,7 +150,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): parts.append(self._createFormPart("name=\"file\"; filename=\"%s\"" % file_name, compressed_gcode)) - self.postFormWithParts("print_jobs/", parts, onFinished=self._onPostPrintJobFinished, onProgress=self._onUploadPrintJobProgress) + self._latest_reply_handler = self.postFormWithParts("print_jobs/", parts, onFinished=self._onPostPrintJobFinished, onProgress=self._onUploadPrintJobProgress) @pyqtProperty(QObject, notify=activePrinterChanged) def activePrinter(self) -> Optional["PrinterOutputModel"]: @@ -187,6 +190,12 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): self._sending_gcode = False Application.getInstance().getController().setActiveStage("PrepareStage") + # After compressing the sliced model Cura sends data to printer, to stop receiving updates from the request + # the "reply" should be disconnected + if self._latest_reply_handler: + self._latest_reply_handler.disconnect() + + @pyqtSlot() def openPrintJobControlPanel(self): Logger.log("d", "Opening print job control panel...") From 3e8f29d380764766383cd87c006f01c0b27c1523 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 6 Mar 2018 09:37:21 +0100 Subject: [PATCH 4/5] Allow floating point values for moving print head The X, Y, Z coordinates and speed don't necessarily have to be full millimetres or millimetres per minute. Fixes #3271. --- cura/PrinterOutput/PrinterOutputModel.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cura/PrinterOutput/PrinterOutputModel.py b/cura/PrinterOutput/PrinterOutputModel.py index 8234989519..1c23d0e18e 100644 --- a/cura/PrinterOutput/PrinterOutputModel.py +++ b/cura/PrinterOutput/PrinterOutputModel.py @@ -103,32 +103,32 @@ class PrinterOutputModel(QObject): self._head_position = Vector(x, y, z) self.headPositionChanged.emit() - @pyqtProperty("long", "long", "long") - @pyqtProperty("long", "long", "long", "long") + @pyqtProperty(float, float, float) + @pyqtProperty(float, float, float, float) def setHeadPosition(self, x, y, z, speed = 3000): self.updateHeadPosition(x, y, z) self._controller.setHeadPosition(self, x, y, z, speed) - @pyqtProperty("long") - @pyqtProperty("long", "long") + @pyqtProperty(float) + @pyqtProperty(float, float) def setHeadX(self, x, speed = 3000): self.updateHeadPosition(x, self._head_position.y, self._head_position.z) self._controller.setHeadPosition(self, x, self._head_position.y, self._head_position.z, speed) - @pyqtProperty("long") - @pyqtProperty("long", "long") + @pyqtProperty(float) + @pyqtProperty(float, float) def setHeadY(self, y, speed = 3000): self.updateHeadPosition(self._head_position.x, y, self._head_position.z) self._controller.setHeadPosition(self, self._head_position.x, y, self._head_position.z, speed) - @pyqtProperty("long") - @pyqtProperty("long", "long") + @pyqtProperty(float) + @pyqtProperty(float, float) def setHeadZ(self, z, speed = 3000): self.updateHeadPosition(self._head_position.x, self._head_position.y, z) self._controller.setHeadPosition(self, self._head_position.x, self._head_position.y, z, speed) - @pyqtSlot("long", "long", "long") - @pyqtSlot("long", "long", "long", "long") + @pyqtSlot(float, float, float) + @pyqtSlot(float, float, float, float) def moveHead(self, x = 0, y = 0, z = 0, speed = 3000): self._controller.moveHead(self, x, y, z, speed) From 8d5a643c9b0830e381c05b7e97c3483d48b369e3 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 6 Mar 2018 10:51:39 +0100 Subject: [PATCH 5/5] Removed `print()` statement --- plugins/PerObjectSettingsTool/PerObjectSettingsTool.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py index b671db48fb..11e26a033a 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py @@ -181,7 +181,6 @@ class PerObjectSettingsTool(Tool): def _checkStackForErrors(self, stack): - print("checking for errors") if stack is None: return False