From 328ec0419d080e6b4895b33c29382a468bf969d8 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 28 Jun 2017 11:49:02 +0200 Subject: [PATCH 01/14] Implement gradual support infill CURA-2724 --- resources/definitions/fdmprinter.def.json | 41 +++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index a3642cf897..b421920713 100755 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -3406,6 +3406,47 @@ "enabled": "support_enable", "settable_per_mesh": true }, + "support_infill_sparse_thickness": + { + "label": "Support Infill Layer Thickness", + "description": "The thickness per layer of support infill material. This value should always be a multiple of the layer height and is otherwise rounded.", + "unit": "mm", + "type": "float", + "default_value": 0.1, + "minimum_value": "resolveOrValue('layer_height')", + "maximum_value_warning": "0.75 * machine_nozzle_size", + "maximum_value": "resolveOrValue('layer_height') * 8", + "value": "resolveOrValue('layer_height')", + "enabled": "support_infill_rate > 0", + "limit_to_extruder": "support_infill_extruder_nr", + "settable_per_mesh": false + }, + "gradual_support_infill_steps": + { + "label": "Gradual Support Infill Steps", + "description": "Number of times to reduce the support infill density by half when getting further below top surfaces. Areas which are closer to top surfaces get a higher density, up to the Support Infill Density.", + "default_value": 0, + "type": "int", + "minimum_value": "0", + "maximum_value_warning": "5", + "maximum_value": "999999 if support_line_distance == 0 else (20 - math.log(support_line_distance) / math.log(2))", + "enabled": "support_enable", + "limit_to_extruder": "support_infill_extruder_nr", + "settable_per_mesh": false + }, + "gradual_support_infill_step_height": + { + "label": "Gradual Support Infill Step Height", + "description": "The height of support infill of a given density before switching to half the density.", + "unit": "mm", + "type": "float", + "default_value": 1.5, + "minimum_value": "0.0001", + "minimum_value_warning": "3 * resolveOrValue('layer_height')", + "enabled": "support_enable and gradual_support_infill_steps > 0", + "limit_to_extruder": "support_infill_extruder_nr", + "settable_per_mesh": false + }, "support_interface_enable": { "label": "Enable Support Interface", From 7b494cccf7e929d793f308d2c92a4565794a8a16 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 30 Jun 2017 15:49:35 +0200 Subject: [PATCH 02/14] Only enable gradual_support_infill_steps when support infill density > 0 CURA-2724 --- 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 b421920713..79b52f40e7 100755 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -3430,7 +3430,7 @@ "minimum_value": "0", "maximum_value_warning": "5", "maximum_value": "999999 if support_line_distance == 0 else (20 - math.log(support_line_distance) / math.log(2))", - "enabled": "support_enable", + "enabled": "support_enable and support_infill_rate > 0", "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false }, From 848c607db165fe56990d9ad8b5c0d8295e3ade6b Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 3 Jul 2017 11:11:23 +0200 Subject: [PATCH 03/14] Only enable gradual support if support infill rate > 0 CURA-2724 --- 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 79b52f40e7..509bd4010c 100755 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -3443,7 +3443,7 @@ "default_value": 1.5, "minimum_value": "0.0001", "minimum_value_warning": "3 * resolveOrValue('layer_height')", - "enabled": "support_enable and gradual_support_infill_steps > 0", + "enabled": "support_enable and support_infill_rate > 0 and gradual_support_infill_steps > 0", "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false }, From b2a263b2db843c1c6e947a6594eff96047f462cd Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 4 Jul 2017 11:38:53 +0200 Subject: [PATCH 04/14] Enable support_infill_sparse_thickness when support is enabled CURA-2724 --- 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 509bd4010c..6784113225 100755 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -3417,7 +3417,7 @@ "maximum_value_warning": "0.75 * machine_nozzle_size", "maximum_value": "resolveOrValue('layer_height') * 8", "value": "resolveOrValue('layer_height')", - "enabled": "support_infill_rate > 0", + "enabled": "support_enable and support_infill_rate > 0", "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false }, From ad87f154f3ca7b60543276e66dda3afe9895f970 Mon Sep 17 00:00:00 2001 From: tsaaristo Date: Thu, 6 Jul 2017 15:56:08 +0300 Subject: [PATCH 05/14] Speed up sidebar-settings scrolling Scroll three rows in one scroll event instead of one --- resources/qml/Settings/SettingView.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 06e53cc03b..822322ad2d 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -142,6 +142,7 @@ Item style: UM.Theme.styles.scrollview; flickableItem.flickableDirection: Flickable.VerticalFlick; + __wheelAreaScrollSpeed: 75; // Scroll three lines in one scroll event ListView { From d9c6fc63f296b16831b943b146361a0566ba0f1f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 7 Jul 2017 14:59:35 +0200 Subject: [PATCH 06/14] Clarify description of skin overlap percentage setting It's unclear what this was a percentage of. Contributes to issue CURA-3892. --- 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 6c86ce9912..f5e86b18e1 100755 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1340,7 +1340,7 @@ "skin_overlap": { "label": "Skin Overlap Percentage", - "description": "The amount of overlap between the skin and the walls. A slight overlap allows the walls to connect firmly to the skin.", + "description": "The amount of overlap between the skin and the walls as a percentage of the line width. A slight overlap allows the walls to connect firmly to the skin. This is a percentage of the average line widths of the skin lines and the innermost wall.", "unit": "%", "type": "float", "default_value": 5, From dcdc1a1f637bd0de341746e5313812ae11608429 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Fri, 7 Jul 2017 16:06:31 +0200 Subject: [PATCH 07/14] feat: print thin walls setting (CURA-4023) --- resources/definitions/fdmprinter.def.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 6c86ce9912..116249431b 100755 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1125,6 +1125,14 @@ "limit_to_extruder": "wall_0_extruder_nr", "settable_per_mesh": true }, + "fill_outline_gaps": { + "label": "Print Thin Walls", + "description": "Print pieces of the model which are horizontally thinner than the nozzle size.", + "type": "bool", + "default_value": "false", + "limit_to_extruder": "wall_0_extruder_nr", + "settable_per_mesh": true + }, "xy_offset": { "label": "Horizontal Expansion", From 81e07b153071edb783d33f799785125cf58d6cf1 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 10 Jul 2017 10:35:03 +0200 Subject: [PATCH 08/14] Use stack properties instead of .findContainer(type = ...) Recently we changed the empty containers such that there is only one empty container instance and it doesn't have the proper type any more. Instead we have properties on the stack that allows us to find the container with the proper type. It's faster and easier to use. We've had a few bugs about this so I decided to update all of them to remove those for the future, except the ones in plugins/MachineSettingsAction/MachineSettingsAction.py because we have a pending pull request that fixes those. Fixing them would give merge conflicts for fieldOfView. It doesn't really belong to CURA-4024 but I'm sticking it under that nomer anyway to get it reviewed. --- cura/Settings/CuraContainerRegistry.py | 6 ++---- cura/Settings/MachineManager.py | 14 ++++++-------- cura/Settings/ProfilesModel.py | 4 ++-- .../UltimakerMachineActions/UMOUpgradeSelection.py | 2 +- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index a67b502b4a..ed63e10909 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -340,10 +340,8 @@ class CuraContainerRegistry(ContainerRegistry): # \return the ID of the active material or the empty string def _activeMaterialId(self): global_container_stack = Application.getInstance().getGlobalContainerStack() - if global_container_stack: - material = global_container_stack.findContainer({"type": "material"}) - if material: - return material.getId() + if global_container_stack and global_container_stack.material: + return global_container_stack.material.getId() return "" ## Returns true if the current machien requires its own quality profiles diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 61fec50992..6499e527f5 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -157,7 +157,7 @@ class MachineManager(QObject): if str(index) == extruder.getMetaDataEntry("position"): matching_extruder = extruder break - if matching_extruder and matching_extruder.findContainer({"type": "variant"}).getName() != hotend_id: + if matching_extruder and matching_extruder.variant.getName() != hotend_id: # Save the material that needs to be changed. Multiple changes will be handled by the callback. self._auto_hotends_changed[str(index)] = containers[0].getId() self._printer_output_devices[0].materialHotendChangedMessage(self._materialHotendChangedCallback) @@ -181,11 +181,10 @@ class MachineManager(QObject): matching_extruder = extruder break - if matching_extruder and matching_extruder.findContainer({"type": "material"}).getMetaDataEntry("GUID") != material_id: + if matching_extruder and matching_extruder.material.getMetaDataEntry("GUID") != material_id: # Save the material that needs to be changed. Multiple changes will be handled by the callback. - variant_container = matching_extruder.findContainer({"type": "variant"}) - if self._global_container_stack.getBottom().getMetaDataEntry("has_variants") and variant_container: - variant_id = self.getQualityVariantId(self._global_container_stack.getBottom(), variant_container) + if self._global_container_stack.getBottom().getMetaDataEntry("has_variants") and matching_extruder.variant: + variant_id = self.getQualityVariantId(self._global_container_stack.getBottom(), matching_extruder.variant) for container in containers: if container.getMetaDataEntry("variant") == variant_id: self._auto_materials_changed[str(index)] = container.getId() @@ -507,9 +506,8 @@ class MachineManager(QObject): result = [] if ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks() is not None: for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): - variant_container = stack.findContainer({"type": "variant"}) - if variant_container and variant_container != self._empty_variant_container: - result.append(variant_container.getId()) + if stack.variant and stack.variant != self._empty_variant_container: + result.append(stack.variant.getId()) return result diff --git a/cura/Settings/ProfilesModel.py b/cura/Settings/ProfilesModel.py index 9056273216..18acb5e9e8 100644 --- a/cura/Settings/ProfilesModel.py +++ b/cura/Settings/ProfilesModel.py @@ -107,9 +107,9 @@ class ProfilesModel(InstanceContainersModel): continue #Quality has no value for layer height either. Get the layer height from somewhere lower in the stack. - skip_until_container = global_container_stack.findContainer({"type": "material"}) + skip_until_container = global_container_stack.material if not skip_until_container: #No material in stack. - skip_until_container = global_container_stack.findContainer({"type": "variant"}) + skip_until_container = global_container_stack.variant if not skip_until_container: #No variant in stack. skip_until_container = global_container_stack.getBottom() item["layer_height"] = str(global_container_stack.getRawProperty("layer_height", "value", skip_until_container = skip_until_container.getId())) + unit #Fall through to the currently loaded material. diff --git a/plugins/UltimakerMachineActions/UMOUpgradeSelection.py b/plugins/UltimakerMachineActions/UMOUpgradeSelection.py index 70a9d3fa0e..476089e533 100644 --- a/plugins/UltimakerMachineActions/UMOUpgradeSelection.py +++ b/plugins/UltimakerMachineActions/UMOUpgradeSelection.py @@ -36,7 +36,7 @@ class UMOUpgradeSelection(MachineAction): global_container_stack = Application.getInstance().getGlobalContainerStack() if global_container_stack: # Make sure there is a definition_changes container to store the machine settings - definition_changes_container = global_container_stack.findContainer({"type": "definition_changes"}) + definition_changes_container = global_container_stack.definition_changes if not definition_changes_container: definition_changes_container = self._createDefinitionChangesContainer(global_container_stack) From f0d327c0d0678be0bcab28f8bff7aae7433eeeb6 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 10 Jul 2017 11:22:35 +0200 Subject: [PATCH 09/14] Set setting_version properly on new stacks so you don't need to upgrade I don't think stacks had a setting_version property previously. Contributes to issue CURA-4024. --- cura/Settings/CuraContainerStack.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cura/Settings/CuraContainerStack.py b/cura/Settings/CuraContainerStack.py index fc90e3b239..75f3034362 100755 --- a/cura/Settings/CuraContainerStack.py +++ b/cura/Settings/CuraContainerStack.py @@ -8,6 +8,7 @@ from typing import Any, Optional from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject from UM.FlameProfiler import pyqtSlot +import cura.CuraApplication #To get the setting version. from UM.Decorators import override from UM.Logger import Logger from UM.Settings.ContainerStack import ContainerStack, InvalidContainerStackError @@ -47,6 +48,8 @@ class CuraContainerStack(ContainerStack): self.containersChanged.connect(self._onContainersChanged) + self.addMetaDataEntry("setting_version", cura.CuraApplication.CuraApplication.SettingVersion) + # This is emitted whenever the containersChanged signal from the ContainerStack base class is emitted. pyqtContainersChanged = pyqtSignal() From 9bfe18393fa699ae7a7203c82ff6efca783f8fce Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 10 Jul 2017 11:45:03 +0200 Subject: [PATCH 10/14] Make sure the preferences file doesn't always get upgraded When the setting is equal to the default the setting_version won't get written to the preferences file. In that case the version upgrade system assumes that the setting_version was 0 or 1 and upgrades it. This makes sure that the setting is never equal to the default so that it always gets written. Found while working on CURA-4024. --- cura/CuraApplication.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 048973c5c4..418b3c0e9b 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -268,7 +268,8 @@ class CuraApplication(QtApplication): ContainerRegistry.getInstance().load() # set the setting version for Preferences - Preferences.getInstance().addPreference("metadata/setting_version", CuraApplication.SettingVersion) + Preferences.getInstance().addPreference("metadata/setting_version", 0) + Preferences.getInstance().setValue("metadata/setting_version", self.SettingVersion) #Don't make it equal to the default so that the setting version always gets written to the file. Preferences.getInstance().addPreference("cura/active_mode", "simple") From 8822307e026d659412a7dd6e9e4a32a323e4d7cf Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 10 Jul 2017 11:54:27 +0200 Subject: [PATCH 11/14] Cache preferences instance during start-up Perhaps a bit faster and less code duplication. Contributes to issue CURA-4024. --- cura/CuraApplication.py | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 418b3c0e9b..211c98782e 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -268,36 +268,37 @@ class CuraApplication(QtApplication): ContainerRegistry.getInstance().load() # set the setting version for Preferences - Preferences.getInstance().addPreference("metadata/setting_version", 0) - Preferences.getInstance().setValue("metadata/setting_version", self.SettingVersion) #Don't make it equal to the default so that the setting version always gets written to the file. + preferences = Preferences.getInstance() + preferences.addPreference("metadata/setting_version", 0) + preferences.setValue("metadata/setting_version", self.SettingVersion) #Don't make it equal to the default so that the setting version always gets written to the file. - Preferences.getInstance().addPreference("cura/active_mode", "simple") + preferences.addPreference("cura/active_mode", "simple") - Preferences.getInstance().addPreference("cura/categories_expanded", "") - Preferences.getInstance().addPreference("cura/jobname_prefix", True) - Preferences.getInstance().addPreference("view/center_on_select", True) - Preferences.getInstance().addPreference("mesh/scale_to_fit", False) - Preferences.getInstance().addPreference("mesh/scale_tiny_meshes", True) - Preferences.getInstance().addPreference("cura/dialog_on_project_save", True) - Preferences.getInstance().addPreference("cura/asked_dialog_on_project_save", False) - Preferences.getInstance().addPreference("cura/choice_on_profile_override", "always_ask") - Preferences.getInstance().addPreference("cura/choice_on_open_project", "always_ask") + preferences.addPreference("cura/categories_expanded", "") + preferences.addPreference("cura/jobname_prefix", True) + preferences.addPreference("view/center_on_select", True) + preferences.addPreference("mesh/scale_to_fit", False) + preferences.addPreference("mesh/scale_tiny_meshes", True) + preferences.addPreference("cura/dialog_on_project_save", True) + preferences.addPreference("cura/asked_dialog_on_project_save", False) + preferences.addPreference("cura/choice_on_profile_override", "always_ask") + preferences.addPreference("cura/choice_on_open_project", "always_ask") - Preferences.getInstance().addPreference("cura/currency", "€") - Preferences.getInstance().addPreference("cura/material_settings", "{}") + preferences.addPreference("cura/currency", "€") + preferences.addPreference("cura/material_settings", "{}") - Preferences.getInstance().addPreference("view/invert_zoom", False) + preferences.addPreference("view/invert_zoom", False) for key in [ "dialog_load_path", # dialog_save_path is in LocalFileOutputDevicePlugin "dialog_profile_path", "dialog_material_path"]: - Preferences.getInstance().addPreference("local_file/%s" % key, os.path.expanduser("~/")) + preferences.addPreference("local_file/%s" % key, os.path.expanduser("~/")) - Preferences.getInstance().setDefault("local_file/last_used_type", "text/x-gcode") + preferences.setDefault("local_file/last_used_type", "text/x-gcode") - Preferences.getInstance().setDefault("general/visible_settings", """ + preferences.setDefault("general/visible_settings", """ machine_settings resolution layer_height From 6d2b46244f910cc5f09b07bdde1955bdcde77afb Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 10 Jul 2017 13:38:40 +0200 Subject: [PATCH 12/14] Home printer after aborting Otherwise the head gets left on top of the print and you'd have to manually move it aside after each abort. --- plugins/USBPrinting/USBPrinterOutputDevice.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index 0100874eab..8ecb503ed8 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -622,6 +622,8 @@ class USBPrinterOutputDevice(PrinterOutputDevice): self._sendCommand("M140 S0") self._sendCommand("M104 S0") self._sendCommand("M107") + self.homeHead() + self.homeBed() self._sendCommand("M84") self._is_printing = False self._is_paused = False From ee52e1b9eaf055433ce5c3367045402c078b50df Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 10 Jul 2017 14:20:49 +0200 Subject: [PATCH 13/14] Reposition prime tower automatically This actually looks really nice. It just moves right along that border there. Eventually we could also auto-position the X position but for now this is fine. --- resources/definitions/ultimaker3.def.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/definitions/ultimaker3.def.json b/resources/definitions/ultimaker3.def.json index 43f1453d72..3ee6ac61bb 100644 --- a/resources/definitions/ultimaker3.def.json +++ b/resources/definitions/ultimaker3.def.json @@ -70,7 +70,7 @@ "machine_start_gcode": { "default_value": "" }, "machine_end_gcode": { "default_value": "" }, "prime_tower_position_x": { "default_value": 175 }, - "prime_tower_position_y": { "default_value": 177 }, + "prime_tower_position_y": { "value": "machine_depth - prime_tower_size - (brim_width if adhesion_type == 'brim' else (raft_margin if adhesion_type == 'raft' else (skirt_gap if adhesion_type == 'skirt' else 0))) - 1" }, "prime_tower_wipe_enabled": { "default_value": false }, "prime_blob_enable": { "enabled": true }, From 012d299d980e87136feb8da4062de6940b378c9d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 10 Jul 2017 16:42:38 +0200 Subject: [PATCH 14/14] Prevent circular import When this is imported during the __init__, it'll long have been imported elsewhere and won't need to import it again but still guarantees that it is actually imported if no other module does it first. Contributes to issue CURA-4024. --- cura/Settings/CuraContainerStack.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/CuraContainerStack.py b/cura/Settings/CuraContainerStack.py index 75f3034362..cdda14ee18 100755 --- a/cura/Settings/CuraContainerStack.py +++ b/cura/Settings/CuraContainerStack.py @@ -8,7 +8,6 @@ from typing import Any, Optional from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject from UM.FlameProfiler import pyqtSlot -import cura.CuraApplication #To get the setting version. from UM.Decorators import override from UM.Logger import Logger from UM.Settings.ContainerStack import ContainerStack, InvalidContainerStackError @@ -48,6 +47,7 @@ class CuraContainerStack(ContainerStack): self.containersChanged.connect(self._onContainersChanged) + import cura.CuraApplication #Here to prevent circular imports. self.addMetaDataEntry("setting_version", cura.CuraApplication.CuraApplication.SettingVersion) # This is emitted whenever the containersChanged signal from the ContainerStack base class is emitted.