From 8cc4063160101e5242f783316d67cb47a5e16da5 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Fri, 12 Oct 2018 12:11:30 +0200 Subject: [PATCH 01/50] feat: option to specify the very bottom thickness --- 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 efa6b9a78c..83c0b88088 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1176,6 +1176,18 @@ "value": "999999 if infill_sparse_density == 100 else math.ceil(round(bottom_thickness / resolveOrValue('layer_height'), 4))", "limit_to_extruder": "top_bottom_extruder_nr", "settable_per_mesh": true + }, + "initial_bottom_layers": + { + "label": "Initial Bottom Layers", + "description": "The number of bottom layers. When calculated by the bottom thickness, this value is rounded to a whole number.", + "minimum_value": "0", + "minimum_value_warning": "2", + "default_value": 6, + "type": "int", + "value": "bottom_layers", + "limit_to_extruder": "top_bottom_extruder_nr", + "settable_per_mesh": true } } } From 0b3757fb3c2e9ae24de5eb069c9705820cacefd7 Mon Sep 17 00:00:00 2001 From: SAMSECTOR Date: Sat, 14 Sep 2019 16:46:58 +0300 Subject: [PATCH 02/50] Add Original_Prusa_i3_MK3S_MK3_platform.stl This is the latest mesh for Prusa i3 MK3/MK3s made by Prusa Research with minor modification to fit in Prusa folder under "add printer" reference : https://manual.prusa3d.com/Guide/How+to+import+profiles+to+Cura+4.x+(Windows+&+macOS)/1421#_ga=2.78043415.205833688.1568467545-859345073.1567270611 --- .../Original_Prusa_i3_MK3S_MK3_platform.stl | Bin 0 -> 487884 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 resources/meshes/Original_Prusa_i3_MK3S_MK3_platform.stl diff --git a/resources/meshes/Original_Prusa_i3_MK3S_MK3_platform.stl b/resources/meshes/Original_Prusa_i3_MK3S_MK3_platform.stl new file mode 100644 index 0000000000000000000000000000000000000000..3b38a7daa2fa39a6e85d3c1b174ab5bbc4db7259 GIT binary patch literal 487884 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

j^v)#!(oSNbq4fDm_QG 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 literal 0 HcmV?d00001 From e946eb1b5ca844f757bd6d0e8deb8f83c5991b26 Mon Sep 17 00:00:00 2001 From: SAMSECTOR Date: Mon, 16 Sep 2019 22:29:58 +0300 Subject: [PATCH 03/50] Creat Original_Prusa_i3_MK3S_MK3.def.json This is the latest definition for Prusa i3 MK3/MK3s made by Prusa Research with minor modification to fit in Prusa folder under "add printer" reference : https://manual.prusa3d.com/Guide/How+to+import+profiles+to+Cura+4.x+(Windows+&+macOS)/1421#_ga=2.78043415.205833688.1568467545-859345073.1567270611 --- .../Original_Prusa_i3_MK3S_MK3.def.json | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 resources/definitions/Original_Prusa_i3_MK3S_MK3.def.json diff --git a/resources/definitions/Original_Prusa_i3_MK3S_MK3.def.json b/resources/definitions/Original_Prusa_i3_MK3S_MK3.def.json new file mode 100644 index 0000000000..439cc1fcda --- /dev/null +++ b/resources/definitions/Original_Prusa_i3_MK3S_MK3.def.json @@ -0,0 +1,53 @@ +{ + "version": 2, + "name": "Original Prusa i3 MK3S/MK3", + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "Prusa Research", + "manufacturer": "Prusa3D", + "file_formats": "text/x-gcode", + "icon": "icon_ultimaker2", + "platform": "Original_Prusa_i3_MK3S_MK3_platform.stl", + "has_materials": true, + "machine_extruder_trains": + { + "0": "Original_Prusa_i3_MK3S_MK3_extruder_0" + } + }, + + "overrides": { + "machine_name": { "default_value": "Original Prusa i3 MK3S/MK3" }, + "machine_heated_bed": { "default_value": true }, + "machine_width": { "default_value": 250 }, + "machine_height": { "default_value": 210 }, + "machine_depth": { "default_value": 210 }, + "machine_center_is_zero": { "default_value": false }, + "material_diameter": { "default_value": 1.75 }, + "material_bed_temperature": { "default_value": 60 }, + "machine_nozzle_size": { "default_value": 0.4 }, + "layer_height": { "default_value": 0.15 }, + "layer_height_0": { "default_value": 0.2 }, + "retraction_amount": { "default_value": 0.8 }, + "retraction_speed": { "default_value": 35 }, + "retraction_retract_speed": { "default_value": 35 }, + "retraction_prime_speed": { "default_value": 35 }, + "adhesion_type": { "default_value": "skirt" }, + "machine_head_with_fans_polygon": { "default_value": [[-31,31],[34,31],[34,-40],[-31,-40]] }, + "gantry_height": { "default_value": 28 }, + "machine_max_feedrate_z": { "default_value": 12 }, + "machine_max_feedrate_e": { "default_value": 120 }, + "machine_max_acceleration_z": { "default_value": 500 }, + "machine_acceleration": { "default_value": 1000 }, + "machine_max_jerk_xy": { "default_value": 10 }, + "machine_max_jerk_z": { "default_value": 0.2 }, + "machine_max_jerk_e": { "default_value": 2.5 }, + "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" }, + "machine_start_gcode": { + "default_value": "G21 ; set units to millimeters\nG90 ; use absolute positioning\nM82 ; absolute extrusion mode\nM104 S{material_print_temperature_layer_0} ; set extruder temp\nM140 S{material_bed_temperature_layer_0} ; set bed temp\nM190 S{material_bed_temperature_layer_0} ; wait for bed temp\nM109 S{material_print_temperature_layer_0} ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG92 E0.0 ; reset extruder distance position\nG1 Y-3.0 F1000.0 ; go outside print area\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E21.5 F1000.0 ; intro line\nG92 E0.0 ; reset extruder distance position" + }, + "machine_end_gcode": { + "default_value": "M104 S0 ; turn off extruder\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y210; home X axis and push Y forward\nM84 ; disable motors" + } + } +} From bd1e370fe66df1b85b52e08e4e0ab0a871eee4c2 Mon Sep 17 00:00:00 2001 From: SAMSECTOR Date: Mon, 16 Sep 2019 22:31:16 +0300 Subject: [PATCH 04/50] Create Original_Prusa_i3_MK3S_MK3_extruder_0.def This is the latest extruder definition for Prusa i3 MK3/MK3s . reference : https://manual.prusa3d.com/Guide/How+to+import+profiles+to+Cura+4.x+(Windows+&+macOS)/1421#_ga=2.78043415.205833688.1568467545-859345073.1567270611 --- ...riginal_Prusa_i3_MK3S_MK3_extruder_0.def.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 resources/extruders/Original_Prusa_i3_MK3S_MK3_extruder_0.def.json diff --git a/resources/extruders/Original_Prusa_i3_MK3S_MK3_extruder_0.def.json b/resources/extruders/Original_Prusa_i3_MK3S_MK3_extruder_0.def.json new file mode 100644 index 0000000000..18d69e4557 --- /dev/null +++ b/resources/extruders/Original_Prusa_i3_MK3S_MK3_extruder_0.def.json @@ -0,0 +1,16 @@ +{ + "id": "Original_Prusa_i3_MK3S_MK3_extruder_0", + "version": 2, + "name": "Extruder 1", + "inherits": "fdmextruder", + "metadata": { + "machine": "Original_Prusa_i3_MK3S_MK3", + "position": "0" + }, + + "overrides": { + "extruder_nr": { "default_value": 0 }, + "machine_nozzle_size": { "default_value": 0.4 }, + "material_diameter": { "default_value": 1.75 } + } +} \ No newline at end of file From 00676e3878a5e0bd3eaf6355de6a0f0fdd5c2cab Mon Sep 17 00:00:00 2001 From: DragonJe <41123088+DragonJe@users.noreply.github.com> Date: Mon, 16 Sep 2019 17:53:13 -0500 Subject: [PATCH 05/50] Create key3d_tyro.def.json --- resources/definitions/key3d_tyro.def.json | 65 +++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 resources/definitions/key3d_tyro.def.json diff --git a/resources/definitions/key3d_tyro.def.json b/resources/definitions/key3d_tyro.def.json new file mode 100644 index 0000000000..e14f601d7d --- /dev/null +++ b/resources/definitions/key3d_tyro.def.json @@ -0,0 +1,65 @@ +{ + "name": "Tyro", + "version": 2, + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "DragonJe", + "manufacturer": "Key3D", + "file_formats": "text/x-gcode", + "platform_offset": [0, 0, 0], + "has_materials": true, + "has_variants": false, + "preferred_quality_type": "normal", + "has_machine_quality": true, + "preferred_material": "generic_pla", + "machine_extruder_trains": + { + "0": "key3d_tyro_extruder_0" + } + }, + + "overrides": { + "machine_name": { + "default_value": "Tyro" + }, + "machine_width": { + "default_value": 150 + }, + "machine_height": { + "default_value": 150 + }, + "machine_depth": { + "default_value": 150 + }, + "machine_head_polygon": { + "default_value": [ + [-30, 34], + [-30, -32], + [30, -32], + [30, 34] + ] + }, + "gantry_height": { + "value": "30" + }, + "machine_heated_bed": { + "default_value": false + }, + "machine_heated_build_volume": { + "default_value": false + }, + "material_diameter": { + "default_value": 1.75 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "default_value": "G28 ; Home\nG1 Z15.0 F6000 ; Move Z axis up 15mm\n ; Prime the extruder\nG92 E0\nG1 F200 E3\nG92 E0" + }, + "machine_end_gcode": { + "default_value": "M104 S0\nM140 S0\n ; Retract the filament\nG92 E1\nG1 E-1 F300\nG28 X0 Y0\nM84" + } + } +} From 3c24e9fa189616b5f5be96ae851e586f2e878a05 Mon Sep 17 00:00:00 2001 From: DragonJe <41123088+DragonJe@users.noreply.github.com> Date: Mon, 16 Sep 2019 17:54:04 -0500 Subject: [PATCH 06/50] Create key3d_tyro_extruder_0.def.json --- .../extruders/key3d_tyro_extruder_0.def.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 resources/extruders/key3d_tyro_extruder_0.def.json diff --git a/resources/extruders/key3d_tyro_extruder_0.def.json b/resources/extruders/key3d_tyro_extruder_0.def.json new file mode 100644 index 0000000000..6d5b83a1ef --- /dev/null +++ b/resources/extruders/key3d_tyro_extruder_0.def.json @@ -0,0 +1,16 @@ +{ + "id": "key3d_tyro_extruder_0", + "version": 2, + "name": "0.4mm Nozzle", + "inherits": "fdmextruder", + "metadata": { + "machine": "Tyro", + "position": "0" + }, + + "overrides": { + "extruder_nr": { "default_value": 0 }, + "machine_nozzle_size": { "default_value": 0.4 }, + "material_diameter": { "default_value": 1.75 } + } +} From 7774da41784998ecd2bf471ae2fb4c9070614ae3 Mon Sep 17 00:00:00 2001 From: DragonJe <41123088+DragonJe@users.noreply.github.com> Date: Mon, 16 Sep 2019 17:55:43 -0500 Subject: [PATCH 07/50] Create key3d_tyro_normal.inst.cfg --- .../quality/key3d/key3d_tyro_normal.inst.cfg | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 resources/quality/key3d/key3d_tyro_normal.inst.cfg diff --git a/resources/quality/key3d/key3d_tyro_normal.inst.cfg b/resources/quality/key3d/key3d_tyro_normal.inst.cfg new file mode 100644 index 0000000000..7f650612ff --- /dev/null +++ b/resources/quality/key3d/key3d_tyro_normal.inst.cfg @@ -0,0 +1,127 @@ +[general] +version = 4 +name = Normal Quality +definition = key3d_tyro + +[metadata] +setting_version = 9 +type = quality +quality_type = normal +weight = 0 +global_quality = True + +[values] +layer_height = 0.16 +layer_height_0 = 0.24 +line_width = 0.4 +initial_layer_line_width_factor = 100 +wall_thickness = 0.8 +wall_0_wipe_dist = 0.2 +roofing_layer_count = 1 +top_bottom_thickness = 0.6 +top_thickness = 0.8 +top_layers = 5 +bottom_thickness = 0.6 +bottom_layers = 3 +top_bottom_pattern = lines +top_bottom_pattern_0 = lines +wall_0_inset = 0 +optimize_wall_printing_order = False +outer_inset_first = False +alternate_extra_perimeter = False +travel_compensate_overlapping_walls_enabled = True +travel_compensate_overlapping_walls_0_enabled = True +travel_compensate_overlapping_walls_x_enabled = True +wall_min_flow = 0 +fill_perimeter_gaps = everywhere +filter_out_tiny_gaps = True +fill_outline_gaps = True +xy_offset = 0 +skin_no_small_gaps_heuristic = True +skin_outline_count = 1 +ironing_enabled = False +infill_sparse_density = 20 +zig_zaggify_infill = False +infill_multiplier = 1 +infill_wall_line_count = 0 +infill_overlap = 10 +skin_overlap = 5 +infill_wipe_dist = 0.1 +gradual_infill_steps = 0 +infill_before_walls = False +infill_support_enabled = False +max_skin_angle_for_expansion = 90 +material_diameter = 1.75 +default_material_print_temperature = 220 +material_print_temperature = 220 +material_print_temperature_layer_0 = 220 +material_initial_print_temperature = 220 +material_final_print_temperature = 220 +default_material_bed_temperature = 0 +material_bed_temperature = 0 +build_volume_temperature = 0 +material_flow = 100 +retraction_enable = True +retract_at_layer_change = False +retraction_amount = 5 +retraction_speed = 45 +retraction_extra_prime_amount = 0 +retraction_min_travel = 0.8 +retraction_count_max = 90 +retraction_extrusion_window = 5 +limit_support_retractions = True +switch_extruder_retraction_amount = 16 +switch_extruder_retraction_speeds = 20 +speed_print = 50 +speed_travel = 150 +speed_layer_0 = 10 +speed_travel_layer_0 = 50 +speed_slowdown_layers = 2 +speed_equalize_flow_enabled = False +acceleration_enabled = False +acceleration_roofing = 3000 +jerk_enabled = False +retraction_combing = off +travel_retract_before_outer_wall = False +retraction_hop_enabled = False +cool_fan_enabled = True +cool_fan_speed = 100 +cool_fan_speed_0 = 0 +cool_fan_full_at_height = 0.32 +cool_lift_head = False +support_enable = True +support_type = everywhere +support_angle = 50 +support_pattern = grid +support_wall_count = 0 +zig_zaggify_support = False +support_infill_rate = =20 if support_enable else 0 if support_tree_enable else 20 +support_infill_angles = [0] +support_brim_enable = True +support_brim_line_count = 5 +support_z_distance = 0.21 +support_xy_distance = 0.7 +support_xy_distance_overhang = 0.2 +support_bottom_stair_step_height = 0.3 +support_bottom_stair_step_width = 5.0 +support_join_distance = 2.0 +support_offset = 0.2 +gradual_support_infill_steps = 0 +support_roof_enable = True +support_bottom_enable = False +support_roof_height = 0.45 +support_roof_density = 45 +support_roof_pattern = lines +support_fan_enable = False +support_use_towers = True +support_tower_diameter = 3 +support_tower_roof_angle = 65 +adhesion_type = skirt +skirt_line_count = 2 +skirt_gap = 3 +meshfix_union_all = True +meshfix_union_all_remove_holes = False +meshfix_extensive_stitching = False +meshfix_keep_open_polygons = False +multiple_mesh_overlap = 0.16 +carve_multiple_volumes = False From 065d6b7f6a23faedaa9fd33710fe6a75730e6c4a Mon Sep 17 00:00:00 2001 From: DragonJe <41123088+DragonJe@users.noreply.github.com> Date: Mon, 16 Sep 2019 17:56:20 -0500 Subject: [PATCH 08/50] Create key3d_tyro_fast.inst.cfg --- .../quality/key3d/key3d_tyro_fast.inst.cfg | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 resources/quality/key3d/key3d_tyro_fast.inst.cfg diff --git a/resources/quality/key3d/key3d_tyro_fast.inst.cfg b/resources/quality/key3d/key3d_tyro_fast.inst.cfg new file mode 100644 index 0000000000..4ca4a65950 --- /dev/null +++ b/resources/quality/key3d/key3d_tyro_fast.inst.cfg @@ -0,0 +1,127 @@ +[general] +version = 4 +name = Fast Quality +definition = key3d_tyro + +[metadata] +setting_version = 9 +type = quality +quality_type = fast +weight = -1 +global_quality = True + +[values] +layer_height = 0.24 +layer_height_0 = 0.24 +line_width = 0.4 +initial_layer_line_width_factor = 100 +wall_thickness = 0.8 +wall_0_wipe_dist = 0.2 +roofing_layer_count = 1 +top_bottom_thickness = 0.6 +top_thickness = 0.8 +top_layers = 5 +bottom_thickness = 0.6 +bottom_layers = 3 +top_bottom_pattern = lines +top_bottom_pattern_0 = lines +wall_0_inset = 0 +optimize_wall_printing_order = False +outer_inset_first = False +alternate_extra_perimeter = False +travel_compensate_overlapping_walls_enabled = True +travel_compensate_overlapping_walls_0_enabled = True +travel_compensate_overlapping_walls_x_enabled = True +wall_min_flow = 0 +fill_perimeter_gaps = everywhere +filter_out_tiny_gaps = True +fill_outline_gaps = True +xy_offset = 0 +skin_no_small_gaps_heuristic = True +skin_outline_count = 1 +ironing_enabled = False +infill_sparse_density = 15 +zig_zaggify_infill = False +infill_multiplier = 1 +infill_wall_line_count = 0 +infill_overlap = 10 +skin_overlap = 5 +infill_wipe_dist = 0.1 +gradual_infill_steps = 0 +infill_before_walls = False +infill_support_enabled = False +max_skin_angle_for_expansion = 90 +material_diameter = 1.75 +default_material_print_temperature = 220 +material_print_temperature = 220 +material_print_temperature_layer_0 = 220 +material_initial_print_temperature = 220 +material_final_print_temperature = 220 +default_material_bed_temperature = 0 +material_bed_temperature = 0 +build_volume_temperature = 0 +material_flow = 100 +retraction_enable = True +retract_at_layer_change = False +retraction_amount = 5 +retraction_speed = 45 +retraction_extra_prime_amount = 0 +retraction_min_travel = 0.8 +retraction_count_max = 90 +retraction_extrusion_window = 5 +limit_support_retractions = True +switch_extruder_retraction_amount = 16 +switch_extruder_retraction_speeds = 20 +speed_print = 60 +speed_travel = 150 +speed_layer_0 = 10 +speed_travel_layer_0 = 50 +speed_slowdown_layers = 2 +speed_equalize_flow_enabled = False +acceleration_enabled = False +acceleration_roofing = 3000 +jerk_enabled = False +retraction_combing = off +travel_retract_before_outer_wall = False +retraction_hop_enabled = False +cool_fan_enabled = True +cool_fan_speed = 100 +cool_fan_speed_0 = 0 +cool_fan_full_at_height = 0.48 +cool_lift_head = False +support_enable = True +support_type = everywhere +support_angle = 50 +support_pattern = grid +support_wall_count = 0 +zig_zaggify_support = False +support_infill_rate = =15 if support_enable else 0 if support_tree_enable else 15 +support_infill_angles = [0] +support_brim_enable = True +support_brim_line_count = 5 +support_z_distance = 0.3 +support_xy_distance = 0.7 +support_xy_distance_overhang = 0.2 +support_bottom_stair_step_height = 0.3 +support_bottom_stair_step_width = 5.0 +support_join_distance = 2.0 +support_offset = 0.2 +gradual_support_infill_steps = 0 +support_roof_enable = True +support_bottom_enable = False +support_roof_height = 0.45 +support_roof_density = 45 +support_roof_pattern = lines +support_fan_enable = False +support_use_towers = True +support_tower_diameter = 3 +support_tower_roof_angle = 65 +adhesion_type = skirt +skirt_line_count = 2 +skirt_gap = 3 +meshfix_union_all = True +meshfix_union_all_remove_holes = False +meshfix_extensive_stitching = False +meshfix_keep_open_polygons = False +multiple_mesh_overlap = 0.16 +carve_multiple_volumes = False From 679e555a34cfae080cab47a8548675078f425fda Mon Sep 17 00:00:00 2001 From: DragonJe <41123088+DragonJe@users.noreply.github.com> Date: Mon, 16 Sep 2019 17:57:29 -0500 Subject: [PATCH 09/50] Create key3d_tyro_best.inst.cfg --- .../quality/key3d/key3d_tyro_best.inst.cfg | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 resources/quality/key3d/key3d_tyro_best.inst.cfg diff --git a/resources/quality/key3d/key3d_tyro_best.inst.cfg b/resources/quality/key3d/key3d_tyro_best.inst.cfg new file mode 100644 index 0000000000..e5a257f898 --- /dev/null +++ b/resources/quality/key3d/key3d_tyro_best.inst.cfg @@ -0,0 +1,128 @@ +[general] +version = 4 +name = Best Quality +definition = key3d_tyro + +[metadata] +setting_version = 9 +type = quality +quality_type = best +weight = 1 +global_quality = True + +[values] +layer_height = 0.08 +layer_height_0 = 0.24 +line_width = 0.4 +wall_line_width_0 = 0.4 +initial_layer_line_width_factor = 100 +wall_thickness = 0.8 +wall_0_wipe_dist = 0.2 +roofing_layer_count = 1 +top_bottom_thickness = 0.6 +top_thickness = 0.8 +top_layers = 5 +bottom_thickness = 0.6 +bottom_layers = 3 +top_bottom_pattern = lines +top_bottom_pattern_0 = lines +wall_0_inset = 0 +optimize_wall_printing_order = False +outer_inset_first = False +alternate_extra_perimeter = False +travel_compensate_overlapping_walls_enabled = True +travel_compensate_overlapping_walls_0_enabled = True +travel_compensate_overlapping_walls_x_enabled = True +wall_min_flow = 0 +fill_perimeter_gaps = everywhere +filter_out_tiny_gaps = True +fill_outline_gaps = True +xy_offset = 0 +skin_no_small_gaps_heuristic = True +skin_outline_count = 1 +ironing_enabled = False +infill_sparse_density = 20 +zig_zaggify_infill = False +infill_multiplier = 1 +infill_wall_line_count = 0 +infill_overlap = 10 +skin_overlap = 5 +infill_wipe_dist = 0.1 +gradual_infill_steps = 0 +infill_before_walls = False +infill_support_enabled = False +max_skin_angle_for_expansion = 90 +material_diameter = 1.75 +default_material_print_temperature = 220 +material_print_temperature = 220 +material_print_temperature_layer_0 = 220 +material_initial_print_temperature = 220 +material_final_print_temperature = 220 +default_material_bed_temperature = 0 +material_bed_temperature = 0 +build_volume_temperature = 0 +material_flow = 100 +retraction_enable = True +retract_at_layer_change = False +retraction_amount = 5 +retraction_speed = 45 +retraction_extra_prime_amount = 0 +retraction_min_travel = 0.8 +retraction_count_max = 90 +retraction_extrusion_window = 5 +limit_support_retractions = True +switch_extruder_retraction_amount = 16 +switch_extruder_retraction_speeds = 20 +speed_print = 30 +speed_travel = 150 +speed_layer_0 = 10 +speed_travel_layer_0 = 50 +speed_slowdown_layers = 2 +speed_equalize_flow_enabled = False +acceleration_enabled = False +acceleration_roofing = 3000 +jerk_enabled = False +retraction_combing = off +travel_retract_before_outer_wall = False +retraction_hop_enabled = False +cool_fan_enabled = True +cool_fan_speed = 100 +cool_fan_speed_0 = 0 +cool_fan_full_at_height = 0.24 +cool_lift_head = False +support_enable = True +support_type = everywhere +support_angle = 50 +support_pattern = grid +support_wall_count = 0 +zig_zaggify_support = False +support_infill_rate = =20 if support_enable else 0 if support_tree_enable else 20 +support_infill_angles = [0] +support_brim_enable = True +support_brim_line_count = 5 +support_z_distance = 0.2 +support_xy_distance = 0.7 +support_xy_distance_overhang = 0.2 +support_bottom_stair_step_height = 0.3 +support_bottom_stair_step_width = 5.0 +support_join_distance = 2.0 +support_offset = 0.2 +gradual_support_infill_steps = 0 +support_roof_enable = True +support_bottom_enable = False +support_roof_height = 0.45 +support_roof_density = 45 +support_roof_pattern = lines +support_fan_enable = False +support_use_towers = True +support_tower_diameter = 3 +support_tower_roof_angle = 65 +adhesion_type = skirt +skirt_line_count = 2 +skirt_gap = 3 +meshfix_union_all = True +meshfix_union_all_remove_holes = False +meshfix_extensive_stitching = False +meshfix_keep_open_polygons = False +multiple_mesh_overlap = 0.16 +carve_multiple_volumes = False From c9e281f52e377fc51dc06c273eaa637aa75d2e61 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 20 Sep 2019 14:51:37 +0200 Subject: [PATCH 10/50] Add preference for general/restore_window_geometry See https://github.com/Ultimaker/Uranium/pull/523 --- resources/qml/Preferences/GeneralPage.qml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/resources/qml/Preferences/GeneralPage.qml b/resources/qml/Preferences/GeneralPage.qml index 4adb3e72d2..cdbe5d7e0e 100644 --- a/resources/qml/Preferences/GeneralPage.qml +++ b/resources/qml/Preferences/GeneralPage.qml @@ -94,6 +94,8 @@ UM.PreferencesPage zoomToMouseCheckbox.checked = boolCheck(UM.Preferences.getValue("view/zoom_to_mouse")) UM.Preferences.resetPreference("view/top_layer_count"); topLayerCountCheckbox.checked = boolCheck(UM.Preferences.getValue("view/top_layer_count")) + UM.Preferences.resetPreference("general/restore_window_geometry") + restoreWindowPositionCheckbox.checked = boolCheck(UM.Preferences.getValue("general/restore_window_geometry")) UM.Preferences.resetPreference("general/camera_perspective_mode") var defaultCameraMode = UM.Preferences.getValue("general/camera_perspective_mode") @@ -458,6 +460,21 @@ UM.PreferencesPage } } + UM.TooltipArea + { + width: childrenRect.width + height: childrenRect.height + text: catalog.i18nc("@info:tooltip", "Should Cura open at the location it was closed?") + + CheckBox + { + id: restoreWindowPositionCheckbox + text: catalog.i18nc("@option:check", "Restore window position on start") + checked: boolCheck(UM.Preferences.getValue("general/restore_window_geometry")) + onCheckedChanged: UM.Preferences.setValue("general/restore_window_geometry", checked) + } + } + UM.TooltipArea { width: childrenRect.width From 5bb23e4c6f335eca18b73dfb5517bbabd85d6782 Mon Sep 17 00:00:00 2001 From: Nino van Hooff Date: Mon, 7 Oct 2019 15:22:04 +0200 Subject: [PATCH 11/50] Make the height of the layer slider dynamic Prevents the action panel from overlapping the layer slider CURA-6853 --- plugins/PreviewStage/PreviewMain.qml | 1 + plugins/SimulationView/LayerSlider.qml | 5 +++++ plugins/SimulationView/SimulationView.py | 2 +- plugins/SimulationView/SimulationViewMainComponent.qml | 10 +++++++++- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/plugins/PreviewStage/PreviewMain.qml b/plugins/PreviewStage/PreviewMain.qml index 6b5ce2436b..cd448dc0b6 100644 --- a/plugins/PreviewStage/PreviewMain.qml +++ b/plugins/PreviewStage/PreviewMain.qml @@ -13,6 +13,7 @@ Item { Loader { + property var panelTop: actionPanelWidget.y id: previewMain anchors.fill: parent diff --git a/plugins/SimulationView/LayerSlider.qml b/plugins/SimulationView/LayerSlider.qml index 88f298d1f5..d2af1e223b 100644 --- a/plugins/SimulationView/LayerSlider.qml +++ b/plugins/SimulationView/LayerSlider.qml @@ -176,6 +176,11 @@ Item } } + onHeightChanged : { + print("new height:" + height) + //rangeHandle.onHandleDragged() + } + // Upper handle Rectangle { diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index 28d5a74523..3a7cb0d2fe 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -48,7 +48,7 @@ if TYPE_CHECKING: catalog = i18nCatalog("cura") -## View used to display g-code paths. +## The preview layer view. It is used to display g-code paths. class SimulationView(CuraView): # Must match SimulationViewMenuComponent.qml LAYER_VIEW_TYPE_MATERIAL_TYPE = 0 diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index 58901652d3..51fc70ade8 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -14,6 +14,7 @@ Item property bool is_simulation_playing: false visible: UM.SimulationView.layerActivity && CuraApplication.platformActivity + // A slider which lets users trace a single layer (XY movements) PathSlider { id: pathSlider @@ -170,18 +171,24 @@ Item } } + // Scrolls trough Z layers LayerSlider { + property var preferredHeight: UM.Theme.getSize("slider_layerview_size").height + property double heightMargin: UM.Theme.getSize("default_margin").height id: layerSlider width: UM.Theme.getSize("slider_handle").width - height: UM.Theme.getSize("slider_layerview_size").height + height: preferredHeight + heightMargin * 2 < panelTop ? preferredHeight : panelTop - heightMargin * 2 anchors { right: parent.right verticalCenter: parent.verticalCenter + verticalCenterOffset: -(parent.height - panelTop) / 2 // center between parent top and panelTop rightMargin: UM.Theme.getSize("default_margin").width + bottomMargin: heightMargin + topMargin: heightMargin } // Custom properties @@ -209,6 +216,7 @@ Item // Make sure the slider handlers show the correct value after switching views Component.onCompleted: { + print("paneltop", panelTop, "screenscaleFactor") layerSlider.setLowerValue(UM.SimulationView.minimumLayer) layerSlider.setUpperValue(UM.SimulationView.currentLayer) } From f090450bba2349bb3b81a713f5d617d7f7316ee6 Mon Sep 17 00:00:00 2001 From: Nino van Hooff Date: Mon, 7 Oct 2019 16:27:25 +0200 Subject: [PATCH 12/50] Fix pixel-position of layer slider after the window was resized. CURA-6853 --- plugins/SimulationView/LayerSlider.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/SimulationView/LayerSlider.qml b/plugins/SimulationView/LayerSlider.qml index d2af1e223b..9706b04e03 100644 --- a/plugins/SimulationView/LayerSlider.qml +++ b/plugins/SimulationView/LayerSlider.qml @@ -177,8 +177,8 @@ Item } onHeightChanged : { - print("new height:" + height) - //rangeHandle.onHandleDragged() + // After a height change, the pixel-position of the lower handle is out of sync with the property value + setLowerValue(lowerValue) } // Upper handle @@ -338,7 +338,7 @@ Item // set the slider position based on the lower value function setValue(value) { - + print("lower handle set value: " + value) // Normalize values between range, since using arrow keys will create out-of-the-range values value = sliderRoot.normalizeValue(value) From 4148f56d2b58465055914910f08e1a92fe657586 Mon Sep 17 00:00:00 2001 From: Nino van Hooff Date: Wed, 9 Oct 2019 16:51:28 +0200 Subject: [PATCH 13/50] Remove external dependency from SimulationViewMainComponent Previously, panelTop had to be defined externally whenever SimulationViewMainComponent was used. I renamed it and set a default so the binding by a parent is optional. CURA-6853 --- plugins/PreviewStage/PreviewMain.qml | 9 ++++++++- plugins/SimulationView/LayerSlider.qml | 1 - plugins/SimulationView/SimulationViewMainComponent.qml | 10 +++++++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/plugins/PreviewStage/PreviewMain.qml b/plugins/PreviewStage/PreviewMain.qml index cd448dc0b6..a065a751ac 100644 --- a/plugins/PreviewStage/PreviewMain.qml +++ b/plugins/PreviewStage/PreviewMain.qml @@ -13,11 +13,18 @@ Item { Loader { - property var panelTop: actionPanelWidget.y id: previewMain anchors.fill: parent source: UM.Controller.activeView != null && UM.Controller.activeView.mainComponent != null ? UM.Controller.activeView.mainComponent : "" + + // Indicate that the layer slider should stay above the action panel + Binding + { + target: previewMain.item + property: "layerSliderSafeYMax" + value: actionPanelWidget.y + } } Cura.ActionPanelWidget diff --git a/plugins/SimulationView/LayerSlider.qml b/plugins/SimulationView/LayerSlider.qml index 9706b04e03..15b0fdbe12 100644 --- a/plugins/SimulationView/LayerSlider.qml +++ b/plugins/SimulationView/LayerSlider.qml @@ -338,7 +338,6 @@ Item // set the slider position based on the lower value function setValue(value) { - print("lower handle set value: " + value) // Normalize values between range, since using arrow keys will create out-of-the-range values value = sliderRoot.normalizeValue(value) diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index 51fc70ade8..c115dafe26 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -12,6 +12,11 @@ import Cura 1.0 as Cura Item { property bool is_simulation_playing: false + // By default, the layer slider can extend to the entire height of the parent + // A parent may bind this property to indicate the bottom of a safe area + // for the Layer slider + property var layerSliderSafeYMax: parent.height + visible: UM.SimulationView.layerActivity && CuraApplication.platformActivity // A slider which lets users trace a single layer (XY movements) @@ -179,13 +184,13 @@ Item id: layerSlider width: UM.Theme.getSize("slider_handle").width - height: preferredHeight + heightMargin * 2 < panelTop ? preferredHeight : panelTop - heightMargin * 2 + height: preferredHeight + heightMargin * 2 < layerSliderSafeYMax ? preferredHeight : layerSliderSafeYMax - heightMargin * 2 anchors { right: parent.right verticalCenter: parent.verticalCenter - verticalCenterOffset: -(parent.height - panelTop) / 2 // center between parent top and panelTop + verticalCenterOffset: -(parent.height - layerSliderSafeYMax) / 2 // center between parent top and layerSliderSafeYMax rightMargin: UM.Theme.getSize("default_margin").width bottomMargin: heightMargin topMargin: heightMargin @@ -216,7 +221,6 @@ Item // Make sure the slider handlers show the correct value after switching views Component.onCompleted: { - print("paneltop", panelTop, "screenscaleFactor") layerSlider.setLowerValue(UM.SimulationView.minimumLayer) layerSlider.setUpperValue(UM.SimulationView.currentLayer) } From 87bbf3259791efc1724f3509f0db239b6af1794e Mon Sep 17 00:00:00 2001 From: Nino van Hooff Date: Wed, 9 Oct 2019 16:53:19 +0200 Subject: [PATCH 14/50] Rename is_simulation_playing CURA-6853 --- .../SimulationView/SimulationViewMainComponent.qml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index c115dafe26..ddbb5b6224 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -11,7 +11,7 @@ import Cura 1.0 as Cura Item { - property bool is_simulation_playing: false + property bool isSimulationPlaying: false // By default, the layer slider can extend to the entire height of the parent // A parent may bind this property to indicate the bottom of a safe area // for the Layer slider @@ -64,7 +64,7 @@ Item UM.SimpleButton { id: playButton - iconSource: !is_simulation_playing ? "./resources/simulation_resume.svg": "./resources/simulation_pause.svg" + iconSource: !isSimulationPlaying ? "./resources/simulation_resume.svg": "./resources/simulation_pause.svg" width: UM.Theme.getSize("small_button").width height: UM.Theme.getSize("small_button").height hoverColor: UM.Theme.getColor("slider_handle_active") @@ -94,7 +94,7 @@ Item onClicked: { - if(is_simulation_playing) + if(isSimulationPlaying) { pauseSimulation() } @@ -108,7 +108,7 @@ Item { UM.SimulationView.setSimulationRunning(false) simulationTimer.stop() - is_simulation_playing = false + isSimulationPlaying = false layerSlider.manuallyChanged = true pathSlider.manuallyChanged = true } @@ -137,7 +137,7 @@ Item // When the user plays the simulation, if the path slider is at the end of this layer, we start // the simulation at the beginning of the current layer. - if (!is_simulation_playing) + if (!isSimulationPlaying) { if (currentPath >= numPaths) { @@ -172,7 +172,7 @@ Item } // The status must be set here instead of in the resumeSimulation function otherwise it won't work // correctly, because part of the logic is in this trigger function. - is_simulation_playing = true + isSimulationPlaying = true } } From 9b836d95d9db1c2a08ed43a53af2487c140294ed Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 16 Oct 2019 13:00:38 +0200 Subject: [PATCH 15/50] Remove quality, variant and material manager We don't use them any more and they are deprecated. Removing them removes a lot of maintenance. Contributes to issue CURA-6801. --- cura/CuraApplication.py | 17 -- cura/Machines/MaterialManager.py | 349 ------------------------------- cura/Machines/QualityManager.py | 215 ------------------- cura/Machines/VariantManager.py | 98 --------- tests/TestMaterialManager.py | 187 ----------------- tests/TestQualityManager.py | 129 ------------ 6 files changed, 995 deletions(-) delete mode 100644 cura/Machines/MaterialManager.py delete mode 100644 cura/Machines/QualityManager.py delete mode 100644 cura/Machines/VariantManager.py delete mode 100644 tests/TestMaterialManager.py delete mode 100644 tests/TestQualityManager.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 579be0d953..8caccc786e 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -73,9 +73,6 @@ from cura.Scene import ZOffsetDecorator from cura.Machines.ContainerTree import ContainerTree from cura.Machines.MachineErrorChecker import MachineErrorChecker -import cura.Machines.MaterialManager #Imported like this to prevent circular imports. -import cura.Machines.QualityManager #Imported like this to prevent circular imports. -from cura.Machines.VariantManager import VariantManager from cura.Machines.Models.BuildPlateModel import BuildPlateModel from cura.Machines.Models.CustomQualityProfilesDropDownMenuModel import CustomQualityProfilesDropDownMenuModel @@ -924,20 +921,6 @@ class CuraApplication(QtApplication): self._extruder_manager = ExtruderManager() return self._extruder_manager - @deprecated("Use the ContainerTree structure instead.", since = "4.3") - def getVariantManager(self, *args) -> VariantManager: - return VariantManager.getInstance() - - # Can't deprecate this function since the deprecation marker collides with pyqtSlot! - @pyqtSlot(result = QObject) - def getMaterialManager(self, *args) -> cura.Machines.MaterialManager.MaterialManager: - return cura.Machines.MaterialManager.MaterialManager.getInstance() - - # Can't deprecate this function since the deprecation marker collides with pyqtSlot! - @pyqtSlot(result = QObject) - def getQualityManager(self, *args) -> cura.Machines.QualityManager.QualityManager: - return cura.Machines.QualityManager.QualityManager.getInstance() - def getIntentManager(self, *args) -> IntentManager: return IntentManager.getInstance() diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py deleted file mode 100644 index 83be6941ea..0000000000 --- a/cura/Machines/MaterialManager.py +++ /dev/null @@ -1,349 +0,0 @@ -# Copyright (c) 2019 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -from collections import defaultdict -import copy -import uuid -from typing import Dict, Optional, TYPE_CHECKING, Any, List, cast - -from PyQt5.Qt import QTimer, QObject, pyqtSignal, pyqtSlot - -from UM.Decorators import deprecated -from UM.Logger import Logger -from UM.Settings.ContainerRegistry import ContainerRegistry -from UM.Util import parseBool -import cura.CuraApplication # Imported like this to prevent circular imports. -from cura.Machines.ContainerTree import ContainerTree -from cura.Settings.CuraContainerRegistry import CuraContainerRegistry - -from .MaterialNode import MaterialNode -from .MaterialGroup import MaterialGroup - -if TYPE_CHECKING: - from UM.Settings.DefinitionContainer import DefinitionContainer - from UM.Settings.InstanceContainer import InstanceContainer - from cura.Settings.GlobalStack import GlobalStack - from cura.Settings.ExtruderStack import ExtruderStack - - -# -# MaterialManager maintains a number of maps and trees for material lookup. -# The models GUI and QML use are now only dependent on the MaterialManager. That means as long as the data in -# MaterialManager gets updated correctly, the GUI models should be updated correctly too, and the same goes for GUI. -# -# For now, updating the lookup maps and trees here is very simple: we discard the old data completely and recreate them -# again. This means the update is exactly the same as initialization. There are performance concerns about this approach -# but so far the creation of the tables and maps is very fast and there is no noticeable slowness, we keep it like this -# because it's simple. -# -class MaterialManager(QObject): - __instance = None - - @classmethod - @deprecated("Use the ContainerTree structure instead.", since = "4.3") - def getInstance(cls) -> "MaterialManager": - if cls.__instance is None: - cls.__instance = MaterialManager() - return cls.__instance - - materialsUpdated = pyqtSignal() # Emitted whenever the material lookup tables are updated. - favoritesUpdated = pyqtSignal() # Emitted whenever the favorites are changed - - def __init__(self, parent = None): - super().__init__(parent) - # Material_type -> generic material metadata - self._fallback_materials_map = dict() # type: Dict[str, Dict[str, Any]] - - # Root_material_id -> MaterialGroup - self._material_group_map = dict() # type: Dict[str, MaterialGroup] - - # Material id including diameter (generic_pla_175) -> material root id (generic_pla) - self._diameter_material_map = dict() # type: Dict[str, str] - - # This is used in Legacy UM3 send material function and the material management page. - # GUID -> a list of material_groups - self._guid_material_groups_map = defaultdict(list) # type: Dict[str, List[MaterialGroup]] - - self._favorites = set(cura.CuraApplication.CuraApplication.getInstance().getPreferences().getValue("cura/favorite_materials").split(";")) - self.materialsUpdated.emit() - - self._update_timer = QTimer(self) - self._update_timer.setInterval(300) - - self._update_timer.setSingleShot(True) - self._update_timer.timeout.connect(self.materialsUpdated) - - container_registry = ContainerRegistry.getInstance() - container_registry.containerMetaDataChanged.connect(self._onContainerMetadataChanged) - container_registry.containerAdded.connect(self._onContainerMetadataChanged) - container_registry.containerRemoved.connect(self._onContainerMetadataChanged) - - def _onContainerMetadataChanged(self, container): - self._onContainerChanged(container) - - def _onContainerChanged(self, container): - container_type = container.getMetaDataEntry("type") - if container_type != "material": - return - - # update the maps - - self._update_timer.start() - - def getMaterialGroup(self, root_material_id: str) -> Optional[MaterialGroup]: - return self._material_group_map.get(root_material_id) - - def getRootMaterialIDForDiameter(self, root_material_id: str, approximate_diameter: str) -> str: - original_material = CuraContainerRegistry.getInstance().findInstanceContainersMetadata(id=root_material_id)[0] - if original_material["approximate_diameter"] == approximate_diameter: - return root_material_id - - matching_materials = CuraContainerRegistry.getInstance().findInstanceContainersMetadata(type = "material", brand = original_material["brand"], definition = original_material["definition"], material = original_material["material"], color_name = original_material["color_name"]) - for material in matching_materials: - if material["approximate_diameter"] == approximate_diameter: - return material["id"] - return root_material_id - - def getRootMaterialIDWithoutDiameter(self, root_material_id: str) -> str: - return self._diameter_material_map.get(root_material_id, "") - - def getMaterialGroupListByGUID(self, guid: str) -> Optional[List[MaterialGroup]]: - return self._guid_material_groups_map.get(guid) - - # Returns a dict of all material groups organized by root_material_id. - def getAllMaterialGroups(self) -> Dict[str, "MaterialGroup"]: - return self._material_group_map - - ## Gives a dictionary of all root material IDs and their associated - # MaterialNodes from the ContainerTree that are available for the given - # printer and variant. - def getAvailableMaterials(self, definition_id: str, nozzle_name: Optional[str]) -> Dict[str, MaterialNode]: - return ContainerTree.getInstance().machines[definition_id].variants[nozzle_name].materials - - # - # A convenience function to get available materials for the given machine with the extruder position. - # - def getAvailableMaterialsForMachineExtruder(self, machine: "GlobalStack", - extruder_stack: "ExtruderStack") -> Dict[str, MaterialNode]: - nozzle_name = None - if extruder_stack.variant.getId() != "empty_variant": - nozzle_name = extruder_stack.variant.getName() - - # Fetch the available materials (ContainerNode) for the current active machine and extruder setup. - materials = self.getAvailableMaterials(machine.definition.getId(), nozzle_name) - compatible_material_diameter = extruder_stack.getApproximateMaterialDiameter() - result = {key: material for key, material in materials.items() if material.container and float(material.container.getMetaDataEntry("approximate_diameter")) == compatible_material_diameter} - return result - - # - # Gets MaterialNode for the given extruder and machine with the given material name. - # Returns None if: - # 1. the given machine doesn't have materials; - # 2. cannot find any material InstanceContainers with the given settings. - # - def getMaterialNode(self, machine_definition_id: str, nozzle_name: Optional[str], - buildplate_name: Optional[str], diameter: float, root_material_id: str) -> Optional["MaterialNode"]: - container_tree = ContainerTree.getInstance() - machine_node = container_tree.machines.get(machine_definition_id) - if machine_node is None: - Logger.log("w", "Could not find machine with definition %s in the container tree", machine_definition_id) - return None - - variant_node = machine_node.variants.get(nozzle_name) - if variant_node is None: - Logger.log("w", "Could not find variant %s for machine with definition %s in the container tree", nozzle_name, machine_definition_id ) - return None - - material_node = variant_node.materials.get(root_material_id) - - if material_node is None: - Logger.log("w", "Could not find material %s for machine with definition %s and variant %s in the container tree", root_material_id, machine_definition_id, nozzle_name) - return None - - return material_node - - # - # Gets MaterialNode for the given extruder and machine with the given material type. - # Returns None if: - # 1. the given machine doesn't have materials; - # 2. cannot find any material InstanceContainers with the given settings. - # - def getMaterialNodeByType(self, global_stack: "GlobalStack", position: str, nozzle_name: str, - buildplate_name: Optional[str], material_guid: str) -> Optional["MaterialNode"]: - machine_definition = global_stack.definition - extruder = global_stack.extruderList[int(position)] - variant_name = extruder.variant.getName() - approximate_diameter = extruder.getApproximateMaterialDiameter() - - return self.getMaterialNode(machine_definition.getId(), variant_name, buildplate_name, approximate_diameter, material_guid) - - # There are 2 ways to get fallback materials; - # - A fallback by type (@sa getFallbackMaterialIdByMaterialType), which adds the generic version of this material - # - A fallback by GUID; If a material has been duplicated, it should also check if the original materials do have - # a GUID. This should only be done if the material itself does not have a quality just yet. - def getFallBackMaterialIdsByMaterial(self, material: "InstanceContainer") -> List[str]: - results = [] # type: List[str] - - material_groups = self.getMaterialGroupListByGUID(material.getMetaDataEntry("GUID")) - for material_group in material_groups: # type: ignore - if material_group.name != material.getId(): - # If the material in the group is read only, put it at the front of the list (since that is the most - # likely one to get a result) - if material_group.is_read_only: - results.insert(0, material_group.name) - else: - results.append(material_group.name) - - fallback = self.getFallbackMaterialIdByMaterialType(material.getMetaDataEntry("material")) - if fallback is not None: - results.append(fallback) - return results - - # - # Built-in quality profiles may be based on generic material IDs such as "generic_pla". - # For materials such as ultimaker_pla_orange, no quality profiles may be found, so we should fall back to use - # the generic material IDs to search for qualities. - # - # An example would be, suppose we have machine with preferred material set to "filo3d_pla" (1.75mm), but its - # extruders only use 2.85mm materials, then we won't be able to find the preferred material for this machine. - # A fallback would be to fetch a generic material of the same type "PLA" as "filo3d_pla", and in this case it will - # be "generic_pla". This function is intended to get a generic fallback material for the given material type. - # - # This function returns the generic root material ID for the given material type, where material types are "PLA", - # "ABS", etc. - # - def getFallbackMaterialIdByMaterialType(self, material_type: str) -> Optional[str]: - # For safety - if material_type not in self._fallback_materials_map: - Logger.log("w", "The material type [%s] does not have a fallback material" % material_type) - return None - fallback_material = self._fallback_materials_map[material_type] - if fallback_material: - return self.getRootMaterialIDWithoutDiameter(fallback_material["id"]) - else: - return None - - ## Get default material for given global stack, extruder position and extruder nozzle name - # you can provide the extruder_definition and then the position is ignored (useful when building up global stack in CuraStackBuilder) - def getDefaultMaterial(self, global_stack: "GlobalStack", position: str, nozzle_name: Optional[str], - extruder_definition: Optional["DefinitionContainer"] = None) -> "MaterialNode": - definition_id = global_stack.definition.getId() - machine_node = ContainerTree.getInstance().machines[definition_id] - if nozzle_name in machine_node.variants: - nozzle_node = machine_node.variants[nozzle_name] - else: - Logger.log("w", "Could not find variant {nozzle_name} for machine with definition {definition_id} in the container tree".format(nozzle_name = nozzle_name, definition_id = definition_id)) - nozzle_node = next(iter(machine_node.variants)) - - if not parseBool(global_stack.getMetaDataEntry("has_materials", False)): - return next(iter(nozzle_node.materials)) - - if extruder_definition is not None: - material_diameter = extruder_definition.getProperty("material_diameter", "value") - else: - material_diameter = global_stack.extruders[position].getCompatibleMaterialDiameter() - approximate_material_diameter = round(material_diameter) - - return nozzle_node.preferredMaterial(approximate_material_diameter) - - def removeMaterialByRootId(self, root_material_id: str): - container_registry = CuraContainerRegistry.getInstance() - results = container_registry.findContainers(id = root_material_id) - if not results: - container_registry.addWrongContainerId(root_material_id) - - for result in results: - container_registry.removeContainer(result.getMetaDataEntry("id", "")) - - @pyqtSlot("QVariant", result = bool) - def canMaterialBeRemoved(self, material_node: "MaterialNode"): - # Check if the material is active in any extruder train. In that case, the material shouldn't be removed! - # In the future we might enable this again, but right now, it's causing a ton of issues if we do (since it - # corrupts the configuration) - root_material_id = material_node.base_file - ids_to_remove = {metadata.get("id", "") for metadata in CuraContainerRegistry.getInstance().findInstanceContainersMetadata(base_file = root_material_id)} - - for extruder_stack in CuraContainerRegistry.getInstance().findContainerStacks(type = "extruder_train"): - if extruder_stack.material.getId() in ids_to_remove: - return False - return True - - ## Change the user-visible name of a material. - # \param material_node The ContainerTree node of the material to rename. - # \param name The new name for the material. - @pyqtSlot("QVariant", str) - def setMaterialName(self, material_node: "MaterialNode", name: str) -> None: - return cura.CuraApplication.CuraApplication.getMaterialManagementModel().setMaterialName(material_node, name) - - ## Deletes a material from Cura. - # - # This function does not do any safety checking any more. Please call this - # function only if: - # - The material is not read-only. - # - The material is not used in any stacks. - # If the material was not lazy-loaded yet, this will fully load the - # container. When removing this material node, all other materials with - # the same base fill will also be removed. - # \param material_node The material to remove. - @pyqtSlot("QVariant") - def removeMaterial(self, material_node: "MaterialNode") -> None: - return cura.CuraApplication.CuraApplication.getMaterialManagementModel().setMaterialName(material_node) - - def duplicateMaterialByRootId(self, root_material_id: str, new_base_id: Optional[str] = None, new_metadata: Optional[Dict[str, Any]] = None) -> Optional[str]: - result = cura.CuraApplication.CuraApplication.getInstance().getMaterialManagementModel().duplicateMaterialByBaseFile(root_material_id, new_base_id, new_metadata) - if result is None: - return "ERROR" - return result - - ## Creates a duplicate of a material with the same GUID and base_file - # metadata. - # \param material_node The node representing the material to duplicate. - # \param new_base_id A new material ID for the base material. The IDs of - # the submaterials will be based off this one. If not provided, a material - # ID will be generated automatically. - # \param new_metadata Metadata for the new material. If not provided, this - # will be duplicated from the original material. - # \return The root material ID of the duplicate material. - @pyqtSlot("QVariant", result = str) - def duplicateMaterial(self, material_node: MaterialNode, new_base_id: Optional[str] = None, new_metadata: Optional[Dict[str, Any]] = None) -> str: - result = cura.CuraApplication.CuraApplication.getInstance().getMaterialManagementModel().duplicateMaterial(material_node, new_base_id, new_metadata) - if result is None: - return "ERROR" - return result - - ## Create a new material by cloning the preferred material for the current - # material diameter and generate a new GUID. - # - # The material type is explicitly left to be the one from the preferred - # material, since this allows the user to still have SOME profiles to work - # with. - # \return The ID of the newly created material. - @pyqtSlot(result = str) - def createMaterial(self) -> str: - return cura.CuraApplication.CuraApplication.getMaterialManagementModel().createMaterial() - - @pyqtSlot(str) - def addFavorite(self, root_material_id: str) -> None: - self._favorites.add(root_material_id) - self.materialsUpdated.emit() - - # Ensure all settings are saved. - cura.CuraApplication.CuraApplication.getInstance().getPreferences().setValue("cura/favorite_materials", ";".join(list(self._favorites))) - cura.CuraApplication.CuraApplication.getInstance().saveSettings() - - @pyqtSlot(str) - def removeFavorite(self, root_material_id: str) -> None: - try: - self._favorites.remove(root_material_id) - except KeyError: - Logger.log("w", "Could not delete material %s from favorites as it was already deleted", root_material_id) - return - self.materialsUpdated.emit() - - # Ensure all settings are saved. - cura.CuraApplication.CuraApplication.getInstance().getPreferences().setValue("cura/favorite_materials", ";".join(list(self._favorites))) - cura.CuraApplication.CuraApplication.getInstance().saveSettings() - - @pyqtSlot() - def getFavorites(self): - return self._favorites diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py deleted file mode 100644 index 4aa88d6775..0000000000 --- a/cura/Machines/QualityManager.py +++ /dev/null @@ -1,215 +0,0 @@ -# Copyright (c) 2019 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -from typing import Any, Dict, List, Optional, TYPE_CHECKING - -from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot - -from UM.Util import parseBool -from UM.Settings.InstanceContainer import InstanceContainer -from UM.Decorators import deprecated - -import cura.CuraApplication -from cura.Settings.ExtruderStack import ExtruderStack - -from cura.Machines.ContainerTree import ContainerTree # The implementation that replaces this manager, to keep the deprecated interface working. -from .QualityChangesGroup import QualityChangesGroup -from .QualityGroup import QualityGroup -from .QualityNode import QualityNode - -if TYPE_CHECKING: - from UM.Settings.Interfaces import DefinitionContainerInterface - from cura.Settings.GlobalStack import GlobalStack - from .QualityChangesGroup import QualityChangesGroup - - -# -# Similar to MaterialManager, QualityManager maintains a number of maps and trees for quality profile lookup. -# The models GUI and QML use are now only dependent on the QualityManager. That means as long as the data in -# QualityManager gets updated correctly, the GUI models should be updated correctly too, and the same goes for GUI. -# -# For now, updating the lookup maps and trees here is very simple: we discard the old data completely and recreate them -# again. This means the update is exactly the same as initialization. There are performance concerns about this approach -# but so far the creation of the tables and maps is very fast and there is no noticeable slowness, we keep it like this -# because it's simple. -# -class QualityManager(QObject): - __instance = None - - @classmethod - @deprecated("Use the ContainerTree structure instead.", since = "4.3") - def getInstance(cls) -> "QualityManager": - if cls.__instance is None: - cls.__instance = QualityManager() - return cls.__instance - - qualitiesUpdated = pyqtSignal() - - def __init__(self, parent = None) -> None: - super().__init__(parent) - application = cura.CuraApplication.CuraApplication.getInstance() - self._container_registry = application.getContainerRegistry() - - self._empty_quality_container = application.empty_quality_container - self._empty_quality_changes_container = application.empty_quality_changes_container - - # For quality lookup - self._machine_nozzle_buildplate_material_quality_type_to_quality_dict = {} # type: Dict[str, QualityNode] - - # For quality_changes lookup - self._machine_quality_type_to_quality_changes_dict = {} # type: Dict[str, QualityNode] - - self._default_machine_definition_id = "fdmprinter" - - self._container_registry.containerMetaDataChanged.connect(self._onContainerMetadataChanged) - self._container_registry.containerAdded.connect(self._onContainerMetadataChanged) - self._container_registry.containerRemoved.connect(self._onContainerMetadataChanged) - - def _onContainerMetadataChanged(self, container: InstanceContainer) -> None: - self._onContainerChanged(container) - - def _onContainerChanged(self, container: InstanceContainer) -> None: - container_type = container.getMetaDataEntry("type") - if container_type not in ("quality", "quality_changes"): - return - - # Returns a dict of "custom profile name" -> QualityChangesGroup - def getQualityChangesGroups(self, machine: "GlobalStack") -> List[QualityChangesGroup]: - variant_names = [extruder.variant.getName() for extruder in machine.extruderList] - material_bases = [extruder.material.getMetaDataEntry("base_file") for extruder in machine.extruderList] - extruder_enabled = [extruder.isEnabled for extruder in machine.extruderList] - machine_node = ContainerTree.getInstance().machines[machine.definition.getId()] - return machine_node.getQualityChangesGroups(variant_names, material_bases, extruder_enabled) - - ## Gets the quality groups for the current printer. - # - # Both available and unavailable quality groups will be included. Whether - # a quality group is available can be known via the field - # ``QualityGroup.is_available``. For more details, see QualityGroup. - # \return A dictionary with quality types as keys and the quality groups - # for those types as values. - def getQualityGroups(self, global_stack: "GlobalStack") -> Dict[str, QualityGroup]: - # Gather up the variant names and material base files for each extruder. - variant_names = [extruder.variant.getName() for extruder in global_stack.extruderList] - material_bases = [extruder.material.getMetaDataEntry("base_file") for extruder in global_stack.extruderList] - extruder_enabled = [extruder.isEnabled for extruder in global_stack.extruderList] - definition_id = global_stack.definition.getId() - return ContainerTree.getInstance().machines[definition_id].getQualityGroups(variant_names, material_bases, extruder_enabled) - - def getQualityGroupsForMachineDefinition(self, machine: "GlobalStack") -> Dict[str, QualityGroup]: - machine_definition_id = getMachineDefinitionIDForQualitySearch(machine.definition) - - # To find the quality container for the GlobalStack, check in the following fall-back manner: - # (1) the machine-specific node - # (2) the generic node - machine_node = self._machine_nozzle_buildplate_material_quality_type_to_quality_dict.get(machine_definition_id) - default_machine_node = self._machine_nozzle_buildplate_material_quality_type_to_quality_dict.get( - self._default_machine_definition_id) - nodes_to_check = [machine_node, default_machine_node] - - # Iterate over all quality_types in the machine node - quality_group_dict = dict() - for node in nodes_to_check: - if node and node.quality_type: - quality_group = QualityGroup(node.getMetaDataEntry("name", ""), node.quality_type) - quality_group.setGlobalNode(node) - quality_group_dict[node.quality_type] = quality_group - - return quality_group_dict - - ## Get the quality group for the preferred quality type for a certain - # global stack. - # - # If the preferred quality type is not available, ``None`` will be - # returned. - # \param machine The global stack of the machine to get the preferred - # quality group for. - # \return The preferred quality group, or ``None`` if that is not - # available. - def getDefaultQualityType(self, machine: "GlobalStack") -> Optional[QualityGroup]: - machine_node = ContainerTree.getInstance().machines[machine.definition.getId()] - quality_groups = self.getQualityGroups(machine) - result = quality_groups.get(machine_node.preferred_quality_type) - if result is not None and result.is_available: - return result - return None # If preferred quality type is not available, leave it up for the caller. - - - # - # Methods for GUI - # - - ## Deletes a custom profile. It will be gone forever. - # \param quality_changes_group The quality changes group representing the - # profile to delete. - @pyqtSlot(QObject) - def removeQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup") -> None: - return cura.CuraApplication.CuraApplication.getInstance().getQualityManagementModel().removeQualityChangesGroup(quality_changes_group) - - ## Rename a custom profile. - # - # Because the names must be unique, the new name may not actually become - # the name that was given. The actual name is returned by this function. - # \param quality_changes_group The custom profile that must be renamed. - # \param new_name The desired name for the profile. - # \return The actual new name of the profile, after making the name - # unique. - @pyqtSlot(QObject, str, result = str) - def renameQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup", new_name: str) -> str: - return cura.CuraApplication.CuraApplication.getInstance().getQualityManagementModel().renameQualityChangesGroup(quality_changes_group, new_name) - - ## Duplicates a given quality profile OR quality changes profile. - # \param new_name The desired name of the new profile. This will be made - # unique, so it might end up with a different name. - # \param quality_model_item The item of this model to duplicate, as - # dictionary. See the descriptions of the roles of this list model. - @pyqtSlot(str, "QVariantMap") - def duplicateQualityChanges(self, quality_changes_name: str, quality_model_item: Dict[str, Any]) -> None: - return cura.CuraApplication.CuraApplication.getInstance().getQualityManagementModel().duplicateQualityChanges(quality_changes_name, quality_model_item) - - ## Create quality changes containers from the user containers in the active - # stacks. - # - # This will go through the global and extruder stacks and create - # quality_changes containers from the user containers in each stack. These - # then replace the quality_changes containers in the stack and clear the - # user settings. - # \param base_name The new name for the quality changes profile. The final - # name of the profile might be different from this, because it needs to be - # made unique. - @pyqtSlot(str) - def createQualityChanges(self, base_name: str) -> None: - return cura.CuraApplication.CuraApplication.getInstance().getQualityManagementModel().createQualityChanges(base_name) - - ## Create a quality changes container with the given set-up. - # \param quality_type The quality type of the new container. - # \param new_name The name of the container. This name must be unique. - # \param machine The global stack to create the profile for. - # \param extruder_stack The extruder stack to create the profile for. If - # not provided, only a global container will be created. - def _createQualityChanges(self, quality_type: str, new_name: str, machine: "GlobalStack", extruder_stack: Optional["ExtruderStack"]) -> "InstanceContainer": - return cura.CuraApplication.CuraApplication.getInstance().getQualityManagementModel()._createQualityChanges(quality_type, new_name, machine, extruder_stack) - -# -# Gets the machine definition ID that can be used to search for Quality containers that are suitable for the given -# machine. The rule is as follows: -# 1. By default, the machine definition ID for quality container search will be "fdmprinter", which is the generic -# machine. -# 2. If a machine has its own machine quality (with "has_machine_quality = True"), we should use the given machine's -# own machine definition ID for quality search. -# Example: for an Ultimaker 3, the definition ID should be "ultimaker3". -# 3. When condition (2) is met, AND the machine has "quality_definition" defined in its definition file, then the -# definition ID specified in "quality_definition" should be used. -# Example: for an Ultimaker 3 Extended, it has "quality_definition = ultimaker3". This means Ultimaker 3 Extended -# shares the same set of qualities profiles as Ultimaker 3. -# -def getMachineDefinitionIDForQualitySearch(machine_definition: "DefinitionContainerInterface", - default_definition_id: str = "fdmprinter") -> str: - machine_definition_id = default_definition_id - if parseBool(machine_definition.getMetaDataEntry("has_machine_quality", False)): - # Only use the machine's own quality definition ID if this machine has machine quality. - machine_definition_id = machine_definition.getMetaDataEntry("quality_definition") - if machine_definition_id is None: - machine_definition_id = machine_definition.getId() - - return machine_definition_id diff --git a/cura/Machines/VariantManager.py b/cura/Machines/VariantManager.py deleted file mode 100644 index 617f85b8ca..0000000000 --- a/cura/Machines/VariantManager.py +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright (c) 2019 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -from collections import OrderedDict -from typing import Optional, TYPE_CHECKING, Dict - -from UM.ConfigurationErrorMessage import ConfigurationErrorMessage -from UM.Decorators import deprecated -from UM.Logger import Logger -from UM.Util import parseBool - -from cura.Machines.ContainerNode import ContainerNode -from cura.Machines.VariantType import VariantType, ALL_VARIANT_TYPES -from cura.Settings.CuraContainerRegistry import CuraContainerRegistry -from cura.Settings.GlobalStack import GlobalStack - -if TYPE_CHECKING: - from UM.Settings.DefinitionContainer import DefinitionContainer - - -# -# VariantManager is THE place to look for a specific variant. It maintains two variant lookup tables with the following -# structure: -# -# [machine_definition_id] -> [variant_type] -> [variant_name] -> ContainerNode(metadata / container) -# Example: "ultimaker3" -> "buildplate" -> "Glass" (if present) -> ContainerNode -# -> ... -# -> "nozzle" -> "AA 0.4" -# -> "BB 0.8" -# -> ... -# -# [machine_definition_id] -> [machine_buildplate_type] -> ContainerNode(metadata / container) -# Example: "ultimaker3" -> "glass" (this is different from the variant name) -> ContainerNode -# -# Note that the "container" field is not loaded in the beginning because it would defeat the purpose of lazy-loading. -# A container is loaded when getVariant() is called to load a variant InstanceContainer. -# -class VariantManager: - __instance = None - - @classmethod - @deprecated("Use the ContainerTree structure instead.", since = "4.3") - def getInstance(cls) -> "VariantManager": - if cls.__instance is None: - cls.__instance = VariantManager() - return cls.__instance - - def __init__(self) -> None: - self._machine_to_variant_dict_map = dict() # type: Dict[str, Dict["VariantType", Dict[str, ContainerNode]]] - - self._exclude_variant_id_list = ["empty_variant"] - - # - # Gets the variant InstanceContainer with the given information. - # Almost the same as getVariantMetadata() except that this returns an InstanceContainer if present. - # - def getVariantNode(self, machine_definition_id: str, variant_name: str, - variant_type: Optional["VariantType"] = None) -> Optional["ContainerNode"]: - if variant_type is None: - variant_node = None - variant_type_dict = self._machine_to_variant_dict_map.get("machine_definition_id", {}) - for variant_dict in variant_type_dict.values(): - if variant_name in variant_dict: - variant_node = variant_dict[variant_name] - break - return variant_node - - return self._machine_to_variant_dict_map.get(machine_definition_id, {}).get(variant_type, {}).get(variant_name) - - def getVariantNodes(self, machine: "GlobalStack", variant_type: "VariantType") -> Dict[str, ContainerNode]: - machine_definition_id = machine.definition.getId() - return self._machine_to_variant_dict_map.get(machine_definition_id, {}).get(variant_type, {}) - - # - # Gets the default variant for the given machine definition. - # If the optional GlobalStack is given, the metadata information will be fetched from the GlobalStack instead of - # the DefinitionContainer. Because for machines such as UM2, you can enable Olsson Block, which will set - # "has_variants" to True in the GlobalStack. In those cases, we need to fetch metadata from the GlobalStack or - # it may not be correct. - # - def getDefaultVariantNode(self, machine_definition: "DefinitionContainer", - variant_type: "VariantType", - global_stack: Optional["GlobalStack"] = None) -> Optional["ContainerNode"]: - machine_definition_id = machine_definition.getId() - container_for_metadata_fetching = global_stack if global_stack is not None else machine_definition - - preferred_variant_name = None - if variant_type == VariantType.BUILD_PLATE: - if parseBool(container_for_metadata_fetching.getMetaDataEntry("has_variant_buildplates", False)): - preferred_variant_name = container_for_metadata_fetching.getMetaDataEntry("preferred_variant_buildplate_name") - else: - if parseBool(container_for_metadata_fetching.getMetaDataEntry("has_variants", False)): - preferred_variant_name = container_for_metadata_fetching.getMetaDataEntry("preferred_variant_name") - - node = None - if preferred_variant_name: - node = self.getVariantNode(machine_definition_id, preferred_variant_name, variant_type) - return node diff --git a/tests/TestMaterialManager.py b/tests/TestMaterialManager.py deleted file mode 100644 index d87ab3a63e..0000000000 --- a/tests/TestMaterialManager.py +++ /dev/null @@ -1,187 +0,0 @@ -from unittest.mock import MagicMock, patch -import pytest -from cura.Machines.MaterialManager import MaterialManager - - -mocked_registry = MagicMock() -material_1 = {"id": "test", "GUID":"TEST!", "base_file": "base_material", "definition": "fdmmachine", "approximate_diameter": "3", "brand": "generic", "material": "pla"} -material_2 = {"id": "base_material", "GUID": "TEST2!", "base_file": "test", "definition": "fdmmachine", "approximate_diameter": "3", "material": "pla"} -mocked_registry.findContainersMetadata = MagicMock(return_value = [material_1, material_2]) - - -mocked_definition = MagicMock() -mocked_definition.getId = MagicMock(return_value = "fdmmachine") -mocked_definition.getMetaDataEntry = MagicMock(return_value = []) - -# These tests are outdated -pytestmark = pytest.mark.skip - -def test_initialize(application): - # Just test if the simple loading works - with patch("UM.Application.Application.getInstance", MagicMock(return_value=application)): - manager = MaterialManager(mocked_registry) - manager.initialize() - # Double check that we actually got some material nodes - assert manager.getMaterialGroup("base_material").name == "base_material" - assert manager.getMaterialGroup("test").name == "test" - - -def test_getMaterialGroupListByGUID(application): - with patch("UM.Application.Application.getInstance", MagicMock(return_value=application)): - manager = MaterialManager(mocked_registry) - manager.initialize() - - assert manager.getMaterialGroupListByGUID("TEST!")[0].name == "test" - assert manager.getMaterialGroupListByGUID("TEST2!")[0].name == "base_material" - - -def test_getRootMaterialIDforDiameter(application): - with patch("UM.Application.Application.getInstance", MagicMock(return_value=application)): - manager = MaterialManager(mocked_registry) - manager.initialize() - - assert manager.getRootMaterialIDForDiameter("base_material", "3") == "base_material" - - -def test_getMaterialNodeByTypeMachineHasNoMaterials(application): - with patch("UM.Application.Application.getInstance", MagicMock(return_value=application)): - manager = MaterialManager(mocked_registry) - manager.initialize() - - mocked_stack = MagicMock() - assert manager.getMaterialNodeByType(mocked_stack, "0", "nozzle", "", "") is None - - -def test_getMaterialNodeByTypeMachineHasMaterialsButNoMaterialFound(application): - with patch("UM.Application.Application.getInstance", MagicMock(return_value=application)): - manager = MaterialManager(mocked_registry) - manager.initialize() - - mocked_stack = MagicMock() - mocked_stack.definition.getMetaDataEntry = MagicMock(return_value = True) # For the "has_materials" metadata - - assert manager.getMaterialNodeByType(mocked_stack, "0", "nozzle", "", "") is None - - -def test_getMaterialNodeByTypeMachineHasMaterialsAndMaterialExists(application): - with patch("UM.Application.Application.getInstance", MagicMock(return_value=application)): - manager = MaterialManager(mocked_registry) - manager.initialize() - mocked_result = MagicMock() - manager.getMaterialNode = MagicMock(return_value = mocked_result) - mocked_stack = MagicMock() - mocked_stack.definition.getMetaDataEntry = MagicMock(return_value = True) # For the "has_materials" metadata - - assert manager.getMaterialNodeByType(mocked_stack, "0", "nozzle", "", "TEST!") is mocked_result - - -def test_getAllMaterialGroups(application): - with patch("UM.Application.Application.getInstance", MagicMock(return_value=application)): - manager = MaterialManager(mocked_registry) - manager.initialize() - - material_groups = manager.getAllMaterialGroups() - - assert "base_material" in material_groups - assert "test" in material_groups - assert material_groups["base_material"].name == "base_material" - assert material_groups["test"].name == "test" - - -class TestAvailableMaterials: - def test_happy(self, application): - with patch("UM.Application.Application.getInstance", MagicMock(return_value=application)): - manager = MaterialManager(mocked_registry) - manager.initialize() - - available_materials = manager.getAvailableMaterials(mocked_definition, None, None, 3) - - assert "base_material" in available_materials - assert "test" in available_materials - - def test_wrongDiameter(self, application): - with patch("UM.Application.Application.getInstance", MagicMock(return_value=application)): - manager = MaterialManager(mocked_registry) - manager.initialize() - - available_materials = manager.getAvailableMaterials(mocked_definition, None, None, 200) - assert available_materials == {} # Nothing found. - - def test_excludedMaterials(self, application): - with patch("UM.Application.Application.getInstance", MagicMock(return_value=application)): - manager = MaterialManager(mocked_registry) - manager.initialize() - with patch.object(mocked_definition, "getMetaDataEntry", MagicMock(return_value = ["test"])): - available_materials = manager.getAvailableMaterials(mocked_definition, None, None, 3) - assert "base_material" in available_materials - assert "test" not in available_materials - - -class Test_getFallbackMaterialIdByMaterialType: - def test_happyFlow(self, application): - with patch("UM.Application.Application.getInstance", MagicMock(return_value=application)): - manager = MaterialManager(mocked_registry) - manager.initialize() - - assert manager.getFallbackMaterialIdByMaterialType("pla") == "test" - - def test_unknownMaterial(self, application): - with patch("UM.Application.Application.getInstance", MagicMock(return_value=application)): - manager = MaterialManager(mocked_registry) - manager.initialize() - assert manager.getFallbackMaterialIdByMaterialType("OMGZOMG") is None - - -def test_getMaterialNode(application): - with patch("UM.Application.Application.getInstance", MagicMock(return_value=application)): - manager = MaterialManager(mocked_registry) - manager._updateMaps() - - assert manager.getMaterialNode("fdmmachine", None, None, 3, "base_material").container_id == "test" - - -def test_getAvailableMaterialsForMachineExtruder(application): - with patch("UM.Application.Application.getInstance", MagicMock(return_value=application)): - manager = MaterialManager(mocked_registry) - manager.initialize() - - mocked_machine = MagicMock() - mocked_machine.getBuildplateName = MagicMock(return_value = "build_plate") - mocked_machine.definition = mocked_definition - mocked_extruder_stack = MagicMock() - mocked_extruder_stack.variant.getId = MagicMock(return_value = "test") - mocked_extruder_stack.getApproximateMaterialDiameter = MagicMock(return_value = 2.85) - - available_materials = manager.getAvailableMaterialsForMachineExtruder(mocked_machine, mocked_extruder_stack) - assert "base_material" in available_materials - assert "test" in available_materials - - -class TestFavorites: - def test_addFavorite(self, application): - with patch("UM.Application.Application.getInstance", MagicMock(return_value=application)): - manager = MaterialManager(mocked_registry) - manager.materialsUpdated = MagicMock() - manager.addFavorite("blarg") - assert manager.getFavorites() == {"blarg"} - - application.getPreferences().setValue.assert_called_once_with("cura/favorite_materials", "blarg") - manager.materialsUpdated.emit.assert_called_once_with() - - def test_removeNotExistingFavorite(self, application): - with patch("UM.Application.Application.getInstance", MagicMock(return_value=application)): - manager = MaterialManager(mocked_registry) - manager.materialsUpdated = MagicMock() - manager.removeFavorite("blarg") - manager.materialsUpdated.emit.assert_not_called() - - def test_removeExistingFavorite(self, application): - with patch("UM.Application.Application.getInstance", MagicMock(return_value=application)): - manager = MaterialManager(mocked_registry) - manager.materialsUpdated = MagicMock() - manager.addFavorite("blarg") - - manager.removeFavorite("blarg") - assert manager.materialsUpdated.emit.call_count == 2 - application.getPreferences().setValue.assert_called_with("cura/favorite_materials", "") - assert manager.getFavorites() == set() \ No newline at end of file diff --git a/tests/TestQualityManager.py b/tests/TestQualityManager.py deleted file mode 100644 index fb96f4476b..0000000000 --- a/tests/TestQualityManager.py +++ /dev/null @@ -1,129 +0,0 @@ -from unittest.mock import MagicMock, patch - -import pytest - -from cura.Machines.QualityChangesGroup import QualityChangesGroup -from cura.Machines.QualityManager import QualityManager - -mocked_stack = MagicMock() -mocked_extruder = MagicMock() - -mocked_material = MagicMock() -mocked_material.getMetaDataEntry = MagicMock(return_value = "base_material") - -mocked_extruder.material = mocked_material -mocked_stack.extruders = {"0": mocked_extruder} - -# These tests are outdated -pytestmark = pytest.mark.skip - -@pytest.fixture() -def material_manager(): - result = MagicMock() - result.getRootMaterialIDWithoutDiameter = MagicMock(return_value = "base_material") - return result - -@pytest.fixture() -def container_registry(): - result = MagicMock() - mocked_metadata = [{"id": "test", "definition": "fdmprinter", "quality_type": "normal", "name": "test_name", "global_quality": True, "type": "quality"}, - {"id": "test_material", "definition": "fdmprinter", "quality_type": "normal", "name": "test_name_material", "material": "base_material", "type": "quality"}, - {"id": "quality_changes_id", "definition": "fdmprinter", "type": "quality_changes", "quality_type": "amazing!", "name": "herp"}] - result.findContainersMetadata = MagicMock(return_value = mocked_metadata) - - result.uniqueName = MagicMock(return_value = "uniqueName") - return result - - -@pytest.fixture() -def quality_mocked_application(material_manager, container_registry): - result = MagicMock() - result.getMaterialManager = MagicMock(return_value=material_manager) - result.getContainerRegistry = MagicMock(return_value=container_registry) - return result - - -def test_getQualityGroups(quality_mocked_application): - manager = QualityManager(quality_mocked_application) - manager.initialize() - - assert "normal" in manager.getQualityGroups(mocked_stack) - - -def test_getQualityChangesGroup(quality_mocked_application): - manager = QualityManager(quality_mocked_application) - manager.initialize() - - assert "herp" in [qcg.name for qcg in manager.getQualityChangesGroups(mocked_stack)] - - -@pytest.mark.skip("Doesn't work on remote") -def test_getDefaultQualityType(quality_mocked_application): - manager = QualityManager(quality_mocked_application) - manager.initialize() - mocked_stack = MagicMock() - mocked_stack.definition.getMetaDataEntry = MagicMock(return_value = "normal") - assert manager.getDefaultQualityType(mocked_stack).quality_type == "normal" - - -def test_createQualityChanges(quality_mocked_application): - manager = QualityManager(quality_mocked_application) - mocked_quality_changes = MagicMock() - manager._createQualityChanges = MagicMock(return_value = mocked_quality_changes) - manager.initialize() - container_manager = MagicMock() - - manager._container_registry.addContainer = MagicMock() # Side effect we want to check. - with patch("cura.Settings.ContainerManager.ContainerManager.getInstance", container_manager): - manager.createQualityChanges("derp") - assert manager._container_registry.addContainer.called_once_with(mocked_quality_changes) - - -def test_renameQualityChangesGroup(quality_mocked_application): - manager = QualityManager(quality_mocked_application) - manager.initialize() - - mocked_container = MagicMock() - - quality_changes_group = QualityChangesGroup("zomg", "beep") - quality_changes_group.getAllNodes = MagicMock(return_value = [mocked_container]) - - # We need to check for "uniqueName" instead of "NEWRANDOMNAMEYAY" because the mocked registry always returns - # "uniqueName" when attempting to generate an unique name. - assert manager.renameQualityChangesGroup(quality_changes_group, "NEWRANDOMNAMEYAY") == "uniqueName" - assert mocked_container.setName.called_once_with("uniqueName") - - -def test_duplicateQualityChangesQualityOnly(quality_mocked_application): - manager = QualityManager(quality_mocked_application) - manager.initialize() - mocked_quality = MagicMock() - quality_group = MagicMock() - quality_group.getAllNodes = MagicMock(return_value = mocked_quality) - mocked_quality_changes = MagicMock() - - # Isolate what we want to test (in this case, we're not interested if createQualityChanges does it's job!) - manager._createQualityChanges = MagicMock(return_value = mocked_quality_changes) - manager._container_registry.addContainer = MagicMock() # Side effect we want to check. - - manager.duplicateQualityChanges("zomg", {"quality_group": quality_group, "quality_changes_group": None}) - assert manager._container_registry.addContainer.called_once_with(mocked_quality_changes) - - -def test_duplicateQualityChanges(quality_mocked_application): - manager = QualityManager(quality_mocked_application) - manager.initialize() - mocked_quality = MagicMock() - quality_group = MagicMock() - quality_group.getAllNodes = MagicMock(return_value = mocked_quality) - quality_changes_group = MagicMock() - mocked_quality_changes = MagicMock() - quality_changes_group.getAllNodes = MagicMock(return_value = [mocked_quality_changes]) - mocked_quality_changes.duplicate = MagicMock(return_value = mocked_quality_changes) - - manager._container_registry.addContainer = MagicMock() # Side effect we want to check. - - manager.duplicateQualityChanges("zomg", {"intent_category": "default", - "quality_group": quality_group, - "quality_changes_group": quality_changes_group}) - assert manager._container_registry.addContainer.called_once_with(mocked_quality_changes) From 8322a36548c52308db86efc4a2a44b78b8e63272 Mon Sep 17 00:00:00 2001 From: Nino van Hooff Date: Wed, 16 Oct 2019 16:59:52 +0200 Subject: [PATCH 16/50] Fix some QML warnings in the MaterialsPage --- .../Materials/MaterialsBrandSection.qml | 13 ++++------ .../Preferences/Materials/MaterialsSlot.qml | 2 ++ .../Materials/MaterialsTypeSection.qml | 24 +++++++------------ 3 files changed, 15 insertions(+), 24 deletions(-) diff --git a/resources/qml/Preferences/Materials/MaterialsBrandSection.qml b/resources/qml/Preferences/Materials/MaterialsBrandSection.qml index 487c87f07c..5dd68c426f 100644 --- a/resources/qml/Preferences/Materials/MaterialsBrandSection.qml +++ b/resources/qml/Preferences/Materials/MaterialsBrandSection.qml @@ -10,6 +10,8 @@ import QtQuick.Dialogs 1.2 import UM 1.2 as UM import Cura 1.0 as Cura +// An expandable list of materials. Includes both the header (this file) and the items (brandMaterialList) + Item { id: brand_section @@ -50,9 +52,8 @@ Item verticalAlignment: Text.AlignVCenter leftPadding: (UM.Theme.getSize("default_margin").width / 2) | 0 } - Button + Item { - text: "" implicitWidth: UM.Theme.getSize("favorites_button").width implicitHeight: UM.Theme.getSize("favorites_button").height UM.RecolorImage @@ -67,10 +68,6 @@ Item color: "black" source: brand_section.expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") } - style: ButtonStyle - { - background: Item { } - } } } MouseArea @@ -99,7 +96,7 @@ Item id: brandMaterialList anchors.top: brand_header.bottom width: parent.width - anchors.left: parent.left + anchors.left: parent ? parent.left : undefined height: brand_section.expanded ? childrenRect.height : 0 visible: brand_section.expanded @@ -109,7 +106,7 @@ Item delegate: Loader { id: loader - width: parent.width + width: parent ? parent.width : 0 property var element: model sourceComponent: hasMaterialTypes ? materialsTypeSection : materialSlot } diff --git a/resources/qml/Preferences/Materials/MaterialsSlot.qml b/resources/qml/Preferences/Materials/MaterialsSlot.qml index c6691460cf..81bb8759ff 100644 --- a/resources/qml/Preferences/Materials/MaterialsSlot.qml +++ b/resources/qml/Preferences/Materials/MaterialsSlot.qml @@ -10,6 +10,8 @@ import QtQuick.Dialogs 1.2 import UM 1.2 as UM import Cura 1.0 as Cura +// A single material row, typically used in a MaterialsBrandSection + Rectangle { id: materialSlot diff --git a/resources/qml/Preferences/Materials/MaterialsTypeSection.qml b/resources/qml/Preferences/Materials/MaterialsTypeSection.qml index 3c36e12651..07630a83b4 100644 --- a/resources/qml/Preferences/Materials/MaterialsTypeSection.qml +++ b/resources/qml/Preferences/Materials/MaterialsTypeSection.qml @@ -20,8 +20,8 @@ Item property var expanded: materialList.expandedTypes.indexOf(materialBrand + "_" + materialName) > -1 property var colorsModel: materialType != null ? materialType.colors: null height: childrenRect.height - width: parent.width - anchors.left: parent.left + width: parent ? parent.width :undefined + anchors.left: parent ? parent.left : undefined Rectangle { id: material_type_header_background @@ -55,7 +55,7 @@ Item leftPadding: UM.Theme.getSize("default_margin").width anchors { - left: parent.left + left: parent ? parent.left : undefined } Label { @@ -65,33 +65,25 @@ Item id: material_type_name verticalAlignment: Text.AlignVCenter } - Button + Item // this one causes lots of warnings { - text: "" implicitWidth: UM.Theme.getSize("favorites_button").width implicitHeight: UM.Theme.getSize("favorites_button").height UM.RecolorImage { anchors { - verticalCenter: parent.verticalCenter - horizontalCenter: parent.horizontalCenter + verticalCenter: parent ? parent.verticalCenter : undefined + horizontalCenter: parent ? parent.horizontalCenter : undefined } width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height color: "black" source: material_type_section.expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") } - style: ButtonStyle - { - background: Rectangle - { - anchors.fill: parent - color: "transparent" - } - } + } } - MouseArea + MouseArea // causes lots of warnings { anchors.fill: material_type_header onPressed: From ad5fae5b6675af9093a1fe286d2a63a6eb68c3a9 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 17 Oct 2019 01:29:24 +0200 Subject: [PATCH 17/50] Only allow optimising infill travels when combing is enabled That's the only time when it will have any effect, since the only thing this does is to calculate the distance to the next infill line better if the nozzle has to make a detour due to combing. --- resources/definitions/fdmprinter.def.json | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 55061d793d..a1df3aed66 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -6217,6 +6217,7 @@ "label": "Infill Travel Optimization", "description": "When enabled, the order in which the infill lines are printed is optimized to reduce the distance travelled. The reduction in travel time achieved very much depends on the model being sliced, infill pattern, density, etc. Note that, for some models that have many small areas of infill, the time to slice the model may be greatly increased.", "type": "bool", + "enabled": "resolveOrValue('retraction_combing') != 'off'", "default_value": false, "settable_per_mesh": true }, From f3f9a2393f26ec02d0d25aa64d37c8706bd20eb0 Mon Sep 17 00:00:00 2001 From: Mark Burton Date: Wed, 16 Oct 2019 20:24:50 +0100 Subject: [PATCH 18/50] Return early from _checkStackForErrors() if top container is empty. --- plugins/CuraEngineBackend/StartSliceJob.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index b973a0775a..06ef2d97b1 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -106,6 +106,10 @@ class StartSliceJob(Job): if stack is None: return False + # if there are no per-object settings we don't need to check the other settings here + if stack.getTop() == None or len(stack.getTop().getAllKeys()) == 0: + return False + for key in stack.getAllKeys(): validation_state = stack.getProperty(key, "validationState") if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError, ValidatorState.Invalid): From 664ed4a6a67fce8a86fb0f1d049931a1d0193b56 Mon Sep 17 00:00:00 2001 From: Nino van Hooff Date: Thu, 17 Oct 2019 12:52:30 +0200 Subject: [PATCH 19/50] Take a more generic approach to safe areas for the SimulationView Re-implements layer slider positioning CURA-6853 --- plugins/PreviewStage/PreviewMain.qml | 16 +++++++++++++--- .../SimulationViewMainComponent.qml | 12 ++++++++---- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/plugins/PreviewStage/PreviewMain.qml b/plugins/PreviewStage/PreviewMain.qml index a065a751ac..1b8387644d 100644 --- a/plugins/PreviewStage/PreviewMain.qml +++ b/plugins/PreviewStage/PreviewMain.qml @@ -11,6 +11,17 @@ import Cura 1.0 as Cura Item { + + // Subtract the actionPanel from the safe area. This way the view won't draw interface elements under/over it + Item { + id: safeArea + visible: false + anchors.left: parent.left + anchors.right: actionPanelWidget.left + anchors.top: parent.top + anchors.bottom: actionPanelWidget.top + } + Loader { id: previewMain @@ -18,12 +29,11 @@ Item source: UM.Controller.activeView != null && UM.Controller.activeView.mainComponent != null ? UM.Controller.activeView.mainComponent : "" - // Indicate that the layer slider should stay above the action panel Binding { target: previewMain.item - property: "layerSliderSafeYMax" - value: actionPanelWidget.y + property: "safeArea" + value:safeArea } } diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index ddbb5b6224..65621605df 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -11,11 +11,14 @@ import Cura 1.0 as Cura Item { + // An Item whose bounds are guaranteed to be safe for overlays to be placed. + // Defaults to parent, ie. the entire available area + // eg. the layer slider will not be placed in this area. + property var safeArea: parent + + property bool isSimulationPlaying: false - // By default, the layer slider can extend to the entire height of the parent - // A parent may bind this property to indicate the bottom of a safe area - // for the Layer slider - property var layerSliderSafeYMax: parent.height + readonly property var layerSliderSafeYMax: safeArea.y + safeArea.height visible: UM.SimulationView.layerActivity && CuraApplication.platformActivity @@ -221,6 +224,7 @@ Item // Make sure the slider handlers show the correct value after switching views Component.onCompleted: { + print("safeArea: " + safeArea, "layerSliderSafeYMax", layerSliderSafeYMax) layerSlider.setLowerValue(UM.SimulationView.minimumLayer) layerSlider.setUpperValue(UM.SimulationView.currentLayer) } From 3709cfa4edcd038fe36f3ad58c05f5072727d840 Mon Sep 17 00:00:00 2001 From: Nino van Hooff Date: Thu, 17 Oct 2019 15:54:03 +0200 Subject: [PATCH 20/50] Add tooltips for intent profiles to the Recommended Quality panel. The description is optional. Tooltip will not show if no description is set CURA-6853 --- cura/Machines/Models/IntentCategoryModel.py | 39 ++++++++++++++----- cura/Settings/MachineManager.py | 5 ++- .../RecommendedQualityProfileSelector.qml | 19 +++++++++ 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/cura/Machines/Models/IntentCategoryModel.py b/cura/Machines/Models/IntentCategoryModel.py index d7d1ee2710..0268d067a9 100644 --- a/cura/Machines/Models/IntentCategoryModel.py +++ b/cura/Machines/Models/IntentCategoryModel.py @@ -3,7 +3,7 @@ from PyQt5.QtCore import Qt import collections -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Optional from cura.Machines.Models.IntentModel import IntentModel from cura.Settings.IntentManager import IntentManager @@ -25,16 +25,26 @@ class IntentCategoryModel(ListModel): IntentCategoryRole = Qt.UserRole + 2 WeightRole = Qt.UserRole + 3 QualitiesRole = Qt.UserRole + 4 - - #Translations to user-visible string. Ordered by weight. - #TODO: Create a solution for this name and weight to be used dynamically. - name_translation = collections.OrderedDict() #type: "collections.OrderedDict[str,str]" - name_translation["default"] = catalog.i18nc("@label", "Default") - name_translation["engineering"] = catalog.i18nc("@label", "Engineering") - name_translation["smooth"] = catalog.i18nc("@label", "Smooth") + DescriptionRole = Qt.UserRole + 5 modelUpdated = pyqtSignal() + # Translations to user-visible string. Ordered by weight. + # TODO: Create a solution for this name and weight to be used dynamically. + _translations = collections.OrderedDict() # type: "collections.OrderedDict[str,Dict[str,Optional[str]]" + _translations["default"] = { + "name": catalog.i18nc("@label", "Default") + } + _translations["engineering"] = { + "name": catalog.i18nc("@label", "Engineering"), + "description": catalog.i18nc("@text", "An profile which is suitable for engineering work") + + } + _translations["smooth"] = { + "name": catalog.i18nc("@label", "Smooth"), + "description": catalog.i18nc("@text", "Ohhh yeah. So tender. So smooth. So Perfect.") + } + ## Creates a new model for a certain intent category. # \param The category to list the intent profiles for. def __init__(self, intent_category: str) -> None: @@ -45,6 +55,7 @@ class IntentCategoryModel(ListModel): self.addRoleName(self.IntentCategoryRole, "intent_category") self.addRoleName(self.WeightRole, "weight") self.addRoleName(self.QualitiesRole, "qualities") + self.addRoleName(self.DescriptionRole, "description") application = cura.CuraApplication.CuraApplication.getInstance() @@ -75,10 +86,18 @@ class IntentCategoryModel(ListModel): qualities = IntentModel() qualities.setIntentCategory(category) result.append({ - "name": self.name_translation.get(category, catalog.i18nc("@label", "Unknown")), + "name": IntentCategoryModel.translation(category, "name", catalog.i18nc("@label", "Unknown")), + "description": IntentCategoryModel.translation(category, "description", None), "intent_category": category, - "weight": list(self.name_translation.keys()).index(category), + "weight": list(self._translations.keys()).index(category), "qualities": qualities }) result.sort(key = lambda k: k["weight"]) self.setItems(result) + + ## Get a display value for a category. See IntenCategoryModel._translations + ## for categories and keys + @staticmethod + def translation(category: str, key: str, default: Optional[str] = None): + display_strings = IntentCategoryModel._translations.get(category, {}) + return display_strings.get(key, default) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 35f3268cce..d1f8cad4b3 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1586,8 +1586,9 @@ class MachineManager(QObject): intent_category = self.activeIntentCategory if intent_category != "default": - intent_display_name = IntentCategoryModel.name_translation.get(intent_category, - catalog.i18nc("@label", "Unknown")) + intent_display_name = IntentCategoryModel.translation(intent_category, + "name", + catalog.i18nc("@label", "Unknown")) display_name = "{intent_name} - {the_rest}".format(intent_name = intent_display_name, the_rest = display_name) diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml index d1f7dd7de2..a75783d096 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml @@ -163,6 +163,25 @@ Item isCheckedFunction: checkedFunction } + + MouseArea // tooltip hover area + { + anchors.fill: parent + hoverEnabled: true + enabled: model.description !== undefined + acceptedButtons: Qt.NoButton // react to hover only, don't steal clicks + + onEntered: + { + print(model.description) + base.showTooltip( + intentCategoryLabel, + Qt.point(-(intentCategoryLabel.x - qualityRow.x) - UM.Theme.getSize("thick_margin").width, 0), + model.description + ) + } + onExited: base.hideTooltip() + } } } From b182830c2157ba3b539c6d92d561e3f9a04ea428 Mon Sep 17 00:00:00 2001 From: Nino van Hooff Date: Thu, 17 Oct 2019 17:17:06 +0200 Subject: [PATCH 21/50] Add tooltips for intent profiles to the Custom Quality panel. The description is optional. Tooltip will not show if no description is set CURA-6853 --- cura/Machines/Models/IntentCategoryModel.py | 2 +- .../Custom/QualitiesWithIntentMenu.qml | 21 ++++++++++++++++++- .../RecommendedQualityProfileSelector.qml | 1 - 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/cura/Machines/Models/IntentCategoryModel.py b/cura/Machines/Models/IntentCategoryModel.py index 0268d067a9..de909df534 100644 --- a/cura/Machines/Models/IntentCategoryModel.py +++ b/cura/Machines/Models/IntentCategoryModel.py @@ -37,7 +37,7 @@ class IntentCategoryModel(ListModel): } _translations["engineering"] = { "name": catalog.i18nc("@label", "Engineering"), - "description": catalog.i18nc("@text", "An profile which is suitable for engineering work") + "description": catalog.i18nc("@text", "A profile which is suitable for engineering work") } _translations["smooth"] = { diff --git a/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml b/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml index c9686a1519..c5a725285c 100644 --- a/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml +++ b/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml @@ -70,12 +70,31 @@ Popup { id: headerLabel text: model.name + color: UM.Theme.getColor("text_inactive") renderType: Text.NativeRendering + width: parent.width height: visible ? contentHeight: 0 - enabled: false visible: qualitiesList.visibleChildren.length > 0 anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width + + MouseArea // tooltip hover area + { + anchors.fill: parent + hoverEnabled: true + enabled: model.description !== undefined + acceptedButtons: Qt.NoButton // react to hover only, don't steal clicks + + onEntered: + { + base.showTooltip( + headerLabel, + Qt.point(- UM.Theme.getSize("default_margin").width, 0), + model.description + ) + } + onExited: base.hideTooltip() + } } Column diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml index a75783d096..05e7202f6d 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml @@ -173,7 +173,6 @@ Item onEntered: { - print(model.description) base.showTooltip( intentCategoryLabel, Qt.point(-(intentCategoryLabel.x - qualityRow.x) - UM.Theme.getSize("thick_margin").width, 0), From 82bd89991e7ee6f15da5ec1baa0d22111796842a Mon Sep 17 00:00:00 2001 From: Mark Burton Date: Thu, 17 Oct 2019 16:42:43 +0100 Subject: [PATCH 22/50] Improve code style. --- plugins/CuraEngineBackend/StartSliceJob.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 06ef2d97b1..94f6d3edfa 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -107,7 +107,7 @@ class StartSliceJob(Job): return False # if there are no per-object settings we don't need to check the other settings here - if stack.getTop() == None or len(stack.getTop().getAllKeys()) == 0: + if stack.getTop() is None or not stack.getTop().getAllKeys(): return False for key in stack.getAllKeys(): From 84c9b28bb26f401234e939bc2b873bf4e4358151 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 18 Oct 2019 00:07:43 +0200 Subject: [PATCH 23/50] Move maximum resolution itself out of experimental as well This was forgotten accidentally, it seems. --- resources/definitions/fdmprinter.def.json | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index a1df3aed66..65ecbc1c91 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -5833,6 +5833,18 @@ "settable_per_mesh": false, "settable_per_extruder": false }, + "meshfix_maximum_resolution": + { + "label": "Maximum Resolution", + "description": "The minimum size of a line segment after slicing. If you increase this, the mesh will have a lower resolution. This may allow the printer to keep up with the speed it has to process g-code and will increase slice speed by removing details of the mesh that it can't process anyway.", + "type": "float", + "unit": "mm", + "default_value": 0.5, + "minimum_value": "0.001", + "minimum_value_warning": "0.01", + "maximum_value_warning": "3", + "settable_per_mesh": true + }, "meshfix_maximum_travel_resolution": { "label": "Maximum Travel Resolution", @@ -6255,18 +6267,6 @@ "settable_per_mesh": true, "settable_per_extruder": false }, - "meshfix_maximum_resolution": - { - "label": "Maximum Resolution", - "description": "The minimum size of a line segment after slicing. If you increase this, the mesh will have a lower resolution. This may allow the printer to keep up with the speed it has to process g-code and will increase slice speed by removing details of the mesh that it can't process anyway.", - "type": "float", - "unit": "mm", - "default_value": 0.5, - "minimum_value": "0.001", - "minimum_value_warning": "0.01", - "maximum_value_warning": "3", - "settable_per_mesh": true - }, "support_skip_some_zags": { "label": "Break Up Support In Chunks", From 915c8e560ca945e419af7bcd5e7a0b2908ffda8c Mon Sep 17 00:00:00 2001 From: Nino van Hooff Date: Fri, 18 Oct 2019 09:04:00 +0200 Subject: [PATCH 24/50] Fix mypy warning --- cura/Machines/Models/IntentCategoryModel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/Machines/Models/IntentCategoryModel.py b/cura/Machines/Models/IntentCategoryModel.py index de909df534..8e7cd0fb5f 100644 --- a/cura/Machines/Models/IntentCategoryModel.py +++ b/cura/Machines/Models/IntentCategoryModel.py @@ -3,7 +3,7 @@ from PyQt5.QtCore import Qt import collections -from typing import TYPE_CHECKING, Optional +from typing import TYPE_CHECKING, Optional, Dict from cura.Machines.Models.IntentModel import IntentModel from cura.Settings.IntentManager import IntentManager @@ -31,7 +31,7 @@ class IntentCategoryModel(ListModel): # Translations to user-visible string. Ordered by weight. # TODO: Create a solution for this name and weight to be used dynamically. - _translations = collections.OrderedDict() # type: "collections.OrderedDict[str,Dict[str,Optional[str]]" + _translations = collections.OrderedDict() # type: "collections.OrderedDict[str,Dict[str,Optional[str]]]" _translations["default"] = { "name": catalog.i18nc("@label", "Default") } From c7a6fa4a006eb8a56c48f9f2eeafddc6603c63c0 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 18 Oct 2019 11:59:21 +0200 Subject: [PATCH 25/50] Remove fixed override of prime tower position Now it uses the calculated value from fdm_printer, which is way smarter about it --- resources/definitions/ultimaker_s5.def.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/definitions/ultimaker_s5.def.json b/resources/definitions/ultimaker_s5.def.json index dfa8da5397..7eb37d0614 100644 --- a/resources/definitions/ultimaker_s5.def.json +++ b/resources/definitions/ultimaker_s5.def.json @@ -70,8 +70,6 @@ "extruder_prime_pos_abs": { "default_value": true }, "machine_start_gcode": { "default_value": "" }, "machine_end_gcode": { "default_value": "" }, - "prime_tower_position_x": { "value": "345" }, - "prime_tower_position_y": { "value": "222.5" }, "prime_blob_enable": { "enabled": true, "default_value": false }, "speed_travel": From 15bdf0fa1c16ae3f45c97c7ef91fa3c97787e38d Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Fri, 18 Oct 2019 14:00:16 +0200 Subject: [PATCH 26/50] Change the description of 'Initial Bottom Layers'. part of CURA-5918 --- 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 8f115c2ed2..5f43cb0bfd 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1194,7 +1194,7 @@ "initial_bottom_layers": { "label": "Initial Bottom Layers", - "description": "The number of bottom layers. When calculated by the bottom thickness, this value is rounded to a whole number.", + "description": "The number of initial bottom layers, from the build-plate upwards. When calculated by the bottom thickness, this value is rounded to a whole number.", "minimum_value": "0", "minimum_value_warning": "2", "default_value": 6, From 25d76aee5ac19d36ce9485be019575b77dbe08ad Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Fri, 18 Oct 2019 14:46:44 +0200 Subject: [PATCH 27/50] Workaround: Make the type-checker understand what's going on. --- plugins/CuraEngineBackend/StartSliceJob.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 94f6d3edfa..29a6d8ff30 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -107,7 +107,8 @@ class StartSliceJob(Job): return False # if there are no per-object settings we don't need to check the other settings here - if stack.getTop() is None or not stack.getTop().getAllKeys(): + stack_top = stack.getTop() + if stack_top is None or not stack_top.getAllKeys(): return False for key in stack.getAllKeys(): From 9316df72b3745d9ce55a5e70f9cc1320c0689c36 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 18 Oct 2019 16:45:15 +0200 Subject: [PATCH 28/50] Add test for overriding default_value while there is a value This should not be done anywhere since the default_value won't have any effect then. We disregard CuraEngine's command line method here but that's infeasible with those profiles anyway. Done during Turbo Testing & Tooling. --- tests/Settings/TestDefinitionContainer.py | 71 ++++++++++++++++++++--- 1 file changed, 64 insertions(+), 7 deletions(-) diff --git a/tests/Settings/TestDefinitionContainer.py b/tests/Settings/TestDefinitionContainer.py index 73d4e89d20..0941840a05 100644 --- a/tests/Settings/TestDefinitionContainer.py +++ b/tests/Settings/TestDefinitionContainer.py @@ -1,18 +1,17 @@ # Copyright (c) 2019 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +import json # To check files for unnecessarily overridden properties. +import os +import os.path import pytest #This module contains automated tests. +from typing import Any, Dict +import uuid import UM.Settings.ContainerRegistry #To create empty instance containers. import UM.Settings.ContainerStack #To set the container registry the container stacks use. from UM.Settings.DefinitionContainer import DefinitionContainer #To check against the class of DefinitionContainer. - - -import os -import os.path -import uuid - from UM.Resources import Resources Resources.addSearchPath(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "resources"))) @@ -51,4 +50,62 @@ def assertIsDefinitionValid(definition_container, path, file_name): assert metadata[0]["platform"] in all_meshes if "platform_texture" in metadata[0]: - assert metadata[0]["platform_texture"] in all_images \ No newline at end of file + assert metadata[0]["platform_texture"] in all_images + +## Tests whether setting values are not being hidden by parent containers. +# +# When a definition container defines a "default_value" but inherits from a +# definition that defines a "value", the "default_value" is ineffective. This +# test fails on those things. +@pytest.mark.parametrize("file_name", machine_filepaths) +def test_validateOverridingDefaultValue(file_name): + definition_path = os.path.join(os.path.dirname(__file__), "..", "..", "resources", "definitions", file_name) + with open(definition_path, encoding = "utf-8") as f: + doc = json.load(f) + + if "inherits" not in doc: + return # We only want to check for documents where the inheritance overrides the children. If there's no inheritance, this can't happen so it's fine. + if "overrides" not in doc: + return # No settings are being overridden. No need to check anything. + parent_settings = getInheritedSettings(doc["inherits"]) + for key, val in doc["overrides"].items(): + if "value" in parent_settings[key]: + assert "default_value" not in val, "Unnecessary default_value in {file_name}".format(file_name = file_name) # If there is a value in the parent settings, then the default_value is not effective. + +def getInheritedSettings(definition_id: str) -> Dict[str, Any]: + definition_path = os.path.join(os.path.dirname(__file__), "..", "..", "resources", "definitions", definition_id + ".def.json") + with open(definition_path, encoding = "utf-8") as f: + doc = json.load(f) + result = {} + + if "inherits" in doc: # Recursive inheritance. + result.update(getInheritedSettings(doc["inherits"])) + if "settings" in doc: + result.update(flattenSettings(doc["settings"])) + if "overrides" in doc: + result = merge_dicts(result, doc["overrides"]) + + return result + +def flattenSettings(settings) -> Dict[str, Any]: + result = {} + for entry, contents in settings.items(): + if "children" in contents: + result.update(flattenSettings(contents["children"])) + del contents["children"] + result[entry] = contents + return result + +def merge_dicts(base: Dict[str, Any], overrides: Dict[str, Any]) -> Dict[str, Any]: + result = {} + result.update(base) + for key, val in overrides.items(): + if key not in result: + result[key] = val + continue + + if hasattr(result[key], "__getitem__") and hasattr(val, "__getitem__"): # Duck typing of dicts. Also works with JSON documents for sure. + result[key] = merge_dicts(result[key], val) + else: + result[key] = val + return result \ No newline at end of file From 76b5f9d37b05cd3a86ac01864c53b9051ad3997c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 18 Oct 2019 16:57:57 +0200 Subject: [PATCH 29/50] Fix testing if JSON elements are mappings Turns out that the JSON objects extend from dict, so this works. Also turns out that strings have a __getitem__. Who knew? Done during Turbo Testing & Tooling. --- tests/Settings/TestDefinitionContainer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Settings/TestDefinitionContainer.py b/tests/Settings/TestDefinitionContainer.py index 0941840a05..3a54fc1bed 100644 --- a/tests/Settings/TestDefinitionContainer.py +++ b/tests/Settings/TestDefinitionContainer.py @@ -104,7 +104,7 @@ def merge_dicts(base: Dict[str, Any], overrides: Dict[str, Any]) -> Dict[str, An result[key] = val continue - if hasattr(result[key], "__getitem__") and hasattr(val, "__getitem__"): # Duck typing of dicts. Also works with JSON documents for sure. + if isinstance(result[key], dict) and isinstance(val, dict): result[key] = merge_dicts(result[key], val) else: result[key] = val From 1d7ad38db2f08379a3a4ebc1393e7b36a54ba59d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 18 Oct 2019 17:00:47 +0200 Subject: [PATCH 30/50] Also name which setting has the dysfunctional override So that it's easier to remove it. Done during Turbo Testing & Tooling. --- tests/Settings/TestDefinitionContainer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Settings/TestDefinitionContainer.py b/tests/Settings/TestDefinitionContainer.py index 3a54fc1bed..fea360f1d2 100644 --- a/tests/Settings/TestDefinitionContainer.py +++ b/tests/Settings/TestDefinitionContainer.py @@ -70,7 +70,7 @@ def test_validateOverridingDefaultValue(file_name): parent_settings = getInheritedSettings(doc["inherits"]) for key, val in doc["overrides"].items(): if "value" in parent_settings[key]: - assert "default_value" not in val, "Unnecessary default_value in {file_name}".format(file_name = file_name) # If there is a value in the parent settings, then the default_value is not effective. + assert "default_value" not in val, "Unnecessary default_value for {key} in {file_name}".format(key = key, file_name = file_name) # If there is a value in the parent settings, then the default_value is not effective. def getInheritedSettings(definition_id: str) -> Dict[str, Any]: definition_path = os.path.join(os.path.dirname(__file__), "..", "..", "resources", "definitions", definition_id + ".def.json") From 15ea29924a856e4073c41c0665a3c4e6cc5ee092 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 18 Oct 2019 17:02:40 +0200 Subject: [PATCH 31/50] Sort definition files before testing them When going through the list of tests for many printers to fix them, it's then easier to go through the failed list. They will appear in the same order as in my IDE. Just a bit of an ease of life thing without any real cost. Done during Turbo Testing & Tooling. --- tests/Settings/TestDefinitionContainer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Settings/TestDefinitionContainer.py b/tests/Settings/TestDefinitionContainer.py index fea360f1d2..09efc3fcb8 100644 --- a/tests/Settings/TestDefinitionContainer.py +++ b/tests/Settings/TestDefinitionContainer.py @@ -16,7 +16,7 @@ from UM.Resources import Resources Resources.addSearchPath(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "resources"))) -machine_filepaths = os.listdir(os.path.join(os.path.dirname(__file__), "..", "..", "resources", "definitions")) +machine_filepaths = sorted(os.listdir(os.path.join(os.path.dirname(__file__), "..", "..", "resources", "definitions"))) all_meshes = os.listdir(os.path.join(os.path.dirname(__file__), "..", "..", "resources", "meshes")) all_images = os.listdir(os.path.join(os.path.dirname(__file__), "..", "..", "resources", "images")) From 4a5673746c5e53bbc9cd4265f5c5a0dd3cf1c2c1 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 18 Oct 2019 18:38:16 +0200 Subject: [PATCH 32/50] Remove unused default_value overrides These are overrides of default_value while there is a value defined. As such these overrides had no effect at all. Changing them to value can actually change the behaviour of the profile. That is not what the profile author has apparently tested with, so I'm not doing that. I'm just removing the unused data. In the future if we get new definitions the author gets notified of the error so that he may test more effectively. The legacy can't be fixed without re-testing, so I'm leaving that to the authors. Done during Turbo Testing & Tooling. I want to go home for the weekend now... --- resources/definitions/101Hero.def.json | 1 - resources/definitions/3dator.def.json | 7 -- .../definitions/Mark2_for_Ultimaker2.def.json | 12 ---- resources/definitions/abax_pri3.def.json | 24 ------- resources/definitions/abax_pri5.def.json | 24 ------- resources/definitions/abax_titan.def.json | 24 ------- resources/definitions/alfawise_u20.def.json | 21 ------ resources/definitions/alfawise_u30.def.json | 7 -- resources/definitions/bfb.def.json | 9 +-- resources/definitions/bq_hephestos.def.json | 24 ------- resources/definitions/bq_hephestos_2.def.json | 14 +--- .../definitions/bq_hephestos_xl.def.json | 24 ------- resources/definitions/bq_witbox.def.json | 24 ------- resources/definitions/bq_witbox_2.def.json | 36 ---------- .../builder_premium_large.def.json | 4 -- .../builder_premium_medium.def.json | 4 -- .../builder_premium_small.def.json | 4 -- .../cocoon_create_modelmaker.def.json | 18 ----- resources/definitions/creality_cr-x.def.json | 5 +- resources/definitions/creatable_d3.def.json | 6 +- resources/definitions/cubicon_common.def.json | 45 +------------ .../definitions/dagoma_discoeasy200.def.json | 3 - resources/definitions/dagoma_magis.def.json | 3 - resources/definitions/dagoma_neva.def.json | 3 - resources/definitions/delta_go.def.json | 4 -- resources/definitions/deltabot.def.json | 5 -- resources/definitions/deltacomb.def.json | 12 ++-- resources/definitions/easyarts_ares.def.json | 18 ----- resources/definitions/erzay3d.def.json | 40 ----------- resources/definitions/fabtotum.def.json | 4 +- resources/definitions/felixpro2dual.def.json | 2 - resources/definitions/felixtec4dual.def.json | 1 - resources/definitions/flsun_qq_s.def.json | 8 +-- resources/definitions/geeetech_a30.def.json | 11 +--- resources/definitions/gmax15plus.def.json | 5 +- .../definitions/gmax15plus_dual.def.json | 5 +- resources/definitions/helloBEEprusa.def.json | 13 ---- .../definitions/innovo_inventor.def.json | 26 -------- resources/definitions/jgaurora_a1.def.json | 21 ------ resources/definitions/jgaurora_a3s.def.json | 21 ------ resources/definitions/jgaurora_a5.def.json | 21 ------ .../jgaurora_jgmaker_magic.def.json | 21 ------ .../definitions/jgaurora_z_603s.def.json | 23 +------ resources/definitions/julia.def.json | 11 ---- resources/definitions/makeit_pro_l.def.json | 15 ----- resources/definitions/makeit_pro_m.def.json | 15 ----- resources/definitions/maker_starter.def.json | 66 ------------------- .../definitions/makerbotreplicator.def.json | 2 - resources/definitions/malyan_m200.def.json | 2 - .../mankati_fullscale_xt_plus.def.json | 10 +-- resources/definitions/ord.def.json | 3 - resources/definitions/printrbot_play.def.json | 1 - resources/definitions/prusa_i3_mk2.def.json | 3 - .../definitions/punchtec_connect_xl.def.json | 6 -- resources/definitions/rigid3d.def.json | 10 --- resources/definitions/rigid3d_3rdgen.def.json | 8 --- resources/definitions/rigid3d_hobby.def.json | 8 --- resources/definitions/rigid3d_mucit.def.json | 5 -- resources/definitions/rigid3d_zero.def.json | 10 --- resources/definitions/rigid3d_zero2.def.json | 10 +-- resources/definitions/rigidbot.def.json | 22 ------- resources/definitions/rigidbot_big.def.json | 22 ------- resources/definitions/robo_3d_r1.def.json | 12 ---- .../definitions/seemecnc_artemis.def.json | 4 +- resources/definitions/seemecnc_v32.def.json | 4 +- resources/definitions/strateo3d.def.json | 2 +- ...tur3d_discov3ry1_complete_um2plus.def.json | 3 - resources/definitions/tam.def.json | 1 - resources/definitions/tizyx_evy.def.json | 5 -- .../definitions/ubuild-3d_mr_bot_280.def.json | 3 - resources/definitions/ultimaker2.def.json | 3 - .../definitions/ultimaker2_plus.def.json | 3 - resources/definitions/vertex_k8400.def.json | 6 -- .../definitions/vertex_k8400_dual.def.json | 6 -- .../definitions/vertex_nano_k8600.def.json | 6 -- resources/definitions/wanhao_d9.def.json | 2 - resources/definitions/zone3d_printer.def.json | 2 - 77 files changed, 24 insertions(+), 874 deletions(-) diff --git a/resources/definitions/101Hero.def.json b/resources/definitions/101Hero.def.json index a77ea5ed97..d356d15da9 100644 --- a/resources/definitions/101Hero.def.json +++ b/resources/definitions/101Hero.def.json @@ -34,7 +34,6 @@ }, "speed_print": { "default_value": 14 }, "speed_travel": { "value": "speed_print" }, - "speed_infill": { "default_value": 14 }, "speed_wall": { "value": "speed_print * 0.7" }, "speed_topbottom": { "value": "speed_print * 0.7" }, "speed_layer_0": { "value": "speed_print * 0.7" }, diff --git a/resources/definitions/3dator.def.json b/resources/definitions/3dator.def.json index 901ea87510..ac37523379 100644 --- a/resources/definitions/3dator.def.json +++ b/resources/definitions/3dator.def.json @@ -17,15 +17,10 @@ "overrides": { "machine_name": { "default_value": "3Dator" }, - "speed_travel": { "default_value": 120 }, "prime_tower_size": { "default_value": 8.660254037844387 }, "infill_sparse_density": { "default_value": 20 }, - "speed_wall_x": { "default_value": 45 }, - "speed_wall_0": { "default_value": 40 }, - "speed_topbottom": { "default_value": 35 }, "layer_height": { "default_value": 0.2 }, "speed_print": { "default_value": 50 }, - "speed_infill": { "default_value": 60 }, "machine_heated_bed": { "default_value": true }, "machine_center_is_zero": { "default_value": false }, "machine_height": { "default_value": 260 }, @@ -33,8 +28,6 @@ "machine_depth": { "default_value": 170 }, "machine_width": { "default_value": 180 }, "retraction_speed": {"default_value":100}, - "cool_fan_speed_min": {"default_value": 20}, - "cool_fan_speed_max": {"default_value": 70}, "adhesion_type": { "default_value": "none" }, "machine_head_with_fans_polygon": { "default_value": [ diff --git a/resources/definitions/Mark2_for_Ultimaker2.def.json b/resources/definitions/Mark2_for_Ultimaker2.def.json index b02dc78adf..1aca2a3844 100644 --- a/resources/definitions/Mark2_for_Ultimaker2.def.json +++ b/resources/definitions/Mark2_for_Ultimaker2.def.json @@ -79,9 +79,6 @@ "line_width": { "value": "round(machine_nozzle_size * 0.875, 2)" }, - "speed_layer_0": { - "default_value": 20 - }, "speed_support": { "value": "speed_wall_0" }, @@ -107,22 +104,18 @@ "default_value": 25 }, "switch_extruder_retraction_amount": { - "default_value": 0, "value": "retraction_amount", "enabled": false }, "switch_extruder_retraction_speeds": { - "default_value": 25, "value": "retraction_speed", "enabled": false }, "switch_extruder_retraction_speed": { - "default_value": 25, "value": "retraction_retract_speed", "enabled": false }, "switch_extruder_prime_speed": { - "default_value": 25, "value": "retraction_prime_speed", "enabled": false }, @@ -142,11 +135,9 @@ "default_value": "RepRap (Marlin/Sprinter)" }, "machine_start_gcode" : { - "default_value": "", "value": "\"\" if machine_gcode_flavor == \"UltiGCode\" else \"G21 ;metric values\\nG90 ;absolute positioning\\nM82 ;set extruder to absolute mode\\nM107 ;start with the fan off\\nM200 D0 T0 ;reset filament diameter\\nM200 D0 T1\\nG28 Z0; home all\\nG28 X0 Y0\\nG0 Z20 F2400 ;move the platform to 20mm\\nG92 E0\\nM190 S{material_bed_temperature_layer_0}\\nM109 T0 S{material_standby_temperature, 0}\\nM109 T1 S{material_print_temperature_layer_0, 1}\\nM104 T0 S{material_print_temperature_layer_0, 0}\\nT1 ; move to the 2th head\\nG0 Z20 F2400\\nG92 E-7.0 ;prime distance\\nG1 E0 F45 ;purge nozzle\\nG1 E-5.1 F1500 ; retract\\nG1 X90 Z0.01 F5000 ; move away from the prime poop\\nG1 X50 F9000\\nG0 Z20 F2400\\nT0 ; move to the first head\\nM104 T1 S{material_standby_temperature, 1}\\nG0 Z20 F2400\\nM104 T{initial_extruder_nr} S{material_print_temperature_layer_0, initial_extruder_nr}\\nG92 E-7.0\\nG1 E0 F45 ;purge nozzle\\nG1 X60 Z0.01 F5000 ; move away from the prime poop\\nG1 X20 F9000\\nM400 ;finish all moves\\nG92 E0\\n;end of startup sequence\\n\"" }, "machine_end_gcode" : { - "default_value": "", "value": "\"\" if machine_gcode_flavor == \"UltiGCode\" else \"G90 ;absolute positioning\\nM104 S0 T0 ;extruder heater off\\nM104 S0 T1\\nM140 S0 ;turn off bed\\nT0 ; move to the first head\\nM107 ;fan off\"" }, "machine_extruder_count": { @@ -158,12 +149,10 @@ }, "acceleration_print": { - "default_value": 2000, "value": "2000" }, "acceleration_travel": { - "default_value": 3000, "value": "acceleration_print if magic_spiralize else 3000" }, "acceleration_layer_0": { "value": "acceleration_topbottom" }, @@ -183,7 +172,6 @@ }, "jerk_travel": { - "default_value": 20, "value": "jerk_print if magic_spiralize else 20" }, "jerk_layer_0": { "value": "jerk_topbottom" }, diff --git a/resources/definitions/abax_pri3.def.json b/resources/definitions/abax_pri3.def.json index 1ab48b865a..529636be90 100644 --- a/resources/definitions/abax_pri3.def.json +++ b/resources/definitions/abax_pri3.def.json @@ -49,33 +49,9 @@ "top_bottom_thickness": { "default_value": 1 }, - "bottom_thickness": { - "default_value": 1 - }, - "material_print_temperature": { - "default_value": 200 - }, - "material_bed_temperature": { - "default_value": 0 - }, "speed_print": { "default_value": 40 }, - "speed_infill": { - "default_value": 70 - }, - "speed_wall": { - "default_value": 25 - }, - "speed_topbottom": { - "default_value": 15 - }, - "speed_travel": { - "default_value": 150 - }, - "speed_layer_0": { - "default_value": 30 - }, "support_enable": { "default_value": true } diff --git a/resources/definitions/abax_pri5.def.json b/resources/definitions/abax_pri5.def.json index 46229ce756..9e4e7e3b20 100644 --- a/resources/definitions/abax_pri5.def.json +++ b/resources/definitions/abax_pri5.def.json @@ -49,33 +49,9 @@ "top_bottom_thickness": { "default_value": 1 }, - "bottom_thickness": { - "default_value": 1 - }, - "material_print_temperature": { - "default_value": 200 - }, - "material_bed_temperature": { - "default_value": 0 - }, "speed_print": { "default_value": 40 }, - "speed_infill": { - "default_value": 70 - }, - "speed_wall": { - "default_value": 25 - }, - "speed_topbottom": { - "default_value": 15 - }, - "speed_travel": { - "default_value": 150 - }, - "speed_layer_0": { - "default_value": 30 - }, "support_enable": { "default_value": true } diff --git a/resources/definitions/abax_titan.def.json b/resources/definitions/abax_titan.def.json index 9f67117d6c..98643df22b 100644 --- a/resources/definitions/abax_titan.def.json +++ b/resources/definitions/abax_titan.def.json @@ -49,33 +49,9 @@ "top_bottom_thickness": { "default_value": 1 }, - "bottom_thickness": { - "default_value": 1 - }, - "material_print_temperature": { - "default_value": 200 - }, - "material_bed_temperature": { - "default_value": 0 - }, "speed_print": { "default_value": 40 }, - "speed_infill": { - "default_value": 70 - }, - "speed_wall": { - "default_value": 25 - }, - "speed_topbottom": { - "default_value": 15 - }, - "speed_travel": { - "default_value": 150 - }, - "speed_layer_0": { - "default_value": 30 - }, "support_enable": { "default_value": true } diff --git a/resources/definitions/alfawise_u20.def.json b/resources/definitions/alfawise_u20.def.json index 748bf8797a..4da42fdb1d 100644 --- a/resources/definitions/alfawise_u20.def.json +++ b/resources/definitions/alfawise_u20.def.json @@ -47,12 +47,6 @@ "material_diameter": { "default_value": 1.75 }, - "material_print_temperature": { - "default_value": 210 - }, - "material_bed_temperature": { - "default_value": 50 - }, "layer_height_0": { "default_value": 0.2 }, @@ -62,21 +56,6 @@ "speed_print": { "default_value": 40 }, - "speed_infill": { - "default_value": 40 - }, - "speed_wall": { - "default_value": 35 - }, - "speed_topbottom": { - "default_value": 35 - }, - "speed_travel": { - "default_value": 120 - }, - "speed_layer_0": { - "default_value": 20 - }, "support_enable": { "default_value": true }, diff --git a/resources/definitions/alfawise_u30.def.json b/resources/definitions/alfawise_u30.def.json index 44caf61d1a..e05536f66c 100644 --- a/resources/definitions/alfawise_u30.def.json +++ b/resources/definitions/alfawise_u30.def.json @@ -22,16 +22,9 @@ "default_value": "; -- END GCODE --\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F80 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning\nM107 ;turn the fan off; -- end of END GCODE --" }, "material_diameter": { "default_value": 1.75 }, - "material_print_temperature": { "default_value": 210 }, - "material_bed_temperature": { "default_value": 50 }, "layer_height_0": { "default_value": 0.2 }, "wall_thickness": { "default_value": 1.2 }, "speed_print": { "default_value": 40 }, - "speed_infill": { "default_value": 50 }, - "speed_wall": { "default_value": 35 }, - "speed_topbottom": { "default_value": 35 }, - "speed_travel": { "default_value": 120 }, - "speed_layer_0": { "default_value": 20 }, "support_enable": { "default_value": true }, "retraction_enable": { "default_value": true }, "retraction_amount": { "default_value": 5 }, diff --git a/resources/definitions/bfb.def.json b/resources/definitions/bfb.def.json index d1dfa9ef1b..e88c8c792b 100644 --- a/resources/definitions/bfb.def.json +++ b/resources/definitions/bfb.def.json @@ -15,26 +15,19 @@ }, "overrides": { - "speed_topbottom": { "default_value": 40 }, "speed_print": { "default_value": 40 }, "machine_extruder_count": { "default_value": 1 }, "prime_tower_size": { "default_value": 7.745966692414834 }, "machine_name": { "default_value": "BFB_Test" }, "machine_heated_bed": { "default_value": false }, - "speed_layer_0": { "default_value": 25 }, "machine_width": { "default_value": 275 }, "machine_gcode_flavor": { "default_value": "BFB" }, "machine_depth": { "default_value": 265 }, - "speed_infill": { "default_value": 30 }, "machine_center_is_zero": { "default_value": true }, "machine_height": { "default_value": 240 }, "layer_height": { "default_value": 0.25 }, - "material_print_temperature": { "default_value": 200 }, "retraction_amount": { "default_value": 0.05 }, - "speed_wall_0": { "default_value": 25 }, - "speed_travel": { "default_value": 50 }, "infill_sparse_density": { "default_value": 10 }, - "layer_height_0": { "default_value": 0.5 }, - "speed_wall_x": { "default_value": 20 } + "layer_height_0": { "default_value": 0.5 } } } diff --git a/resources/definitions/bq_hephestos.def.json b/resources/definitions/bq_hephestos.def.json index be024cd6fa..d9e84dae87 100644 --- a/resources/definitions/bq_hephestos.def.json +++ b/resources/definitions/bq_hephestos.def.json @@ -54,33 +54,9 @@ "top_bottom_thickness": { "default_value": 1 }, - "bottom_thickness": { - "default_value": 1 - }, - "material_print_temperature": { - "default_value": 220 - }, - "material_bed_temperature": { - "default_value": 0 - }, "speed_print": { "default_value": 40 }, - "speed_infill": { - "default_value": 40 - }, - "speed_wall": { - "default_value": 35 - }, - "speed_topbottom": { - "default_value": 35 - }, - "speed_travel": { - "default_value": 120 - }, - "speed_layer_0": { - "default_value": 20 - }, "support_enable": { "default_value": true } diff --git a/resources/definitions/bq_hephestos_2.def.json b/resources/definitions/bq_hephestos_2.def.json index 90a86433fb..5c122eb9a4 100644 --- a/resources/definitions/bq_hephestos_2.def.json +++ b/resources/definitions/bq_hephestos_2.def.json @@ -24,26 +24,14 @@ "machine_height": { "default_value": 220 }, "machine_heated_bed": { "default_value": false }, "machine_center_is_zero": { "default_value": false }, - "material_print_temperature": { "default_value": 210 }, - "material_bed_temperature": { "default_value": 0 }, "layer_height": { "default_value": 0.2 }, "layer_height_0": { "default_value": 0.2 }, - "wall_line_count": { "default_value": 3 }, "wall_thickness": { "default_value": 1.2 }, "top_bottom_thickness": { "default_value": 1.2 }, "infill_sparse_density": { "default_value": 20 }, - "infill_overlap": { "default_value": 15 }, "speed_print": { "default_value": 60 }, - "speed_travel": { "default_value": 160 }, - "speed_layer_0": { "default_value": 30 }, - "speed_wall_x": { "default_value": 35 }, - "speed_wall_0": { "default_value": 30 }, - "speed_infill": { "default_value": 80 }, - "speed_topbottom": { "default_value": 35 }, - "skirt_brim_speed": { "default_value": 35 }, "skirt_line_count": { "default_value": 4 }, "skirt_brim_minimal_length": { "default_value": 30 }, - "skirt_gap": { "default_value": 6 }, - "cool_fan_full_at_height": { "default_value": 0.4 } + "skirt_gap": { "default_value": 6 } } } diff --git a/resources/definitions/bq_hephestos_xl.def.json b/resources/definitions/bq_hephestos_xl.def.json index a8d63cbb41..16d0953bf1 100644 --- a/resources/definitions/bq_hephestos_xl.def.json +++ b/resources/definitions/bq_hephestos_xl.def.json @@ -53,33 +53,9 @@ "top_bottom_thickness": { "default_value": 1 }, - "bottom_thickness": { - "default_value": 1 - }, - "material_print_temperature": { - "default_value": 220 - }, - "material_bed_temperature": { - "default_value": 0 - }, "speed_print": { "default_value": 40 }, - "speed_infill": { - "default_value": 40 - }, - "speed_wall": { - "default_value": 35 - }, - "speed_topbottom": { - "default_value": 35 - }, - "speed_travel": { - "default_value": 120 - }, - "speed_layer_0": { - "default_value": 20 - }, "support_enable": { "default_value": true } diff --git a/resources/definitions/bq_witbox.def.json b/resources/definitions/bq_witbox.def.json index b96da6179c..fce2af9f97 100644 --- a/resources/definitions/bq_witbox.def.json +++ b/resources/definitions/bq_witbox.def.json @@ -54,33 +54,9 @@ "top_bottom_thickness": { "default_value": 1 }, - "bottom_thickness": { - "default_value": 1 - }, - "material_print_temperature": { - "default_value": 220 - }, - "material_bed_temperature": { - "default_value": 0 - }, "speed_print": { "default_value": 40 }, - "speed_infill": { - "default_value": 40 - }, - "speed_wall": { - "default_value": 35 - }, - "speed_topbottom": { - "default_value": 35 - }, - "speed_travel": { - "default_value": 120 - }, - "speed_layer_0": { - "default_value": 20 - }, "support_enable": { "default_value": true } diff --git a/resources/definitions/bq_witbox_2.def.json b/resources/definitions/bq_witbox_2.def.json index 7412647852..d1114aafd6 100644 --- a/resources/definitions/bq_witbox_2.def.json +++ b/resources/definitions/bq_witbox_2.def.json @@ -41,21 +41,12 @@ "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" }, - "material_print_temperature": { - "default_value": 210 - }, - "material_bed_temperature": { - "default_value": 0 - }, "layer_height": { "default_value": 0.2 }, "layer_height_0": { "default_value": 0.2 }, - "wall_line_count": { - "default_value": 3 - }, "wall_thickness": { "default_value": 1.2 }, @@ -65,33 +56,9 @@ "infill_sparse_density": { "default_value": 20 }, - "infill_overlap": { - "default_value": 15 - }, "speed_print": { "default_value": 60 }, - "speed_travel": { - "default_value": 160 - }, - "speed_layer_0": { - "default_value": 30 - }, - "speed_wall_x": { - "default_value": 35 - }, - "speed_wall_0": { - "default_value": 30 - }, - "speed_infill": { - "default_value": 80 - }, - "speed_topbottom": { - "default_value": 35 - }, - "skirt_brim_speed": { - "default_value": 35 - }, "skirt_line_count": { "default_value": 4 }, @@ -101,9 +68,6 @@ "skirt_gap": { "default_value": 6 }, - "cool_fan_full_at_height": { - "default_value": 0.4 - }, "support_enable": { "default_value": false } diff --git a/resources/definitions/builder_premium_large.def.json b/resources/definitions/builder_premium_large.def.json index d100cd1ba9..e5411027e3 100644 --- a/resources/definitions/builder_premium_large.def.json +++ b/resources/definitions/builder_premium_large.def.json @@ -35,8 +35,6 @@ "material_standby_temperature": { "value": "material_print_temperature" }, "switch_extruder_retraction_speeds": {"default_value": 15 }, - "switch_extruder_retraction_speed": {"default_value": 15 }, - "switch_extruder_prime_speed": {"default_value": 15 }, "switch_extruder_retraction_amount": {"value": 1 }, "speed_travel": { "value": "100" }, @@ -85,8 +83,6 @@ "retraction_amount": { "default_value": 3 }, "retraction_speed": { "default_value": 15 }, - "retraction_retract_speed": { "default_value": 15 }, - "retraction_prime_speed": { "default_value": 15 }, "travel_retract_before_outer_wall": { "default_value": true }, "skin_overlap": { "value": "15" }, "adhesion_type": { "default_value": "skirt" }, diff --git a/resources/definitions/builder_premium_medium.def.json b/resources/definitions/builder_premium_medium.def.json index 16aeeffdae..1817dfe7db 100644 --- a/resources/definitions/builder_premium_medium.def.json +++ b/resources/definitions/builder_premium_medium.def.json @@ -35,8 +35,6 @@ "material_standby_temperature": { "value": "material_print_temperature" }, "switch_extruder_retraction_speeds": {"default_value": 15 }, - "switch_extruder_retraction_speed": {"default_value": 15 }, - "switch_extruder_prime_speed": {"default_value": 15 }, "switch_extruder_retraction_amount": {"value": 1 }, "speed_travel": { "value": "100" }, @@ -85,8 +83,6 @@ "retraction_amount": { "default_value": 3 }, "retraction_speed": { "default_value": 15 }, - "retraction_retract_speed": { "default_value": 15 }, - "retraction_prime_speed": { "default_value": 15 }, "travel_retract_before_outer_wall": { "default_value": true }, "skin_overlap": { "value": "15" }, "adhesion_type": { "default_value": "skirt" }, diff --git a/resources/definitions/builder_premium_small.def.json b/resources/definitions/builder_premium_small.def.json index 290e79660f..f126da7752 100644 --- a/resources/definitions/builder_premium_small.def.json +++ b/resources/definitions/builder_premium_small.def.json @@ -34,8 +34,6 @@ "material_standby_temperature": { "value": "material_print_temperature" }, "switch_extruder_retraction_speeds": {"default_value": 15 }, - "switch_extruder_retraction_speed": {"default_value": 15 }, - "switch_extruder_prime_speed": {"default_value": 15 }, "switch_extruder_retraction_amount": {"value": 1 }, "speed_travel": { "value": "100" }, @@ -84,8 +82,6 @@ "retraction_amount": { "default_value": 3 }, "retraction_speed": { "default_value": 15 }, - "retraction_retract_speed": { "default_value": 15 }, - "retraction_prime_speed": { "default_value": 15 }, "travel_retract_before_outer_wall": { "default_value": true }, "skin_overlap": { "value": "15" }, "adhesion_type": { "default_value": "skirt" }, diff --git a/resources/definitions/cocoon_create_modelmaker.def.json b/resources/definitions/cocoon_create_modelmaker.def.json index 83d1f41a99..b738dc64ff 100644 --- a/resources/definitions/cocoon_create_modelmaker.def.json +++ b/resources/definitions/cocoon_create_modelmaker.def.json @@ -47,9 +47,6 @@ "material_diameter": { "default_value": 1.75 }, - "material_print_temperature": { - "default_value": 220 - }, "layer_height": { "default_value": 0.10 }, @@ -65,21 +62,6 @@ "speed_print": { "default_value": 40 }, - "speed_infill": { - "default_value": 40 - }, - "speed_wall": { - "default_value": 35 - }, - "speed_topbottom": { - "default_value": 35 - }, - "speed_travel": { - "default_value": 70 - }, - "speed_layer_0": { - "default_value": 20 - }, "support_enable": { "default_value": true }, diff --git a/resources/definitions/creality_cr-x.def.json b/resources/definitions/creality_cr-x.def.json index 0117c4fffe..15bea1edf1 100644 --- a/resources/definitions/creality_cr-x.def.json +++ b/resources/definitions/creality_cr-x.def.json @@ -32,7 +32,6 @@ "adhesion_type": { "default_value": "skirt" }, "gantry_height": { "value": "30" }, "speed_print": { "default_value": 60 }, - "speed_travel": { "default_value": 120 }, "machine_max_acceleration_x": { "default_value": 500 }, "machine_max_acceleration_y": { "default_value": 500 }, "machine_max_acceleration_z": { "default_value": 100 }, @@ -43,9 +42,7 @@ "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" }, "machine_start_gcode": { "default_value": "G21 ;metric values\nG28 ;home all\nG90 ;absolute positioning\nM107 ;start with the fan off\nG1 F2400 Z15.0 ;raise the nozzle 15mm\nM109 S{material_print_temperature} ;Set Extruder Temperature and Wait\nM190 S{material_bed_temperature}; Wait for bed temperature to reach target temp\nT0 ;Switch to Extruder 1\nG1 F3000 X5 Y10 Z0.2 ;move to prime start position\nG92 E0 ;reset extrusion distance\nG1 F600 X160 E15 ;prime nozzle in a line\nG1 F5000 X180 ;quick wipe\nG92 E0 ;reset extrusion distance" }, "machine_end_gcode": { "default_value": "M104 S0 ;hotend off\nM140 S0 ;bed off\nG92 E0\nG1 F2000 E-100 ;retract filament 100mm\nG92 E0\nG1 F3000 X0 Y270 ;move bed for easy part removal\nM84 ;disable steppers" }, - "material_print_temperature": { "default_value": 200 }, "wall_thickness": { "default_value": 1 }, - "top_bottom_thickness": { "default_value": 1 }, - "bottom_thickness": { "default_value": 1 } + "top_bottom_thickness": { "default_value": 1 } } } diff --git a/resources/definitions/creatable_d3.def.json b/resources/definitions/creatable_d3.def.json index 1491089e24..f621bcbe97 100644 --- a/resources/definitions/creatable_d3.def.json +++ b/resources/definitions/creatable_d3.def.json @@ -27,14 +27,12 @@ "machine_max_feedrate_z": { "default_value": 300 }, "gantry_height": {"value": "43"}, "layer_height": { "default_value": 0.1 }, - "relative_extrusion": { "default_value": false }, + "relative_extrusion": { "value": "False" }, "retraction_combing": { "default_value": "off" }, - "retraction_hop_enabled": { "default_value": true }, + "retraction_hop_enabled": { "default_value": true }, "retraction_hop_only_when_collides": { "default_value": false }, - "retraction_retract_speed": { "default_value": 100 }, "retraction_speed": { "default_value": 100 }, "retraction_amount": { "default_value": 4.5 }, - "retraction_prime_speed": { "default_value": 45 }, "machine_start_gcode": { "default_value": "G21\nG90\nM82\nM106 S255\nG28\nG92 E0\nG1 Z100 F5000\nM190 S50\nM109 S200\nG1 X-135\nG1 Z0.3\nG92 E-32\nG1 E0 F1000\nG1 E50 F200\nG1 F1000\nG1 X-125\nG92 E0" }, diff --git a/resources/definitions/cubicon_common.def.json b/resources/definitions/cubicon_common.def.json index ae085c7552..6b1e3d953e 100644 --- a/resources/definitions/cubicon_common.def.json +++ b/resources/definitions/cubicon_common.def.json @@ -23,77 +23,34 @@ "travel_compensate_overlapping_walls_enabled": { "default_value": false }, - "travel_compensate_overlapping_walls_0_enabled": { - "default_value": false - }, - "travel_compensate_overlapping_walls_x_enabled": { - "default_value": false - }, "layer_height": { "default_value": 0.2 }, "layer_height_0": { "default_value": 0.2 }, - "infill_line_width": { - "default_value": 0.6 - }, "adhesion_type": { "default_value": "raft" }, - "roofing_pattern": { "default_value": "lines" }, "top_bottom_pattern": { "default_value": "lines" }, - "top_bottom_pattern_0": { - "default_value": "zigzag" - }, "fill_perimeter_gaps": { "default_value": "everywhere" }, - "infill_pattern": { - "default_value": "zigzag" - }, "infill_sparse_density": { "default_value": 20 }, - "infill_overlap": { - "default_value": 15 - }, "infill_before_walls": { "default_value": false }, - "infill_sparse_thickness": { "default_value": 0.2 }, "top_bottom_thickness": { "default_value": 1.0 }, - "top_thickness": { - "default_value": 1.0 - }, "bottom_thickness": { - "default_value": 0.6, "value": "top_bottom_thickness * 0.6" }, - "roofing_layer_count": { - "default_value": 1 - }, - "skin_preshrink": { "default_value": true }, "material_flow_layer_0": { "default_value": 100 }, - "top_skin_preshrink": { "default_value": 1.2 }, - "bottom_skin_preshrink": { "default_value": 1.2 }, "max_skin_angle_for_expansion": { "default_value": 90 }, - "min_skin_width_for_expansion": { "default_value": 2.7475 }, "skin_angles": { "default_value": "[135,45]" }, - "roofing_angles": { "default_value": "[135,45]" }, "coasting_volume": { "default_value": 0.032 }, "wall_thickness": { "default_value": 1.2 }, - "wall_line_count": { "default_value": 3 }, - "speed_wall_0": { "default_value": 25 }, - "skin_overlap": { "default_value": 5 }, "cool_min_layer_time_fan_speed_max": { "default_value": 15 }, "cool_min_layer_time": { "default_value": 15 }, - "support_roof_pattern": { "default_value": "zigzag" }, - "support_bottom_pattern": { "default_value": "zigzag" }, "support_interface_pattern": { "default_value": "zigzag" }, "support_pattern": { "default_value": "zigzag" }, - "retraction_amount": { "default_value": 1.5 }, - "top_layers": { - "default_value": 5 - }, - "bottom_layers": { - "default_value": 3 - } + "retraction_amount": { "default_value": 1.5 } } } \ No newline at end of file diff --git a/resources/definitions/dagoma_discoeasy200.def.json b/resources/definitions/dagoma_discoeasy200.def.json index 17e285a422..30c0abdab2 100644 --- a/resources/definitions/dagoma_discoeasy200.def.json +++ b/resources/definitions/dagoma_discoeasy200.def.json @@ -52,9 +52,6 @@ "speed_print": { "default_value": 60 }, - "speed_travel": { - "default_value": 100 - }, "retraction_amount": { "default_value": 3.5 }, diff --git a/resources/definitions/dagoma_magis.def.json b/resources/definitions/dagoma_magis.def.json index 9d2f7170c6..dc5a0f86d2 100644 --- a/resources/definitions/dagoma_magis.def.json +++ b/resources/definitions/dagoma_magis.def.json @@ -55,9 +55,6 @@ "speed_print": { "default_value": 40 }, - "speed_travel": { - "default_value": 120 - }, "retraction_amount": { "default_value": 3.8 }, diff --git a/resources/definitions/dagoma_neva.def.json b/resources/definitions/dagoma_neva.def.json index ea6046b613..43a3e0c4f1 100644 --- a/resources/definitions/dagoma_neva.def.json +++ b/resources/definitions/dagoma_neva.def.json @@ -55,9 +55,6 @@ "speed_print": { "default_value": 40 }, - "speed_travel": { - "default_value": 120 - }, "retraction_amount": { "default_value": 3.8 }, diff --git a/resources/definitions/delta_go.def.json b/resources/definitions/delta_go.def.json index cd1fb180c2..04f0580898 100644 --- a/resources/definitions/delta_go.def.json +++ b/resources/definitions/delta_go.def.json @@ -16,12 +16,8 @@ "overrides": { "machine_name": { "default_value": "Delta Go" }, "default_material_print_temperature": { "default_value": 210 }, - "speed_travel": { "default_value": 150 }, "prime_tower_size": { "default_value": 8.66 }, "infill_sparse_density": { "default_value": 10 }, - "speed_wall_x": { "default_value": 30 }, - "speed_wall_0": { "default_value": 30 }, - "speed_topbottom": { "default_value": 20 }, "layer_height": { "default_value": 0.15 }, "speed_print": { "default_value": 30 }, "machine_heated_bed": { "default_value": false }, diff --git a/resources/definitions/deltabot.def.json b/resources/definitions/deltabot.def.json index 613b61d32c..ad6a207bb2 100644 --- a/resources/definitions/deltabot.def.json +++ b/resources/definitions/deltabot.def.json @@ -15,15 +15,10 @@ }, "overrides": { - "speed_travel": { "default_value": 150 }, "prime_tower_size": { "default_value": 8.660254037844387 }, "infill_sparse_density": { "default_value": 10 }, - "speed_wall_x": { "default_value": 30 }, - "speed_wall_0": { "default_value": 30 }, - "speed_topbottom": { "default_value": 30 }, "layer_height": { "default_value": 0.2 }, "speed_print": { "default_value": 30 }, - "speed_infill": { "default_value": 30 }, "machine_extruder_count": { "default_value": 1 }, "machine_heated_bed": { "default_value": true }, "machine_center_is_zero": { "default_value": true }, diff --git a/resources/definitions/deltacomb.def.json b/resources/definitions/deltacomb.def.json index c46beeec2d..ac2ea5abe1 100755 --- a/resources/definitions/deltacomb.def.json +++ b/resources/definitions/deltacomb.def.json @@ -37,7 +37,7 @@ "retraction_amount" : { "default_value": 3.5 }, "retraction_speed" : { "default_value": 30 }, "retraction_combing" : { "default_value": "noskin" }, - "travel_avoid_distance": { "default_value": 1, "value": "1" }, + "travel_avoid_distance": { "value": "1" }, "speed_print" : { "default_value": 80 }, "speed_infill": { "value": "round(speed_print * 1.05, 0)" }, "speed_topbottom": { "value": "round(speed_print * 0.95, 0)" }, @@ -45,7 +45,7 @@ "speed_wall_0": { "value": "30" }, "speed_wall_x": { "value": "speed_wall" }, "speed_layer_0": { "value": "min(round(speed_print * 0.75, 0), 45.0)" }, - "speed_travel": { "default_value": 150, "value": 150 }, + "speed_travel": { "value": 150 }, "speed_travel_layer_0": { "value": "round(speed_travel * 0.7, 0)" }, "skirt_brim_speed": { "value": "speed_layer_0" }, "skirt_line_count": { "default_value": 3 }, @@ -57,10 +57,10 @@ "support_z_distance": { "value": "layer_height * 2" }, "support_bottom_distance": { "value": "layer_height" }, "support_use_towers" : { "default_value": false }, - "jerk_enabled": { "default_value": 1, "value": "1" }, - "jerk_infill" : { "default_value": 5, "value": "5" }, - "jerk_support" : { "default_value": 5, "value": "5" }, - "acceleration_enabled": { "default_value": 1, "value": "1" }, + "jerk_enabled": { "value": "True" }, + "jerk_infill" : { "value": "5" }, + "jerk_support" : { "value": "5" }, + "acceleration_enabled": { "value": "1" }, "acceleration_travel" : { "value": 5000 }, "machine_max_feedrate_z" : { "default_value": 300 } } diff --git a/resources/definitions/easyarts_ares.def.json b/resources/definitions/easyarts_ares.def.json index 0e2742f484..18d73a3531 100644 --- a/resources/definitions/easyarts_ares.def.json +++ b/resources/definitions/easyarts_ares.def.json @@ -49,27 +49,9 @@ "top_bottom_thickness": { "default_value": 1 }, - "bottom_thickness": { - "default_value": 1 - }, "speed_print": { "default_value": 75 }, - "speed_infill": { - "default_value": 100 - }, - "speed_wall": { - "default_value": 25 - }, - "speed_topbottom": { - "default_value": 15 - }, - "speed_travel": { - "default_value": 150 - }, - "speed_layer_0": { - "default_value": 30 - }, "support_enable": { "default_value": true } diff --git a/resources/definitions/erzay3d.def.json b/resources/definitions/erzay3d.def.json index 0a6d676bea..875aea708e 100644 --- a/resources/definitions/erzay3d.def.json +++ b/resources/definitions/erzay3d.def.json @@ -56,57 +56,17 @@ "ironing_pattern": { "default_value": "concentric" }, "ironing_flow": { "default_value": 7.0 }, - "roofing_pattern": { "default_value": "concentric" }, "infill_sparse_density": { "default_value": 20 }, - "infill_line_distance": { "default_value": 4 }, "default_material_print_temperature": { "default_value": 220 }, - "material_print_temperature": { "default_value": 220 }, - "material_print_temperature_layer_0": { "default_value": 220 }, - "material_initial_print_temperature": { "default_value": 220 }, - "material_final_print_temperature": { "default_value": 220 }, "retraction_amount": { "default_value": 6.5 }, "speed_print": { "default_value": 40 }, - "speed_infill": { "default_value": 60 }, - "speed_wall": { "default_value": 20 }, - "speed_wall_0": { "default_value": 20 }, - "speed_wall_x": { "default_value": 40 }, - "speed_roofing": { "default_value": 20 }, - "speed_topbottom": { "default_value": 20 }, - "speed_support": { "default_value": 40 }, - "speed_support_infill": { "default_value": 40 }, - "speed_support_interface": { "default_value": 25 }, - "speed_support_roof": { "default_value": 25 }, - "speed_support_bottom": { "default_value": 25 }, - "speed_prime_tower": { "default_value": 40 }, - "speed_travel": { "default_value": 100 }, - "speed_layer_0": { "default_value": 20 }, - "speed_print_layer_0": { "default_value": 20 }, - "speed_travel_layer_0": { "default_value": 80 }, - "skirt_brim_speed": { "default_value": 20 }, "speed_equalize_flow_enabled": { "default_value": true }, "speed_equalize_flow_max": { "default_value": 100 }, "acceleration_print": { "default_value": 1000 }, - "acceleration_infill": { "default_value": 3000 }, - "acceleration_wall": { "default_value": 1000 }, - "acceleration_wall_0": { "default_value": 1000 }, - "acceleration_wall_x": { "default_value": 1000 }, - "acceleration_roofing": { "default_value": 1000 }, - "acceleration_topbottom": { "default_value": 1000 }, - "acceleration_support": { "default_value": 1000 }, - "acceleration_support_infill": { "default_value": 1000 }, - "acceleration_support_interface": { "default_value": 1000 }, - "acceleration_support_roof": { "default_value": 1000 }, - "acceleration_support_bottom": { "default_value": 1000 }, - "acceleration_prime_tower": { "default_value": 1000 }, - "acceleration_travel": { "default_value": 1500 }, - "acceleration_layer_0": { "default_value": 1000 }, - "acceleration_print_layer_0": { "default_value": 1000 }, - "acceleration_travel_layer_0": { "default_value": 1000 }, - "acceleration_skirt_brim": { "default_value": 1000 }, "jerk_print": { "default_value": 10 }, diff --git a/resources/definitions/fabtotum.def.json b/resources/definitions/fabtotum.def.json index 959a5bdaec..355f6a1434 100644 --- a/resources/definitions/fabtotum.def.json +++ b/resources/definitions/fabtotum.def.json @@ -50,8 +50,8 @@ "retraction_hop_enabled": { "default_value": false }, "material_final_print_temperature": { "value": "material_print_temperature - 5" }, "material_initial_print_temperature": { "value": "material_print_temperature" }, - "travel_avoid_distance": { "default_value": 1, "value": 1 }, - "speed_travel": { "default_value": 200, "value": 200 }, + "travel_avoid_distance": { "value": 1 }, + "speed_travel": { "value": 200 }, "speed_infill": { "value": "round(speed_print * 1.05, 0)" }, "speed_topbottom": { "value": "round(speed_print * 0.95, 0)" }, "speed_wall": { "value": "speed_print" }, diff --git a/resources/definitions/felixpro2dual.def.json b/resources/definitions/felixpro2dual.def.json index 0c978cdb71..fdd8a1b694 100644 --- a/resources/definitions/felixpro2dual.def.json +++ b/resources/definitions/felixpro2dual.def.json @@ -24,7 +24,6 @@ "layer_height": { "default_value": 0.15 }, "layer_height_0": { "default_value": 0.2 }, - "speed_layer_0": { "default_value": 20}, "infill_sparse_density": { "default_value": 20 }, "wall_thickness": { "default_value": 1 }, @@ -53,7 +52,6 @@ "machine_center_is_zero": { "default_value": false }, "speed_print": { "default_value": 80 }, - "speed_travel": { "default_value": 200 }, "retraction_amount": { "default_value": 1 }, "retraction_speed": { "default_value": 50}, diff --git a/resources/definitions/felixtec4dual.def.json b/resources/definitions/felixtec4dual.def.json index ba5bcfa112..efc13c1759 100644 --- a/resources/definitions/felixtec4dual.def.json +++ b/resources/definitions/felixtec4dual.def.json @@ -39,7 +39,6 @@ "machine_center_is_zero": { "default_value": false }, "speed_print": { "default_value": 60 }, - "speed_travel": { "default_value": 200 }, "retraction_amount": { "default_value": 1 }, "retraction_speed": { "default_value": 50}, diff --git a/resources/definitions/flsun_qq_s.def.json b/resources/definitions/flsun_qq_s.def.json index 5a739e9ae1..6b10a7f0cc 100644 --- a/resources/definitions/flsun_qq_s.def.json +++ b/resources/definitions/flsun_qq_s.def.json @@ -33,14 +33,8 @@ "z_seam_type": { "default_value": "back" }, - "top_thickness": { - "default_value": 5 - }, - "bottom_layers": { - "default_value": 4 - }, "gantry_height": { - "default_value": 0 + "value": "0" }, "machine_nozzle_size": { "default_value": 0.4 diff --git a/resources/definitions/geeetech_a30.def.json b/resources/definitions/geeetech_a30.def.json index 3d8823f438..52b6ad8f7f 100644 --- a/resources/definitions/geeetech_a30.def.json +++ b/resources/definitions/geeetech_a30.def.json @@ -42,9 +42,6 @@ "material_diameter": { "default_value": 1.75 }, - "material_bed_temperature": { - "default_value": 60 - }, "machine_nozzle_size": { "default_value": 0.4 }, @@ -60,12 +57,6 @@ "retraction_speed": { "default_value": 25 }, - "retraction_retract_speed": { - "default_value": 25 - }, - "retraction_prime_speed": { - "default_value": 25 - }, "adhesion_type": { "default_value": "skirt" }, @@ -86,7 +77,7 @@ ] }, "gantry_height": { - "default_value": 55 + "value": "55" }, "machine_max_feedrate_x": { "default_value": 300 diff --git a/resources/definitions/gmax15plus.def.json b/resources/definitions/gmax15plus.def.json index eb576f0e19..b5e0efe27c 100644 --- a/resources/definitions/gmax15plus.def.json +++ b/resources/definitions/gmax15plus.def.json @@ -39,7 +39,6 @@ "adhesion_type": { "default_value": "skirt" }, "gantry_height": { "value": "50" }, "speed_print": { "default_value": 50 }, - "speed_travel": { "default_value": 70 }, "machine_max_acceleration_x": { "default_value": 600 }, "machine_max_acceleration_y": { "default_value": 600 }, "machine_max_acceleration_z": { "default_value": 30 }, @@ -50,9 +49,7 @@ "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" }, "machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 ;Home X/Y/Z\nM104 S{material_print_temperature} ; Preheat\nM109 S{material_print_temperature} ; Preheat\nG91 ;relative positioning\nG90 ;absolute positioning\nG1 Z25.0 F9000 ;raise nozzle 25mm\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." }, "machine_end_gcode": { "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" }, - "material_print_temperature": { "default_value": 202 }, "wall_thickness": { "default_value": 1 }, - "top_bottom_thickness": { "default_value": 1 }, - "bottom_thickness": { "default_value": 1 } + "top_bottom_thickness": { "default_value": 1 } } } diff --git a/resources/definitions/gmax15plus_dual.def.json b/resources/definitions/gmax15plus_dual.def.json index 40a3dde303..89ffda490a 100644 --- a/resources/definitions/gmax15plus_dual.def.json +++ b/resources/definitions/gmax15plus_dual.def.json @@ -37,7 +37,6 @@ "adhesion_type": { "default_value": "skirt" }, "gantry_height": { "value": "50" }, "speed_print": { "default_value": 50 }, - "speed_travel": { "default_value": 70 }, "machine_max_acceleration_x": { "default_value": 600 }, "machine_max_acceleration_y": { "default_value": 600 }, "machine_max_acceleration_z": { "default_value": 30 }, @@ -48,9 +47,7 @@ "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" }, "machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 ;Home X/Y/Z\nM104 S{material_print_temperature} T0 ; Preheat Left Extruder\nM104 S{material_print_temperature} T1 ; Preheat Right Extruder\nM109 S{material_print_temperature} T0 ; Preheat Left Extruder\nM109 S{material_print_temperature} T1 ; Preheat Right Extruder\nG91 ;relative positioning\nG90 ;absolute positioning\nM218 T1 X34.3 Y0; Set 2nd extruder offset. This can be changed later if needed\nG1 Z25.0 F9000 ;raise nozzle 25mm\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." }, "machine_end_gcode": { "default_value": "M104 S0 T0;Left extruder off\nM104 S0 T1; Right extruder off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" }, - "material_print_temperature": { "default_value": 202 }, "wall_thickness": { "default_value": 1 }, - "top_bottom_thickness": { "default_value": 1 }, - "bottom_thickness": { "default_value": 1 } + "top_bottom_thickness": { "default_value": 1 } } } diff --git a/resources/definitions/helloBEEprusa.def.json b/resources/definitions/helloBEEprusa.def.json index 65716ac175..2c8c4839d0 100644 --- a/resources/definitions/helloBEEprusa.def.json +++ b/resources/definitions/helloBEEprusa.def.json @@ -26,28 +26,15 @@ "machine_height": { "default_value": 190 }, "machine_heated_bed": { "default_value": true }, "machine_center_is_zero": { "default_value": false }, - "material_print_temperature": { "default_value": 200 }, - "material_bed_temperature": { "default_value": 60 }, - "line_width": { "default_value": 0.48 }, "layer_height": { "default_value": 0.2 }, "layer_height_0": { "default_value": 0.2 }, - "wall_line_count": { "default_value": 3 }, "wall_thickness": { "default_value": 1.2 }, "top_bottom_thickness": { "default_value": 1.2 }, "infill_sparse_density": { "default_value": 20 }, - "infill_overlap": { "default_value": 15 }, "speed_print": { "default_value": 60 }, - "speed_travel": { "default_value": 160 }, - "speed_layer_0": { "default_value": 30 }, - "speed_wall_x": { "default_value": 35 }, - "speed_wall_0": { "default_value": 30 }, - "speed_infill": { "default_value": 60 }, - "speed_topbottom": { "default_value": 20 }, - "skirt_brim_speed": { "default_value": 35 }, "skirt_line_count": { "default_value": 4 }, "skirt_brim_minimal_length": { "default_value": 30 }, "skirt_gap": { "default_value": 6 }, - "cool_fan_full_at_height": { "default_value": 0.4 }, "retraction_speed": { "default_value": 15.0}, "retraction_amount": { "default_value": 1.5} } diff --git a/resources/definitions/innovo_inventor.def.json b/resources/definitions/innovo_inventor.def.json index 72a9ec3edb..13a8a7c59b 100644 --- a/resources/definitions/innovo_inventor.def.json +++ b/resources/definitions/innovo_inventor.def.json @@ -61,36 +61,10 @@ "top_bottom_thickness": { "default_value": 1.2 }, - "material_print_temperature": { - "default_value": 205 - }, - "material_bed_temperature": { - "default_value": 60 - }, "speed_print": { "default_value": 50 }, - "speed_wall_0": { - "default_value": 25 - }, - "speed_wall_x": { - "default_value": 40 - }, - "speed_infill": { - "default_value": 80 - }, - "speed_topbottom": { - "default_value": 30 - }, - "speed_support_interface": - { - "default_value": 20 - }, - "speed_travel": { - "default_value": 150 - }, "speed_layer_0": { - "default_value": 30.0, "minimum_value": 0.1 } } diff --git a/resources/definitions/jgaurora_a1.def.json b/resources/definitions/jgaurora_a1.def.json index 3c9f9c61e9..1c910f0d95 100644 --- a/resources/definitions/jgaurora_a1.def.json +++ b/resources/definitions/jgaurora_a1.def.json @@ -47,12 +47,6 @@ "material_diameter": { "default_value": 1.75 }, - "material_print_temperature": { - "default_value": 215 - }, - "material_bed_temperature": { - "default_value": 67 - }, "layer_height_0": { "default_value": 0.12 }, @@ -62,21 +56,6 @@ "speed_print": { "default_value": 40 }, - "speed_infill": { - "default_value": 40 - }, - "speed_wall": { - "default_value": 35 - }, - "speed_topbottom": { - "default_value": 35 - }, - "speed_travel": { - "default_value": 120 - }, - "speed_layer_0": { - "default_value": 12 - }, "support_enable": { "default_value": true }, diff --git a/resources/definitions/jgaurora_a3s.def.json b/resources/definitions/jgaurora_a3s.def.json index bd8d0bd0e3..ead0a5f9e7 100644 --- a/resources/definitions/jgaurora_a3s.def.json +++ b/resources/definitions/jgaurora_a3s.def.json @@ -47,12 +47,6 @@ "material_diameter": { "default_value": 1.75 }, - "material_print_temperature": { - "default_value": 210 - }, - "material_bed_temperature": { - "default_value": 65 - }, "layer_height_0": { "default_value": 0.12 }, @@ -62,21 +56,6 @@ "speed_print": { "default_value": 35 }, - "speed_infill": { - "default_value": 40 - }, - "speed_wall": { - "default_value": 30 - }, - "speed_topbottom": { - "default_value": 20 - }, - "speed_travel": { - "default_value": 100 - }, - "speed_layer_0": { - "default_value": 12 - }, "support_enable": { "default_value": true }, diff --git a/resources/definitions/jgaurora_a5.def.json b/resources/definitions/jgaurora_a5.def.json index e02fca881b..b9f179d38e 100644 --- a/resources/definitions/jgaurora_a5.def.json +++ b/resources/definitions/jgaurora_a5.def.json @@ -49,12 +49,6 @@ "material_diameter": { "default_value": 1.75 }, - "material_print_temperature": { - "default_value": 215 - }, - "material_bed_temperature": { - "default_value": 67 - }, "layer_height_0": { "default_value": 0.12 }, @@ -64,21 +58,6 @@ "speed_print": { "default_value": 40 }, - "speed_infill": { - "default_value": 40 - }, - "speed_wall": { - "default_value": 35 - }, - "speed_topbottom": { - "default_value": 35 - }, - "speed_travel": { - "default_value": 120 - }, - "speed_layer_0": { - "default_value": 12 - }, "support_enable": { "default_value": true }, diff --git a/resources/definitions/jgaurora_jgmaker_magic.def.json b/resources/definitions/jgaurora_jgmaker_magic.def.json index 703305151a..8d0349a48c 100644 --- a/resources/definitions/jgaurora_jgmaker_magic.def.json +++ b/resources/definitions/jgaurora_jgmaker_magic.def.json @@ -47,12 +47,6 @@ "material_diameter": { "default_value": 1.75 }, - "material_print_temperature": { - "default_value": 200 - }, - "material_bed_temperature": { - "default_value": 60 - }, "layer_height_0": { "default_value": 0.2 }, @@ -62,21 +56,6 @@ "speed_print": { "default_value": 60 }, - "speed_infill": { - "default_value": 60 - }, - "speed_wall": { - "default_value": 30 - }, - "speed_topbottom": { - "default_value": 45 - }, - "speed_travel": { - "default_value": 125 - }, - "speed_layer_0": { - "default_value": 30 - }, "support_enable": { "default_value": true }, diff --git a/resources/definitions/jgaurora_z_603s.def.json b/resources/definitions/jgaurora_z_603s.def.json index ceade3243a..8dbf5a82bb 100644 --- a/resources/definitions/jgaurora_z_603s.def.json +++ b/resources/definitions/jgaurora_z_603s.def.json @@ -22,7 +22,7 @@ }, "machine_end_gcode": { "default_value": "; -- END GCODE --\nM104 S0 ;turn off nozzle heater\nM140 S0 ;turn off bed heater\nG91 ;set to relative positioning\nG1 E-10 F300 ;retract the filament slightly\nG90 ;set to absolute positioning\nG28 X0 Y0 F600 ;move to the X/Y-axis origin (Home)\nM84 ;turn off stepper motors\n; -- end of END GCODE --" - }, + }, "machine_width": { "default_value": 280 }, @@ -47,12 +47,6 @@ "material_diameter": { "default_value": 1.75 }, - "material_print_temperature": { - "default_value": 210 - }, - "material_bed_temperature": { - "default_value": 55 - }, "layer_height_0": { "default_value": 0.2 }, @@ -62,21 +56,6 @@ "speed_print": { "default_value": 60 }, - "speed_infill": { - "default_value": 60 - }, - "speed_wall": { - "default_value": 30 - }, - "speed_topbottom": { - "default_value": 45 - }, - "speed_travel": { - "default_value": 125 - }, - "speed_layer_0": { - "default_value": 20 - }, "support_enable": { "default_value": true }, diff --git a/resources/definitions/julia.def.json b/resources/definitions/julia.def.json index 62e4170c1f..15e5057a55 100644 --- a/resources/definitions/julia.def.json +++ b/resources/definitions/julia.def.json @@ -21,25 +21,14 @@ "machine_end_gcode": { "default_value": " M104 S0 ;extruder heater off\n M140 S0 ;heated bed heater off (if you have it)\n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning\n" }, - "material_bed_temperature": { "default_value": 100 }, "layer_height": { "default_value": 0.2 }, "support_angle": { "default_value": 30 }, - "infill_overlap": { "default_value": 30 }, "layer_height_0": { "default_value": 0.2 }, "speed_print": { "default_value": 80 }, - "speed_wall_0": { "default_value": 30 }, - "speed_travel": { "default_value": 150 }, - "brim_line_count": { "default_value": 15 }, - "skin_overlap": { "default_value": 30 }, "prime_tower_size": { "default_value": 8.660254037844387 }, - "bottom_thickness": { "default_value": 0.8 }, "retraction_amount": { "default_value": 3 }, - "speed_topbottom": { "default_value": 80 }, - "material_print_temperature": { "default_value": 230 }, "support_pattern": { "default_value": "grid" }, - "speed_infill": { "default_value": 80 }, "infill_sparse_density": { "default_value": 10 }, - "top_thickness": { "default_value": 0.8 }, "machine_extruder_count": { "default_value": 1 }, "retraction_combing": { "default_value": "off" }, "machine_heated_bed": { "default_value": true }, diff --git a/resources/definitions/makeit_pro_l.def.json b/resources/definitions/makeit_pro_l.def.json index 5d09189de8..d601a5c309 100644 --- a/resources/definitions/makeit_pro_l.def.json +++ b/resources/definitions/makeit_pro_l.def.json @@ -77,27 +77,12 @@ "retraction_amount": { "default_value": 6 }, - "retraction_min_travel": { - "default_value": 1.5 - }, - "speed_travel": { - "default_value": 150 - }, "speed_print": { "default_value": 60 }, "wall_thickness": { "default_value": 1.2 }, - "bottom_thickness": { - "default_value": 0.2 - }, - "speed_layer_0": { - "default_value": 20 - }, - "speed_print_layer_0": { - "default_value": 20 - }, "cool_min_layer_time_fan_speed_max": { "default_value": 5 }, diff --git a/resources/definitions/makeit_pro_m.def.json b/resources/definitions/makeit_pro_m.def.json index 57e2a7dbd4..267646b647 100644 --- a/resources/definitions/makeit_pro_m.def.json +++ b/resources/definitions/makeit_pro_m.def.json @@ -77,27 +77,12 @@ "retraction_amount": { "default_value": 6 }, - "retraction_min_travel": { - "default_value": 1.5 - }, - "speed_travel": { - "default_value": 150 - }, "speed_print": { "default_value": 60 }, "wall_thickness": { "default_value": 1.2 }, - "bottom_thickness": { - "default_value": 0.2 - }, - "speed_layer_0": { - "default_value": 20 - }, - "speed_print_layer_0": { - "default_value": 20 - }, "cool_min_layer_time_fan_speed_max": { "default_value": 5 }, diff --git a/resources/definitions/maker_starter.def.json b/resources/definitions/maker_starter.def.json index 560e53ccb9..96dca118af 100644 --- a/resources/definitions/maker_starter.def.json +++ b/resources/definitions/maker_starter.def.json @@ -53,57 +53,15 @@ "layer_height_0": { "default_value": 0.2 }, - "wall_line_count": { - "default_value": 2 - }, - "top_layers": { - "default_value": 4 - }, - "bottom_layers": { - "default_value": 4 - }, "speed_print": { "default_value": 50 }, - "speed_wall": { - "default_value": 30 - }, - "speed_wall_0": { - "default_value": 30 - }, - "speed_wall_x": { - "default_value": 30 - }, - "speed_topbottom": { - "default_value": 50 - }, - "speed_support": { - "default_value": 50 - }, - "speed_travel": { - "default_value": 120 - }, - "speed_layer_0": { - "default_value": 20 - }, - "skirt_brim_speed": { - "default_value": 15 - }, "speed_slowdown_layers": { "default_value": 4 }, "infill_sparse_density": { "default_value": 20 }, - "cool_fan_speed_min": { - "default_value": 50 - }, - "cool_fan_speed_max": { - "default_value": 100 - }, - "cool_fan_full_layer": { - "default_value": 4 - }, "cool_min_layer_time": { "default_value": 5 }, @@ -122,12 +80,6 @@ "support_z_distance": { "default_value": 0.2 }, - "support_top_distance": { - "default_value": 0.2 - }, - "support_bottom_distance": { - "default_value": 0.24 - }, "support_pattern": { "default_value": "ZigZag" }, @@ -140,24 +92,6 @@ "skirt_brim_minimal_length": { "default_value": 100 }, - "raft_base_line_spacing": { - "default_value": 2 - }, - "raft_base_thickness": { - "default_value": 0.3 - }, - "raft_base_line_width": { - "default_value": 2 - }, - "raft_base_speed": { - "default_value": 15 - }, - "raft_interface_thickness": { - "default_value": 0.24 - }, - "raft_interface_line_width": { - "default_value": 0.6 - }, "raft_airgap": { "default_value": 0.2 }, diff --git a/resources/definitions/makerbotreplicator.def.json b/resources/definitions/makerbotreplicator.def.json index 3b02215e74..24b556e1ee 100644 --- a/resources/definitions/makerbotreplicator.def.json +++ b/resources/definitions/makerbotreplicator.def.json @@ -18,9 +18,7 @@ "overrides": { "prime_tower_size": { "default_value": 10.0 }, "infill_sparse_density": { "default_value": 10 }, - "speed_travel": { "default_value": 150 }, "layer_height": { "default_value": 0.15 }, - "material_print_temperature": { "default_value": 220 }, "machine_extruder_count": { "default_value": 1 }, "machine_heated_bed": { "default_value": true }, "machine_center_is_zero": { "default_value": false }, diff --git a/resources/definitions/malyan_m200.def.json b/resources/definitions/malyan_m200.def.json index 71c94184b2..13ad07ccae 100644 --- a/resources/definitions/malyan_m200.def.json +++ b/resources/definitions/malyan_m200.def.json @@ -30,8 +30,6 @@ "speed_wall_x": { "value": "speed_print" }, "speed_support": { "value": "speed_wall_0" }, "speed_layer_0": { "value": "round(speed_print / 2.0, 2)" }, - "speed_travel": { "default_value": 50 }, - "speed_travel_layer_0": { "default_value": 40 }, "speed_infill": { "value": "speed_print" }, "speed_topbottom": {"value": "speed_print / 2"}, diff --git a/resources/definitions/mankati_fullscale_xt_plus.def.json b/resources/definitions/mankati_fullscale_xt_plus.def.json index 104be7091b..b6fa040750 100644 --- a/resources/definitions/mankati_fullscale_xt_plus.def.json +++ b/resources/definitions/mankati_fullscale_xt_plus.def.json @@ -41,23 +41,15 @@ "layer_height": { "default_value": 0.2 }, "wall_thickness": { "default_value": 0.8 }, "top_bottom_thickness": { "default_value": 0.3 }, - "material_print_temperature": { "default_value": 195 }, - "material_bed_temperature": { "default_value": 60 }, "retraction_enable": { "default_value": true }, "retraction_speed": { "default_value": 50 }, "retraction_amount": { "default_value": 0.8 }, "retraction_hop": { "default_value": 0.075 }, "speed_print": { "default_value": 60 }, - "speed_infill": { "default_value": 100 }, - "speed_topbottom": { "default_value": 15 }, - "speed_travel": { "default_value": 150 }, "speed_layer_0": { - "minimum_value": "0.1", - "default_value": 15.0 + "minimum_value": "0.1" }, - "infill_overlap": { "default_value": 10 }, "cool_fan_enabled": { "default_value": false }, - "cool_fan_speed": { "default_value": 0 }, "skirt_line_count": { "default_value": 3 }, "skirt_gap": { "default_value": 4 }, "skirt_brim_minimal_length": { "default_value": 200 } diff --git a/resources/definitions/ord.def.json b/resources/definitions/ord.def.json index de410b0d58..4a550602f2 100644 --- a/resources/definitions/ord.def.json +++ b/resources/definitions/ord.def.json @@ -19,12 +19,9 @@ }, "overrides": { - "material_bed_temperature": { "default_value": 60 }, "prime_tower_size": { "default_value": 7.0710678118654755 }, "infill_sparse_density": { "default_value": 15 }, - "speed_travel": { "default_value": 150 }, "layer_height": { "default_value": 0.3 }, - "material_print_temperature": { "default_value": 240 }, "machine_extruder_count": { "default_value": 5 }, "machine_heated_bed": { "default_value": true }, "machine_center_is_zero": { "default_value": false }, diff --git a/resources/definitions/printrbot_play.def.json b/resources/definitions/printrbot_play.def.json index b8879e825c..bf52363800 100644 --- a/resources/definitions/printrbot_play.def.json +++ b/resources/definitions/printrbot_play.def.json @@ -29,7 +29,6 @@ "machine_head_with_fans_polygon": { "default_value": [[-32,999],[37,999],[37,-32],[-32,-32]] }, "gantry_height": { "value": "55" }, "speed_print": { "default_value": 50 }, - "speed_travel": { "default_value": 55 }, "machine_max_feedrate_x": {"default_value": 125}, "machine_max_feedrate_y": {"default_value": 125}, "machine_max_feedrate_z": { "default_value": 5 }, diff --git a/resources/definitions/prusa_i3_mk2.def.json b/resources/definitions/prusa_i3_mk2.def.json index ff6f4469e7..5ae541049d 100644 --- a/resources/definitions/prusa_i3_mk2.def.json +++ b/resources/definitions/prusa_i3_mk2.def.json @@ -22,13 +22,10 @@ "machine_height": { "default_value": 200 }, "machine_depth": { "default_value": 210 }, "machine_center_is_zero": { "default_value": false }, - "material_bed_temperature": { "default_value": 55 }, "layer_height": { "default_value": 0.1 }, "layer_height_0": { "default_value": 0.15 }, "retraction_amount": { "default_value": 0.8 }, "retraction_speed": { "default_value": 35 }, - "retraction_retract_speed": { "default_value": 35 }, - "retraction_prime_speed": { "default_value": 35 }, "adhesion_type": { "default_value": "skirt" }, "machine_head_with_fans_polygon": { "default_value": [[-31,31],[34,31],[34,-40],[-31,-40]] }, "gantry_height": { "value": "28" }, diff --git a/resources/definitions/punchtec_connect_xl.def.json b/resources/definitions/punchtec_connect_xl.def.json index 1efdd226fd..b262daa445 100644 --- a/resources/definitions/punchtec_connect_xl.def.json +++ b/resources/definitions/punchtec_connect_xl.def.json @@ -17,15 +17,9 @@ "overrides": { "machine_head_polygon": { "default_value": [[ 0, 0], [ 0, 0], [ 0, 0], [ 0, 0]] }, - "speed_travel": { "default_value": 150 }, "prime_tower_size": { "default_value": 8.660254037844387 }, - "speed_wall_x": { "default_value": 40 }, - "speed_wall_0": { "default_value": 40 }, - "speed_topbottom": { "default_value": 40 }, "layer_height": { "default_value": 0.2 }, - "material_print_temperature": { "default_value": 195 }, "speed_print": { "default_value": 40 }, - "speed_infill": { "default_value": 40 }, "machine_extruder_count": { "default_value": 2 }, "machine_heated_bed": { "default_value": true }, "machine_center_is_zero": { "default_value": false }, diff --git a/resources/definitions/rigid3d.def.json b/resources/definitions/rigid3d.def.json index 43ffd6924a..a66559b393 100644 --- a/resources/definitions/rigid3d.def.json +++ b/resources/definitions/rigid3d.def.json @@ -25,23 +25,13 @@ "skirt_gap": { "default_value": 5.0 }, "cool_min_layer_time": { "default_value": 10 }, "prime_tower_size": { "default_value": 7.745966692414834 }, - "speed_wall_x": { "default_value": 40 }, - "speed_travel": { "default_value": 100 }, - "bottom_thickness": { "default_value": 0.75 }, "layer_height_0": { "default_value": 0.25 }, "support_angle": { "default_value": 45 }, - "material_bed_temperature": { "default_value": 100 }, - "top_thickness": { "default_value": 0.75 }, - "material_print_temperature": { "default_value": 235 }, "retraction_speed": { "default_value": 60.0 }, "wall_thickness": { "default_value": 0.8 }, - "retraction_min_travel": { "default_value": 2 }, - "speed_wall_0": { "default_value": 30 }, "retraction_amount": { "default_value": 1 }, - "speed_topbottom": { "default_value": 30 }, "layer_height": { "default_value": 0.25 }, "speed_print": { "default_value": 40 }, - "speed_infill": { "default_value": 40 }, "machine_extruder_count": { "default_value": 1 }, "machine_heated_bed": { "default_value": true }, "machine_center_is_zero": { "default_value": false }, diff --git a/resources/definitions/rigid3d_3rdgen.def.json b/resources/definitions/rigid3d_3rdgen.def.json index bb3414b75d..b4d0252075 100644 --- a/resources/definitions/rigid3d_3rdgen.def.json +++ b/resources/definitions/rigid3d_3rdgen.def.json @@ -25,20 +25,12 @@ "cool_min_layer_time": { "default_value": 10 }, "prime_tower_size": { "default_value": 7.745966692414834 }, "skirt_gap": { "default_value": 5.0 }, - "speed_travel": { "default_value": 120 }, - "bottom_thickness": { "default_value": 0.75 }, "layer_height_0": { "default_value": 0.25 }, "support_angle": { "default_value": 45 }, - "material_bed_temperature": { "default_value": 100 }, - "retraction_min_travel": { "default_value": 2 }, - "speed_wall_0": { "default_value": 30 }, "retraction_speed": { "default_value": 60.0 }, "wall_thickness": { "default_value": 0.8 }, - "material_print_temperature": { "default_value": 235 }, "retraction_amount": { "default_value": 1 }, - "speed_topbottom": { "default_value": 25 }, "layer_height": { "default_value": 0.25 }, - "top_thickness": { "default_value": 0.75 }, "machine_extruder_count": { "default_value": 1 }, "machine_heated_bed": { "default_value": true }, "machine_center_is_zero": { "default_value": false }, diff --git a/resources/definitions/rigid3d_hobby.def.json b/resources/definitions/rigid3d_hobby.def.json index db48195fe0..f50df0c47d 100644 --- a/resources/definitions/rigid3d_hobby.def.json +++ b/resources/definitions/rigid3d_hobby.def.json @@ -17,25 +17,17 @@ "overrides": { "machine_head_polygon": { "default_value": [[ 16, 30], [ 16, 45], [ 16, 45], [ 16, 30]] }, "prime_tower_size": { "default_value": 8.660254037844387 }, - "speed_travel": { "default_value": 40 }, "skirt_gap": { "default_value": 5.0 }, "cool_min_layer_time": { "default_value": 15 }, "support_pattern": { "default_value": "grid" }, "layer_height_0": { "default_value": 0.25 }, - "speed_wall_x": { "default_value": 30 }, "skirt_line_count": { "default_value": 2 }, "support_angle": { "default_value": 45 }, - "speed_topbottom": { "default_value": 20 }, - "material_print_temperature": { "default_value": 205 }, "retraction_speed": { "default_value": 80 }, "wall_thickness": { "default_value": 0.8 }, - "retraction_min_travel": { "default_value": 2 }, - "speed_wall_0": { "default_value": 20 }, "retraction_amount": { "default_value": 2 }, - "speed_layer_0": { "default_value": 15 }, "layer_height": { "default_value": 0.2 }, "speed_print": { "default_value": 30 }, - "speed_infill": { "default_value": 30 }, "machine_extruder_count": { "default_value": 1 }, "machine_heated_bed": { "default_value": false }, "machine_center_is_zero": { "default_value": false }, diff --git a/resources/definitions/rigid3d_mucit.def.json b/resources/definitions/rigid3d_mucit.def.json index 42cd99a3bd..75853fab8b 100644 --- a/resources/definitions/rigid3d_mucit.def.json +++ b/resources/definitions/rigid3d_mucit.def.json @@ -76,14 +76,9 @@ "default_value": true }, "cool_fan_speed": { - "default_value": 100, "value": "100" }, - "cool_fan_speed_min": { - "default_value": 0 - }, "cool_fan_full_at_height": { - "default_value": 0.5, "value": "0.5" }, "support_z_distance": { diff --git a/resources/definitions/rigid3d_zero.def.json b/resources/definitions/rigid3d_zero.def.json index f55f913a56..64909630d2 100644 --- a/resources/definitions/rigid3d_zero.def.json +++ b/resources/definitions/rigid3d_zero.def.json @@ -24,21 +24,11 @@ "machine_head_polygon": { "default_value": [[ 40, 15], [ 40, 60], [ 30, 60], [ 30, 15]] }, "support_pattern": { "default_value": "grid" }, "cool_min_layer_time": { "default_value": 10 }, - "speed_travel": { "default_value": 80 }, "support_angle": { "default_value": 45 }, - "retraction_min_travel": { "default_value": 2 }, - "speed_wall_0": { "default_value": 20 }, - "speed_layer_0": { "default_value": 15 }, - "speed_infill": { "default_value": 30 }, - "speed_topbottom": { "default_value": 30 }, "prime_tower_size": { "default_value": 7.745966692414834 }, "skirt_line_count": { "default_value": 2 }, - "speed_wall_x": { "default_value": 30 }, - "bottom_thickness": { "default_value": 0.75 }, "layer_height_0": { "default_value": 0.25 }, - "top_thickness": { "default_value": 0.75 }, "wall_thickness": { "default_value": 0.8 }, - "material_print_temperature": { "default_value": 195 }, "retraction_amount": { "default_value": 1.5 }, "skirt_gap": { "default_value": 5.0 }, "layer_height": { "default_value": 0.25 }, diff --git a/resources/definitions/rigid3d_zero2.def.json b/resources/definitions/rigid3d_zero2.def.json index f24c869636..cc922769f7 100644 --- a/resources/definitions/rigid3d_zero2.def.json +++ b/resources/definitions/rigid3d_zero2.def.json @@ -44,9 +44,6 @@ "material_print_temperature": { "value": 235 }, - "material_bed_temperature": { - "default_value": 100 - }, "speed_print": { "default_value": 40 }, @@ -55,7 +52,7 @@ }, "speed_travel": { "value": 100 - }, + }, "support_enable": { "default_value": false }, @@ -90,14 +87,9 @@ "default_value": false }, "cool_fan_speed": { - "default_value": 50, "value": 50 }, - "cool_fan_speed_min": { - "default_value": 0 - }, "cool_fan_full_at_height": { - "default_value": 1.0, "value": 1.0 }, "support_z_distance": { diff --git a/resources/definitions/rigidbot.def.json b/resources/definitions/rigidbot.def.json index c04cd7c5e6..d6fb4f1651 100644 --- a/resources/definitions/rigidbot.def.json +++ b/resources/definitions/rigidbot.def.json @@ -49,37 +49,15 @@ "top_bottom_thickness": { "default_value": 0.3 }, - "material_print_temperature": { - "default_value": 195 - }, - "material_bed_temperature": { - "default_value": 60 - }, "speed_print": { "default_value": 60 }, - "speed_infill": { - "default_value": 100 - }, - "speed_topbottom": { - "default_value": 15 - }, - "speed_travel": { - "default_value": 150 - }, "speed_layer_0": { - "default_value": 15, "minimum_value": "0.1" }, - "infill_overlap": { - "default_value": 10 - }, "cool_fan_enabled": { "default_value": false }, - "cool_fan_speed": { - "default_value": 0 - }, "skirt_line_count": { "default_value": 3 }, diff --git a/resources/definitions/rigidbot_big.def.json b/resources/definitions/rigidbot_big.def.json index c97c6df9f3..9568417acc 100644 --- a/resources/definitions/rigidbot_big.def.json +++ b/resources/definitions/rigidbot_big.def.json @@ -49,37 +49,15 @@ "top_bottom_thickness": { "default_value": 0.3 }, - "material_print_temperature": { - "default_value": 195 - }, - "material_bed_temperature": { - "default_value": 60 - }, "speed_print": { "default_value": 60 }, - "speed_infill": { - "default_value": 100 - }, - "speed_topbottom": { - "default_value": 15 - }, - "speed_travel": { - "default_value": 150 - }, "speed_layer_0": { - "default_value": 15, "minimum_value": "0.1" }, - "infill_overlap": { - "default_value": 10 - }, "cool_fan_enabled": { "default_value": false }, - "cool_fan_speed": { - "default_value": 0 - }, "skirt_line_count": { "default_value": 3 }, diff --git a/resources/definitions/robo_3d_r1.def.json b/resources/definitions/robo_3d_r1.def.json index 8d7698e198..36b8addd27 100644 --- a/resources/definitions/robo_3d_r1.def.json +++ b/resources/definitions/robo_3d_r1.def.json @@ -22,28 +22,16 @@ "default_value": " M104 S0 ;extruder heater off\n M140 S0 ;heated bed heater off (if you have it)\n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning\n" }, "cool_min_layer_time": { "default_value": 7 }, - "speed_topbottom": { "default_value": 40 }, "retraction_speed": { "default_value": 50 }, - "layer_0_z_overlap": { "default_value": 0.2 }, "cool_min_speed": { "default_value": 19 }, - "material_bed_temperature": { "default_value": 60 }, "support_angle": { "default_value": 50 }, - "speed_layer_0": { "default_value": 30 }, - "line_width": { "default_value": 0.4 }, - "speed_infill": { "default_value": 60 }, "prime_tower_size": { "default_value": 8.660254037844387 }, "support_enable": { "default_value": true }, - "cool_fan_full_at_height": { "default_value": 0.1 }, - "bottom_thickness": { "default_value": 1.2 }, "raft_airgap": { "default_value": 0.2 }, "layer_height_0": { "default_value": 0.15 }, - "top_thickness": { "default_value": 1.2 }, - "speed_wall_0": { "default_value": 40 }, - "retraction_min_travel": { "default_value": 5 }, "material_flow": { "default_value": 100 }, "infill_sparse_density": { "default_value": 10 }, "wall_thickness": { "default_value": 1.2 }, - "material_print_temperature": { "default_value": 190 }, "retraction_amount": { "default_value": 3 }, "layer_height": { "default_value": 0.2 }, "speed_print": { "default_value": 40 }, diff --git a/resources/definitions/seemecnc_artemis.def.json b/resources/definitions/seemecnc_artemis.def.json index ec92f528d7..88c1d84b3d 100644 --- a/resources/definitions/seemecnc_artemis.def.json +++ b/resources/definitions/seemecnc_artemis.def.json @@ -27,13 +27,11 @@ "machine_name": { "default_value": "Artemis" }, "machine_shape": { "default_value": "elliptic" }, "machine_width": { "default_value": 290 }, - "relative_extrusion": { "default_value": false }, + "relative_extrusion": { "value": "False" }, "retraction_amount": { "default_value": 3.2 }, "retraction_combing": { "default_value": "off" }, "retraction_hop_enabled": { "default_value": true }, "retraction_hop_only_when_collides": { "default_value": false }, - "retraction_prime_speed": { "default_value": 45 }, - "retraction_retract_speed": { "default_value": 45 }, "retraction_speed": { "default_value": 45 }, "machine_start_gcode": { "default_value": "G28\nG1 Z15.0 F10000\nG92 E0" diff --git a/resources/definitions/seemecnc_v32.def.json b/resources/definitions/seemecnc_v32.def.json index d4316c25d9..0f49410116 100644 --- a/resources/definitions/seemecnc_v32.def.json +++ b/resources/definitions/seemecnc_v32.def.json @@ -27,13 +27,11 @@ "machine_name": { "default_value": "Rostock Max V3.2" }, "machine_shape": { "default_value": "elliptic" }, "machine_width": { "default_value": 265 }, - "relative_extrusion": { "default_value": false }, + "relative_extrusion": { "value": "False" }, "retraction_amount": { "default_value": 3.2 }, "retraction_combing": { "default_value": "off" }, "retraction_hop_enabled": { "default_value": true }, "retraction_hop_only_when_collides": { "default_value": false }, - "retraction_prime_speed": { "default_value": 45 }, - "retraction_retract_speed": { "default_value": 45 }, "retraction_speed": { "default_value": 45 }, "machine_start_gcode": { "default_value": "G28\nG1 Z15.0 F10000\nG92 E0" diff --git a/resources/definitions/strateo3d.def.json b/resources/definitions/strateo3d.def.json index a3710fb9af..4ae8473285 100644 --- a/resources/definitions/strateo3d.def.json +++ b/resources/definitions/strateo3d.def.json @@ -32,7 +32,7 @@ "machine_heated_bed": { "default_value": true }, "machine_center_is_zero": { "default_value": false }, "machine_head_with_fans_polygon": { "default_value": [ [ -76, -51.8 ] , [ 25, -51.8 ] , [ 25, 38.2 ] , [ -76, 38.2 ] ] }, - "gantry_height": { "default_value": 40 }, + "gantry_height": { "value": "40" }, "machine_extruder_count": { "default_value": 2 }, "machine_gcode_flavor": { "default_value": "Marlin" }, "machine_start_gcode": { "default_value": "G28 \nG90 G1 X300 Y210 Z15 F6000 \nG92 E0" }, diff --git a/resources/definitions/structur3d_discov3ry1_complete_um2plus.def.json b/resources/definitions/structur3d_discov3ry1_complete_um2plus.def.json index a7f4b7e549..e4893cacac 100644 --- a/resources/definitions/structur3d_discov3ry1_complete_um2plus.def.json +++ b/resources/definitions/structur3d_discov3ry1_complete_um2plus.def.json @@ -55,9 +55,6 @@ "line_width": { "value": "round(machine_nozzle_size * 0.875, 2)" }, - "speed_layer_0": { - "default_value": 10 - }, "speed_support": { "value": "speed_wall_0" }, diff --git a/resources/definitions/tam.def.json b/resources/definitions/tam.def.json index 67a4bb8eab..211049ca3d 100644 --- a/resources/definitions/tam.def.json +++ b/resources/definitions/tam.def.json @@ -37,7 +37,6 @@ "machine_center_is_zero": { "default_value": false }, "speed_print": { "default_value": 60 }, - "speed_travel": { "default_value": 200 }, "retraction_amount": { "default_value": 0.4 }, "retraction_speed": { "default_value": 35}, diff --git a/resources/definitions/tizyx_evy.def.json b/resources/definitions/tizyx_evy.def.json index f92f679677..57c7337196 100644 --- a/resources/definitions/tizyx_evy.def.json +++ b/resources/definitions/tizyx_evy.def.json @@ -50,13 +50,8 @@ "fill_outline_gaps": { "default_value": true}, "infill_sparse_density": { "default_value": 15}, "retraction_amount": { "default_value": 2.5}, - "retraction_min_travel": { "default_value": 2}, "retraction_speed": { "default_value": 30}, "speed_print": { "default_value": 60}, - "speed_topbottom": { "default_value": 50}, - "speed_wall_0": { "default_value": 40}, - "top_layers": { "default_value": 4}, - "wall_line_count": { "default_value": 2}, "cool_min_layer_time": { "default_value": 11}, "layer_height": { "maximum_value": "(0.8 * min(extruderValues('machine_nozzle_size')))" }, "layer_height_0": { "maximum_value": "(0.8 * min(extruderValues('machine_nozzle_size')))" }, diff --git a/resources/definitions/ubuild-3d_mr_bot_280.def.json b/resources/definitions/ubuild-3d_mr_bot_280.def.json index 060752387b..5157befc10 100644 --- a/resources/definitions/ubuild-3d_mr_bot_280.def.json +++ b/resources/definitions/ubuild-3d_mr_bot_280.def.json @@ -24,12 +24,9 @@ "machine_height": { "default_value": 275 }, "machine_depth": { "default_value": 275 }, "machine_center_is_zero": { "default_value": false }, - "material_bed_temperature": { "default_value": 70 }, "layer_height_0": { "default_value": 0.1 }, "retraction_amount": { "default_value": 2 }, "retraction_speed": { "default_value": 50 }, - "retraction_retract_speed": { "default_value": 50 }, - "retraction_prime_speed": { "default_value": 30 }, "adhesion_type": { "default_value": "skirt" }, "machine_nozzle_heat_up_speed": { "default_value": 2 }, "machine_nozzle_cool_down_speed": { "default_value": 2 }, diff --git a/resources/definitions/ultimaker2.def.json b/resources/definitions/ultimaker2.def.json index bb1ab13196..40fbdaf709 100644 --- a/resources/definitions/ultimaker2.def.json +++ b/resources/definitions/ultimaker2.def.json @@ -88,9 +88,6 @@ }, "machine_acceleration": { "default_value": 3000 - }, - "machine_nozzle_temp_enabled": { - "default_value": false } } } diff --git a/resources/definitions/ultimaker2_plus.def.json b/resources/definitions/ultimaker2_plus.def.json index 65ee8f063b..633e50bdba 100644 --- a/resources/definitions/ultimaker2_plus.def.json +++ b/resources/definitions/ultimaker2_plus.def.json @@ -37,9 +37,6 @@ "line_width": { "value": "round(machine_nozzle_size * 0.875, 2)" }, - "speed_layer_0": { - "default_value": 20 - }, "speed_support": { "value": "speed_wall_0" }, diff --git a/resources/definitions/vertex_k8400.def.json b/resources/definitions/vertex_k8400.def.json index 6bba095978..dad50cffe8 100644 --- a/resources/definitions/vertex_k8400.def.json +++ b/resources/definitions/vertex_k8400.def.json @@ -20,12 +20,6 @@ "machine_heated_bed": { "default_value": true }, - "material_bed_temperature": { - "default_value": 0 - }, - "material_bed_temperature_layer_0": { - "default_value": 0 - }, "machine_width": { "default_value": 200 }, diff --git a/resources/definitions/vertex_k8400_dual.def.json b/resources/definitions/vertex_k8400_dual.def.json index 9d014b9cf8..f5c4921cfc 100644 --- a/resources/definitions/vertex_k8400_dual.def.json +++ b/resources/definitions/vertex_k8400_dual.def.json @@ -18,12 +18,6 @@ "machine_heated_bed": { "default_value": true }, - "material_bed_temperature": { - "default_value": 0 - }, - "material_bed_temperature_layer_0": { - "default_value": 0 - }, "machine_width": { "default_value": 223.7 }, diff --git a/resources/definitions/vertex_nano_k8600.def.json b/resources/definitions/vertex_nano_k8600.def.json index 02697a1152..ef9552caf3 100644 --- a/resources/definitions/vertex_nano_k8600.def.json +++ b/resources/definitions/vertex_nano_k8600.def.json @@ -19,12 +19,6 @@ "machine_heated_bed": { "default_value": false }, - "material_bed_temperature": { - "default_value": 0 - }, - "material_bed_temperature_layer_0": { - "default_value": 0 - }, "machine_width": { "default_value": 80 }, diff --git a/resources/definitions/wanhao_d9.def.json b/resources/definitions/wanhao_d9.def.json index 39ad139ff8..ac4d41fa40 100644 --- a/resources/definitions/wanhao_d9.def.json +++ b/resources/definitions/wanhao_d9.def.json @@ -31,8 +31,6 @@ "support_angle": { "default_value": 60 }, "support_enable": { "default_value": true }, "layer_height_0": { "default_value": 0.15 }, - "top_thickness": { "default_value": 0.6 }, - "material_print_temperature": { "default_value": 190 }, "layer_height": { "default_value": 0.2 }, "speed_print": { "default_value": 30 }, "adhesion_type": { "default_value": "raft" }, diff --git a/resources/definitions/zone3d_printer.def.json b/resources/definitions/zone3d_printer.def.json index 5aa015cace..4c72422788 100644 --- a/resources/definitions/zone3d_printer.def.json +++ b/resources/definitions/zone3d_printer.def.json @@ -16,9 +16,7 @@ "overrides": { "prime_tower_size": { "default_value": 10.350983390135314 }, - "material_print_temperature": { "default_value": 260 }, "layer_height": { "default_value": 0.14 }, - "speed_travel": { "default_value": 150 }, "machine_extruder_count": { "default_value": 1 }, "machine_heated_bed": { "default_value": true }, "machine_center_is_zero": { "default_value": false }, From 8cd583ad33940af8b5afbf4c6fde1b01356ac17a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 21 Oct 2019 01:48:01 +0200 Subject: [PATCH 33/50] Only show conical support min width if angle is positive If the angle is 0 or negative, this setting won't have any effect since the support cannot be made wider than it already is using this setting. It can only prevent it from becoming smaller, and it will only become smaller from a positive conical support angle. Discovered during work on the Settings Guide. --- 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 5f43cb0bfd..019f533cf8 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -6607,7 +6607,7 @@ "minimum_value_warning": "machine_nozzle_size * 3", "maximum_value_warning": "100.0", "type": "float", - "enabled": "support_conical_enabled and support_enable", + "enabled": "support_conical_enabled and support_enable and support_conical_angle > 0", "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": true }, From 5149baf5932f0abb02af040bce1ecd6b0dcde96a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 21 Oct 2019 09:06:04 +0200 Subject: [PATCH 34/50] Fix custom quality fetching CURA-6913 --- cura/Machines/Models/QualityManagementModel.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cura/Machines/Models/QualityManagementModel.py b/cura/Machines/Models/QualityManagementModel.py index 3b503edcf0..d8b0785778 100644 --- a/cura/Machines/Models/QualityManagementModel.py +++ b/cura/Machines/Models/QualityManagementModel.py @@ -345,11 +345,13 @@ class QualityManagementModel(ListModel): # Create quality_changes group items quality_changes_item_list = [] for quality_changes_group in quality_changes_group_list: + # CURA-6913 Note that custom qualities can be based on "not supported", so the quality group can be None. quality_group = quality_group_dict.get(quality_changes_group.quality_type) + quality_type = quality_changes_group.quality_type item = {"name": quality_changes_group.name, "is_read_only": False, "quality_group": quality_group, - "quality_type": quality_group.quality_type, + "quality_type": quality_type, "quality_changes_group": quality_changes_group, "intent_category": quality_changes_group.intent_category, "section_name": catalog.i18nc("@label", "Custom profiles"), From cd0dbb390214e61c844a6e0ef7c9de6255a79047 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 21 Oct 2019 09:22:38 +0200 Subject: [PATCH 35/50] Fix defaultExtruderPosition() usage in fdmprinter CURA-6913 getDefaultValueInExtruder() expects the extruder_position to be an int, but defaultExtruderPosition() returns a str. This will cause the formula evaluation to fail. --- 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 019f533cf8..ab5a41344a 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -4083,7 +4083,7 @@ "description": "The extruder train to use for printing the support. This is used in multi-extrusion.", "type": "extruder", "default_value": "0", - "value": "defaultExtruderPosition()", + "value": "int(defaultExtruderPosition())", "enabled": "(support_enable or support_tree_enable) and extruders_enabled_count > 1", "settable_per_mesh": false, "settable_per_extruder": false, @@ -5050,7 +5050,7 @@ "description": "The extruder train to use for printing the skirt/brim/raft. This is used in multi-extrusion.", "type": "extruder", "default_value": "0", - "value": "defaultExtruderPosition()", + "value": "int(defaultExtruderPosition())", "enabled": "extruders_enabled_count > 1 and (resolveOrValue('adhesion_type') != 'none' or resolveOrValue('prime_tower_brim_enable'))", "settable_per_mesh": false, "settable_per_extruder": false From 5602c71ec7f54af0e9cbeb432f54062164710f1b Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 21 Oct 2019 09:53:12 +0200 Subject: [PATCH 36/50] Fix material model update and signal recursion CURA-6904 --- cura/Machines/Models/BaseMaterialsModel.py | 38 +++++++++++++------ .../Machines/Models/FavoriteMaterialsModel.py | 4 +- cura/Machines/Models/GenericMaterialsModel.py | 2 +- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/cura/Machines/Models/BaseMaterialsModel.py b/cura/Machines/Models/BaseMaterialsModel.py index fc2f90f1e4..3ed23a2c9e 100644 --- a/cura/Machines/Models/BaseMaterialsModel.py +++ b/cura/Machines/Models/BaseMaterialsModel.py @@ -1,9 +1,9 @@ # Copyright (c) 2019 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import Optional, Dict, Set +from typing import Dict, Set -from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty +from PyQt5.QtCore import Qt, QTimer, pyqtSignal, pyqtProperty from UM.Qt.ListModel import ListModel @@ -38,14 +38,25 @@ class BaseMaterialsModel(ListModel): self._extruder_stack = None self._enabled = True + # CURA-6904 + # Updating the material model requires information from material nodes and containers. We use a timer here to + # make sure that an update function call will not be directly invoked by an event. Because the triggered event + # can be caused in the middle of a XMLMaterial loading, and the material container we try to find may not be + # in the system yet. This will cause an infinite recursion of (1) trying to load a material, (2) trying to + # update the material model, (3) cannot find the material container, load it, (4) repeat #1. + self._update_timer = QTimer() + self._update_timer.setInterval(100) + self._update_timer.setSingleShot(True) + self._update_timer.timeout.connect(self._update) + # Update the stack and the model data when the machine changes self._machine_manager.globalContainerChanged.connect(self._updateExtruderStack) self._updateExtruderStack() # Update this model when switching machines, when adding materials or changing their metadata. - self._machine_manager.activeStackChanged.connect(self._update) + self._machine_manager.activeStackChanged.connect(self._onChanged) ContainerTree.getInstance().materialsChanged.connect(self._materialsListChanged) - self._application.getMaterialManagementModel().favoritesChanged.connect(self._update) + self._application.getMaterialManagementModel().favoritesChanged.connect(self._onChanged) self.addRoleName(Qt.UserRole + 1, "root_material_id") self.addRoleName(Qt.UserRole + 2, "id") @@ -64,14 +75,17 @@ class BaseMaterialsModel(ListModel): self.addRoleName(Qt.UserRole + 15, "container_node") self.addRoleName(Qt.UserRole + 16, "is_favorite") + def _onChanged(self) -> None: + self._update_timer.start() + def _updateExtruderStack(self): global_stack = self._machine_manager.activeMachine if global_stack is None: return if self._extruder_stack is not None: - self._extruder_stack.pyqtContainersChanged.disconnect(self._update) - self._extruder_stack.approximateMaterialDiameterChanged.disconnect(self._update) + self._extruder_stack.pyqtContainersChanged.disconnect(self._onChanged) + self._extruder_stack.approximateMaterialDiameterChanged.disconnect(self._onChanged) try: self._extruder_stack = global_stack.extruderList[self._extruder_position] @@ -79,10 +93,10 @@ class BaseMaterialsModel(ListModel): self._extruder_stack = None if self._extruder_stack is not None: - self._extruder_stack.pyqtContainersChanged.connect(self._update) - self._extruder_stack.approximateMaterialDiameterChanged.connect(self._update) + self._extruder_stack.pyqtContainersChanged.connect(self._onChanged) + self._extruder_stack.approximateMaterialDiameterChanged.connect(self._onChanged) # Force update the model when the extruder stack changes - self._update() + self._onChanged() def setExtruderPosition(self, position: int): if self._extruder_stack is None or self._extruder_position != position: @@ -99,7 +113,7 @@ class BaseMaterialsModel(ListModel): self._enabled = enabled if self._enabled: # ensure the data is there again. - self._update() + self._onChanged() self.enabledChanged.emit() @pyqtProperty(bool, fset = setEnabled, notify = enabledChanged) @@ -119,12 +133,12 @@ class BaseMaterialsModel(ListModel): return if material.variant.machine.container_id != global_stack.definition.getId(): return - self._update() + self._onChanged() ## Triggered when the list of favorite materials is changed. def _favoritesChanged(self, material_base_file: str) -> None: if material_base_file in self._available_materials: - self._update() + self._onChanged() ## This is an abstract method that needs to be implemented by the specific # models themselves. diff --git a/cura/Machines/Models/FavoriteMaterialsModel.py b/cura/Machines/Models/FavoriteMaterialsModel.py index 255ef1dc0a..c5b245e400 100644 --- a/cura/Machines/Models/FavoriteMaterialsModel.py +++ b/cura/Machines/Models/FavoriteMaterialsModel.py @@ -9,14 +9,14 @@ class FavoriteMaterialsModel(BaseMaterialsModel): def __init__(self, parent = None): super().__init__(parent) cura.CuraApplication.CuraApplication.getInstance().getPreferences().preferenceChanged.connect(self._onFavoritesChanged) - self._update() + self._onChanged() ## Triggered when any preference changes, but only handles it when the list # of favourites is changed. def _onFavoritesChanged(self, preference_key: str) -> None: if preference_key != "cura/favorite_materials": return - self._update() + self._onChanged() def _update(self): if not self._canUpdate(): diff --git a/cura/Machines/Models/GenericMaterialsModel.py b/cura/Machines/Models/GenericMaterialsModel.py index 2542a6412a..00adf5636a 100644 --- a/cura/Machines/Models/GenericMaterialsModel.py +++ b/cura/Machines/Models/GenericMaterialsModel.py @@ -7,7 +7,7 @@ class GenericMaterialsModel(BaseMaterialsModel): def __init__(self, parent = None): super().__init__(parent) - self._update() + self._onChanged() def _update(self): if not self._canUpdate(): From 5548c30616e84aa6480ac6f0ed469ba88a759927 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 21 Oct 2019 10:21:48 +0200 Subject: [PATCH 37/50] Catch WinErrors for zeroconf CURA-6855 --- .../UM3NetworkPrinting/src/Network/ZeroConfClient.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Network/ZeroConfClient.py b/plugins/UM3NetworkPrinting/src/Network/ZeroConfClient.py index b6416b2bd0..0446af177b 100644 --- a/plugins/UM3NetworkPrinting/src/Network/ZeroConfClient.py +++ b/plugins/UM3NetworkPrinting/src/Network/ZeroConfClient.py @@ -36,9 +36,15 @@ class ZeroConfClient: def start(self) -> None: self._service_changed_request_queue = Queue() self._service_changed_request_event = Event() - self._service_changed_request_thread = Thread(target=self._handleOnServiceChangedRequests, daemon=True) + try: + self._zero_conf = Zeroconf() + # CURA-6855 catch WinErrors + except OSError: + Logger.logException("e", "Failed to create zeroconf instance.") + return + + self._service_changed_request_thread = Thread(target = self._handleOnServiceChangedRequests, daemon = True) self._service_changed_request_thread.start() - self._zero_conf = Zeroconf() self._zero_conf_browser = ServiceBrowser(self._zero_conf, self.ZERO_CONF_NAME, [self._queueService]) # Cleanup ZeroConf resources. From b2f9dc612d3fe4a08caafaf9d5942421d9f06d09 Mon Sep 17 00:00:00 2001 From: Nino van Hooff Date: Mon, 21 Oct 2019 10:33:52 +0200 Subject: [PATCH 38/50] Change intent profile descriptions to not trigger pervs and prudes. CURA-6851 --- cura/Machines/Models/IntentCategoryModel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/Machines/Models/IntentCategoryModel.py b/cura/Machines/Models/IntentCategoryModel.py index 8e7cd0fb5f..70165a33f1 100644 --- a/cura/Machines/Models/IntentCategoryModel.py +++ b/cura/Machines/Models/IntentCategoryModel.py @@ -37,12 +37,12 @@ class IntentCategoryModel(ListModel): } _translations["engineering"] = { "name": catalog.i18nc("@label", "Engineering"), - "description": catalog.i18nc("@text", "A profile which is suitable for engineering work") + "description": catalog.i18nc("@text", "Suitable for engineering work") } _translations["smooth"] = { "name": catalog.i18nc("@label", "Smooth"), - "description": catalog.i18nc("@text", "Ohhh yeah. So tender. So smooth. So Perfect.") + "description": catalog.i18nc("@text", "Optimized for a smooth surfaces") } ## Creates a new model for a certain intent category. From 3d30674465674aa3d75cdc98955056c4a3846dd0 Mon Sep 17 00:00:00 2001 From: Nino van Hooff Date: Mon, 21 Oct 2019 13:37:28 +0200 Subject: [PATCH 39/50] Clarify "reset quality button" purpose --- .../Recommended/RecommendedQualityProfileSelector.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml index d1f7dd7de2..ae121e0349 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml @@ -55,7 +55,7 @@ Item } UM.SimpleButton { - id: customisedSettings + id: resetToDefaultQualityButton visible: Cura.SimpleModeSettingsManager.isProfileCustomized || Cura.MachineManager.hasCustomQuality height: visible ? UM.Theme.getSize("print_setup_icon").height : 0 From 9d931d8d2b91ab044d83d0e237e8a206765da997 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 21 Oct 2019 14:24:52 +0200 Subject: [PATCH 40/50] Remove stray print statement CURA-6853 --- plugins/SimulationView/SimulationViewMainComponent.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index 65621605df..cd7d108370 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -224,7 +224,6 @@ Item // Make sure the slider handlers show the correct value after switching views Component.onCompleted: { - print("safeArea: " + safeArea, "layerSliderSafeYMax", layerSliderSafeYMax) layerSlider.setLowerValue(UM.SimulationView.minimumLayer) layerSlider.setUpperValue(UM.SimulationView.currentLayer) } From 00abde2c8f2b32e0ae81192c85ece1903ba6d937 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 22 Oct 2019 08:09:28 +0200 Subject: [PATCH 41/50] Update setting_version for key3d tyro qualities CURA-6815 --- resources/quality/key3d/key3d_tyro_best.inst.cfg | 2 +- resources/quality/key3d/key3d_tyro_fast.inst.cfg | 2 +- resources/quality/key3d/key3d_tyro_normal.inst.cfg | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/quality/key3d/key3d_tyro_best.inst.cfg b/resources/quality/key3d/key3d_tyro_best.inst.cfg index e5a257f898..0b9289b042 100644 --- a/resources/quality/key3d/key3d_tyro_best.inst.cfg +++ b/resources/quality/key3d/key3d_tyro_best.inst.cfg @@ -4,7 +4,7 @@ name = Best Quality definition = key3d_tyro [metadata] -setting_version = 9 +setting_version = 10 type = quality quality_type = best weight = 1 diff --git a/resources/quality/key3d/key3d_tyro_fast.inst.cfg b/resources/quality/key3d/key3d_tyro_fast.inst.cfg index 4ca4a65950..7ab9776b4e 100644 --- a/resources/quality/key3d/key3d_tyro_fast.inst.cfg +++ b/resources/quality/key3d/key3d_tyro_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast Quality definition = key3d_tyro [metadata] -setting_version = 9 +setting_version = 10 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/key3d/key3d_tyro_normal.inst.cfg b/resources/quality/key3d/key3d_tyro_normal.inst.cfg index 7f650612ff..7ed3791edc 100644 --- a/resources/quality/key3d/key3d_tyro_normal.inst.cfg +++ b/resources/quality/key3d/key3d_tyro_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal Quality definition = key3d_tyro [metadata] -setting_version = 9 +setting_version = 10 type = quality quality_type = normal weight = 0 From 51c3acc6542ed3b74d1623db3da2a2d4da6aa8b8 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 22 Oct 2019 09:56:27 +0200 Subject: [PATCH 42/50] Document helper functions --- tests/Settings/TestDefinitionContainer.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/Settings/TestDefinitionContainer.py b/tests/Settings/TestDefinitionContainer.py index 09efc3fcb8..73d10d871c 100644 --- a/tests/Settings/TestDefinitionContainer.py +++ b/tests/Settings/TestDefinitionContainer.py @@ -72,6 +72,11 @@ def test_validateOverridingDefaultValue(file_name): if "value" in parent_settings[key]: assert "default_value" not in val, "Unnecessary default_value for {key} in {file_name}".format(key = key, file_name = file_name) # If there is a value in the parent settings, then the default_value is not effective. +## Get all settings and their properties from a definition we're inheriting +# from. +# \param definition_id The definition we're inheriting from. +# \return A dictionary of settings by key. Each setting is a dictionary of +# properties. def getInheritedSettings(definition_id: str) -> Dict[str, Any]: definition_path = os.path.join(os.path.dirname(__file__), "..", "..", "resources", "definitions", definition_id + ".def.json") with open(definition_path, encoding = "utf-8") as f: @@ -87,7 +92,13 @@ def getInheritedSettings(definition_id: str) -> Dict[str, Any]: return result -def flattenSettings(settings) -> Dict[str, Any]: +## Put all settings in the main dictionary rather than in children dicts. +# \param settings Nested settings. The keys are the setting IDs. The values +# are dictionaries of properties per setting, including the "children" +# property. +# \return A dictionary of settings by key. Each setting is a dictionary of +# properties. +def flattenSettings(settings: Dict[str, Any]) -> Dict[str, Any]: result = {} for entry, contents in settings.items(): if "children" in contents: @@ -96,6 +107,11 @@ def flattenSettings(settings) -> Dict[str, Any]: result[entry] = contents return result +## Make one dictionary override the other. Nested dictionaries override each +# other in the same way. +# \param base A dictionary of settings that will get overridden by the other. +# \param overrides A dictionary of settings that will override the other. +# \return Combined setting data. def merge_dicts(base: Dict[str, Any], overrides: Dict[str, Any]) -> Dict[str, Any]: result = {} result.update(base) From d561810024cd060fbc15af0a952de3dbc87c7d76 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 22 Oct 2019 11:00:49 +0200 Subject: [PATCH 43/50] Remove ID metadata fields from definition files They are not being used any more. For some reason people thought that an exception was made for extruders or something. And people keep adding them for the definition files too. I'll add a test to prevent that. --- resources/definitions/bibo2_dual.def.json | 1 - resources/definitions/creality_cr-x.def.json | 1 - resources/definitions/cubicon_3dp_110f.def.json | 1 - resources/definitions/cubicon_3dp_210f.def.json | 1 - resources/definitions/cubicon_3dp_310f.def.json | 1 - resources/definitions/flsun_qq_s.def.json | 1 - resources/definitions/geeetech_a30.def.json | 1 - resources/definitions/gmax15plus.def.json | 1 - resources/definitions/gmax15plus_dual.def.json | 1 - resources/definitions/malyan_m180.def.json | 1 - resources/definitions/malyan_m200.def.json | 1 - resources/definitions/monoprice_select_mini_v1.def.json | 1 - resources/definitions/monoprice_select_mini_v2.def.json | 1 - resources/definitions/ubuild-3d_mr_bot_280.def.json | 1 - resources/definitions/ultimaker_s3.def.json | 1 - resources/definitions/ultimaker_s5.def.json | 1 - resources/definitions/uni_print_3d.def.json | 1 - resources/extruders/101Hero_extruder_0.def.json | 1 - resources/extruders/3dator_extruder_0.def.json | 1 - resources/extruders/Mark2_extruder1.def.json | 1 - resources/extruders/Mark2_extruder2.def.json | 1 - resources/extruders/abax_pri3_extruder_0.def.json | 1 - resources/extruders/abax_pri5_extruder_0.def.json | 1 - resources/extruders/abax_titan_extruder_0.def.json | 1 - resources/extruders/alfawise_u20_extruder_0.def.json | 1 - resources/extruders/alfawise_u30_extruder_0.def.json | 1 - resources/extruders/alya3dp_extruder_0.def.json | 1 - resources/extruders/anet_a6_extruder_0.def.json | 1 - resources/extruders/anycubic_4max_extruder_0.def.json | 1 - resources/extruders/anycubic_chiron_extruder_0.def.json | 1 - resources/extruders/anycubic_i3_mega_extruder_0.def.json | 1 - resources/extruders/bfb_extruder_0.def.json | 1 - resources/extruders/bibo2_dual_extruder_0.def.json | 1 - resources/extruders/bibo2_dual_extruder_1.def.json | 1 - resources/extruders/bq_hephestos_2_extruder_0.def.json | 1 - resources/extruders/bq_hephestos_extruder_0.def.json | 1 - resources/extruders/bq_hephestos_xl_extruder_0.def.json | 1 - resources/extruders/bq_witbox_2_extruder_0.def.json | 1 - resources/extruders/bq_witbox_extruder_0.def.json | 1 - resources/extruders/builder_premium_large_front.def.json | 1 - resources/extruders/builder_premium_large_rear.def.json | 1 - resources/extruders/builder_premium_medium_front.def.json | 1 - resources/extruders/builder_premium_medium_rear.def.json | 1 - resources/extruders/builder_premium_small_front.def.json | 1 - resources/extruders/builder_premium_small_rear.def.json | 1 - resources/extruders/cartesio_extruder_0.def.json | 1 - resources/extruders/cartesio_extruder_1.def.json | 1 - resources/extruders/cartesio_extruder_2.def.json | 1 - resources/extruders/cartesio_extruder_3.def.json | 1 - resources/extruders/cocoon_create_modelmaker_extruder_0.def.json | 1 - resources/extruders/cr-x_extruder_0.def.json | 1 - resources/extruders/cr-x_extruder_1.def.json | 1 - resources/extruders/creatable_d3_extruder_0.def.json | 1 - resources/extruders/cubicon_3dp_110f_extruder_0.def.json | 1 - resources/extruders/cubicon_3dp_210f_extruder_0.def.json | 1 - resources/extruders/cubicon_3dp_310f_extruder_0.def.json | 1 - resources/extruders/cubicon_dual_pro_a30_extruder_0.def.json | 1 - resources/extruders/cubicon_dual_pro_a30_extruder_1.def.json | 1 - resources/extruders/cubicon_style_plus_a15_extruder_0.def.json | 1 - resources/extruders/custom_extruder_1.def.json | 1 - resources/extruders/custom_extruder_2.def.json | 1 - resources/extruders/custom_extruder_3.def.json | 1 - resources/extruders/custom_extruder_4.def.json | 1 - resources/extruders/custom_extruder_5.def.json | 1 - resources/extruders/custom_extruder_6.def.json | 1 - resources/extruders/custom_extruder_7.def.json | 1 - resources/extruders/custom_extruder_8.def.json | 1 - resources/extruders/delta_go_extruder_0.def.json | 1 - resources/extruders/deltabot_extruder_0.def.json | 1 - resources/extruders/deltacomb_extruder_0.def.json | 1 - resources/extruders/deltacomb_extruder_1.def.json | 1 - resources/extruders/easyarts_ares_extruder_0.def.json | 1 - resources/extruders/erzay3d_extruder_0.def.json | 1 - resources/extruders/fabtotum_extruder_0.def.json | 1 - resources/extruders/felixpro2_dual_extruder_0.def.json | 1 - resources/extruders/felixpro2_dual_extruder_1.def.json | 1 - resources/extruders/felixtec4_dual_extruder_0.def.json | 1 - resources/extruders/felixtec4_dual_extruder_1.def.json | 1 - resources/extruders/flsun_qq_extruder.def.json | 1 - resources/extruders/flsun_qq_s_extruder_0.def.json | 1 - resources/extruders/folgertech_FT-5_extruder_0.def.json | 1 - resources/extruders/geeetech_a30_extruder_0.def.json | 1 - resources/extruders/gmax15plus_dual_extruder_0.def.json | 1 - resources/extruders/gmax15plus_dual_extruder_1.def.json | 1 - resources/extruders/gmax15plus_extruder_0.def.json | 1 - resources/extruders/grr_neo_extruder_0.def.json | 1 - resources/extruders/hBp_extruder_left.def.json | 1 - resources/extruders/hBp_extruder_right.def.json | 1 - resources/extruders/hms434_tool_1.def.json | 1 - resources/extruders/hms434_tool_2.def.json | 1 - resources/extruders/hms434_tool_3.def.json | 1 - resources/extruders/hms434_tool_4.def.json | 1 - resources/extruders/hms434_tool_5.def.json | 1 - resources/extruders/hms434_tool_6.def.json | 1 - resources/extruders/hms434_tool_7.def.json | 1 - resources/extruders/hms434_tool_8.def.json | 1 - resources/extruders/imade3d_jellybox_2_extruder_0.def.json | 1 - resources/extruders/imade3d_jellybox_extruder_0.def.json | 1 - resources/extruders/innovo_inventor_extruder_0.def.json | 1 - resources/extruders/jgaurora_a1_extruder_0.def.json | 1 - resources/extruders/jgaurora_a3s_extruder_0.def.json | 1 - resources/extruders/jgaurora_a5_extruder_0.def.json | 1 - resources/extruders/jgaurora_jgmaker_magic_extruder_0.def.json | 1 - resources/extruders/jgaurora_z_603s_extruder_0.def.json | 1 - resources/extruders/julia_extruder_0.def.json | 1 - resources/extruders/kemiq_q2_beta_extruder_0.def.json | 1 - resources/extruders/kemiq_q2_gama_extruder_0.def.json | 1 - resources/extruders/key3d_tyro_extruder_0.def.json | 1 - resources/extruders/kossel_mini_extruder_0.def.json | 1 - resources/extruders/kossel_pro_extruder_0.def.json | 1 - resources/extruders/kupido_extruder_0.def.json | 1 - resources/extruders/makeR_pegasus_extruder_0.def.json | 1 - resources/extruders/makeR_prusa_tairona_i3_extruder_0.def.json | 1 - resources/extruders/makeit_dual_1st.def.json | 1 - resources/extruders/makeit_dual_2nd.def.json | 1 - resources/extruders/makeit_l_dual_1st.def.json | 1 - resources/extruders/makeit_l_dual_2nd.def.json | 1 - resources/extruders/maker_starter_extruder_0.def.json | 1 - resources/extruders/makerbotreplicator_extruder_0.def.json | 1 - resources/extruders/malyan_m180_extruder_0.def.json | 1 - resources/extruders/malyan_m200_extruder_0.def.json | 1 - .../extruders/mankati_fullscale_xt_plus_extruder_0.def.json | 1 - resources/extruders/mendel90_extruder_0.def.json | 1 - resources/extruders/monoprice_select_mini_v1_extruder_0.def.json | 1 - resources/extruders/monoprice_select_mini_v2_extruder_0.def.json | 1 - resources/extruders/nwa3d_a31_extruder_0.def.json | 1 - resources/extruders/nwa3d_a5_extruder_0.def.json | 1 - resources/extruders/ord_extruder_0.def.json | 1 - resources/extruders/ord_extruder_1.def.json | 1 - resources/extruders/ord_extruder_2.def.json | 1 - resources/extruders/ord_extruder_3.def.json | 1 - resources/extruders/ord_extruder_4.def.json | 1 - resources/extruders/peopoly_moai_extruder_0.def.json | 1 - resources/extruders/printrbot_play_extruder_0.def.json | 1 - resources/extruders/printrbot_play_heated_extruder_0.def.json | 1 - .../extruders/printrbot_simple_extended_extruder_0.def.json | 1 - resources/extruders/printrbot_simple_extruder_0.def.json | 1 - .../extruders/printrbot_simple_makers_kit_extruder_0.def.json | 1 - resources/extruders/prusa_i3_extruder_0.def.json | 1 - resources/extruders/prusa_i3_mk2_extruder_0.def.json | 1 - resources/extruders/prusa_i3_xl_extruder_0.def.json | 1 - resources/extruders/punchtec_connect_xl_extruder_0.def.json | 1 - resources/extruders/punchtec_connect_xl_extruder_1.def.json | 1 - resources/extruders/raise3D_N2_dual_extruder_0.def.json | 1 - resources/extruders/raise3D_N2_dual_extruder_1.def.json | 1 - resources/extruders/raise3D_N2_plus_dual_extruder_0.def.json | 1 - resources/extruders/raise3D_N2_plus_dual_extruder_1.def.json | 1 - resources/extruders/raise3D_N2_single_extruder_0.def.json | 1 - resources/extruders/renkforce_rf100_extruder_0.def.json | 1 - resources/extruders/rigid3d_3rdgen_extruder_0.def.json | 1 - resources/extruders/rigid3d_extruder_0.def.json | 1 - resources/extruders/rigid3d_hobby_extruder_0.def.json | 1 - resources/extruders/rigid3d_mucit_extruder_0.def.json | 1 - resources/extruders/rigid3d_zero2_extruder_0.def.json | 1 - resources/extruders/rigid3d_zero_extruder_0.def.json | 1 - resources/extruders/rigidbot_big_extruder_0.def.json | 1 - resources/extruders/rigidbot_extruder_0.def.json | 1 - resources/extruders/robo_3d_r1_extruder_0.def.json | 1 - resources/extruders/seemecnc_artemis_extruder_0.def.json | 1 - resources/extruders/seemecnc_v32_extruder_0.def.json | 1 - resources/extruders/stereotech_start_extruder_0.def.json | 1 - resources/extruders/stereotech_ste320_1st.def.json | 1 - resources/extruders/stereotech_ste320_2nd.def.json | 1 - resources/extruders/strateo3d_left_extruder.def.json | 1 - resources/extruders/strateo3d_right_extruder.def.json | 1 - .../structur3d_discov3ry1_complete_um2plus_extruder_0.def.json | 1 - resources/extruders/tam_extruder_0.def.json | 1 - resources/extruders/tevo_blackwidow_extruder_0.def.json | 1 - resources/extruders/tevo_tarantula_extruder_0.def.json | 1 - resources/extruders/tevo_tornado_extruder_0.def.json | 1 - resources/extruders/tizyx_evy_dual_extruder_0.def.JSON | 1 - resources/extruders/tizyx_evy_dual_extruder_1.def.JSON | 1 - resources/extruders/tizyx_evy_extruder_0.def.JSON | 1 - resources/extruders/tizyx_k25_extruder_0.def.json | 1 - resources/extruders/ubuild-3d_mr_bot_280_extruder_0.def.json | 1 - resources/extruders/ultimaker2_extended_extruder_0.def.json | 1 - resources/extruders/ultimaker2_extended_plus_extruder_0.def.json | 1 - resources/extruders/ultimaker2_extruder_0.def.json | 1 - resources/extruders/ultimaker2_go_extruder_0.def.json | 1 - resources/extruders/ultimaker2_plus_extruder_0.def.json | 1 - resources/extruders/ultimaker3_extended_extruder_left.def.json | 1 - resources/extruders/ultimaker3_extended_extruder_right.def.json | 1 - resources/extruders/ultimaker3_extruder_left.def.json | 1 - resources/extruders/ultimaker3_extruder_right.def.json | 1 - resources/extruders/ultimaker_original_dual_1st.def.json | 1 - resources/extruders/ultimaker_original_dual_2nd.def.json | 1 - resources/extruders/ultimaker_original_extruder_0.def.json | 1 - resources/extruders/ultimaker_original_plus_extruder_0.def.json | 1 - resources/extruders/ultimaker_s3_extruder_left.def.json | 1 - resources/extruders/ultimaker_s3_extruder_right.def.json | 1 - resources/extruders/ultimaker_s5_extruder_left.def.json | 1 - resources/extruders/ultimaker_s5_extruder_right.def.json | 1 - resources/extruders/uni_print_3d_extruder_0.def.json | 1 - resources/extruders/uniqbot_one_extruder_0.def.json | 1 - resources/extruders/vertex_delta_k8800_extruder_0.def.json | 1 - resources/extruders/vertex_k8400_dual_1st.def.json | 1 - resources/extruders/vertex_k8400_dual_2nd.def.json | 1 - resources/extruders/vertex_k8400_extruder_0.def.json | 1 - resources/extruders/wanhao_d4s_extruder_0.def.json | 1 - resources/extruders/wanhao_d6_extruder_0.def.json | 1 - resources/extruders/wanhao_d6_plus_extruder_0.def.json | 1 - resources/extruders/wanhao_d9_extruder_0.def.json | 1 - resources/extruders/wanhao_duplicator5S_extruder_0.def.json | 1 - resources/extruders/wanhao_duplicator5Smini_extruder_0.def.json | 1 - resources/extruders/wanhao_i3_extruder_0.def.json | 1 - resources/extruders/wanhao_i3mini_extruder_0.def.json | 1 - resources/extruders/wanhao_i3plus_extruder_0.def.json | 1 - resources/extruders/z-bolt_extruder_0.def.json | 1 - resources/extruders/zone3d_printer_extruder_0.def.json | 1 - resources/extruders/zyyx_agile_extruder_0.def.json | 1 - 210 files changed, 210 deletions(-) diff --git a/resources/definitions/bibo2_dual.def.json b/resources/definitions/bibo2_dual.def.json index 0197426ac6..a644185915 100644 --- a/resources/definitions/bibo2_dual.def.json +++ b/resources/definitions/bibo2_dual.def.json @@ -1,5 +1,4 @@ { - "id": "BIBO2 dual", "version": 2, "name": "BIBO2 dual", "inherits": "fdmprinter", diff --git a/resources/definitions/creality_cr-x.def.json b/resources/definitions/creality_cr-x.def.json index 15bea1edf1..13409a7212 100644 --- a/resources/definitions/creality_cr-x.def.json +++ b/resources/definitions/creality_cr-x.def.json @@ -1,5 +1,4 @@ { - "id": "CR-X", "version": 2, "name": "Creality CR-X", "inherits": "fdmprinter", diff --git a/resources/definitions/cubicon_3dp_110f.def.json b/resources/definitions/cubicon_3dp_110f.def.json index 168b57cd66..eecfdd5911 100644 --- a/resources/definitions/cubicon_3dp_110f.def.json +++ b/resources/definitions/cubicon_3dp_110f.def.json @@ -1,5 +1,4 @@ { - "id": "3DP-110F", "version": 2, "name": "Cubicon Single", "inherits": "cubicon_common", diff --git a/resources/definitions/cubicon_3dp_210f.def.json b/resources/definitions/cubicon_3dp_210f.def.json index cc99899f92..5d8ff78487 100644 --- a/resources/definitions/cubicon_3dp_210f.def.json +++ b/resources/definitions/cubicon_3dp_210f.def.json @@ -1,5 +1,4 @@ { - "id": "3DP-210F", "version": 2, "name": "Cubicon Style", "inherits": "cubicon_common", diff --git a/resources/definitions/cubicon_3dp_310f.def.json b/resources/definitions/cubicon_3dp_310f.def.json index 90d0e3f25c..1dc78f0ebf 100644 --- a/resources/definitions/cubicon_3dp_310f.def.json +++ b/resources/definitions/cubicon_3dp_310f.def.json @@ -1,5 +1,4 @@ { - "id": "3DP-310F", "version": 2, "name": "Cubicon Single Plus", "inherits": "cubicon_common", diff --git a/resources/definitions/flsun_qq_s.def.json b/resources/definitions/flsun_qq_s.def.json index 6b10a7f0cc..9c3bf571ae 100644 --- a/resources/definitions/flsun_qq_s.def.json +++ b/resources/definitions/flsun_qq_s.def.json @@ -1,5 +1,4 @@ { - "id": "flsun_qq_s", "version": 2, "name": "FLSUN QQ-S", "inherits": "fdmprinter", diff --git a/resources/definitions/geeetech_a30.def.json b/resources/definitions/geeetech_a30.def.json index 52b6ad8f7f..a700f4e473 100644 --- a/resources/definitions/geeetech_a30.def.json +++ b/resources/definitions/geeetech_a30.def.json @@ -1,5 +1,4 @@ { - "id": "geeetech_a30", "version": 2, "name": "Geeetech A30", "inherits": "fdmprinter", diff --git a/resources/definitions/gmax15plus.def.json b/resources/definitions/gmax15plus.def.json index b5e0efe27c..e98d6c02fe 100644 --- a/resources/definitions/gmax15plus.def.json +++ b/resources/definitions/gmax15plus.def.json @@ -1,5 +1,4 @@ { - "id": "gmax15plus", "version": 2, "name": "gMax 1.5 Plus", "inherits": "fdmprinter", diff --git a/resources/definitions/gmax15plus_dual.def.json b/resources/definitions/gmax15plus_dual.def.json index 89ffda490a..aaba2cc55b 100644 --- a/resources/definitions/gmax15plus_dual.def.json +++ b/resources/definitions/gmax15plus_dual.def.json @@ -1,5 +1,4 @@ { - "id": "gmax15plus_dual", "version": 2, "name": "gMax 1.5 Plus Dual Extruder", "inherits": "fdmprinter", diff --git a/resources/definitions/malyan_m180.def.json b/resources/definitions/malyan_m180.def.json index cd3a068134..bb812b6dd6 100644 --- a/resources/definitions/malyan_m180.def.json +++ b/resources/definitions/malyan_m180.def.json @@ -1,5 +1,4 @@ { - "id": "malyan_m180", "version": 2, "name": "Malyan M180", "inherits": "fdmprinter", diff --git a/resources/definitions/malyan_m200.def.json b/resources/definitions/malyan_m200.def.json index 13ad07ccae..fc8756ff6a 100644 --- a/resources/definitions/malyan_m200.def.json +++ b/resources/definitions/malyan_m200.def.json @@ -1,5 +1,4 @@ { - "id": "malyan_m200", "version": 2, "name": "Malyan M200", "inherits": "fdmprinter", diff --git a/resources/definitions/monoprice_select_mini_v1.def.json b/resources/definitions/monoprice_select_mini_v1.def.json index a516d54b18..4fe67fc92e 100644 --- a/resources/definitions/monoprice_select_mini_v1.def.json +++ b/resources/definitions/monoprice_select_mini_v1.def.json @@ -1,5 +1,4 @@ { - "id": "monoprice_select_mini_v1", "version": 2, "name": "Monoprice Select Mini V1", "inherits": "malyan_m200", diff --git a/resources/definitions/monoprice_select_mini_v2.def.json b/resources/definitions/monoprice_select_mini_v2.def.json index bed4fb1adb..2364e49383 100644 --- a/resources/definitions/monoprice_select_mini_v2.def.json +++ b/resources/definitions/monoprice_select_mini_v2.def.json @@ -1,5 +1,4 @@ { - "id": "monoprice_select_mini_v2", "version": 2, "name": "Monoprice Select Mini V2 (E3D)", "inherits": "malyan_m200", diff --git a/resources/definitions/ubuild-3d_mr_bot_280.def.json b/resources/definitions/ubuild-3d_mr_bot_280.def.json index 5157befc10..255d8f032b 100644 --- a/resources/definitions/ubuild-3d_mr_bot_280.def.json +++ b/resources/definitions/ubuild-3d_mr_bot_280.def.json @@ -1,5 +1,4 @@ { - "id": "ubuild-3d_mr_bot_280", "version": 2, "name": "uBuild-3D Mr Bot 280", "inherits": "fdmprinter", diff --git a/resources/definitions/ultimaker_s3.def.json b/resources/definitions/ultimaker_s3.def.json index 0d6834521e..7348c14a2a 100644 --- a/resources/definitions/ultimaker_s3.def.json +++ b/resources/definitions/ultimaker_s3.def.json @@ -1,5 +1,4 @@ { - "id": "ultimaker_s3", "version": 2, "name": "Ultimaker S3", "inherits": "ultimaker", diff --git a/resources/definitions/ultimaker_s5.def.json b/resources/definitions/ultimaker_s5.def.json index 7eb37d0614..dcd44a371a 100644 --- a/resources/definitions/ultimaker_s5.def.json +++ b/resources/definitions/ultimaker_s5.def.json @@ -1,5 +1,4 @@ { - "id": "ultimaker_s5", "version": 2, "name": "Ultimaker S5", "inherits": "ultimaker", diff --git a/resources/definitions/uni_print_3d.def.json b/resources/definitions/uni_print_3d.def.json index 427177176a..99d9eab1e0 100644 --- a/resources/definitions/uni_print_3d.def.json +++ b/resources/definitions/uni_print_3d.def.json @@ -1,5 +1,4 @@ { - "id": "uni_print_3d", "name": "UNI-PRINT-3D", "version": 2, "inherits": "fdmprinter", diff --git a/resources/extruders/101Hero_extruder_0.def.json b/resources/extruders/101Hero_extruder_0.def.json index 82c06e40d6..21c892133c 100644 --- a/resources/extruders/101Hero_extruder_0.def.json +++ b/resources/extruders/101Hero_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "101Hero_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/3dator_extruder_0.def.json b/resources/extruders/3dator_extruder_0.def.json index 6749eb7bb4..97b03518f7 100644 --- a/resources/extruders/3dator_extruder_0.def.json +++ b/resources/extruders/3dator_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "3dator_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/Mark2_extruder1.def.json b/resources/extruders/Mark2_extruder1.def.json index 915c331083..27becf88ff 100644 --- a/resources/extruders/Mark2_extruder1.def.json +++ b/resources/extruders/Mark2_extruder1.def.json @@ -1,5 +1,4 @@ { - "id": "Mark2_extruder1", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/Mark2_extruder2.def.json b/resources/extruders/Mark2_extruder2.def.json index 2c05a09391..ac654d9c00 100644 --- a/resources/extruders/Mark2_extruder2.def.json +++ b/resources/extruders/Mark2_extruder2.def.json @@ -1,5 +1,4 @@ { - "id": "Mark2_extruder2", "version": 2, "name": "Extruder 2", "inherits": "fdmextruder", diff --git a/resources/extruders/abax_pri3_extruder_0.def.json b/resources/extruders/abax_pri3_extruder_0.def.json index 27e86d6042..618ca7f596 100644 --- a/resources/extruders/abax_pri3_extruder_0.def.json +++ b/resources/extruders/abax_pri3_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "abax_pri3_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/abax_pri5_extruder_0.def.json b/resources/extruders/abax_pri5_extruder_0.def.json index 842e76e5f3..4a96b5e12e 100644 --- a/resources/extruders/abax_pri5_extruder_0.def.json +++ b/resources/extruders/abax_pri5_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "abax_pri5_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/abax_titan_extruder_0.def.json b/resources/extruders/abax_titan_extruder_0.def.json index 79e1974def..078b9f0470 100644 --- a/resources/extruders/abax_titan_extruder_0.def.json +++ b/resources/extruders/abax_titan_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "abax_titan_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/alfawise_u20_extruder_0.def.json b/resources/extruders/alfawise_u20_extruder_0.def.json index 2fbe3f1772..6bb2bde534 100644 --- a/resources/extruders/alfawise_u20_extruder_0.def.json +++ b/resources/extruders/alfawise_u20_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "alfawise_u20_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/alfawise_u30_extruder_0.def.json b/resources/extruders/alfawise_u30_extruder_0.def.json index 37f59eb567..4014b5ab62 100644 --- a/resources/extruders/alfawise_u30_extruder_0.def.json +++ b/resources/extruders/alfawise_u30_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "alfawise_u30_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/alya3dp_extruder_0.def.json b/resources/extruders/alya3dp_extruder_0.def.json index 3676f01ad2..5e05210e2c 100644 --- a/resources/extruders/alya3dp_extruder_0.def.json +++ b/resources/extruders/alya3dp_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "alya3dp_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/anet_a6_extruder_0.def.json b/resources/extruders/anet_a6_extruder_0.def.json index 704d3a55ca..c87160a542 100644 --- a/resources/extruders/anet_a6_extruder_0.def.json +++ b/resources/extruders/anet_a6_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "anet_a6_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/anycubic_4max_extruder_0.def.json b/resources/extruders/anycubic_4max_extruder_0.def.json index 5c2ab8d479..9ea55928b8 100644 --- a/resources/extruders/anycubic_4max_extruder_0.def.json +++ b/resources/extruders/anycubic_4max_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "anycubic_4max_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/anycubic_chiron_extruder_0.def.json b/resources/extruders/anycubic_chiron_extruder_0.def.json index cc48df08bb..b4117c755a 100644 --- a/resources/extruders/anycubic_chiron_extruder_0.def.json +++ b/resources/extruders/anycubic_chiron_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "anycubic_chiron_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/anycubic_i3_mega_extruder_0.def.json b/resources/extruders/anycubic_i3_mega_extruder_0.def.json index 6d9c330536..f15eab4829 100644 --- a/resources/extruders/anycubic_i3_mega_extruder_0.def.json +++ b/resources/extruders/anycubic_i3_mega_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "anycubic_i3_mega_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/bfb_extruder_0.def.json b/resources/extruders/bfb_extruder_0.def.json index 88c81ee03e..6dd995d098 100644 --- a/resources/extruders/bfb_extruder_0.def.json +++ b/resources/extruders/bfb_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "bfb_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/bibo2_dual_extruder_0.def.json b/resources/extruders/bibo2_dual_extruder_0.def.json index f83801fa0c..b918d070be 100644 --- a/resources/extruders/bibo2_dual_extruder_0.def.json +++ b/resources/extruders/bibo2_dual_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "BIBO1", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/bibo2_dual_extruder_1.def.json b/resources/extruders/bibo2_dual_extruder_1.def.json index 5f479ba54b..e0386188bb 100644 --- a/resources/extruders/bibo2_dual_extruder_1.def.json +++ b/resources/extruders/bibo2_dual_extruder_1.def.json @@ -1,5 +1,4 @@ { - "id": "BIBO2", "version": 2, "name": "Extruder 2", "inherits": "fdmextruder", diff --git a/resources/extruders/bq_hephestos_2_extruder_0.def.json b/resources/extruders/bq_hephestos_2_extruder_0.def.json index 833907937d..d58d8d755a 100644 --- a/resources/extruders/bq_hephestos_2_extruder_0.def.json +++ b/resources/extruders/bq_hephestos_2_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "bq_hephestos_2_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/bq_hephestos_extruder_0.def.json b/resources/extruders/bq_hephestos_extruder_0.def.json index 753778f399..dc9b42d66d 100644 --- a/resources/extruders/bq_hephestos_extruder_0.def.json +++ b/resources/extruders/bq_hephestos_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "bq_hephestos_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/bq_hephestos_xl_extruder_0.def.json b/resources/extruders/bq_hephestos_xl_extruder_0.def.json index 91cac04dc9..a52032f129 100644 --- a/resources/extruders/bq_hephestos_xl_extruder_0.def.json +++ b/resources/extruders/bq_hephestos_xl_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "bq_hephestos_xl_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/bq_witbox_2_extruder_0.def.json b/resources/extruders/bq_witbox_2_extruder_0.def.json index 04107f4471..62fe62ad0b 100644 --- a/resources/extruders/bq_witbox_2_extruder_0.def.json +++ b/resources/extruders/bq_witbox_2_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "bq_witbox_2_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/bq_witbox_extruder_0.def.json b/resources/extruders/bq_witbox_extruder_0.def.json index d3a5c677af..37b1492676 100644 --- a/resources/extruders/bq_witbox_extruder_0.def.json +++ b/resources/extruders/bq_witbox_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "bq_witbox_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/builder_premium_large_front.def.json b/resources/extruders/builder_premium_large_front.def.json index 4834bc8fd9..dc1c557304 100644 --- a/resources/extruders/builder_premium_large_front.def.json +++ b/resources/extruders/builder_premium_large_front.def.json @@ -1,5 +1,4 @@ { - "id": "builder_premium_large_front", "version": 2, "name": "Front Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/builder_premium_large_rear.def.json b/resources/extruders/builder_premium_large_rear.def.json index f257749ea4..5dbe6d30c9 100644 --- a/resources/extruders/builder_premium_large_rear.def.json +++ b/resources/extruders/builder_premium_large_rear.def.json @@ -1,5 +1,4 @@ { - "id": "builder_premium_large_rear", "version": 2, "name": "Rear Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/builder_premium_medium_front.def.json b/resources/extruders/builder_premium_medium_front.def.json index 05dcb3d49f..2d38e48aab 100644 --- a/resources/extruders/builder_premium_medium_front.def.json +++ b/resources/extruders/builder_premium_medium_front.def.json @@ -1,5 +1,4 @@ { - "id": "builder_premium_medium_front", "version": 2, "name": "Front Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/builder_premium_medium_rear.def.json b/resources/extruders/builder_premium_medium_rear.def.json index 3461e07f09..0a789c38f1 100644 --- a/resources/extruders/builder_premium_medium_rear.def.json +++ b/resources/extruders/builder_premium_medium_rear.def.json @@ -1,5 +1,4 @@ { - "id": "builder_premium_medium_rear", "version": 2, "name": "Rear Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/builder_premium_small_front.def.json b/resources/extruders/builder_premium_small_front.def.json index 7a1c352c73..b36c535aeb 100644 --- a/resources/extruders/builder_premium_small_front.def.json +++ b/resources/extruders/builder_premium_small_front.def.json @@ -1,5 +1,4 @@ { - "id": "builder_premium_small_front", "version": 2, "name": "Front Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/builder_premium_small_rear.def.json b/resources/extruders/builder_premium_small_rear.def.json index 7085236a5c..8e00d0cc39 100644 --- a/resources/extruders/builder_premium_small_rear.def.json +++ b/resources/extruders/builder_premium_small_rear.def.json @@ -1,5 +1,4 @@ { - "id": "builder_premium_small_rear", "version": 2, "name": "Rear Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/cartesio_extruder_0.def.json b/resources/extruders/cartesio_extruder_0.def.json index 6d2b5f634e..ad27d4854c 100644 --- a/resources/extruders/cartesio_extruder_0.def.json +++ b/resources/extruders/cartesio_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "cartesio_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/cartesio_extruder_1.def.json b/resources/extruders/cartesio_extruder_1.def.json index 3d49a220c0..1699a9c6a8 100644 --- a/resources/extruders/cartesio_extruder_1.def.json +++ b/resources/extruders/cartesio_extruder_1.def.json @@ -1,5 +1,4 @@ { - "id": "cartesio_extruder_1", "version": 2, "name": "Extruder 2", "inherits": "fdmextruder", diff --git a/resources/extruders/cartesio_extruder_2.def.json b/resources/extruders/cartesio_extruder_2.def.json index 1f8f8b9ca9..2521ada681 100644 --- a/resources/extruders/cartesio_extruder_2.def.json +++ b/resources/extruders/cartesio_extruder_2.def.json @@ -1,5 +1,4 @@ { - "id": "cartesio_extruder_2", "version": 2, "name": "Extruder 3", "inherits": "fdmextruder", diff --git a/resources/extruders/cartesio_extruder_3.def.json b/resources/extruders/cartesio_extruder_3.def.json index 0b1cfe493e..c844e7ce54 100644 --- a/resources/extruders/cartesio_extruder_3.def.json +++ b/resources/extruders/cartesio_extruder_3.def.json @@ -1,5 +1,4 @@ { - "id": "cartesio_extruder_3", "version": 2, "name": "Extruder 4", "inherits": "fdmextruder", diff --git a/resources/extruders/cocoon_create_modelmaker_extruder_0.def.json b/resources/extruders/cocoon_create_modelmaker_extruder_0.def.json index 26d847483d..dfa06c776a 100644 --- a/resources/extruders/cocoon_create_modelmaker_extruder_0.def.json +++ b/resources/extruders/cocoon_create_modelmaker_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "cocoon_create_modelmaker_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/cr-x_extruder_0.def.json b/resources/extruders/cr-x_extruder_0.def.json index 8135815afb..4e73fd0e8e 100644 --- a/resources/extruders/cr-x_extruder_0.def.json +++ b/resources/extruders/cr-x_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "cr-x_extruder_0", "version": 2, "name": "Left Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/cr-x_extruder_1.def.json b/resources/extruders/cr-x_extruder_1.def.json index 9313f2ea78..ed6056dab9 100644 --- a/resources/extruders/cr-x_extruder_1.def.json +++ b/resources/extruders/cr-x_extruder_1.def.json @@ -1,5 +1,4 @@ { - "id": "cr-x_extruder_1", "version": 2, "name": "Right Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/creatable_d3_extruder_0.def.json b/resources/extruders/creatable_d3_extruder_0.def.json index 7d45bb8e8a..6a805febd5 100644 --- a/resources/extruders/creatable_d3_extruder_0.def.json +++ b/resources/extruders/creatable_d3_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "creatable_d3_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/cubicon_3dp_110f_extruder_0.def.json b/resources/extruders/cubicon_3dp_110f_extruder_0.def.json index 9c854fd2a1..048c12b992 100644 --- a/resources/extruders/cubicon_3dp_110f_extruder_0.def.json +++ b/resources/extruders/cubicon_3dp_110f_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "cubicon_3dp_110f_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/cubicon_3dp_210f_extruder_0.def.json b/resources/extruders/cubicon_3dp_210f_extruder_0.def.json index 8a8573760a..07fe7f3769 100644 --- a/resources/extruders/cubicon_3dp_210f_extruder_0.def.json +++ b/resources/extruders/cubicon_3dp_210f_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "cubicon_3dp_210f_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/cubicon_3dp_310f_extruder_0.def.json b/resources/extruders/cubicon_3dp_310f_extruder_0.def.json index 4edbbd5a6c..8dc336877f 100644 --- a/resources/extruders/cubicon_3dp_310f_extruder_0.def.json +++ b/resources/extruders/cubicon_3dp_310f_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "cubicon_3dp_310f_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/cubicon_dual_pro_a30_extruder_0.def.json b/resources/extruders/cubicon_dual_pro_a30_extruder_0.def.json index 689be873e0..6c8993e799 100644 --- a/resources/extruders/cubicon_dual_pro_a30_extruder_0.def.json +++ b/resources/extruders/cubicon_dual_pro_a30_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "cubicon_dual_pro_a30_extruder_1", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/cubicon_dual_pro_a30_extruder_1.def.json b/resources/extruders/cubicon_dual_pro_a30_extruder_1.def.json index c01a05a894..ccdfdee1f7 100644 --- a/resources/extruders/cubicon_dual_pro_a30_extruder_1.def.json +++ b/resources/extruders/cubicon_dual_pro_a30_extruder_1.def.json @@ -1,5 +1,4 @@ { - "id": "cubicon_dual_pro_a30_extruder_2", "version": 2, "name": "Extruder 2", "inherits": "fdmextruder", diff --git a/resources/extruders/cubicon_style_plus_a15_extruder_0.def.json b/resources/extruders/cubicon_style_plus_a15_extruder_0.def.json index 18621ba429..12d022cd1e 100644 --- a/resources/extruders/cubicon_style_plus_a15_extruder_0.def.json +++ b/resources/extruders/cubicon_style_plus_a15_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "cubicon_style_plus_a15_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/custom_extruder_1.def.json b/resources/extruders/custom_extruder_1.def.json index 859c6a2f22..942f3e96b9 100644 --- a/resources/extruders/custom_extruder_1.def.json +++ b/resources/extruders/custom_extruder_1.def.json @@ -1,5 +1,4 @@ { - "id": "custom_extruder_1", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/custom_extruder_2.def.json b/resources/extruders/custom_extruder_2.def.json index eecda5dfcd..cd43efa994 100644 --- a/resources/extruders/custom_extruder_2.def.json +++ b/resources/extruders/custom_extruder_2.def.json @@ -1,5 +1,4 @@ { - "id": "custom_extruder_2", "version": 2, "name": "Extruder 2", "inherits": "fdmextruder", diff --git a/resources/extruders/custom_extruder_3.def.json b/resources/extruders/custom_extruder_3.def.json index 77909ec05d..be5bdd0e6a 100644 --- a/resources/extruders/custom_extruder_3.def.json +++ b/resources/extruders/custom_extruder_3.def.json @@ -1,5 +1,4 @@ { - "id": "custom_extruder_3", "version": 2, "name": "Extruder 3", "inherits": "fdmextruder", diff --git a/resources/extruders/custom_extruder_4.def.json b/resources/extruders/custom_extruder_4.def.json index be792c3a8e..ce1df0a5f5 100644 --- a/resources/extruders/custom_extruder_4.def.json +++ b/resources/extruders/custom_extruder_4.def.json @@ -1,5 +1,4 @@ { - "id": "custom_extruder_4", "version": 2, "name": "Extruder 4", "inherits": "fdmextruder", diff --git a/resources/extruders/custom_extruder_5.def.json b/resources/extruders/custom_extruder_5.def.json index ea64605041..beb4786505 100644 --- a/resources/extruders/custom_extruder_5.def.json +++ b/resources/extruders/custom_extruder_5.def.json @@ -1,5 +1,4 @@ { - "id": "custom_extruder_5", "version": 2, "name": "Extruder 5", "inherits": "fdmextruder", diff --git a/resources/extruders/custom_extruder_6.def.json b/resources/extruders/custom_extruder_6.def.json index fd27fadace..7f1e1a1343 100644 --- a/resources/extruders/custom_extruder_6.def.json +++ b/resources/extruders/custom_extruder_6.def.json @@ -1,5 +1,4 @@ { - "id": "custom_extruder_6", "version": 2, "name": "Extruder 6", "inherits": "fdmextruder", diff --git a/resources/extruders/custom_extruder_7.def.json b/resources/extruders/custom_extruder_7.def.json index cf003d1a6b..e4239f35f0 100644 --- a/resources/extruders/custom_extruder_7.def.json +++ b/resources/extruders/custom_extruder_7.def.json @@ -1,5 +1,4 @@ { - "id": "custom_extruder_7", "version": 2, "name": "Extruder 7", "inherits": "fdmextruder", diff --git a/resources/extruders/custom_extruder_8.def.json b/resources/extruders/custom_extruder_8.def.json index f418a55186..7671825792 100644 --- a/resources/extruders/custom_extruder_8.def.json +++ b/resources/extruders/custom_extruder_8.def.json @@ -1,5 +1,4 @@ { - "id": "custom_extruder_8", "version": 2, "name": "Extruder 8", "inherits": "fdmextruder", diff --git a/resources/extruders/delta_go_extruder_0.def.json b/resources/extruders/delta_go_extruder_0.def.json index 2262270dfb..330cde08bf 100644 --- a/resources/extruders/delta_go_extruder_0.def.json +++ b/resources/extruders/delta_go_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "delta_go_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/deltabot_extruder_0.def.json b/resources/extruders/deltabot_extruder_0.def.json index e13d6a6ee3..d4773ccf9f 100644 --- a/resources/extruders/deltabot_extruder_0.def.json +++ b/resources/extruders/deltabot_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "deltabot_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/deltacomb_extruder_0.def.json b/resources/extruders/deltacomb_extruder_0.def.json index 64c512b7fe..875655d5c7 100755 --- a/resources/extruders/deltacomb_extruder_0.def.json +++ b/resources/extruders/deltacomb_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "deltacomb_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/deltacomb_extruder_1.def.json b/resources/extruders/deltacomb_extruder_1.def.json index 1657688482..b1f30f4624 100755 --- a/resources/extruders/deltacomb_extruder_1.def.json +++ b/resources/extruders/deltacomb_extruder_1.def.json @@ -1,5 +1,4 @@ { - "id": "deltacomb_extruder_1", "version": 2, "name": "Extruder 2", "inherits": "fdmextruder", diff --git a/resources/extruders/easyarts_ares_extruder_0.def.json b/resources/extruders/easyarts_ares_extruder_0.def.json index ec7ba81c57..4ddd476dbb 100644 --- a/resources/extruders/easyarts_ares_extruder_0.def.json +++ b/resources/extruders/easyarts_ares_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "easyarts_ares_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/erzay3d_extruder_0.def.json b/resources/extruders/erzay3d_extruder_0.def.json index 65bf515263..a9cea62897 100644 --- a/resources/extruders/erzay3d_extruder_0.def.json +++ b/resources/extruders/erzay3d_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "erzay3d_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/fabtotum_extruder_0.def.json b/resources/extruders/fabtotum_extruder_0.def.json index 5ed4da6256..a763fbcc15 100644 --- a/resources/extruders/fabtotum_extruder_0.def.json +++ b/resources/extruders/fabtotum_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "fabtotum_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/felixpro2_dual_extruder_0.def.json b/resources/extruders/felixpro2_dual_extruder_0.def.json index 90c41a83b5..4278a532f9 100644 --- a/resources/extruders/felixpro2_dual_extruder_0.def.json +++ b/resources/extruders/felixpro2_dual_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "felixpro2_dual_extruder_0", "version": 2, "name": "Left Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/felixpro2_dual_extruder_1.def.json b/resources/extruders/felixpro2_dual_extruder_1.def.json index 3ff0d401fd..195aad474d 100644 --- a/resources/extruders/felixpro2_dual_extruder_1.def.json +++ b/resources/extruders/felixpro2_dual_extruder_1.def.json @@ -1,5 +1,4 @@ { - "id": "felixpro2_dual_extruder_1", "version": 2, "name": "Right Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/felixtec4_dual_extruder_0.def.json b/resources/extruders/felixtec4_dual_extruder_0.def.json index 2a2d0468e1..1821b0e601 100644 --- a/resources/extruders/felixtec4_dual_extruder_0.def.json +++ b/resources/extruders/felixtec4_dual_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "felixtec4_dual_extruder_0", "version": 2, "name": "Left Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/felixtec4_dual_extruder_1.def.json b/resources/extruders/felixtec4_dual_extruder_1.def.json index 5d7e9c74a3..37a99c5fb4 100644 --- a/resources/extruders/felixtec4_dual_extruder_1.def.json +++ b/resources/extruders/felixtec4_dual_extruder_1.def.json @@ -1,5 +1,4 @@ { - "id": "felixtec4_dual_extruder_1", "version": 2, "name": "Right Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/flsun_qq_extruder.def.json b/resources/extruders/flsun_qq_extruder.def.json index 7c93776836..c7ca0ed6eb 100644 --- a/resources/extruders/flsun_qq_extruder.def.json +++ b/resources/extruders/flsun_qq_extruder.def.json @@ -1,5 +1,4 @@ { - "id": "flsun_qq_extruder", "version": 2, "name": "Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/flsun_qq_s_extruder_0.def.json b/resources/extruders/flsun_qq_s_extruder_0.def.json index cba424e182..e61056fcd3 100644 --- a/resources/extruders/flsun_qq_s_extruder_0.def.json +++ b/resources/extruders/flsun_qq_s_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "flsun_qq_s_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/folgertech_FT-5_extruder_0.def.json b/resources/extruders/folgertech_FT-5_extruder_0.def.json index 8ba9d130c6..861b0e7a7e 100644 --- a/resources/extruders/folgertech_FT-5_extruder_0.def.json +++ b/resources/extruders/folgertech_FT-5_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "folgertech_FT-5_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/geeetech_a30_extruder_0.def.json b/resources/extruders/geeetech_a30_extruder_0.def.json index bc1d6a6ed6..90cb496877 100644 --- a/resources/extruders/geeetech_a30_extruder_0.def.json +++ b/resources/extruders/geeetech_a30_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "geeetech_a30_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/gmax15plus_dual_extruder_0.def.json b/resources/extruders/gmax15plus_dual_extruder_0.def.json index d3146a0576..45f35dee1f 100644 --- a/resources/extruders/gmax15plus_dual_extruder_0.def.json +++ b/resources/extruders/gmax15plus_dual_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "gmax15plus_dual_extruder_0", "version": 2, "name": "Left Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/gmax15plus_dual_extruder_1.def.json b/resources/extruders/gmax15plus_dual_extruder_1.def.json index 7b7354d794..6d0d5db06f 100644 --- a/resources/extruders/gmax15plus_dual_extruder_1.def.json +++ b/resources/extruders/gmax15plus_dual_extruder_1.def.json @@ -1,5 +1,4 @@ { - "id": "gmax15plus_dual_extruder_1", "version": 2, "name": "Right Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/gmax15plus_extruder_0.def.json b/resources/extruders/gmax15plus_extruder_0.def.json index 70389745b3..5b0889d46d 100644 --- a/resources/extruders/gmax15plus_extruder_0.def.json +++ b/resources/extruders/gmax15plus_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "gmax15plus_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/grr_neo_extruder_0.def.json b/resources/extruders/grr_neo_extruder_0.def.json index 6d76c90796..a9f1fa4faa 100644 --- a/resources/extruders/grr_neo_extruder_0.def.json +++ b/resources/extruders/grr_neo_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "grr_neo_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/hBp_extruder_left.def.json b/resources/extruders/hBp_extruder_left.def.json index 7e71ca27a8..ce23f27c29 100644 --- a/resources/extruders/hBp_extruder_left.def.json +++ b/resources/extruders/hBp_extruder_left.def.json @@ -1,5 +1,4 @@ { - "id": "hBp_extruder_left", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/hBp_extruder_right.def.json b/resources/extruders/hBp_extruder_right.def.json index acd2312268..170556a1fd 100644 --- a/resources/extruders/hBp_extruder_right.def.json +++ b/resources/extruders/hBp_extruder_right.def.json @@ -1,5 +1,4 @@ { - "id": "hBp_extruder_right", "version": 2, "name": "Extruder 2", "inherits": "fdmextruder", diff --git a/resources/extruders/hms434_tool_1.def.json b/resources/extruders/hms434_tool_1.def.json index c1e20140f3..3a1619d98b 100644 --- a/resources/extruders/hms434_tool_1.def.json +++ b/resources/extruders/hms434_tool_1.def.json @@ -1,5 +1,4 @@ { - "id": "hms434_tool_1", "version": 2, "name": "Tool 1", "inherits": "fdmextruder", diff --git a/resources/extruders/hms434_tool_2.def.json b/resources/extruders/hms434_tool_2.def.json index a2015006dc..3a174f82b9 100644 --- a/resources/extruders/hms434_tool_2.def.json +++ b/resources/extruders/hms434_tool_2.def.json @@ -1,5 +1,4 @@ { - "id": "hms434_tool_2", "version": 2, "name": "Tool 2", "inherits": "fdmextruder", diff --git a/resources/extruders/hms434_tool_3.def.json b/resources/extruders/hms434_tool_3.def.json index b0199d5523..e1e237d332 100644 --- a/resources/extruders/hms434_tool_3.def.json +++ b/resources/extruders/hms434_tool_3.def.json @@ -1,5 +1,4 @@ { - "id": "hms434_tool_3", "version": 2, "name": "Tool 3", "inherits": "fdmextruder", diff --git a/resources/extruders/hms434_tool_4.def.json b/resources/extruders/hms434_tool_4.def.json index 9346dafd67..1a68d5aff5 100644 --- a/resources/extruders/hms434_tool_4.def.json +++ b/resources/extruders/hms434_tool_4.def.json @@ -1,5 +1,4 @@ { - "id": "hms434_tool_4", "version": 2, "name": "Tool 4", "inherits": "fdmextruder", diff --git a/resources/extruders/hms434_tool_5.def.json b/resources/extruders/hms434_tool_5.def.json index 051227fb1b..b56e8be84e 100644 --- a/resources/extruders/hms434_tool_5.def.json +++ b/resources/extruders/hms434_tool_5.def.json @@ -1,5 +1,4 @@ { - "id": "hms434_tool_5", "version": 2, "name": "Tool 5", "inherits": "fdmextruder", diff --git a/resources/extruders/hms434_tool_6.def.json b/resources/extruders/hms434_tool_6.def.json index 056bb66741..b8c8cdf062 100644 --- a/resources/extruders/hms434_tool_6.def.json +++ b/resources/extruders/hms434_tool_6.def.json @@ -1,5 +1,4 @@ { - "id": "hms434_tool_6", "version": 2, "name": "Tool 6", "inherits": "fdmextruder", diff --git a/resources/extruders/hms434_tool_7.def.json b/resources/extruders/hms434_tool_7.def.json index ff8f938e1c..3fc04078fa 100644 --- a/resources/extruders/hms434_tool_7.def.json +++ b/resources/extruders/hms434_tool_7.def.json @@ -1,5 +1,4 @@ { - "id": "hms434_tool_7", "version": 2, "name": "Tool 7", "inherits": "fdmextruder", diff --git a/resources/extruders/hms434_tool_8.def.json b/resources/extruders/hms434_tool_8.def.json index 2e9302e26c..faa6f36871 100644 --- a/resources/extruders/hms434_tool_8.def.json +++ b/resources/extruders/hms434_tool_8.def.json @@ -1,5 +1,4 @@ { - "id": "hms434_tool_8", "version": 2, "name": "Tool 8", "inherits": "fdmextruder", diff --git a/resources/extruders/imade3d_jellybox_2_extruder_0.def.json b/resources/extruders/imade3d_jellybox_2_extruder_0.def.json index 1d50297343..ca25b62286 100644 --- a/resources/extruders/imade3d_jellybox_2_extruder_0.def.json +++ b/resources/extruders/imade3d_jellybox_2_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "imade3d_jellybox_2_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/imade3d_jellybox_extruder_0.def.json b/resources/extruders/imade3d_jellybox_extruder_0.def.json index feaa717ee6..69c6d87d79 100644 --- a/resources/extruders/imade3d_jellybox_extruder_0.def.json +++ b/resources/extruders/imade3d_jellybox_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "imade3d_jellybox_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/innovo_inventor_extruder_0.def.json b/resources/extruders/innovo_inventor_extruder_0.def.json index ed599463f2..8758f3d516 100644 --- a/resources/extruders/innovo_inventor_extruder_0.def.json +++ b/resources/extruders/innovo_inventor_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "innovo_inventor_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/jgaurora_a1_extruder_0.def.json b/resources/extruders/jgaurora_a1_extruder_0.def.json index 71742b734a..f67d8d553e 100644 --- a/resources/extruders/jgaurora_a1_extruder_0.def.json +++ b/resources/extruders/jgaurora_a1_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "jgaurora_a1_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/jgaurora_a3s_extruder_0.def.json b/resources/extruders/jgaurora_a3s_extruder_0.def.json index 430867b38b..9a42d0da04 100644 --- a/resources/extruders/jgaurora_a3s_extruder_0.def.json +++ b/resources/extruders/jgaurora_a3s_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "jgaurora_a3s_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/jgaurora_a5_extruder_0.def.json b/resources/extruders/jgaurora_a5_extruder_0.def.json index fbc6ba77e6..5308c57934 100644 --- a/resources/extruders/jgaurora_a5_extruder_0.def.json +++ b/resources/extruders/jgaurora_a5_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "jgaurora_a5_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/jgaurora_jgmaker_magic_extruder_0.def.json b/resources/extruders/jgaurora_jgmaker_magic_extruder_0.def.json index 41593a4821..58beaa4cc8 100644 --- a/resources/extruders/jgaurora_jgmaker_magic_extruder_0.def.json +++ b/resources/extruders/jgaurora_jgmaker_magic_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "jgaurora_jgmaker_magic_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/jgaurora_z_603s_extruder_0.def.json b/resources/extruders/jgaurora_z_603s_extruder_0.def.json index 987425b28a..647016d5ff 100644 --- a/resources/extruders/jgaurora_z_603s_extruder_0.def.json +++ b/resources/extruders/jgaurora_z_603s_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "jgaurora_z_603s_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/julia_extruder_0.def.json b/resources/extruders/julia_extruder_0.def.json index 53a569ccd8..ef0ca83ac4 100644 --- a/resources/extruders/julia_extruder_0.def.json +++ b/resources/extruders/julia_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "julia_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/kemiq_q2_beta_extruder_0.def.json b/resources/extruders/kemiq_q2_beta_extruder_0.def.json index 0c7d1b7b50..79d55223f3 100644 --- a/resources/extruders/kemiq_q2_beta_extruder_0.def.json +++ b/resources/extruders/kemiq_q2_beta_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "kemiq_q2_beta_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/kemiq_q2_gama_extruder_0.def.json b/resources/extruders/kemiq_q2_gama_extruder_0.def.json index bb165ca35e..ad6e6372ee 100644 --- a/resources/extruders/kemiq_q2_gama_extruder_0.def.json +++ b/resources/extruders/kemiq_q2_gama_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "kemiq_q2_gama_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/key3d_tyro_extruder_0.def.json b/resources/extruders/key3d_tyro_extruder_0.def.json index 6d5b83a1ef..11619da332 100644 --- a/resources/extruders/key3d_tyro_extruder_0.def.json +++ b/resources/extruders/key3d_tyro_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "key3d_tyro_extruder_0", "version": 2, "name": "0.4mm Nozzle", "inherits": "fdmextruder", diff --git a/resources/extruders/kossel_mini_extruder_0.def.json b/resources/extruders/kossel_mini_extruder_0.def.json index f57154e1a3..7da2cff3b1 100644 --- a/resources/extruders/kossel_mini_extruder_0.def.json +++ b/resources/extruders/kossel_mini_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "kossel_mini_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/kossel_pro_extruder_0.def.json b/resources/extruders/kossel_pro_extruder_0.def.json index 921e1d8bb4..48c1180f84 100644 --- a/resources/extruders/kossel_pro_extruder_0.def.json +++ b/resources/extruders/kossel_pro_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "kossel_pro_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/kupido_extruder_0.def.json b/resources/extruders/kupido_extruder_0.def.json index ef988d4fde..784e453bd1 100644 --- a/resources/extruders/kupido_extruder_0.def.json +++ b/resources/extruders/kupido_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "kupido_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/makeR_pegasus_extruder_0.def.json b/resources/extruders/makeR_pegasus_extruder_0.def.json index e37891abde..c17c51d599 100644 --- a/resources/extruders/makeR_pegasus_extruder_0.def.json +++ b/resources/extruders/makeR_pegasus_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "makeR_pegasus_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/makeR_prusa_tairona_i3_extruder_0.def.json b/resources/extruders/makeR_prusa_tairona_i3_extruder_0.def.json index a80d4079cb..278981f355 100644 --- a/resources/extruders/makeR_prusa_tairona_i3_extruder_0.def.json +++ b/resources/extruders/makeR_prusa_tairona_i3_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "makeR_prusa_tairona_i3_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/makeit_dual_1st.def.json b/resources/extruders/makeit_dual_1st.def.json index 0f5a716e16..16374b40d1 100644 --- a/resources/extruders/makeit_dual_1st.def.json +++ b/resources/extruders/makeit_dual_1st.def.json @@ -1,5 +1,4 @@ { - "id": "makeit_dual_1st", "version": 2, "name": "1st Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/makeit_dual_2nd.def.json b/resources/extruders/makeit_dual_2nd.def.json index f93d670c85..562cfcbc40 100644 --- a/resources/extruders/makeit_dual_2nd.def.json +++ b/resources/extruders/makeit_dual_2nd.def.json @@ -1,5 +1,4 @@ { - "id": "makeit_dual_2nd", "version": 2, "name": "2nd Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/makeit_l_dual_1st.def.json b/resources/extruders/makeit_l_dual_1st.def.json index 6a9e8e3fc1..8fbc2944b1 100644 --- a/resources/extruders/makeit_l_dual_1st.def.json +++ b/resources/extruders/makeit_l_dual_1st.def.json @@ -1,5 +1,4 @@ { - "id": "makeit_l_dual_1st", "version": 2, "name": "1st Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/makeit_l_dual_2nd.def.json b/resources/extruders/makeit_l_dual_2nd.def.json index 72b86b22e4..e163e9565a 100644 --- a/resources/extruders/makeit_l_dual_2nd.def.json +++ b/resources/extruders/makeit_l_dual_2nd.def.json @@ -1,5 +1,4 @@ { - "id": "makeit_l_dual_2nd", "version": 2, "name": "2nd Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/maker_starter_extruder_0.def.json b/resources/extruders/maker_starter_extruder_0.def.json index ee94250248..76e2f74a4c 100644 --- a/resources/extruders/maker_starter_extruder_0.def.json +++ b/resources/extruders/maker_starter_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "maker_starter_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/makerbotreplicator_extruder_0.def.json b/resources/extruders/makerbotreplicator_extruder_0.def.json index 36a975ace1..595134d788 100644 --- a/resources/extruders/makerbotreplicator_extruder_0.def.json +++ b/resources/extruders/makerbotreplicator_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "makerbotreplicator_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/malyan_m180_extruder_0.def.json b/resources/extruders/malyan_m180_extruder_0.def.json index bdf5350b26..04bc70ce55 100644 --- a/resources/extruders/malyan_m180_extruder_0.def.json +++ b/resources/extruders/malyan_m180_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "malyan_m180_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/malyan_m200_extruder_0.def.json b/resources/extruders/malyan_m200_extruder_0.def.json index 4a135aa72d..88d99fb426 100644 --- a/resources/extruders/malyan_m200_extruder_0.def.json +++ b/resources/extruders/malyan_m200_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "malyan_m200_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/mankati_fullscale_xt_plus_extruder_0.def.json b/resources/extruders/mankati_fullscale_xt_plus_extruder_0.def.json index 032a577022..4cb893336e 100644 --- a/resources/extruders/mankati_fullscale_xt_plus_extruder_0.def.json +++ b/resources/extruders/mankati_fullscale_xt_plus_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "mankati_fullscale_xt_plus_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/mendel90_extruder_0.def.json b/resources/extruders/mendel90_extruder_0.def.json index 3ee2fd2b10..2ea4d9a7de 100644 --- a/resources/extruders/mendel90_extruder_0.def.json +++ b/resources/extruders/mendel90_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "mendel90_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/monoprice_select_mini_v1_extruder_0.def.json b/resources/extruders/monoprice_select_mini_v1_extruder_0.def.json index e4a899d7af..023bd6b27c 100644 --- a/resources/extruders/monoprice_select_mini_v1_extruder_0.def.json +++ b/resources/extruders/monoprice_select_mini_v1_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "monoprice_select_mini_v1_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/monoprice_select_mini_v2_extruder_0.def.json b/resources/extruders/monoprice_select_mini_v2_extruder_0.def.json index b727cfce1f..79ba110701 100644 --- a/resources/extruders/monoprice_select_mini_v2_extruder_0.def.json +++ b/resources/extruders/monoprice_select_mini_v2_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "monoprice_select_mini_v2_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/nwa3d_a31_extruder_0.def.json b/resources/extruders/nwa3d_a31_extruder_0.def.json index 999fe37d28..de1938956a 100644 --- a/resources/extruders/nwa3d_a31_extruder_0.def.json +++ b/resources/extruders/nwa3d_a31_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "nwa3d_a31_extruder_0", "version": 2, "name": "Standard 0.4mm", "inherits": "fdmextruder", diff --git a/resources/extruders/nwa3d_a5_extruder_0.def.json b/resources/extruders/nwa3d_a5_extruder_0.def.json index 5c3cc6a127..9131480732 100644 --- a/resources/extruders/nwa3d_a5_extruder_0.def.json +++ b/resources/extruders/nwa3d_a5_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "nwa3d_a5_extruder_0", "version": 2, "name": "Regular 0.4mm Nozzle", "inherits": "fdmextruder", diff --git a/resources/extruders/ord_extruder_0.def.json b/resources/extruders/ord_extruder_0.def.json index 317ad70a3c..61317c4a17 100644 --- a/resources/extruders/ord_extruder_0.def.json +++ b/resources/extruders/ord_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "ord_extruder_0", "version": 2, "name": "0", "inherits": "fdmextruder", diff --git a/resources/extruders/ord_extruder_1.def.json b/resources/extruders/ord_extruder_1.def.json index 6e29ad2f2b..43bc11fa71 100644 --- a/resources/extruders/ord_extruder_1.def.json +++ b/resources/extruders/ord_extruder_1.def.json @@ -1,5 +1,4 @@ { - "id": "ord_extruder_1", "version": 2, "name": "1", "inherits": "fdmextruder", diff --git a/resources/extruders/ord_extruder_2.def.json b/resources/extruders/ord_extruder_2.def.json index 849930c988..84bcbd5332 100644 --- a/resources/extruders/ord_extruder_2.def.json +++ b/resources/extruders/ord_extruder_2.def.json @@ -1,5 +1,4 @@ { - "id": "ord_extruder_2", "version": 2, "name": "2", "inherits": "fdmextruder", diff --git a/resources/extruders/ord_extruder_3.def.json b/resources/extruders/ord_extruder_3.def.json index eb3676c14f..db81f82b78 100644 --- a/resources/extruders/ord_extruder_3.def.json +++ b/resources/extruders/ord_extruder_3.def.json @@ -1,5 +1,4 @@ { - "id": "ord_extruder_3", "version": 2, "name": "3", "inherits": "fdmextruder", diff --git a/resources/extruders/ord_extruder_4.def.json b/resources/extruders/ord_extruder_4.def.json index 291e9e5501..2ca7609e06 100644 --- a/resources/extruders/ord_extruder_4.def.json +++ b/resources/extruders/ord_extruder_4.def.json @@ -1,5 +1,4 @@ { - "id": "ord_extruder_4", "version": 2, "name": "4", "inherits": "fdmextruder", diff --git a/resources/extruders/peopoly_moai_extruder_0.def.json b/resources/extruders/peopoly_moai_extruder_0.def.json index bbffd4ac4d..1acf5b499f 100644 --- a/resources/extruders/peopoly_moai_extruder_0.def.json +++ b/resources/extruders/peopoly_moai_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "peopoly_moai_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/printrbot_play_extruder_0.def.json b/resources/extruders/printrbot_play_extruder_0.def.json index ef1284758b..682810c8d8 100644 --- a/resources/extruders/printrbot_play_extruder_0.def.json +++ b/resources/extruders/printrbot_play_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "printrbot_play_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/printrbot_play_heated_extruder_0.def.json b/resources/extruders/printrbot_play_heated_extruder_0.def.json index 0a3eeb3d06..72335e82d6 100644 --- a/resources/extruders/printrbot_play_heated_extruder_0.def.json +++ b/resources/extruders/printrbot_play_heated_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "printrbot_play_heated_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/printrbot_simple_extended_extruder_0.def.json b/resources/extruders/printrbot_simple_extended_extruder_0.def.json index 71c8863552..b50a142d2e 100644 --- a/resources/extruders/printrbot_simple_extended_extruder_0.def.json +++ b/resources/extruders/printrbot_simple_extended_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "printrbot_simple_extended_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/printrbot_simple_extruder_0.def.json b/resources/extruders/printrbot_simple_extruder_0.def.json index e97977e07e..4fa5d7fbf2 100644 --- a/resources/extruders/printrbot_simple_extruder_0.def.json +++ b/resources/extruders/printrbot_simple_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "printrbot_simple_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/printrbot_simple_makers_kit_extruder_0.def.json b/resources/extruders/printrbot_simple_makers_kit_extruder_0.def.json index f002bb9cf5..a58195fdfb 100644 --- a/resources/extruders/printrbot_simple_makers_kit_extruder_0.def.json +++ b/resources/extruders/printrbot_simple_makers_kit_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "printrbot_simple_makers_kit_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/prusa_i3_extruder_0.def.json b/resources/extruders/prusa_i3_extruder_0.def.json index 11c52e062b..dbb01032b8 100644 --- a/resources/extruders/prusa_i3_extruder_0.def.json +++ b/resources/extruders/prusa_i3_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "prusa_i3_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/prusa_i3_mk2_extruder_0.def.json b/resources/extruders/prusa_i3_mk2_extruder_0.def.json index a56aae4300..e802687062 100644 --- a/resources/extruders/prusa_i3_mk2_extruder_0.def.json +++ b/resources/extruders/prusa_i3_mk2_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "prusa_i3_mk2_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/prusa_i3_xl_extruder_0.def.json b/resources/extruders/prusa_i3_xl_extruder_0.def.json index 5dc2ab3bc0..c4125b36ee 100644 --- a/resources/extruders/prusa_i3_xl_extruder_0.def.json +++ b/resources/extruders/prusa_i3_xl_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "prusa_i3_xl_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/punchtec_connect_xl_extruder_0.def.json b/resources/extruders/punchtec_connect_xl_extruder_0.def.json index 68c3d8c906..f286140167 100644 --- a/resources/extruders/punchtec_connect_xl_extruder_0.def.json +++ b/resources/extruders/punchtec_connect_xl_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "punchtec_connect_xl_extruder_0", "version": 2, "name": "0", "inherits": "fdmextruder", diff --git a/resources/extruders/punchtec_connect_xl_extruder_1.def.json b/resources/extruders/punchtec_connect_xl_extruder_1.def.json index a2e4b31714..47d28882cf 100644 --- a/resources/extruders/punchtec_connect_xl_extruder_1.def.json +++ b/resources/extruders/punchtec_connect_xl_extruder_1.def.json @@ -1,5 +1,4 @@ { - "id": "punchtec_connect_xl_extruder_1", "version": 2, "name": "1", "inherits": "fdmextruder", diff --git a/resources/extruders/raise3D_N2_dual_extruder_0.def.json b/resources/extruders/raise3D_N2_dual_extruder_0.def.json index 48746969d3..9294a73933 100644 --- a/resources/extruders/raise3D_N2_dual_extruder_0.def.json +++ b/resources/extruders/raise3D_N2_dual_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "raise3D_N2_dual_extruder_0", "version": 2, "name": "Left Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/raise3D_N2_dual_extruder_1.def.json b/resources/extruders/raise3D_N2_dual_extruder_1.def.json index 8ea6f95b16..e09cb6b9fc 100644 --- a/resources/extruders/raise3D_N2_dual_extruder_1.def.json +++ b/resources/extruders/raise3D_N2_dual_extruder_1.def.json @@ -1,5 +1,4 @@ { - "id": "raise3D_N2_dual_extruder_1", "version": 2, "name": "Right Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/raise3D_N2_plus_dual_extruder_0.def.json b/resources/extruders/raise3D_N2_plus_dual_extruder_0.def.json index fc7531cf1b..d8821204f0 100644 --- a/resources/extruders/raise3D_N2_plus_dual_extruder_0.def.json +++ b/resources/extruders/raise3D_N2_plus_dual_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "raise3D_N2_plus_dual_extruder_0", "version": 2, "name": "Left Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/raise3D_N2_plus_dual_extruder_1.def.json b/resources/extruders/raise3D_N2_plus_dual_extruder_1.def.json index 83f949bb22..0a6ded63a3 100644 --- a/resources/extruders/raise3D_N2_plus_dual_extruder_1.def.json +++ b/resources/extruders/raise3D_N2_plus_dual_extruder_1.def.json @@ -1,5 +1,4 @@ { - "id": "raise3D_N2_plus_dual_extruder_1", "version": 2, "name": "Right Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/raise3D_N2_single_extruder_0.def.json b/resources/extruders/raise3D_N2_single_extruder_0.def.json index 08fedff99c..399d577110 100644 --- a/resources/extruders/raise3D_N2_single_extruder_0.def.json +++ b/resources/extruders/raise3D_N2_single_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "raise3D_N2_single_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/renkforce_rf100_extruder_0.def.json b/resources/extruders/renkforce_rf100_extruder_0.def.json index 6a7f883309..ff64e2f86a 100644 --- a/resources/extruders/renkforce_rf100_extruder_0.def.json +++ b/resources/extruders/renkforce_rf100_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "renkforce_rf100_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/rigid3d_3rdgen_extruder_0.def.json b/resources/extruders/rigid3d_3rdgen_extruder_0.def.json index e309086a72..edc87f695e 100644 --- a/resources/extruders/rigid3d_3rdgen_extruder_0.def.json +++ b/resources/extruders/rigid3d_3rdgen_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "rigid3d_3rdgen_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/rigid3d_extruder_0.def.json b/resources/extruders/rigid3d_extruder_0.def.json index e34987cd6e..eaac6b16a0 100644 --- a/resources/extruders/rigid3d_extruder_0.def.json +++ b/resources/extruders/rigid3d_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "rigid3d_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/rigid3d_hobby_extruder_0.def.json b/resources/extruders/rigid3d_hobby_extruder_0.def.json index 681aeecb43..68dd523af3 100644 --- a/resources/extruders/rigid3d_hobby_extruder_0.def.json +++ b/resources/extruders/rigid3d_hobby_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "rigid3d_hobby_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/rigid3d_mucit_extruder_0.def.json b/resources/extruders/rigid3d_mucit_extruder_0.def.json index af3f54e150..de72db7a33 100644 --- a/resources/extruders/rigid3d_mucit_extruder_0.def.json +++ b/resources/extruders/rigid3d_mucit_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "rigid3d_mucit_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/rigid3d_zero2_extruder_0.def.json b/resources/extruders/rigid3d_zero2_extruder_0.def.json index 30d1dbb3c4..051ce2384d 100644 --- a/resources/extruders/rigid3d_zero2_extruder_0.def.json +++ b/resources/extruders/rigid3d_zero2_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "rigid3d_zero2_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/rigid3d_zero_extruder_0.def.json b/resources/extruders/rigid3d_zero_extruder_0.def.json index 6c5ae10ddb..76a8fceaae 100644 --- a/resources/extruders/rigid3d_zero_extruder_0.def.json +++ b/resources/extruders/rigid3d_zero_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "rigid3d_zero_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/rigidbot_big_extruder_0.def.json b/resources/extruders/rigidbot_big_extruder_0.def.json index 2b07adaaaa..9ef72d5203 100644 --- a/resources/extruders/rigidbot_big_extruder_0.def.json +++ b/resources/extruders/rigidbot_big_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "rigidbot_big_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/rigidbot_extruder_0.def.json b/resources/extruders/rigidbot_extruder_0.def.json index 32ce3fc1c3..9155be0ff1 100644 --- a/resources/extruders/rigidbot_extruder_0.def.json +++ b/resources/extruders/rigidbot_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "rigidbot_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/robo_3d_r1_extruder_0.def.json b/resources/extruders/robo_3d_r1_extruder_0.def.json index 0872e91a11..60811842ac 100644 --- a/resources/extruders/robo_3d_r1_extruder_0.def.json +++ b/resources/extruders/robo_3d_r1_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "robo_3d_r1_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/seemecnc_artemis_extruder_0.def.json b/resources/extruders/seemecnc_artemis_extruder_0.def.json index a709a80cbf..a86e5eb2bd 100644 --- a/resources/extruders/seemecnc_artemis_extruder_0.def.json +++ b/resources/extruders/seemecnc_artemis_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "seemecnc_artemis_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/seemecnc_v32_extruder_0.def.json b/resources/extruders/seemecnc_v32_extruder_0.def.json index 5bd489e537..b223116be3 100644 --- a/resources/extruders/seemecnc_v32_extruder_0.def.json +++ b/resources/extruders/seemecnc_v32_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "seemecnc_v32_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/stereotech_start_extruder_0.def.json b/resources/extruders/stereotech_start_extruder_0.def.json index 8658944ebd..b0a1e91d1c 100644 --- a/resources/extruders/stereotech_start_extruder_0.def.json +++ b/resources/extruders/stereotech_start_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "stereotech_start_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/stereotech_ste320_1st.def.json b/resources/extruders/stereotech_ste320_1st.def.json index ffbf5bde2f..8110775d33 100644 --- a/resources/extruders/stereotech_ste320_1st.def.json +++ b/resources/extruders/stereotech_ste320_1st.def.json @@ -1,5 +1,4 @@ { - "id": "stereotech_ste320_1st", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/stereotech_ste320_2nd.def.json b/resources/extruders/stereotech_ste320_2nd.def.json index ae1b8f0f15..12a1479164 100644 --- a/resources/extruders/stereotech_ste320_2nd.def.json +++ b/resources/extruders/stereotech_ste320_2nd.def.json @@ -1,5 +1,4 @@ { - "id": "stereotech_ste320_2nd", "version": 2, "name": "Extruder 2", "inherits": "fdmextruder", diff --git a/resources/extruders/strateo3d_left_extruder.def.json b/resources/extruders/strateo3d_left_extruder.def.json index 1df8eb0ebb..096b265030 100644 --- a/resources/extruders/strateo3d_left_extruder.def.json +++ b/resources/extruders/strateo3d_left_extruder.def.json @@ -1,5 +1,4 @@ { - "id": "strateo3d_left_extruder", "version": 2, "name": "Left Extruder 2", "inherits": "fdmextruder", diff --git a/resources/extruders/strateo3d_right_extruder.def.json b/resources/extruders/strateo3d_right_extruder.def.json index ea59870329..24acdef8b5 100644 --- a/resources/extruders/strateo3d_right_extruder.def.json +++ b/resources/extruders/strateo3d_right_extruder.def.json @@ -1,5 +1,4 @@ { - "id": "strateo3d_right_extruder", "version": 2, "name": "Right Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/structur3d_discov3ry1_complete_um2plus_extruder_0.def.json b/resources/extruders/structur3d_discov3ry1_complete_um2plus_extruder_0.def.json index 8436dc0a94..c63f740f11 100644 --- a/resources/extruders/structur3d_discov3ry1_complete_um2plus_extruder_0.def.json +++ b/resources/extruders/structur3d_discov3ry1_complete_um2plus_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "structur3d_discov3ry1_complete_um2plus_extruder_0", "version": 2, "name": "Discov3ry Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/tam_extruder_0.def.json b/resources/extruders/tam_extruder_0.def.json index fc53efad3f..f487a6ff90 100644 --- a/resources/extruders/tam_extruder_0.def.json +++ b/resources/extruders/tam_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "tam_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/tevo_blackwidow_extruder_0.def.json b/resources/extruders/tevo_blackwidow_extruder_0.def.json index 125cf19c98..3450b36ac6 100644 --- a/resources/extruders/tevo_blackwidow_extruder_0.def.json +++ b/resources/extruders/tevo_blackwidow_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "tevo_blackwidow_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/tevo_tarantula_extruder_0.def.json b/resources/extruders/tevo_tarantula_extruder_0.def.json index bc43986814..a2ac48c06d 100644 --- a/resources/extruders/tevo_tarantula_extruder_0.def.json +++ b/resources/extruders/tevo_tarantula_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "tevo_tarantula_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/tevo_tornado_extruder_0.def.json b/resources/extruders/tevo_tornado_extruder_0.def.json index b47a757113..6c0c9f39b1 100644 --- a/resources/extruders/tevo_tornado_extruder_0.def.json +++ b/resources/extruders/tevo_tornado_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "tevo_tornado_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/tizyx_evy_dual_extruder_0.def.JSON b/resources/extruders/tizyx_evy_dual_extruder_0.def.JSON index 59e9311e50..282d9d2651 100644 --- a/resources/extruders/tizyx_evy_dual_extruder_0.def.JSON +++ b/resources/extruders/tizyx_evy_dual_extruder_0.def.JSON @@ -1,5 +1,4 @@ { - "id": "tizyx_evy_dual_extruder_0", "version": 2, "name": "Classic Extruder", "inherits": "fdmextruder", diff --git a/resources/extruders/tizyx_evy_dual_extruder_1.def.JSON b/resources/extruders/tizyx_evy_dual_extruder_1.def.JSON index cf5dc76caa..69e4a60952 100644 --- a/resources/extruders/tizyx_evy_dual_extruder_1.def.JSON +++ b/resources/extruders/tizyx_evy_dual_extruder_1.def.JSON @@ -1,5 +1,4 @@ { - "id": "tizyx_evy_dual_extruder_1", "version": 2, "name": "Direct Drive", "inherits": "fdmextruder", diff --git a/resources/extruders/tizyx_evy_extruder_0.def.JSON b/resources/extruders/tizyx_evy_extruder_0.def.JSON index bd3c4c9792..4f93648491 100644 --- a/resources/extruders/tizyx_evy_extruder_0.def.JSON +++ b/resources/extruders/tizyx_evy_extruder_0.def.JSON @@ -1,5 +1,4 @@ { - "id": "tizyx_evy_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/tizyx_k25_extruder_0.def.json b/resources/extruders/tizyx_k25_extruder_0.def.json index 409198d77c..626fedf434 100644 --- a/resources/extruders/tizyx_k25_extruder_0.def.json +++ b/resources/extruders/tizyx_k25_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "tizyx_k25_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/ubuild-3d_mr_bot_280_extruder_0.def.json b/resources/extruders/ubuild-3d_mr_bot_280_extruder_0.def.json index b04ca0dcbf..749a5ed77d 100644 --- a/resources/extruders/ubuild-3d_mr_bot_280_extruder_0.def.json +++ b/resources/extruders/ubuild-3d_mr_bot_280_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "ubuild-3d_mr_bot_280_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/ultimaker2_extended_extruder_0.def.json b/resources/extruders/ultimaker2_extended_extruder_0.def.json index 6387ec72ed..cc7306a393 100644 --- a/resources/extruders/ultimaker2_extended_extruder_0.def.json +++ b/resources/extruders/ultimaker2_extended_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "ultimaker2_extended_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/ultimaker2_extended_plus_extruder_0.def.json b/resources/extruders/ultimaker2_extended_plus_extruder_0.def.json index 39fc665ff2..337c120097 100644 --- a/resources/extruders/ultimaker2_extended_plus_extruder_0.def.json +++ b/resources/extruders/ultimaker2_extended_plus_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "ultimaker2_extended_plus_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/ultimaker2_extruder_0.def.json b/resources/extruders/ultimaker2_extruder_0.def.json index 2daf57c73f..64ac8698f1 100644 --- a/resources/extruders/ultimaker2_extruder_0.def.json +++ b/resources/extruders/ultimaker2_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "ultimaker2_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/ultimaker2_go_extruder_0.def.json b/resources/extruders/ultimaker2_go_extruder_0.def.json index 4c258e237e..5ddcfbd551 100644 --- a/resources/extruders/ultimaker2_go_extruder_0.def.json +++ b/resources/extruders/ultimaker2_go_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "ultimaker2_go_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/ultimaker2_plus_extruder_0.def.json b/resources/extruders/ultimaker2_plus_extruder_0.def.json index 13ab0c59ea..abf36c0b08 100644 --- a/resources/extruders/ultimaker2_plus_extruder_0.def.json +++ b/resources/extruders/ultimaker2_plus_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "ultimaker2_plus_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/ultimaker3_extended_extruder_left.def.json b/resources/extruders/ultimaker3_extended_extruder_left.def.json index 2d81424bc6..fbc49a1f32 100644 --- a/resources/extruders/ultimaker3_extended_extruder_left.def.json +++ b/resources/extruders/ultimaker3_extended_extruder_left.def.json @@ -1,5 +1,4 @@ { - "id": "ultimaker3_extended_extruder_left", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/ultimaker3_extended_extruder_right.def.json b/resources/extruders/ultimaker3_extended_extruder_right.def.json index 7cdd5876c1..fbe6bcc878 100644 --- a/resources/extruders/ultimaker3_extended_extruder_right.def.json +++ b/resources/extruders/ultimaker3_extended_extruder_right.def.json @@ -1,5 +1,4 @@ { - "id": "ultimaker3_extended_extruder_right", "version": 2, "name": "Extruder 2", "inherits": "fdmextruder", diff --git a/resources/extruders/ultimaker3_extruder_left.def.json b/resources/extruders/ultimaker3_extruder_left.def.json index 9f5ed34692..b18e2decfa 100644 --- a/resources/extruders/ultimaker3_extruder_left.def.json +++ b/resources/extruders/ultimaker3_extruder_left.def.json @@ -1,5 +1,4 @@ { - "id": "ultimaker3_extruder_left", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/ultimaker3_extruder_right.def.json b/resources/extruders/ultimaker3_extruder_right.def.json index 7298a552b7..4753fde489 100644 --- a/resources/extruders/ultimaker3_extruder_right.def.json +++ b/resources/extruders/ultimaker3_extruder_right.def.json @@ -1,5 +1,4 @@ { - "id": "ultimaker3_extruder_right", "version": 2, "name": "Extruder 2", "inherits": "fdmextruder", diff --git a/resources/extruders/ultimaker_original_dual_1st.def.json b/resources/extruders/ultimaker_original_dual_1st.def.json index 3d837fc989..acc8168d94 100644 --- a/resources/extruders/ultimaker_original_dual_1st.def.json +++ b/resources/extruders/ultimaker_original_dual_1st.def.json @@ -1,5 +1,4 @@ { - "id": "ultimaker_original_dual_1st", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/ultimaker_original_dual_2nd.def.json b/resources/extruders/ultimaker_original_dual_2nd.def.json index 80cc17c58d..7907571e66 100644 --- a/resources/extruders/ultimaker_original_dual_2nd.def.json +++ b/resources/extruders/ultimaker_original_dual_2nd.def.json @@ -1,5 +1,4 @@ { - "id": "ultimaker_original_dual_2nd", "version": 2, "name": "Extruder 2", "inherits": "fdmextruder", diff --git a/resources/extruders/ultimaker_original_extruder_0.def.json b/resources/extruders/ultimaker_original_extruder_0.def.json index 4aab693212..30df96df58 100644 --- a/resources/extruders/ultimaker_original_extruder_0.def.json +++ b/resources/extruders/ultimaker_original_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "ultimaker_original_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/ultimaker_original_plus_extruder_0.def.json b/resources/extruders/ultimaker_original_plus_extruder_0.def.json index 91d0751861..fec40e93a9 100644 --- a/resources/extruders/ultimaker_original_plus_extruder_0.def.json +++ b/resources/extruders/ultimaker_original_plus_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "ultimaker_original_plus_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/ultimaker_s3_extruder_left.def.json b/resources/extruders/ultimaker_s3_extruder_left.def.json index 61d3149e0b..7af6f7d0dc 100644 --- a/resources/extruders/ultimaker_s3_extruder_left.def.json +++ b/resources/extruders/ultimaker_s3_extruder_left.def.json @@ -1,5 +1,4 @@ { - "id": "ultimaker_s3_extruder_left", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/ultimaker_s3_extruder_right.def.json b/resources/extruders/ultimaker_s3_extruder_right.def.json index efcb6ae06a..6771e1c0a8 100644 --- a/resources/extruders/ultimaker_s3_extruder_right.def.json +++ b/resources/extruders/ultimaker_s3_extruder_right.def.json @@ -1,5 +1,4 @@ { - "id": "ultimaker_s3_extruder_right", "version": 2, "name": "Extruder 2", "inherits": "fdmextruder", diff --git a/resources/extruders/ultimaker_s5_extruder_left.def.json b/resources/extruders/ultimaker_s5_extruder_left.def.json index 275f60bb31..24de85e9cc 100644 --- a/resources/extruders/ultimaker_s5_extruder_left.def.json +++ b/resources/extruders/ultimaker_s5_extruder_left.def.json @@ -1,5 +1,4 @@ { - "id": "ultimaker_s5_extruder_left", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/ultimaker_s5_extruder_right.def.json b/resources/extruders/ultimaker_s5_extruder_right.def.json index 92e08f5cc5..1e0ac3eace 100644 --- a/resources/extruders/ultimaker_s5_extruder_right.def.json +++ b/resources/extruders/ultimaker_s5_extruder_right.def.json @@ -1,5 +1,4 @@ { - "id": "ultimaker_s5_extruder_right", "version": 2, "name": "Extruder 2", "inherits": "fdmextruder", diff --git a/resources/extruders/uni_print_3d_extruder_0.def.json b/resources/extruders/uni_print_3d_extruder_0.def.json index d0711fd458..747fb9e020 100644 --- a/resources/extruders/uni_print_3d_extruder_0.def.json +++ b/resources/extruders/uni_print_3d_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "uni_print_3d_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/uniqbot_one_extruder_0.def.json b/resources/extruders/uniqbot_one_extruder_0.def.json index 65436ee789..0a8982559d 100644 --- a/resources/extruders/uniqbot_one_extruder_0.def.json +++ b/resources/extruders/uniqbot_one_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "uniqbot_one_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/vertex_delta_k8800_extruder_0.def.json b/resources/extruders/vertex_delta_k8800_extruder_0.def.json index 5e09046faf..05a010222f 100644 --- a/resources/extruders/vertex_delta_k8800_extruder_0.def.json +++ b/resources/extruders/vertex_delta_k8800_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "vertex_delta_k8800_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/vertex_k8400_dual_1st.def.json b/resources/extruders/vertex_k8400_dual_1st.def.json index 86fb2266ba..947cfbc7d8 100644 --- a/resources/extruders/vertex_k8400_dual_1st.def.json +++ b/resources/extruders/vertex_k8400_dual_1st.def.json @@ -1,5 +1,4 @@ { - "id": "vertex_k8400_dual_1st", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/vertex_k8400_dual_2nd.def.json b/resources/extruders/vertex_k8400_dual_2nd.def.json index 306b2dcb7a..e606e46337 100644 --- a/resources/extruders/vertex_k8400_dual_2nd.def.json +++ b/resources/extruders/vertex_k8400_dual_2nd.def.json @@ -1,5 +1,4 @@ { - "id": "vertex_k8400_dual_2nd", "version": 2, "name": "Extruder 2", "inherits": "fdmextruder", diff --git a/resources/extruders/vertex_k8400_extruder_0.def.json b/resources/extruders/vertex_k8400_extruder_0.def.json index c03453b519..e0304f57bd 100644 --- a/resources/extruders/vertex_k8400_extruder_0.def.json +++ b/resources/extruders/vertex_k8400_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "vertex_k8400_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/wanhao_d4s_extruder_0.def.json b/resources/extruders/wanhao_d4s_extruder_0.def.json index 9a750e072c..bd6023faf4 100644 --- a/resources/extruders/wanhao_d4s_extruder_0.def.json +++ b/resources/extruders/wanhao_d4s_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "wanhao_d4s_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/wanhao_d6_extruder_0.def.json b/resources/extruders/wanhao_d6_extruder_0.def.json index a8a3bf15d3..093546eabf 100644 --- a/resources/extruders/wanhao_d6_extruder_0.def.json +++ b/resources/extruders/wanhao_d6_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "wanhao_d6_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/wanhao_d6_plus_extruder_0.def.json b/resources/extruders/wanhao_d6_plus_extruder_0.def.json index b2b1e6ab05..acc5b66072 100644 --- a/resources/extruders/wanhao_d6_plus_extruder_0.def.json +++ b/resources/extruders/wanhao_d6_plus_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "wanhao_d6_plus_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/wanhao_d9_extruder_0.def.json b/resources/extruders/wanhao_d9_extruder_0.def.json index 76d501e5a2..40fcf422f5 100644 --- a/resources/extruders/wanhao_d9_extruder_0.def.json +++ b/resources/extruders/wanhao_d9_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "wanhao_d9_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/wanhao_duplicator5S_extruder_0.def.json b/resources/extruders/wanhao_duplicator5S_extruder_0.def.json index 74f47158a3..7274d5117e 100644 --- a/resources/extruders/wanhao_duplicator5S_extruder_0.def.json +++ b/resources/extruders/wanhao_duplicator5S_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "wanhao_duplicator5S_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/wanhao_duplicator5Smini_extruder_0.def.json b/resources/extruders/wanhao_duplicator5Smini_extruder_0.def.json index 8c91de4685..3479c94e35 100644 --- a/resources/extruders/wanhao_duplicator5Smini_extruder_0.def.json +++ b/resources/extruders/wanhao_duplicator5Smini_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "wanhao_duplicator5Smini_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/wanhao_i3_extruder_0.def.json b/resources/extruders/wanhao_i3_extruder_0.def.json index 7d881079c4..387a456ff2 100644 --- a/resources/extruders/wanhao_i3_extruder_0.def.json +++ b/resources/extruders/wanhao_i3_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "wanhao_i3_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/wanhao_i3mini_extruder_0.def.json b/resources/extruders/wanhao_i3mini_extruder_0.def.json index c5abbd175e..2d52f0d126 100644 --- a/resources/extruders/wanhao_i3mini_extruder_0.def.json +++ b/resources/extruders/wanhao_i3mini_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "wanhao_i3mini_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/wanhao_i3plus_extruder_0.def.json b/resources/extruders/wanhao_i3plus_extruder_0.def.json index 0dae64ce63..103e3b9335 100644 --- a/resources/extruders/wanhao_i3plus_extruder_0.def.json +++ b/resources/extruders/wanhao_i3plus_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "wanhao_i3plus_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/z-bolt_extruder_0.def.json b/resources/extruders/z-bolt_extruder_0.def.json index 70e9f6177c..04c8d10cbb 100644 --- a/resources/extruders/z-bolt_extruder_0.def.json +++ b/resources/extruders/z-bolt_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "z-bolt_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/zone3d_printer_extruder_0.def.json b/resources/extruders/zone3d_printer_extruder_0.def.json index ca024dd5c4..fb8f40d3e2 100644 --- a/resources/extruders/zone3d_printer_extruder_0.def.json +++ b/resources/extruders/zone3d_printer_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "zone3d_printer_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", diff --git a/resources/extruders/zyyx_agile_extruder_0.def.json b/resources/extruders/zyyx_agile_extruder_0.def.json index edda9b3097..c01ffb59f3 100644 --- a/resources/extruders/zyyx_agile_extruder_0.def.json +++ b/resources/extruders/zyyx_agile_extruder_0.def.json @@ -1,5 +1,4 @@ { - "id": "zyyx_agile_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", From 985aac9e601337d310b5a9c3e9160ed39852104e Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 22 Oct 2019 11:01:16 +0200 Subject: [PATCH 44/50] Assert that there is no ID metadata entry in definition containers --- tests/Settings/TestDefinitionContainer.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/tests/Settings/TestDefinitionContainer.py b/tests/Settings/TestDefinitionContainer.py index 73d10d871c..6e502280cd 100644 --- a/tests/Settings/TestDefinitionContainer.py +++ b/tests/Settings/TestDefinitionContainer.py @@ -58,7 +58,7 @@ def assertIsDefinitionValid(definition_container, path, file_name): # definition that defines a "value", the "default_value" is ineffective. This # test fails on those things. @pytest.mark.parametrize("file_name", machine_filepaths) -def test_validateOverridingDefaultValue(file_name): +def test_validateOverridingDefaultValue(file_name: str): definition_path = os.path.join(os.path.dirname(__file__), "..", "..", "resources", "definitions", file_name) with open(definition_path, encoding = "utf-8") as f: doc = json.load(f) @@ -124,4 +124,16 @@ def merge_dicts(base: Dict[str, Any], overrides: Dict[str, Any]) -> Dict[str, An result[key] = merge_dicts(result[key], val) else: result[key] = val - return result \ No newline at end of file + return result + +## Verifies that definition contains don't have an ID field. +# +# ID fields are legacy. They should not be used any more. This is legacy that +# people don't seem to be able to get used to. +@pytest.mark.parametrize("file_name", machine_filepaths) +def test_noId(file_name): + definition_path = os.path.join(os.path.dirname(__file__), "..", "..", "resources", "definitions", file_name) + with open(definition_path, encoding = "utf-8") as f: + doc = json.load(f) + + assert "id" not in doc, "Definitions should not have an ID field." \ No newline at end of file From fc0b8185b7df0f223a67f24384e3e6bad663c8a1 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 22 Oct 2019 11:37:33 +0200 Subject: [PATCH 45/50] Fix setMetaDataEntry() dependency on ContainerRegistery CURA-6920 --- plugins/XmlMaterialProfile/XmlMaterialProfile.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index fe0f73f2b3..093638d594 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -76,7 +76,9 @@ class XmlMaterialProfile(InstanceContainer): new_setting_values_dict[self.__material_properties_setting_map[k]] = v if not apply_to_all: # Historical: If you only want to modify THIS container. We only used that to prevent recursion but with the below code that's no longer necessary. - container_query = registry.findContainers(id = self.getId()) + # CURA-6920: This is an optimization, but it also fixes the problem that you can only set metadata for a + # material container that can be found in the container registry. + container_query = [self] else: container_query = registry.findContainers(base_file = self.getMetaDataEntry("base_file")) From cb9b385a851958b3a71450a1d661f905efb09826 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 22 Oct 2019 13:46:21 +0200 Subject: [PATCH 46/50] Remove Alternate Skin Rotations setting It's been replaced completely by the Top/Bottom Line Directions setting. --- .../VersionUpgrade43to44/VersionUpgrade43to44.py | 6 ++++++ resources/definitions/fdmprinter.def.json | 10 ---------- resources/setting_visibility/expert.cfg | 1 - 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade43to44/VersionUpgrade43to44.py b/plugins/VersionUpgrade/VersionUpgrade43to44/VersionUpgrade43to44.py index 195bc70016..4858c6f9bf 100644 --- a/plugins/VersionUpgrade/VersionUpgrade43to44/VersionUpgrade43to44.py +++ b/plugins/VersionUpgrade/VersionUpgrade43to44/VersionUpgrade43to44.py @@ -2,6 +2,7 @@ import configparser from typing import Tuple, List import io from UM.VersionUpgrade import VersionUpgrade +from UM.Util import parseBool # To parse whether the Alternate Skin Rotations function is activated. _renamed_container_id_map = { "ultimaker2_0.25": "ultimaker2_olsson_0.25", @@ -61,6 +62,11 @@ class VersionUpgrade43to44(VersionUpgrade): if parser["metadata"].get("type", "") == "quality_changes": parser["metadata"]["intent_category"] = "default" + if "values" in parser: + # Alternate skin rotation should be translated to top/bottom line directions. + if "skin_alternate_rotation" in parser["values"] and parseBool(parser["values"]["skin_alternate_rotation"]): + parser["skin_angles"] = "[45, 135, 0, 90]" + result = io.StringIO() parser.write(result) return [filename], [result.getvalue()] diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index ab5a41344a..ca0057adb4 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -6441,16 +6441,6 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "skin_alternate_rotation": - { - "label": "Alternate Skin Rotation", - "description": "Alternate the direction in which the top/bottom layers are printed. Normally they are printed diagonally only. This setting adds the X-only and Y-only directions.", - "type": "bool", - "default_value": false, - "enabled": "(top_layers > 0 or bottom_layers > 0) and top_bottom_pattern != 'concentric'", - "limit_to_extruder": "top_bottom_extruder_nr", - "settable_per_mesh": true - }, "cross_infill_pocket_size": { "label": "Cross 3D Pocket Size", diff --git a/resources/setting_visibility/expert.cfg b/resources/setting_visibility/expert.cfg index ad0d2993d2..2b9ad362fc 100644 --- a/resources/setting_visibility/expert.cfg +++ b/resources/setting_visibility/expert.cfg @@ -372,7 +372,6 @@ coasting_enable coasting_volume coasting_min_volume coasting_speed -skin_alternate_rotation cross_infill_pocket_size spaghetti_infill_enabled spaghetti_infill_stepped From 66bc20eab1633e62d321d7b4c038c3e47c21ff3d Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 22 Oct 2019 14:53:11 +0200 Subject: [PATCH 47/50] Revert incorrect material handling code in VariantNode CURA-6921 --- cura/Machines/VariantNode.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/Machines/VariantNode.py b/cura/Machines/VariantNode.py index 1c5474422e..334a01158b 100644 --- a/cura/Machines/VariantNode.py +++ b/cura/Machines/VariantNode.py @@ -122,8 +122,8 @@ class VariantNode(ContainerNode): if base_file not in self.materials: # Completely new base file. Always better than not having a file as long as it matches our set-up. if material_definition != "fdmprinter" and material_definition != self.machine.container_id: return - material_variant = container.getMetaDataEntry("variant_name", empty_variant_container.getName()) - if material_variant != self.variant_name: + material_variant = container.getMetaDataEntry("variant_name") + if material_variant is not None and material_variant != self.variant_name: return else: # We already have this base profile. Replace the base profile if the new one is more specific. new_definition = container.getMetaDataEntry("definition") From 66005f28f31c343aff697d22ecdbc1d06a6e86c2 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 22 Oct 2019 15:00:51 +0200 Subject: [PATCH 48/50] Fix typo in removing Alternate Skin Rotations --- .../VersionUpgrade/VersionUpgrade43to44/VersionUpgrade43to44.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade43to44/VersionUpgrade43to44.py b/plugins/VersionUpgrade/VersionUpgrade43to44/VersionUpgrade43to44.py index 4858c6f9bf..e8eefb1bb0 100644 --- a/plugins/VersionUpgrade/VersionUpgrade43to44/VersionUpgrade43to44.py +++ b/plugins/VersionUpgrade/VersionUpgrade43to44/VersionUpgrade43to44.py @@ -65,7 +65,7 @@ class VersionUpgrade43to44(VersionUpgrade): if "values" in parser: # Alternate skin rotation should be translated to top/bottom line directions. if "skin_alternate_rotation" in parser["values"] and parseBool(parser["values"]["skin_alternate_rotation"]): - parser["skin_angles"] = "[45, 135, 0, 90]" + parser["values"]["skin_angles"] = "[45, 135, 0, 90]" result = io.StringIO() parser.write(result) From f2c66f8d3a4f2734d6a0a8de824bca8cdad039d9 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 22 Oct 2019 15:30:19 +0200 Subject: [PATCH 49/50] Fix TestVariantNode CURA-6921 --- tests/Machines/TestVariantNode.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Machines/TestVariantNode.py b/tests/Machines/TestVariantNode.py index 4e58069be3..bc860058a1 100644 --- a/tests/Machines/TestVariantNode.py +++ b/tests/Machines/TestVariantNode.py @@ -16,7 +16,7 @@ instance_container_metadata_dict = {"fdmprinter": {"no_variant": [{"base_file": material_node_added_test_data = [({"type": "Not a material"}, ["material_1", "material_2"]), # Wrong type ({"type": "material", "base_file": "material_3"}, ["material_1", "material_2"]), # material_3 is on the "NOPE" list. ({"type": "material", "base_file": "material_4", "definition": "machine_3"}, ["material_1", "material_2"]), # Wrong machine - ({"type": "material", "base_file": "material_4", "definition": "machine_1"}, ["material_1", "material_2"]), # No variant + ({"type": "material", "base_file": "material_4", "definition": "machine_1"}, ["material_1", "material_2", "material_4"]), # No variant ({"type": "material", "base_file": "material_4", "definition": "machine_1", "variant_name": "Variant Three"}, ["material_1", "material_2"]), # Wrong variant ({"type": "material", "base_file": "material_4", "definition": "machine_1", "variant_name": "Variant One"}, ["material_1", "material_2", "material_4"]) ] From 59e55dab5ee6731a868098672935c8a8051b6d0e Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 22 Oct 2019 17:23:32 +0200 Subject: [PATCH 50/50] Fixes for consistency with other printers Contributes to issue CURA-6814. --- ...l_Prusa_i3_MK3S_MK3.def.json => prusa_i3_mk3.def.json} | 8 ++++---- ...truder_0.def.json => prusa_i3_mk3_extruder_0.def.json} | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) rename resources/definitions/{Original_Prusa_i3_MK3S_MK3.def.json => prusa_i3_mk3.def.json} (93%) rename resources/extruders/{Original_Prusa_i3_MK3S_MK3_extruder_0.def.json => prusa_i3_mk3_extruder_0.def.json} (75%) diff --git a/resources/definitions/Original_Prusa_i3_MK3S_MK3.def.json b/resources/definitions/prusa_i3_mk3.def.json similarity index 93% rename from resources/definitions/Original_Prusa_i3_MK3S_MK3.def.json rename to resources/definitions/prusa_i3_mk3.def.json index 439cc1fcda..0b55e4f200 100644 --- a/resources/definitions/Original_Prusa_i3_MK3S_MK3.def.json +++ b/resources/definitions/prusa_i3_mk3.def.json @@ -1,6 +1,6 @@ { "version": 2, - "name": "Original Prusa i3 MK3S/MK3", + "name": "Prusa i3 Mk3/Mk3s", "inherits": "fdmprinter", "metadata": { "visible": true, @@ -10,14 +10,14 @@ "icon": "icon_ultimaker2", "platform": "Original_Prusa_i3_MK3S_MK3_platform.stl", "has_materials": true, - "machine_extruder_trains": + "machine_extruder_trains": { - "0": "Original_Prusa_i3_MK3S_MK3_extruder_0" + "0": "prusa_i3_mk3_extruder_0" } }, "overrides": { - "machine_name": { "default_value": "Original Prusa i3 MK3S/MK3" }, + "machine_name": { "default_value": "Prusa i3 Mk3/Mk3s" }, "machine_heated_bed": { "default_value": true }, "machine_width": { "default_value": 250 }, "machine_height": { "default_value": 210 }, diff --git a/resources/extruders/Original_Prusa_i3_MK3S_MK3_extruder_0.def.json b/resources/extruders/prusa_i3_mk3_extruder_0.def.json similarity index 75% rename from resources/extruders/Original_Prusa_i3_MK3S_MK3_extruder_0.def.json rename to resources/extruders/prusa_i3_mk3_extruder_0.def.json index 18d69e4557..29156f0d70 100644 --- a/resources/extruders/Original_Prusa_i3_MK3S_MK3_extruder_0.def.json +++ b/resources/extruders/prusa_i3_mk3_extruder_0.def.json @@ -1,10 +1,9 @@ { - "id": "Original_Prusa_i3_MK3S_MK3_extruder_0", "version": 2, "name": "Extruder 1", "inherits": "fdmextruder", "metadata": { - "machine": "Original_Prusa_i3_MK3S_MK3", + "machine": "prusa_i3_mk3", "position": "0" },