From fcf89b79c6d1f1caf973555a73f3468964744443 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 6 Sep 2016 08:55:32 +0200 Subject: [PATCH 1/8] Update wording of error messages --- plugins/RemovableDriveOutputDevice/RemovableDrivePlugin.py | 2 +- plugins/USBPrinting/USBPrinterOutputDevice.py | 2 +- plugins/USBPrinting/USBPrinterOutputDeviceManager.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/RemovableDriveOutputDevice/RemovableDrivePlugin.py b/plugins/RemovableDriveOutputDevice/RemovableDrivePlugin.py index 37f4422a11..90adac73b1 100644 --- a/plugins/RemovableDriveOutputDevice/RemovableDrivePlugin.py +++ b/plugins/RemovableDriveOutputDevice/RemovableDrivePlugin.py @@ -49,7 +49,7 @@ class RemovableDrivePlugin(OutputDevicePlugin): message = Message(catalog.i18nc("@info:status", "Ejected {0}. You can now safely remove the drive.").format(device.getName())) message.show() else: - message = Message(catalog.i18nc("@info:status", "Failed to eject {0}. Maybe it is still in use?").format(device.getName())) + message = Message(catalog.i18nc("@info:status", "Failed to eject {0}. Another program may be using the drive.").format(device.getName())) message.show() return result diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index 920a71d40f..4838fe9b96 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -140,7 +140,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice): # \param gcode_list List with gcode (strings). def printGCode(self, gcode_list): if self._progress or self._connection_state != ConnectionState.connected: - self._error_message = Message(catalog.i18nc("@info:status", "Printer is busy or not connected. Unable to start a new job.")) + self._error_message = Message(catalog.i18nc("@info:status", "Unable to start a new job because the printer is busy or not connected.")) self._error_message.show() Logger.log("d", "Printer is busy or not connected, aborting print") self.writeError.emit(self) diff --git a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py index 7d1b3fea3b..b50b69188b 100644 --- a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py +++ b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py @@ -107,7 +107,7 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension): def updateAllFirmware(self, file_name): file_name = file_name.replace("file://", "") # File dialogs prepend the path with file://, which we don't need / want if not self._usb_output_devices: - Message(i18n_catalog.i18nc("@info", "Cannot update firmware, there were no connected printers found.")).show() + Message(i18n_catalog.i18nc("@info", "Unable to update firmware because there are no printers connected.")).show() return for printer_connection in self._usb_output_devices: From 7c8e80b751d721032cdc924a956e74245266ec04 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 6 Sep 2016 11:21:48 +0200 Subject: [PATCH 2/8] Properly hide moves and retractions in lower layers Not the neatest solution. We might want to make a preference for this? I sorta like to see those travel moves, actually. Contributes to issue CURA-2049. --- cura/LayerPolygon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/LayerPolygon.py b/cura/LayerPolygon.py index c5eb4b699e..387a369aa3 100644 --- a/cura/LayerPolygon.py +++ b/cura/LayerPolygon.py @@ -16,7 +16,7 @@ class LayerPolygon: MoveRetractionType = 9 SupportInterfaceType = 10 - __jump_map = numpy.logical_or( numpy.arange(11) == NoneType, numpy.arange(11) >= MoveRetractionType ) + __jump_map = numpy.logical_or(numpy.logical_or(numpy.arange(11) == NoneType, numpy.arange(11) == MoveCombingType), numpy.arange(11) == MoveRetractionType) def __init__(self, mesh, extruder, line_types, data, line_widths): self._mesh = mesh From dc01cdbc882faee68b66fcdf924884e7bc95dfa1 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 6 Sep 2016 11:30:38 +0200 Subject: [PATCH 3/8] Fix displaying support interface in layerview CURA-2049 --- cura/LayerPolygon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/LayerPolygon.py b/cura/LayerPolygon.py index 387a369aa3..d3da01e590 100644 --- a/cura/LayerPolygon.py +++ b/cura/LayerPolygon.py @@ -42,7 +42,7 @@ class LayerPolygon: # When type is used as index returns true if type == LayerPolygon.InfillType or type == LayerPolygon.SkinType or type == LayerPolygon.SupportInfillType # Should be generated in better way, not hardcoded. - self._isInfillOrSkinTypeMap = numpy.array([0, 0, 0, 1, 0, 0, 1, 1, 0, 0], dtype=numpy.bool) + self._isInfillOrSkinTypeMap = numpy.array([0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1], dtype=numpy.bool) self._build_cache_line_mesh_mask = None self._build_cache_needed_points = None From 75c1f12d33a6ac817677338d9d1eaf1e2fcd714f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 6 Sep 2016 11:42:46 +0200 Subject: [PATCH 4/8] If a group node is outside build area, all it's children are also marked as such CURA-403 --- cura/PlatformPhysics.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cura/PlatformPhysics.py b/cura/PlatformPhysics.py index d718f25b87..d25a74bf91 100644 --- a/cura/PlatformPhysics.py +++ b/cura/PlatformPhysics.py @@ -48,6 +48,8 @@ class PlatformPhysics: # same direction. transformed_nodes = [] + group_nodes = [] + for node in BreadthFirstIterator(root): if node is root or type(node) is not SceneNode or node.getBoundingBox() is None: continue @@ -69,6 +71,9 @@ class PlatformPhysics: if build_volume_bounding_box.intersectsBox(bbox) != AxisAlignedBox.IntersectionResult.FullIntersection: node._outside_buildarea = True + if node.callDecoration("isGroup"): + group_nodes.append(node) # Keep list of affected group_nodes + # Move it downwards if bottom is above platform move_vector = Vector() if Preferences.getInstance().getValue("physics/automatic_drop_down") and not (node.getParent() and node.getParent().callDecoration("isGroup")): #If an object is grouped, don't move it down @@ -144,7 +149,6 @@ class PlatformPhysics: overlap = convex_hull.intersectsPolygon(area) if overlap is None: continue - node._outside_buildarea = True if not Vector.Null.equals(move_vector, epsilon=1e-5): @@ -152,6 +156,12 @@ class PlatformPhysics: op = PlatformPhysicsOperation.PlatformPhysicsOperation(node, move_vector) op.push() + # Group nodes should override the _outside_buildarea property of their children. + for group_node in group_nodes: + for child_node in group_node.getAllChildren(): + child_node._outside_buildarea = group_node._outside_buildarea + + def _onToolOperationStarted(self, tool): self._enabled = False From fc6e92e10f15c88e3aff3bf39d0faca6bc91ab83 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 6 Sep 2016 13:07:15 +0200 Subject: [PATCH 5/8] Fix uploading custom firmware on windows The simple string replacement left an extraneous "/" in front of the path, which Windows can't handle. QUrl.toLocalFile() does a proper conversion. CURA-955 --- plugins/USBPrinting/USBPrinterOutputDeviceManager.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py index 603696f1c6..4dec2e3a06 100644 --- a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py +++ b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py @@ -105,7 +105,8 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension): @pyqtSlot(str) def updateAllFirmware(self, file_name): - file_name = file_name.replace("file://", "") # File dialogs prepend the path with file://, which we don't need / want + if file_name.startswith("file://"): + file_name = QUrl(file_name).toLocalFile() # File dialogs prepend the path with file://, which we don't need / want if not self._usb_output_devices: Message(i18n_catalog.i18nc("@info", "Unable to update firmware because there are no printers connected.")).show() return From 7a6124f221d420ff73f0fa440d42c785700c590e Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 6 Sep 2016 14:58:29 +0200 Subject: [PATCH 6/8] Get the overhang angle from the proper multiextrusion stack CURA-2289 --- plugins/SolidView/SolidView.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 3b56ac1881..2d017f829f 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -13,6 +13,7 @@ from UM.Settings.Validator import ValidatorState from UM.View.GL.OpenGL import OpenGL import cura.Settings +from cura.Settings.ExtruderManager import ExtruderManager import math @@ -45,8 +46,16 @@ class SolidView(View): global_container_stack = Application.getInstance().getGlobalContainerStack() if global_container_stack: + multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1 + + if multi_extrusion: + support_extruder_nr = global_container_stack.getProperty("support_extruder_nr", "value") + support_angle_stack = ExtruderManager.getInstance().getExtruderStack(support_extruder_nr) + else: + support_angle_stack = global_container_stack + if Preferences.getInstance().getValue("view/show_overhang"): - angle = global_container_stack.getProperty("support_angle", "value") + angle = support_angle_stack.getProperty("support_angle", "value") # Make sure the overhang angle is valid before passing it to the shader # Note: if the overhang angle is set to its default value, it does not need to get validated (validationState = None) if angle is not None and global_container_stack.getProperty("support_angle", "validationState") in [None, ValidatorState.Valid]: @@ -56,7 +65,6 @@ class SolidView(View): else: self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0))) - multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1 for node in DepthFirstIterator(scene.getRoot()): if not node.render(renderer): From a40476eb6236b2c6239f4bfcb7bd87f2e1cdf571 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 6 Sep 2016 15:38:27 +0200 Subject: [PATCH 7/8] Add distinctive titles to profile rename dialogs CURA-2161 --- resources/qml/Preferences/ProfilesPage.qml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 56d8bd41a4..03c66cb59d 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -267,6 +267,7 @@ UM.ManagementPage UM.RenameDialog { + title: catalog.i18nc("@title:window", "Rename Profile") id: renameDialog; object: base.currentItem != null ? base.currentItem.name : "" onAccepted: @@ -279,6 +280,7 @@ UM.ManagementPage // Dialog to request a name when creating a new profile UM.RenameDialog { + title: catalog.i18nc("@title:window", "Create Profile") id: newNameDialog; object: ""; onAccepted: @@ -292,6 +294,7 @@ UM.ManagementPage // Dialog to request a name when duplicating a new profile UM.RenameDialog { + title: catalog.i18nc("@title:window", "Duplicate Profile") id: newDuplicateNameDialog; object: ""; onAccepted: From 68ddf90d5807ca7563f6297f995807b7b96a4845 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 6 Sep 2016 15:39:44 +0200 Subject: [PATCH 8/8] Make behavior of Create Profile consistent between prefs and menu CURA-2161 --- resources/qml/Cura.qml | 9 ++++----- resources/qml/Preferences/ProfilesPage.qml | 9 +++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 42c2ad9cf4..005a0892a3 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -464,12 +464,11 @@ UM.MainWindow target: Cura.Actions.addProfile onTriggered: { - Cura.ContainerManager.createQualityChanges(null); preferences.setPage(4); preferences.show(); - // Show the renameDialog after a very short delay so the preference page has time to initiate - showProfileNameDialogTimer.start(); + // Create a new profile after a very short delay so the preference page has time to initiate + createProfileTimer.start(); } } @@ -516,11 +515,11 @@ UM.MainWindow Timer { - id: showProfileNameDialogTimer + id: createProfileTimer repeat: false interval: 1 - onTriggered: preferences.getCurrentItem().showProfileNameDialog() + onTriggered: preferences.getCurrentItem().createProfile() } // BlurSettings is a way to force the focus away from any of the setting items. diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 03c66cb59d..df8de3f00d 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -141,11 +141,12 @@ UM.ManagementPage scrollviewCaption: catalog.i18nc("@label %1 is printer name","Printer: %1").arg(Cura.MachineManager.activeMachineName) - signal showProfileNameDialog() - onShowProfileNameDialog: + signal createProfile() + onCreateProfile: { - renameDialog.open(); - renameDialog.selectText(); + newNameDialog.object = base.currentItem != null ? base.currentItem.name : ""; + newNameDialog.open(); + newNameDialog.selectText(); } signal selectContainer(string name)