From 4ffcabd8560d952d0dc81f16632733c084e490bd Mon Sep 17 00:00:00 2001 From: nickthetait Date: Thu, 15 Sep 2016 09:11:46 -0600 Subject: [PATCH 01/50] Standardize formatting of fdmprinter definition Used custom settings in JSON Editor Plugin for Eclipse and afterwards removed some extra whitespace changes that are not desired Fixes github #980 --- resources/definitions/fdmprinter.def.json | 298 ++++++++++++++-------- 1 file changed, 195 insertions(+), 103 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index eae6593fb8..9c31e97b62 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -265,7 +265,9 @@ "label": "Disallowed areas", "description": "A list of polygons with areas the print head is not allowed to enter.", "type": "polygons", - "default_value": [], + "default_value": + [ + ], "settable_per_mesh": false, "settable_per_extruder": false, "settable_per_meshgroup": false @@ -379,7 +381,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "machine_max_feedrate_x": { + "machine_max_feedrate_x": + { "label": "Maximum Speed X", "description": "The maximum speed for the motor of the X-direction.", "unit": "mm/s", @@ -389,7 +392,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_feedrate_y": { + "machine_max_feedrate_y": + { "label": "Maximum Speed Y", "description": "The maximum speed for the motor of the Y-direction.", "unit": "mm/s", @@ -399,7 +403,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_feedrate_z": { + "machine_max_feedrate_z": + { "label": "Maximum Speed Z", "description": "The maximum speed for the motor of the Z-direction.", "unit": "mm/s", @@ -409,7 +414,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_feedrate_e": { + "machine_max_feedrate_e": + { "label": "Maximum Feedrate", "description": "The maximum speed of the filament.", "unit": "mm/s", @@ -419,7 +425,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_acceleration_x": { + "machine_max_acceleration_x": + { "label": "Maximum Acceleration X", "description": "Maximum acceleration for the motor of the X-direction", "unit": "mm/s²", @@ -429,7 +436,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_acceleration_y": { + "machine_max_acceleration_y": + { "label": "Maximum Acceleration Y", "description": "Maximum acceleration for the motor of the Y-direction.", "unit": "mm/s²", @@ -439,7 +447,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_acceleration_z": { + "machine_max_acceleration_z": + { "label": "Maximum Acceleration Z", "description": "Maximum acceleration for the motor of the Z-direction.", "unit": "mm/s²", @@ -449,7 +458,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_acceleration_e": { + "machine_max_acceleration_e": + { "label": "Maximum Filament Acceleration", "description": "Maximum acceleration for the motor of the filament.", "unit": "mm/s²", @@ -459,7 +469,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_acceleration": { + "machine_acceleration": + { "label": "Default Acceleration", "description": "The default acceleration of print head movement.", "unit": "mm/s²", @@ -469,7 +480,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_jerk_xy": { + "machine_max_jerk_xy": + { "label": "Default X-Y Jerk", "description": "Default jerk for movement in the horizontal plane.", "unit": "mm/s", @@ -479,7 +491,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_jerk_z": { + "machine_max_jerk_z": + { "label": "Default Z Jerk", "description": "Default jerk for the motor of the Z-direction.", "unit": "mm/s", @@ -489,7 +502,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_jerk_e": { + "machine_max_jerk_e": + { "label": "Default Filament Jerk", "description": "Default jerk for the motor of the filament.", "unit": "mm/s", @@ -499,7 +513,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_minimum_feedrate": { + "machine_minimum_feedrate": + { "label": "Minimum Feedrate", "description": "The minimal movement speed of the print head.", "unit": "mm/s", @@ -567,7 +582,7 @@ "minimum_value": "0.0001", "minimum_value_warning": "0.2", "maximum_value_warning": "5", - "value":"line_width", + "value": "line_width", "default_value": 0.4, "type": "float", "settable_per_mesh": true, @@ -582,7 +597,7 @@ "minimum_value_warning": "0.2", "maximum_value_warning": "5", "default_value": 0.4, - "value":"wall_line_width", + "value": "wall_line_width", "type": "float", "settable_per_mesh": true }, @@ -595,7 +610,7 @@ "minimum_value_warning": "0.2", "maximum_value_warning": "5", "default_value": 0.4, - "value":"wall_line_width", + "value": "wall_line_width", "type": "float", "settable_per_mesh": true } @@ -834,7 +849,8 @@ "settable_per_mesh": true, "children": { - "travel_compensate_overlapping_walls_0_enabled": { + "travel_compensate_overlapping_walls_0_enabled": + { "label": "Compensate Outer Wall Overlaps", "description": "Compensate the flow for parts of an outer wall being printed where there is already a wall in place.", "type": "bool", @@ -842,7 +858,8 @@ "value": "travel_compensate_overlapping_walls_enabled", "settable_per_mesh": true }, - "travel_compensate_overlapping_walls_x_enabled": { + "travel_compensate_overlapping_walls_x_enabled": + { "label": "Compensate Inner Wall Overlaps", "description": "Compensate the flow for parts of an inner wall being printed where there is already a wall in place.", "type": "bool", @@ -968,7 +985,8 @@ } } }, - "skin_overlap": { + "skin_overlap": + { "label": "Skin Overlap Percentage", "description": "The amount of overlap between the skin and the walls. A slight overlap allows the walls to connect firmly to the skin.", "unit": "%", @@ -979,8 +997,10 @@ "value": "5 if top_bottom_pattern != 'concentric' else 0", "enabled": "top_bottom_pattern != 'concentric'", "settable_per_mesh": true, - "children": { - "skin_overlap_mm": { + "children": + { + "skin_overlap_mm": + { "label": "Skin Overlap", "description": "The amount of overlap between the skin and the walls. A slight overlap allows the walls to connect firmly to the skin.", "unit": "mm", @@ -991,9 +1011,9 @@ "value": "skin_line_width * skin_overlap / 100 if top_bottom_pattern != 'concentric' else 0", "enabled": "top_bottom_pattern != 'concentric'", "settable_per_mesh": true - } - } - }, + } + } + }, "infill_wipe_dist": { "label": "Infill Wipe Distance", @@ -1095,7 +1115,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "material_extrusion_cool_down_speed": { + "material_extrusion_cool_down_speed": + { "label": "Extrusion Cool Down Speed Modifier", "description": "The extra speed by which the nozzle cools while extruding. The same value is used to signify the heat up speed lost when heating up while extruding.", "unit": "°C/s", @@ -1108,7 +1129,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "material_bed_temperature": { + "material_bed_temperature": + { "label": "Build Plate Temperature", "description": "The temperature used for the heated build plate. Set at 0 to pre-heat the printer manually.", "unit": "°C", @@ -1122,7 +1144,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "material_diameter": { + "material_diameter": + { "label": "Diameter", "description": "Adjusts the diameter of the filament used. Match this value with the diameter of the used filament.", "unit": "mm", @@ -1134,7 +1157,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "material_flow": { + "material_flow": + { "label": "Flow", "description": "Flow compensation: the amount of material extruded is multiplied by this value.", "unit": "%", @@ -1145,7 +1169,8 @@ "maximum_value_warning": "150", "settable_per_mesh": true }, - "retraction_enable": { + "retraction_enable": + { "label": "Enable Retraction", "description": "Retract the filament when the nozzle is moving over a non-printed area. ", "type": "bool", @@ -1153,7 +1178,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "retraction_amount": { + "retraction_amount": + { "label": "Retraction Distance", "description": "The length of material retracted during a retraction move.", "unit": "mm", @@ -1165,7 +1191,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "retraction_speed": { + "retraction_speed": + { "label": "Retraction Speed", "description": "The speed at which the filament is retracted and primed during a retraction move.", "unit": "mm/s", @@ -1177,8 +1204,10 @@ "enabled": "retraction_enable", "settable_per_mesh": false, "settable_per_extruder": true, - "children": { - "retraction_retract_speed": { + "children": + { + "retraction_retract_speed": + { "label": "Retraction Retract Speed", "description": "The speed at which the filament is retracted during a retraction move.", "unit": "mm/s", @@ -1192,7 +1221,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "retraction_prime_speed": { + "retraction_prime_speed": + { "label": "Retraction Prime Speed", "description": "The speed at which the filament is primed during a retraction move.", "unit": "mm/s", @@ -1208,7 +1238,8 @@ } } }, - "retraction_extra_prime_amount": { + "retraction_extra_prime_amount": + { "label": "Retraction Extra Prime Amount", "description": "Some material can ooze away during a travel move, which can be compensated for here.", "unit": "mm³", @@ -1220,7 +1251,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "retraction_min_travel": { + "retraction_min_travel": + { "label": "Retraction Minimum Travel", "description": "The minimum distance of travel needed for a retraction to happen at all. This helps to get fewer retractions in a small area.", "unit": "mm", @@ -1233,7 +1265,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "retraction_count_max": { + "retraction_count_max": + { "label": "Maximum Retraction Count", "description": "This setting limits the number of retractions occurring within the minimum extrusion distance window. Further retractions within this window will be ignored. This avoids retracting repeatedly on the same piece of filament, as that can flatten the filament and cause grinding issues.", "default_value": 90, @@ -1244,7 +1277,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "retraction_extrusion_window": { + "retraction_extrusion_window": + { "label": "Minimum Extrusion Distance Window", "description": "The window in which the maximum retraction count is enforced. This value should be approximately the same as the retraction distance, so that effectively the number of times a retraction passes the same patch of material is limited.", "unit": "mm", @@ -1257,7 +1291,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "retraction_hop_enabled": { + "retraction_hop_enabled": + { "label": "Z Hop when Retracted", "description": "Whenever a retraction is done, the build plate is lowered to create clearance between the nozzle and the print. It prevents the nozzle from hitting the print during travel moves, reducing the chance to knock the print from the build plate.", "type": "bool", @@ -1266,7 +1301,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "retraction_hop_only_when_collides": { + "retraction_hop_only_when_collides": + { "label": "Z Hop Only Over Printed Parts", "description": "Only perform a Z Hop when moving over printed parts which cannot be avoided by horizontal motion by Avoid Printed Parts when Traveling.", "type": "bool", @@ -1275,7 +1311,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "retraction_hop": { + "retraction_hop": + { "label": "Z Hop Height", "description": "The height difference when performing a Z Hop.", "unit": "mm", @@ -1357,7 +1394,8 @@ } } }, - "retraction_hop_after_extruder_switch": { + "retraction_hop_after_extruder_switch": + { "label": "Z Hop After Extruder Switch", "description": "After the machine switched from one extruder to the other, the build plate is lowered to create clearance between the nozzle and the print. This prevents the nozzle from leaving oozed material on the outside of a print.", "type": "bool", @@ -1539,7 +1577,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "speed_layer_0": { + "speed_layer_0": + { "label": "Initial Layer Speed", "description": "The speed for the initial layer. A lower value is advised to improve adhesion to the build plate.", "unit": "mm/s", @@ -1580,7 +1619,8 @@ } } }, - "skirt_brim_speed": { + "skirt_brim_speed": + { "label": "Skirt/Brim Speed", "description": "The speed at which the skirt and brim are printed. Normally this is done at the initial layer speed, but sometimes you might want to print the skirt or brim at a different speed.", "unit": "mm/s", @@ -1642,9 +1682,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - - - "acceleration_enabled": { + "acceleration_enabled": + { "label": "Enable Acceleration Control", "description": "Enables adjusting the print head acceleration. Increasing the accelerations can reduce printing time at the cost of print quality.", "type": "bool", @@ -1652,7 +1691,8 @@ "settable_per_mesh": false, "settable_per_extruder": false }, - "acceleration_print": { + "acceleration_print": + { "label": "Print Acceleration", "description": "The acceleration with which printing happens.", "unit": "mm/s²", @@ -1663,8 +1703,10 @@ "default_value": 3000, "enabled": "acceleration_enabled", "settable_per_mesh": true, - "children": { - "acceleration_infill": { + "children": + { + "acceleration_infill": + { "label": "Infill Acceleration", "description": "The acceleration with which infill is printed.", "unit": "mm/s²", @@ -1677,7 +1719,8 @@ "enabled": "acceleration_enabled", "settable_per_mesh": true }, - "acceleration_wall": { + "acceleration_wall": + { "label": "Wall Acceleration", "description": "The acceleration with which the walls are printed.", "unit": "mm/s²", @@ -1689,8 +1732,10 @@ "value": "acceleration_print", "enabled": "acceleration_enabled", "settable_per_mesh": true, - "children": { - "acceleration_wall_0": { + "children": + { + "acceleration_wall_0": + { "label": "Outer Wall Acceleration", "description": "The acceleration with which the outermost walls are printed.", "unit": "mm/s²", @@ -1703,7 +1748,8 @@ "enabled": "acceleration_enabled", "settable_per_mesh": true }, - "acceleration_wall_x": { + "acceleration_wall_x": + { "label": "Inner Wall Acceleration", "description": "The acceleration with which all inner walls are printed.", "unit": "mm/s²", @@ -1718,7 +1764,8 @@ } } }, - "acceleration_topbottom": { + "acceleration_topbottom": + { "label": "Top/Bottom Acceleration", "description": "The acceleration with which top/bottom layers are printed.", "unit": "mm/s²", @@ -1731,7 +1778,8 @@ "enabled": "acceleration_enabled", "settable_per_mesh": true }, - "acceleration_support": { + "acceleration_support": + { "label": "Support Acceleration", "description": "The acceleration with which the support structure is printed.", "unit": "mm/s²", @@ -1745,8 +1793,10 @@ "settable_per_mesh": false, "limit_to_extruder": "support_extruder_nr", "settable_per_extruder": true, - "children": { - "acceleration_support_infill": { + "children": + { + "acceleration_support_infill": + { "label": "Support Infill Acceleration", "description": "The acceleration with which the infill of support is printed.", "unit": "mm/s²", @@ -1761,7 +1811,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "acceleration_support_interface": { + "acceleration_support_interface": + { "label": "Support Interface Acceleration", "description": "The acceleration with which the roofs and bottoms of support are printed. Printing them at lower accelerations can improve overhang quality.", "unit": "mm/s²", @@ -1778,7 +1829,8 @@ } } }, - "acceleration_prime_tower": { + "acceleration_prime_tower": + { "label": "Prime Tower Acceleration", "description": "The acceleration with which the prime tower is printed.", "unit": "mm/s²", @@ -1793,7 +1845,8 @@ } } }, - "acceleration_travel": { + "acceleration_travel": + { "label": "Travel Acceleration", "description": "The acceleration with which travel moves are made.", "unit": "mm/s²", @@ -1806,7 +1859,8 @@ "enabled": "acceleration_enabled", "settable_per_mesh": false }, - "acceleration_layer_0": { + "acceleration_layer_0": + { "label": "Initial Layer Acceleration", "description": "The acceleration for the initial layer.", "unit": "mm/s²", @@ -1818,7 +1872,8 @@ "maximum_value_warning": "10000", "enabled": "acceleration_enabled", "settable_per_mesh": true, - "children": { + "children": + { "acceleration_print_layer_0": { "label": "Initial Layer Print Acceleration", @@ -1850,7 +1905,8 @@ } } }, - "acceleration_skirt_brim": { + "acceleration_skirt_brim": + { "label": "Skirt/Brim Acceleration", "description": "The acceleration with which the skirt and brim are printed. Normally this is done with the initial layer acceleration, but sometimes you might want to print the skirt or brim at a different acceleration.", "unit": "mm/s²", @@ -1864,8 +1920,8 @@ "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr" }, - - "jerk_enabled": { + "jerk_enabled": + { "label": "Enable Jerk Control", "description": "Enables adjusting the jerk of print head when the velocity in the X or Y axis changes. Increasing the jerk can reduce printing time at the cost of print quality.", "type": "bool", @@ -1873,7 +1929,8 @@ "settable_per_mesh": false, "settable_per_extruder": false }, - "jerk_print": { + "jerk_print": + { "label": "Print Jerk", "description": "The maximum instantaneous velocity change of the print head.", "unit": "mm/s", @@ -1884,8 +1941,10 @@ "default_value": 20, "enabled": "jerk_enabled", "settable_per_mesh": true, - "children": { - "jerk_infill": { + "children": + { + "jerk_infill": + { "label": "Infill Jerk", "description": "The maximum instantaneous velocity change with which infill is printed.", "unit": "mm/s", @@ -1898,7 +1957,8 @@ "enabled": "jerk_enabled", "settable_per_mesh": true }, - "jerk_wall": { + "jerk_wall": + { "label": "Wall Jerk", "description": "The maximum instantaneous velocity change with which the walls are printed.", "unit": "mm/s", @@ -1910,8 +1970,10 @@ "value": "jerk_print", "enabled": "jerk_enabled", "settable_per_mesh": true, - "children": { - "jerk_wall_0": { + "children": + { + "jerk_wall_0": + { "label": "Outer Wall Jerk", "description": "The maximum instantaneous velocity change with which the outermost walls are printed.", "unit": "mm/s", @@ -1924,7 +1986,8 @@ "enabled": "jerk_enabled", "settable_per_mesh": true }, - "jerk_wall_x": { + "jerk_wall_x": + { "label": "Inner Wall Jerk", "description": "The maximum instantaneous velocity change with which all inner walls are printed.", "unit": "mm/s", @@ -1939,7 +2002,8 @@ } } }, - "jerk_topbottom": { + "jerk_topbottom": + { "label": "Top/Bottom Jerk", "description": "The maximum instantaneous velocity change with which top/bottom layers are printed.", "unit": "mm/s", @@ -1952,7 +2016,8 @@ "enabled": "jerk_enabled", "settable_per_mesh": true }, - "jerk_support": { + "jerk_support": + { "label": "Support Jerk", "description": "The maximum instantaneous velocity change with which the support structure is printed.", "unit": "mm/s", @@ -1966,8 +2031,10 @@ "settable_per_mesh": false, "settable_per_extruder": true, "limit_to_extruder": "support_extruder_nr", - "children": { - "jerk_support_infill": { + "children": + { + "jerk_support_infill": + { "label": "Support Infill Jerk", "description": "The maximum instantaneous velocity change with which the infill of support is printed.", "unit": "mm/s", @@ -1982,7 +2049,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "jerk_support_interface": { + "jerk_support_interface": + { "label": "Support Interface Jerk", "description": "The maximum instantaneous velocity change with which the roofs and bottoms of support are printed.", "unit": "mm/s", @@ -1999,7 +2067,8 @@ } } }, - "jerk_prime_tower": { + "jerk_prime_tower": + { "label": "Prime Tower Jerk", "description": "The maximum instantaneous velocity change with which the prime tower is printed.", "unit": "mm/s", @@ -2014,7 +2083,8 @@ } } }, - "jerk_travel": { + "jerk_travel": + { "label": "Travel Jerk", "description": "The maximum instantaneous velocity change with which travel moves are made.", "unit": "mm/s", @@ -2027,7 +2097,8 @@ "enabled": "jerk_enabled", "settable_per_mesh": false }, - "jerk_layer_0": { + "jerk_layer_0": + { "label": "Initial Layer Jerk", "description": "The print maximum instantaneous velocity change for the initial layer.", "unit": "mm/s", @@ -2039,7 +2110,8 @@ "maximum_value_warning": "50", "enabled": "jerk_enabled", "settable_per_mesh": true, - "children": { + "children": + { "jerk_print_layer_0": { "label": "Initial Layer Print Jerk", @@ -2071,7 +2143,8 @@ } } }, - "jerk_skirt_brim": { + "jerk_skirt_brim": + { "label": "Skirt/Brim Jerk", "description": "The maximum instantaneous velocity change with which the skirt and brim are printed.", "unit": "mm/s", @@ -2360,7 +2433,8 @@ "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true, - "children": { + "children": + { "support_line_distance": { "label": "Support Line Distance", @@ -2434,11 +2508,13 @@ "enabled": "support_enable", "settable_per_mesh": true }, - "support_xy_overrides_z": { + "support_xy_overrides_z": + { "label": "Support Distance Priority", "description": "Whether the Support X/Y Distance overrides the Support Z Distance or vice versa. When X/Y overrides Z the X/Y distance can push away the support from the model, influencing the actual Z distance to the overhang. We can disable this by not applying the X/Y distance around overhangs.", "type": "enum", - "options": { + "options": + { "xy_overrides_z": "X/Y overrides Z", "z_overrides_xy": "Z overrides X/Y" }, @@ -2447,7 +2523,8 @@ "enabled": "support_enable", "settable_per_mesh": true }, - "support_xy_distance_overhang": { + "support_xy_distance_overhang": + { "label": "Minimum Support X/Y Distance", "description": "Distance of the support structure from the overhang in the X/Y directions. ", "unit": "mm", @@ -2828,7 +2905,8 @@ "settable_per_extruder": true, "limit_to_extruder": "adhesion_extruder_nr" }, - "layer_0_z_overlap": { + "layer_0_z_overlap": + { "label": "Initial Layer Z Overlap", "description": "Make the first and second layer of the model overlap in the Z direction to compensate for the filament lost in the airgap. All models above the first model layer will be shifted down by this amount.", "unit": "mm", @@ -3057,7 +3135,8 @@ } } }, - "raft_acceleration": { + "raft_acceleration": + { "label": "Raft Print Acceleration", "description": "The acceleration with which the raft is printed.", "unit": "mm/s²", @@ -3070,8 +3149,10 @@ "enabled": "adhesion_type == \"raft\" and acceleration_enabled", "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr", - "children": { - "raft_surface_acceleration": { + "children": + { + "raft_surface_acceleration": + { "label": "Raft Top Print Acceleration", "description": "The acceleration with which the top raft layers are printed.", "unit": "mm/s²", @@ -3085,7 +3166,8 @@ "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr" }, - "raft_interface_acceleration": { + "raft_interface_acceleration": + { "label": "Raft Middle Print Acceleration", "description": "The acceleration with which the middle raft layer is printed.", "unit": "mm/s²", @@ -3099,7 +3181,8 @@ "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr" }, - "raft_base_acceleration": { + "raft_base_acceleration": + { "label": "Raft Base Print Acceleration", "description": "The acceleration with which the base raft layer is printed.", "unit": "mm/s²", @@ -3115,7 +3198,8 @@ } } }, - "raft_jerk": { + "raft_jerk": + { "label": "Raft Print Jerk", "description": "The jerk with which the raft is printed.", "unit": "mm/s", @@ -3128,8 +3212,10 @@ "enabled": "adhesion_type == \"raft\" and jerk_enabled", "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr", - "children": { - "raft_surface_jerk": { + "children": + { + "raft_surface_jerk": + { "label": "Raft Top Print Jerk", "description": "The jerk with which the top raft layers are printed.", "unit": "mm/s", @@ -3143,7 +3229,8 @@ "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr" }, - "raft_interface_jerk": { + "raft_interface_jerk": + { "label": "Raft Middle Print Jerk", "description": "The jerk with which the middle raft layer is printed.", "unit": "mm/s", @@ -3157,7 +3244,8 @@ "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr" }, - "raft_base_jerk": { + "raft_base_jerk": + { "label": "Raft Base Print Jerk", "description": "The jerk with which the base raft layer is printed.", "unit": "mm/s", @@ -3173,7 +3261,8 @@ } } }, - "raft_fan_speed": { + "raft_fan_speed": + { "label": "Raft Fan Speed", "description": "The fan speed for the raft.", "unit": "%", @@ -3264,7 +3353,8 @@ "enabled": "support_enable and machine_extruder_count > 1", "settable_per_mesh": false, "settable_per_extruder": false, - "children": { + "children": + { "support_infill_extruder_nr": { "label": "Support Infill Extruder", @@ -3601,13 +3691,15 @@ "settable_per_mesh": false, "settable_per_extruder": false }, - "conical_overhang_enabled": { + "conical_overhang_enabled": + { "label": "Make Overhang Printable", "description": "Change the geometry of the printed model such that minimal support is required. Steep overhangs will become shallow overhangs. Overhanging areas will drop down to become more vertical.", "type": "bool", "default_value": false }, - "conical_overhang_angle": { + "conical_overhang_angle": + { "label": "Maximum Model Angle", "description": "The maximum angle of overhangs after the they have been made printable. At a value of 0° all overhangs are replaced by a piece of model connected to the build plate, 90° will not change the model in any way.", "unit": "°", From b38bb5a0076832d1766bc14c16f5b63da90c5d0c Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 10 Oct 2016 11:02:43 +0200 Subject: [PATCH 02/50] fix: nylon has standby temp 175 (CURA-2567) --- resources/materials/ultimaker_nylon_black.xml.fdm_material | 2 +- .../materials/ultimaker_nylon_transparent.xml.fdm_material | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/materials/ultimaker_nylon_black.xml.fdm_material b/resources/materials/ultimaker_nylon_black.xml.fdm_material index 2d013ab408..4eed0b025c 100644 --- a/resources/materials/ultimaker_nylon_black.xml.fdm_material +++ b/resources/materials/ultimaker_nylon_black.xml.fdm_material @@ -20,6 +20,6 @@ Generic Nylon profile. Serves as an example file, data in this file is not corre 250 60 - 100 + 175 diff --git a/resources/materials/ultimaker_nylon_transparent.xml.fdm_material b/resources/materials/ultimaker_nylon_transparent.xml.fdm_material index 639f5188d4..7d80a0568c 100644 --- a/resources/materials/ultimaker_nylon_transparent.xml.fdm_material +++ b/resources/materials/ultimaker_nylon_transparent.xml.fdm_material @@ -20,6 +20,6 @@ Generic Nylon profile. Serves as an example file, data in this file is not corre 250 60 - 100 + 175 From 879ab529f229664b500cc7eb176df70d8a76a6c0 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 10 Oct 2016 17:48:00 +0200 Subject: [PATCH 03/50] Fix deleting grouped object using the context-menu CURA-2573 --- cura/CuraApplication.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index fa22227a43..b7092c4eaa 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -646,8 +646,6 @@ class CuraApplication(QtApplication): op.addOperation(RemoveSceneNodeOperation(group_node)) op.push() - pass - ## Remove an object from the scene. # Note that this only removes an object if it is selected. @pyqtSlot("quint64") @@ -661,17 +659,17 @@ class CuraApplication(QtApplication): node = Selection.getSelectedObject(0) if node: - group_node = None - if node.getParent(): - group_node = node.getParent() - op = RemoveSceneNodeOperation(node) + op = GroupedOperation() + op.addOperation(RemoveSceneNodeOperation(node)) + + group_node = node.getParent() + if group_node: + # Note that at this point the node has not yet been deleted + if len(group_node.getChildren()) <= 2 and group_node.callDecoration("isGroup"): + op.addOperation(SetParentOperation(group_node.getChildren()[0], group_node.getParent())) + op.addOperation(RemoveSceneNodeOperation(group_node)) op.push() - if group_node: - if len(group_node.getChildren()) == 1 and group_node.callDecoration("isGroup"): - op.addOperation(SetParentOperation(group_node.getChildren()[0], group_node.getParent())) - op = RemoveSceneNodeOperation(group_node) - op.push() ## Create a number of copies of existing object. @pyqtSlot("quint64", int) From 0af42587b08b0f7aca332878d6e4a1712dd47c00 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 10 Oct 2016 18:42:55 +0200 Subject: [PATCH 04/50] Fix jobname when opening multiple files at once --- resources/qml/Cura.qml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 6556f7e56a..59e4848851 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -666,10 +666,13 @@ UM.MainWindow for(var i in fileUrls) { UM.MeshFileHandler.readLocalFile(fileUrls[i]) - } - var meshName = backgroundItem.getMeshName(fileUrl.toString()) - backgroundItem.hasMesh(decodeURIComponent(meshName)) + if (i == fileUrls.length - 1) + { + var meshName = backgroundItem.getMeshName(fileUrls.toString()) + backgroundItem.hasMesh(decodeURIComponent(meshName)) + } + } } } From 3b38d52c7589b87c34a3a24a79410edf4b8f60d4 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Tue, 11 Oct 2016 11:22:16 +0200 Subject: [PATCH 05/50] fix: changelog bugfixes formatting (CURA-2000) --- plugins/ChangeLogPlugin/ChangeLog.txt | 49 ++++++++++++++------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/plugins/ChangeLogPlugin/ChangeLog.txt b/plugins/ChangeLogPlugin/ChangeLog.txt index b5f7b35457..e853933827 100644 --- a/plugins/ChangeLogPlugin/ChangeLog.txt +++ b/plugins/ChangeLogPlugin/ChangeLog.txt @@ -59,40 +59,43 @@ Set the travel speed of the initial layer(s) to reduce risk of extruder pulling *Support Interface It is now possible to print a support bottom as well as a support roof. Support bottoms are placed where the support rests on the model. -*Bug fixes & minor changes -Deleting grouped objects works as intended again. -Duplicating groups works as intended again. -Bridging works as intended again. +*Bug fixes +Deleting grouped objects +Duplicating groups +Bridging +Drag and drop on the first run on Windows +Unretraction speeds +Bottom layer in Spiralize mode +Overlap Compensation +Retractions on Raft +Retractions now occur after each object printed in one-at-a-time mode. Rafts are no longer printed outside of build area. -Messages are now displayed 30 seconds instead of 10, making it less likely that certain messages are missed. -Drag and drop on the first run on windows works again. -You are now notified if you try to save to a locked SD card. -Combing is applied in more cases and results in better paths. -Infill thickness now supports Grid infill also for even multiples of the layer height. -Unretraction speeds are correct again. -Spiralize mode doesn’t spiralize the bottom layer any more. Spiralize now spiralizes each part in a layer. -Support is no longer removed by unprintable thin parts of the model. -Support is now generated on each layer it’s supposed to. -Support doesn't go outside overhang areas any more. Line distance is now the actual line distance. Enabling raft doesn’t influence at which height the model is sliced any more. Brim is now always printed just once. -Overlap Compensation works as intended again. -A raft now produces a reasonable amount of retractions. -No more string plume on top of one-at-a-time printed objects. -Engine log is now included in the application log. Support roofs now only occur just below overhang. -Brim is now also generated under the support. -Compensate overlapping wall parts now also works for inner walls. -Bed Level and Checkup procedures for UMO+ can now be done without re-adding machine. + +*Minor changes +Messages are now displayed 30 seconds instead of 10, making it less likely that certain messages are missed. +You are now notified if you try to save to a locked SD card. +Engine log is now included in the application log. Undo and Redo now work correctly with multiple operations. The last used folder is now remembered (instead of defaulting to home folder) -You can now adjust the speed at which the bed is lowered each layer. -Settings shared between skirt and brim now also activate when brim is selected. Made it possible to add multiple Per Model Settings at once. +Bed Level and Checkup procedures for UMO+ can now be done without re-adding machine. +Combing is applied in more cases and results in better paths. +Infill thickness now supports Grid infill also for even multiples of the layer height. +Support is no longer removed by unprintable thin parts of the model. +Support is now generated on each layer it’s supposed to. +Support doesn't go outside overhang areas any more. Support doesn't remove brim around the object any more. +Brim is now also generated under the support. Draft shield and Ooze shield get their own brim or raft. +Settings shared between skirt and brim now also activate when brim is selected. +Compensate overlapping wall parts now also works for inner walls. +You can now adjust the speed at which the bed is lowered each layer. + [2.1.3] From 311ebdc3ba75d311e528bfa188d474594b7ac6c1 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Tue, 11 Oct 2016 11:35:20 +0200 Subject: [PATCH 06/50] fix: changelog clarity improvements suggested by nickthetait (CURA-2000) --- plugins/ChangeLogPlugin/ChangeLog.txt | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/plugins/ChangeLogPlugin/ChangeLog.txt b/plugins/ChangeLogPlugin/ChangeLog.txt index e853933827..8452399346 100644 --- a/plugins/ChangeLogPlugin/ChangeLog.txt +++ b/plugins/ChangeLogPlugin/ChangeLog.txt @@ -7,7 +7,7 @@ The first thing you will notice is the speed. STL loading is now 10 to 20 times Machines with multiple extruders are now supported. If you’ve got the Ultimaker Original with the dual extrusion upgrade kit, we’ve got you covered. *Custom Machine Support -The new custom machine plug-in allows you to change machine settings with ease. That means it’s now much easier to use Cura with custom machines. +It’s now much easier to use Cura with custom machines. You can edit the machine settings when you load a new custom machine. *Improved Position Tool Place objects precisely where you want them by manually entering the values for the position. @@ -35,14 +35,17 @@ Cura now estimates print weight as well as length. Configurations from older installations of Cura 2.1 are automatically imported into the newest installation. *Slicing features -*Infill Improvements -We've introduced two new infill types: Tetrahedral and Cubic. They change along with the Z-axis for more uniform strength in all directions. Also, now you can change the density of the infill based on the distance from the top layers. Your objects print faster, use less material, and maintain the same strength. +*Infill Types +We've introduced two new infill types: Tetrahedral and Cubic. They change along with the Z-axis for more uniform strength in all directions. There are now 7 infill types to choose from. + +*Gradual Infill +Now you can change the density of the infill based on the distance from the top layers. Your objects print faster, use less material, while top surfaces have the same quality. *Set Acceleration and Jerk by Feature You can now set Jerk and Acceleration by feature-type (infill, walls, top/bottom, etc), for more precision. *Outer Wall Offset -Apply an offset to where the outer wall is printed for better surface quality when the outer wall line width is smaller than the nozzle size. +If your outer wall line width is smaller than your nozzle size, move the nozzle a bit inward when printing the outer wall, to improve surface quality. *Enhanced Combing The “No Skin” option allows you to comb over infill only to avoid scars on top surfaces. @@ -57,7 +60,7 @@ The Skin Overlap setting allows you to overlap the skin lines with the walls for Set the travel speed of the initial layer(s) to reduce risk of extruder pulling the print from the bed. *Support Interface -It is now possible to print a support bottom as well as a support roof. Support bottoms are placed where the support rests on the model. +It is now possible to print a support bottom as well as a support roof. Support bottoms are placed where the support rests on the model. Printing the support interface with PVA leads to improved surface quality. *Bug fixes Deleting grouped objects @@ -70,7 +73,7 @@ Overlap Compensation Retractions on Raft Retractions now occur after each object printed in one-at-a-time mode. Rafts are no longer printed outside of build area. -Spiralize now spiralizes each part in a layer. +Spiralize no longer only spiralizes the first printed segment only. Line distance is now the actual line distance. Enabling raft doesn’t influence at which height the model is sliced any more. Brim is now always printed just once. @@ -81,7 +84,8 @@ Messages are now displayed 30 seconds instead of 10, making it less likely that You are now notified if you try to save to a locked SD card. Engine log is now included in the application log. Undo and Redo now work correctly with multiple operations. -The last used folder is now remembered (instead of defaulting to home folder) +The last used folder is now remembered (instead of defaulting to home folder). +Import X3D files. Made it possible to add multiple Per Model Settings at once. Bed Level and Checkup procedures for UMO+ can now be done without re-adding machine. Combing is applied in more cases and results in better paths. @@ -96,7 +100,6 @@ Settings shared between skirt and brim now also activate when brim is selected. Compensate overlapping wall parts now also works for inner walls. You can now adjust the speed at which the bed is lowered each layer. - [2.1.3] *Material Profiles From 0c604ca002e9635237257b225d35b1e5b3ef3c62 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 11 Oct 2016 13:34:02 +0200 Subject: [PATCH 07/50] Update translation of PostProcessingPlugin These were missed previous time because I had my extract script set-up wrong. Contributes to issue CURA-570. --- resources/i18n/de/cura.po | 39 +++++++++++++++++++++++++++++++++++++++ resources/i18n/es/cura.po | 39 +++++++++++++++++++++++++++++++++++++++ resources/i18n/fi/cura.po | 39 +++++++++++++++++++++++++++++++++++++++ resources/i18n/fr/cura.po | 39 +++++++++++++++++++++++++++++++++++++++ resources/i18n/it/cura.po | 39 +++++++++++++++++++++++++++++++++++++++ resources/i18n/nl/cura.po | 39 +++++++++++++++++++++++++++++++++++++++ resources/i18n/tr/cura.po | 39 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 273 insertions(+) diff --git a/resources/i18n/de/cura.po b/resources/i18n/de/cura.po index 5865f8ebed..7dd480bf81 100644 --- a/resources/i18n/de/cura.po +++ b/resources/i18n/de/cura.po @@ -2294,3 +2294,42 @@ msgid "" "\n" "Click to open the profile manager." msgstr "Einige Einstellungswerte unterscheiden sich von den im Profil gespeicherten Werten.\n\nKlicken Sie, um den Profilmanager zu öffnen." + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:24 +msgid "Modify G-Code" +msgstr "G-Code ändern" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:12 +msgctxt "@label" +msgid "Post Processing" +msgstr "Nachbearbeitung" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:16 +msgctxt "Description of plugin" +msgid "Extension that allows for user created scripts for post processing" +msgstr "Erweiterung, die eine Nachbearbeitung von Skripten ermöglicht, die von Benutzern erstellt wurden." + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:18 +msgctxt "@title:window" +msgid "Post Processing Plugin" +msgstr "Plugin Nachbearbeitung" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:49 +msgctxt "@label" +msgid "Post Processing Scripts" +msgstr "Skripts Nachbearbeitung" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:218 +msgctxt "@action" +msgid "Add a script" +msgstr "Ein Skript hinzufügen" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:264 +msgctxt "@label" +msgid "Settings" +msgstr "Einstellungen" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:456 +msgctxt "@info:tooltip" +msgid "Change active post-processing scripts" +msgstr "Aktive Skripts Nachbearbeitung ändern" diff --git a/resources/i18n/es/cura.po b/resources/i18n/es/cura.po index 8bee1f3c52..ef82e6be05 100644 --- a/resources/i18n/es/cura.po +++ b/resources/i18n/es/cura.po @@ -2294,3 +2294,42 @@ msgid "" "\n" "Click to open the profile manager." msgstr "Algunos valores son distintos de los valores almacenados en el perfil.\n\nHaga clic para abrir el administrador de perfiles." + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:24 +msgid "Modify G-Code" +msgstr "Modificar GCode" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:12 +msgctxt "@label" +msgid "Post Processing" +msgstr "Posprocesamiento" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:16 +msgctxt "Description of plugin" +msgid "Extension that allows for user created scripts for post processing" +msgstr "Extensión que permite el posprocesamiento de las secuencias de comandos creadas por los usuarios." + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:18 +msgctxt "@title:window" +msgid "Post Processing Plugin" +msgstr "Complemento de posprocesamiento" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:49 +msgctxt "@label" +msgid "Post Processing Scripts" +msgstr "Secuencias de comandos de posprocesamiento" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:218 +msgctxt "@action" +msgid "Add a script" +msgstr "Añadir secuencia de comando" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:264 +msgctxt "@label" +msgid "Settings" +msgstr "Ajustes" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:456 +msgctxt "@info:tooltip" +msgid "Change active post-processing scripts" +msgstr "Cambia las secuencias de comandos de posprocesamiento." diff --git a/resources/i18n/fi/cura.po b/resources/i18n/fi/cura.po index 04b196c6ce..c96b976be0 100644 --- a/resources/i18n/fi/cura.po +++ b/resources/i18n/fi/cura.po @@ -2294,3 +2294,42 @@ msgid "" "\n" "Click to open the profile manager." msgstr "Jotkut asetusten arvot eroavat profiiliin tallennetuista arvoista.\n\nAvaa profiilin hallinta napsauttamalla." + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:24 +msgid "Modify G-Code" +msgstr "Muokkaa GCode-arvoa" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:12 +msgctxt "@label" +msgid "Post Processing" +msgstr "Jälkikäsittely" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:16 +msgctxt "Description of plugin" +msgid "Extension that allows for user created scripts for post processing" +msgstr "Lisäosa, jonka avulla käyttäjät voivat luoda komentosarjoja jälkikäsittelyä varten" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:18 +msgctxt "@title:window" +msgid "Post Processing Plugin" +msgstr "Jälkikäsittelylisäosa" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:49 +msgctxt "@label" +msgid "Post Processing Scripts" +msgstr "Jälkikäsittelykomentosarjat" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:218 +msgctxt "@action" +msgid "Add a script" +msgstr "Lisää komentosarja" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:264 +msgctxt "@label" +msgid "Settings" +msgstr "Asetukset" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:456 +msgctxt "@info:tooltip" +msgid "Change active post-processing scripts" +msgstr "Muuta aktiivisia jälkikäsittelykomentosarjoja" diff --git a/resources/i18n/fr/cura.po b/resources/i18n/fr/cura.po index c895cd41f5..ea3ed63c31 100644 --- a/resources/i18n/fr/cura.po +++ b/resources/i18n/fr/cura.po @@ -2294,3 +2294,42 @@ msgid "" "\n" "Click to open the profile manager." msgstr "Certaines valeurs de paramètre sont différentes des valeurs enregistrées dans le profil.\n\nCliquez pour ouvrir le gestionnaire de profils." + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:24 +msgid "Modify G-Code" +msgstr "Modifier le G-Code" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:12 +msgctxt "@label" +msgid "Post Processing" +msgstr "Post-traitement" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:16 +msgctxt "Description of plugin" +msgid "Extension that allows for user created scripts for post processing" +msgstr "Extension qui permet le post-traitement des scripts créés par l'utilisateur" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:18 +msgctxt "@title:window" +msgid "Post Processing Plugin" +msgstr "Plug-in de post-traitement" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:49 +msgctxt "@label" +msgid "Post Processing Scripts" +msgstr "Scripts de post-traitement" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:218 +msgctxt "@action" +msgid "Add a script" +msgstr "Ajouter un script" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:264 +msgctxt "@label" +msgid "Settings" +msgstr "Paramètres" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:456 +msgctxt "@info:tooltip" +msgid "Change active post-processing scripts" +msgstr "Modifier les scripts de post-traitement actifs" diff --git a/resources/i18n/it/cura.po b/resources/i18n/it/cura.po index 2483c09260..92ecd581cd 100644 --- a/resources/i18n/it/cura.po +++ b/resources/i18n/it/cura.po @@ -2294,3 +2294,42 @@ msgid "" "\n" "Click to open the profile manager." msgstr "Alcuni valori di impostazione sono diversi dai valori memorizzati nel profilo.\n\nFare clic per aprire la gestione profili." + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:24 +msgid "Modify G-Code" +msgstr "Modifica il codice G" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:12 +msgctxt "@label" +msgid "Post Processing" +msgstr "Post-elaborazione" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:16 +msgctxt "Description of plugin" +msgid "Extension that allows for user created scripts for post processing" +msgstr "Estensione che consente la post-elaborazione degli script creati da utente" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:18 +msgctxt "@title:window" +msgid "Post Processing Plugin" +msgstr "Plug-in di post-elaborazione" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:49 +msgctxt "@label" +msgid "Post Processing Scripts" +msgstr "Script di post-elaborazione" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:218 +msgctxt "@action" +msgid "Add a script" +msgstr "Aggiungi uno script" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:264 +msgctxt "@label" +msgid "Settings" +msgstr "Impostazioni" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:456 +msgctxt "@info:tooltip" +msgid "Change active post-processing scripts" +msgstr "Modifica script di post-elaborazione attivi" diff --git a/resources/i18n/nl/cura.po b/resources/i18n/nl/cura.po index 3dd69d0a0d..ee566a61ad 100644 --- a/resources/i18n/nl/cura.po +++ b/resources/i18n/nl/cura.po @@ -2294,3 +2294,42 @@ msgid "" "\n" "Click to open the profile manager." msgstr "Sommige instellingswaarden zijn anders dan de waarden die in het profiel zijn opgeslagen.\n\nKlik om het profielbeheer te openen." + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:24 +msgid "Modify G-Code" +msgstr "G-code wijzigen" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:12 +msgctxt "@label" +msgid "Post Processing" +msgstr "Nabewerken" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:16 +msgctxt "Description of plugin" +msgid "Extension that allows for user created scripts for post processing" +msgstr "Uitbreiding waarmee door de gebruiker gemaakte scripts voor nabewerking kunnen worden gebruikt" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:18 +msgctxt "@title:window" +msgid "Post Processing Plugin" +msgstr "Invoegtoepassing voor nabewerking" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:49 +msgctxt "@label" +msgid "Post Processing Scripts" +msgstr "Scripts voor nabewerking" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:218 +msgctxt "@action" +msgid "Add a script" +msgstr "Een script toevoegen" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:264 +msgctxt "@label" +msgid "Settings" +msgstr "Instellingen" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:456 +msgctxt "@info:tooltip" +msgid "Change active post-processing scripts" +msgstr "Actieve scripts voor nabewerking wijzigen" diff --git a/resources/i18n/tr/cura.po b/resources/i18n/tr/cura.po index 940ffb3e5e..511ed43c47 100644 --- a/resources/i18n/tr/cura.po +++ b/resources/i18n/tr/cura.po @@ -2294,3 +2294,42 @@ msgid "" "\n" "Click to open the profile manager." msgstr "Bazı ayar değerleri profilinizde saklanan değerlerden farklıdır.\n\nProfil yöneticisini açmak için tıklayın." + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:24 +msgid "Modify G-Code" +msgstr "GCode Değiştir" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:12 +msgctxt "@label" +msgid "Post Processing" +msgstr "Son İşleme" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:16 +msgctxt "Description of plugin" +msgid "Extension that allows for user created scripts for post processing" +msgstr "Kullanıcının oluşturduğu komut dosyalarına son işleme için izin veren uzantı" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:18 +msgctxt "@title:window" +msgid "Post Processing Plugin" +msgstr "Son İşleme Uzantısı" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:49 +msgctxt "@label" +msgid "Post Processing Scripts" +msgstr "Son İşleme Dosyaları" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:218 +msgctxt "@action" +msgid "Add a script" +msgstr "Dosya ekle" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:264 +msgctxt "@label" +msgid "Settings" +msgstr "Ayarlar" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:456 +msgctxt "@info:tooltip" +msgid "Change active post-processing scripts" +msgstr "Etkin son işleme dosyalarını değiştir" From d04e6a664417108141ae9fae319c037588d468a1 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 11 Oct 2016 13:34:48 +0200 Subject: [PATCH 08/50] Use buffered writing for writing gcode to removable drives GCode files are still written line by line, but python is instructed to use buffering. This greatly decreases the total time required to write large(ish) files to USB drives, while having minimal impact on memory use. CURA-2544 --- .../RemovableDriveOutputDevice.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py index efb7929327..b7d31e68f8 100644 --- a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py +++ b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py @@ -23,6 +23,7 @@ class RemovableDriveOutputDevice(OutputDevice): self.setPriority(1) self._writing = False + self._stream = None def requestWrite(self, node, file_name = None, filter_by_machine = False): filter_by_machine = True # This plugin is indended to be used by machine (regardless of what it was told to do) @@ -65,8 +66,8 @@ class RemovableDriveOutputDevice(OutputDevice): try: Logger.log("d", "Writing to %s", file_name) - stream = open(file_name, "wt") - job = WriteMeshJob(writer, stream, node, MeshWriter.OutputMode.TextMode) + self._stream = open(file_name, "wt", buffering = 1) + job = WriteMeshJob(writer, self._stream, node, MeshWriter.OutputMode.TextMode) job.setFileName(file_name) job.progress.connect(self._onProgress) job.finished.connect(self._onFinished) @@ -92,6 +93,10 @@ class RemovableDriveOutputDevice(OutputDevice): self.writeProgress.emit(self, progress) def _onFinished(self, job): + if self._stream: + self._stream.close() + self._stream = None + if hasattr(job, "_message"): job._message.hide() job._message = None From 15a870c050b3d45151d30147608f868811114481 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 11 Oct 2016 13:39:44 +0200 Subject: [PATCH 09/50] Add some documentation CURA-2544 --- .../RemovableDriveOutputDevice/RemovableDriveOutputDevice.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py index b7d31e68f8..8b6dce8292 100644 --- a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py +++ b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py @@ -66,6 +66,7 @@ class RemovableDriveOutputDevice(OutputDevice): try: Logger.log("d", "Writing to %s", file_name) + # Using buffering greatly reduces the write time for many lines of gcode self._stream = open(file_name, "wt", buffering = 1) job = WriteMeshJob(writer, self._stream, node, MeshWriter.OutputMode.TextMode) job.setFileName(file_name) @@ -94,6 +95,7 @@ class RemovableDriveOutputDevice(OutputDevice): def _onFinished(self, job): if self._stream: + # Explicitly closing the stream flushes the write-buffer self._stream.close() self._stream = None From 63afe917e5a4933e0a6c8a7cf144f4e9960881d4 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Tue, 11 Oct 2016 14:08:10 +0200 Subject: [PATCH 10/50] JSON fix: combing mode has link icon now (CURA-2568) --- resources/definitions/fdmprinter.def.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 094735e50e..7e9419c709 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -2159,7 +2159,8 @@ }, "default_value": "all", "resolve": "'noskin' if 'noskin' in extruderValues('retraction_combing') else ('all' if 'all' in extruderValues('retraction_combing') else 'off')", - "settable_per_mesh": true + "settable_per_mesh": true, + "settable_per_extruder": false }, "travel_avoid_other_parts": { From 16d5633b74c1dcc470c5e4ab43c270a1f90070f3 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 11 Oct 2016 14:21:40 +0200 Subject: [PATCH 11/50] Fix "unsupported" warning on UM2+ 0.25 and 0.8 variants Contributes to 2271, fixes 2616 --- cura/Settings/MachineManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 8f7f311f47..46c1ec09b7 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -568,7 +568,7 @@ class MachineManager(QObject): candidate_quality = quality_manager.findQualityByQualityType(quality_type, quality_manager.getWholeMachineDefinition(machine_definition), [material_container]) - if not candidate_quality: + if not candidate_quality or candidate_quality.getId() == "empty_quality": # Fall back to a quality new_quality = quality_manager.findQualityByQualityType(None, quality_manager.getWholeMachineDefinition(machine_definition), From f2e054b449e343f3d99bb0e38f5649eae8500ccf Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 11 Oct 2016 11:01:14 +0200 Subject: [PATCH 12/50] Fix the active quality id activeQualityId and activeQualityName were not referencing the same profile. activeMaterialName seems to have the correct one. CURA-2271 --- cura/Settings/MachineManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 46c1ec09b7..7508fc6952 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -475,11 +475,11 @@ class MachineManager(QObject): @pyqtProperty(str, notify=activeQualityChanged) def activeQualityId(self): - if self._global_container_stack: + if self._active_container_stack and self._global_container_stack: quality = self._global_container_stack.findContainer({"type": "quality_changes"}) if quality and quality != self._empty_quality_changes_container: return quality.getId() - quality = self._global_container_stack.findContainer({"type": "quality"}) + quality = self._active_container_stack.findContainer({"type": "quality"}) if quality: return quality.getId() return "" From b119be7d119db9485ce6aacdc91a5260bac557d9 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 11 Oct 2016 15:00:17 +0200 Subject: [PATCH 13/50] Remove settings from extruder that are not settable_per_extruder. CURA-2605 --- plugins/CuraEngineBackend/StartSliceJob.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 210652720a..3c73a6ef90 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -204,6 +204,8 @@ class StartSliceJob(Job): material_instance_container = stack.findContainer({"type": "material"}) for key in stack.getAllKeys(): + if stack.getProperty(key, "settable_per_extruder") == False: + continue setting = message.getMessage("settings").addRepeatedMessage("settings") setting.name = key if key == "material_guid" and material_instance_container: From e31253084057fd56c699fa7e3413ef39a5eff1b1 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 11 Oct 2016 12:34:29 +0200 Subject: [PATCH 14/50] Fix errors on profiles page for unsupported material combinations CURA-2271 --- cura/Settings/QualitySettingsModel.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cura/Settings/QualitySettingsModel.py b/cura/Settings/QualitySettingsModel.py index 638a53e4b8..eb59c7597f 100644 --- a/cura/Settings/QualitySettingsModel.py +++ b/cura/Settings/QualitySettingsModel.py @@ -120,7 +120,11 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): quality_container = quality_container[0] quality_type = quality_container.getMetaDataEntry("quality_type") - definition_id = quality_container.getDefinition().getId() + definition = quality_container.getDefinition() + if definition: + definition_id = definition.getId() + else: + definition_id = "empty_quality" criteria = {"type": "quality", "quality_type": quality_type, "definition": definition_id} @@ -136,9 +140,9 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): new_criteria.pop("extruder") containers = self._container_registry.findInstanceContainers(**new_criteria) - if not containers: + if not containers and "material" in criteria: # Try again, this time without material - criteria.pop("material") + criteria.pop("material", None) containers = self._container_registry.findInstanceContainers(**criteria) if not containers: @@ -147,7 +151,7 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): containers = self._container_registry.findInstanceContainers(**criteria) if not containers: - UM.Logger.log("Could not find any quality containers matching the search criteria %s" % str(criteria)) + UM.Logger.log("w", "Could not find any quality containers matching the search criteria %s" % str(criteria)) return if quality_changes_container: From d45f61f778d5fa788ed018f0fe5f922d1eb2ae89 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 11 Oct 2016 15:13:16 +0200 Subject: [PATCH 15/50] Comment. CURA-2605 --- plugins/CuraEngineBackend/StartSliceJob.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 3c73a6ef90..18c7fb1f5c 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -204,6 +204,7 @@ class StartSliceJob(Job): material_instance_container = stack.findContainer({"type": "material"}) for key in stack.getAllKeys(): + # Do not send settings that are not settable_per_extruder. if stack.getProperty(key, "settable_per_extruder") == False: continue setting = message.getMessage("settings").addRepeatedMessage("settings") From 95fabbaf6d9522cf05804a143cbbb67a87171535 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 11 Oct 2016 15:20:13 +0200 Subject: [PATCH 16/50] Don't allow creating profiles based on empty_profile ...because empty_profile has no quality_type CURA-2271 --- resources/qml/Actions.qml | 2 +- resources/qml/Preferences/ProfilesPage.qml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index 3ee8630183..300a9056d4 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -137,7 +137,7 @@ Item Action { id: addProfileAction; - enabled: Cura.MachineManager.isActiveStackValid && Cura.MachineManager.hasUserSettings + enabled: Cura.MachineManager.isActiveStackValid && Cura.MachineManager.hasUserSettings && Cura.MachineManager.activeQualityId != "empty_quality" text: catalog.i18nc("@action:inmenu menubar:profile","&Create profile from current settings..."); } diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 42c055486a..238b5f022b 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -62,7 +62,7 @@ UM.ManagementPage Button { text: catalog.i18nc("@label", "Create") - enabled: base.canCreateProfile() + enabled: base.canCreateProfile() && Cura.MachineManager.activeQualityId != "empty_quality" visible: base.canCreateProfile() iconName: "list-add"; @@ -78,7 +78,7 @@ UM.ManagementPage Button { text: catalog.i18nc("@label", "Duplicate") - enabled: ! base.canCreateProfile() + enabled: ! base.canCreateProfile() && Cura.MachineManager.activeQualityId != "empty_quality" visible: ! base.canCreateProfile() iconName: "list-add"; From 50390dae03f71dc6ce6c39ee3a9781efd8d62028 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 11 Oct 2016 16:01:06 +0200 Subject: [PATCH 17/50] Replace all instances of "layer_height" in functions with resolveOrValue Since we have layer_height in quality profiles (and cannot remove it) we need to handle this. It turns out using resolveOrValue is a quick fix. Fixes CURA-2604 --- resources/definitions/fdmprinter.def.json | 32 +++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 7e9419c709..ef16334c09 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -761,7 +761,7 @@ "unit": "mm", "default_value": 0.8, "minimum_value": "0", - "minimum_value_warning": "3 * layer_height", + "minimum_value_warning": "3 * resolveOrValue('layer_height')", "maximum_value": "machine_height", "type": "float", "value": "top_bottom_thickness", @@ -777,7 +777,7 @@ "maximum_value_warning": "100", "type": "int", "minimum_value_warning": "4", - "value": "0 if infill_sparse_density == 100 else math.ceil(round(top_thickness / layer_height, 4))", + "value": "0 if infill_sparse_density == 100 else math.ceil(round(top_thickness / resolveOrValue('layer_height'), 4))", "settable_per_mesh": true } } @@ -789,7 +789,7 @@ "unit": "mm", "default_value": 0.6, "minimum_value": "0", - "minimum_value_warning": "3 * layer_height", + "minimum_value_warning": "3 * resolveOrValue('layer_height')", "type": "float", "value": "top_bottom_thickness", "maximum_value": "machine_height", @@ -804,7 +804,7 @@ "minimum_value_warning": "4", "default_value": 6, "type": "int", - "value": "999999 if infill_sparse_density == 100 else math.ceil(round(bottom_thickness / layer_height, 4))", + "value": "999999 if infill_sparse_density == 100 else math.ceil(round(bottom_thickness / resolveOrValue('layer_height'), 4))", "settable_per_mesh": true } } @@ -1044,10 +1044,10 @@ "unit": "mm", "type": "float", "default_value": 0.1, - "minimum_value": "layer_height", + "minimum_value": "resolveOrValue('layer_height')", "maximum_value_warning": "0.75 * machine_nozzle_size", - "maximum_value": "layer_height * 8", - "value": "layer_height", + "maximum_value": "resolveOrValue('layer_height') * 8", + "value": "resolveOrValue('layer_height')", "enabled": "infill_sparse_density > 0", "settable_per_mesh": true }, @@ -1071,7 +1071,7 @@ "type": "float", "default_value": 5.0, "minimum_value": "0.0001", - "minimum_value_warning": "3 * layer_height", + "minimum_value_warning": "3 * resolveOrValue('layer_height')", "maximum_value_warning": "100", "enabled": "infill_sparse_density > 0 and gradual_infill_steps > 0", "settable_per_mesh": true @@ -1664,7 +1664,7 @@ "default_value": 2, "resolve": "sum(extruderValues('speed_slowdown_layers')) / len(extruderValues('speed_slowdown_layers'))", "minimum_value": "0", - "maximum_value_warning": "1.0 / layer_height", + "maximum_value_warning": "1.0 / resolveOrValue('layer_height')", "settable_per_mesh": false, "settable_per_extruder": false }, @@ -2284,8 +2284,8 @@ "type": "int", "default_value": 2, "minimum_value": "1", - "maximum_value_warning": "10 / layer_height", - "value": "max(1, int(math.floor((cool_fan_full_at_height - resolveOrValue('layer_height_0')) / layer_height) + 2))", + "maximum_value_warning": "10 / resolveOrValue('layer_height')", + "value": "max(1, int(math.floor((cool_fan_full_at_height - resolveOrValue('layer_height_0')) / resolveOrValue('layer_height')) + 2))", "settable_per_mesh": false, "settable_per_extruder": true } @@ -2574,7 +2574,7 @@ "type": "float", "default_value": 1, "minimum_value": "0", - "minimum_value_warning": "3 * layer_height", + "minimum_value_warning": "3 * resolveOrValue('layer_height')", "maximum_value_warning": "10", "limit_to_extruder": "support_interface_extruder_nr", "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable", @@ -2589,7 +2589,7 @@ "type": "float", "default_value": 1, "minimum_value": "0", - "minimum_value_warning": "3 * layer_height", + "minimum_value_warning": "3 * resolveOrValue('layer_height')", "maximum_value_warning": "10", "value": "extruderValue(support_interface_extruder_nr, 'support_interface_height')", "limit_to_extruder": "support_interface_extruder_nr", @@ -2605,7 +2605,7 @@ "default_value": 1, "value": "extruderValue(support_interface_extruder_nr, 'support_interface_height')", "minimum_value": "0", - "minimum_value_warning": "min(3 * layer_height, extruderValue(support_interface_extruder_nr, 'support_bottom_stair_step_height'))", + "minimum_value_warning": "min(3 * resolveOrValue('layer_height'), extruderValue(support_interface_extruder_nr, 'support_bottom_stair_step_height'))", "maximum_value_warning": "10", "limit_to_extruder": "support_interface_extruder_nr", "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable", @@ -2926,7 +2926,7 @@ "unit": "mm", "type": "float", "default_value": 0.1, - "value": "layer_height", + "value": "resolveOrValue('layer_height')", "minimum_value": "0.001", "minimum_value_warning": "0.04", "maximum_value_warning": "0.75 * extruderValue(adhesion_extruder_nr, 'machine_nozzle_size')", @@ -2974,7 +2974,7 @@ "unit": "mm", "type": "float", "default_value": 0.15, - "value": "layer_height * 1.5", + "value": "resolveOrValue('layer_height') * 1.5", "minimum_value": "0.001", "minimum_value_warning": "0.04", "maximum_value_warning": "0.75 * extruderValue(adhesion_extruder_nr, 'raft_interface_line_width')", From 34630fa646f13f683b4778fbbe1a2be688e1fadf Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 11 Oct 2016 16:36:32 +0200 Subject: [PATCH 18/50] Also show the "unsupported" warning when a custom profile is selected ...by making sure we're looking at the quality container (not quality_changes) of the active extruder/stack CURA-2271 --- cura/Settings/MachineManager.py | 15 +++++++++++++++ resources/qml/SidebarHeader.qml | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 7508fc6952..6c038a2ee7 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -492,6 +492,21 @@ class MachineManager(QObject): return quality.getMetaDataEntry("quality_type") return "" + ## Get the Quality ID associated with the currently active extruder + # Note that this only returns the "quality", not the "quality_changes" + # \returns QualityID (string) if found, empty string otherwise + # \sa activeQualityId() + # \todo Ideally, this method would be named activeQualityId(), and the other one + # would be named something like activeQualityOrQualityChanges() for consistency + @pyqtProperty(str, notify = activeQualityChanged) + def activeQualityContainerId(self): + # We're using the active stack instead of the global stack in case the list of qualities differs per extruder + if self._active_container_stack: + quality = self._active_container_stack.findContainer(type = "quality") + if quality: + return quality.getId() + return "" + @pyqtProperty(str, notify = activeQualityChanged) def activeQualityChangesId(self): if self._global_container_stack: diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 3e36cfbaa0..e8f4aa8e47 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -244,7 +244,7 @@ Column } } - property var valueWarning: Cura.MachineManager.activeQualityId == "empty_quality" + property var valueWarning: Cura.MachineManager.activeQualityContainerId == "empty_quality" enabled: !extrudersList.visible || base.currentExtruderIndex > -1 From ef3e8dc4fa186e308c71ec2edb37e5ae1cb593ee Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Wed, 12 Oct 2016 11:31:18 +0200 Subject: [PATCH 19/50] Make sure that the activeQualityChanged signal is emitted when the _active_container_stack changes. CURA-2271 --- cura/Settings/MachineManager.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 6c038a2ee7..2ec0d69bdd 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -223,6 +223,9 @@ class MachineManager(QObject): def _onActiveExtruderStackChanged(self): self.blurSettings.emit() # Ensure no-one has focus. + + old_active_container_stack = self._active_container_stack + if self._active_container_stack and self._active_container_stack != self._global_container_stack: self._active_container_stack.containersChanged.disconnect(self._onInstanceContainersChanged) self._active_container_stack.propertyChanged.disconnect(self._onPropertyChanged) @@ -232,8 +235,16 @@ class MachineManager(QObject): self._active_container_stack.propertyChanged.connect(self._onPropertyChanged) else: self._active_container_stack = self._global_container_stack + + old_active_stack_valid = self._active_stack_valid self._active_stack_valid = not self._checkStackForErrors(self._active_container_stack) - self.activeStackValidationChanged.emit() + if old_active_stack_valid != self._active_stack_valid: + self.activeStackValidationChanged.emit() + + if old_active_container_stack != self._active_container_stack: + # Many methods and properties related to the active quality actually depend + # on _active_container_stack. If it changes, then the properties change. + self.activeQualityChanged.emit() def _onInstanceContainersChanged(self, container): container_type = container.getMetaDataEntry("type") From d9b428e6c8cd849cff5824b30b999daf1da6b4a3 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 12 Oct 2016 11:42:07 +0200 Subject: [PATCH 20/50] Get material IDs from correct definition id if quality_definition For printers with a quality_definition, such as UM2E+, the material ID needs to be taken for the definition ID specified in the quality_definition metadata field. The self.activeQualityDefinitionId takes care of that, even though it is named wrong (as it applies to materials as well as quality profiles). Contributes to issue CURA-2600. --- cura/Settings/MachineManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 46c1ec09b7..33d7119378 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -134,7 +134,7 @@ class MachineManager(QObject): definition_id = "fdmprinter" if self._global_container_stack.getMetaDataEntry("has_machine_materials", False): - definition_id = self._global_container_stack.getBottom().getId() + definition_id = self.activeQualityDefinitionId extruder_manager = ExtruderManager.getInstance() containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "material", definition = definition_id, GUID = material_id) if containers: # New material ID is known @@ -145,7 +145,7 @@ class MachineManager(QObject): matching_extruder = extruder break - if matching_extruder and matching_extruder.findContainer({"type":"material"}).getMetaDataEntry("GUID") != material_id: + if matching_extruder and matching_extruder.findContainer({"type": "material"}).getMetaDataEntry("GUID") != material_id: # Save the material that needs to be changed. Multiple changes will be handled by the callback. self._auto_materials_changed[str(index)] = containers[0].getId() self._printer_output_devices[0].materialHotendChangedMessage(self._materialHotendChangedCallback) From f60146ad26102cf98c60b34f9bd65a684c3c1c28 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 12 Oct 2016 11:59:54 +0200 Subject: [PATCH 21/50] Active quality ID is selected from active stack instead of global CURA-2624 --- cura/Settings/MachineManager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 46c1ec09b7..fb30ff42a8 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -475,11 +475,11 @@ class MachineManager(QObject): @pyqtProperty(str, notify=activeQualityChanged) def activeQualityId(self): - if self._global_container_stack: - quality = self._global_container_stack.findContainer({"type": "quality_changes"}) + if self._active_container_stack: + quality = self._active_container_stack.findContainer({"type": "quality_changes"}) if quality and quality != self._empty_quality_changes_container: return quality.getId() - quality = self._global_container_stack.findContainer({"type": "quality"}) + quality = self._active_container_stack.findContainer({"type": "quality"}) if quality: return quality.getId() return "" From 67a02ee90e34d1ec65ff7816d3f50762d2cc0557 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 12 Oct 2016 13:48:08 +0200 Subject: [PATCH 22/50] ActiveQualityType and activeQualityChangesId now use activeContainer CURA-2624 --- cura/Settings/MachineManager.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 3e36bab8e1..a4f0c4eb91 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -486,16 +486,16 @@ class MachineManager(QObject): @pyqtProperty(str, notify = activeQualityChanged) def activeQualityType(self): - if self._global_container_stack: - quality = self._global_container_stack.findContainer(type = "quality") + if self._active_container_stack: + quality = self._active_container_stack.findContainer(type = "quality") if quality: return quality.getMetaDataEntry("quality_type") return "" @pyqtProperty(str, notify = activeQualityChanged) def activeQualityChangesId(self): - if self._global_container_stack: - changes = self._global_container_stack.findContainer(type = "quality_changes") + if self._active_container_stack: + changes = self._active_container_stack.findContainer(type = "quality_changes") if changes: return changes.getId() return "" From 3f6877d2ec8f2df42ccac8f6488a5cb2a385e53b Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 12 Oct 2016 13:58:09 +0200 Subject: [PATCH 23/50] Keep per object extruder when switching machines. CURA-2533 --- cura/Settings/SettingOverrideDecorator.py | 9 +++++++++ .../PerObjectSettingsTool/PerObjectSettingsTool.py | 13 +++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/cura/Settings/SettingOverrideDecorator.py b/cura/Settings/SettingOverrideDecorator.py index 8c10542069..a8cfcd8d80 100644 --- a/cura/Settings/SettingOverrideDecorator.py +++ b/cura/Settings/SettingOverrideDecorator.py @@ -61,6 +61,15 @@ class SettingOverrideDecorator(SceneNodeDecorator): def getActiveExtruder(self): return self._extruder_stack + ## Gets the currently active extruders position + # + # \return An extruder's position, or None if no position info is available. + def getActiveExtruderPosition(self): + containers = ContainerRegistry.getInstance().findContainers(id = self.getActiveExtruder()) + if containers: + container_stack = containers[0] + return container_stack.getMetaDataEntry("position", default=None) + def _onSettingChanged(self, instance, property_name): # Reminder: 'property' is a built-in function if property_name == "value": # Only reslice if the value has changed. Application.getInstance().getBackend().forceSlice() diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py index a90bb4b6d0..5834a5c606 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py @@ -84,11 +84,20 @@ class PerObjectSettingsTool(Tool): default_stack = ExtruderManager.getInstance().getExtruderStack(0) if default_stack: default_stack_id = default_stack.getId() - else: default_stack_id = global_container_stack.getId() + else: + default_stack_id = global_container_stack.getId() root_node = Application.getInstance().getController().getScene().getRoot() for node in DepthFirstIterator(root_node): - node.callDecoration("setActiveExtruder", default_stack_id) + new_stack_id = default_stack_id + # Get position of old extruder stack for this node + old_extruder_pos = node.callDecoration("getActiveExtruderPosition") + if old_extruder_pos is not None: + # Fetch current (new) extruder stack at position + new_stack = ExtruderManager.getInstance().getExtruderStack(old_extruder_pos) + if new_stack: + new_stack_id = new_stack.getId() + node.callDecoration("setActiveExtruder", new_stack_id) self._updateEnabled() From c3cf7624518dc238523414208c9e3c5ce9b655da Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Wed, 12 Oct 2016 15:57:50 +0200 Subject: [PATCH 24/50] Show the warning color for unsupported materials/qualities by using the new 'supported' metadata flag. CURA-2271 --- cura/QualityManager.py | 8 +------- cura/Settings/MachineManager.py | 11 ++++++++++- cura/Settings/QualitySettingsModel.py | 6 +----- resources/qml/Actions.qml | 2 +- resources/qml/Preferences/ProfilesPage.qml | 4 ++-- resources/qml/SidebarHeader.qml | 4 ++-- 6 files changed, 17 insertions(+), 18 deletions(-) diff --git a/cura/QualityManager.py b/cura/QualityManager.py index a304eb1db3..c356951156 100644 --- a/cura/QualityManager.py +++ b/cura/QualityManager.py @@ -20,9 +20,6 @@ class QualityManager: __instance = None - def __init__(self): - self._empty_quality_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_quality")[0] - ## Find a quality by name for a specific machine definition and materials. # # \param quality_name @@ -96,7 +93,7 @@ class QualityManager: basic_materials = self._getBasicMaterials(material_containers[0]) result = self._getFilteredContainersForStack(machine_definition, basic_materials, **criteria) - return result[0] if result else self._empty_quality_container + return result[0] if result else None ## Find all suitable qualities for a combination of machine and material. # @@ -110,9 +107,6 @@ class QualityManager: basic_materials = self._getBasicMaterials(material_container) result = self._getFilteredContainersForStack(machine_definition, basic_materials, **criteria) - if not result: - result = [ self._empty_quality_container ] - return result ## Find all quality changes for a machine. diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 9b62e3ac0d..868df179ae 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -3,6 +3,7 @@ from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal from PyQt5.QtWidgets import QMessageBox +from UM import Util from UM.Application import Application from UM.Preferences import Preferences @@ -503,6 +504,14 @@ class MachineManager(QObject): return quality.getMetaDataEntry("quality_type") return "" + @pyqtProperty(bool, notify = activeQualityChanged) + def isActiveQualitySupported(self): + if self._active_container_stack: + quality = self._active_container_stack.findContainer(type = "quality") + if quality: + return Util.parseBool(quality.getMetaDataEntry("supported", True)) + return "" + ## Get the Quality ID associated with the currently active extruder # Note that this only returns the "quality", not the "quality_changes" # \returns QualityID (string) if found, empty string otherwise @@ -512,7 +521,7 @@ class MachineManager(QObject): @pyqtProperty(str, notify = activeQualityChanged) def activeQualityContainerId(self): # We're using the active stack instead of the global stack in case the list of qualities differs per extruder - if self._active_container_stack: + if self._global_container_stack: quality = self._active_container_stack.findContainer(type = "quality") if quality: return quality.getId() diff --git a/cura/Settings/QualitySettingsModel.py b/cura/Settings/QualitySettingsModel.py index eb59c7597f..97f830a82b 100644 --- a/cura/Settings/QualitySettingsModel.py +++ b/cura/Settings/QualitySettingsModel.py @@ -120,11 +120,7 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): quality_container = quality_container[0] quality_type = quality_container.getMetaDataEntry("quality_type") - definition = quality_container.getDefinition() - if definition: - definition_id = definition.getId() - else: - definition_id = "empty_quality" + definition_id = quality_container.getDefinition().getId() criteria = {"type": "quality", "quality_type": quality_type, "definition": definition_id} diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index 300a9056d4..3ee8630183 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -137,7 +137,7 @@ Item Action { id: addProfileAction; - enabled: Cura.MachineManager.isActiveStackValid && Cura.MachineManager.hasUserSettings && Cura.MachineManager.activeQualityId != "empty_quality" + enabled: Cura.MachineManager.isActiveStackValid && Cura.MachineManager.hasUserSettings text: catalog.i18nc("@action:inmenu menubar:profile","&Create profile from current settings..."); } diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 238b5f022b..42c055486a 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -62,7 +62,7 @@ UM.ManagementPage Button { text: catalog.i18nc("@label", "Create") - enabled: base.canCreateProfile() && Cura.MachineManager.activeQualityId != "empty_quality" + enabled: base.canCreateProfile() visible: base.canCreateProfile() iconName: "list-add"; @@ -78,7 +78,7 @@ UM.ManagementPage Button { text: catalog.i18nc("@label", "Duplicate") - enabled: ! base.canCreateProfile() && Cura.MachineManager.activeQualityId != "empty_quality" + enabled: ! base.canCreateProfile() visible: ! base.canCreateProfile() iconName: "list-add"; diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index e8f4aa8e47..20ee5f66cd 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -244,7 +244,7 @@ Column } } - property var valueWarning: Cura.MachineManager.activeQualityContainerId == "empty_quality" + property var valueWarning: ! Cura.MachineManager.isActiveQualitySupported enabled: !extrudersList.visible || base.currentExtruderIndex > -1 @@ -292,7 +292,7 @@ Column height: UM.Theme.getSize("setting_control").height tooltip: Cura.MachineManager.activeQualityName style: UM.Theme.styles.sidebar_header_button - property var valueWarning: Cura.MachineManager.activeQualityId == "empty_quality" + property var valueWarning: ! Cura.MachineManager.isActiveQualitySupported menu: ProfileMenu { } UM.SimpleButton From 0a39802cb2280037e35bfee69fd2d63403d3763a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 12 Oct 2016 16:08:54 +0200 Subject: [PATCH 25/50] Fix resolve function of support_type It was not quoted, so it interpreted it as a variable. --- 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 ef16334c09..a26afefb5c 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -2354,7 +2354,7 @@ "everywhere": "Everywhere" }, "default_value": "everywhere", - "resolve": "'everywhere' if 'everywhere' in extruderValues('support_type') else buildplate", + "resolve": "'everywhere' if 'everywhere' in extruderValues('support_type') else 'buildplate'", "enabled": "support_enable", "settable_per_mesh": false, "settable_per_extruder": false From fcb88f06ab3d9cd423f318e04bf7d3c7eeddbe4b Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 12 Oct 2016 16:18:54 +0200 Subject: [PATCH 26/50] Fix typo in incompatibility warning message This is the actual fix that we couldn't do due to the string freeze. Contributes to issue CURA-2626. --- cura/Settings/MachineManager.py | 2 +- plugins/CuraEngineBackend/CuraEngineBackend.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 9b62e3ac0d..0744485ad8 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -73,7 +73,7 @@ class MachineManager(QObject): self._auto_hotends_changed = {} self._material_incompatible_message = Message(catalog.i18nc("@info:status", - "The selected material is imcompatible with the selected machine or configuration.")) + "The selected material is incompatible with the selected machine or configuration.")) globalContainerChanged = pyqtSignal() # Emitted whenever the global stack is changed (ie: when changing between printers, changing a global profile, but not when changing a value) activeMaterialChanged = pyqtSignal() diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index c24ea1cf76..f82e210524 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -230,7 +230,7 @@ class CuraEngineBackend(Backend): if job.getResult() == StartSliceJob.StartJobResult.MaterialIncompatible: if Application.getInstance().getPlatformActivity: self._error_message = Message(catalog.i18nc("@info:status", - "The selected material is imcompatible with the selected machine or configuration.")) + "The selected material is incompatible with the selected machine or configuration.")) self._error_message.show() self.backendStateChange.emit(BackendState.Error) else: From 4a31f9c5b654e294a6736f9a725d880a929ac46c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 12 Oct 2016 17:49:20 +0200 Subject: [PATCH 27/50] Removed wrong check for material for quality_changes CURA-2635 --- cura/Settings/QualitySettingsModel.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/cura/Settings/QualitySettingsModel.py b/cura/Settings/QualitySettingsModel.py index eb59c7597f..47c1bbbc73 100644 --- a/cura/Settings/QualitySettingsModel.py +++ b/cura/Settings/QualitySettingsModel.py @@ -110,9 +110,6 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): "definition": quality_changes_container.getDefinition().getId() } - if self._material_id and self._material_id != "empty_material": - criteria["material"] = self._material_id - quality_container = self._container_registry.findInstanceContainers(**criteria) if not quality_container: UM.Logger.log("w", "Could not find a quality container matching quality changes %s", quality_changes_container.getId()) From c0654c56a046e99b2082fa4a5a0cf5a120986a75 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 12 Oct 2016 19:04:18 +0200 Subject: [PATCH 28/50] Variants are now taken into account when auto updating material CURA-2600 --- cura/Settings/MachineManager.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index ef2fcd9342..342ef8b450 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -148,7 +148,17 @@ class MachineManager(QObject): if matching_extruder and matching_extruder.findContainer({"type": "material"}).getMetaDataEntry("GUID") != material_id: # Save the material that needs to be changed. Multiple changes will be handled by the callback. - self._auto_materials_changed[str(index)] = containers[0].getId() + if matching_extruder: + variant_container = matching_extruder.findContainer({"type": "variant"}) + if self._global_container_stack.getBottom().getMetaDataEntry("has_variants") and variant_container: + variant_id = self.getQualityVariantId(self._global_container_stack.getBottom(), variant_container) + for container in containers: + if container.getMetaDataEntry("variant") == variant_id: + self._auto_materials_changed[str(index)] = container.getId() + break + else: + # Just use the first result we found. + self._auto_materials_changed[str(index)] = containers[0].getId() self._printer_output_devices[0].materialHotendChangedMessage(self._materialHotendChangedCallback) else: Logger.log("w", "No material definition found for printer definition %s and GUID %s" % (definition_id, material_id)) From f659d01da185380268ff18fd5f0e2bf0dea7307d Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Thu, 13 Oct 2016 10:55:32 +0200 Subject: [PATCH 29/50] Make the labels in the quality menus match those from the selected extruder. CURA-2271 Warn for unsupported material/printcore combinations --- cura/QualityManager.py | 3 ++- cura/Settings/ProfilesModel.py | 11 ++++++++++- cura/Settings/QualityAndUserProfilesModel.py | 12 ++++++++++-- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/cura/QualityManager.py b/cura/QualityManager.py index c356951156..09e9d283ed 100644 --- a/cura/QualityManager.py +++ b/cura/QualityManager.py @@ -131,7 +131,8 @@ class QualityManager: # # \param global_container_stack \type{ContainerStack} the global machine definition # \param extruder_stacks \type{List[ContainerStack]} the list of extruder stacks - # \return \type{List[InstanceContainer]} the list of the matching qualities + # \return \type{List[InstanceContainer]} the list of the matching qualities. The quality profiles + # return come from the first extruder in the given list of extruders. def findAllUsableQualitiesForMachineAndExtruders(self, global_container_stack, extruder_stacks): global_machine_definition = global_container_stack.getBottom() diff --git a/cura/Settings/ProfilesModel.py b/cura/Settings/ProfilesModel.py index 5b82ce9221..8c0cb1a93c 100644 --- a/cura/Settings/ProfilesModel.py +++ b/cura/Settings/ProfilesModel.py @@ -28,5 +28,14 @@ class ProfilesModel(InstanceContainersModel): if global_container_stack is None: return [] + # Get the list of extruders and place the selected extruder at the front of the list. + extruder_manager = ExtruderManager.getInstance() + active_extruder = extruder_manager.getActiveExtruderStack() + extruder_stacks = extruder_manager.getActiveExtruderStacks() + extruder_stacks.remove(active_extruder) + extruder_stacks = [active_extruder] + extruder_stacks + + # Fetch the list of useable qualities across all extruders. + # The actual list of quality profiles come from the first extruder in the extruder list. return QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack, - ExtruderManager.getInstance().getActiveExtruderStacks()) + extruder_stacks) diff --git a/cura/Settings/QualityAndUserProfilesModel.py b/cura/Settings/QualityAndUserProfilesModel.py index dcb6c698cf..3ca5507c5b 100644 --- a/cura/Settings/QualityAndUserProfilesModel.py +++ b/cura/Settings/QualityAndUserProfilesModel.py @@ -25,9 +25,17 @@ class QualityAndUserProfilesModel(ProfilesModel): machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.getBottom()) quality_changes_list = quality_manager.findAllQualityChangesForMachine(machine_definition) - # Fetch the list of qualities + # Get the list of extruders and place the selected extruder at the front of the list. + extruder_manager = ExtruderManager.getInstance() + active_extruder = extruder_manager.getActiveExtruderStack() + extruder_stacks = extruder_manager.getActiveExtruderStacks() + extruder_stacks.remove(active_extruder) + extruder_stacks = [active_extruder] + extruder_stacks + + # Fetch the list of useable qualities across all extruders. + # The actual list of quality profiles come from the first extruder in the extruder list. quality_list = QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack, - ExtruderManager.getInstance().getActiveExtruderStacks()) + extruder_stacks) # Filter the quality_change by the list of available quality_types quality_type_set = set([x.getMetaDataEntry("quality_type") for x in quality_list]) From f7fe59c7074214f5b57e5fdb14fb5dd37bac6918 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Thu, 13 Oct 2016 11:10:40 +0200 Subject: [PATCH 30/50] A small fix for the case when Cura is starting up and there is no printer. CURA-2271 Warn for unsupported material/printcore combinations --- cura/Settings/ProfilesModel.py | 5 +++-- cura/Settings/QualityAndUserProfilesModel.py | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/cura/Settings/ProfilesModel.py b/cura/Settings/ProfilesModel.py index 8c0cb1a93c..0f7c8c1ae7 100644 --- a/cura/Settings/ProfilesModel.py +++ b/cura/Settings/ProfilesModel.py @@ -32,8 +32,9 @@ class ProfilesModel(InstanceContainersModel): extruder_manager = ExtruderManager.getInstance() active_extruder = extruder_manager.getActiveExtruderStack() extruder_stacks = extruder_manager.getActiveExtruderStacks() - extruder_stacks.remove(active_extruder) - extruder_stacks = [active_extruder] + extruder_stacks + if active_extruder in extruder_stacks: + extruder_stacks.remove(active_extruder) + extruder_stacks = [active_extruder] + extruder_stacks # Fetch the list of useable qualities across all extruders. # The actual list of quality profiles come from the first extruder in the extruder list. diff --git a/cura/Settings/QualityAndUserProfilesModel.py b/cura/Settings/QualityAndUserProfilesModel.py index 3ca5507c5b..db093126cc 100644 --- a/cura/Settings/QualityAndUserProfilesModel.py +++ b/cura/Settings/QualityAndUserProfilesModel.py @@ -29,8 +29,9 @@ class QualityAndUserProfilesModel(ProfilesModel): extruder_manager = ExtruderManager.getInstance() active_extruder = extruder_manager.getActiveExtruderStack() extruder_stacks = extruder_manager.getActiveExtruderStacks() - extruder_stacks.remove(active_extruder) - extruder_stacks = [active_extruder] + extruder_stacks + if active_extruder in extruder_stacks: + extruder_stacks.remove(active_extruder) + extruder_stacks = [active_extruder] + extruder_stacks # Fetch the list of useable qualities across all extruders. # The actual list of quality profiles come from the first extruder in the extruder list. From a3ffc9e46f230d1fffcb6599daca689249951dfe Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Thu, 13 Oct 2016 11:10:40 +0200 Subject: [PATCH 31/50] A small fix for the case when Cura is starting up and there is no printer. CURA-2271 Warn for unsupported material/printcore combinations --- cura/Settings/ProfilesModel.py | 5 +++-- cura/Settings/QualityAndUserProfilesModel.py | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/cura/Settings/ProfilesModel.py b/cura/Settings/ProfilesModel.py index 8c0cb1a93c..0f7c8c1ae7 100644 --- a/cura/Settings/ProfilesModel.py +++ b/cura/Settings/ProfilesModel.py @@ -32,8 +32,9 @@ class ProfilesModel(InstanceContainersModel): extruder_manager = ExtruderManager.getInstance() active_extruder = extruder_manager.getActiveExtruderStack() extruder_stacks = extruder_manager.getActiveExtruderStacks() - extruder_stacks.remove(active_extruder) - extruder_stacks = [active_extruder] + extruder_stacks + if active_extruder in extruder_stacks: + extruder_stacks.remove(active_extruder) + extruder_stacks = [active_extruder] + extruder_stacks # Fetch the list of useable qualities across all extruders. # The actual list of quality profiles come from the first extruder in the extruder list. diff --git a/cura/Settings/QualityAndUserProfilesModel.py b/cura/Settings/QualityAndUserProfilesModel.py index 3ca5507c5b..db093126cc 100644 --- a/cura/Settings/QualityAndUserProfilesModel.py +++ b/cura/Settings/QualityAndUserProfilesModel.py @@ -29,8 +29,9 @@ class QualityAndUserProfilesModel(ProfilesModel): extruder_manager = ExtruderManager.getInstance() active_extruder = extruder_manager.getActiveExtruderStack() extruder_stacks = extruder_manager.getActiveExtruderStacks() - extruder_stacks.remove(active_extruder) - extruder_stacks = [active_extruder] + extruder_stacks + if active_extruder in extruder_stacks: + extruder_stacks.remove(active_extruder) + extruder_stacks = [active_extruder] + extruder_stacks # Fetch the list of useable qualities across all extruders. # The actual list of quality profiles come from the first extruder in the extruder list. From c9ee7afcb8cc2f0fbc195e0eea90b489529b6804 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 13 Oct 2016 11:31:07 +0200 Subject: [PATCH 32/50] Remove superfluous if statement CURA-2600 --- cura/Settings/MachineManager.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 342ef8b450..1e7fc19c3e 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -148,8 +148,7 @@ class MachineManager(QObject): if matching_extruder and matching_extruder.findContainer({"type": "material"}).getMetaDataEntry("GUID") != material_id: # Save the material that needs to be changed. Multiple changes will be handled by the callback. - if matching_extruder: - variant_container = matching_extruder.findContainer({"type": "variant"}) + variant_container = matching_extruder.findContainer({"type": "variant"}) if self._global_container_stack.getBottom().getMetaDataEntry("has_variants") and variant_container: variant_id = self.getQualityVariantId(self._global_container_stack.getBottom(), variant_container) for container in containers: From ce6e3982fe7187a9fe68dfeca5b9bc501f78b940 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 13 Oct 2016 13:15:16 +0200 Subject: [PATCH 33/50] Make resolve function of bed temperature use max We want the bed to have the highest temperature of the two. This causes some melting for softer materials, but it is required for harder materials to stick to the build plate. --- 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 a26afefb5c..603349726e 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1149,7 +1149,7 @@ "description": "The temperature used for the heated build plate. Set at 0 to pre-heat the printer manually.", "unit": "°C", "type": "float", - "resolve": "sum(extruderValues('material_bed_temperature')) / len(extruderValues('material_bed_temperature'))", + "resolve": "max(extruderValues('material_bed_temperature'))", "default_value": 60, "minimum_value": "-273.15", "minimum_value_warning": "0", From fe60b2fab8845be3d904ceda160b7abcdb1f475d Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 13 Oct 2016 13:18:51 +0200 Subject: [PATCH 34/50] Add missing elide for "Print Setup" label And fix some code style --- resources/qml/Sidebar.qml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/resources/qml/Sidebar.qml b/resources/qml/Sidebar.qml index 036f1283cc..22815c8b66 100644 --- a/resources/qml/Sidebar.qml +++ b/resources/qml/Sidebar.qml @@ -186,20 +186,21 @@ Rectangle Label { id: settingsModeLabel - text: catalog.i18nc("@label:listbox","Print Setup"); + text: catalog.i18nc("@label:listbox", "Print Setup"); anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width; anchors.top: headerSeparator.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height - width: parent.width/100*45 + width: parent.width * 0.45 - 2 * UM.Theme.getSize("default_margin").width font: UM.Theme.getFont("large") color: UM.Theme.getColor("text") visible: !monitoringPrint + elide: Text.ElideRight } Rectangle { id: settingsModeSelection - width: parent.width/100*55 + width: parent.width * 0.55 height: UM.Theme.getSize("sidebar_header_mode_toggle").height anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("default_margin").width @@ -262,7 +263,7 @@ Rectangle anchors.leftMargin: UM.Theme.getSize("default_margin").width; anchors.top: headerSeparator.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height - width: parent.width/100*45 + width: parent.width * 0.45 font: UM.Theme.getFont("large") color: UM.Theme.getColor("text") visible: monitoringPrint From 79a62ec45f4a1ee1852b8f65dd92bed1597c677f Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Thu, 13 Oct 2016 13:48:15 +0200 Subject: [PATCH 35/50] Only reset the setting for the currently selected extruder. CURA-2640 Restore to default not per extruder --- cura/Settings/MachineManager.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 1e7fc19c3e..bf51699300 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -387,7 +387,8 @@ class MachineManager(QObject): top_container.removeInstance(key, postpone_emit=True) send_emits_containers.append(top_container) - for stack in ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()): + stack = ExtruderManager.getInstance().getActiveExtruderStack() + if stack: container = stack.getTop() container.removeInstance(key, postpone_emit=True) send_emits_containers.append(container) From 8b487130d25a16def725e822d70523aef4296494 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Thu, 13 Oct 2016 14:33:29 +0200 Subject: [PATCH 36/50] Take 'linked' settings into account when reverting. CURA-2640 Restore to default not per extruder --- cura/Settings/MachineManager.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index bf51699300..0487f75de9 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -387,8 +387,16 @@ class MachineManager(QObject): top_container.removeInstance(key, postpone_emit=True) send_emits_containers.append(top_container) - stack = ExtruderManager.getInstance().getActiveExtruderStack() - if stack: + linked = not self._global_container_stack.getProperty(key, "settable_per_extruder") or \ + self._global_container_stack.getProperty(key, "limit_to_extruder") != "-1" + + if not linked: + stack = ExtruderManager.getInstance().getActiveExtruderStack() + stacks = [stack] + else: + stacks = ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()) + + for stack in stacks: container = stack.getTop() container.removeInstance(key, postpone_emit=True) send_emits_containers.append(container) From 1bc2f1e18977b124ae30ebf2ff91b1605cd8599d Mon Sep 17 00:00:00 2001 From: nickthetait Date: Thu, 13 Oct 2016 08:11:15 -0600 Subject: [PATCH 37/50] More formatting updates --- resources/definitions/fdmprinter.def.json | 41 +++++++++++++++-------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 2cbf19dadc..898c099a5d 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -392,7 +392,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "machine_max_feedrate_x": { + "machine_max_feedrate_x": + { "label": "Maximum Speed X", "description": "The maximum speed for the motor of the X-direction.", "unit": "mm/s", @@ -402,7 +403,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_feedrate_y": { + "machine_max_feedrate_y": + { "label": "Maximum Speed Y", "description": "The maximum speed for the motor of the Y-direction.", "unit": "mm/s", @@ -412,7 +414,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_feedrate_z": { + "machine_max_feedrate_z": + { "label": "Maximum Speed Z", "description": "The maximum speed for the motor of the Z-direction.", "unit": "mm/s", @@ -422,7 +425,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_feedrate_e": { + "machine_max_feedrate_e": + { "label": "Maximum Feedrate", "description": "The maximum speed of the filament.", "unit": "mm/s", @@ -432,7 +436,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_acceleration_x": { + "machine_max_acceleration_x": + { "label": "Maximum Acceleration X", "description": "Maximum acceleration for the motor of the X-direction", "unit": "mm/s²", @@ -442,7 +447,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_acceleration_y": { + "machine_max_acceleration_y": + { "label": "Maximum Acceleration Y", "description": "Maximum acceleration for the motor of the Y-direction.", "unit": "mm/s²", @@ -452,7 +458,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_acceleration_z": { + "machine_max_acceleration_z": + { "label": "Maximum Acceleration Z", "description": "Maximum acceleration for the motor of the Z-direction.", "unit": "mm/s²", @@ -462,7 +469,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_acceleration_e": { + "machine_max_acceleration_e": + { "label": "Maximum Filament Acceleration", "description": "Maximum acceleration for the motor of the filament.", "unit": "mm/s²", @@ -472,7 +480,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_acceleration": { + "machine_acceleration": + { "label": "Default Acceleration", "description": "The default acceleration of print head movement.", "unit": "mm/s²", @@ -482,7 +491,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_jerk_xy": { + "machine_max_jerk_xy": + { "label": "Default X-Y Jerk", "description": "Default jerk for movement in the horizontal plane.", "unit": "mm/s", @@ -492,7 +502,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_jerk_z": { + "machine_max_jerk_z": + { "label": "Default Z Jerk", "description": "Default jerk for the motor of the Z-direction.", "unit": "mm/s", @@ -502,7 +513,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_jerk_e": { + "machine_max_jerk_e": + { "label": "Default Filament Jerk", "description": "Default jerk for the motor of the filament.", "unit": "mm/s", @@ -512,7 +524,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_minimum_feedrate": { + "machine_minimum_feedrate": + { "label": "Minimum Feedrate", "description": "The minimal movement speed of the print head.", "unit": "mm/s", @@ -839,7 +852,7 @@ "maximum_value_warning": "machine_nozzle_size", "settable_per_mesh": true }, - "outer_inset_first": + "outer_inset_first": { "label": "Outer Before Inner Walls", "description": "Prints walls in order of outside to inside when enabled. This can help improve dimensional accuracy in X and Y when using a high viscosity plastic like ABS; however it can decrease outer surface print quality, especially on overhangs.", From a291131acad19aca4e0204659c0fac3b4ed1b576 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 13 Oct 2016 21:18:17 +0200 Subject: [PATCH 38/50] Fix qml warning when no printer is connected --- resources/qml/MonitorButton.qml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resources/qml/MonitorButton.qml b/resources/qml/MonitorButton.qml index 607d0a24ca..4a68e532d1 100644 --- a/resources/qml/MonitorButton.qml +++ b/resources/qml/MonitorButton.qml @@ -161,6 +161,10 @@ Rectangle visible: showProgress; indeterminate: { + if(!printerConnected) + { + return false; + } switch(Cura.MachineManager.printerOutputDevices[0].jobState) { case "pausing": From 4769b22138a739cbb113976defb196747891931e Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 14 Oct 2016 11:46:39 +0200 Subject: [PATCH 39/50] Sort profiles on extruder position before exporting In the importer the extruders are sorted on extruder position. In the exporter they need to be in the same order. Contributes to issue CURA-2655. --- plugins/GCodeWriter/GCodeWriter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/GCodeWriter/GCodeWriter.py b/plugins/GCodeWriter/GCodeWriter.py index 695e90dbf8..ee35a05215 100644 --- a/plugins/GCodeWriter/GCodeWriter.py +++ b/plugins/GCodeWriter/GCodeWriter.py @@ -106,7 +106,7 @@ class GCodeWriter(MeshWriter): serialized = flat_global_container.serialize() data = {"global_quality": serialized} - for extruder in ExtruderManager.getInstance().getMachineExtruders(stack.getId()): + for extruder in sorted(ExtruderManager.getInstance().getMachineExtruders(stack.getId()), key = lambda k: k.getMetaDataEntry("position")): extruder_quality = extruder.findContainer({"type": "quality_changes"}) if not extruder_quality: Logger.log("w", "No extruder quality profile found, not writing quality for extruder %s to file!", extruder.getId()) From ff24def63c9dc997b79ff90fdf414e0fb1e58326 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Sat, 15 Oct 2016 17:05:55 +0200 Subject: [PATCH 40/50] Use globalProfileId to check if we need to show changed settings CURA-2690 --- cura/Settings/MachineManager.py | 11 +++++++++++ resources/qml/Preferences/ProfileTab.qml | 6 +++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 0487f75de9..16d748f8d2 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -514,6 +514,17 @@ class MachineManager(QObject): return quality.getId() return "" + @pyqtProperty(str, notify=activeQualityChanged) + def globalQualityId(self): + if self._global_container_stack: + quality = self._global_container_stack.findContainer({"type": "quality_changes"}) + if quality and quality != self._empty_quality_changes_container: + return quality.getId() + quality = self._global_container_stack.findContainer({"type": "quality"}) + if quality: + return quality.getId() + return "" + @pyqtProperty(str, notify = activeQualityChanged) def activeQualityType(self): if self._active_container_stack: diff --git a/resources/qml/Preferences/ProfileTab.qml b/resources/qml/Preferences/ProfileTab.qml index 3fd4ca6a5a..2c3bb0a2eb 100644 --- a/resources/qml/Preferences/ProfileTab.qml +++ b/resources/qml/Preferences/ProfileTab.qml @@ -38,8 +38,8 @@ Tab anchors.leftMargin: UM.Theme.getSize("default_margin").width anchors.right: parent.right text: styleData.value - font.strikeout: styleData.column == 1 && quality == Cura.MachineManager.activeQualityId && setting.user_value != "" - font.italic: setting.profile_value_source == "quality_changes" || (quality == Cura.MachineManager.activeQualityId && setting.user_value != "") + font.strikeout: styleData.column == 1 && quality == Cura.MachineManager.globalQualityId && setting.user_value != "" + font.italic: setting.profile_value_source == "quality_changes" || (quality == Cura.MachineManager.globalQualityId && setting.user_value != "") opacity: font.strikeout ? 0.5 : 1 color: styleData.textColor elide: Text.ElideRight @@ -65,7 +65,7 @@ Tab { role: "user_value" title: catalog.i18nc("@title:column", "Current"); - visible: quality == Cura.MachineManager.activeQualityId + visible: quality == Cura.MachineManager.globalQualityId width: parent.width * 0.18 delegate: itemDelegate } From d12219cab8d407e1c0f81782409aea50bf3d4085 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Sat, 15 Oct 2016 17:10:26 +0200 Subject: [PATCH 41/50] Right profile is now checked again in dropdown CURA-2690 --- resources/qml/Menus/ProfileMenu.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index 1cb97153dd..0b2c7a5ae2 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -42,7 +42,7 @@ Menu { text: model.name checkable: true - checked: Cura.MachineManager.activeQualityId == model.id + checked: Cura.MachineManager.globalQualityId == model.id exclusiveGroup: group onTriggered: Cura.MachineManager.setActiveQuality(model.id) } From a3df53c1e186d678f81fc237800d688fa62d3ad2 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Sat, 15 Oct 2016 18:36:05 +0200 Subject: [PATCH 42/50] Quality_changes are now taken into account for UM3Extended CURA-2690 --- cura/Settings/QualitySettingsModel.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cura/Settings/QualitySettingsModel.py b/cura/Settings/QualitySettingsModel.py index 6c59e3bde3..07191cd49d 100644 --- a/cura/Settings/QualitySettingsModel.py +++ b/cura/Settings/QualitySettingsModel.py @@ -117,7 +117,7 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): quality_container = quality_container[0] quality_type = quality_container.getMetaDataEntry("quality_type") - definition_id = quality_container.getDefinition().getId() + definition_id = UM.Application.getInstance().getMachineManager().getQualityDefinitionId(quality_container.getDefinition()) criteria = {"type": "quality", "quality_type": quality_type, "definition": definition_id} @@ -150,8 +150,10 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): if quality_changes_container: criteria = {"type": "quality_changes", "quality_type": quality_type, "definition": definition_id, "name": quality_changes_container.getName()} if self._extruder_definition_id != "": - criteria["extruder"] = self._extruder_definition_id - criteria["name"] = quality_changes_container.getName() + extruder_definitions = self._container_registry.findDefinitionContainers(id = self._extruder_definition_id) + if extruder_definitions: + criteria["extruder"] = UM.Application.getInstance().getMachineManager().getQualityDefinitionId(extruder_definitions[0]) + criteria["name"] = quality_changes_container.getName() else: criteria["extruder"] = None From 3afd813e5ec53a21e0f1b7934859796d9382ac94 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Sat, 15 Oct 2016 19:23:07 +0200 Subject: [PATCH 43/50] Profiles page is now correctly updated when single extrusion machine is used --- resources/qml/Preferences/ProfilesPage.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 42c055486a..1bc705fe62 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -208,7 +208,7 @@ UM.ManagementPage anchors.right: parent.right anchors.bottom: parent.bottom - currentIndex: ExtruderManager.activeExtruderIndex + 1; + currentIndex: ExtruderManager.extruderCount > 0 ? ExtruderManager.activeExtruderIndex + 1 : 0 ProfileTab { From 95f2b84fb5e306fabaadf17723c651b30aaa4e97 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Sun, 16 Oct 2016 14:20:04 +0200 Subject: [PATCH 44/50] Fixed importing profiles for machines with inheritance --- cura/Settings/CuraContainerRegistry.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index fd3f529351..86fc5335be 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -142,6 +142,7 @@ class CuraContainerRegistry(ContainerRegistry): # \return \type{Dict} dict with a 'status' key containing the string 'ok' or 'error', and a 'message' key # containing a message for the user def importProfile(self, file_name): + Logger.log("d", "Attempting to import profile %s", file_name) if not file_name: return { "status": "error", "message": catalog.i18nc("@info:status", "Failed to import profile from {0}: {1}", file_name, "Invalid path")} @@ -181,7 +182,7 @@ class CuraContainerRegistry(ContainerRegistry): for profile in profile_or_list: if profile_index >= 0: if len(machine_extruders) > profile_index: - extruder_id = machine_extruders[profile_index].getBottom().getId() + extruder_id = Application.getInstance().getMachineManager().getQualityDefinitionId(machine_extruders[profile_index].getBottom()) # Ensure the extruder profiles get non-conflicting names # NB: these are not user-facing if "extruder" in profile.getMetaData(): From cda8fd5827e5f7b78b793198532be58d712d389f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Sun, 16 Oct 2016 16:14:05 +0200 Subject: [PATCH 45/50] Revert buttons now work for single extrusion machines again --- cura/Settings/MachineManager.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 16d748f8d2..08d1bff0e9 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -397,9 +397,10 @@ class MachineManager(QObject): stacks = ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()) for stack in stacks: - container = stack.getTop() - container.removeInstance(key, postpone_emit=True) - send_emits_containers.append(container) + if stack is not None: + container = stack.getTop() + container.removeInstance(key, postpone_emit=True) + send_emits_containers.append(container) for container in send_emits_containers: container.sendPostponedEmits() From 1cd50526664a9c673394b34124a138355932e079 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Mon, 17 Oct 2016 13:57:24 +0200 Subject: [PATCH 46/50] Fixed translation of 4 words in profiles page. CURA-570 --- resources/qml/Preferences/ProfilesPage.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 1bc705fe62..f85d967cfe 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -235,7 +235,7 @@ UM.ManagementPage Item { - UM.I18nCatalog { id: catalog; name: "uranium"; } + UM.I18nCatalog { id: catalog; name: "cura"; } UM.ConfirmRemoveDialog { From 98a2ebc157a96ef2f60453a4f6bd40065a31382f Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 17 Oct 2016 14:10:02 +0200 Subject: [PATCH 47/50] Fix translation of machines page and some other references to Uranium CURA-570 --- resources/qml/Preferences/GeneralPage.qml | 4 ++-- resources/qml/Preferences/MachinesPage.qml | 4 ++-- resources/qml/Preferences/ProfilesPage.qml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/resources/qml/Preferences/GeneralPage.qml b/resources/qml/Preferences/GeneralPage.qml index f727af5a10..adbad802ef 100644 --- a/resources/qml/Preferences/GeneralPage.qml +++ b/resources/qml/Preferences/GeneralPage.qml @@ -1,5 +1,5 @@ -// Copyright (c) 2015 Ultimaker B.V. -// Uranium is released under the terms of the AGPLv3 or higher. +// Copyright (c) 2016 Ultimaker B.V. +// Cura is released under the terms of the AGPLv3 or higher. import QtQuick 2.1 import QtQuick.Controls 1.1 diff --git a/resources/qml/Preferences/MachinesPage.qml b/resources/qml/Preferences/MachinesPage.qml index f2937c04e6..78553bb37f 100644 --- a/resources/qml/Preferences/MachinesPage.qml +++ b/resources/qml/Preferences/MachinesPage.qml @@ -1,5 +1,5 @@ // Copyright (c) 2016 Ultimaker B.V. -// Uranium is released under the terms of the AGPLv3 or higher. +// Cura is released under the terms of the AGPLv3 or higher. import QtQuick 2.1 import QtQuick.Controls 1.1 @@ -229,7 +229,7 @@ UM.ManagementPage } } - UM.I18nCatalog { id: catalog; name: "uranium"; } + UM.I18nCatalog { id: catalog; name: "cura"; } UM.ConfirmRemoveDialog { diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index f85d967cfe..621ecb3184 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -1,5 +1,5 @@ -// Copyright (c) 2015 Ultimaker B.V. -// Uranium is released under the terms of the AGPLv3 or higher. +// Copyright (c) 2016 Ultimaker B.V. +// Cura is released under the terms of the AGPLv3 or higher. import QtQuick 2.1 import QtQuick.Controls 1.1 From e2d32ef963dbd73af78d59b26aa0d62eb27ff95d Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 17 Oct 2016 14:17:28 +0200 Subject: [PATCH 48/50] Change references from Uranium to Cura --- resources/qml/Preferences/ReadOnlySpinBox.qml | 2 +- resources/qml/Preferences/ReadOnlyTextArea.qml | 2 +- resources/qml/Preferences/ReadOnlyTextField.qml | 2 +- resources/qml/Preferences/SettingVisibilityPage.qml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/qml/Preferences/ReadOnlySpinBox.qml b/resources/qml/Preferences/ReadOnlySpinBox.qml index 8692f55708..90314ac323 100644 --- a/resources/qml/Preferences/ReadOnlySpinBox.qml +++ b/resources/qml/Preferences/ReadOnlySpinBox.qml @@ -1,5 +1,5 @@ // Copyright (c) 2016 Ultimaker B.V. -// Uranium is released under the terms of the AGPLv3 or higher. +// Cura is released under the terms of the AGPLv3 or higher. import QtQuick 2.1 import QtQuick.Controls 1.1 diff --git a/resources/qml/Preferences/ReadOnlyTextArea.qml b/resources/qml/Preferences/ReadOnlyTextArea.qml index 080aec5f53..1c457eb5d2 100644 --- a/resources/qml/Preferences/ReadOnlyTextArea.qml +++ b/resources/qml/Preferences/ReadOnlyTextArea.qml @@ -1,5 +1,5 @@ // Copyright (c) 2016 Ultimaker B.V. -// Uranium is released under the terms of the AGPLv3 or higher. +// Cura is released under the terms of the AGPLv3 or higher. import QtQuick 2.1 import QtQuick.Controls 1.1 diff --git a/resources/qml/Preferences/ReadOnlyTextField.qml b/resources/qml/Preferences/ReadOnlyTextField.qml index 2ff0357020..a34c39cde3 100644 --- a/resources/qml/Preferences/ReadOnlyTextField.qml +++ b/resources/qml/Preferences/ReadOnlyTextField.qml @@ -1,5 +1,5 @@ // Copyright (c) 2016 Ultimaker B.V. -// Uranium is released under the terms of the AGPLv3 or higher. +// Cura is released under the terms of the AGPLv3 or higher. // Different than the name suggests, it is not always read-only. import QtQuick 2.1 diff --git a/resources/qml/Preferences/SettingVisibilityPage.qml b/resources/qml/Preferences/SettingVisibilityPage.qml index e68df94122..cada8adfda 100644 --- a/resources/qml/Preferences/SettingVisibilityPage.qml +++ b/resources/qml/Preferences/SettingVisibilityPage.qml @@ -1,5 +1,5 @@ // Copyright (c) 2016 Ultimaker B.V. -// Uranium is released under the terms of the AGPLv3 or higher. +// Cura is released under the terms of the AGPLv3 or higher. import QtQuick 2.1 import QtQuick.Controls 1.1 From b3e3053323cbc30faa0dfbf02d55c30e8d04b74a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 17 Oct 2016 13:22:41 +0200 Subject: [PATCH 49/50] Move automatic file name generating to separate function This will make it easier to have multiple nodes here in the future. I'll have to modify this function for that, but I'll do that in a separate commit. Contributes to issue CURA-2617. --- .../RemovableDriveOutputDevice.py | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py index 8b6dce8292..2cd33dafdc 100644 --- a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py +++ b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py @@ -50,15 +50,7 @@ class RemovableDriveOutputDevice(OutputDevice): extension = file_formats[0]["extension"] if file_name is None: - for n in BreadthFirstIterator(node): - if n.getMeshData(): - file_name = n.getName() - if file_name: - break - - if not file_name: - Logger.log("e", "Could not determine a proper file name when trying to write to %s, aborting", self.getName()) - raise OutputDeviceError.WriteRequestFailedError() + file_name = self._automaticFileName(node) if extension: # Not empty string. extension = "." + extension @@ -88,6 +80,21 @@ class RemovableDriveOutputDevice(OutputDevice): Logger.log("e", "Operating system would not let us write to %s: %s", file_name, str(e)) raise OutputDeviceError.WriteRequestFailedError(catalog.i18nc("@info:status", "Could not save to {0}: {1}").format(file_name, str(e))) from e + ## Generate a file name automatically for the specified nodes to be saved + # in. + # + # The name generated will be the name of one of the nodes. Which node that + # is can not be guaranteed. + # + # \param root A node for which to generate a file name. + def _automaticFileName(self, root): + for child in BreadthFirstIterator(root): + if child.getMeshData(): + name = child.getName() + if name: + return name + raise OutputDeviceError.WriteRequestFailedError("Could not find a file name when trying to write to {device}.".format(device = self.getName())) + def _onProgress(self, job, progress): if hasattr(job, "_message"): job._message.setProgress(progress) From 96e516c676e78ab7671a48b97bbf1a6a3a81f63d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 17 Oct 2016 15:50:35 +0200 Subject: [PATCH 50/50] Allow for saving multiple scene nodes at the same time The selection saving saves the entire current selection and their child nodes. Contributes to issue CURA-2617. --- cura/PrinterOutputDevice.py | 2 +- plugins/GCodeWriter/GCodeWriter.py | 12 ++++++- .../RemovableDriveOutputDevice.py | 33 +++++++++++++------ plugins/USBPrinting/USBPrinterOutputDevice.py | 11 +++++-- 4 files changed, 44 insertions(+), 14 deletions(-) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 12335e940b..bbf35da6f8 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -49,7 +49,7 @@ class PrinterOutputDevice(QObject, OutputDevice): self._printer_state = "" self._printer_type = "unknown" - def requestWrite(self, node, file_name = None, filter_by_machine = False): + def requestWrite(self, nodes, file_name = None, filter_by_machine = False): raise NotImplementedError("requestWrite needs to be implemented") ## Signals diff --git a/plugins/GCodeWriter/GCodeWriter.py b/plugins/GCodeWriter/GCodeWriter.py index ee35a05215..3784d9d13e 100644 --- a/plugins/GCodeWriter/GCodeWriter.py +++ b/plugins/GCodeWriter/GCodeWriter.py @@ -46,7 +46,17 @@ class GCodeWriter(MeshWriter): def __init__(self): super().__init__() - def write(self, stream, node, mode = MeshWriter.OutputMode.TextMode): + ## Writes the g-code for the entire scene to a stream. + # + # Note that even though the function accepts a collection of nodes, the + # entire scene is always written to the file since it is not possible to + # separate the g-code for just specific nodes. + # + # \param stream The stream to write the g-code to. + # \param nodes This is ignored. + # \param mode Additional information on how to format the g-code in the + # file. This must always be text mode. + def write(self, stream, nodes, mode = MeshWriter.OutputMode.TextMode): if mode != MeshWriter.OutputMode.TextMode: Logger.log("e", "GCode Writer does not support non-text mode.") return False diff --git a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py index 2cd33dafdc..8de1720107 100644 --- a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py +++ b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py @@ -1,3 +1,6 @@ +# Copyright (c) 2016 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. + import os.path from UM.Application import Application @@ -25,7 +28,16 @@ class RemovableDriveOutputDevice(OutputDevice): self._writing = False self._stream = None - def requestWrite(self, node, file_name = None, filter_by_machine = False): + ## Request the specified nodes to be written to the removable drive. + # + # \param nodes A collection of scene nodes that should be written to the + # removable drive. + # \param file_name \type{string} A suggestion for the file name to write + # to. If none is provided, a file name will be made from the names of the + # meshes. + # \param limit_mimetypes Should we limit the available MIME types to the + # MIME types available to the currently active machine? + def requestWrite(self, nodes, file_name = None, filter_by_machine = False): filter_by_machine = True # This plugin is indended to be used by machine (regardless of what it was told to do) if self._writing: raise OutputDeviceError.DeviceBusyError() @@ -50,7 +62,7 @@ class RemovableDriveOutputDevice(OutputDevice): extension = file_formats[0]["extension"] if file_name is None: - file_name = self._automaticFileName(node) + file_name = self._automaticFileName(nodes) if extension: # Not empty string. extension = "." + extension @@ -60,7 +72,7 @@ class RemovableDriveOutputDevice(OutputDevice): Logger.log("d", "Writing to %s", file_name) # Using buffering greatly reduces the write time for many lines of gcode self._stream = open(file_name, "wt", buffering = 1) - job = WriteMeshJob(writer, self._stream, node, MeshWriter.OutputMode.TextMode) + job = WriteMeshJob(writer, self._stream, nodes, MeshWriter.OutputMode.TextMode) job.setFileName(file_name) job.progress.connect(self._onProgress) job.finished.connect(self._onFinished) @@ -86,13 +98,14 @@ class RemovableDriveOutputDevice(OutputDevice): # The name generated will be the name of one of the nodes. Which node that # is can not be guaranteed. # - # \param root A node for which to generate a file name. - def _automaticFileName(self, root): - for child in BreadthFirstIterator(root): - if child.getMeshData(): - name = child.getName() - if name: - return name + # \param nodes A collection of nodes for which to generate a file name. + def _automaticFileName(self, nodes): + for root in nodes: + for child in BreadthFirstIterator(root): + if child.getMeshData(): + name = child.getName() + if name: + return name raise OutputDeviceError.WriteRequestFailedError("Could not find a file name when trying to write to {device}.".format(device = self.getName())) def _onProgress(self, job, progress): diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index 4838fe9b96..d98f631a2e 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 Ultimaker B.V. +# Copyright (c) 2016 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. from .avr_isp import stk500v2, ispBase, intelHex @@ -426,7 +426,14 @@ class USBPrinterOutputDevice(PrinterOutputDevice): self._error_state = error self.onError.emit() - def requestWrite(self, node, file_name = None, filter_by_machine = False): + ## Request the current scene to be sent to a USB-connected printer. + # + # \param nodes A collection of scene nodes to send. This is ignored. + # \param file_name \type{string} A suggestion for a file name to write. + # This is ignored. + # \param filter_by_machine Whether to filter MIME types by machine. This + # is ignored. + def requestWrite(self, nodes, file_name = None, filter_by_machine = False): Application.getInstance().showPrintMonitor.emit(True) self.startPrint()