From 4cc5b6d9ebb54e6a76058f721b2542f17fca2070 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Mon, 3 Oct 2016 10:27:31 +0200 Subject: [PATCH 01/29] Added activeStackChanged to BuildVolume, it is semantically more correct. Contributes to CURA-2232 --- cura/BuildVolume.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index c3c35bc07b..4e5c3a7d03 100644 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -85,6 +85,9 @@ class BuildVolume(SceneNode): # activeQualityChanged is always emitted after setActiveVariant, setActiveMaterial and setActiveQuality. # Therefore this works. Application.getInstance().getMachineManager().activeQualityChanged.connect(self._onStackChanged) + # This should also ways work, and it is semantically more correct, + # but it does not update the disallowed areas after material change + Application.getInstance().getMachineManager().activeStackChanged.connect(self._onStackChanged) def _onSceneChanged(self, source): if self._global_container_stack: From 3c30275201186bb168f5eaa33101d0b5fe95193d Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 3 Oct 2016 11:52:28 +0200 Subject: [PATCH 02/29] Import profiles as quality_changes profiles CURA-2478 --- cura/Settings/CuraContainerRegistry.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 8b028171b3..4de0133654 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -156,6 +156,10 @@ class CuraContainerRegistry(ContainerRegistry): profile_name = name_seed new_name = container_registry.uniqueName(profile_name) profile.setDirty(True) # Ensure the profiles are correctly saved + if "type" in profile.getMetaData(): + profile.setMetaDataEntry("type", "quality_changes") + else: + profile.addMetaDataEntry("type", "quality_changes") self._configureProfile(profile, profile_name) profile.setName(new_name) From 3e6cbd58f1ac7384557ae252da758e449567ac3e Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Mon, 3 Oct 2016 12:05:09 +0200 Subject: [PATCH 03/29] Added some more method docs. Contributes to CURA-2477 Profile menu should only contain valid options for all materials --- cura/QualityManager.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cura/QualityManager.py b/cura/QualityManager.py index 529cc5bc41..1ec3b85c48 100644 --- a/cura/QualityManager.py +++ b/cura/QualityManager.py @@ -60,6 +60,11 @@ class QualityManager: return list(common_quality_types) + ## Fetches a dict of quality types names to quality profiles for a combination of machine and material. + # + # \param machine_definition \type{DefinitionContainer} the machine definition. + # \param material \type{ContainerInstance} the material. + # \return \type{Dict[str, ContainerInstance]} the dict of suitable quality type names mapping to qualities. def __fetchQualityTypeDictForMaterial(self, machine_definition, material): qualities = self.findAllQualitiesForMachineMaterial(machine_definition, material) quality_type_dict = {} @@ -87,6 +92,11 @@ class QualityManager: result = self._getFilteredContainersForStack(machine_definition, [basic_material], **criteria) return result[0] if result else None + ## Find all suitable qualities for a combination of machine and material. + # + # \param machine_definition \type{DefinitionContainer} the machine definition. + # \param material_container \type{ContainerInstance} the material. + # \return \type{List[ContainerInstance]} the list of suitable qualities. def findAllQualitiesForMachineMaterial(self, machine_definition, material_container): criteria = {"type": "quality" } result = self._getFilteredContainersForStack(machine_definition, [material_container], **criteria) @@ -95,6 +105,11 @@ class QualityManager: result = self._getFilteredContainersForStack(machine_definition, [basic_material], **criteria) return result + ## Fetch a more basic version of a material. + # + # This tries to find a generic or basic version of the given material. + # \param material_container \type{InstanceContainer} the material + # \return \type{Option[InstanceContainer]} the basic material or None if one could not be found. def _getBasicMaterial(self, material_container): base_material = material_container.getMetaDataEntry("material") if base_material: From b722a6260c352e2f72aa2bf2b6f11d9ed4e1c3ee Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 3 Oct 2016 14:34:49 +0200 Subject: [PATCH 04/29] JSON fix: new resolve functions (CURA-2410) --- resources/definitions/fdmprinter.def.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 3aa45f7af7..eab501ffc6 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -550,6 +550,7 @@ "unit": "mm", "type": "float", "default_value": 0.3, + "resolve": "sum(extruderValues('layer_height_0')) / len(extruderValues('layer_height_0'))", "minimum_value": "0.001", "minimum_value_warning": "0.04", "maximum_value_warning": "0.8 * min(extruderValues('machine_nozzle_size'))", @@ -1640,6 +1641,7 @@ "description": "The first few layers are printed slower than the rest of the model, to get better adhesion to the build plate and improve the overall success rate of prints. The speed is gradually increased over these layers.", "type": "int", "default_value": 2, + "resolve": "sum(extruderValues('speed_slowdown_layers')) / len(extruderValues('speed_slowdown_layers'))", "minimum_value": "0", "maximum_value_warning": "1.0 / layer_height", "settable_per_mesh": false, @@ -1675,6 +1677,7 @@ "description": "Enables adjusting the print head acceleration. Increasing the accelerations can reduce printing time at the cost of print quality.", "type": "bool", "default_value": false, + "resolve": "any(extruderValues('acceleration_enabled'))", "settable_per_mesh": false, "settable_per_extruder": false }, @@ -1896,6 +1899,7 @@ "description": "Enables adjusting the jerk of print head when the velocity in the X or Y axis changes. Increasing the jerk can reduce printing time at the cost of print quality.", "type": "bool", "default_value": false, + "resolve": "any(extruderValues('jerk_enabled'))", "settable_per_mesh": false, "settable_per_extruder": false }, @@ -2133,6 +2137,7 @@ "noskin": "No Skin" }, "default_value": "all", + "resolve": "'noskin' if 'noskin' in extruderValues('retraction_combing') else ('all' if 'all' in extruderValues('retraction_combing') else 'off')", "settable_per_mesh": true }, "travel_avoid_other_parts": @@ -2326,6 +2331,7 @@ "everywhere": "Everywhere" }, "default_value": "everywhere", + "resolve": "'everywhere' if 'everywhere' in extruderValues('support_type') else buildplate", "enabled": "support_enable", "settable_per_mesh": false, "settable_per_extruder": false @@ -3348,6 +3354,7 @@ "enabled": "resolveOrValue('prime_tower_enable')", "default_value": 15, "value": "15 if resolveOrValue('prime_tower_enable') else 0", + "resolve": "max(extruderValues('prime_tower_size'))", "minimum_value": "0", "maximum_value": "min(0.5 * machine_width, 0.5 * machine_depth)", "maximum_value_warning": "20", @@ -3405,6 +3412,7 @@ "type": "bool", "enabled": "resolveOrValue('prime_tower_enable')", "default_value": true, + "resolve": "any(extruderValues('prime_tower_wipe_enabled'))", "settable_per_mesh": false, "settable_per_extruder": false }, @@ -3424,6 +3432,7 @@ "label": "Enable Ooze Shield", "description": "Enable exterior ooze shield. This will create a shell around the model which is likely to wipe a second nozzle if it's at the same height as the first nozzle.", "type": "bool", + "resolve": "any(extruderValues('ooze_shield_enabled'))", "default_value": false, "settable_per_mesh": false, "settable_per_extruder": false @@ -3436,6 +3445,7 @@ "unit": "°", "enabled": "ooze_shield_enabled", "default_value": 60, + "resolve": "min(extruderValues('ooze_shield_angle'))", "minimum_value": "0", "maximum_value": "90", "settable_per_mesh": false, @@ -3449,6 +3459,7 @@ "unit": "mm", "enabled": "ooze_shield_enabled", "default_value": 2, + "resolve": "max(extruderValues('ooze_shield_dist'))", "minimum_value": "0", "maximum_value_warning": "30", "settable_per_mesh": false, @@ -3596,6 +3607,7 @@ "minimum_value": "0", "maximum_value_warning": "100", "default_value": 10, + "resolve": "max(extruderValues('draft_shield_dist'))", "enabled": "draft_shield_enabled", "settable_per_mesh": false, "settable_per_extruder": false @@ -3611,6 +3623,7 @@ "limited": "Limited" }, "default_value": "full", + "resolve": "'full' if 'full' in extruderValues('draft_shield_height_limitation') else 'limited'", "enabled": "draft_shield_enabled", "settable_per_mesh": false, "settable_per_extruder": false From 8363f40a2f422c9f183e3e8f7e0fedf07fd35dd6 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 3 Oct 2016 14:35:31 +0200 Subject: [PATCH 05/29] JSON fix: resolveOrValue for acceleration_enabled (CURA-2410) --- resources/definitions/fdmprinter.def.json | 38 +++++++++++------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index eab501ffc6..ab1ef3ec13 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1690,7 +1690,7 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default_value": 3000, - "enabled": "acceleration_enabled", + "enabled": "resolveOrValue('acceleration_enabled')", "settable_per_mesh": true, "children": { "acceleration_infill": { @@ -1703,7 +1703,7 @@ "maximum_value_warning": "10000", "default_value": 3000, "value": "acceleration_print", - "enabled": "acceleration_enabled and infill_sparse_density > 0", + "enabled": "resolveOrValue('acceleration_enabled') and infill_sparse_density > 0", "settable_per_mesh": true }, "acceleration_wall": { @@ -1716,7 +1716,7 @@ "maximum_value_warning": "10000", "default_value": 3000, "value": "acceleration_print", - "enabled": "acceleration_enabled", + "enabled": "resolveOrValue('acceleration_enabled')", "settable_per_mesh": true, "children": { "acceleration_wall_0": { @@ -1729,7 +1729,7 @@ "maximum_value_warning": "10000", "default_value": 3000, "value": "acceleration_wall", - "enabled": "acceleration_enabled", + "enabled": "resolveOrValue('acceleration_enabled')", "settable_per_mesh": true }, "acceleration_wall_x": { @@ -1742,7 +1742,7 @@ "maximum_value_warning": "10000", "default_value": 3000, "value": "acceleration_wall", - "enabled": "acceleration_enabled", + "enabled": "resolveOrValue('acceleration_enabled')", "settable_per_mesh": true } } @@ -1757,7 +1757,7 @@ "maximum_value_warning": "10000", "default_value": 3000, "value": "acceleration_print", - "enabled": "acceleration_enabled", + "enabled": "resolveOrValue('acceleration_enabled')", "settable_per_mesh": true }, "acceleration_support": { @@ -1770,7 +1770,7 @@ "maximum_value_warning": "10000", "default_value": 3000, "value": "acceleration_print", - "enabled": "acceleration_enabled and support_enable", + "enabled": "resolveOrValue('acceleration_enabled') and support_enable", "settable_per_mesh": false, "limit_to_extruder": "support_extruder_nr", "settable_per_extruder": true, @@ -1785,7 +1785,7 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "enabled": "acceleration_enabled and support_enable", + "enabled": "resolveOrValue('acceleration_enabled') and support_enable", "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true @@ -1800,7 +1800,7 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "enabled": "acceleration_enabled and extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable", + "enabled": "resolveOrValue('acceleration_enabled') and extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable", "limit_to_extruder": "support_interface_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true @@ -1817,7 +1817,7 @@ "maximum_value_warning": "10000", "default_value": 3000, "value": "acceleration_print", - "enabled": "resolveOrValue('prime_tower_enable') and acceleration_enabled", + "enabled": "resolveOrValue('prime_tower_enable') and resolveOrValue('acceleration_enabled')", "settable_per_mesh": false } } @@ -1832,7 +1832,7 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "value": "acceleration_print if magic_spiralize else 5000", - "enabled": "acceleration_enabled", + "enabled": "resolveOrValue('acceleration_enabled')", "settable_per_mesh": false }, "acceleration_layer_0": { @@ -1845,7 +1845,7 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "enabled": "acceleration_enabled", + "enabled": "resolveOrValue('acceleration_enabled')", "settable_per_mesh": true, "children": { "acceleration_print_layer_0": @@ -1859,7 +1859,7 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "enabled": "acceleration_enabled", + "enabled": "resolveOrValue('acceleration_enabled')", "settable_per_mesh": true }, "acceleration_travel_layer_0": @@ -1873,7 +1873,7 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "enabled": "acceleration_enabled", + "enabled": "resolveOrValue('acceleration_enabled')", "settable_per_extruder": true, "settable_per_mesh": false } @@ -1889,7 +1889,7 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "enabled": "acceleration_enabled", + "enabled": "resolveOrValue('acceleration_enabled')", "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr" }, @@ -3101,7 +3101,7 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "value": "acceleration_print", - "enabled": "resolveOrValue('adhesion_type') == 'raft' and acceleration_enabled", + "enabled": "resolveOrValue('adhesion_type') == 'raft' and resolveOrValue('acceleration_enabled')", "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr", "children": { @@ -3115,7 +3115,7 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "enabled": "resolveOrValue('adhesion_type') == 'raft' and acceleration_enabled", + "enabled": "resolveOrValue('adhesion_type') == 'raft' and resolveOrValue('acceleration_enabled')", "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr" }, @@ -3129,7 +3129,7 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "enabled": "resolveOrValue('adhesion_type') == 'raft' and acceleration_enabled", + "enabled": "resolveOrValue('adhesion_type') == 'raft' and resolveOrValue('acceleration_enabled')", "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr" }, @@ -3143,7 +3143,7 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "enabled": "resolveOrValue('adhesion_type') == 'raft' and acceleration_enabled", + "enabled": "resolveOrValue('adhesion_type') == 'raft' and resolveOrValue('acceleration_enabled')", "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr" } From 16a07a3c3e1bfa7b73a6d059d68863093c0ca191 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 3 Oct 2016 14:41:09 +0200 Subject: [PATCH 06/29] JSON fix: RigidBot had weird outdated enabled formulas for skirt settings (CURA-2410) --- resources/definitions/rigidbot.def.json | 9 +++------ resources/definitions/rigidbot_big.def.json | 9 +++------ 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/resources/definitions/rigidbot.def.json b/resources/definitions/rigidbot.def.json index 7266c12a38..8b268410f9 100644 --- a/resources/definitions/rigidbot.def.json +++ b/resources/definitions/rigidbot.def.json @@ -88,16 +88,13 @@ "default_value": 0 }, "skirt_line_count": { - "default_value": 3, - "enabled": "adhesion_type == \"Skirt\"" + "default_value": 3 }, "skirt_gap": { - "default_value": 4, - "enabled": "adhesion_type == \"Skirt\"" + "default_value": 4 }, "skirt_brim_minimal_length": { - "default_value": 200, - "enabled": "adhesion_type == \"Skirt\"" + "default_value": 200 } } } diff --git a/resources/definitions/rigidbot_big.def.json b/resources/definitions/rigidbot_big.def.json index 9ada143fbc..f8cf1e1da0 100644 --- a/resources/definitions/rigidbot_big.def.json +++ b/resources/definitions/rigidbot_big.def.json @@ -91,16 +91,13 @@ "default_value": 0 }, "skirt_line_count": { - "default_value": 3, - "enabled": "adhesion_type == \"Skirt\"" + "default_value": 3 }, "skirt_gap": { - "default_value": 4, - "enabled": "adhesion_type == \"Skirt\"" + "default_value": 4 }, "skirt_brim_minimal_length": { - "default_value": 200, - "enabled": "adhesion_type == \"Skirt\"" + "default_value": 200 } } } \ No newline at end of file From 6564ada60dc6de67ee58278490071b8d9f405594 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 3 Oct 2016 14:42:14 +0200 Subject: [PATCH 07/29] JSON bugfix: prusa i3 had wrong adhesion setting (CURA-2410) --- resources/definitions/maker_starter.def.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/definitions/maker_starter.def.json b/resources/definitions/maker_starter.def.json index e59c22fb5e..74cdc694ee 100644 --- a/resources/definitions/maker_starter.def.json +++ b/resources/definitions/maker_starter.def.json @@ -144,7 +144,7 @@ "default_value": 15 }, "adhesion_type": { - "default_value": "Raft" + "default_value": "raft" }, "skirt_brim_minimal_length": { "default_value": 100 From 8696d2ff34fa0974bbb030b75e1b798088b6cc27 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 3 Oct 2016 14:44:14 +0200 Subject: [PATCH 08/29] JSON fix: resolveOrValue for jerk_enabled (CURA-2410) --- resources/definitions/fdmprinter.def.json | 38 +++++++++++------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index ab1ef3ec13..1966b19528 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1912,7 +1912,7 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default_value": 20, - "enabled": "jerk_enabled", + "enabled": "resolveOrValue('jerk_enabled')", "settable_per_mesh": true, "children": { "jerk_infill": { @@ -1925,7 +1925,7 @@ "maximum_value_warning": "50", "default_value": 20, "value": "jerk_print", - "enabled": "jerk_enabled and infill_sparse_density > 0", + "enabled": "resolveOrValue('jerk_enabled') and infill_sparse_density > 0", "settable_per_mesh": true }, "jerk_wall": { @@ -1938,7 +1938,7 @@ "maximum_value_warning": "50", "default_value": 20, "value": "jerk_print", - "enabled": "jerk_enabled", + "enabled": "resolveOrValue('jerk_enabled')", "settable_per_mesh": true, "children": { "jerk_wall_0": { @@ -1951,7 +1951,7 @@ "maximum_value_warning": "50", "default_value": 20, "value": "jerk_wall", - "enabled": "jerk_enabled", + "enabled": "resolveOrValue('jerk_enabled')", "settable_per_mesh": true }, "jerk_wall_x": { @@ -1964,7 +1964,7 @@ "maximum_value_warning": "50", "default_value": 20, "value": "jerk_wall", - "enabled": "jerk_enabled", + "enabled": "resolveOrValue('jerk_enabled')", "settable_per_mesh": true } } @@ -1979,7 +1979,7 @@ "maximum_value_warning": "50", "default_value": 20, "value": "jerk_print", - "enabled": "jerk_enabled", + "enabled": "resolveOrValue('jerk_enabled')", "settable_per_mesh": true }, "jerk_support": { @@ -1992,7 +1992,7 @@ "maximum_value_warning": "50", "default_value": 20, "value": "jerk_print", - "enabled": "jerk_enabled and support_enable", + "enabled": "resolveOrValue('jerk_enabled') and support_enable", "settable_per_mesh": false, "settable_per_extruder": true, "limit_to_extruder": "support_extruder_nr", @@ -2007,7 +2007,7 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "enabled": "jerk_enabled and support_enable", + "enabled": "resolveOrValue('jerk_enabled') and support_enable", "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true @@ -2022,7 +2022,7 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "enabled": "jerk_enabled and extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable", + "enabled": "resolveOrValue('jerk_enabled') and extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable", "limit_to_extruder": "support_interface_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true @@ -2039,7 +2039,7 @@ "maximum_value_warning": "50", "default_value": 20, "value": "jerk_print", - "enabled": "resolveOrValue('prime_tower_enable') and jerk_enabled", + "enabled": "resolveOrValue('prime_tower_enable') and resolveOrValue('jerk_enabled')", "settable_per_mesh": false } } @@ -2054,7 +2054,7 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "value": "jerk_print if magic_spiralize else 30", - "enabled": "jerk_enabled", + "enabled": "resolveOrValue('jerk_enabled')", "settable_per_mesh": false }, "jerk_layer_0": { @@ -2067,7 +2067,7 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "enabled": "jerk_enabled", + "enabled": "resolveOrValue('jerk_enabled')", "settable_per_mesh": true, "children": { "jerk_print_layer_0": @@ -2081,7 +2081,7 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "enabled": "jerk_enabled", + "enabled": "resolveOrValue('jerk_enabled')", "settable_per_mesh": true }, "jerk_travel_layer_0": @@ -2095,7 +2095,7 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "enabled": "jerk_enabled", + "enabled": "resolveOrValue('jerk_enabled')", "settable_per_extruder": true, "settable_per_mesh": false } @@ -2111,7 +2111,7 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "value": "jerk_layer_0", - "enabled": "jerk_enabled", + "enabled": "resolveOrValue('jerk_enabled')", "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr" } @@ -3159,7 +3159,7 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "value": "jerk_print", - "enabled": "resolveOrValue('adhesion_type') == 'raft' and jerk_enabled", + "enabled": "resolveOrValue('adhesion_type') == 'raft' and resolveOrValue('jerk_enabled')", "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr", "children": { @@ -3173,7 +3173,7 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "100", - "enabled": "resolveOrValue('adhesion_type') == 'raft' and jerk_enabled", + "enabled": "resolveOrValue('adhesion_type') == 'raft' and resolveOrValue('jerk_enabled')", "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr" }, @@ -3187,7 +3187,7 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "enabled": "resolveOrValue('adhesion_type') == 'raft' and jerk_enabled", + "enabled": "resolveOrValue('adhesion_type') == 'raft' and resolveOrValue('jerk_enabled')", "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr" }, @@ -3201,7 +3201,7 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "enabled": "resolveOrValue('adhesion_type') == 'raft' and jerk_enabled", + "enabled": "resolveOrValue('adhesion_type') == 'raft' and resolveOrValue('jerk_enabled')", "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr" } From c7fbaa9fb8bc331a31e536fd1ad4f63be83fff65 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 3 Oct 2016 14:46:36 +0200 Subject: [PATCH 09/29] JSON fix: resolveOrValue for layer_height_0 (CURA-2410) --- resources/definitions/fdmprinter.def.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 1966b19528..faaeedd7a2 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -2247,7 +2247,7 @@ "unit": "mm", "type": "float", "default_value": 0.5, - "value": "0 if resolveOrValue('adhesion_type') == 'raft' else layer_height_0", + "value": "0 if resolveOrValue('adhesion_type') == 'raft' else resolveOrValue('layer_height_0')", "minimum_value": "0", "maximum_value_warning": "10.0", "settable_per_mesh": false, @@ -2262,7 +2262,7 @@ "default_value": 2, "minimum_value": "1", "maximum_value_warning": "100", - "value": "max(1, int(math.floor((cool_fan_full_at_height - layer_height_0) / layer_height) + 2))", + "value": "max(1, int(math.floor((cool_fan_full_at_height - resolveOrValue('layer_height_0')) / layer_height) + 2))", "settable_per_mesh": false, "settable_per_extruder": true } @@ -2986,7 +2986,7 @@ "unit": "mm", "type": "float", "default_value": 0.3, - "value": "layer_height_0 * 1.2", + "value": "resolveOrValue('layer_height_0') * 1.2", "minimum_value": "0", "maximum_value_warning": "5.0", "enabled": "resolveOrValue('adhesion_type') == 'raft'", From dee434b9586ea487366c1311ed70e6b255c8c2ca Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 3 Oct 2016 14:49:01 +0200 Subject: [PATCH 10/29] JSON fix: resolveOrValue for ooze_shield_enalbed (CURA-2410) --- resources/definitions/fdmprinter.def.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index faaeedd7a2..8d61220446 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -3443,7 +3443,7 @@ "description": "The maximum angle a part in the ooze shield will have. With 0 degrees being vertical, and 90 degrees being horizontal. A smaller angle leads to less failed ooze shields, but more material.", "type": "float", "unit": "°", - "enabled": "ooze_shield_enabled", + "enabled": "resolveOrValue('ooze_shield_enabled')", "default_value": 60, "resolve": "min(extruderValues('ooze_shield_angle'))", "minimum_value": "0", @@ -3457,7 +3457,7 @@ "description": "Distance of the ooze shield from the print, in the X/Y directions.", "type": "float", "unit": "mm", - "enabled": "ooze_shield_enabled", + "enabled": "resolveOrValue('ooze_shield_enabled')", "default_value": 2, "resolve": "max(extruderValues('ooze_shield_dist'))", "minimum_value": "0", From 91bed05d6388140ae96720fa0570df6a4072402e Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 3 Oct 2016 14:50:20 +0200 Subject: [PATCH 11/29] JSON fix: resolveOrValue for prime_tower_size (CURA-2410) --- resources/definitions/fdmprinter.def.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 8d61220446..9ff9705c48 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -3371,8 +3371,8 @@ "default_value": 200, "minimum_value_warning": "-1000", "maximum_value_warning": "1000", - "maximum_value": "machine_width - 0.5 * prime_tower_size", - "minimum_value": "0.5 * prime_tower_size", + "maximum_value": "machine_width - 0.5 * resolveOrValue('prime_tower_size')", + "minimum_value": "0.5 * resolveOrValue('prime_tower_size')", "settable_per_mesh": false, "settable_per_extruder": false }, @@ -3386,8 +3386,8 @@ "default_value": 200, "minimum_value_warning": "-1000", "maximum_value_warning": "1000", - "maximum_value": "machine_depth - 0.5 * prime_tower_size", - "minimum_value": "0.5 * prime_tower_size", + "maximum_value": "machine_depth - 0.5 * resolveOrValue('prime_tower_size')", + "minimum_value": "0.5 * resolveOrValue('prime_tower_size')", "settable_per_mesh": false, "settable_per_extruder": false }, From 4c46985c75768631c3bc46ed56370db1ff396f0c Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 3 Oct 2016 14:51:28 +0200 Subject: [PATCH 12/29] JSON fix: resolveOrValue for retraction_combing (CURA-2410) --- resources/definitions/fdmprinter.def.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 9ff9705c48..daa6b12328 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -2146,7 +2146,7 @@ "description": "The nozzle avoids already printed parts when traveling. This option is only available when combing is enabled.", "type": "bool", "default_value": true, - "enabled": "retraction_combing != 'off'", + "enabled": "resolveOrValue('retraction_combing') != 'off'", "settable_per_mesh": false, "settable_per_extruder": true }, @@ -2160,7 +2160,7 @@ "value": "machine_nozzle_tip_outer_diameter / 2 * 1.25", "minimum_value": "0", "maximum_value_warning": "machine_nozzle_tip_outer_diameter * 5", - "enabled": "retraction_combing != 'off' and travel_avoid_other_parts", + "enabled": "resolveOrValue('retraction_combing') != 'off' and travel_avoid_other_parts", "settable_per_mesh": false, "settable_per_extruder": true } From 4e4171fc53183bdcd14c699e47c9d0449ed41ac5 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 3 Oct 2016 14:52:33 +0200 Subject: [PATCH 13/29] JSON fix: resolveOrValue for support_type (CURA-2410) --- resources/definitions/fdmprinter.def.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index daa6b12328..456fb92307 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -2445,10 +2445,10 @@ "minimum_value": "0", "maximum_value_warning": "10", "default_value": 0.1, - "value": "extruderValue(support_extruder_nr, 'support_z_distance') if support_type == 'everywhere' else 0", + "value": "extruderValue(support_extruder_nr, 'support_z_distance') if resolveOrValue('support_type') == 'everywhere' else 0", "limit_to_extruder": "support_interface_extruder_nr if support_interface_enable else support_infill_extruder_nr", "type": "float", - "enabled": "support_enable and support_type == 'everywhere'", + "enabled": "support_enable and resolveOrValue('support_type') == 'everywhere'", "settable_per_mesh": true } } From 513c05b78c04ae1704820dee9c6fa982df909d63 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 3 Oct 2016 15:03:25 +0200 Subject: [PATCH 14/29] Extruders model now listens to global container changed, instead of definition changed. This solves issue where switching between machines with the same definition did not cause extruder materials to be updated CURA-2493 --- cura/Settings/ExtrudersModel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/Settings/ExtrudersModel.py b/cura/Settings/ExtrudersModel.py index c5a8160bf4..7dc55c1d81 100644 --- a/cura/Settings/ExtrudersModel.py +++ b/cura/Settings/ExtrudersModel.py @@ -50,9 +50,9 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): self._active_extruder_stack = None - #Listen to changes. + # Listen to changes. + UM.Application.getInstance().globalContainerStackChanged.connect(self._updateExtruders) manager = ExtruderManager.getInstance() - manager.globalContainerStackDefinitionChanged.connect(self._updateExtruders) #When the global stack changes to a printer with different extruders. self._updateExtruders() From a0f345285dbf0d54e50ce76b9d4569ef08202c8e Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Mon, 3 Oct 2016 15:06:38 +0200 Subject: [PATCH 15/29] Rename ProfilesPageModel.py to QualityAndUserProfilesModel.py. Step 1 of 2. Contributes to CURA-2414 Quality changes profiles are created incorrectly --- .../{ProfilesPageModel.py => QualityAndUserProfilesModel.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename cura/Settings/{ProfilesPageModel.py => QualityAndUserProfilesModel.py} (100%) diff --git a/cura/Settings/ProfilesPageModel.py b/cura/Settings/QualityAndUserProfilesModel.py similarity index 100% rename from cura/Settings/ProfilesPageModel.py rename to cura/Settings/QualityAndUserProfilesModel.py From 5d1b77c55126d96c5b1bb5c5b5ee3c83bf6f74d1 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Mon, 3 Oct 2016 15:19:15 +0200 Subject: [PATCH 16/29] Rename ProfilesPageModel.py to QualityAndUserProfilesModel.py. Step 2 of 2. Contributes to CURA-2414 Quality changes profiles are created incorrectly --- cura/CuraApplication.py | 2 +- cura/Settings/QualityAndUserProfilesModel.py | 2 +- cura/Settings/__init__.py | 2 +- resources/qml/Preferences/ProfilesPage.qml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 77bc3bbc49..0725c6e48c 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -503,7 +503,7 @@ class CuraApplication(QtApplication): qmlRegisterType(cura.Settings.ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel") qmlRegisterType(cura.Settings.ProfilesModel, "Cura", 1, 0, "ProfilesModel") - qmlRegisterType(cura.Settings.ProfilesPageModel, "Cura", 1, 0, "ProfilesPageModel") + qmlRegisterType(cura.Settings.QualityAndUserProfilesModel, "Cura", 1, 0, "QualityAndUserProfilesModel") qmlRegisterType(cura.Settings.MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler") qmlRegisterType(cura.Settings.QualitySettingsModel, "Cura", 1, 0, "QualitySettingsModel") diff --git a/cura/Settings/QualityAndUserProfilesModel.py b/cura/Settings/QualityAndUserProfilesModel.py index 31caeeda4f..8aca66a994 100644 --- a/cura/Settings/QualityAndUserProfilesModel.py +++ b/cura/Settings/QualityAndUserProfilesModel.py @@ -8,7 +8,7 @@ from cura.Settings.ProfilesModel import ProfilesModel ## QML Model for listing the current list of valid quality and quality changes profiles. # -class ProfilesPageModel(ProfilesModel): +class QualityAndUserProfilesModel(ProfilesModel): def __init__(self, parent = None): super().__init__(parent) diff --git a/cura/Settings/__init__.py b/cura/Settings/__init__.py index 6957e5031c..0fb2ef611c 100644 --- a/cura/Settings/__init__.py +++ b/cura/Settings/__init__.py @@ -13,4 +13,4 @@ from .SettingOverrideDecorator import SettingOverrideDecorator from .QualitySettingsModel import QualitySettingsModel from .SettingInheritanceManager import SettingInheritanceManager from .ProfilesModel import ProfilesModel -from .ProfilesPageModel import ProfilesPageModel +from .QualityAndUserProfilesModel import QualityAndUserProfilesModel diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 244e33f3f5..1809e06a36 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -15,7 +15,7 @@ UM.ManagementPage title: catalog.i18nc("@title:tab", "Profiles"); property var extrudersModel: Cura.ExtrudersModel{} - model: Cura.ProfilesPageModel { } + model: Cura.QualityAndUserProfilesModel { } section.property: "readOnly" section.delegate: Rectangle From 2f57d0fb6e0c5371aa77dd1a97e7ce46cf20d3df Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 3 Oct 2016 15:29:25 +0200 Subject: [PATCH 17/29] Import profiles for the current machine Takes into consideration printers that use quality-profiles from other printers, while gracefully handling mismatches in the number of extruders Fixes CURA-2500, contributes to CURA-2478 --- cura/Settings/ContainerManager.py | 10 +++++ cura/Settings/CuraContainerRegistry.py | 55 +++++++++++++++++++++----- 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 9fdf037acb..7537bb3555 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -678,6 +678,16 @@ class ContainerManager(QObject): duplicated_container.setDirty(True) self._container_registry.addContainer(duplicated_container) + ## Get the singleton instance for this class. + @classmethod + def getInstance(cls): + # Note: Explicit use of class name to prevent issues with inheritance. + if ContainerManager.__instance is None: + ContainerManager.__instance = cls() + return ContainerManager.__instance + + __instance = None + # Factory function, used by QML @staticmethod def createContainerManager(engine, js_engine): diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 4de0133654..69951127b5 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -16,6 +16,9 @@ from UM.Platform import Platform from UM.PluginRegistry import PluginRegistry #For getting the possible profile writers to write with. from UM.Util import parseBool +from cura.Settings.ExtruderManager import ExtruderManager +from cura.Settings.ContainerManager import ContainerManager + from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") @@ -128,8 +131,14 @@ class CuraContainerRegistry(ContainerRegistry): return { "status": "error", "message": catalog.i18nc("@info:status", "Failed to import profile from {0}: {1}", file_name, "Invalid path")} plugin_registry = PluginRegistry.getInstance() - container_registry = ContainerRegistry.getInstance() extension = file_name.split(".")[-1] + + global_container_stack = Application.getInstance().getGlobalContainerStack() + if not global_container_stack: + return + + machine_extruders = list(ExtruderManager.getInstance().getMachineExtruders(global_container_stack.getId())) + for plugin_id, meta_data in self._getIOPlugins("profile_reader"): if meta_data["profile_reader"][0]["extension"] != extension: continue @@ -148,13 +157,35 @@ class CuraContainerRegistry(ContainerRegistry): self._configureProfile(profile, name_seed) return { "status": "ok", "message": catalog.i18nc("@info:status", "Successfully imported profile {0}", profile.getName()) } else: + profile_index = -1 + global_profile = None + for profile in profile_or_list: - extruder_id = profile.getMetaDataEntry("extruder") - if extruder_id: - profile_name = "%s_%s" % (extruder_id, name_seed) + if profile_index >= 0: + if len(machine_extruders) > profile_index: + extruder_id = machine_extruders[profile_index].getBottom().getId() + profile_name = "%s_%s" % (extruder_id, name_seed) + # Ensure the extruder profiles get non-conflicting names + # NB: these are not user-facing + if "extruder" in profile.getMetaData(): + profile.setMetaDataEntry("extruder", extruder_id) + else: + profile.addMetaDataEntry("extruder", extruder_id) + elif profile_index == 0: + # Importing a multiextrusion profile into a single extrusion machine; merge 1st extruder profile into global profile + profile._id = self.uniqueName("temporary_profile") + self.addContainer(profile) + ContainerManager.getInstance().mergeContainers(global_profile.getId(), profile.getId()) + self.removeContainer(profile.getId()) + continue + else: + # The imported composite profile has a profile for an extruder that this machine does not have. Ignore this extruder-profile + continue else: + global_profile = profile profile_name = name_seed - new_name = container_registry.uniqueName(profile_name) + new_name = self.uniqueName(profile_name) + profile.setDirty(True) # Ensure the profiles are correctly saved if "type" in profile.getMetaData(): profile.setMetaDataEntry("type", "quality_changes") @@ -163,6 +194,8 @@ class CuraContainerRegistry(ContainerRegistry): self._configureProfile(profile, profile_name) profile.setName(new_name) + profile_index += 1 + 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. @@ -175,7 +208,7 @@ class CuraContainerRegistry(ContainerRegistry): profile._id = new_id if self._machineHasOwnQualities(): - profile.setDefinition(self._activeDefinition()) + profile.setDefinition(self._activeQualityDefinition()) if self._machineHasOwnMaterials(): profile.addMetaDataEntry("material", self._activeMaterialId()) else: @@ -196,12 +229,14 @@ class CuraContainerRegistry(ContainerRegistry): result.append( (plugin_id, meta_data) ) return result - ## Gets the active definition - # \return the active definition object or None if there is no definition - def _activeDefinition(self): + ## Get the definition to use to select quality profiles for the active machine + # \return the active quality definition object or None if there is no quality definition + def _activeQualityDefinition(self): global_container_stack = Application.getInstance().getGlobalContainerStack() if global_container_stack: - definition = global_container_stack.getBottom() + definition_id = Application.getInstance().getMachineManager().getQualityDefinitionId(global_container_stack.getBottom()) + definition = self.findDefinitionContainers(id=definition_id)[0] + if definition: return definition return None From 7d9d751121ef4b1503b90d9015ce26d122d3497c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 3 Oct 2016 15:43:42 +0200 Subject: [PATCH 18/29] ProfilesModel is now updated when active variant or material is changed Contributes to CURA-2494 --- cura/Settings/ExtrudersModel.py | 2 +- cura/Settings/ProfilesModel.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/cura/Settings/ExtrudersModel.py b/cura/Settings/ExtrudersModel.py index 7dc55c1d81..7de8f0c8ee 100644 --- a/cura/Settings/ExtrudersModel.py +++ b/cura/Settings/ExtrudersModel.py @@ -50,7 +50,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): self._active_extruder_stack = None - # Listen to changes. + #Listen to changes. UM.Application.getInstance().globalContainerStackChanged.connect(self._updateExtruders) manager = ExtruderManager.getInstance() diff --git a/cura/Settings/ProfilesModel.py b/cura/Settings/ProfilesModel.py index 3024961387..954f8e8ae8 100644 --- a/cura/Settings/ProfilesModel.py +++ b/cura/Settings/ProfilesModel.py @@ -6,6 +6,7 @@ from UM.Settings.Models.InstanceContainersModel import InstanceContainersModel from cura.QualityManager import QualityManager from cura.Settings.ExtruderManager import ExtruderManager +from cura.Settings.MachineManager import MachineManager ## QML Model for listing the current list of valid quality profiles. # @@ -15,6 +16,10 @@ class ProfilesModel(InstanceContainersModel): Application.getInstance().globalContainerStackChanged.connect(self._update) + Application.getInstance().getMachineManager().activeVariantChanged.connect(self._update) + Application.getInstance().getMachineManager().activeStackChanged.connect(self._update) + Application.getInstance().getMachineManager().activeMaterialChanged.connect(self._update) + ## Fetch the list of containers to display. # # See UM.Settings.Models.InstanceContainersModel._fetchInstanceContainers(). From 527a503eac2a47190dccbbe7e602953ed5b65eab Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 3 Oct 2016 15:54:18 +0200 Subject: [PATCH 19/29] Added more logging to indicate changing of certain containers actually succeeded --- cura/Settings/MachineManager.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index d4fafa5a6f..a1b4caa7af 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -544,6 +544,7 @@ class MachineManager(QObject): material_index = self._active_container_stack.getContainerIndex(old_material) self._active_container_stack.replaceContainer(material_index, material_container) + Logger.log("d", "Active material changed") material_container.nameChanged.connect(self._onMaterialNameChanged) @@ -588,7 +589,7 @@ class MachineManager(QObject): self.blurSettings.emit() variant_index = self._active_container_stack.getContainerIndex(old_variant) self._active_container_stack.replaceContainer(variant_index, containers[0]) - + Logger.log("d", "Active variant changed") preferred_material = None if old_material: preferred_material_name = old_material.getName() From 0e74b8eb08a15326a0f2134ef285d2f672b6c1e7 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 3 Oct 2016 15:58:05 +0200 Subject: [PATCH 20/29] setActiveMaterial now uses id instead of entire container to set quality CURA-2494 --- cura/Settings/MachineManager.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index a1b4caa7af..96e7f88a91 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -567,10 +567,11 @@ class MachineManager(QObject): [material_container]) if not candidate_quality: # Fall back to a quality - new_quality_id = quality_manager.findQualityByQualityType(None, + new_quality = quality_manager.findQualityByQualityType(None, quality_manager.getWholeMachineDefinition(machine_definition), [material_container]) - + if new_quality: + new_quality_id = new_quality.getId() else: if not old_quality_changes: new_quality_id = candidate_quality.getId() From e7da471199bbe4afd45d69e1c835ca94ba078bc5 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 3 Oct 2016 17:04:46 +0200 Subject: [PATCH 21/29] Fix showing profile values for extruders The profiles page would show the setting values in the quality profile, ignoring the quality_changes profile, because it could not find the appropriate quality_changes profile for the extruders CURA-2478 --- cura/Settings/ExtrudersModel.py | 10 ++++++++-- cura/Settings/QualitySettingsModel.py | 17 +++++++++++++++-- resources/qml/Preferences/ProfileTab.qml | 4 +++- resources/qml/Preferences/ProfilesPage.qml | 1 + 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/cura/Settings/ExtrudersModel.py b/cura/Settings/ExtrudersModel.py index 7de8f0c8ee..7e06b95100 100644 --- a/cura/Settings/ExtrudersModel.py +++ b/cura/Settings/ExtrudersModel.py @@ -29,6 +29,9 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): # containers. IndexRole = Qt.UserRole + 4 + # The ID of the definition of the extruder. + DefinitionRole = Qt.UserRole + 5 + ## List of colours to display if there is no material or the material has no known # colour. defaultColors = ["#ffc924", "#86ec21", "#22eeee", "#245bff", "#9124ff", "#ff24c8"] @@ -44,6 +47,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): self.addRoleName(self.NameRole, "name") self.addRoleName(self.ColorRole, "color") self.addRoleName(self.IndexRole, "index") + self.addRoleName(self.DefinitionRole, "definition") self._add_global = False self._simple_names = False @@ -126,7 +130,8 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): "id": global_container_stack.getId(), "name": "Global", "color": color, - "index": -1 + "index": -1, + "definition": "" } items.append(item) changed = True @@ -148,7 +153,8 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): "id": extruder.getId(), "name": extruder_name, "color": color, - "index": position + "index": position, + "definition": extruder.getBottom().getId() } items.append(item) changed = True diff --git a/cura/Settings/QualitySettingsModel.py b/cura/Settings/QualitySettingsModel.py index 1e5fbc97e7..e57e09e862 100644 --- a/cura/Settings/QualitySettingsModel.py +++ b/cura/Settings/QualitySettingsModel.py @@ -25,6 +25,7 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): self._container_registry = UM.Settings.ContainerRegistry.getInstance() self._extruder_id = None + self._extruder_definition_id = None self._quality = None self._material = None @@ -46,6 +47,17 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): def extruderId(self): return self._extruder_id + def setExtruderDefinition(self, extruder_definition): + if extruder_definition != self._extruder_definition_id: + self._extruder_definition_id = extruder_definition + self._update() + self.extruderDefinitionChanged.emit() + + extruderDefinitionChanged = pyqtSignal() + @pyqtProperty(str, fset = setExtruderDefinition, notify = extruderDefinitionChanged) + def extruderDefinition(self): + return self._extruder_definition_id + def setQuality(self, quality): if quality != self._quality: self._quality = quality @@ -138,8 +150,9 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): if quality_changes_container: criteria = {"type": "quality_changes", "quality_type": quality_type, "definition": definition_id, "name": quality_changes_container.getName()} - if self._extruder_id != "": - criteria["extruder"] = self._extruder_id + if self._extruder_definition_id != "": + criteria["extruder"] = self._extruder_definition_id + criteria["name"] = "%s_%s" % (self._extruder_definition_id, quality_changes_container.getName()) else: criteria["extruder"] = None diff --git a/resources/qml/Preferences/ProfileTab.qml b/resources/qml/Preferences/ProfileTab.qml index d50689ccf9..630d524871 100644 --- a/resources/qml/Preferences/ProfileTab.qml +++ b/resources/qml/Preferences/ProfileTab.qml @@ -12,6 +12,7 @@ Tab id: base property string extruderId: ""; + property string extruderDefinition: ""; property string quality: ""; property string material: ""; @@ -55,7 +56,8 @@ Tab model: Cura.QualitySettingsModel { - extruderId: base.extruderId != "" ? base.extruderId : "" + extruderId: base.extruderId + extruderDefinition: base.extruderDefinition quality: base.quality != null ? base.quality : "" material: base.material != null ? base.material : "" } diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 1809e06a36..335bfda82c 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -223,6 +223,7 @@ UM.ManagementPage { title: model.name; extruderId: model.id; + extruderDefinition: model.definition; quality: base.currentItem != null ? base.currentItem.id : ""; material: Cura.MachineManager.allActiveMaterialIds[model.id] } From e1d70ed4b61fe5148ce22d6264111760ff9e8cfd Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 3 Oct 2016 21:58:34 +0200 Subject: [PATCH 22/29] Fix selecting quality_changes profiles for extruders Now that containers in a quality_changes set don't share a common name, the quality_changes containers for extruders have a metadata entry "global_profile" pointing to the global quality_changes container id. Contributes to CURA-2478 and CURA-2484 --- cura/QualityManager.py | 7 ++++++- cura/Settings/ContainerManager.py | 19 +++++++++++++++++-- cura/Settings/CuraContainerRegistry.py | 4 ++++ cura/Settings/MachineManager.py | 2 +- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/cura/QualityManager.py b/cura/QualityManager.py index 1ec3b85c48..fb3a623466 100644 --- a/cura/QualityManager.py +++ b/cura/QualityManager.py @@ -42,7 +42,12 @@ class QualityManager: # \return the matching quality changes containers \type{List[ContainerInstance]} def findQualityChangesByName(self, quality_changes_name, machine_definition=None): criteria = {"type": "quality_changes", "name": quality_changes_name} - return self._getFilteredContainersForStack(machine_definition, [], **criteria) + result = self._getFilteredContainersForStack(machine_definition, [], **criteria) + + criteria = {"type": "quality_changes", "global_profile": quality_changes_name} + result.extend(self._getFilteredContainersForStack(machine_definition, [], **criteria)) + + return result ## Fetch the list of available quality types for this combination of machine definition and materials. # diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 7537bb3555..494e64c7c2 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -467,6 +467,8 @@ class ContainerManager(QObject): base_name = active_quality_name unique_name = self._container_registry.uniqueName(base_name) + global_changes = None + # Go through the active stacks and create quality_changes containers from the user containers. for stack in cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): user_container = stack.getTop() @@ -482,6 +484,11 @@ class ContainerManager(QObject): extruder_id) self._performMerge(new_changes, user_container) + if stack is global_stack: + global_changes = new_changes + else: + new_changes.setMetaDataEntry("global_profile", global_changes.getId()) + self._container_registry.addContainer(new_changes) stack.replaceContainer(stack.getContainerIndex(quality_changes_container), new_changes) @@ -628,8 +635,9 @@ class ContainerManager(QObject): new_change_instances = [] # Handle the global stack first. - new_changes = self._createQualityChanges(quality_container, new_name, machine_definition, None) - new_change_instances.append(new_changes) + global_changes = self._createQualityChanges(quality_container, new_name, machine_definition, None) + new_changes.addMetaDataEntry("global_profile", global_changes.getId()) + new_change_instances.append(global_changes) self._container_registry.addContainer(new_changes) # Handle the extruders if present. @@ -638,6 +646,7 @@ class ContainerManager(QObject): for key in extruders: value = extruders[key] new_changes = self._createQualityChanges(quality_container, new_name, machine_definition, value) + new_changes.addMetaDataEntry("global_profile", global_changes.getId()) new_change_instances.append(new_changes) self._container_registry.addContainer(new_changes) @@ -646,10 +655,16 @@ class ContainerManager(QObject): # Duplicate a quality changes container def _duplicateQualityChangesForMachineType(self, quality_changes_name, base_name, machine_definition): new_change_instances = [] + profile_index = -1 + global_changes_id = "" for container in QualityManager.getInstance().findQualityChangesByName(quality_changes_name, machine_definition): new_unique_id = self._createUniqueId(container.getId(), base_name) new_container = container.duplicate(new_unique_id, base_name) + if profile_index >= 0: + new_changes.setMetaDataEntry("global_profile", global_changes_id) + else: + global_changes_id = new_unique_id new_change_instances.append(new_container) self._container_registry.addContainer(new_container) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 69951127b5..bd1f981c80 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -171,6 +171,10 @@ class CuraContainerRegistry(ContainerRegistry): profile.setMetaDataEntry("extruder", extruder_id) else: profile.addMetaDataEntry("extruder", extruder_id) + if "global_profile" in profile.getMetaData(): + profile.setMetaDataEntry("global_profile", global_profile.getId()) + else: + profile.addMetaDataEntry("global_profile", global_profile.getId()) elif profile_index == 0: # Importing a multiextrusion profile into a single extrusion machine; merge 1st extruder profile into global profile profile._id = self.uniqueName("temporary_profile") diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 96e7f88a91..1803a59d00 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -462,7 +462,7 @@ class MachineManager(QObject): @pyqtProperty(str, notify=activeQualityChanged) def activeQualityName(self): if self._active_container_stack: - quality = self._active_container_stack.findContainer({"type": "quality_changes"}) + quality = self._global_container_stack.findContainer({"type": "quality_changes"}) if quality and quality != self._empty_quality_changes_container: return quality.getName() quality = self._active_container_stack.findContainer({"type": "quality"}) From 046d0b59566471baedce300de6c4c1ea47437956 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 3 Oct 2016 22:17:56 +0200 Subject: [PATCH 23/29] Rename extruder quality changes files when renaming a custom profile CURA-2484 --- cura/Settings/ContainerManager.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 494e64c7c2..294ca4297a 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -570,9 +570,16 @@ class ContainerManager(QObject): container_registry = self._container_registry containers_to_rename = self._container_registry.findInstanceContainers(type = "quality_changes", name = quality_name) + containers_to_rename.extend(self._container_registry.findInstanceContainers(type = "quality_changes", global_profile = quality_name)) + + global_changes_id = "" for container in containers_to_rename: stack_id = container.getMetaDataEntry("extruder", global_stack.getId()) container_registry.renameContainer(container.getId(), new_name, self._createUniqueId(stack_id, new_name)) + if "global_profile" not in container.getMetaData(): + global_changes_id = container.getId() + else: + container.setMetaDataEntry("global_profile", global_changes_id) if not containers_to_rename: UM.Logger.log("e", "Unable to rename %s, because we could not find the profile", quality_name) From 144dcb5a655e51923cebc838c60cef0e31c77d0e Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 3 Oct 2016 22:18:38 +0200 Subject: [PATCH 24/29] Slightly more defensive programming in case of extruder mismatch --- cura/Settings/CuraContainerRegistry.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index bd1f981c80..d858bf73f4 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -181,10 +181,10 @@ class CuraContainerRegistry(ContainerRegistry): self.addContainer(profile) ContainerManager.getInstance().mergeContainers(global_profile.getId(), profile.getId()) self.removeContainer(profile.getId()) - continue + break else: # The imported composite profile has a profile for an extruder that this machine does not have. Ignore this extruder-profile - continue + break else: global_profile = profile profile_name = name_seed From f55c35df6eb93f22423a250ad9816945cc4b41d5 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 3 Oct 2016 22:40:05 +0200 Subject: [PATCH 25/29] Load extruder profiles into the correct extruder CURA-2478 --- cura/Settings/CuraContainerRegistry.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index d858bf73f4..f5b6568c4a 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -138,6 +138,7 @@ class CuraContainerRegistry(ContainerRegistry): return machine_extruders = list(ExtruderManager.getInstance().getMachineExtruders(global_container_stack.getId())) + machine_extruders.sort(key = lambda k: k.getMetaDataEntry("position")) for plugin_id, meta_data in self._getIOPlugins("profile_reader"): if meta_data["profile_reader"][0]["extension"] != extension: From 556431b984616ebfed89f43ea0975e58081d7f70 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 3 Oct 2016 22:40:28 +0200 Subject: [PATCH 26/29] Fix error when no machine is selected --- cura/Settings/MachineManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 1803a59d00..7bcf155e06 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -461,7 +461,7 @@ class MachineManager(QObject): @pyqtProperty(str, notify=activeQualityChanged) def activeQualityName(self): - if self._active_container_stack: + if self._active_container_stack and self._global_container_stack: quality = self._global_container_stack.findContainer({"type": "quality_changes"}) if quality and quality != self._empty_quality_changes_container: return quality.getName() From 72bd268e2d6796dbf332635f96d4fb1486ce3d17 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 4 Oct 2016 10:37:48 +0200 Subject: [PATCH 27/29] Export now exports correct extruder profiles as well CURA-2496 --- resources/qml/Preferences/ProfilesPage.qml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 335bfda82c..4dfd656cde 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -336,18 +336,16 @@ UM.ManagementPage folder: CuraApplication.getDefaultPath("dialog_profile_path") onAccepted: { - var profiles_to_export = [base.currentItem.id] - for(var extruder_nr in base.extrudersModel.items) - { - profiles_to_export.push(ExtruderManager.getQualityChangesIdByExtruderStackId(base.extrudersModel.items[extruder_nr].id)) - } - var result = base.model.exportProfile(profiles_to_export, fileUrl, selectedNameFilter) + var containers = Cura.ContainerManager.findInstanceContainers({"type": "quality_changes", "name": base.currentItem.name}) + var result = base.model.exportProfile(containers, fileUrl, selectedNameFilter) + if(result && result.status == "error") { messageDialog.icon = StandardIcon.Critical messageDialog.text = result.message messageDialog.open() } + // else pop-up Message thing from python code CuraApplication.setDefaultPath("dialog_profile_path", folder) } From faf98e40f865e29bf559350e79a48ec49c63e8e4 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 4 Oct 2016 10:46:13 +0200 Subject: [PATCH 28/29] Inherit button now correctly removes values if needed for multi extrusion machines CURA-2374 --- resources/qml/Settings/SettingItem.qml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index 0d26ecc760..0c7dec0784 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -217,10 +217,9 @@ Item { break; } } - - if(last_entry == 4 && base.stackLevel == 0 && base.stackLevels.length == 2) + if((last_entry == 4 || last_entry == 11) && base.stackLevel == 0 && base.stackLevels.length == 2) { - // Special case of the inherit reset. If only the definition (4th container) and the first + // Special case of the inherit reset. If only the definition (4th or 11th) container) and the first // entry (user container) are set, we can simply remove the container. propertyProvider.removeFromContainer(0) } From 3b6d8f40aac88a161b359f5e8a2d1a77fbfd3f5c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 4 Oct 2016 11:00:02 +0200 Subject: [PATCH 29/29] Also hide support interface line width if support is disabled Also, the extruderValue call is superfluous since the setting is already limited to this extruder. --- 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 3aa45f7af7..9c6b2d3d40 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -679,7 +679,7 @@ "minimum_value": "0.0001", "maximum_value_warning": "machine_nozzle_size * 2", "type": "float", - "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable')", + "enabled": "support_enable and support_interface_enable", "limit_to_extruder": "support_interface_extruder_nr", "value": "line_width", "settable_per_mesh": false,