From e40abb5d3757a8c6e0b91dcddd03b41fefe087a9 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 10 Nov 2016 16:42:09 +0100 Subject: [PATCH 01/29] feat: cool_fan_speed_0 (CURA-2182) --- resources/definitions/fdmprinter.def.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 9edf1499b3..d7b671d173 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -2373,6 +2373,20 @@ "settable_per_extruder": true, "children": { + "cool_fan_speed_0": + { + "label": "Initial Fan Speed", + "description": "The speed at which the fans spin at the start of the print. In subsequent layers the fan speed is gradually increased up to the layer corresponding to Regular Fan Speed at Height.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value": "100", + "value": "cool_fan_speed", + "default_value": 100, + "enabled": "cool_fan_enabled", + "settable_per_mesh": false, + "settable_per_extruder": true + }, "cool_fan_speed_min": { "label": "Regular Fan Speed", @@ -2418,7 +2432,7 @@ "cool_fan_full_at_height": { "label": "Regular Fan Speed at Height", - "description": "The height at which the fans spin on regular fan speed. At the layers below the fan speed gradually increases from zero to regular fan speed.", + "description": "The height at which the fans spin on regular fan speed. At the layers below the fan speed gradually increases from Initial Fan Speed to Regular Fan Speed.", "unit": "mm", "type": "float", "default_value": 0.5, From 337cd127dccac02bed809b1549d069f29dda3b8f Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 14 Nov 2016 12:02:23 +0100 Subject: [PATCH 02/29] JSOn feat: adhesion_type none (CURA-759) --- resources/definitions/fdmprinter.def.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index ce6a341467..7c5200ba1f 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -2985,7 +2985,8 @@ { "skirt": "Skirt", "brim": "Brim", - "raft": "Raft" + "raft": "Raft", + "none": "None" }, "default_value": "brim", "resolve": "'raft' if 'raft' in extruderValues('adhesion_type') else ('brim' if 'brim' in extruderValues('adhesion_type') else 'skirt')", From 995705f82b610a683bc58c1daf22bc78124dfca9 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 14 Nov 2016 12:36:21 +0100 Subject: [PATCH 03/29] fix: don't expand disallowed areas when using none platform adhesion (CURA-759) --- cura/BuildVolume.py | 2 ++ cura/ConvexHullDecorator.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index 327f79f67b..51b7e07794 100644 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -653,6 +653,8 @@ class BuildVolume(SceneNode): bed_adhesion_size += value elif adhesion_type == "raft": bed_adhesion_size = self._getSettingFromAdhesionExtruder("raft_margin") + elif adhesion_type == "none": + bed_adhesion_size = 0 else: raise Exception("Unknown bed adhesion type. Did you forget to update the build volume calculations for your new bed adhesion type?") diff --git a/cura/ConvexHullDecorator.py b/cura/ConvexHullDecorator.py index a7d0775e21..c4b2fe0337 100644 --- a/cura/ConvexHullDecorator.py +++ b/cura/ConvexHullDecorator.py @@ -236,6 +236,8 @@ class ConvexHullDecorator(SceneNodeDecorator): extra_margin = max(0, self._getSettingProperty("raft_margin", "value")) elif adhesion_type == "brim": extra_margin = max(0, self._getSettingProperty("brim_line_count", "value") * self._getSettingProperty("skirt_brim_line_width", "value")) + elif adhesion_type == "none": + extra_margin = 0 elif adhesion_type == "skirt": extra_margin = max( 0, self._getSettingProperty("skirt_gap", "value") + From 0c550859ddea84c172a8cc3a75adff47f803b7fb Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 14 Nov 2016 12:39:41 +0100 Subject: [PATCH 04/29] fix: don't register adhesion_extruder_nr as used if adhesion_type == none (CURA-759) Also the old line obtained brim_line_count from the global stack, while it is settable_per_extruder! Also we now assume selecting a brim means you want to print it. I don't think having a brim line count of zero meant that you wouldnt get a brim; the minimal brim length also plays a role... --- cura/Settings/ExtruderManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 5517830141..a3eef51009 100644 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -336,8 +336,8 @@ class ExtruderManager(QObject): if support_interface_enabled: used_extruder_stack_ids.add(self.extruderIds[str(global_stack.getProperty("support_interface_extruder_nr", "value"))]) - #The platform adhesion extruder. Not used if using brim and brim width is 0. - if global_stack.getProperty("adhesion_type", "value") != "brim" or global_stack.getProperty("brim_line_count", "value") > 0: + #The platform adhesion extruder. Not used if using none. + if global_stack.getProperty("adhesion_type", "value") != "none": used_extruder_stack_ids.add(self.extruderIds[str(global_stack.getProperty("adhesion_extruder_nr", "value"))]) return [container_registry.findContainerStacks(id = stack_id)[0] for stack_id in used_extruder_stack_ids] From 16828d98d482bb92c7b37857da2d36073e1304e5 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 14 Nov 2016 12:50:01 +0100 Subject: [PATCH 05/29] JSON spelling fix: draft ==> draught (CURA-759) --- resources/definitions/fdmprinter.def.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 7c5200ba1f..c4be63f917 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -3821,7 +3821,7 @@ { "draft_shield_enabled": { - "label": "Enable Draft Shield", + "label": "Enable Draught Shield", "description": "This will create a wall around the model, which traps (hot) air and shields against exterior airflow. Especially useful for materials which warp easily.", "type": "bool", "default_value": false, @@ -3830,8 +3830,8 @@ }, "draft_shield_dist": { - "label": "Draft Shield X/Y Distance", - "description": "Distance of the draft shield from the print, in the X/Y directions.", + "label": "Draught Shield X/Y Distance", + "description": "Distance of the draught shield from the print, in the X/Y directions.", "unit": "mm", "type": "float", "minimum_value": "0", @@ -3844,8 +3844,8 @@ }, "draft_shield_height_limitation": { - "label": "Draft Shield Limitation", - "description": "Set the height of the draft shield. Choose to print the draft shield at the full height of the model or at a limited height.", + "label": "Draught Shield Limitation", + "description": "Set the height of the draught shield. Choose to print the draught shield at the full height of the model or at a limited height.", "type": "enum", "options": { @@ -3860,8 +3860,8 @@ }, "draft_shield_height": { - "label": "Draft Shield Height", - "description": "Height limitation of the draft shield. Above this height no draft shield will be printed.", + "label": "Draught Shield Height", + "description": "Height limitation of the draught shield. Above this height no draught shield will be printed.", "unit": "mm", "type": "float", "minimum_value": "0", From ff141747243d5f1e67e1370876c11f376dd3f794 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 16 Nov 2016 17:15:37 +0100 Subject: [PATCH 06/29] Revert "JSON spelling fix: draft ==> draught (CURA-759)" This reverts commit 16828d98d482bb92c7b37857da2d36073e1304e5. --- resources/definitions/fdmprinter.def.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index c4be63f917..7c5200ba1f 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -3821,7 +3821,7 @@ { "draft_shield_enabled": { - "label": "Enable Draught Shield", + "label": "Enable Draft Shield", "description": "This will create a wall around the model, which traps (hot) air and shields against exterior airflow. Especially useful for materials which warp easily.", "type": "bool", "default_value": false, @@ -3830,8 +3830,8 @@ }, "draft_shield_dist": { - "label": "Draught Shield X/Y Distance", - "description": "Distance of the draught shield from the print, in the X/Y directions.", + "label": "Draft Shield X/Y Distance", + "description": "Distance of the draft shield from the print, in the X/Y directions.", "unit": "mm", "type": "float", "minimum_value": "0", @@ -3844,8 +3844,8 @@ }, "draft_shield_height_limitation": { - "label": "Draught Shield Limitation", - "description": "Set the height of the draught shield. Choose to print the draught shield at the full height of the model or at a limited height.", + "label": "Draft Shield Limitation", + "description": "Set the height of the draft shield. Choose to print the draft shield at the full height of the model or at a limited height.", "type": "enum", "options": { @@ -3860,8 +3860,8 @@ }, "draft_shield_height": { - "label": "Draught Shield Height", - "description": "Height limitation of the draught shield. Above this height no draught shield will be printed.", + "label": "Draft Shield Height", + "description": "Height limitation of the draft shield. Above this height no draft shield will be printed.", "unit": "mm", "type": "float", "minimum_value": "0", From 4da9b99ff803e5751af825aefd67cd9346bb93e2 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 17 Nov 2016 12:43:14 +0100 Subject: [PATCH 07/29] Disable print sequence for all multi-extrusion machines Also for ORD and whatever else we have. It is now more inherent in the setting and it gives a better indication of why the setting is disabled when you hover the 'i' in the setting visibility screen. --- resources/definitions/fdmprinter.def.json | 3 ++- resources/definitions/ultimaker3.def.json | 2 -- resources/definitions/ultimaker_original_dual.def.json | 3 --- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 1962476424..8ac4f4f6e4 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -169,7 +169,7 @@ }, "machine_extruder_count": { - "label": "Number extruders", + "label": "Number of Extruders", "description": "Number of extruder trains. An extruder train is the combination of a feeder, bowden tube, and nozzle.", "default_value": 1, "minimum_value": "1", @@ -3769,6 +3769,7 @@ "one_at_a_time": "One at a Time" }, "default_value": "all_at_once", + "enabled": "machine_extruder_count == 1", "settable_per_mesh": false, "settable_per_extruder": false, "settable_per_meshgroup": false diff --git a/resources/definitions/ultimaker3.def.json b/resources/definitions/ultimaker3.def.json index 16feda7d64..f9ee93ee65 100644 --- a/resources/definitions/ultimaker3.def.json +++ b/resources/definitions/ultimaker3.def.json @@ -71,8 +71,6 @@ "prime_tower_position_x": { "default_value": 175 }, "prime_tower_position_y": { "default_value": 179 }, - "print_sequence": {"enabled": false}, - "acceleration_enabled": { "value": "True" }, "acceleration_layer_0": { "value": "acceleration_topbottom" }, "acceleration_prime_tower": { "value": "math.ceil(acceleration_print * 2000 / 4000)" }, diff --git a/resources/definitions/ultimaker_original_dual.def.json b/resources/definitions/ultimaker_original_dual.def.json index 48d2436b92..ab2f3ddf46 100644 --- a/resources/definitions/ultimaker_original_dual.def.json +++ b/resources/definitions/ultimaker_original_dual.def.json @@ -72,9 +72,6 @@ "machine_extruder_count": { "default_value": 2 }, - "print_sequence": { - "enabled": false - }, "prime_tower_position_x": { "default_value": 185 }, From 54825151577512803f908a982c8f762d2c64ae4a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 17 Nov 2016 13:15:25 +0100 Subject: [PATCH 08/29] Importing profiles from g-code made by Cura 2.3 is now possible again CURA-2943 --- plugins/GCodeProfileReader/GCodeProfileReader.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/plugins/GCodeProfileReader/GCodeProfileReader.py b/plugins/GCodeProfileReader/GCodeProfileReader.py index 24c92d08e9..abfef6e296 100644 --- a/plugins/GCodeProfileReader/GCodeProfileReader.py +++ b/plugins/GCodeProfileReader/GCodeProfileReader.py @@ -70,10 +70,19 @@ class GCodeProfileReader(ProfileReader): json_data = json.loads(serialized) - profile_strings = [json_data["global_quality"]] - profile_strings.extend(json_data.get("extruder_quality", [])) + profiles = [] + global_profile = readQualityProfileFromString(json_data["global_quality"]) - return [readQualityProfileFromString(profile_string) for profile_string in profile_strings] + # This is a fix for profiles created with 2.3.0 For some reason it added the "extruder" property to the + # global profile. + # The fix is simple and safe, as a global profile should never have the extruder entry. + if global_profile.getMetaDataEntry("extruder", None) is not None: + global_profile.setMetaDataEntry("extruder", None) + profiles.append(global_profile) + + for profile_string in json_data.get("extruder_quality", []): + profiles.append(readQualityProfileFromString(profile_string)) + return profiles ## Unescape a string which has been escaped for use in a gcode comment. # From 891eda203e34f1e493bd14e1d7254edb109bb87e Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 17 Nov 2016 14:57:26 +0100 Subject: [PATCH 09/29] JSOn fix: start each layer near switching bay (CURA-1112) --- resources/definitions/ultimaker3.def.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/definitions/ultimaker3.def.json b/resources/definitions/ultimaker3.def.json index f9ee93ee65..1356efff91 100644 --- a/resources/definitions/ultimaker3.def.json +++ b/resources/definitions/ultimaker3.def.json @@ -99,8 +99,8 @@ "jerk_wall": { "value": "math.ceil(jerk_print * 10 / 25)" }, "jerk_wall_0": { "value": "math.ceil(jerk_wall * 5 / 10)" }, "layer_height_0": { "value": "round(machine_nozzle_size / 1.5, 2)" }, - "layer_start_x": { "value": "sum(extruderValues('extruder_prime_pos_x')) / len(extruderValues('extruder_prime_pos_x'))" }, - "layer_start_y": { "value": "sum(extruderValues('extruder_prime_pos_y')) / len(extruderValues('extruder_prime_pos_y'))" }, + "layer_start_x": { "value": "sum(extruderValues('machine_extruder_start_pos_x')) / len(extruderValues('machine_extruder_start_pos_x'))" }, + "layer_start_y": { "value": "sum(extruderValues('machine_extruder_start_pos_y')) / len(extruderValues('machine_extruder_start_pos_y'))" }, "line_width": { "value": "machine_nozzle_size * 0.875" }, "machine_min_cool_heat_time_window": { "value": "15" }, "material_print_temperature": { "value": "200" }, From 7bba0eb9301296084b4d05f272cefd371940deee Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 17 Nov 2016 19:54:38 +0100 Subject: [PATCH 10/29] JSON: feat: alternate_carve_order (CURA-2992) --- resources/definitions/fdmprinter.def.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 8ac4f4f6e4..ccf6c13db5 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -3747,6 +3747,17 @@ "settable_per_mesh": false, "settable_per_extruder": false, "settable_per_meshgroup": true + }, + "alternate_carve_order": + { + "label": "Alternate Mesh Removal", + "description": "With every layer switch from which model intersecting volumes are removed, so that the overlapping volumes become interwoven.", + "type": "bool", + "default_value": true, + "enabled": "carve_multiple_volumes", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true } } }, From 850fcac9c29f067963e5cbd3f063b09d8b6b715d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 18 Nov 2016 10:41:07 +0100 Subject: [PATCH 11/29] Build plate extruder now hides itself if the adhesion type is none CURA-759 --- 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 16a1e8f44d..6803b65e49 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -3011,7 +3011,7 @@ "description": "The extruder train to use for printing the skirt/brim/raft. This is used in multi-extrusion.", "type": "extruder", "default_value": "0", - "enabled": "machine_extruder_count > 1", + "enabled": "machine_extruder_count > 1 and resolveOrValue('adhesion_type') != 'none'", "settable_per_mesh": false, "settable_per_extruder": false }, From 2e1f4e374042f5dcaf4f3a6c495381d503681122 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 18 Nov 2016 12:39:19 +0100 Subject: [PATCH 12/29] Serialize now uses base_file as well instead of only GUID to find containers to use CURA-2467 --- plugins/XmlMaterialProfile/XmlMaterialProfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 07acc5c37c..fd48280fb2 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -165,7 +165,7 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): machine_container_map = {} machine_nozzle_map = {} - all_containers = registry.findInstanceContainers(GUID = self.getMetaDataEntry("GUID")) + all_containers = registry.findInstanceContainers(GUID = self.getMetaDataEntry("GUID"), base_file = self._id) for container in all_containers: definition_id = container.getDefinition().id if definition_id == "fdmprinter": From a71bb633189ac084742c59baa6e70f6ab2656214 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 18 Nov 2016 12:50:51 +0100 Subject: [PATCH 13/29] Resetting transformation now works again for ungrouped nodes CURA-2925 --- cura/CuraApplication.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 0216bacce4..a445f127ef 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -799,11 +799,9 @@ class CuraApplication(QtApplication): for node in nodes: # Ensure that the object is above the build platform node.removeDecorator(ZOffsetDecorator.ZOffsetDecorator) - center_y = 0 - if node.callDecoration("isGroup"): - center_y = node.getWorldPosition().y - node.getBoundingBox().bottom - else: - center_y = node.getMeshData().getCenterPosition().y + + center_y = node.getWorldPosition().y - node.getBoundingBox().bottom + op.addOperation(SetTransformOperation(node, Vector(0, center_y, 0), Quaternion(), Vector(1, 1, 1))) op.push() From d2a50cada123477cccea675a39ff16b91cb52f95 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 18 Nov 2016 12:56:07 +0100 Subject: [PATCH 14/29] Only reset transformation/ position if there is a bounding box. If a node has no bounding box, it's because it has no data to change. CURA-2925 --- cura/CuraApplication.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index a445f127ef..5c186fbe75 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -777,7 +777,8 @@ class CuraApplication(QtApplication): for node in nodes: # Ensure that the object is above the build platform node.removeDecorator(ZOffsetDecorator.ZOffsetDecorator) - op.addOperation(SetTransformOperation(node, Vector(0, node.getWorldPosition().y - node.getBoundingBox().bottom, 0))) + if node.getBoundingBox(): + op.addOperation(SetTransformOperation(node, Vector(0, node.getWorldPosition().y - node.getBoundingBox().bottom, 0))) op.push() ## Reset all transformations on nodes with mesh data. @@ -799,10 +800,9 @@ class CuraApplication(QtApplication): for node in nodes: # Ensure that the object is above the build platform node.removeDecorator(ZOffsetDecorator.ZOffsetDecorator) - - center_y = node.getWorldPosition().y - node.getBoundingBox().bottom - - op.addOperation(SetTransformOperation(node, Vector(0, center_y, 0), Quaternion(), Vector(1, 1, 1))) + if node.getBoundingBox(): + center_y = node.getWorldPosition().y - node.getBoundingBox().bottom + op.addOperation(SetTransformOperation(node, Vector(0, center_y, 0), Quaternion(), Vector(1, 1, 1))) op.push() ## Reload all mesh data on the screen from file. From 312bd2a963af8ac732849528820bd457814986b9 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 18 Nov 2016 13:28:14 +0100 Subject: [PATCH 15/29] Resetting now simply resets everything to 0 if there is no bounding box For the current usage, this won't change anything, but it's more future proof CURA-2925 --- cura/CuraApplication.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 5c186fbe75..5ac414f00d 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -778,7 +778,10 @@ class CuraApplication(QtApplication): # Ensure that the object is above the build platform node.removeDecorator(ZOffsetDecorator.ZOffsetDecorator) if node.getBoundingBox(): - op.addOperation(SetTransformOperation(node, Vector(0, node.getWorldPosition().y - node.getBoundingBox().bottom, 0))) + center_y = node.getWorldPosition().y - node.getBoundingBox().bottom + else: + center_y = 0 + op.addOperation(SetTransformOperation(node, Vector(0, center_y, 0))) op.push() ## Reset all transformations on nodes with mesh data. @@ -802,7 +805,9 @@ class CuraApplication(QtApplication): node.removeDecorator(ZOffsetDecorator.ZOffsetDecorator) if node.getBoundingBox(): center_y = node.getWorldPosition().y - node.getBoundingBox().bottom - op.addOperation(SetTransformOperation(node, Vector(0, center_y, 0), Quaternion(), Vector(1, 1, 1))) + else: + center_y = 0 + op.addOperation(SetTransformOperation(node, Vector(0, center_y, 0), Quaternion(), Vector(1, 1, 1))) op.push() ## Reload all mesh data on the screen from file. From c007c1fc4cacd3e1afd176ee1c9945003e30bf79 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 18 Nov 2016 14:17:46 +0100 Subject: [PATCH 16/29] Fixed global error keys always overriding the extruder error keys CURA-2481 --- plugins/CuraEngineBackend/CuraEngineBackend.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 89b3ed7a82..c04e4d74f5 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -243,9 +243,8 @@ class CuraEngineBackend(Backend): error_keys = [] for extruder in extruders: error_keys.extend(extruder.getErrorKeys()) - else: + if not extruders: error_keys = self._global_container_stack.getErrorKeys() - error_labels = set() definition_container = self._global_container_stack.getBottom() for key in error_keys: From 782a02661cb4d8076751584247deec6cac7e7eb7 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 18 Nov 2016 14:24:32 +0100 Subject: [PATCH 17/29] If prime tower or prime position has an invalid position, we now give a specifc error message to indicate this CURA-2481 --- plugins/CuraEngineBackend/CuraEngineBackend.py | 11 +++++++++++ plugins/CuraEngineBackend/StartSliceJob.py | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index c04e4d74f5..9d448e11bb 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -220,6 +220,9 @@ class CuraEngineBackend(Backend): # # \param job The start slice job that was just finished. def _onStartSliceCompleted(self, job): + if self._error_message: + self._error_message.hide() + # Note that cancelled slice jobs can still call this method. if self._start_slice_job is job: self._start_slice_job = None @@ -258,6 +261,14 @@ class CuraEngineBackend(Backend): self.backendStateChange.emit(BackendState.NotStarted) return + if job.getResult() == StartSliceJob.StartJobResult.BuildPlateError: + if Application.getInstance().getPlatformActivity: + self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice because the prime tower or prime position(s) are invalid.")) + self._error_message.show() + self.backendStateChange.emit(BackendState.Error) + else: + self.backendStateChange.emit(BackendState.NotStarted) + if job.getResult() == StartSliceJob.StartJobResult.NothingToSlice: if Application.getInstance().getPlatformActivity: self._error_message = Message(catalog.i18nc("@info:status", "Nothing to slice because none of the models fit the build volume. Please scale or rotate models to fit.")) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index b343c307af..0319186518 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -25,6 +25,7 @@ class StartJobResult(IntEnum): SettingError = 3 NothingToSlice = 4 MaterialIncompatible = 5 + BuildPlateError = 6 ## Formatter class that handles token expansion in start/end gcod @@ -80,7 +81,7 @@ class StartSliceJob(Job): return if Application.getInstance().getBuildVolume().hasErrors(): - self.setResult(StartJobResult.SettingError) + self.setResult(StartJobResult.BuildPlateError) return for extruder_stack in cura.Settings.ExtruderManager.getInstance().getMachineExtruders(stack.getId()): From cc7b2a4901ce1214f2d9c24949be090ff83d24bf Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Fri, 11 Nov 2016 14:39:13 +0100 Subject: [PATCH 18/29] JSON feat: perimeter_gaps as it was in e57ca0aa53def8342cfc18971cafbe4b39caffec (CURA-2306) --- resources/definitions/fdmprinter.def.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 0e1ff7db49..6b7b9be42a 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -921,6 +921,18 @@ } } }, + "fill_perimeter_gaps": { + "label": "Fill Gaps Between Walls", + "description": "Fills the gaps between walls where no walls fit.", + "type": "enum", + "options": { + "nowhere": "Nowhere", + "everywhere": "Everywhere", + "skin": "Skin" + }, + "default_value": "everywhere", + "settable_per_mesh": true + }, "xy_offset": { "label": "Horizontal Expansion", From 8dbe018a5bbdb5c3fe7e0765e99ecc65f7565692 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Fri, 11 Nov 2016 14:59:40 +0100 Subject: [PATCH 19/29] JSON removal: removed the gap filling option 'skin' (CURA-2306) --- resources/definitions/fdmprinter.def.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 6b7b9be42a..57641e63df 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -927,8 +927,7 @@ "type": "enum", "options": { "nowhere": "Nowhere", - "everywhere": "Everywhere", - "skin": "Skin" + "everywhere": "Everywhere" }, "default_value": "everywhere", "settable_per_mesh": true From c1650125e9b690245e2f48cd5c9c19694ce0c0cc Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 18 Nov 2016 15:43:32 +0100 Subject: [PATCH 20/29] The compatible setting is now serialized correctly CURA-2940 --- plugins/XmlMaterialProfile/XmlMaterialProfile.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index fd48280fb2..30d1307d01 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -209,7 +209,17 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): if not variant_containers: continue - builder.start("hotend", { "id": variant_containers[0].getName() }) + builder.start("hotend", {"id": variant_containers[0].getName()}) + + # Compatible is a special case, as it's added as a meta data entry (instead of an instance). + compatible = hotend.getMetaDataEntry("compatible") + if compatible is not None: + builder.start("setting", {"key": "hardware compatible"}) + if compatible: + builder.data("yes") + else: + builder.data("no") + builder.end("setting") for instance in hotend.findInstances(): if container.getInstance(instance.definition.key) and container.getProperty(instance.definition.key, "value") == instance.value: From 1b01455c36a21fad9ce7454dbd01a7cf3c4e8c11 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 18 Nov 2016 16:15:53 +0100 Subject: [PATCH 21/29] Increased tolerance around prime area CURA-2934 --- cura/BuildVolume.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index 534cae1bbb..603cda14d1 100644 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -27,7 +27,7 @@ import UM.Settings.ContainerRegistry # Setting for clearance around the prime -PRIME_CLEARANCE = 1.5 +PRIME_CLEARANCE = 6.5 ## Build volume is a special kind of node that is responsible for rendering the printable area & disallowed areas. From ac708d54b696aa09598915942fc84efc9ae4dcba Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 18 Nov 2016 16:46:54 +0100 Subject: [PATCH 22/29] Importing invalid filetypes now gives proper error messages CURA-2883 --- cura/Settings/CuraContainerRegistry.py | 2 +- plugins/CuraProfileReader/CuraProfileReader.py | 2 ++ plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 98c37da617..3982418070 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -210,7 +210,7 @@ class CuraContainerRegistry(ContainerRegistry): return {"status": "ok", "message": catalog.i18nc("@info:status", "Successfully imported profile {0}", profile_or_list[0].getName())} # If it hasn't returned by now, none of the plugins loaded the profile successfully. - return {"status": "error", "message": catalog.i18nc("@info:status", "Profile {0} has an unknown file type.", file_name)} + return {"status": "error", "message": catalog.i18nc("@info:status", "Profile {0} has an unknown file type or is corrupted.", file_name)} def _configureProfile(self, profile, id_seed, new_name): profile.setReadOnly(False) diff --git a/plugins/CuraProfileReader/CuraProfileReader.py b/plugins/CuraProfileReader/CuraProfileReader.py index d1be5b59a8..2198d73b22 100644 --- a/plugins/CuraProfileReader/CuraProfileReader.py +++ b/plugins/CuraProfileReader/CuraProfileReader.py @@ -99,4 +99,6 @@ class CuraProfileReader(ProfileReader): return [] filenames, outputs = profile_convert_funcs[0](serialized, profile_id) + if filenames is None and outputs is None: + return [] return list(zip(outputs, filenames)) diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py b/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py index d7d20db071..e55a89faf3 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py @@ -5,6 +5,7 @@ import configparser #To read config files. import io #To write config files to strings as if they were files. import UM.VersionUpgrade +from UM.Logger import Logger ## Creates a new profile instance by parsing a serialised profile in version 1 # of the file format. @@ -80,6 +81,7 @@ class Profile: import VersionUpgrade21to22 # Import here to prevent circular dependencies. if self._name == "Current settings": + Logger.log("w", "Unable to upgrade this profile. Skipping it.") return None, None #Can't upgrade these, because the new current profile needs to specify the definition ID and the old file only had the machine instance, not the definition. config = configparser.ConfigParser(interpolation = None) From bafaf16fcbba5867353d012509f27c1c3f1a8d8f Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Sun, 20 Nov 2016 14:59:35 +0100 Subject: [PATCH 23/29] PrinterOutputDevice: Adding isConnectionState Adding isConnectionState here to make direct comparisons, whether the current state is the correct one. Looks better than `self._connection_state == ` in my point of view. --- cura/PrinterOutputDevice.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 6eae259e1e..156920e295 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -366,6 +366,11 @@ class PrinterOutputDevice(QObject, OutputDevice): self._connection_state = connection_state self.connectionStateChanged.emit(self._id) + ## Check the connection state of this output device. + # /param connection_state ConnectionState enum. + def isConnectionState(self, connection_state): + return self._connection_state == connection_state + @pyqtProperty(str, notify = connectionTextChanged) def connectionText(self): return self._connection_text @@ -535,4 +540,4 @@ class ConnectionState(IntEnum): connecting = 1 connected = 2 busy = 3 - error = 4 \ No newline at end of file + error = 4 From 6dc194d8de4c09037851f80e4d2347a25e355aff Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Sun, 20 Nov 2016 15:09:20 +0100 Subject: [PATCH 24/29] Revert "PrinterOutputDevice: Adding isConnectionState" 1. Shouldn't go directly to upstream's master 2. GitHub still loves to kill the last line This reverts commit bafaf16fcbba5867353d012509f27c1c3f1a8d8f. --- cura/PrinterOutputDevice.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 156920e295..6eae259e1e 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -366,11 +366,6 @@ class PrinterOutputDevice(QObject, OutputDevice): self._connection_state = connection_state self.connectionStateChanged.emit(self._id) - ## Check the connection state of this output device. - # /param connection_state ConnectionState enum. - def isConnectionState(self, connection_state): - return self._connection_state == connection_state - @pyqtProperty(str, notify = connectionTextChanged) def connectionText(self): return self._connection_text @@ -540,4 +535,4 @@ class ConnectionState(IntEnum): connecting = 1 connected = 2 busy = 3 - error = 4 + error = 4 \ No newline at end of file From 9057174691d0df8b9cb0c7b1242a46cebfd82360 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 21 Nov 2016 11:10:23 +0100 Subject: [PATCH 25/29] Resolve is now updated from the base property The resolve doesn't update always update well for single extrusion machines, so the wrong value gets used. There is however, no need for a resolve with a single extrusion machine, so we can disable the resolve for those alltogether. CURA-2939 --- resources/qml/Settings/SettingCheckBox.qml | 4 ++-- resources/qml/Settings/SettingComboBox.qml | 4 ++-- resources/qml/Settings/SettingItem.qml | 3 ++- resources/qml/Settings/SettingTextField.qml | 4 ++-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/resources/qml/Settings/SettingCheckBox.qml b/resources/qml/Settings/SettingCheckBox.qml index 1fcd24ccf6..97a72a026e 100644 --- a/resources/qml/Settings/SettingCheckBox.qml +++ b/resources/qml/Settings/SettingCheckBox.qml @@ -29,11 +29,11 @@ SettingItem // 4: variant // 5: machine var value; - if ((propertyProvider.properties.resolve != "None") && (stackLevel != 0) && (stackLevel != 1)) { + if ((base.resolve != "None") && (stackLevel != 0) && (stackLevel != 1)) { // We have a resolve function. Indicates that the setting is not settable per extruder and that // we have to choose between the resolved value (default) and the global value // (if user has explicitly set this). - value = propertyProvider.properties.resolve; + value = base.resolve; } else { value = propertyProvider.properties.value; } diff --git a/resources/qml/Settings/SettingComboBox.qml b/resources/qml/Settings/SettingComboBox.qml index c4ca637506..dfa070667a 100644 --- a/resources/qml/Settings/SettingComboBox.qml +++ b/resources/qml/Settings/SettingComboBox.qml @@ -96,11 +96,11 @@ SettingItem { // FIXME this needs to go away once 'resolve' is combined with 'value' in our data model. var value; - if ((propertyProvider.properties.resolve != "None") && (base.stackLevel != 0) && (base.stackLevel != 1)) { + if ((base.resolve != "None") && (base.stackLevel != 0) && (base.stackLevel != 1)) { // We have a resolve function. Indicates that the setting is not settable per extruder and that // we have to choose between the resolved value (default) and the global value // (if user has explicitly set this). - value = propertyProvider.properties.resolve; + value = base.resolve; } else { value = propertyProvider.properties.value; } diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index 7fa2856e27..2aa15e9244 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -27,7 +27,8 @@ Item { // Create properties to put property provider stuff in (bindings break in qt 5.5.1 otherwise) property var state: propertyProvider.properties.state - property var resolve: propertyProvider.properties.resolve + // There is no resolve property if there is only one stack. + property var resolve: Cura.MachineManager.activeStackId != Cura.MachineManager.activeMachineId ? propertyProvider.properties.resolve : "None" property var stackLevels: propertyProvider.stackLevels property var stackLevel: stackLevels[0] diff --git a/resources/qml/Settings/SettingTextField.qml b/resources/qml/Settings/SettingTextField.qml index d02c8854b4..d89f540aa3 100644 --- a/resources/qml/Settings/SettingTextField.qml +++ b/resources/qml/Settings/SettingTextField.qml @@ -114,11 +114,11 @@ SettingItem // 3: material -> user changed material in materialspage // 4: variant // 5: machine - if ((propertyProvider.properties.resolve != "None" && propertyProvider.properties.resolve) && (stackLevel != 0) && (stackLevel != 1)) { + if ((base.resolve != "None" && base.resolve) && (stackLevel != 0) && (stackLevel != 1)) { // We have a resolve function. Indicates that the setting is not settable per extruder and that // we have to choose between the resolved value (default) and the global value // (if user has explicitly set this). - return propertyProvider.properties.resolve; + return base.resolve; } else { return propertyProvider.properties.value; } From 1a2138de5ab3d074465571872a4a1d68f189dde8 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 21 Nov 2016 11:21:20 +0100 Subject: [PATCH 26/29] Moved warning to VersionUpgradeManager CURA-2883 --- plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py b/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py index e55a89faf3..8be5a63151 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py @@ -81,7 +81,6 @@ class Profile: import VersionUpgrade21to22 # Import here to prevent circular dependencies. if self._name == "Current settings": - Logger.log("w", "Unable to upgrade this profile. Skipping it.") return None, None #Can't upgrade these, because the new current profile needs to specify the definition ID and the old file only had the machine instance, not the definition. config = configparser.ConfigParser(interpolation = None) From aceff72c34f8067ab16b7d90322e089305043ae7 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 21 Nov 2016 11:49:50 +0100 Subject: [PATCH 27/29] PerObject tool is now disabled when switching to a group as well CURA-2287 --- cura/CuraApplication.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 5ac414f00d..b89df31dd9 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -581,6 +581,8 @@ class CuraApplication(QtApplication): else: if self._previous_active_tool: self.getController().setActiveTool(self._previous_active_tool) + if not self.getController().getActiveTool().getEnabled(): + self.getController().setActiveTool("TranslateTool") self._previous_active_tool = None else: # Default From 50609bfe7e36490b1275da41eb6370d0d4a9a174 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 21 Nov 2016 13:28:40 +0100 Subject: [PATCH 28/29] Make support line distance only give warning if actually less than line width Otherwise you get a warning with the default settings. --- 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 d00c28ef88..6591a9f3ec 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -2896,7 +2896,7 @@ "type": "float", "default_value": 0.4, "minimum_value": "0", - "minimum_value_warning": "support_interface_line_width", + "minimum_value_warning": "support_interface_line_width - 0.0001", "value": "0 if support_interface_density == 0 else (support_interface_line_width * 100) / support_interface_density * (2 if support_interface_pattern == 'grid' else (3 if support_interface_pattern == 'triangles' else 1))", "limit_to_extruder": "support_interface_extruder_nr", "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable", From d09c2d2fa597649da1e89d717786024d49ae1ffa Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 21 Nov 2016 13:42:08 +0100 Subject: [PATCH 29/29] No longer cast ObjectId to int Fixes CURA-148 --- resources/qml/MultiplyObjectOptions.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/MultiplyObjectOptions.qml b/resources/qml/MultiplyObjectOptions.qml index 7756ab074b..4b22a96644 100644 --- a/resources/qml/MultiplyObjectOptions.qml +++ b/resources/qml/MultiplyObjectOptions.qml @@ -19,7 +19,7 @@ UM.Dialog width: minimumWidth height: minimumHeight - property int objectId: 0; + property var objectId: 0; onAccepted: Printer.multiplyObject(base.objectId, parseInt(copiesField.text)) property variant catalog: UM.I18nCatalog { name: "cura" }