From b4b24822bb4660b96a7e0661eecd58092570862e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 2 May 2016 16:44:02 +0200 Subject: [PATCH 001/705] First stub of reworked FDM printer CURA-1278 --- resources/machines/fdmprinter.def.json | 2452 ++++++++++++++++++++++++ 1 file changed, 2452 insertions(+) create mode 100644 resources/machines/fdmprinter.def.json diff --git a/resources/machines/fdmprinter.def.json b/resources/machines/fdmprinter.def.json new file mode 100644 index 0000000000..3d39e8a652 --- /dev/null +++ b/resources/machines/fdmprinter.def.json @@ -0,0 +1,2452 @@ +{ + "id": "fdmprinter", + "version": 2, + "metadata": + { + "category": "Ultimaker", + "manufacturer": "Ultimaker", + "visible": false + }, + "name": "FDM Printer Base Description", + "author": "Ultimaker B.V.", + "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g", + + "settings": + { + "machine_settings": + { + "label": "Machine", + "type": "category", + "description": "Machine specific settings", + "children": + { + "machine_show_variants": { + "description": "Whether to show the different variants of this machine, which are described in separate json files.", + "default_value": false, + "type": "bool", + "label": "Show machine variants" + }, + "machine_start_gcode": { + "description": "Gcode commands to be executed at the very start - separated by \\n.", + "default_value": "G28 ;Home\nG1 Z15.0 F6000 ;Move the platform down 15mm\n;Prime the extruder\nG92 E0\nG1 F200 E3\nG92 E0", + "label": "Start GCode", + "global_only": true, + "type": "str" + }, + "machine_end_gcode": { + "description": "Gcode commands to be executed at the very end - separated by \\n.", + "default_value": "M104 S0\nM140 S0\n;Retract the filament\nG92 E1\nG1 E-1 F300\nG28 X0 Y0\nM84", + "label": "End GCode", + "global_only": true, + "type": "str" + }, + "material_bed_temp_wait": { + "description": "Whether to insert a command to wait until the bed temperature is reached at the start.", + "label": "Wait for bed heatup", + "default_value": true, + "global_only": true, + "type": "bool" + }, + "material_print_temp_prepend": { + "description": "Whether to include nozzle temperature commands at the start of the gcode. When the start_gcode already contains nozzle temperature commands Cura frontend will automatically disable this setting.", + "default_value": true, + "global_only": true, + "type": "bool", + "label": "Wait for material heatup" + }, + "machine_width": { + "description": "The width (X-direction) of the printable area.", + "default_value": 100, + "global_only": true, + "type": "float", + "label": "Machine width" + }, + "machine_depth": { + "description": "The depth (Y-direction) of the printable area.", + "default_value": 100, + "global_only": true, + "type": "float", + "label": "Machine depth" + }, + "machine_height": { + "description": "The height (Z-direction) of the printable area.", + "default_value": 100, + "global_only": true, + "type": "float", + "label": "Machine height" + }, + "machine_heated_bed": { + "description": "Whether the machine has a heated bed present.", + "default_value": false, + "global_only": true, + "label": "Has heated bed", + "type": "bool" + }, + "machine_center_is_zero": { + "description": "Whether the X/Y coordinates of the zero position of the printer is at the center of the printable area.", + "default_value": false, + "global_only": true, + "type": "bool", + "label": "Is center origin" + }, + "machine_extruder_count": { + "description": "Number of extruder trains. An extruder train is the combination of a feeder, bowden tube, and nozzle.", + "default_value": 1, + "global_only": true, + "type": "bool", + "label": "Number extruders" + }, + "machine_nozzle_tip_outer_diameter": { + "description": "The outer diameter of the tip of the nozzle.", + "label": "Outer nozzle diameter", + "default_value": 1, + "global_only": true, + "type": "float" + }, + "machine_nozzle_head_distance": { + "description": "The height difference between the tip of the nozzle and the lowest part of the print head.", + "default_value": 3, + "global_only": true, + "type": "float", + "label": "Nozzle length" + }, + "machine_nozzle_expansion_angle": { + "description": "The angle between the horizontal plane and the conical part right above the tip of the nozzle.", + "default_value": 45, + "global_only": true, + "type": "int", + "label": "Nozzle angle" + }, + "machine_heat_zone_length": { + "description": "The distance from the tip of the nozzle in which heat from the nozzle is transfered to the filament.", + "default_value": 16, + "global_only": true, + "type": "float", + "label": "Heat zone length" + }, + "machine_nozzle_heat_up_speed": { + "description": "The speed (°C/s) by which the nozzle heats up averaged over the window of normal printing temperatures and the standby temperature.", + "default_value": 2.0, + "global_only": true, + "type": "float", + "label": "Heat up speed" + }, + "machine_nozzle_cool_down_speed": { + "description": "The speed (°C/s) by which the nozzle cools down averaged over the window of normal printing temperatures and the standby temperature.", + "default_value": 2.0, + "global_only": true, + "type": "float", + "label": "Cool down speed" + }, + "machine_gcode_flavor": { + "description": "The type of gcode to be generated.", + "default_value": "RepRap", + "global_only": true, + "type": "str", + "label": "Gcode flavour" + }, + "machine_disallowed_areas": { + "description": "A list of polygons with areas the print head is not allowed to enter.", + "type": "polygons", + "default_value": [], + "global_only": true, + "label": "Disallowed areas" + }, + "machine_head_polygon": { + "description": "A 2D silhouette of the print head (fan caps excluded).", + "type": "polygon", + "default_value": [ + [ + -1, + 1 + ], + [ + -1, + -1 + ], + [ + 1, + -1 + ], + [ + 1, + 1 + ] + ], + "global_only": true, + "label": "Machine head polygon" + }, + "machine_head_with_fans_polygon": { + "description": "A 2D silhouette of the print head (fan caps included).", + "type": "polygon", + "default_value": [ + [ + -20, + 10 + ], + [ + 10, + 10 + ], + [ + 10, + -10 + ], + [ + -20, + -10 + ] + ], + "global_only": true, + "label": "Machine head & Fan polygon" + }, + "gantry_height": { + "description": "The height difference between the tip of the nozzle and the gantry system (X and Y axes).", + "default_value": 99999999999, + "global_only": true, + "label": "Gantry height", + "type": "float" + }, + "machine_nozzle_size": { + "label": "Nozzle Diameter", + "description": "The inner diameter of the nozzle. Change this setting when using a non-standard nozzle size.", + "unit": "mm", + "type": "float", + "default_value": 0.4, + "minimum_value": "0.001", + "maximum_value_warning": "10", + "visible": false + } + } + }, + "resolution": + { + "label": "Quality", + "type": "category", + "icon": "category_layer_height", + "description": "All settings that influence the resolution of the print. These settings have a large impact on the quality (and print time)", + "children": + { + "layer_height": + { + "label": "Layer Height", + "description": "The height of each layer in mm. Higher values produce faster prints in lower resolution, lower values produce slower prints in higher resolution.", + "unit": "mm", + "type": "float", + "default_value": 0.1, + "minimum_value": "0.001", + "minimum_value_warning": "0.04", + "maximum_value_warning": "0.8 * machine_nozzle_size", + "global_only": "True" + }, + "layer_height_0": + { + "label": "Initial Layer Height", + "description": "The height of the initial layer in mm. A thicker initial layer makes adhesion to the build plate easier.", + "unit": "mm", + "type": "float", + "default_value": 0.3, + "minimum_value": "0.001", + "minimum_value_warning": "0.04", + "maximum_value_warning": "0.8 * machine_nozzle_size", + "global_only": "True" + }, + "line_width": + { + "label": "Line Width", + "description": "Width of a single line. Generally, the width of each line should correspond to the width of the nozzle. However, slightly reducing this value could produce better prints.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "2 * machine_nozzle_size", + "default_value": 0.4, + "type": "float", + "inherit_function": "machine_nozzle_size", + "children": + { + "wall_line_width": + { + "label": "Wall Line Width", + "description": "Width of a single wall line.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "default_value": 0.4, + "type": "float", + "children": + { + "wall_line_width_0": + { + "label": "Outer Wall Line Width", + "description": "Width of the outermost wall line. By lowering this value, higher levels of detail can be printed.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "default_value": 0.4, + "type": "float" + }, + "wall_line_width_x": + { + "label": "Inner Wall(s) Line Width", + "description": "Width of a single wall line for all wall lines except the outermost one.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "default_value": 0.4, + "type": "float" + } + } + }, + "skin_line_width": + { + "label": "Top/bottom Line Width", + "description": "Width of a single top/bottom line.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "default_value": 0.4, + "type": "float" + }, + "infill_line_width": + { + "label": "Infill Line Width", + "description": "Width of a single infill line.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "default_value": 0.4, + "type": "float" + }, + "skirt_line_width": + { + "label": "Skirt Line Width", + "description": "Width of a single skirt line.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "default_value": 0.4, + "type": "float", + "global_only": true + }, + "support_line_width": + { + "label": "Support Line Width", + "description": "Width of a single support structure line.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "default_value": 0.4, + "type": "float", + "enabled": "support_enable", + "global_only": true + }, + "support_roof_line_width": + { + "label": "Support Roof Line Width", + "description": "Width of a single support roof line.", + "unit": "mm", + "default_value": 0.4, + "minimum_value": "0.0001", + "maximum_value_warning": "machine_nozzle_size * 2", + "type": "float", + "enabled": "support_roof_enable", + "global_only": true + } + } + } + } + }, + "shell": + { + "label": "Shell", + "visible": true, + "icon": "category_shell", + "description": "Shell", + "type": "category", + "children": + { + "wall_thickness": + { + "label": "Wall Thickness", + "description": "The thickness of the outside walls in the horizontal direction. This value divided by the wall line width defines the number of walls.", + "unit": "mm", + "default_value": 0.8, + "minimum_value": "0", + "minimum_value_warning": "line_width", + "maximum_value_warning": "5 * line_width", + "type": "float", + "children": + { + "wall_line_count": + { + "label": "Wall Line Count", + "description": "The number of walls. When calculated by the wall thickness, this value is rounded to a whole number.", + "default_value": 2, + "minimum_value": "0", + "type": "int", + "inherit_function": "1 if magic_spiralize else max(1, round((wall_thickness - wall_line_width_0) / wall_line_width_x) + 1)" + } + } + }, + "top_bottom_thickness": + { + "label": "Top/Bottom Thickness", + "description": "The thickness of the top/bottom layers in the print. This value divided by the layer height defines the number of top/bottom layers.", + "unit": "mm", + "default_value": 0.8, + "minimum_value": "0", + "maximum_value": "5", + "minimum_value_warning": "0.6", + "type": "float", + "children": + { + "top_thickness": + { + "label": "Top Thickness", + "description": "The thickness of the top layers in the print. This value divided by the layer height defines the number of top layers.", + "unit": "mm", + "default_value": 0.8, + "minimum_value": "0", + "maximum_value_warning": "100", + "type": "float", + "children": + { + "top_layers": + { + "label": "Top Layers", + "description": "The number of top layers. When calculated by the top thickness, this value is rounded to a whole number.", + "default_value": 8, + "minimum_value": "0", + "maximum_value_warning": "100", + "type": "int", + "inherit_function": "0 if infill_sparse_density == 100 else math.ceil(round(parent_value / layer_height, 4))" + } + } + }, + "bottom_thickness": + { + "label": "Bottom Thickness", + "description": "The thickness of the bottom layers in the print. This value divided by the layer height defines the number of bottom layers.", + "unit": "mm", + "default_value": 0.6, + "minimum_value": "0", + "type": "float", + "children": + { + "bottom_layers": + { + "label": "Bottom Layers", + "description": "The number of bottom layers. When calculated by the bottom thickness, this value is rounded to a whole number.", + "minimum_value": "0", + "default_value": 6, + "type": "int", + "inherit_function": "999999 if infill_sparse_density == 100 else math.ceil(round(parent_value / layer_height, 4))" + } + } + } + } + }, + "top_bottom_pattern": + { + "label": "Top/Bottom Pattern", + "description": "The pattern of the top/bottom layers.", + "type": "enum", + "options": + { + "lines": "Lines", + "concentric": "Concentric", + "zigzag": "Zig Zag" + }, + "default_value": "lines" + }, + "wall_0_inset": + { + "label": "Outer Wall Inset", + "description": "Inset applied to the path of the outer wall. If the outer wall is smaller than the nozzle, and printed after the inner walls, use this offset to get the hole in the nozzle to overlap with the inner walls instead of the outside of the object.", + "unit": "mm", + "type": "float", + "default_value": 0.0, + "inherit_function": "(machine_nozzle_size - wall_line_width_0) / 2 if wall_line_width_0 < machine_nozzle_size else 0", + "minimum_value_warning": "0", + "maximum_value_warning": "machine_nozzle_size" + }, + "alternate_extra_perimeter": + { + "label": "Alternate Extra Wall", + "description": "Prints an extra wall at every other layer. This way infill gets caught between these extra walls, resulting in stronger prints.", + "type": "bool", + "default_value": false, + "inherit": false + }, + "remove_overlapping_walls_enabled": + { + "label": "Remove Overlapping Wall Parts", + "description": "Remove parts of a wall which share an overlap which would result in overextrusion in some places. These overlaps occur in thin parts and sharp corners in models.", + "type": "bool", + "default_value": false, + "enabled": "False", + "children": + { + "remove_overlapping_walls_0_enabled": + { + "label": "Remove Overlapping Outer Wall Parts", + "description": "Remove parts of an outer wall which share an overlap which would result in overextrusion in some places. These overlaps occur in thin pieces in a model and sharp corners.", + "type": "bool", + "default_value": false, + "inherit": true, + "enabled": "False" + }, + "remove_overlapping_walls_x_enabled": + { + "label": "Remove Overlapping Inner Wall Parts", + "description": "Remove parts of an inner wall that would otherwise overlap and cause over-extrusion. These overlaps occur in thin pieces in a model and sharp corners.", + "type": "bool", + "default_value": true, + "inherit": false + } + } + }, + "fill_perimeter_gaps": + { + "label": "Fill Gaps Between Walls", + "description": "Fills the gaps between walls when overlapping inner wall parts are removed.", + "type": "enum", + "options": + { + "nowhere": "Nowhere", + "everywhere": "Everywhere", + "skin": "Skin" + }, + "default_value": "everywhere", + "enabled": "remove_overlapping_walls_x_enabled" + }, + "travel_compensate_overlapping_walls_enabled": + { + "label": "Compensate Wall Overlaps", + "description": "Compensate the flow for parts of a wall being printed where there is already a wall in place.", + "type": "bool", + "default_value": true + }, + "xy_offset": + { + "label": "Horizontal Expansion", + "description": "Amount of offset applied to all polygons in each layer. Positive values can compensate for too big holes; negative values can compensate for too small holes.", + "unit": "mm", + "type": "float", + "minimum_value_warning": "-10", + "maximum_value_warning": "10", + "default_value": 0 + }, + "z_seam_type": + { + "label": "Z Seam Alignment", + "description": "Starting point of each path in a layer. When paths in consecutive layers start at the same point a vertical seam may show on the print. When aligning these at the back, the seam is easiest to remove. When placed randomly the inaccuracies at the paths' start will be less noticeable. When taking the shortest path the print will be quicker.", + "type": "enum", + "options": + { + "back": "Back", + "shortest": "Shortest", + "random": "Random" + }, + "default_value": "shortest" + }, + "skin_no_small_gaps_heuristic": + { + "label": "Ignore Small Z Gaps", + "description": "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such case, disable the setting.", + "type": "bool", + "default_value": true + } + } + }, + "infill": + { + "label": "Infill", + "icon": "category_infill", + "description": "Infill", + "type": "category", + "children": + { + "infill_sparse_density": + { + "label": "Infill Density", + "description": "Adjusts the density of infill of the print.", + "unit": "%", + "type": "float", + "default_value": 20, + "minimum_value": "0", + "maximum_value_warning": "100", + "children": + { + "infill_line_distance": + { + "label": "Infill Line Distance", + "description": "Distance between the printed infill lines. This setting is calculated by the infill density and the infill line width.", + "unit": "mm", + "type": "float", + "default_value": 2, + "minimum_value": "0", + "inherit_function": "0 if infill_sparse_density == 0 else (infill_line_width * 100) / infill_sparse_density * (2 if infill_pattern == \"grid\" else (3 if infill_pattern == \"triangles\" else 1))" + } + } + }, + "infill_pattern": + { + "label": "Infill Pattern", + "description": "The pattern of the infill material of the print. The line and zig zag infill swap direction on alternate layers, reducing material cost. The grid, triangle and concentric patterns are fully printed every layer.", + "type": "enum", + "options": + { + "grid": "Grid", + "lines": "Lines", + "triangles": "Triangles", + "concentric": "Concentric", + "zigzag": "Zig Zag" + }, + "default_value": "grid", + "inherit_function": "'lines' if infill_sparse_density > 25 else 'grid'" + }, + "infill_overlap": + { + "label": "Infill Overlap Percentage", + "description": "The amount of overlap between the infill and the walls. A slight overlap allows the walls to connect firmly to the infill.", + "unit": "%", + "type": "float", + "default_value": 10, + "inherit_function": "10 if infill_sparse_density < 95 else 0", + "minimum_value_warning": "-50", + "maximum_value_warning": "100", + "children": + { + "infill_overlap_mm": + { + "label": "Infill Overlap", + "description": "The amount of overlap between the infill and the walls. A slight overlap allows the walls to connect firmly to the infill.", + "unit": "mm", + "type": "float", + "default_value": 0.04, + "minimum_value_warning": "-0.5 * machine_nozzle_size", + "maximum_value_warning": "machine_nozzle_size", + "inherit_function": "infill_line_width * parent_value / 100 if infill_sparse_density < 95 else 0" + } + } + }, + "infill_wipe_dist": + { + "label": "Infill Wipe Distance", + "description": "Distance of a travel move inserted after every infill line, to make the infill stick to the walls better. This option is similar to infill overlap, but without extrusion and only on one end of the infill line.", + "unit": "mm", + "type": "float", + "default_value": 0.04, + "inherit_function": "wall_line_width_0 / 4 if wall_line_count == 1 else wall_line_width_x / 4", + "minimum_value_warning": "0", + "maximum_value_warning": "machine_nozzle_size" + }, + "infill_sparse_thickness": + { + "label": "Infill Layer Thickness", + "description": "The thickness per layer of infill material. This value should always be a multiple of the layer height and is otherwise rounded.", + "unit": "mm", + "type": "float", + "default_value": 0.1, + "minimum_value": "0.0001", + "maximum_value_warning": "0.32", + "maximum_value": "layer_height * 8", + "inherit_function": "layer_height" + }, + "infill_before_walls": + { + "label": "Infill Before Walls", + "description": "Print the infill before printing the walls. Printing the walls first may lead to more accurate walls, but overhangs print worse. Printing the infill first leads to sturdier walls, but the infill pattern might sometimes show through the surface.", + "type": "bool", + "default_value": true + } + } + }, + "material": + { + "label": "Material", + "icon": "category_material", + "description": "Material", + "type": "category", + "children": + { + "material_flow_dependent_temperature": { + "label": "Auto Temperature", + "description": "Change the temperature for each layer automatically with the average flow speed of that layer.", + "type": "bool", + "default_value": false, + "visible": false, + "enabled": "False", + "global_only": true + }, + "material_print_temperature": { + "label": "Printing Temperature", + "description": "The temperature used for printing. Set at 0 to pre-heat the printer manually.", + "unit": "°C", + "type": "float", + "default_value": 210, + "minimum_value": "0", + "maximum_value_warning": "260", + "enabled": "not (material_flow_dependent_temperature)" + }, + "material_flow_temp_graph": { + "label": "Flow Temperature Graph", + "description": "Data linking material flow (in mm3 per second) to temperature (degrees Celsius).", + "unit": "", + "type": "str", + "default_value": "[[3.5,200],[7.0,240]]", + "enabled": "False", + "enabled_before_removal": "material_flow_dependent_temperature", + "global_only": true + }, + "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", + "type": "float", + "default_value": 0.5, + "minimum_value": "0", + "maximum_value_warning": "10.0", + "global_only": "True", + "enabled": "False", + "enabled_before_removal": "material_flow_dependent_temperature or machine_extruder_count > 1", + "visible": false + }, + "material_bed_temperature": { + "label": "Bed Temperature", + "description": "The temperature used for the heated bed. Set at 0 to pre-heat the printer manually.", + "unit": "°C", + "type": "float", + "default_value": 60, + "minimum_value": "0", + "maximum_value_warning": "260", + "enabled": "machine_heated_bed", + "global_only": "True" + }, + "material_diameter": { + "label": "Diameter", + "description": "Adjusts the diameter of the filament used. Match this value with the diameter of the used filament.", + "unit": "mm", + "type": "float", + "default_value": 2.85, + "minimum_value": "0.0001", + "minimum_value_warning": "0.4", + "maximum_value_warning": "3.5", + "global_only": "True" + }, + "material_flow": { + "label": "Flow", + "description": "Flow compensation: the amount of material extruded is multiplied by this value.", + "unit": "%", + "default_value": 100, + "type": "float", + "minimum_value": "5", + "minimum_value_warning": "50", + "maximum_value_warning": "150" + }, + "retraction_enable": { + "label": "Enable Retraction", + "description": "Retract the filament when the nozzle is moving over a non-printed area. ", + "type": "bool", + "default_value": true, + "visible": true + }, + "retraction_amount": { + "label": "Retraction Distance", + "description": "The length of material retracted during a retraction move.", + "unit": "mm", + "type": "float", + "default_value": 6.5, + "minimum_value_warning": "-0.0001", + "maximum_value_warning": "10.0", + "visible": false, + "inherit": false, + "enabled": "retraction_enable" + }, + "retraction_speed": { + "label": "Retraction Speed", + "description": "The speed at which the filament is retracted and primed during a retraction move.", + "unit": "mm/s", + "type": "float", + "default_value": 25, + "minimum_value": "0", + "maximum_value": "299792458000", + "maximum_value_warning": "100", + "visible": false, + "inherit": false, + "enabled": "retraction_enable", + "children": { + "retraction_retract_speed": { + "label": "Retraction Retract Speed", + "description": "The speed at which the filament is retracted during a retraction move.", + "unit": "mm/s", + "type": "float", + "default_value": 25, + "minimum_value": "0", + "maximum_value": "299792458000", + "maximum_value_warning": "100", + "visible": false, + "enabled": "retraction_enable" + }, + "retraction_prime_speed": { + "label": "Retraction Prime Speed", + "description": "The speed at which the filament is primed during a retraction move.", + "unit": "mm/s", + "type": "float", + "default_value": 25, + "minimum_value": "0", + "maximum_value": "299792458000", + "maximum_value_warning": "100", + "visible": false, + "enabled": "retraction_enable" + } + } + }, + "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³", + "type": "float", + "default_value": 0, + "minimum_value_warning": "-0.0001", + "maximum_value_warning": "5.0", + "visible": false, + "inherit": false, + "enabled": "retraction_enable" + }, + "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", + "type": "float", + "default_value": 1.5, + "inherit_function": "line_width * 2", + "minimum_value": "0", + "maximum_value_warning": "10", + "visible": false, + "inherit": false, + "enabled": "retraction_enable" + }, + "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": 45, + "minimum_value": "0", + "maximum_value_warning": "100", + "type": "int", + "visible": false, + "inherit": false, + "enabled": "retraction_enable" + }, + "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", + "type": "float", + "default_value": 4.5, + "minimum_value": "0", + "maximum_value_warning": "retraction_amount * 2", + "visible": false, + "inherit_function": "retraction_amount", + "enabled": "retraction_enable" + }, + "retraction_hop": { + "label": "Z Hop when Retracting", + "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.", + "unit": "mm", + "type": "float", + "default_value": 0, + "minimum_value_warning": "-0.0001", + "maximum_value_warning": "10", + "inherit": false, + "enabled": "retraction_enable" + } + } + }, + "speed": + { + "label": "Speed", + "icon": "category_speed", + "description": "Speed", + "type": "category", + "children": + { + "speed_print": + { + "label": "Print Speed", + "description": "The speed at which printing happens.", + "unit": "mm/s", + "type": "float", + "minimum_value": "0.1", + "maximum_value_warning": "150", + "maximum_value": "299792458000", + "default_value": 60, + "children": + { + "speed_infill": + { + "label": "Infill Speed", + "description": "The speed at which infill is printed.", + "unit": "mm/s", + "type": "float", + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "default_value": 60 + }, + "speed_wall": + { + "label": "Wall Speed", + "description": "The speed at which the walls are printed.", + "unit": "mm/s", + "type": "float", + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "default_value": 30, + "visible": false, + "inherit_function": "parent_value / 2", + "children": + { + "speed_wall_0": + { + "label": "Outer Wall Speed", + "description": "The speed at which the outermost walls are printed. Printing the outer wall at a lower speed improves the final skin quality. However, having a large difference between the inner wall speed and the outer wall speed will effect quality in a negative way.", + "unit": "mm/s", + "type": "float", + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "default_value": 30 + }, + "speed_wall_x": + { + "label": "Inner Wall Speed", + "description": "The speed at which all inner walls are printed Printing the inner wall faster than the outer wall will reduce printing time. It works well to set this in between the outer wall speed and the infill speed.", + "unit": "mm/s", + "type": "float", + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "default_value": 60, + "inherit_function": "parent_value * 2" + } + } + }, + "speed_topbottom": + { + "label": "Top/Bottom Speed", + "description": "The speed at which top/bottom layers are printed.", + "unit": "mm/s", + "type": "float", + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "default_value": 30, + "inherit_function": "parent_value / 2" + }, + "speed_support": + { + "label": "Support Speed", + "description": "The speed at which the support structure is printed. Printing support at higher speeds can greatly reduce printing time. The surface quality of the support structure is not important since it is removed after printing.", + "unit": "mm/s", + "type": "float", + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "default_value": 60, + "inherit_function": "speed_print", + "enabled": "support_roof_enable", + "children": + { + "speed_support_infill": + { + "label": "Support Infill Speed", + "description": "The speed at which the infill of support is printed. Printing the infill at lower speeds improves stability.", + "unit": "mm/s", + "type": "float", + "default_value": 60, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "inherit": true, + "enabled": "support_enable", + "global_only": true + }, + "speed_support_roof": + { + "label": "Support Roof Speed", + "description": "The speed at which the roofs of support are printed. Printing the support roof at lower speeds can improve overhang quality.", + "unit": "mm/s", + "type": "float", + "default_value": 40, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "enabled": "support_roof_enable", + "inherit_function": "parent_value / 1.5", + "global_only": true + } + } + } + } + }, + "speed_travel": + { + "label": "Travel Speed", + "description": "The speed at which travel moves are made.", + "unit": "mm/s", + "type": "float", + "default_value": 120, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "300", + "inherit_function": "speed_print if magic_spiralize else 120", + "global_only": true + }, + "speed_layer_0": { + "label": "Initial Layer Speed", + "description": "The print speed for the initial layer. A lower value is advised to improve adhesion to the build plate.", + "unit": "mm/s", + "type": "float", + "default_value": 30, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "300" + }, + "skirt_speed": { + "label": "Skirt 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 at a different speed.", + "unit": "mm/s", + "type": "float", + "default_value": 30, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "300", + "inherit_function": "speed_layer_0", + "global_only": true + }, + "speed_slowdown_layers": + { + "label": "Number of Slower Layers", + "description": "The first few layers are printed slower than the rest of the object, to get better adhesion to the build plate and improve the overall success rate of prints. The speed is gradually increased over these layers.", + "type": "int", + "default_value": 2, + "minimum_value": "0", + "maximum_value": "299792458000", + "maximum_value_warning": "300", + "global_only": true + } + } + }, + "travel": + { + "label": "Travel", + "icon": "category_travel", + "description": "travel", + "type": "category", + "children": + { + "retraction_combing": + { + "label": "Combing Mode", + "description": "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas by combing within the infill only. It is also possible to avoid combing over top/bottom skin areas by combing within the infill only.", + "type": "enum", + "options": + { + "off": "Off", + "all": "All", + "noskin": "No Skin" + }, + "default_value": "all", + "global_only": true + }, + "travel_avoid_other_parts": + { + "label": "Avoid Printed Parts when Traveling", + "description": "The nozzle avoids already printed parts when traveling. This option is only available when combing is enabled.", + "type": "bool", + "default_value": true, + "enabled": "retraction_combing != \"off\"", + "global_only": "True" + }, + "travel_avoid_distance": + { + "label": "Travel Avoid Distance", + "description": "The distance between the nozzle and already printed parts when avoiding during travel moves.", + "unit": "mm", + "type": "float", + "default_value": 1.5, + "inherit_function": "machine_nozzle_tip_outer_diameter / 2 * 1.25", + "minimum_value": "0", + "maximum_value_warning": "machine_nozzle_tip_outer_diameter * 5", + "inherit": false, + "enabled": "retraction_combing != \"off\" and travel_avoid_other_parts", + "global_only": "True" + } + } + }, + "cooling": + { + "label": "Cooling", + "icon": "category_cool", + "description": "Cooling", + "type": "category", + "children": + { + "cool_fan_enabled": + { + "label": "Enable Cooling Fans", + "description": "Enables the cooling fans while printing. The fans improve print quality on layers with short layer times and bridging / overhangs.", + "type": "bool", + "default_value": true, + "global_only": "True" + }, + "cool_fan_speed": + { + "label": "Fan Speed", + "description": "The speed at which the cooling fans spin.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value": "100", + "default_value": 100, + "inherit_function": "100.0 if cool_fan_enabled else 0.0", + "enabled": "cool_fan_enabled", + "global_only": "True", + "children": + { + "cool_fan_speed_min": + { + "label": "Regular Fan Speed", + "description": "The speed at which the fans spin before hitting the threshold. When a layer prints faster than the threshold, the fan speed gradually inclines towards the maximum fan speed.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value": "100", + "inherit_function": "parent_value", + "default_value": 100, + "visible": false, + "enabled": "cool_fan_enabled", + "global_only": "True" + }, + "cool_fan_speed_max": + { + "label": "Maximum Fan Speed", + "description": "The speed at which the fans spin on the minimum layer time. The fan speed gradually increases between the regular fan speed and maximum fan speed when the threshold is hit.", + "unit": "%", + "type": "float", + "minimum_value": "max(0, cool_fan_speed_min)", + "maximum_value": "100", + "default_value": 100, + "enabled": "cool_fan_enabled", + "global_only": "True" + } + } + }, + "cool_min_layer_time_fan_speed_max": + { + "label": "Regular/Maximum Fan Speed Threshold", + "description": "The layer time which sets the threshold between regular fan speed and maximum fan speed. Layers that print slower than this time use regular fan speed. For faster layers the fan speed gradually increases towards the maximum fan speed.", + "unit": "sec", + "type": "float", + "default_value": 10, + "minimum_value": "cool_min_layer_time", + "maximum_value_warning": "600", + "global_only": "True" + }, + "cool_fan_full_at_height": + { + "label": "Regular Fan Speed at Height", + "description": "The height at which the fans spin on regular fan speed. At the layers below the fan speed gradually increases from zero to regular fan speed.", + "unit": "mm", + "type": "float", + "default_value": 0.5, + "inherit_function": "layer_height_0", + "minimum_value": "0", + "maximum_value_warning": "10.0", + "global_only": "True", + "children": + { + "cool_fan_full_layer": + { + "label": "Regular Fan Speed at Layer", + "description": "The layer at which the fans spin on regular fan speed. If regular fan speed at height is set, this value is calculated and rounded to a whole number.", + "type": "int", + "default_value": 1, + "minimum_value": "0", + "maximum_value_warning": "100", + "inherit_function": "int((parent_value - layer_height_0 + 0.001) / layer_height) + 1", + "global_only": "True" + } + } + }, + "cool_min_layer_time": + { + "label": "Minimum Layer Time", + "description": "The minimum time spent in a layer. This forces the printer to slow down, to at least spend the time set here in one layer. This allows the printed material to cool down properly before printing the next layer.", + "unit": "sec", + "type": "float", + "default_value": 5, + "minimum_value": "0", + "maximum_value_warning": "600", + "global_only": "True" + }, + "cool_min_speed": + { + "label": "Minimum Speed", + "description": "The minimum print speed, despite slowing down due to the minimum layer time. When the printer would slow down too much, the pressure in the nozzle would be too low and result in bad print quality.", + "unit": "mm/s", + "type": "float", + "default_value": 10, + "minimum_value": "0", + "maximum_value_warning": "100", + "global_only": "True" + }, + "cool_lift_head": + { + "label": "Lift Head", + "description": "When the minimum speed is hit because of minimum layer time, lift the head away from the print and wait the extra time until the minimum layer time is reached.", + "type": "bool", + "default_value": false, + "global_only": "True" + } + } + }, + "support": + { + "label": "Support", + "type": "category", + "icon": "category_support", + "description": "Support", + "children": + { + "support_enable": + { + "label": "Enable Support", + "description": "Enable support structures. These structures support parts of the model with severe overhangs.", + "type": "bool", + "default_value": false + }, + "support_type": + { + "label": "Support Placement", + "description": "Adjusts the placement of the support structures. The placement can be set to touching build plate or everywhere. When set to everywhere the support structures will also be printed on the model.", + "type": "enum", + "options": + { + "buildplate": "Touching Buildplate", + "everywhere": "Everywhere" + }, + "default_value": "everywhere", + "enabled": "support_enable" + }, + "support_angle": + { + "label": "Support Overhang Angle", + "description": "The minimum angle of overhangs for which support is added. At a value of 0° all overhangs are supported, 90° will not provide any support.", + "unit": "°", + "type": "float", + "minimum_value": "0", + "maximum_value": "90", + "default_value": 50, + "enabled": "support_enable" + }, + "support_pattern": + { + "label": "Support Pattern", + "description": "The pattern of the support structures of the print. The different options available result in sturdy or easy to remove support.", + "type": "enum", + "options": + { + "lines": "Lines", + "grid": "Grid", + "triangles": "Triangles", + "concentric": "Concentric", + "zigzag": "Zig Zag" + }, + "default_value": "zigzag", + "enabled": "support_enable", + "global_only": true + }, + "support_connect_zigzags": + { + "label": "Connect Support ZigZags", + "description": "Connect the ZigZags. This will increase the strength of the zig zag support structure.", + "type": "bool", + "default_value": true, + "enabled": "support_enable and (support_pattern == \"zigzag\")", + "global_only": true + }, + "support_infill_rate": + { + "label": "Support Density", + "description": "Adjusts the density of the support structure. A higher value results in better overhangs, but the supports are harder to remove.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value_warning": "100", + "default_value": 15, + "enabled": "support_enable", + "global_only": true, + "children": { + "support_line_distance": + { + "label": "Support Line Distance", + "description": "Distance between the printed support structure lines. This setting is calculated by the support density.", + "unit": "mm", + "type": "float", + "minimum_value": "0", + "default_value": 2.66, + "enabled": "support_enable", + "inherit_function": "(support_line_width * 100) / parent_value * (2 if support_pattern == \"grid\" else (3 if support_pattern == \"triangles\" else 1))", + "global_only": true + } + } + }, + "support_xy_distance": + { + "label": "Support X/Y Distance", + "description": "Distance of the support structure from the print in the X/Y directions.", + "unit": "mm", + "type": "float", + "minimum_value": "0", + "maximum_value_warning": "10", + "default_value": 0.7, + "enabled": "support_enable" + }, + "support_z_distance": + { + "label": "Support Z Distance", + "description": "Distance from the top/bottom of the support structure to the print. This gap provides clearance to remove the supports after the model is printed. This value is rounded down to a multiple of the layer height.", + "unit": "mm", + "type": "float", + "minimum_value": "0", + "maximum_value_warning": "10", + "default_value": 0.15, + "enabled": "support_enable", + + "children": + { + "support_top_distance": + { + "label": "Support Top Distance", + "description": "Distance from the top of the support to the print.", + "unit": "mm", + "minimum_value": "0", + "maximum_value_warning": "10", + "default_value": 0.15, + "type": "float", + "enabled": "support_enable" + }, + "support_bottom_distance": + { + "label": "Support Bottom Distance", + "description": "Distance from the print to the bottom of the support.", + "unit": "mm", + "minimum_value": "0", + "maximum_value_warning": "10", + "default_value": 0.1, + "inherit_function": "0.1 if support_type == 'everywhere' else 0", + "type": "float", + "enabled": "support_enable and support_type == 'everywhere'" + } + } + }, + "support_bottom_stair_step_height": + { + "label": "Support Stair Step Height", + "description": "The height of the steps of the stair-like bottom of support resting on the model. A low value makes the support harder to remove, but too high values can lead to unstable support structures.", + "unit": "mm", + "type": "float", + "default_value": 0.3, + "minimum_value": "0", + "maximum_value_warning": "1.0", + "enabled": "support_enable" + }, + "support_join_distance": + { + "label": "Support Join Distance", + "description": "The maximum distance between support structures in the X/Y directions. When seperate structures are closer together than this value, the structures merge into one.", + "unit": "mm", + "type": "float", + "default_value": 2.0, + "minimum_value_warning": "0", + "maximum_value_warning": "10", + "enabled": "support_enable" + }, + "support_offset": + { + "label": "Support Horizontal Expansion", + "description": "Amount of offset applied to all support polygons in each layer. Positive values can smooth out the support areas and result in more sturdy support.", + "unit": "mm", + "type": "float", + "default_value": 0.2, + "minimum_value_warning": "-0.5", + "maximum_value_warning": "5.0", + "enabled": "support_enable" + }, + "support_area_smoothing": + { + "label": "Support Area Smoothing", + "description": "Maximum distance in the X/Y directions of a line segment which is to be smoothed out. Ragged lines are introduced by the join distance and support bridge, which cause the machine to resonate. Smoothing the support areas won't cause them to break with the constraints, except it might change the overhang.", + "unit": "mm", + "type": "float", + "default_value": 0.6, + "minimum_value": "0", + "maximum_value_warning": "1.0", + "enabled": "support_enable" + }, + "support_roof_enable": + { + "label": "Enable Support Roof", + "description": "Generate a dense top skin at the top of the support on which the model is printed.", + "type": "bool", + "default_value": false, + "visible": true, + "enabled": "support_enable" + }, + "support_roof_height": + { + "label": "Support Roof Thickness", + "description": "The thickness of the support roofs.", + "unit": "mm", + "type": "float", + "default_value": 1, + "minimum_value": "0", + "maximum_value_warning": "10", + "enabled": "support_roof_enable" + }, + "support_roof_density": + { + "label": "Support Roof Density", + "description": "Adjusts the density of the roof of the support structure. A higher value results in better overhangs, but the supports are harder to remove.", + "unit": "%", + "type": "float", + "default_value": 100, + "minimum_value": "0", + "maximum_value_warning": "100", + "enabled":"support_roof_enable", + "global_only": true, + "children": + { + "support_roof_line_distance": + { + "label": "Support Roof Line Distance", + "description": "Distance between the printed support roof lines. This setting is calculated by the support roof Density, but can be adjusted separately.", + "unit": "mm", + "type": "float", + "default_value": 0.4, + "minimum_value": "0", + "inherit_function": "0 if parent_value == 0 else (support_roof_line_width * 100) / parent_value * (2 if support_roof_pattern == \"grid\" else (3 if support_roof_pattern == \"triangles\" else 1))", + "enabled": "support_roof_enable", + "global_only": true + } + } + }, + "support_roof_pattern": + { + "label": "Support Roof Pattern", + "description": "The pattern with which the top of the support is printed.", + "type": "enum", + "options": + { + "lines": "Lines", + "grid": "Grid", + "triangles": "Triangles", + "concentric": "Concentric", + "zigzag": "Zig Zag" + }, + "default_value": "concentric", + "enabled": "support_roof_enable", + "global_only": true + }, + "support_use_towers": + { + "label": "Use Towers", + "description": "Use specialized towers to support tiny overhang areas. These towers have a larger diameter than the region they support. Near the overhang the towers' diameter decreases, forming a roof.", + "type": "bool", + "default_value": true, + "enabled": "support_enable" + }, + "support_tower_diameter": + { + "label": "Tower Diameter", + "description": "The diameter of a special tower.", + "unit": "mm", + "type": "float", + "default_value": 3.0, + "minimum_value": "0", + "maximum_value_warning": "10", + "enabled": "support_enable and support_use_towers" + }, + "support_minimal_diameter": + { + "label": "Minimum Diameter", + "description": "Minimum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower.", + "unit": "mm", + "type": "float", + "default_value": 3.0, + "minimum_value": "0", + "maximum_value_warning": "10", + "maximum_value": "support_tower_diameter", + "inherit": true, + "enabled": "support_enable and support_use_towers" + }, + "support_tower_roof_angle": + { + "label": "Tower Roof Angle", + "description": "The angle of a rooftop of a tower. A higher value results in pointed tower roofs, a lower value results in flattened tower roofs.", + "unit": "°", + "type": "int", + "minimum_value": "0", + "maximum_value": "90", + "default_value": 65, + "enabled": "support_enable and support_use_towers" + } + } + }, + "platform_adhesion": + { + "label": "Platform Adhesion", + "type": "category", + "icon": "category_adhesion", + "description": "Adhesion", + "children": + { + "adhesion_type": + { + "label": "Platform Adhesion Type", + "description": "Different options that help to improve both priming your extrusion and adhesion to the build plate. Brim adds a single layer flat area around the base of your object to prevent warping. Raft adds a thick grid with a roof below the object. Skirt is a line printed around the object, but not connected to the model.", + "type": "enum", + "options": + { + "skirt": "Skirt", + "brim": "Brim", + "raft": "Raft" + }, + "default_value": "brim", + "global_only": "True" + }, + "skirt_line_count": + { + "label": "Skirt Line Count", + "description": "Multiple skirt lines help to prime your extrusion better for small objects. Setting this to 0 will disable the skirt.", + "type": "int", + "default_value": 1, + "minimum_value": "0", + "maximum_value_warning": "10", + "enabled": "adhesion_type == \"skirt\"", + "global_only": "True" + }, + "skirt_gap": + { + "label": "Skirt Distance", + "description": "The horizontal distance between the skirt and the first layer of the print.\nThis is the minimum distance, multiple skirt lines will extend outwards from this distance.", + "unit": "mm", + "type": "float", + "default_value": 3, + "minimum_value_warning": "0", + "maximum_value_warning": "100", + "enabled": "adhesion_type == \"skirt\"", + "global_only": "True" + }, + "skirt_minimal_length": + { + "label": "Skirt Minimum Length", + "description": "The minimum length of the skirt. If this length is not reached by the skirt line count, more skirt lines will be added until the minimum length is reached. Note: If the line count is set to 0 this is ignored.", + "unit": "mm", + "type": "float", + "default_value": 250, + "minimum_value": "0", + "minimum_value_warning": "25", + "maximum_value_warning": "2500", + "enabled": "adhesion_type == \"skirt\"", + "global_only": "True" + }, + "brim_width": + { + "label": "Brim Width", + "description": "The distance from the model to the outermost brim line. A larger brim enhances adhesion to the build plate, but also reduces the effective print area.", + "type": "float", + "unit": "mm", + "default_value": 8.0, + "minimum_value": "0.0", + "maximum_value_warning": "100.0", + "enabled": "adhesion_type == \"brim\"", + "global_only": "True", + "children": + { + "brim_line_count": + { + "label": "Brim Line Count", + "description": "The number of lines used for a brim. More brim lines enhance adhesion to the build plate, but also reduces the effective print area.", + "type": "int", + "default_value": 20, + "minimum_value": "0", + "maximum_value_warning": "300", + "inherit_function": "math.ceil(parent_value / skirt_line_width)", + "enabled": "adhesion_type == \"brim\"", + "global_only": "True" + } + } + }, + "raft_margin": + { + "label": "Raft Extra Margin", + "description": "If the raft is enabled, this is the extra raft area around the object which is also given a raft. Increasing this margin will create a stronger raft while using more material and leaving less area for your print.", + "unit": "mm", + "type": "float", + "default_value": 5, + "minimum_value_warning": "0", + "maximum_value_warning": "10", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_airgap": + { + "label": "Raft Air Gap", + "description": "The gap between the final raft layer and the first layer of the object. Only the first layer is raised by this amount to lower the bonding between the raft layer and the object. Makes it easier to peel off the raft.", + "unit": "mm", + "type": "float", + "default_value": 0.35, + "minimum_value": "0", + "maximum_value_warning": "1.0", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_surface_layers": + { + "label": "Raft Top Layers", + "description": "The number of top layers on top of the 2nd raft layer. These are fully filled layers that the object sits on. 2 layers result in a smoother top surface than 1.", + "type": "int", + "default_value": 2, + "minimum_value": "0", + "maximum_value_warning": "20", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_surface_thickness": + { + "label": "Raft Top Layer Thickness", + "description": "Layer thickness of the top raft layers.", + "unit": "mm", + "type": "float", + "default_value": 0.1, + "minimum_value": "0", + "maximum_value_warning": "2.0", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_surface_line_width": + { + "label": "Raft Top Line Width", + "description": "Width of the lines in the top surface of the raft. These can be thin lines so that the top of the raft becomes smooth.", + "unit": "mm", + "type": "float", + "default_value": 0.3, + "minimum_value": "0.0001", + "maximum_value_warning": "machine_nozzle_size * 2", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_surface_line_spacing": + { + "label": "Raft Top Spacing", + "description": "The distance between the raft lines for the top raft layers. The spacing should be equal to the line width, so that the surface is solid.", + "unit": "mm", + "type": "float", + "default_value": 0.3, + "minimum_value": "0.0001", + "maximum_value_warning": "5.0", + "enabled": "adhesion_type == \"raft\"", + "inherit_function": "raft_surface_line_width", + "global_only": "True" + }, + "raft_interface_thickness": + { + "label": "Raft Middle Thickness", + "description": "Layer thickness of the middle raft layer.", + "unit": "mm", + "type": "float", + "default_value": 0.27, + "minimum_value": "0", + "maximum_value_warning": "5.0", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_interface_line_width": + { + "label": "Raft Middle Line Width", + "description": "Width of the lines in the middle raft layer. Making the second layer extrude more causes the lines to stick to the bed.", + "unit": "mm", + "type": "float", + "default_value": 1, + "inherit_function": "line_width", + "minimum_value": "0.0001", + "maximum_value_warning": "machine_nozzle_size * 2", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_interface_line_spacing": + { + "label": "Raft Middle Spacing", + "description": "The distance between the raft lines for the middle raft layer. The spacing of the middle should be quite wide, while being dense enough to support the top raft layers.", + "unit": "mm", + "type": "float", + "default_value": 1.0, + "minimum_value": "0", + "maximum_value_warning": "15.0", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_base_thickness": + { + "label": "Raft Base Thickness", + "description": "Layer thickness of the base raft layer. This should be a thick layer which sticks firmly to the printer bed.", + "unit": "mm", + "type": "float", + "default_value": 0.3, + "minimum_value": "0", + "maximum_value_warning": "5.0", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_base_line_width": + { + "label": "Raft Base Line Width", + "description": "Width of the lines in the base raft layer. These should be thick lines to assist in bed adhesion.", + "unit": "mm", + "type": "float", + "default_value": 1, + "minimum_value": "0.0001", + "inherit_function": "line_width", + "maximum_value_warning": "machine_nozzle_size * 2", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_base_line_spacing": + { + "label": "Raft Line Spacing", + "description": "The distance between the raft lines for the base raft layer. Wide spacing makes for easy removal of the raft from the build plate.", + "unit": "mm", + "type": "float", + "default_value": 3.0, + "minimum_value": "0.0001", + "maximum_value_warning": "100", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_speed": + { + "label": "Raft Print Speed", + "description": "The speed at which the raft is printed.", + "unit": "mm/s", + "type": "float", + "default_value": 30, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "200", + "enabled": "adhesion_type == \"raft\"", + "inherit_function": "speed_print / 60 * 30", + "global_only": "True", + "children": + { + "raft_surface_speed": + { + "label": "Raft Surface Print Speed", + "description": "The speed at which the surface raft layers are printed. These should be printed a bit slower, so that the nozzle can slowly smooth out adjacent surface lines.", + "unit": "mm/s", + "type": "float", + "default_value": 30, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "100", + "enabled": "adhesion_type == \"raft\"", + "inherit_function": "parent_value", + "global_only": "True" + }, + "raft_interface_speed": + { + "label": "Raft Interface Print Speed", + "description": "The speed at which the interface raft layer is printed. This should be printed quite slowly, as the volume of material coming out of the nozzle is quite high.", + "unit": "mm/s", + "type": "float", + "default_value": 15, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "enabled": "adhesion_type == \"raft\"", + "inherit_function": "0.5 * parent_value", + "global_only": "True" + }, + "raft_base_speed": + { + "label": "Raft Base Print Speed", + "description": "The speed at which the base raft layer is printed. This should be printed quite slowly, as the volume of material coming out of the nozzle is quite high.", + "unit": "mm/s", + "type": "float", + "default_value": 15, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "200", + "enabled": "adhesion_type == \"raft\"", + "inherit_function": "0.5 * parent_value", + "global_only": "True" + } + } + }, + "raft_fan_speed": + { + "label": "Raft Fan Speed", + "description": "The fan speed for the raft.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value": "100", + "default_value": 100, + "global_only": "True", + "enabled": "adhesion_type == \"raft\"", + "children": + { + "raft_surface_fan_speed": + { + "label": "Raft Surface Fan Speed", + "description": "The fan speed for the surface raft layers.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value": "100", + "default_value": 100, + "global_only": "True", + "inherit": true, + "enabled": "adhesion_type == \"raft\"" + }, + "raft_interface_fan_speed": + { + "label": "Raft Interface Fan Speed", + "description": "The fan speed for the interface raft layer.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value": "100", + "default_value": 100, + "global_only": "True", + "inherit": true, + "enabled": "adhesion_type == \"raft\"" + }, + "raft_base_fan_speed": + { + "label": "Raft Base Fan Speed", + "description": "The fan speed for the base raft layer.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value": "100", + "default_value": 100, + "global_only": "True", + "inherit": true, + "enabled": "adhesion_type == \"raft\"" + } + } + } + } + }, + "meshfix": + { + "label": "Mesh Fixes", + "type": "category", + "icon": "category_fixes", + "description": "category_fixes", + "children": + { + "meshfix_union_all": + { + "label": "Union Overlapping Volumes", + "description": "Ignore the internal geometry arising from overlapping volumes and print the volumes as one. This may cause internal cavities to disappear.", + "type": "bool", + "default_value": true + }, + "meshfix_union_all_remove_holes": + { + "label": "Remove All Holes", + "description": "Remove the holes in each layer and keep only the outside shape. This will ignore any invisible internal geometry. However, it also ignores layer holes which can be viewed from above or below.", + "type": "bool", + "default_value": false + }, + "meshfix_extensive_stitching": + { + "label": "Extensive Stitching", + "description": "Extensive stitching tries to stitch up open holes in the mesh by closing the hole with touching polygons. This option can introduce a lot of processing time.", + "type": "bool", + "default_value": false + }, + "meshfix_keep_open_polygons": + { + "label": "Keep Disconnected Faces", + "description": "Normally Cura tries to stitch up small holes in the mesh and remove parts of a layer with big holes. Enabling this option keeps those parts which cannot be stitched. This option should be used as a last resort option when everything else fails to produce proper GCode.", + "type": "bool", + "default_value": false + } + } + }, + "blackmagic": + { + "label": "Special Modes", + "type": "category", + "icon": "category_blackmagic", + "description": "category_blackmagic", + "children": + { + "print_sequence": + { + "label": "Print Sequence", + "description": "Whether to print all objects one layer at a time or to wait for one object to finish, before moving on to the next. One at a time mode is only possible if all models are separated in such a way that the whole print head can move in between and all models are lower than the distance between the nozzle and the X/Y axes.", + "type": "enum", + "options": + { + "all_at_once": "All at Once", + "one_at_a_time": "One at a Time" + }, + "default_value": "all_at_once", + "global_only": true + }, + "magic_mesh_surface_mode": + { + "label": "Surface Mode", + "description": "Treat the model as a surface only, a volume, or volumes with loose surfaces. The normal print mode only prints enclosed volumes. \"Surface\" prints a single wall tracing the mesh surface with no infill and no top/bottom skin. \"Both\" prints enclosed volumes like normal and any remaining polygons as surfaces.", + "type": "enum", + "options": + { + "normal": "Normal", + "surface": "Surface", + "both": "Both" + }, + "default_value": "normal" + }, + "magic_spiralize": + { + "label": "Spiralize Outer Contour", + "description": "Spiralize smooths out the Z move of the outer edge. This will create a steady Z increase over the whole print. This feature turns a solid object into a single walled print with a solid bottom. This feature used to be called Joris in older versions.", + "type": "bool", + "default_value": false, + "global_only": "True" + } + } + }, + "blackmagic": + { + "label": "Experimental Modes", + "type": "category", + "icon": "category_blackmagic", + "description": "category_blackmagic", + "children": + { + "draft_shield_enabled": + { + "label": "Enable Draft Shield", + "description": "This will create a wall around the object, which traps (hot) air and shields against exterior airflow. Especially useful for materials which warp easily.", + "type": "bool", + "default_value": false, + "global_only": true + }, + "draft_shield_dist": + { + "label": "Draft Shield X/Y Distance", + "description": "Distance of the draft shield from the print, in the X/Y directions.", + "unit": "mm", + "type": "float", + "minimum_value": "0", + "maximum_value_warning": "100", + "default_value": 10, + "enabled": "draft_shield_enabled", + "global_only": true + }, + "draft_shield_height_limitation": + { + "label": "Draft Shield Limitation", + "description": "Set the height of the draft shield. Choose to print the draft shield at the full height of the object or at a limited height.", + "type": "enum", + "options": + { + "full": "Full", + "limited": "Limited" + }, + "default_value": "full", + "enabled": "draft_shield_enabled", + "global_only": true + }, + "draft_shield_height": + { + "label": "Draft Shield Height", + "description": "Height limitation of the draft shield. Above this height no draft shield will be printed.", + "unit": "mm", + "type": "float", + "minimum_value": "0", + "maximum_value_warning": "9999", + "default_value": 0, + "inherit_function": "9999 if draft_shield_height_limitation == 'full' and draft_shield_enabled else 0.0", + "enabled": "draft_shield_height_limitation == \"limited\"", + "global_only": true + }, + "coasting_enable": + { + "label": "Enable Coasting", + "description": "Coasting replaces the last part of an extrusion path with a travel path. The oozed material is used to print the last piece of the extrusion path in order to reduce stringing.", + "type": "bool", + "default_value": false, + "global_only": true + }, + "coasting_volume": + { + "label": "Coasting Volume", + "description": "The volume otherwise oozed. This value should generally be close to the nozzle diameter cubed.", + "unit": "mm³", + "type": "float", + "default_value": 0.064, + "minimum_value": "0", + "maximum_value_warning": "2.0", + "inherit": false, + "enabled": "coasting_enable", + "global_only": true + }, + "coasting_min_volume": + { + "label": "Minimum Volume Before Coasting", + "description": "The smallest volume an extrusion path should have before allowing coasting. For smaller extrusion paths, less pressure has been built up in the bowden tube and so the coasted volume is scaled linearly. This value should always be larger than the Coasting Volume.", + "unit": "mm³", + "type": "float", + "default_value": 0.8, + "minimum_value": "0", + "maximum_value_warning": "10.0", + "enabled": "coasting_enable", + "global_only": true + }, + "coasting_speed": + { + "label": "Coasting Speed", + "description": "The speed by which to move during coasting, relative to the speed of the extrusion path. A value slightly under 100% is advised, since during the coasting move the pressure in the bowden tube drops.", + "unit": "%", + "type": "float", + "default_value": 90, + "minimum_value": "0.0001", + "maximum_value_warning": "100", + "inherit": false, + "enabled": "coasting_enable", + "global_only": true + }, + "skin_outline_count": + { + "label": "Extra Skin Wall Count", + "description": "Replaces the outermost part of the top/bottom pattern with a number of concentric lines. Using one or two lines improves roofs that start on infill material.", + "default_value": 0, + "minimum_value": "0", + "maximum_value_warning": "10", + "type": "int" + }, + "skin_alternate_rotation": + { + "label": "Alternate Skin Rotation", + "description": "Alternate the direction in which the top/bottom layers are printed. Normally they are printed diagonally only. This setting adds the X-only and Y-only directions.", + "type": "bool", + "default_value": false, + "enabled": "top_bottom_pattern != \"concentric\"" + }, + "support_conical_enabled": + { + "label": "Enable Conical Support", + "description": "Experimental feature: Make support areas smaller at the bottom than at the overhang.", + "type": "bool", + "default_value": false, + "enabled": "support_enable" + }, + "support_conical_angle": + { + "label": "Conical Support Angle", + "description": "The angle of the tilt of conical support. With 0 degrees being vertical, and 90 degrees being horizontal. Smaller angles cause the support to be more sturdy, but consist of more material. Negative angles cause the base of the support to be wider than the top.", + "unit": "°", + "type": "float", + "minimum_value": "-90", + "minimum_value_warning": "-45", + "maximum_value_warning": "45", + "maximum_value": "90", + "default_value": 30, + "enabled": "support_conical_enabled and support_enable" + }, + "support_conical_min_width": + { + "label": "Conical Support Minimum Width", + "description": "Minimum width to which the base of the conical support area is reduced. Small widths can lead to unstable support structures.", + "unit": "mm", + "default_value": 5.0, + "minimum_value": "0", + "minimum_value_warning": "machine_nozzle_size * 3", + "maximum_value_warning": "100.0", + "type": "float", + "enabled": "support_conical_enabled and support_enable" + }, + "magic_fuzzy_skin_enabled": + { + "label": "Fuzzy Skin", + "description": "Randomly jitter while printing the outer wall, so that the surface has a rough and fuzzy look.", + "type": "bool", + "default_value": false + }, + "magic_fuzzy_skin_thickness": + { + "label": "Fuzzy Skin Thickness", + "description": "The width within which to jitter. It's advised to keep this below the outer wall width, since the inner walls are unaltered.", + "type": "float", + "unit": "mm", + "default_value": 0.3, + "minimum_value": "0.001", + "maximum_value_warning": "wall_line_width_0", + "enabled": "magic_fuzzy_skin_enabled" + }, + "magic_fuzzy_skin_point_density": + { + "label": "Fuzzy Skin Density", + "description": "The average density of points introduced on each polygon in a layer. Note that the original points of the polygon are discarded, so a low density results in a reduction of the resolution.", + "type": "float", + "unit": "1/mm", + "default_value": 1.25, + "minimum_value": "0.008", + "minimum_value_warning": "0.1", + "maximum_value_warning": "10", + "maximum_value": "2 / magic_fuzzy_skin_thickness", + "enabled": "magic_fuzzy_skin_enabled", + "children": + { + "magic_fuzzy_skin_point_dist": + { + "label": "Fuzzy Skin Point Distance", + "description": "The average distance between the random points introduced on each line segment. Note that the original points of the polygon are discarded, so a high smoothness results in a reduction of the resolution. This value must be higher than half the Fuzzy Skin Thickness.", + "type": "float", + "unit": "mm", + "default_value": 0.8, + "minimum_value": "magic_fuzzy_skin_thickness / 2", + "minimum_value_warning": "0.1", + "maximum_value_warning": "10", + "inherit_function": "10000 if parent_value == 0 else 1 / parent_value", + "enabled": "magic_fuzzy_skin_enabled" + } + } + }, + "wireframe_enabled": + { + "label": "Wire Printing", + "description": "Print only the outside surface with a sparse webbed structure, printing 'in thin air'. This is realized by horizontally printing the contours of the model at given Z intervals which are connected via upward and diagonally downward lines.", + "type": "bool", + "default_value": false, + "global_only": "True" + }, + "wireframe_height": + { + "label": "WP Connection Height", + "description": "The height of the upward and diagonally downward lines between two horizontal parts. This determines the overall density of the net structure. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 3, + "minimum_value": "0.0001", + "maximum_value_warning": "20", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_roof_inset": + { + "label": "WP Roof Inset Distance", + "description": "The distance covered when making a connection from a roof outline inward. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 3, + "minimum_value": "0", + "minimum_value_warning": "machine_nozzle_size", + "maximum_value_warning": "20", + "enabled": "wireframe_enabled", + "inherit_function": "wireframe_height", + "global_only": "True" + }, + "wireframe_printspeed": + { + "label": "WP Speed", + "description": "Speed at which the nozzle moves when extruding material. Only applies to Wire Printing.", + "unit": "mm/s", + "type": "float", + "default_value": 5, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "50", + "enabled": "wireframe_enabled", + "global_only": "True", + "children": + { + "wireframe_printspeed_bottom": + { + "label": "WP Bottom Printing Speed", + "description": "Speed of printing the first layer, which is the only layer touching the build platform. Only applies to Wire Printing.", + "unit": "mm/s", + "type": "float", + "default_value": 5, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "50", + "visible": false, + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_printspeed_up": + { + "label": "WP Upward Printing Speed", + "description": "Speed of printing a line upward 'in thin air'. Only applies to Wire Printing.", + "unit": "mm/s", + "type": "float", + "default_value": 5, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "50", + "visible": false, + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_printspeed_down": + { + "label": "WP Downward Printing Speed", + "description": "Speed of printing a line diagonally downward. Only applies to Wire Printing.", + "unit": "mm/s", + "type": "float", + "default_value": 5, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "50", + "visible": false, + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_printspeed_flat": + { + "label": "WP Horizontal Printing Speed", + "description": "Speed of printing the horizontal contours of the object. Only applies to Wire Printing.", + "unit": "mm/s", + "type": "float", + "default_value": 5, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "100", + "inherit": true, + "enabled": "wireframe_enabled", + "global_only": "True" + } + } + }, + "wireframe_flow": + { + "label": "WP Flow", + "description": "Flow compensation: the amount of material extruded is multiplied by this value. Only applies to Wire Printing.", + "unit": "%", + "default_value": 100, + "minimum_value": "0", + "maximum_value_warning": "100", + "type": "float", + "enabled": "wireframe_enabled", + "global_only": "True", + "children": + { + "wireframe_flow_connection": + { + "label": "WP Connection Flow", + "description": "Flow compensation when going up or down. Only applies to Wire Printing.", + "unit": "%", + "default_value": 100, + "minimum_value": "0", + "maximum_value_warning": "100", + "type": "float", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_flow_flat": + { + "label": "WP Flat Flow", + "description": "Flow compensation when printing flat lines. Only applies to Wire Printing.", + "unit": "%", + "default_value": 100, + "minimum_value": "0", + "maximum_value_warning": "100", + "type": "float", + "enabled": "wireframe_enabled", + "global_only": "True" + } + } + }, + "wireframe_top_delay": + { + "label": "WP Top Delay", + "description": "Delay time after an upward move, so that the upward line can harden. Only applies to Wire Printing.", + "unit": "sec", + "type": "float", + "default_value": 0, + "minimum_value": "0", + "maximum_value_warning": "1", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_bottom_delay": + { + "label": "WP Bottom Delay", + "description": "Delay time after a downward move. Only applies to Wire Printing.", + "unit": "sec", + "type": "float", + "default_value": 0, + "minimum_value": "0", + "maximum_value_warning": "1", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_flat_delay": + { + "label": "WP Flat Delay", + "description": "Delay time between two horizontal segments. Introducing such a delay can cause better adhesion to previous layers at the connection points, while too long delays cause sagging. Only applies to Wire Printing.", + "unit": "sec", + "type": "float", + "default_value": 0.1, + "minimum_value": "0", + "maximum_value_warning": "0.5", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_up_half_speed": + { + "label": "WP Ease Upward", + "description": "Distance of an upward move which is extruded with half speed.\nThis can cause better adhesion to previous layers, while not heating the material in those layers too much. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 0.3, + "minimum_value": "0", + "maximum_value_warning": "5.0", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_top_jump": + { + "label": "WP Knot Size", + "description": "Creates a small knot at the top of an upward line, so that the consecutive horizontal layer has a better chance to connect to it. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 0.6, + "minimum_value": "0", + "maximum_value_warning": "2.0", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_fall_down": + { + "label": "WP Fall Down", + "description": "Distance with which the material falls down after an upward extrusion. This distance is compensated for. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 0.5, + "minimum_value": "0", + "maximum_value_warning": "wireframe_height", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_drag_along": + { + "label": "WP Drag Along", + "description": "Distance with which the material of an upward extrusion is dragged along with the diagonally downward extrusion. This distance is compensated for. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 0.6, + "minimum_value": "0", + "maximum_value_warning": "wireframe_height", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_strategy": + { + "label": "WP Strategy", + "description": "Strategy for making sure two consecutive layers connect at each connection point. Retraction lets the upward lines harden in the right position, but may cause filament grinding. A knot can be made at the end of an upward line to heighten the chance of connecting to it and to let the line cool; however, it may require slow printing speeds. Another strategy is to compensate for the sagging of the top of an upward line; however, the lines won't always fall down as predicted.", + "type": "enum", + "options": + { + "compensate": "Compensate", + "knot": "Knot", + "retract": "Retract" + }, + "default_value": "compensate", + "visible": false, + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_straight_before_down": + { + "label": "WP Straighten Downward Lines", + "description": "Percentage of a diagonally downward line which is covered by a horizontal line piece. This can prevent sagging of the top most point of upward lines. Only applies to Wire Printing.", + "type": "float", + "unit": "%", + "default_value": 20, + "minimum_value": "0", + "maximum_value": "100", + "visible": false, + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_roof_fall_down": + { + "label": "WP Roof Fall Down", + "description": "The distance which horizontal roof lines printed 'in thin air' fall down when being printed. This distance is compensated for. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 2, + "minimum_value_warning": "0", + "maximum_value_warning": "wireframe_roof_inset", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_roof_drag_along": + { + "label": "WP Roof Drag Along", + "description": "The distance of the end piece of an inward line which gets dragged along when going back to the outer outline of the roof. This distance is compensated for. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 0.8, + "minimum_value": "0", + "maximum_value_warning": "10", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_roof_outer_delay": + { + "label": "WP Roof Outer Delay", + "description": "Time spent at the outer perimeters of hole which is to become a roof. Longer times can ensure a better connection. Only applies to Wire Printing.", + "type": "float", + "unit": "sec", + "default_value": 0.2, + "minimum_value": "0", + "maximum_value_warning": "2.0", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_nozzle_clearance": + { + "label": "WP Nozzle Clearance", + "description": "Distance between the nozzle and horizontally downward lines. Larger clearance results in diagonally downward lines with a less steep angle, which in turn results in less upward connections with the next layer. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 1, + "minimum_value_warning": "0", + "maximum_value_warning": "10.0", + "enabled": "wireframe_enabled", + "global_only": "True" + } + } + } + } +} From 9b1f560935da77757b057ec6ab929ad95191b4dc Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 2 May 2016 16:47:15 +0200 Subject: [PATCH 002/705] Removed last stray visible properties CURA-1278 --- resources/machines/fdmprinter.def.json | 28 +++----------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/resources/machines/fdmprinter.def.json b/resources/machines/fdmprinter.def.json index 3d39e8a652..b44d720d33 100644 --- a/resources/machines/fdmprinter.def.json +++ b/resources/machines/fdmprinter.def.json @@ -4,8 +4,7 @@ "metadata": { "category": "Ultimaker", - "manufacturer": "Ultimaker", - "visible": false + "manufacturer": "Ultimaker" }, "name": "FDM Printer Base Description", "author": "Ultimaker B.V.", @@ -215,7 +214,6 @@ "default_value": 0.4, "minimum_value": "0.001", "maximum_value_warning": "10", - "visible": false } } }, @@ -366,7 +364,6 @@ "shell": { "label": "Shell", - "visible": true, "icon": "category_shell", "description": "Shell", "type": "category", @@ -683,7 +680,6 @@ "description": "Change the temperature for each layer automatically with the average flow speed of that layer.", "type": "bool", "default_value": false, - "visible": false, "enabled": "False", "global_only": true }, @@ -717,8 +713,7 @@ "maximum_value_warning": "10.0", "global_only": "True", "enabled": "False", - "enabled_before_removal": "material_flow_dependent_temperature or machine_extruder_count > 1", - "visible": false + "enabled_before_removal": "material_flow_dependent_temperature or machine_extruder_count > 1" }, "material_bed_temperature": { "label": "Bed Temperature", @@ -756,8 +751,7 @@ "label": "Enable Retraction", "description": "Retract the filament when the nozzle is moving over a non-printed area. ", "type": "bool", - "default_value": true, - "visible": true + "default_value": true }, "retraction_amount": { "label": "Retraction Distance", @@ -767,7 +761,6 @@ "default_value": 6.5, "minimum_value_warning": "-0.0001", "maximum_value_warning": "10.0", - "visible": false, "inherit": false, "enabled": "retraction_enable" }, @@ -780,7 +773,6 @@ "minimum_value": "0", "maximum_value": "299792458000", "maximum_value_warning": "100", - "visible": false, "inherit": false, "enabled": "retraction_enable", "children": { @@ -793,7 +785,6 @@ "minimum_value": "0", "maximum_value": "299792458000", "maximum_value_warning": "100", - "visible": false, "enabled": "retraction_enable" }, "retraction_prime_speed": { @@ -805,7 +796,6 @@ "minimum_value": "0", "maximum_value": "299792458000", "maximum_value_warning": "100", - "visible": false, "enabled": "retraction_enable" } } @@ -818,7 +808,6 @@ "default_value": 0, "minimum_value_warning": "-0.0001", "maximum_value_warning": "5.0", - "visible": false, "inherit": false, "enabled": "retraction_enable" }, @@ -831,7 +820,6 @@ "inherit_function": "line_width * 2", "minimum_value": "0", "maximum_value_warning": "10", - "visible": false, "inherit": false, "enabled": "retraction_enable" }, @@ -842,7 +830,6 @@ "minimum_value": "0", "maximum_value_warning": "100", "type": "int", - "visible": false, "inherit": false, "enabled": "retraction_enable" }, @@ -854,7 +841,6 @@ "default_value": 4.5, "minimum_value": "0", "maximum_value_warning": "retraction_amount * 2", - "visible": false, "inherit_function": "retraction_amount", "enabled": "retraction_enable" }, @@ -912,7 +898,6 @@ "maximum_value": "299792458000", "maximum_value_warning": "150", "default_value": 30, - "visible": false, "inherit_function": "parent_value / 2", "children": { @@ -1134,7 +1119,6 @@ "maximum_value": "100", "inherit_function": "parent_value", "default_value": 100, - "visible": false, "enabled": "cool_fan_enabled", "global_only": "True" }, @@ -1411,7 +1395,6 @@ "description": "Generate a dense top skin at the top of the support on which the model is printed.", "type": "bool", "default_value": false, - "visible": true, "enabled": "support_enable" }, "support_roof_height": @@ -2198,7 +2181,6 @@ "minimum_value": "0.1", "maximum_value": "299792458000", "maximum_value_warning": "50", - "visible": false, "enabled": "wireframe_enabled", "global_only": "True" }, @@ -2212,7 +2194,6 @@ "minimum_value": "0.1", "maximum_value": "299792458000", "maximum_value_warning": "50", - "visible": false, "enabled": "wireframe_enabled", "global_only": "True" }, @@ -2226,7 +2207,6 @@ "minimum_value": "0.1", "maximum_value": "299792458000", "maximum_value_warning": "50", - "visible": false, "enabled": "wireframe_enabled", "global_only": "True" }, @@ -2381,7 +2361,6 @@ "retract": "Retract" }, "default_value": "compensate", - "visible": false, "enabled": "wireframe_enabled", "global_only": "True" }, @@ -2394,7 +2373,6 @@ "default_value": 20, "minimum_value": "0", "maximum_value": "100", - "visible": false, "enabled": "wireframe_enabled", "global_only": "True" }, From ad506be34cf455409e31557ac9294b769bf6fb21 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 2 May 2016 16:48:58 +0200 Subject: [PATCH 003/705] Formatting CURA-1278 --- resources/machines/fdmprinter.def.json | 77 +++++++++++++++++--------- 1 file changed, 51 insertions(+), 26 deletions(-) diff --git a/resources/machines/fdmprinter.def.json b/resources/machines/fdmprinter.def.json index b44d720d33..db7bcfb864 100644 --- a/resources/machines/fdmprinter.def.json +++ b/resources/machines/fdmprinter.def.json @@ -19,142 +19,163 @@ "description": "Machine specific settings", "children": { - "machine_show_variants": { + "machine_show_variants": + { "description": "Whether to show the different variants of this machine, which are described in separate json files.", "default_value": false, "type": "bool", "label": "Show machine variants" }, - "machine_start_gcode": { + "machine_start_gcode": + { "description": "Gcode commands to be executed at the very start - separated by \\n.", "default_value": "G28 ;Home\nG1 Z15.0 F6000 ;Move the platform down 15mm\n;Prime the extruder\nG92 E0\nG1 F200 E3\nG92 E0", "label": "Start GCode", "global_only": true, "type": "str" }, - "machine_end_gcode": { + "machine_end_gcode": + { "description": "Gcode commands to be executed at the very end - separated by \\n.", "default_value": "M104 S0\nM140 S0\n;Retract the filament\nG92 E1\nG1 E-1 F300\nG28 X0 Y0\nM84", "label": "End GCode", "global_only": true, "type": "str" }, - "material_bed_temp_wait": { + "material_bed_temp_wait": + { "description": "Whether to insert a command to wait until the bed temperature is reached at the start.", "label": "Wait for bed heatup", "default_value": true, "global_only": true, "type": "bool" }, - "material_print_temp_prepend": { + "material_print_temp_prepend": + { "description": "Whether to include nozzle temperature commands at the start of the gcode. When the start_gcode already contains nozzle temperature commands Cura frontend will automatically disable this setting.", "default_value": true, "global_only": true, "type": "bool", "label": "Wait for material heatup" }, - "machine_width": { + "machine_width": + { "description": "The width (X-direction) of the printable area.", "default_value": 100, "global_only": true, "type": "float", "label": "Machine width" }, - "machine_depth": { + "machine_depth": + { "description": "The depth (Y-direction) of the printable area.", "default_value": 100, "global_only": true, "type": "float", "label": "Machine depth" }, - "machine_height": { + "machine_height": + { "description": "The height (Z-direction) of the printable area.", "default_value": 100, "global_only": true, "type": "float", "label": "Machine height" }, - "machine_heated_bed": { + "machine_heated_bed": + { "description": "Whether the machine has a heated bed present.", "default_value": false, "global_only": true, "label": "Has heated bed", "type": "bool" }, - "machine_center_is_zero": { + "machine_center_is_zero": + { "description": "Whether the X/Y coordinates of the zero position of the printer is at the center of the printable area.", "default_value": false, "global_only": true, "type": "bool", "label": "Is center origin" }, - "machine_extruder_count": { + "machine_extruder_count": + { "description": "Number of extruder trains. An extruder train is the combination of a feeder, bowden tube, and nozzle.", "default_value": 1, "global_only": true, "type": "bool", "label": "Number extruders" }, - "machine_nozzle_tip_outer_diameter": { + "machine_nozzle_tip_outer_diameter": + { "description": "The outer diameter of the tip of the nozzle.", "label": "Outer nozzle diameter", "default_value": 1, "global_only": true, "type": "float" }, - "machine_nozzle_head_distance": { + "machine_nozzle_head_distance": + { "description": "The height difference between the tip of the nozzle and the lowest part of the print head.", "default_value": 3, "global_only": true, "type": "float", "label": "Nozzle length" }, - "machine_nozzle_expansion_angle": { + "machine_nozzle_expansion_angle": + { "description": "The angle between the horizontal plane and the conical part right above the tip of the nozzle.", "default_value": 45, "global_only": true, "type": "int", "label": "Nozzle angle" }, - "machine_heat_zone_length": { + "machine_heat_zone_length": + { "description": "The distance from the tip of the nozzle in which heat from the nozzle is transfered to the filament.", "default_value": 16, "global_only": true, "type": "float", "label": "Heat zone length" }, - "machine_nozzle_heat_up_speed": { + "machine_nozzle_heat_up_speed": + { "description": "The speed (°C/s) by which the nozzle heats up averaged over the window of normal printing temperatures and the standby temperature.", "default_value": 2.0, "global_only": true, "type": "float", "label": "Heat up speed" }, - "machine_nozzle_cool_down_speed": { + "machine_nozzle_cool_down_speed": + { "description": "The speed (°C/s) by which the nozzle cools down averaged over the window of normal printing temperatures and the standby temperature.", "default_value": 2.0, "global_only": true, "type": "float", "label": "Cool down speed" }, - "machine_gcode_flavor": { + "machine_gcode_flavor": + { "description": "The type of gcode to be generated.", "default_value": "RepRap", "global_only": true, "type": "str", "label": "Gcode flavour" }, - "machine_disallowed_areas": { + "machine_disallowed_areas": + { "description": "A list of polygons with areas the print head is not allowed to enter.", "type": "polygons", "default_value": [], "global_only": true, "label": "Disallowed areas" }, - "machine_head_polygon": { + "machine_head_polygon": + { "description": "A 2D silhouette of the print head (fan caps excluded).", "type": "polygon", - "default_value": [ + "default_value": + [ [ -1, 1 @@ -175,10 +196,12 @@ "global_only": true, "label": "Machine head polygon" }, - "machine_head_with_fans_polygon": { + "machine_head_with_fans_polygon": + { "description": "A 2D silhouette of the print head (fan caps included).", "type": "polygon", - "default_value": [ + "default_value": + [ [ -20, 10 @@ -199,21 +222,23 @@ "global_only": true, "label": "Machine head & Fan polygon" }, - "gantry_height": { + "gantry_height": + { "description": "The height difference between the tip of the nozzle and the gantry system (X and Y axes).", "default_value": 99999999999, "global_only": true, "label": "Gantry height", "type": "float" }, - "machine_nozzle_size": { + "machine_nozzle_size": + { "label": "Nozzle Diameter", "description": "The inner diameter of the nozzle. Change this setting when using a non-standard nozzle size.", "unit": "mm", "type": "float", "default_value": 0.4, "minimum_value": "0.001", - "maximum_value_warning": "10", + "maximum_value_warning": "10" } } }, From 1eab26dcc02d1a09186aa21efebc8bf6e0e9f902 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 3 May 2016 09:23:20 +0200 Subject: [PATCH 004/705] Added invisible to metadata again CURA-1278 --- resources/machines/fdmprinter.def.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/machines/fdmprinter.def.json b/resources/machines/fdmprinter.def.json index db7bcfb864..3bf66226f5 100644 --- a/resources/machines/fdmprinter.def.json +++ b/resources/machines/fdmprinter.def.json @@ -4,12 +4,12 @@ "metadata": { "category": "Ultimaker", - "manufacturer": "Ultimaker" + "manufacturer": "Ultimaker", + "visible": false }, "name": "FDM Printer Base Description", "author": "Ultimaker B.V.", "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g", - "settings": { "machine_settings": From c69652531753364a8d326848a1448f0b54807068 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 3 May 2016 11:38:59 +0200 Subject: [PATCH 005/705] Updated inherit function to value (and in cases where there was implicit inheritance made it explicit) CURA-1278 --- resources/machines/fdmprinter.def.json | 175 +++++++++++++------------ 1 file changed, 94 insertions(+), 81 deletions(-) diff --git a/resources/machines/fdmprinter.def.json b/resources/machines/fdmprinter.def.json index 3bf66226f5..cf92aa847f 100644 --- a/resources/machines/fdmprinter.def.json +++ b/resources/machines/fdmprinter.def.json @@ -284,7 +284,7 @@ "maximum_value_warning": "2 * machine_nozzle_size", "default_value": 0.4, "type": "float", - "inherit_function": "machine_nozzle_size", + "value": "machine_nozzle_size", "children": { "wall_line_width": @@ -295,6 +295,7 @@ "minimum_value": "0.0001", "minimum_value_warning": "0.2", "maximum_value_warning": "5", + "value":"line_width", "default_value": 0.4, "type": "float", "children": @@ -308,6 +309,7 @@ "minimum_value_warning": "0.2", "maximum_value_warning": "5", "default_value": 0.4, + "value":"wall_line_width", "type": "float" }, "wall_line_width_x": @@ -319,6 +321,7 @@ "minimum_value_warning": "0.2", "maximum_value_warning": "5", "default_value": 0.4, + "value":"wall_line_width", "type": "float" } } @@ -332,7 +335,8 @@ "minimum_value_warning": "0.2", "maximum_value_warning": "5", "default_value": 0.4, - "type": "float" + "type": "float", + "value": "line_width" }, "infill_line_width": { @@ -343,7 +347,8 @@ "minimum_value_warning": "0.2", "maximum_value_warning": "5", "default_value": 0.4, - "type": "float" + "type": "float", + "value": "line_width" }, "skirt_line_width": { @@ -355,7 +360,8 @@ "maximum_value_warning": "5", "default_value": 0.4, "type": "float", - "global_only": true + "global_only": true, + "value": "line_width" }, "support_line_width": { @@ -368,7 +374,8 @@ "default_value": 0.4, "type": "float", "enabled": "support_enable", - "global_only": true + "global_only": true, + "value": "line_width" }, "support_roof_line_width": { @@ -380,7 +387,8 @@ "maximum_value_warning": "machine_nozzle_size * 2", "type": "float", "enabled": "support_roof_enable", - "global_only": true + "global_only": true, + "value": "line_width" } } } @@ -413,7 +421,7 @@ "default_value": 2, "minimum_value": "0", "type": "int", - "inherit_function": "1 if magic_spiralize else max(1, round((wall_thickness - wall_line_width_0) / wall_line_width_x) + 1)" + "value": "1 if magic_spiralize else max(1, round((wall_thickness - wall_line_width_0) / wall_line_width_x) + 1)" } } }, @@ -438,6 +446,7 @@ "minimum_value": "0", "maximum_value_warning": "100", "type": "float", + "value": "top_bottom_thickness", "children": { "top_layers": @@ -448,7 +457,7 @@ "minimum_value": "0", "maximum_value_warning": "100", "type": "int", - "inherit_function": "0 if infill_sparse_density == 100 else math.ceil(round(parent_value / layer_height, 4))" + "value": "0 if infill_sparse_density == 100 else math.ceil(round(parent_value / layer_height, 4))" } } }, @@ -460,6 +469,7 @@ "default_value": 0.6, "minimum_value": "0", "type": "float", + "value": "top_bottom_thickness", "children": { "bottom_layers": @@ -469,7 +479,7 @@ "minimum_value": "0", "default_value": 6, "type": "int", - "inherit_function": "999999 if infill_sparse_density == 100 else math.ceil(round(parent_value / layer_height, 4))" + "value": "999999 if infill_sparse_density == 100 else math.ceil(round(parent_value / layer_height, 4))" } } } @@ -495,7 +505,7 @@ "unit": "mm", "type": "float", "default_value": 0.0, - "inherit_function": "(machine_nozzle_size - wall_line_width_0) / 2 if wall_line_width_0 < machine_nozzle_size else 0", + "value": "(machine_nozzle_size - wall_line_width_0) / 2 if wall_line_width_0 < machine_nozzle_size else 0", "minimum_value_warning": "0", "maximum_value_warning": "machine_nozzle_size" }, @@ -504,8 +514,7 @@ "label": "Alternate Extra Wall", "description": "Prints an extra wall at every other layer. This way infill gets caught between these extra walls, resulting in stronger prints.", "type": "bool", - "default_value": false, - "inherit": false + "default_value": false }, "remove_overlapping_walls_enabled": { @@ -522,7 +531,7 @@ "description": "Remove parts of an outer wall which share an overlap which would result in overextrusion in some places. These overlaps occur in thin pieces in a model and sharp corners.", "type": "bool", "default_value": false, - "inherit": true, + "value": "remove_overlapping_walls_enabled", "enabled": "False" }, "remove_overlapping_walls_x_enabled": @@ -531,7 +540,7 @@ "description": "Remove parts of an inner wall that would otherwise overlap and cause over-extrusion. These overlaps occur in thin pieces in a model and sharp corners.", "type": "bool", "default_value": true, - "inherit": false + "value": "remove_overlapping_walls_enabled" } } }, @@ -615,7 +624,7 @@ "type": "float", "default_value": 2, "minimum_value": "0", - "inherit_function": "0 if infill_sparse_density == 0 else (infill_line_width * 100) / infill_sparse_density * (2 if infill_pattern == \"grid\" else (3 if infill_pattern == \"triangles\" else 1))" + "value": "0 if infill_sparse_density == 0 else (infill_line_width * 100) / infill_sparse_density * (2 if infill_pattern == \"grid\" else (3 if infill_pattern == \"triangles\" else 1))" } } }, @@ -633,7 +642,7 @@ "zigzag": "Zig Zag" }, "default_value": "grid", - "inherit_function": "'lines' if infill_sparse_density > 25 else 'grid'" + "value": "'lines' if infill_sparse_density > 25 else 'grid'" }, "infill_overlap": { @@ -642,7 +651,7 @@ "unit": "%", "type": "float", "default_value": 10, - "inherit_function": "10 if infill_sparse_density < 95 else 0", + "value": "10 if infill_sparse_density < 95 else 0", "minimum_value_warning": "-50", "maximum_value_warning": "100", "children": @@ -656,7 +665,7 @@ "default_value": 0.04, "minimum_value_warning": "-0.5 * machine_nozzle_size", "maximum_value_warning": "machine_nozzle_size", - "inherit_function": "infill_line_width * parent_value / 100 if infill_sparse_density < 95 else 0" + "value": "infill_line_width * infill_overlap / 100 if infill_sparse_density < 95 else 0" } } }, @@ -667,7 +676,7 @@ "unit": "mm", "type": "float", "default_value": 0.04, - "inherit_function": "wall_line_width_0 / 4 if wall_line_count == 1 else wall_line_width_x / 4", + "value": "wall_line_width_0 / 4 if wall_line_count == 1 else wall_line_width_x / 4", "minimum_value_warning": "0", "maximum_value_warning": "machine_nozzle_size" }, @@ -681,7 +690,7 @@ "minimum_value": "0.0001", "maximum_value_warning": "0.32", "maximum_value": "layer_height * 8", - "inherit_function": "layer_height" + "value": "layer_height" }, "infill_before_walls": { @@ -700,7 +709,8 @@ "type": "category", "children": { - "material_flow_dependent_temperature": { + "material_flow_dependent_temperature": + { "label": "Auto Temperature", "description": "Change the temperature for each layer automatically with the average flow speed of that layer.", "type": "bool", @@ -708,7 +718,8 @@ "enabled": "False", "global_only": true }, - "material_print_temperature": { + "material_print_temperature": + { "label": "Printing Temperature", "description": "The temperature used for printing. Set at 0 to pre-heat the printer manually.", "unit": "°C", @@ -718,14 +729,15 @@ "maximum_value_warning": "260", "enabled": "not (material_flow_dependent_temperature)" }, - "material_flow_temp_graph": { + "material_flow_temp_graph": + { "label": "Flow Temperature Graph", "description": "Data linking material flow (in mm3 per second) to temperature (degrees Celsius).", "unit": "", "type": "str", "default_value": "[[3.5,200],[7.0,240]]", "enabled": "False", - "enabled_before_removal": "material_flow_dependent_temperature", + "comments": "old enabled function: material_flow_dependent_temperature", "global_only": true }, "material_extrusion_cool_down_speed": { @@ -738,7 +750,7 @@ "maximum_value_warning": "10.0", "global_only": "True", "enabled": "False", - "enabled_before_removal": "material_flow_dependent_temperature or machine_extruder_count > 1" + "comments": "old enabled function: material_flow_dependent_temperature or machine_extruder_count > 1" }, "material_bed_temperature": { "label": "Bed Temperature", @@ -786,7 +798,6 @@ "default_value": 6.5, "minimum_value_warning": "-0.0001", "maximum_value_warning": "10.0", - "inherit": false, "enabled": "retraction_enable" }, "retraction_speed": { @@ -798,7 +809,6 @@ "minimum_value": "0", "maximum_value": "299792458000", "maximum_value_warning": "100", - "inherit": false, "enabled": "retraction_enable", "children": { "retraction_retract_speed": { @@ -810,7 +820,8 @@ "minimum_value": "0", "maximum_value": "299792458000", "maximum_value_warning": "100", - "enabled": "retraction_enable" + "enabled": "retraction_enable", + "value": "retraction_speed" }, "retraction_prime_speed": { "label": "Retraction Prime Speed", @@ -821,7 +832,8 @@ "minimum_value": "0", "maximum_value": "299792458000", "maximum_value_warning": "100", - "enabled": "retraction_enable" + "enabled": "retraction_enable", + "value": "retraction_speed" } } }, @@ -833,7 +845,6 @@ "default_value": 0, "minimum_value_warning": "-0.0001", "maximum_value_warning": "5.0", - "inherit": false, "enabled": "retraction_enable" }, "retraction_min_travel": { @@ -842,10 +853,9 @@ "unit": "mm", "type": "float", "default_value": 1.5, - "inherit_function": "line_width * 2", + "value": "line_width * 2", "minimum_value": "0", "maximum_value_warning": "10", - "inherit": false, "enabled": "retraction_enable" }, "retraction_count_max": { @@ -855,7 +865,6 @@ "minimum_value": "0", "maximum_value_warning": "100", "type": "int", - "inherit": false, "enabled": "retraction_enable" }, "retraction_extrusion_window": { @@ -866,7 +875,7 @@ "default_value": 4.5, "minimum_value": "0", "maximum_value_warning": "retraction_amount * 2", - "inherit_function": "retraction_amount", + "value": "retraction_amount", "enabled": "retraction_enable" }, "retraction_hop": { @@ -877,7 +886,6 @@ "default_value": 0, "minimum_value_warning": "-0.0001", "maximum_value_warning": "10", - "inherit": false, "enabled": "retraction_enable" } } @@ -911,7 +919,8 @@ "minimum_value": "0.1", "maximum_value": "299792458000", "maximum_value_warning": "150", - "default_value": 60 + "default_value": 60, + "value": "speed_print" }, "speed_wall": { @@ -923,7 +932,7 @@ "maximum_value": "299792458000", "maximum_value_warning": "150", "default_value": 30, - "inherit_function": "parent_value / 2", + "value": "speed_print / 2", "children": { "speed_wall_0": @@ -935,7 +944,8 @@ "minimum_value": "0.1", "maximum_value": "299792458000", "maximum_value_warning": "150", - "default_value": 30 + "default_value": 30, + "value": "speed_wall" }, "speed_wall_x": { @@ -947,7 +957,7 @@ "maximum_value": "299792458000", "maximum_value_warning": "150", "default_value": 60, - "inherit_function": "parent_value * 2" + "value": "speed_wall * 2" } } }, @@ -961,7 +971,7 @@ "maximum_value": "299792458000", "maximum_value_warning": "150", "default_value": 30, - "inherit_function": "parent_value / 2" + "value": "speed_print / 2" }, "speed_support": { @@ -973,7 +983,7 @@ "maximum_value": "299792458000", "maximum_value_warning": "150", "default_value": 60, - "inherit_function": "speed_print", + "value": "speed_print", "enabled": "support_roof_enable", "children": { @@ -987,7 +997,7 @@ "minimum_value": "0.1", "maximum_value": "299792458000", "maximum_value_warning": "150", - "inherit": true, + "value": "speed_support", "enabled": "support_enable", "global_only": true }, @@ -1002,7 +1012,7 @@ "maximum_value": "299792458000", "maximum_value_warning": "150", "enabled": "support_roof_enable", - "inherit_function": "parent_value / 1.5", + "value": "speed_support / 1.5", "global_only": true } } @@ -1019,7 +1029,7 @@ "minimum_value": "0.1", "maximum_value": "299792458000", "maximum_value_warning": "300", - "inherit_function": "speed_print if magic_spiralize else 120", + "value": "speed_print if magic_spiralize else 120", "global_only": true }, "speed_layer_0": { @@ -1041,7 +1051,7 @@ "minimum_value": "0.1", "maximum_value": "299792458000", "maximum_value_warning": "300", - "inherit_function": "speed_layer_0", + "value": "speed_layer_0", "global_only": true }, "speed_slowdown_layers": @@ -1095,10 +1105,9 @@ "unit": "mm", "type": "float", "default_value": 1.5, - "inherit_function": "machine_nozzle_tip_outer_diameter / 2 * 1.25", + "value": "machine_nozzle_tip_outer_diameter / 2 * 1.25", "minimum_value": "0", "maximum_value_warning": "machine_nozzle_tip_outer_diameter * 5", - "inherit": false, "enabled": "retraction_combing != \"off\" and travel_avoid_other_parts", "global_only": "True" } @@ -1129,7 +1138,7 @@ "minimum_value": "0", "maximum_value": "100", "default_value": 100, - "inherit_function": "100.0 if cool_fan_enabled else 0.0", + "value": "100.0 if cool_fan_enabled else 0.0", "enabled": "cool_fan_enabled", "global_only": "True", "children": @@ -1142,7 +1151,7 @@ "type": "float", "minimum_value": "0", "maximum_value": "100", - "inherit_function": "parent_value", + "value": "cool_fan_speed", "default_value": 100, "enabled": "cool_fan_enabled", "global_only": "True" @@ -1157,7 +1166,8 @@ "maximum_value": "100", "default_value": 100, "enabled": "cool_fan_enabled", - "global_only": "True" + "global_only": "True", + "value": "cool_fan_speed" } } }, @@ -1179,7 +1189,7 @@ "unit": "mm", "type": "float", "default_value": 0.5, - "inherit_function": "layer_height_0", + "value": "layer_height_0", "minimum_value": "0", "maximum_value_warning": "10.0", "global_only": "True", @@ -1193,7 +1203,7 @@ "default_value": 1, "minimum_value": "0", "maximum_value_warning": "100", - "inherit_function": "int((parent_value - layer_height_0 + 0.001) / layer_height) + 1", + "value": "int((cool_fan_full_at_height - layer_height_0 + 0.001) / layer_height) + 1", "global_only": "True" } } @@ -1316,7 +1326,7 @@ "minimum_value": "0", "default_value": 2.66, "enabled": "support_enable", - "inherit_function": "(support_line_width * 100) / parent_value * (2 if support_pattern == \"grid\" else (3 if support_pattern == \"triangles\" else 1))", + "value": "(support_line_width * 100) / support_infill_rate * (2 if support_pattern == \"grid\" else (3 if support_pattern == \"triangles\" else 1))", "global_only": true } } @@ -1354,7 +1364,8 @@ "maximum_value_warning": "10", "default_value": 0.15, "type": "float", - "enabled": "support_enable" + "enabled": "support_enable", + "value": "support_z_distance" }, "support_bottom_distance": { @@ -1364,7 +1375,7 @@ "minimum_value": "0", "maximum_value_warning": "10", "default_value": 0.1, - "inherit_function": "0.1 if support_type == 'everywhere' else 0", + "value": "0.1 if support_type == 'everywhere' else 0", "type": "float", "enabled": "support_enable and support_type == 'everywhere'" } @@ -1454,7 +1465,7 @@ "type": "float", "default_value": 0.4, "minimum_value": "0", - "inherit_function": "0 if parent_value == 0 else (support_roof_line_width * 100) / parent_value * (2 if support_roof_pattern == \"grid\" else (3 if support_roof_pattern == \"triangles\" else 1))", + "value": "0 if support_roof_density == 0 else (support_roof_line_width * 100) / support_roof_density * (2 if support_roof_pattern == \"grid\" else (3 if support_roof_pattern == \"triangles\" else 1))", "enabled": "support_roof_enable", "global_only": true } @@ -1506,7 +1517,6 @@ "minimum_value": "0", "maximum_value_warning": "10", "maximum_value": "support_tower_diameter", - "inherit": true, "enabled": "support_enable and support_use_towers" }, "support_tower_roof_angle": @@ -1601,7 +1611,7 @@ "default_value": 20, "minimum_value": "0", "maximum_value_warning": "300", - "inherit_function": "math.ceil(parent_value / skirt_line_width)", + "value": "math.ceil(brim_width / skirt_line_width)", "enabled": "adhesion_type == \"brim\"", "global_only": "True" } @@ -1676,7 +1686,7 @@ "minimum_value": "0.0001", "maximum_value_warning": "5.0", "enabled": "adhesion_type == \"raft\"", - "inherit_function": "raft_surface_line_width", + "value": "raft_surface_line_width", "global_only": "True" }, "raft_interface_thickness": @@ -1698,7 +1708,7 @@ "unit": "mm", "type": "float", "default_value": 1, - "inherit_function": "line_width", + "value": "line_width", "minimum_value": "0.0001", "maximum_value_warning": "machine_nozzle_size * 2", "enabled": "adhesion_type == \"raft\"", @@ -1736,7 +1746,7 @@ "type": "float", "default_value": 1, "minimum_value": "0.0001", - "inherit_function": "line_width", + "value": "line_width", "maximum_value_warning": "machine_nozzle_size * 2", "enabled": "adhesion_type == \"raft\"", "global_only": "True" @@ -1764,7 +1774,7 @@ "maximum_value": "299792458000", "maximum_value_warning": "200", "enabled": "adhesion_type == \"raft\"", - "inherit_function": "speed_print / 60 * 30", + "value": "speed_print / 60 * 30", "global_only": "True", "children": { @@ -1779,7 +1789,7 @@ "maximum_value": "299792458000", "maximum_value_warning": "100", "enabled": "adhesion_type == \"raft\"", - "inherit_function": "parent_value", + "value": "raft_speed", "global_only": "True" }, "raft_interface_speed": @@ -1793,7 +1803,7 @@ "maximum_value": "299792458000", "maximum_value_warning": "150", "enabled": "adhesion_type == \"raft\"", - "inherit_function": "0.5 * parent_value", + "value": "0.5 * raft_speed", "global_only": "True" }, "raft_base_speed": @@ -1807,7 +1817,7 @@ "maximum_value": "299792458000", "maximum_value_warning": "200", "enabled": "adhesion_type == \"raft\"", - "inherit_function": "0.5 * parent_value", + "value": "0.5 * raft_speed", "global_only": "True" } } @@ -1835,7 +1845,7 @@ "maximum_value": "100", "default_value": 100, "global_only": "True", - "inherit": true, + "value": "raft_fan_speed", "enabled": "adhesion_type == \"raft\"" }, "raft_interface_fan_speed": @@ -1848,7 +1858,7 @@ "maximum_value": "100", "default_value": 100, "global_only": "True", - "inherit": true, + "value": "raft_fan_speed", "enabled": "adhesion_type == \"raft\"" }, "raft_base_fan_speed": @@ -1861,7 +1871,7 @@ "maximum_value": "100", "default_value": 100, "global_only": "True", - "inherit": true, + "value": "raft_fan_speed", "enabled": "adhesion_type == \"raft\"" } } @@ -1950,12 +1960,12 @@ } } }, - "blackmagic": + "experimental": { "label": "Experimental Modes", "type": "category", "icon": "category_blackmagic", - "description": "category_blackmagic", + "description": "experimental!", "children": { "draft_shield_enabled": @@ -2001,7 +2011,7 @@ "minimum_value": "0", "maximum_value_warning": "9999", "default_value": 0, - "inherit_function": "9999 if draft_shield_height_limitation == 'full' and draft_shield_enabled else 0.0", + "value": "9999 if draft_shield_height_limitation == 'full' and draft_shield_enabled else 0.0", "enabled": "draft_shield_height_limitation == \"limited\"", "global_only": true }, @@ -2022,7 +2032,6 @@ "default_value": 0.064, "minimum_value": "0", "maximum_value_warning": "2.0", - "inherit": false, "enabled": "coasting_enable", "global_only": true }, @@ -2047,7 +2056,6 @@ "default_value": 90, "minimum_value": "0.0001", "maximum_value_warning": "100", - "inherit": false, "enabled": "coasting_enable", "global_only": true }, @@ -2143,7 +2151,7 @@ "minimum_value": "magic_fuzzy_skin_thickness / 2", "minimum_value_warning": "0.1", "maximum_value_warning": "10", - "inherit_function": "10000 if parent_value == 0 else 1 / parent_value", + "value": "10000 if parent_value == 0 else 1 / magic_fuzzy_skin_point_density", "enabled": "magic_fuzzy_skin_enabled" } } @@ -2179,7 +2187,7 @@ "minimum_value_warning": "machine_nozzle_size", "maximum_value_warning": "20", "enabled": "wireframe_enabled", - "inherit_function": "wireframe_height", + "value": "wireframe_height", "global_only": "True" }, "wireframe_printspeed": @@ -2207,7 +2215,8 @@ "maximum_value": "299792458000", "maximum_value_warning": "50", "enabled": "wireframe_enabled", - "global_only": "True" + "global_only": "True", + "value": "wireframe_printspeed" }, "wireframe_printspeed_up": { @@ -2220,7 +2229,8 @@ "maximum_value": "299792458000", "maximum_value_warning": "50", "enabled": "wireframe_enabled", - "global_only": "True" + "global_only": "True", + "value": "wireframe_printspeed" }, "wireframe_printspeed_down": { @@ -2233,7 +2243,8 @@ "maximum_value": "299792458000", "maximum_value_warning": "50", "enabled": "wireframe_enabled", - "global_only": "True" + "global_only": "True", + "value": "wireframe_printspeed" }, "wireframe_printspeed_flat": { @@ -2245,7 +2256,7 @@ "minimum_value": "0.1", "maximum_value": "299792458000", "maximum_value_warning": "100", - "inherit": true, + "value": "wireframe_printspeed", "enabled": "wireframe_enabled", "global_only": "True" } @@ -2274,7 +2285,8 @@ "maximum_value_warning": "100", "type": "float", "enabled": "wireframe_enabled", - "global_only": "True" + "global_only": "True", + "value": "wireframe_flow" }, "wireframe_flow_flat": { @@ -2286,7 +2298,8 @@ "maximum_value_warning": "100", "type": "float", "enabled": "wireframe_enabled", - "global_only": "True" + "global_only": "True", + "value": "wireframe_flow" } } }, From 44246c0676e8d432eb53e27157197b14a59526dc Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 9 May 2016 12:06:11 +0200 Subject: [PATCH 006/705] Comment out all things that use settings related things so we can at least start --- cura/CuraApplication.py | 8 ++++---- plugins/CuraEngineBackend/CuraEngineBackend.py | 10 +++++----- resources/qml/Cura.qml | 6 +++--- resources/qml/ProfileSetup.qml | 2 +- resources/qml/SidebarHeader.qml | 6 +++--- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 2a22b624a9..1f83cd1f3d 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -101,8 +101,8 @@ class CuraApplication(QtApplication): self._camera_animation = None self._cura_actions = None - self.getMachineManager().activeMachineInstanceChanged.connect(self._onActiveMachineChanged) - self.getMachineManager().addMachineRequested.connect(self._onAddMachineRequested) + #self.getMachineManager().activeMachineInstanceChanged.connect(self._onActiveMachineChanged) + #self.getMachineManager().addMachineRequested.connect(self._onAddMachineRequested) self.getController().getScene().sceneChanged.connect(self.updatePlatformActivity) self.getController().toolOperationStopped.connect(self._onToolOperationStopped) @@ -175,9 +175,9 @@ class CuraApplication(QtApplication): Selection.selectionChanged.connect(self.onSelectionChanged) root = controller.getScene().getRoot() - self._platform = Platform(root) + #self._platform = Platform(root) - self._volume = BuildVolume.BuildVolume(root) + #self._volume = BuildVolume.BuildVolume(root) self.getRenderer().setBackgroundColor(QColor(245, 245, 245)) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 7a5d332d9e..5102427823 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -52,11 +52,11 @@ class CuraEngineBackend(Backend): # When there are current settings and machine instance is changed, there is no profile changed event. We should # pretend there is though. - Application.getInstance().getMachineManager().activeMachineInstanceChanged.connect(self._onActiveProfileChanged) + #Application.getInstance().getMachineManager().activeMachineInstanceChanged.connect(self._onActiveProfileChanged) - self._profile = None - Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onActiveProfileChanged) - self._onActiveProfileChanged() + #self._profile = None + #Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onActiveProfileChanged) + #self._onActiveProfileChanged() self._change_timer = QTimer() self._change_timer.setInterval(500) @@ -84,7 +84,7 @@ class CuraEngineBackend(Backend): Application.getInstance().getController().toolOperationStarted.connect(self._onToolOperationStarted) Application.getInstance().getController().toolOperationStopped.connect(self._onToolOperationStopped) - Application.getInstance().getMachineManager().activeMachineInstanceChanged.connect(self._onInstanceChanged) + #Application.getInstance().getMachineManager().activeMachineInstanceChanged.connect(self._onInstanceChanged) def close(self): # Terminate CuraEngine if it is still running at this point diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 1759eabfc6..cdff5fc9ab 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -168,7 +168,7 @@ UM.MainWindow Instantiator { - model: UM.MachineInstancesModel { } +// model: UM.MachineInstancesModel { } MenuItem { text: model.name; @@ -187,7 +187,7 @@ UM.MainWindow Instantiator { - model: UM.MachineVariantsModel { } +// model: UM.MachineVariantsModel { } MenuItem { text: model.name; checkable: true; @@ -215,7 +215,7 @@ UM.MainWindow Instantiator { id: profileMenuInstantiator - model: UM.ProfilesModel {} +// model: UM.ProfilesModel {} property int separatorIndex: -1 Loader { diff --git a/resources/qml/ProfileSetup.qml b/resources/qml/ProfileSetup.qml index d6ff042a44..24668f43b0 100644 --- a/resources/qml/ProfileSetup.qml +++ b/resources/qml/ProfileSetup.qml @@ -56,7 +56,7 @@ Item{ Instantiator { id: profileSelectionInstantiator - model: UM.ProfilesModel {} +// model: UM.ProfilesModel {} property int separatorIndex: -1 Loader { diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index b5fcc880f6..1c17233acb 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -71,7 +71,7 @@ Item id: machineSelectionMenu Instantiator { - model: UM.MachineInstancesModel { } +// model: UM.MachineInstancesModel { } MenuItem { text: model.name; @@ -139,7 +139,7 @@ Item Instantiator { id: variantSelectionInstantiator - model: UM.MachineVariantsModel { id: variantsModel } +// model: UM.MachineVariantsModel { id: variantsModel } MenuItem { text: model.name; @@ -183,7 +183,7 @@ Item Instantiator { id: materialSelectionInstantiator - model: UM.MachineMaterialsModel { id: machineMaterialsModel } +// model: UM.MachineMaterialsModel { id: machineMaterialsModel } MenuItem { text: model.name; From 38492cb2304b1f84620701d60ad276655076c43c Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 9 May 2016 12:06:35 +0200 Subject: [PATCH 007/705] Update API version of two required plugins --- plugins/CuraEngineBackend/__init__.py | 2 +- plugins/SolidView/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/CuraEngineBackend/__init__.py b/plugins/CuraEngineBackend/__init__.py index 86a53d3ada..2e652ae845 100644 --- a/plugins/CuraEngineBackend/__init__.py +++ b/plugins/CuraEngineBackend/__init__.py @@ -13,7 +13,7 @@ def getMetaData(): "name": catalog.i18nc("@label", "CuraEngine Backend"), "author": "Ultimaker", "description": catalog.i18nc("@info:whatsthis", "Provides the link to the CuraEngine slicing backend."), - "api": 2 + "api": 3 } } diff --git a/plugins/SolidView/__init__.py b/plugins/SolidView/__init__.py index 0317648e6e..945ccba8f6 100644 --- a/plugins/SolidView/__init__.py +++ b/plugins/SolidView/__init__.py @@ -13,7 +13,7 @@ def getMetaData(): "author": "Ultimaker", "version": "1.0", "description": i18n_catalog.i18nc("@info:whatsthis", "Provides a normal solid mesh view."), - "api": 2 + "api": 3 }, "view": { "name": i18n_catalog.i18nc("@item:inmenu", "Solid"), From 2f54e3554ad446d1715a29c397b5b57aa73d2711 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Mon, 9 May 2016 11:36:43 +0200 Subject: [PATCH 008/705] When trying to exit the application, forcefully shutdown the backend exe. Fixes CURA-1453 Cura in slicing loop (Arcus Error (6, native 54)) --- plugins/CuraEngineBackend/CuraEngineBackend.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 09817aa995..e3f9a4542e 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -103,6 +103,9 @@ class CuraEngineBackend(Backend): return [Preferences.getInstance().getValue("backend/location"), "connect", "127.0.0.1:{0}".format(self._port), "-j", json_path, "-vv"] + def close(self): + self._terminate() # Forcefully shutdown the backend. + ## Emitted when we get a message containing print duration and material amount. This also implies the slicing has finished. # \param time The amount of time the print will take. # \param material_amount The amount of material the print will use. From 1b9c29579b6febbc8281d833698cef27f8c06606 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 9 May 2016 14:55:01 +0200 Subject: [PATCH 009/705] Reworked add machine (Still stub) CURA-1278 --- resources/qml/AddMachineDialog.qml | 165 +++++++++++++++++++++++++++++ resources/qml/Cura.qml | 14 +-- 2 files changed, 172 insertions(+), 7 deletions(-) create mode 100644 resources/qml/AddMachineDialog.qml diff --git a/resources/qml/AddMachineDialog.qml b/resources/qml/AddMachineDialog.qml new file mode 100644 index 0000000000..c6e852aa3e --- /dev/null +++ b/resources/qml/AddMachineDialog.qml @@ -0,0 +1,165 @@ +// Copyright (c) 2016 Ultimaker B.V. +// Cura is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.1 +import QtQuick.Layouts 1.1 +import QtQuick.Window 2.1 + +import QtQuick.Controls.Styles 1.1 + +import UM 1.1 as UM +import Cura 1.0 as Cura + + +UM.Dialog +{ + id: base + title: catalog.i18nc("@title:window", "Add Printer") + property string activeManufacturer: "Ultimaker"; + + function getMachineName() + { + var name = machineList.model.getItem(machineList.currentIndex).name + return name + } + + ScrollView + { + id: machinesHolder + + anchors + { + left: parent.left; + top: parent.top; + right: parent.right; + bottom: parent.bottom; + } + ListView + { + id: machineList + + model: UM.DefinitionContainersModel + { + id: machineDefinitionsModel + filter: {"visible":true} + } + section.property: "manufacturer" + section.delegate: Button + { + text: section + style: ButtonStyle + { + background: Rectangle + { + border.width: 0 + color: "transparent"; + height: UM.Theme.getSize("standard_list_lineheight").height + width: machineList.width + } + label: Label + { + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("standard_arrow").width + UM.Theme.getSize("default_margin").width + text: control.text + color: palette.windowText + font.bold: true + UM.RecolorImage + { + id: downArrow + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.left + anchors.rightMargin: UM.Theme.getSize("default_margin").width + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width + sourceSize.height: width + color: palette.windowText + source: base.activeManufacturer == section ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_right") + } + } + } + + onClicked: + { + base.activeManufacturer = section; + machineList.currentIndex = machineList.model.find("manufacturer", section) + machineName.text = getMachineName() + } + } + + delegate: RadioButton + { + id: machineButton + + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("standard_list_lineheight").width + + opacity: 1; + height: UM.Theme.getSize("standard_list_lineheight").height; + + checked: ListView.isCurrentItem; + + exclusiveGroup: printerGroup; + + text: model.name + + onClicked: + { + ListView.view.currentIndex = index; + machineName.text = getMachineName() + } + + states: State + { + name: "collapsed"; + when: base.activeManufacturer != model.manufacturer; + + PropertyChanges { target: machineButton; opacity: 0; height: 0; } + } + + transitions: + [ + Transition + { + to: "collapsed"; + SequentialAnimation + { + NumberAnimation { property: "opacity"; duration: 75; } + NumberAnimation { property: "height"; duration: 75; } + } + }, + Transition + { + from: "collapsed"; + SequentialAnimation + { + NumberAnimation { property: "height"; duration: 75; } + NumberAnimation { property: "opacity"; duration: 75; } + } + } + ] + } + } + } + + TextField + { + id: machineName; + text: getMachineName() + implicitWidth: UM.Theme.getSize("standard_list_input").width + maximumLength: 40 + anchors.bottom:parent.bottom + } + + Item + { + UM.I18nCatalog + { + id: catalog; + name: "cura"; + } + SystemPalette { id: palette } + ExclusiveGroup { id: printerGroup; } + } +} \ No newline at end of file diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index cdff5fc9ab..e39cd733d9 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -626,7 +626,7 @@ UM.MainWindow resetAll.onTriggered: Printer.resetAll(); reloadAll.onTriggered: Printer.reloadAll(); - addMachine.onTriggered: addMachineWizard.visible = true; + addMachine.onTriggered: addMachineDialog.visible = true; addProfile.onTriggered: { UM.MachineManager.createProfile(); @@ -742,9 +742,9 @@ UM.MainWindow id: engineLog; } - AddMachineWizard + AddMachineDialog { - id: addMachineWizard + id: addMachineDialog } AboutDialog @@ -757,8 +757,8 @@ UM.MainWindow target: Printer onRequestAddPrinter: { - addMachineWizard.visible = true - addMachineWizard.firstRun = false + addMachineDialog.visible = true + addMachineDialog.firstRun = false } } @@ -777,8 +777,8 @@ UM.MainWindow } else if(UM.MachineManager.activeMachineInstance == "") { - addMachineWizard.firstRun = true; - addMachineWizard.open(); + addMachineDialog.firstRun = true; + addMachineDialog.open(); } } } From 0049ee13777f3e61a6b03f9f818f657f6b6fa902 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 9 May 2016 15:42:47 +0200 Subject: [PATCH 010/705] SolidView now uses activeContainerStack CURA-1278 --- plugins/SolidView/SolidView.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 8719e9c6e4..561d194dd3 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -34,12 +34,11 @@ class SolidView(View): self._disabled_shader.setUniformValue("u_diffuseColor", [0.68, 0.68, 0.68, 1.0]) self._disabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0))) - if Application.getInstance().getMachineManager().getWorkingProfile(): - profile = Application.getInstance().getMachineManager().getWorkingProfile() + if Application.getInstance().getActiveContainerStack(): if Preferences.getInstance().getValue("view/show_overhang"): - angle = profile.getSettingValue("support_angle") - if angle != None: + angle = Application.getInstance().getActiveContainerStack().getValue("support_angle") + if angle is not None: self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(90 - angle))) else: self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0))) #Overhang angle of 0 causes no area at all to be marked as overhang. From 293fd5e80d4fdde9a61506d7dc0927a33e2377e6 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 9 May 2016 15:44:04 +0200 Subject: [PATCH 011/705] Moved fdmprinter.def.json to definitions folder CURA-1278 --- resources/definitions/fdmprinter.def.json | 2468 +++++++++++++++++++++ 1 file changed, 2468 insertions(+) create mode 100644 resources/definitions/fdmprinter.def.json diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json new file mode 100644 index 0000000000..cf92aa847f --- /dev/null +++ b/resources/definitions/fdmprinter.def.json @@ -0,0 +1,2468 @@ +{ + "id": "fdmprinter", + "version": 2, + "metadata": + { + "category": "Ultimaker", + "manufacturer": "Ultimaker", + "visible": false + }, + "name": "FDM Printer Base Description", + "author": "Ultimaker B.V.", + "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g", + "settings": + { + "machine_settings": + { + "label": "Machine", + "type": "category", + "description": "Machine specific settings", + "children": + { + "machine_show_variants": + { + "description": "Whether to show the different variants of this machine, which are described in separate json files.", + "default_value": false, + "type": "bool", + "label": "Show machine variants" + }, + "machine_start_gcode": + { + "description": "Gcode commands to be executed at the very start - separated by \\n.", + "default_value": "G28 ;Home\nG1 Z15.0 F6000 ;Move the platform down 15mm\n;Prime the extruder\nG92 E0\nG1 F200 E3\nG92 E0", + "label": "Start GCode", + "global_only": true, + "type": "str" + }, + "machine_end_gcode": + { + "description": "Gcode commands to be executed at the very end - separated by \\n.", + "default_value": "M104 S0\nM140 S0\n;Retract the filament\nG92 E1\nG1 E-1 F300\nG28 X0 Y0\nM84", + "label": "End GCode", + "global_only": true, + "type": "str" + }, + "material_bed_temp_wait": + { + "description": "Whether to insert a command to wait until the bed temperature is reached at the start.", + "label": "Wait for bed heatup", + "default_value": true, + "global_only": true, + "type": "bool" + }, + "material_print_temp_prepend": + { + "description": "Whether to include nozzle temperature commands at the start of the gcode. When the start_gcode already contains nozzle temperature commands Cura frontend will automatically disable this setting.", + "default_value": true, + "global_only": true, + "type": "bool", + "label": "Wait for material heatup" + }, + "machine_width": + { + "description": "The width (X-direction) of the printable area.", + "default_value": 100, + "global_only": true, + "type": "float", + "label": "Machine width" + }, + "machine_depth": + { + "description": "The depth (Y-direction) of the printable area.", + "default_value": 100, + "global_only": true, + "type": "float", + "label": "Machine depth" + }, + "machine_height": + { + "description": "The height (Z-direction) of the printable area.", + "default_value": 100, + "global_only": true, + "type": "float", + "label": "Machine height" + }, + "machine_heated_bed": + { + "description": "Whether the machine has a heated bed present.", + "default_value": false, + "global_only": true, + "label": "Has heated bed", + "type": "bool" + }, + "machine_center_is_zero": + { + "description": "Whether the X/Y coordinates of the zero position of the printer is at the center of the printable area.", + "default_value": false, + "global_only": true, + "type": "bool", + "label": "Is center origin" + }, + "machine_extruder_count": + { + "description": "Number of extruder trains. An extruder train is the combination of a feeder, bowden tube, and nozzle.", + "default_value": 1, + "global_only": true, + "type": "bool", + "label": "Number extruders" + }, + "machine_nozzle_tip_outer_diameter": + { + "description": "The outer diameter of the tip of the nozzle.", + "label": "Outer nozzle diameter", + "default_value": 1, + "global_only": true, + "type": "float" + }, + "machine_nozzle_head_distance": + { + "description": "The height difference between the tip of the nozzle and the lowest part of the print head.", + "default_value": 3, + "global_only": true, + "type": "float", + "label": "Nozzle length" + }, + "machine_nozzle_expansion_angle": + { + "description": "The angle between the horizontal plane and the conical part right above the tip of the nozzle.", + "default_value": 45, + "global_only": true, + "type": "int", + "label": "Nozzle angle" + }, + "machine_heat_zone_length": + { + "description": "The distance from the tip of the nozzle in which heat from the nozzle is transfered to the filament.", + "default_value": 16, + "global_only": true, + "type": "float", + "label": "Heat zone length" + }, + "machine_nozzle_heat_up_speed": + { + "description": "The speed (°C/s) by which the nozzle heats up averaged over the window of normal printing temperatures and the standby temperature.", + "default_value": 2.0, + "global_only": true, + "type": "float", + "label": "Heat up speed" + }, + "machine_nozzle_cool_down_speed": + { + "description": "The speed (°C/s) by which the nozzle cools down averaged over the window of normal printing temperatures and the standby temperature.", + "default_value": 2.0, + "global_only": true, + "type": "float", + "label": "Cool down speed" + }, + "machine_gcode_flavor": + { + "description": "The type of gcode to be generated.", + "default_value": "RepRap", + "global_only": true, + "type": "str", + "label": "Gcode flavour" + }, + "machine_disallowed_areas": + { + "description": "A list of polygons with areas the print head is not allowed to enter.", + "type": "polygons", + "default_value": [], + "global_only": true, + "label": "Disallowed areas" + }, + "machine_head_polygon": + { + "description": "A 2D silhouette of the print head (fan caps excluded).", + "type": "polygon", + "default_value": + [ + [ + -1, + 1 + ], + [ + -1, + -1 + ], + [ + 1, + -1 + ], + [ + 1, + 1 + ] + ], + "global_only": true, + "label": "Machine head polygon" + }, + "machine_head_with_fans_polygon": + { + "description": "A 2D silhouette of the print head (fan caps included).", + "type": "polygon", + "default_value": + [ + [ + -20, + 10 + ], + [ + 10, + 10 + ], + [ + 10, + -10 + ], + [ + -20, + -10 + ] + ], + "global_only": true, + "label": "Machine head & Fan polygon" + }, + "gantry_height": + { + "description": "The height difference between the tip of the nozzle and the gantry system (X and Y axes).", + "default_value": 99999999999, + "global_only": true, + "label": "Gantry height", + "type": "float" + }, + "machine_nozzle_size": + { + "label": "Nozzle Diameter", + "description": "The inner diameter of the nozzle. Change this setting when using a non-standard nozzle size.", + "unit": "mm", + "type": "float", + "default_value": 0.4, + "minimum_value": "0.001", + "maximum_value_warning": "10" + } + } + }, + "resolution": + { + "label": "Quality", + "type": "category", + "icon": "category_layer_height", + "description": "All settings that influence the resolution of the print. These settings have a large impact on the quality (and print time)", + "children": + { + "layer_height": + { + "label": "Layer Height", + "description": "The height of each layer in mm. Higher values produce faster prints in lower resolution, lower values produce slower prints in higher resolution.", + "unit": "mm", + "type": "float", + "default_value": 0.1, + "minimum_value": "0.001", + "minimum_value_warning": "0.04", + "maximum_value_warning": "0.8 * machine_nozzle_size", + "global_only": "True" + }, + "layer_height_0": + { + "label": "Initial Layer Height", + "description": "The height of the initial layer in mm. A thicker initial layer makes adhesion to the build plate easier.", + "unit": "mm", + "type": "float", + "default_value": 0.3, + "minimum_value": "0.001", + "minimum_value_warning": "0.04", + "maximum_value_warning": "0.8 * machine_nozzle_size", + "global_only": "True" + }, + "line_width": + { + "label": "Line Width", + "description": "Width of a single line. Generally, the width of each line should correspond to the width of the nozzle. However, slightly reducing this value could produce better prints.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "2 * machine_nozzle_size", + "default_value": 0.4, + "type": "float", + "value": "machine_nozzle_size", + "children": + { + "wall_line_width": + { + "label": "Wall Line Width", + "description": "Width of a single wall line.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "value":"line_width", + "default_value": 0.4, + "type": "float", + "children": + { + "wall_line_width_0": + { + "label": "Outer Wall Line Width", + "description": "Width of the outermost wall line. By lowering this value, higher levels of detail can be printed.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "default_value": 0.4, + "value":"wall_line_width", + "type": "float" + }, + "wall_line_width_x": + { + "label": "Inner Wall(s) Line Width", + "description": "Width of a single wall line for all wall lines except the outermost one.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "default_value": 0.4, + "value":"wall_line_width", + "type": "float" + } + } + }, + "skin_line_width": + { + "label": "Top/bottom Line Width", + "description": "Width of a single top/bottom line.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "default_value": 0.4, + "type": "float", + "value": "line_width" + }, + "infill_line_width": + { + "label": "Infill Line Width", + "description": "Width of a single infill line.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "default_value": 0.4, + "type": "float", + "value": "line_width" + }, + "skirt_line_width": + { + "label": "Skirt Line Width", + "description": "Width of a single skirt line.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "default_value": 0.4, + "type": "float", + "global_only": true, + "value": "line_width" + }, + "support_line_width": + { + "label": "Support Line Width", + "description": "Width of a single support structure line.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "default_value": 0.4, + "type": "float", + "enabled": "support_enable", + "global_only": true, + "value": "line_width" + }, + "support_roof_line_width": + { + "label": "Support Roof Line Width", + "description": "Width of a single support roof line.", + "unit": "mm", + "default_value": 0.4, + "minimum_value": "0.0001", + "maximum_value_warning": "machine_nozzle_size * 2", + "type": "float", + "enabled": "support_roof_enable", + "global_only": true, + "value": "line_width" + } + } + } + } + }, + "shell": + { + "label": "Shell", + "icon": "category_shell", + "description": "Shell", + "type": "category", + "children": + { + "wall_thickness": + { + "label": "Wall Thickness", + "description": "The thickness of the outside walls in the horizontal direction. This value divided by the wall line width defines the number of walls.", + "unit": "mm", + "default_value": 0.8, + "minimum_value": "0", + "minimum_value_warning": "line_width", + "maximum_value_warning": "5 * line_width", + "type": "float", + "children": + { + "wall_line_count": + { + "label": "Wall Line Count", + "description": "The number of walls. When calculated by the wall thickness, this value is rounded to a whole number.", + "default_value": 2, + "minimum_value": "0", + "type": "int", + "value": "1 if magic_spiralize else max(1, round((wall_thickness - wall_line_width_0) / wall_line_width_x) + 1)" + } + } + }, + "top_bottom_thickness": + { + "label": "Top/Bottom Thickness", + "description": "The thickness of the top/bottom layers in the print. This value divided by the layer height defines the number of top/bottom layers.", + "unit": "mm", + "default_value": 0.8, + "minimum_value": "0", + "maximum_value": "5", + "minimum_value_warning": "0.6", + "type": "float", + "children": + { + "top_thickness": + { + "label": "Top Thickness", + "description": "The thickness of the top layers in the print. This value divided by the layer height defines the number of top layers.", + "unit": "mm", + "default_value": 0.8, + "minimum_value": "0", + "maximum_value_warning": "100", + "type": "float", + "value": "top_bottom_thickness", + "children": + { + "top_layers": + { + "label": "Top Layers", + "description": "The number of top layers. When calculated by the top thickness, this value is rounded to a whole number.", + "default_value": 8, + "minimum_value": "0", + "maximum_value_warning": "100", + "type": "int", + "value": "0 if infill_sparse_density == 100 else math.ceil(round(parent_value / layer_height, 4))" + } + } + }, + "bottom_thickness": + { + "label": "Bottom Thickness", + "description": "The thickness of the bottom layers in the print. This value divided by the layer height defines the number of bottom layers.", + "unit": "mm", + "default_value": 0.6, + "minimum_value": "0", + "type": "float", + "value": "top_bottom_thickness", + "children": + { + "bottom_layers": + { + "label": "Bottom Layers", + "description": "The number of bottom layers. When calculated by the bottom thickness, this value is rounded to a whole number.", + "minimum_value": "0", + "default_value": 6, + "type": "int", + "value": "999999 if infill_sparse_density == 100 else math.ceil(round(parent_value / layer_height, 4))" + } + } + } + } + }, + "top_bottom_pattern": + { + "label": "Top/Bottom Pattern", + "description": "The pattern of the top/bottom layers.", + "type": "enum", + "options": + { + "lines": "Lines", + "concentric": "Concentric", + "zigzag": "Zig Zag" + }, + "default_value": "lines" + }, + "wall_0_inset": + { + "label": "Outer Wall Inset", + "description": "Inset applied to the path of the outer wall. If the outer wall is smaller than the nozzle, and printed after the inner walls, use this offset to get the hole in the nozzle to overlap with the inner walls instead of the outside of the object.", + "unit": "mm", + "type": "float", + "default_value": 0.0, + "value": "(machine_nozzle_size - wall_line_width_0) / 2 if wall_line_width_0 < machine_nozzle_size else 0", + "minimum_value_warning": "0", + "maximum_value_warning": "machine_nozzle_size" + }, + "alternate_extra_perimeter": + { + "label": "Alternate Extra Wall", + "description": "Prints an extra wall at every other layer. This way infill gets caught between these extra walls, resulting in stronger prints.", + "type": "bool", + "default_value": false + }, + "remove_overlapping_walls_enabled": + { + "label": "Remove Overlapping Wall Parts", + "description": "Remove parts of a wall which share an overlap which would result in overextrusion in some places. These overlaps occur in thin parts and sharp corners in models.", + "type": "bool", + "default_value": false, + "enabled": "False", + "children": + { + "remove_overlapping_walls_0_enabled": + { + "label": "Remove Overlapping Outer Wall Parts", + "description": "Remove parts of an outer wall which share an overlap which would result in overextrusion in some places. These overlaps occur in thin pieces in a model and sharp corners.", + "type": "bool", + "default_value": false, + "value": "remove_overlapping_walls_enabled", + "enabled": "False" + }, + "remove_overlapping_walls_x_enabled": + { + "label": "Remove Overlapping Inner Wall Parts", + "description": "Remove parts of an inner wall that would otherwise overlap and cause over-extrusion. These overlaps occur in thin pieces in a model and sharp corners.", + "type": "bool", + "default_value": true, + "value": "remove_overlapping_walls_enabled" + } + } + }, + "fill_perimeter_gaps": + { + "label": "Fill Gaps Between Walls", + "description": "Fills the gaps between walls when overlapping inner wall parts are removed.", + "type": "enum", + "options": + { + "nowhere": "Nowhere", + "everywhere": "Everywhere", + "skin": "Skin" + }, + "default_value": "everywhere", + "enabled": "remove_overlapping_walls_x_enabled" + }, + "travel_compensate_overlapping_walls_enabled": + { + "label": "Compensate Wall Overlaps", + "description": "Compensate the flow for parts of a wall being printed where there is already a wall in place.", + "type": "bool", + "default_value": true + }, + "xy_offset": + { + "label": "Horizontal Expansion", + "description": "Amount of offset applied to all polygons in each layer. Positive values can compensate for too big holes; negative values can compensate for too small holes.", + "unit": "mm", + "type": "float", + "minimum_value_warning": "-10", + "maximum_value_warning": "10", + "default_value": 0 + }, + "z_seam_type": + { + "label": "Z Seam Alignment", + "description": "Starting point of each path in a layer. When paths in consecutive layers start at the same point a vertical seam may show on the print. When aligning these at the back, the seam is easiest to remove. When placed randomly the inaccuracies at the paths' start will be less noticeable. When taking the shortest path the print will be quicker.", + "type": "enum", + "options": + { + "back": "Back", + "shortest": "Shortest", + "random": "Random" + }, + "default_value": "shortest" + }, + "skin_no_small_gaps_heuristic": + { + "label": "Ignore Small Z Gaps", + "description": "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such case, disable the setting.", + "type": "bool", + "default_value": true + } + } + }, + "infill": + { + "label": "Infill", + "icon": "category_infill", + "description": "Infill", + "type": "category", + "children": + { + "infill_sparse_density": + { + "label": "Infill Density", + "description": "Adjusts the density of infill of the print.", + "unit": "%", + "type": "float", + "default_value": 20, + "minimum_value": "0", + "maximum_value_warning": "100", + "children": + { + "infill_line_distance": + { + "label": "Infill Line Distance", + "description": "Distance between the printed infill lines. This setting is calculated by the infill density and the infill line width.", + "unit": "mm", + "type": "float", + "default_value": 2, + "minimum_value": "0", + "value": "0 if infill_sparse_density == 0 else (infill_line_width * 100) / infill_sparse_density * (2 if infill_pattern == \"grid\" else (3 if infill_pattern == \"triangles\" else 1))" + } + } + }, + "infill_pattern": + { + "label": "Infill Pattern", + "description": "The pattern of the infill material of the print. The line and zig zag infill swap direction on alternate layers, reducing material cost. The grid, triangle and concentric patterns are fully printed every layer.", + "type": "enum", + "options": + { + "grid": "Grid", + "lines": "Lines", + "triangles": "Triangles", + "concentric": "Concentric", + "zigzag": "Zig Zag" + }, + "default_value": "grid", + "value": "'lines' if infill_sparse_density > 25 else 'grid'" + }, + "infill_overlap": + { + "label": "Infill Overlap Percentage", + "description": "The amount of overlap between the infill and the walls. A slight overlap allows the walls to connect firmly to the infill.", + "unit": "%", + "type": "float", + "default_value": 10, + "value": "10 if infill_sparse_density < 95 else 0", + "minimum_value_warning": "-50", + "maximum_value_warning": "100", + "children": + { + "infill_overlap_mm": + { + "label": "Infill Overlap", + "description": "The amount of overlap between the infill and the walls. A slight overlap allows the walls to connect firmly to the infill.", + "unit": "mm", + "type": "float", + "default_value": 0.04, + "minimum_value_warning": "-0.5 * machine_nozzle_size", + "maximum_value_warning": "machine_nozzle_size", + "value": "infill_line_width * infill_overlap / 100 if infill_sparse_density < 95 else 0" + } + } + }, + "infill_wipe_dist": + { + "label": "Infill Wipe Distance", + "description": "Distance of a travel move inserted after every infill line, to make the infill stick to the walls better. This option is similar to infill overlap, but without extrusion and only on one end of the infill line.", + "unit": "mm", + "type": "float", + "default_value": 0.04, + "value": "wall_line_width_0 / 4 if wall_line_count == 1 else wall_line_width_x / 4", + "minimum_value_warning": "0", + "maximum_value_warning": "machine_nozzle_size" + }, + "infill_sparse_thickness": + { + "label": "Infill Layer Thickness", + "description": "The thickness per layer of infill material. This value should always be a multiple of the layer height and is otherwise rounded.", + "unit": "mm", + "type": "float", + "default_value": 0.1, + "minimum_value": "0.0001", + "maximum_value_warning": "0.32", + "maximum_value": "layer_height * 8", + "value": "layer_height" + }, + "infill_before_walls": + { + "label": "Infill Before Walls", + "description": "Print the infill before printing the walls. Printing the walls first may lead to more accurate walls, but overhangs print worse. Printing the infill first leads to sturdier walls, but the infill pattern might sometimes show through the surface.", + "type": "bool", + "default_value": true + } + } + }, + "material": + { + "label": "Material", + "icon": "category_material", + "description": "Material", + "type": "category", + "children": + { + "material_flow_dependent_temperature": + { + "label": "Auto Temperature", + "description": "Change the temperature for each layer automatically with the average flow speed of that layer.", + "type": "bool", + "default_value": false, + "enabled": "False", + "global_only": true + }, + "material_print_temperature": + { + "label": "Printing Temperature", + "description": "The temperature used for printing. Set at 0 to pre-heat the printer manually.", + "unit": "°C", + "type": "float", + "default_value": 210, + "minimum_value": "0", + "maximum_value_warning": "260", + "enabled": "not (material_flow_dependent_temperature)" + }, + "material_flow_temp_graph": + { + "label": "Flow Temperature Graph", + "description": "Data linking material flow (in mm3 per second) to temperature (degrees Celsius).", + "unit": "", + "type": "str", + "default_value": "[[3.5,200],[7.0,240]]", + "enabled": "False", + "comments": "old enabled function: material_flow_dependent_temperature", + "global_only": true + }, + "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", + "type": "float", + "default_value": 0.5, + "minimum_value": "0", + "maximum_value_warning": "10.0", + "global_only": "True", + "enabled": "False", + "comments": "old enabled function: material_flow_dependent_temperature or machine_extruder_count > 1" + }, + "material_bed_temperature": { + "label": "Bed Temperature", + "description": "The temperature used for the heated bed. Set at 0 to pre-heat the printer manually.", + "unit": "°C", + "type": "float", + "default_value": 60, + "minimum_value": "0", + "maximum_value_warning": "260", + "enabled": "machine_heated_bed", + "global_only": "True" + }, + "material_diameter": { + "label": "Diameter", + "description": "Adjusts the diameter of the filament used. Match this value with the diameter of the used filament.", + "unit": "mm", + "type": "float", + "default_value": 2.85, + "minimum_value": "0.0001", + "minimum_value_warning": "0.4", + "maximum_value_warning": "3.5", + "global_only": "True" + }, + "material_flow": { + "label": "Flow", + "description": "Flow compensation: the amount of material extruded is multiplied by this value.", + "unit": "%", + "default_value": 100, + "type": "float", + "minimum_value": "5", + "minimum_value_warning": "50", + "maximum_value_warning": "150" + }, + "retraction_enable": { + "label": "Enable Retraction", + "description": "Retract the filament when the nozzle is moving over a non-printed area. ", + "type": "bool", + "default_value": true + }, + "retraction_amount": { + "label": "Retraction Distance", + "description": "The length of material retracted during a retraction move.", + "unit": "mm", + "type": "float", + "default_value": 6.5, + "minimum_value_warning": "-0.0001", + "maximum_value_warning": "10.0", + "enabled": "retraction_enable" + }, + "retraction_speed": { + "label": "Retraction Speed", + "description": "The speed at which the filament is retracted and primed during a retraction move.", + "unit": "mm/s", + "type": "float", + "default_value": 25, + "minimum_value": "0", + "maximum_value": "299792458000", + "maximum_value_warning": "100", + "enabled": "retraction_enable", + "children": { + "retraction_retract_speed": { + "label": "Retraction Retract Speed", + "description": "The speed at which the filament is retracted during a retraction move.", + "unit": "mm/s", + "type": "float", + "default_value": 25, + "minimum_value": "0", + "maximum_value": "299792458000", + "maximum_value_warning": "100", + "enabled": "retraction_enable", + "value": "retraction_speed" + }, + "retraction_prime_speed": { + "label": "Retraction Prime Speed", + "description": "The speed at which the filament is primed during a retraction move.", + "unit": "mm/s", + "type": "float", + "default_value": 25, + "minimum_value": "0", + "maximum_value": "299792458000", + "maximum_value_warning": "100", + "enabled": "retraction_enable", + "value": "retraction_speed" + } + } + }, + "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³", + "type": "float", + "default_value": 0, + "minimum_value_warning": "-0.0001", + "maximum_value_warning": "5.0", + "enabled": "retraction_enable" + }, + "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", + "type": "float", + "default_value": 1.5, + "value": "line_width * 2", + "minimum_value": "0", + "maximum_value_warning": "10", + "enabled": "retraction_enable" + }, + "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": 45, + "minimum_value": "0", + "maximum_value_warning": "100", + "type": "int", + "enabled": "retraction_enable" + }, + "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", + "type": "float", + "default_value": 4.5, + "minimum_value": "0", + "maximum_value_warning": "retraction_amount * 2", + "value": "retraction_amount", + "enabled": "retraction_enable" + }, + "retraction_hop": { + "label": "Z Hop when Retracting", + "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.", + "unit": "mm", + "type": "float", + "default_value": 0, + "minimum_value_warning": "-0.0001", + "maximum_value_warning": "10", + "enabled": "retraction_enable" + } + } + }, + "speed": + { + "label": "Speed", + "icon": "category_speed", + "description": "Speed", + "type": "category", + "children": + { + "speed_print": + { + "label": "Print Speed", + "description": "The speed at which printing happens.", + "unit": "mm/s", + "type": "float", + "minimum_value": "0.1", + "maximum_value_warning": "150", + "maximum_value": "299792458000", + "default_value": 60, + "children": + { + "speed_infill": + { + "label": "Infill Speed", + "description": "The speed at which infill is printed.", + "unit": "mm/s", + "type": "float", + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "default_value": 60, + "value": "speed_print" + }, + "speed_wall": + { + "label": "Wall Speed", + "description": "The speed at which the walls are printed.", + "unit": "mm/s", + "type": "float", + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "default_value": 30, + "value": "speed_print / 2", + "children": + { + "speed_wall_0": + { + "label": "Outer Wall Speed", + "description": "The speed at which the outermost walls are printed. Printing the outer wall at a lower speed improves the final skin quality. However, having a large difference between the inner wall speed and the outer wall speed will effect quality in a negative way.", + "unit": "mm/s", + "type": "float", + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "default_value": 30, + "value": "speed_wall" + }, + "speed_wall_x": + { + "label": "Inner Wall Speed", + "description": "The speed at which all inner walls are printed Printing the inner wall faster than the outer wall will reduce printing time. It works well to set this in between the outer wall speed and the infill speed.", + "unit": "mm/s", + "type": "float", + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "default_value": 60, + "value": "speed_wall * 2" + } + } + }, + "speed_topbottom": + { + "label": "Top/Bottom Speed", + "description": "The speed at which top/bottom layers are printed.", + "unit": "mm/s", + "type": "float", + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "default_value": 30, + "value": "speed_print / 2" + }, + "speed_support": + { + "label": "Support Speed", + "description": "The speed at which the support structure is printed. Printing support at higher speeds can greatly reduce printing time. The surface quality of the support structure is not important since it is removed after printing.", + "unit": "mm/s", + "type": "float", + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "default_value": 60, + "value": "speed_print", + "enabled": "support_roof_enable", + "children": + { + "speed_support_infill": + { + "label": "Support Infill Speed", + "description": "The speed at which the infill of support is printed. Printing the infill at lower speeds improves stability.", + "unit": "mm/s", + "type": "float", + "default_value": 60, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "value": "speed_support", + "enabled": "support_enable", + "global_only": true + }, + "speed_support_roof": + { + "label": "Support Roof Speed", + "description": "The speed at which the roofs of support are printed. Printing the support roof at lower speeds can improve overhang quality.", + "unit": "mm/s", + "type": "float", + "default_value": 40, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "enabled": "support_roof_enable", + "value": "speed_support / 1.5", + "global_only": true + } + } + } + } + }, + "speed_travel": + { + "label": "Travel Speed", + "description": "The speed at which travel moves are made.", + "unit": "mm/s", + "type": "float", + "default_value": 120, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "300", + "value": "speed_print if magic_spiralize else 120", + "global_only": true + }, + "speed_layer_0": { + "label": "Initial Layer Speed", + "description": "The print speed for the initial layer. A lower value is advised to improve adhesion to the build plate.", + "unit": "mm/s", + "type": "float", + "default_value": 30, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "300" + }, + "skirt_speed": { + "label": "Skirt 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 at a different speed.", + "unit": "mm/s", + "type": "float", + "default_value": 30, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "300", + "value": "speed_layer_0", + "global_only": true + }, + "speed_slowdown_layers": + { + "label": "Number of Slower Layers", + "description": "The first few layers are printed slower than the rest of the object, to get better adhesion to the build plate and improve the overall success rate of prints. The speed is gradually increased over these layers.", + "type": "int", + "default_value": 2, + "minimum_value": "0", + "maximum_value": "299792458000", + "maximum_value_warning": "300", + "global_only": true + } + } + }, + "travel": + { + "label": "Travel", + "icon": "category_travel", + "description": "travel", + "type": "category", + "children": + { + "retraction_combing": + { + "label": "Combing Mode", + "description": "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas by combing within the infill only. It is also possible to avoid combing over top/bottom skin areas by combing within the infill only.", + "type": "enum", + "options": + { + "off": "Off", + "all": "All", + "noskin": "No Skin" + }, + "default_value": "all", + "global_only": true + }, + "travel_avoid_other_parts": + { + "label": "Avoid Printed Parts when Traveling", + "description": "The nozzle avoids already printed parts when traveling. This option is only available when combing is enabled.", + "type": "bool", + "default_value": true, + "enabled": "retraction_combing != \"off\"", + "global_only": "True" + }, + "travel_avoid_distance": + { + "label": "Travel Avoid Distance", + "description": "The distance between the nozzle and already printed parts when avoiding during travel moves.", + "unit": "mm", + "type": "float", + "default_value": 1.5, + "value": "machine_nozzle_tip_outer_diameter / 2 * 1.25", + "minimum_value": "0", + "maximum_value_warning": "machine_nozzle_tip_outer_diameter * 5", + "enabled": "retraction_combing != \"off\" and travel_avoid_other_parts", + "global_only": "True" + } + } + }, + "cooling": + { + "label": "Cooling", + "icon": "category_cool", + "description": "Cooling", + "type": "category", + "children": + { + "cool_fan_enabled": + { + "label": "Enable Cooling Fans", + "description": "Enables the cooling fans while printing. The fans improve print quality on layers with short layer times and bridging / overhangs.", + "type": "bool", + "default_value": true, + "global_only": "True" + }, + "cool_fan_speed": + { + "label": "Fan Speed", + "description": "The speed at which the cooling fans spin.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value": "100", + "default_value": 100, + "value": "100.0 if cool_fan_enabled else 0.0", + "enabled": "cool_fan_enabled", + "global_only": "True", + "children": + { + "cool_fan_speed_min": + { + "label": "Regular Fan Speed", + "description": "The speed at which the fans spin before hitting the threshold. When a layer prints faster than the threshold, the fan speed gradually inclines towards the maximum fan speed.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value": "100", + "value": "cool_fan_speed", + "default_value": 100, + "enabled": "cool_fan_enabled", + "global_only": "True" + }, + "cool_fan_speed_max": + { + "label": "Maximum Fan Speed", + "description": "The speed at which the fans spin on the minimum layer time. The fan speed gradually increases between the regular fan speed and maximum fan speed when the threshold is hit.", + "unit": "%", + "type": "float", + "minimum_value": "max(0, cool_fan_speed_min)", + "maximum_value": "100", + "default_value": 100, + "enabled": "cool_fan_enabled", + "global_only": "True", + "value": "cool_fan_speed" + } + } + }, + "cool_min_layer_time_fan_speed_max": + { + "label": "Regular/Maximum Fan Speed Threshold", + "description": "The layer time which sets the threshold between regular fan speed and maximum fan speed. Layers that print slower than this time use regular fan speed. For faster layers the fan speed gradually increases towards the maximum fan speed.", + "unit": "sec", + "type": "float", + "default_value": 10, + "minimum_value": "cool_min_layer_time", + "maximum_value_warning": "600", + "global_only": "True" + }, + "cool_fan_full_at_height": + { + "label": "Regular Fan Speed at Height", + "description": "The height at which the fans spin on regular fan speed. At the layers below the fan speed gradually increases from zero to regular fan speed.", + "unit": "mm", + "type": "float", + "default_value": 0.5, + "value": "layer_height_0", + "minimum_value": "0", + "maximum_value_warning": "10.0", + "global_only": "True", + "children": + { + "cool_fan_full_layer": + { + "label": "Regular Fan Speed at Layer", + "description": "The layer at which the fans spin on regular fan speed. If regular fan speed at height is set, this value is calculated and rounded to a whole number.", + "type": "int", + "default_value": 1, + "minimum_value": "0", + "maximum_value_warning": "100", + "value": "int((cool_fan_full_at_height - layer_height_0 + 0.001) / layer_height) + 1", + "global_only": "True" + } + } + }, + "cool_min_layer_time": + { + "label": "Minimum Layer Time", + "description": "The minimum time spent in a layer. This forces the printer to slow down, to at least spend the time set here in one layer. This allows the printed material to cool down properly before printing the next layer.", + "unit": "sec", + "type": "float", + "default_value": 5, + "minimum_value": "0", + "maximum_value_warning": "600", + "global_only": "True" + }, + "cool_min_speed": + { + "label": "Minimum Speed", + "description": "The minimum print speed, despite slowing down due to the minimum layer time. When the printer would slow down too much, the pressure in the nozzle would be too low and result in bad print quality.", + "unit": "mm/s", + "type": "float", + "default_value": 10, + "minimum_value": "0", + "maximum_value_warning": "100", + "global_only": "True" + }, + "cool_lift_head": + { + "label": "Lift Head", + "description": "When the minimum speed is hit because of minimum layer time, lift the head away from the print and wait the extra time until the minimum layer time is reached.", + "type": "bool", + "default_value": false, + "global_only": "True" + } + } + }, + "support": + { + "label": "Support", + "type": "category", + "icon": "category_support", + "description": "Support", + "children": + { + "support_enable": + { + "label": "Enable Support", + "description": "Enable support structures. These structures support parts of the model with severe overhangs.", + "type": "bool", + "default_value": false + }, + "support_type": + { + "label": "Support Placement", + "description": "Adjusts the placement of the support structures. The placement can be set to touching build plate or everywhere. When set to everywhere the support structures will also be printed on the model.", + "type": "enum", + "options": + { + "buildplate": "Touching Buildplate", + "everywhere": "Everywhere" + }, + "default_value": "everywhere", + "enabled": "support_enable" + }, + "support_angle": + { + "label": "Support Overhang Angle", + "description": "The minimum angle of overhangs for which support is added. At a value of 0° all overhangs are supported, 90° will not provide any support.", + "unit": "°", + "type": "float", + "minimum_value": "0", + "maximum_value": "90", + "default_value": 50, + "enabled": "support_enable" + }, + "support_pattern": + { + "label": "Support Pattern", + "description": "The pattern of the support structures of the print. The different options available result in sturdy or easy to remove support.", + "type": "enum", + "options": + { + "lines": "Lines", + "grid": "Grid", + "triangles": "Triangles", + "concentric": "Concentric", + "zigzag": "Zig Zag" + }, + "default_value": "zigzag", + "enabled": "support_enable", + "global_only": true + }, + "support_connect_zigzags": + { + "label": "Connect Support ZigZags", + "description": "Connect the ZigZags. This will increase the strength of the zig zag support structure.", + "type": "bool", + "default_value": true, + "enabled": "support_enable and (support_pattern == \"zigzag\")", + "global_only": true + }, + "support_infill_rate": + { + "label": "Support Density", + "description": "Adjusts the density of the support structure. A higher value results in better overhangs, but the supports are harder to remove.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value_warning": "100", + "default_value": 15, + "enabled": "support_enable", + "global_only": true, + "children": { + "support_line_distance": + { + "label": "Support Line Distance", + "description": "Distance between the printed support structure lines. This setting is calculated by the support density.", + "unit": "mm", + "type": "float", + "minimum_value": "0", + "default_value": 2.66, + "enabled": "support_enable", + "value": "(support_line_width * 100) / support_infill_rate * (2 if support_pattern == \"grid\" else (3 if support_pattern == \"triangles\" else 1))", + "global_only": true + } + } + }, + "support_xy_distance": + { + "label": "Support X/Y Distance", + "description": "Distance of the support structure from the print in the X/Y directions.", + "unit": "mm", + "type": "float", + "minimum_value": "0", + "maximum_value_warning": "10", + "default_value": 0.7, + "enabled": "support_enable" + }, + "support_z_distance": + { + "label": "Support Z Distance", + "description": "Distance from the top/bottom of the support structure to the print. This gap provides clearance to remove the supports after the model is printed. This value is rounded down to a multiple of the layer height.", + "unit": "mm", + "type": "float", + "minimum_value": "0", + "maximum_value_warning": "10", + "default_value": 0.15, + "enabled": "support_enable", + + "children": + { + "support_top_distance": + { + "label": "Support Top Distance", + "description": "Distance from the top of the support to the print.", + "unit": "mm", + "minimum_value": "0", + "maximum_value_warning": "10", + "default_value": 0.15, + "type": "float", + "enabled": "support_enable", + "value": "support_z_distance" + }, + "support_bottom_distance": + { + "label": "Support Bottom Distance", + "description": "Distance from the print to the bottom of the support.", + "unit": "mm", + "minimum_value": "0", + "maximum_value_warning": "10", + "default_value": 0.1, + "value": "0.1 if support_type == 'everywhere' else 0", + "type": "float", + "enabled": "support_enable and support_type == 'everywhere'" + } + } + }, + "support_bottom_stair_step_height": + { + "label": "Support Stair Step Height", + "description": "The height of the steps of the stair-like bottom of support resting on the model. A low value makes the support harder to remove, but too high values can lead to unstable support structures.", + "unit": "mm", + "type": "float", + "default_value": 0.3, + "minimum_value": "0", + "maximum_value_warning": "1.0", + "enabled": "support_enable" + }, + "support_join_distance": + { + "label": "Support Join Distance", + "description": "The maximum distance between support structures in the X/Y directions. When seperate structures are closer together than this value, the structures merge into one.", + "unit": "mm", + "type": "float", + "default_value": 2.0, + "minimum_value_warning": "0", + "maximum_value_warning": "10", + "enabled": "support_enable" + }, + "support_offset": + { + "label": "Support Horizontal Expansion", + "description": "Amount of offset applied to all support polygons in each layer. Positive values can smooth out the support areas and result in more sturdy support.", + "unit": "mm", + "type": "float", + "default_value": 0.2, + "minimum_value_warning": "-0.5", + "maximum_value_warning": "5.0", + "enabled": "support_enable" + }, + "support_area_smoothing": + { + "label": "Support Area Smoothing", + "description": "Maximum distance in the X/Y directions of a line segment which is to be smoothed out. Ragged lines are introduced by the join distance and support bridge, which cause the machine to resonate. Smoothing the support areas won't cause them to break with the constraints, except it might change the overhang.", + "unit": "mm", + "type": "float", + "default_value": 0.6, + "minimum_value": "0", + "maximum_value_warning": "1.0", + "enabled": "support_enable" + }, + "support_roof_enable": + { + "label": "Enable Support Roof", + "description": "Generate a dense top skin at the top of the support on which the model is printed.", + "type": "bool", + "default_value": false, + "enabled": "support_enable" + }, + "support_roof_height": + { + "label": "Support Roof Thickness", + "description": "The thickness of the support roofs.", + "unit": "mm", + "type": "float", + "default_value": 1, + "minimum_value": "0", + "maximum_value_warning": "10", + "enabled": "support_roof_enable" + }, + "support_roof_density": + { + "label": "Support Roof Density", + "description": "Adjusts the density of the roof of the support structure. A higher value results in better overhangs, but the supports are harder to remove.", + "unit": "%", + "type": "float", + "default_value": 100, + "minimum_value": "0", + "maximum_value_warning": "100", + "enabled":"support_roof_enable", + "global_only": true, + "children": + { + "support_roof_line_distance": + { + "label": "Support Roof Line Distance", + "description": "Distance between the printed support roof lines. This setting is calculated by the support roof Density, but can be adjusted separately.", + "unit": "mm", + "type": "float", + "default_value": 0.4, + "minimum_value": "0", + "value": "0 if support_roof_density == 0 else (support_roof_line_width * 100) / support_roof_density * (2 if support_roof_pattern == \"grid\" else (3 if support_roof_pattern == \"triangles\" else 1))", + "enabled": "support_roof_enable", + "global_only": true + } + } + }, + "support_roof_pattern": + { + "label": "Support Roof Pattern", + "description": "The pattern with which the top of the support is printed.", + "type": "enum", + "options": + { + "lines": "Lines", + "grid": "Grid", + "triangles": "Triangles", + "concentric": "Concentric", + "zigzag": "Zig Zag" + }, + "default_value": "concentric", + "enabled": "support_roof_enable", + "global_only": true + }, + "support_use_towers": + { + "label": "Use Towers", + "description": "Use specialized towers to support tiny overhang areas. These towers have a larger diameter than the region they support. Near the overhang the towers' diameter decreases, forming a roof.", + "type": "bool", + "default_value": true, + "enabled": "support_enable" + }, + "support_tower_diameter": + { + "label": "Tower Diameter", + "description": "The diameter of a special tower.", + "unit": "mm", + "type": "float", + "default_value": 3.0, + "minimum_value": "0", + "maximum_value_warning": "10", + "enabled": "support_enable and support_use_towers" + }, + "support_minimal_diameter": + { + "label": "Minimum Diameter", + "description": "Minimum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower.", + "unit": "mm", + "type": "float", + "default_value": 3.0, + "minimum_value": "0", + "maximum_value_warning": "10", + "maximum_value": "support_tower_diameter", + "enabled": "support_enable and support_use_towers" + }, + "support_tower_roof_angle": + { + "label": "Tower Roof Angle", + "description": "The angle of a rooftop of a tower. A higher value results in pointed tower roofs, a lower value results in flattened tower roofs.", + "unit": "°", + "type": "int", + "minimum_value": "0", + "maximum_value": "90", + "default_value": 65, + "enabled": "support_enable and support_use_towers" + } + } + }, + "platform_adhesion": + { + "label": "Platform Adhesion", + "type": "category", + "icon": "category_adhesion", + "description": "Adhesion", + "children": + { + "adhesion_type": + { + "label": "Platform Adhesion Type", + "description": "Different options that help to improve both priming your extrusion and adhesion to the build plate. Brim adds a single layer flat area around the base of your object to prevent warping. Raft adds a thick grid with a roof below the object. Skirt is a line printed around the object, but not connected to the model.", + "type": "enum", + "options": + { + "skirt": "Skirt", + "brim": "Brim", + "raft": "Raft" + }, + "default_value": "brim", + "global_only": "True" + }, + "skirt_line_count": + { + "label": "Skirt Line Count", + "description": "Multiple skirt lines help to prime your extrusion better for small objects. Setting this to 0 will disable the skirt.", + "type": "int", + "default_value": 1, + "minimum_value": "0", + "maximum_value_warning": "10", + "enabled": "adhesion_type == \"skirt\"", + "global_only": "True" + }, + "skirt_gap": + { + "label": "Skirt Distance", + "description": "The horizontal distance between the skirt and the first layer of the print.\nThis is the minimum distance, multiple skirt lines will extend outwards from this distance.", + "unit": "mm", + "type": "float", + "default_value": 3, + "minimum_value_warning": "0", + "maximum_value_warning": "100", + "enabled": "adhesion_type == \"skirt\"", + "global_only": "True" + }, + "skirt_minimal_length": + { + "label": "Skirt Minimum Length", + "description": "The minimum length of the skirt. If this length is not reached by the skirt line count, more skirt lines will be added until the minimum length is reached. Note: If the line count is set to 0 this is ignored.", + "unit": "mm", + "type": "float", + "default_value": 250, + "minimum_value": "0", + "minimum_value_warning": "25", + "maximum_value_warning": "2500", + "enabled": "adhesion_type == \"skirt\"", + "global_only": "True" + }, + "brim_width": + { + "label": "Brim Width", + "description": "The distance from the model to the outermost brim line. A larger brim enhances adhesion to the build plate, but also reduces the effective print area.", + "type": "float", + "unit": "mm", + "default_value": 8.0, + "minimum_value": "0.0", + "maximum_value_warning": "100.0", + "enabled": "adhesion_type == \"brim\"", + "global_only": "True", + "children": + { + "brim_line_count": + { + "label": "Brim Line Count", + "description": "The number of lines used for a brim. More brim lines enhance adhesion to the build plate, but also reduces the effective print area.", + "type": "int", + "default_value": 20, + "minimum_value": "0", + "maximum_value_warning": "300", + "value": "math.ceil(brim_width / skirt_line_width)", + "enabled": "adhesion_type == \"brim\"", + "global_only": "True" + } + } + }, + "raft_margin": + { + "label": "Raft Extra Margin", + "description": "If the raft is enabled, this is the extra raft area around the object which is also given a raft. Increasing this margin will create a stronger raft while using more material and leaving less area for your print.", + "unit": "mm", + "type": "float", + "default_value": 5, + "minimum_value_warning": "0", + "maximum_value_warning": "10", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_airgap": + { + "label": "Raft Air Gap", + "description": "The gap between the final raft layer and the first layer of the object. Only the first layer is raised by this amount to lower the bonding between the raft layer and the object. Makes it easier to peel off the raft.", + "unit": "mm", + "type": "float", + "default_value": 0.35, + "minimum_value": "0", + "maximum_value_warning": "1.0", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_surface_layers": + { + "label": "Raft Top Layers", + "description": "The number of top layers on top of the 2nd raft layer. These are fully filled layers that the object sits on. 2 layers result in a smoother top surface than 1.", + "type": "int", + "default_value": 2, + "minimum_value": "0", + "maximum_value_warning": "20", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_surface_thickness": + { + "label": "Raft Top Layer Thickness", + "description": "Layer thickness of the top raft layers.", + "unit": "mm", + "type": "float", + "default_value": 0.1, + "minimum_value": "0", + "maximum_value_warning": "2.0", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_surface_line_width": + { + "label": "Raft Top Line Width", + "description": "Width of the lines in the top surface of the raft. These can be thin lines so that the top of the raft becomes smooth.", + "unit": "mm", + "type": "float", + "default_value": 0.3, + "minimum_value": "0.0001", + "maximum_value_warning": "machine_nozzle_size * 2", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_surface_line_spacing": + { + "label": "Raft Top Spacing", + "description": "The distance between the raft lines for the top raft layers. The spacing should be equal to the line width, so that the surface is solid.", + "unit": "mm", + "type": "float", + "default_value": 0.3, + "minimum_value": "0.0001", + "maximum_value_warning": "5.0", + "enabled": "adhesion_type == \"raft\"", + "value": "raft_surface_line_width", + "global_only": "True" + }, + "raft_interface_thickness": + { + "label": "Raft Middle Thickness", + "description": "Layer thickness of the middle raft layer.", + "unit": "mm", + "type": "float", + "default_value": 0.27, + "minimum_value": "0", + "maximum_value_warning": "5.0", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_interface_line_width": + { + "label": "Raft Middle Line Width", + "description": "Width of the lines in the middle raft layer. Making the second layer extrude more causes the lines to stick to the bed.", + "unit": "mm", + "type": "float", + "default_value": 1, + "value": "line_width", + "minimum_value": "0.0001", + "maximum_value_warning": "machine_nozzle_size * 2", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_interface_line_spacing": + { + "label": "Raft Middle Spacing", + "description": "The distance between the raft lines for the middle raft layer. The spacing of the middle should be quite wide, while being dense enough to support the top raft layers.", + "unit": "mm", + "type": "float", + "default_value": 1.0, + "minimum_value": "0", + "maximum_value_warning": "15.0", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_base_thickness": + { + "label": "Raft Base Thickness", + "description": "Layer thickness of the base raft layer. This should be a thick layer which sticks firmly to the printer bed.", + "unit": "mm", + "type": "float", + "default_value": 0.3, + "minimum_value": "0", + "maximum_value_warning": "5.0", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_base_line_width": + { + "label": "Raft Base Line Width", + "description": "Width of the lines in the base raft layer. These should be thick lines to assist in bed adhesion.", + "unit": "mm", + "type": "float", + "default_value": 1, + "minimum_value": "0.0001", + "value": "line_width", + "maximum_value_warning": "machine_nozzle_size * 2", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_base_line_spacing": + { + "label": "Raft Line Spacing", + "description": "The distance between the raft lines for the base raft layer. Wide spacing makes for easy removal of the raft from the build plate.", + "unit": "mm", + "type": "float", + "default_value": 3.0, + "minimum_value": "0.0001", + "maximum_value_warning": "100", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_speed": + { + "label": "Raft Print Speed", + "description": "The speed at which the raft is printed.", + "unit": "mm/s", + "type": "float", + "default_value": 30, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "200", + "enabled": "adhesion_type == \"raft\"", + "value": "speed_print / 60 * 30", + "global_only": "True", + "children": + { + "raft_surface_speed": + { + "label": "Raft Surface Print Speed", + "description": "The speed at which the surface raft layers are printed. These should be printed a bit slower, so that the nozzle can slowly smooth out adjacent surface lines.", + "unit": "mm/s", + "type": "float", + "default_value": 30, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "100", + "enabled": "adhesion_type == \"raft\"", + "value": "raft_speed", + "global_only": "True" + }, + "raft_interface_speed": + { + "label": "Raft Interface Print Speed", + "description": "The speed at which the interface raft layer is printed. This should be printed quite slowly, as the volume of material coming out of the nozzle is quite high.", + "unit": "mm/s", + "type": "float", + "default_value": 15, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "enabled": "adhesion_type == \"raft\"", + "value": "0.5 * raft_speed", + "global_only": "True" + }, + "raft_base_speed": + { + "label": "Raft Base Print Speed", + "description": "The speed at which the base raft layer is printed. This should be printed quite slowly, as the volume of material coming out of the nozzle is quite high.", + "unit": "mm/s", + "type": "float", + "default_value": 15, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "200", + "enabled": "adhesion_type == \"raft\"", + "value": "0.5 * raft_speed", + "global_only": "True" + } + } + }, + "raft_fan_speed": + { + "label": "Raft Fan Speed", + "description": "The fan speed for the raft.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value": "100", + "default_value": 100, + "global_only": "True", + "enabled": "adhesion_type == \"raft\"", + "children": + { + "raft_surface_fan_speed": + { + "label": "Raft Surface Fan Speed", + "description": "The fan speed for the surface raft layers.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value": "100", + "default_value": 100, + "global_only": "True", + "value": "raft_fan_speed", + "enabled": "adhesion_type == \"raft\"" + }, + "raft_interface_fan_speed": + { + "label": "Raft Interface Fan Speed", + "description": "The fan speed for the interface raft layer.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value": "100", + "default_value": 100, + "global_only": "True", + "value": "raft_fan_speed", + "enabled": "adhesion_type == \"raft\"" + }, + "raft_base_fan_speed": + { + "label": "Raft Base Fan Speed", + "description": "The fan speed for the base raft layer.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value": "100", + "default_value": 100, + "global_only": "True", + "value": "raft_fan_speed", + "enabled": "adhesion_type == \"raft\"" + } + } + } + } + }, + "meshfix": + { + "label": "Mesh Fixes", + "type": "category", + "icon": "category_fixes", + "description": "category_fixes", + "children": + { + "meshfix_union_all": + { + "label": "Union Overlapping Volumes", + "description": "Ignore the internal geometry arising from overlapping volumes and print the volumes as one. This may cause internal cavities to disappear.", + "type": "bool", + "default_value": true + }, + "meshfix_union_all_remove_holes": + { + "label": "Remove All Holes", + "description": "Remove the holes in each layer and keep only the outside shape. This will ignore any invisible internal geometry. However, it also ignores layer holes which can be viewed from above or below.", + "type": "bool", + "default_value": false + }, + "meshfix_extensive_stitching": + { + "label": "Extensive Stitching", + "description": "Extensive stitching tries to stitch up open holes in the mesh by closing the hole with touching polygons. This option can introduce a lot of processing time.", + "type": "bool", + "default_value": false + }, + "meshfix_keep_open_polygons": + { + "label": "Keep Disconnected Faces", + "description": "Normally Cura tries to stitch up small holes in the mesh and remove parts of a layer with big holes. Enabling this option keeps those parts which cannot be stitched. This option should be used as a last resort option when everything else fails to produce proper GCode.", + "type": "bool", + "default_value": false + } + } + }, + "blackmagic": + { + "label": "Special Modes", + "type": "category", + "icon": "category_blackmagic", + "description": "category_blackmagic", + "children": + { + "print_sequence": + { + "label": "Print Sequence", + "description": "Whether to print all objects one layer at a time or to wait for one object to finish, before moving on to the next. One at a time mode is only possible if all models are separated in such a way that the whole print head can move in between and all models are lower than the distance between the nozzle and the X/Y axes.", + "type": "enum", + "options": + { + "all_at_once": "All at Once", + "one_at_a_time": "One at a Time" + }, + "default_value": "all_at_once", + "global_only": true + }, + "magic_mesh_surface_mode": + { + "label": "Surface Mode", + "description": "Treat the model as a surface only, a volume, or volumes with loose surfaces. The normal print mode only prints enclosed volumes. \"Surface\" prints a single wall tracing the mesh surface with no infill and no top/bottom skin. \"Both\" prints enclosed volumes like normal and any remaining polygons as surfaces.", + "type": "enum", + "options": + { + "normal": "Normal", + "surface": "Surface", + "both": "Both" + }, + "default_value": "normal" + }, + "magic_spiralize": + { + "label": "Spiralize Outer Contour", + "description": "Spiralize smooths out the Z move of the outer edge. This will create a steady Z increase over the whole print. This feature turns a solid object into a single walled print with a solid bottom. This feature used to be called Joris in older versions.", + "type": "bool", + "default_value": false, + "global_only": "True" + } + } + }, + "experimental": + { + "label": "Experimental Modes", + "type": "category", + "icon": "category_blackmagic", + "description": "experimental!", + "children": + { + "draft_shield_enabled": + { + "label": "Enable Draft Shield", + "description": "This will create a wall around the object, which traps (hot) air and shields against exterior airflow. Especially useful for materials which warp easily.", + "type": "bool", + "default_value": false, + "global_only": true + }, + "draft_shield_dist": + { + "label": "Draft Shield X/Y Distance", + "description": "Distance of the draft shield from the print, in the X/Y directions.", + "unit": "mm", + "type": "float", + "minimum_value": "0", + "maximum_value_warning": "100", + "default_value": 10, + "enabled": "draft_shield_enabled", + "global_only": true + }, + "draft_shield_height_limitation": + { + "label": "Draft Shield Limitation", + "description": "Set the height of the draft shield. Choose to print the draft shield at the full height of the object or at a limited height.", + "type": "enum", + "options": + { + "full": "Full", + "limited": "Limited" + }, + "default_value": "full", + "enabled": "draft_shield_enabled", + "global_only": true + }, + "draft_shield_height": + { + "label": "Draft Shield Height", + "description": "Height limitation of the draft shield. Above this height no draft shield will be printed.", + "unit": "mm", + "type": "float", + "minimum_value": "0", + "maximum_value_warning": "9999", + "default_value": 0, + "value": "9999 if draft_shield_height_limitation == 'full' and draft_shield_enabled else 0.0", + "enabled": "draft_shield_height_limitation == \"limited\"", + "global_only": true + }, + "coasting_enable": + { + "label": "Enable Coasting", + "description": "Coasting replaces the last part of an extrusion path with a travel path. The oozed material is used to print the last piece of the extrusion path in order to reduce stringing.", + "type": "bool", + "default_value": false, + "global_only": true + }, + "coasting_volume": + { + "label": "Coasting Volume", + "description": "The volume otherwise oozed. This value should generally be close to the nozzle diameter cubed.", + "unit": "mm³", + "type": "float", + "default_value": 0.064, + "minimum_value": "0", + "maximum_value_warning": "2.0", + "enabled": "coasting_enable", + "global_only": true + }, + "coasting_min_volume": + { + "label": "Minimum Volume Before Coasting", + "description": "The smallest volume an extrusion path should have before allowing coasting. For smaller extrusion paths, less pressure has been built up in the bowden tube and so the coasted volume is scaled linearly. This value should always be larger than the Coasting Volume.", + "unit": "mm³", + "type": "float", + "default_value": 0.8, + "minimum_value": "0", + "maximum_value_warning": "10.0", + "enabled": "coasting_enable", + "global_only": true + }, + "coasting_speed": + { + "label": "Coasting Speed", + "description": "The speed by which to move during coasting, relative to the speed of the extrusion path. A value slightly under 100% is advised, since during the coasting move the pressure in the bowden tube drops.", + "unit": "%", + "type": "float", + "default_value": 90, + "minimum_value": "0.0001", + "maximum_value_warning": "100", + "enabled": "coasting_enable", + "global_only": true + }, + "skin_outline_count": + { + "label": "Extra Skin Wall Count", + "description": "Replaces the outermost part of the top/bottom pattern with a number of concentric lines. Using one or two lines improves roofs that start on infill material.", + "default_value": 0, + "minimum_value": "0", + "maximum_value_warning": "10", + "type": "int" + }, + "skin_alternate_rotation": + { + "label": "Alternate Skin Rotation", + "description": "Alternate the direction in which the top/bottom layers are printed. Normally they are printed diagonally only. This setting adds the X-only and Y-only directions.", + "type": "bool", + "default_value": false, + "enabled": "top_bottom_pattern != \"concentric\"" + }, + "support_conical_enabled": + { + "label": "Enable Conical Support", + "description": "Experimental feature: Make support areas smaller at the bottom than at the overhang.", + "type": "bool", + "default_value": false, + "enabled": "support_enable" + }, + "support_conical_angle": + { + "label": "Conical Support Angle", + "description": "The angle of the tilt of conical support. With 0 degrees being vertical, and 90 degrees being horizontal. Smaller angles cause the support to be more sturdy, but consist of more material. Negative angles cause the base of the support to be wider than the top.", + "unit": "°", + "type": "float", + "minimum_value": "-90", + "minimum_value_warning": "-45", + "maximum_value_warning": "45", + "maximum_value": "90", + "default_value": 30, + "enabled": "support_conical_enabled and support_enable" + }, + "support_conical_min_width": + { + "label": "Conical Support Minimum Width", + "description": "Minimum width to which the base of the conical support area is reduced. Small widths can lead to unstable support structures.", + "unit": "mm", + "default_value": 5.0, + "minimum_value": "0", + "minimum_value_warning": "machine_nozzle_size * 3", + "maximum_value_warning": "100.0", + "type": "float", + "enabled": "support_conical_enabled and support_enable" + }, + "magic_fuzzy_skin_enabled": + { + "label": "Fuzzy Skin", + "description": "Randomly jitter while printing the outer wall, so that the surface has a rough and fuzzy look.", + "type": "bool", + "default_value": false + }, + "magic_fuzzy_skin_thickness": + { + "label": "Fuzzy Skin Thickness", + "description": "The width within which to jitter. It's advised to keep this below the outer wall width, since the inner walls are unaltered.", + "type": "float", + "unit": "mm", + "default_value": 0.3, + "minimum_value": "0.001", + "maximum_value_warning": "wall_line_width_0", + "enabled": "magic_fuzzy_skin_enabled" + }, + "magic_fuzzy_skin_point_density": + { + "label": "Fuzzy Skin Density", + "description": "The average density of points introduced on each polygon in a layer. Note that the original points of the polygon are discarded, so a low density results in a reduction of the resolution.", + "type": "float", + "unit": "1/mm", + "default_value": 1.25, + "minimum_value": "0.008", + "minimum_value_warning": "0.1", + "maximum_value_warning": "10", + "maximum_value": "2 / magic_fuzzy_skin_thickness", + "enabled": "magic_fuzzy_skin_enabled", + "children": + { + "magic_fuzzy_skin_point_dist": + { + "label": "Fuzzy Skin Point Distance", + "description": "The average distance between the random points introduced on each line segment. Note that the original points of the polygon are discarded, so a high smoothness results in a reduction of the resolution. This value must be higher than half the Fuzzy Skin Thickness.", + "type": "float", + "unit": "mm", + "default_value": 0.8, + "minimum_value": "magic_fuzzy_skin_thickness / 2", + "minimum_value_warning": "0.1", + "maximum_value_warning": "10", + "value": "10000 if parent_value == 0 else 1 / magic_fuzzy_skin_point_density", + "enabled": "magic_fuzzy_skin_enabled" + } + } + }, + "wireframe_enabled": + { + "label": "Wire Printing", + "description": "Print only the outside surface with a sparse webbed structure, printing 'in thin air'. This is realized by horizontally printing the contours of the model at given Z intervals which are connected via upward and diagonally downward lines.", + "type": "bool", + "default_value": false, + "global_only": "True" + }, + "wireframe_height": + { + "label": "WP Connection Height", + "description": "The height of the upward and diagonally downward lines between two horizontal parts. This determines the overall density of the net structure. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 3, + "minimum_value": "0.0001", + "maximum_value_warning": "20", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_roof_inset": + { + "label": "WP Roof Inset Distance", + "description": "The distance covered when making a connection from a roof outline inward. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 3, + "minimum_value": "0", + "minimum_value_warning": "machine_nozzle_size", + "maximum_value_warning": "20", + "enabled": "wireframe_enabled", + "value": "wireframe_height", + "global_only": "True" + }, + "wireframe_printspeed": + { + "label": "WP Speed", + "description": "Speed at which the nozzle moves when extruding material. Only applies to Wire Printing.", + "unit": "mm/s", + "type": "float", + "default_value": 5, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "50", + "enabled": "wireframe_enabled", + "global_only": "True", + "children": + { + "wireframe_printspeed_bottom": + { + "label": "WP Bottom Printing Speed", + "description": "Speed of printing the first layer, which is the only layer touching the build platform. Only applies to Wire Printing.", + "unit": "mm/s", + "type": "float", + "default_value": 5, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "50", + "enabled": "wireframe_enabled", + "global_only": "True", + "value": "wireframe_printspeed" + }, + "wireframe_printspeed_up": + { + "label": "WP Upward Printing Speed", + "description": "Speed of printing a line upward 'in thin air'. Only applies to Wire Printing.", + "unit": "mm/s", + "type": "float", + "default_value": 5, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "50", + "enabled": "wireframe_enabled", + "global_only": "True", + "value": "wireframe_printspeed" + }, + "wireframe_printspeed_down": + { + "label": "WP Downward Printing Speed", + "description": "Speed of printing a line diagonally downward. Only applies to Wire Printing.", + "unit": "mm/s", + "type": "float", + "default_value": 5, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "50", + "enabled": "wireframe_enabled", + "global_only": "True", + "value": "wireframe_printspeed" + }, + "wireframe_printspeed_flat": + { + "label": "WP Horizontal Printing Speed", + "description": "Speed of printing the horizontal contours of the object. Only applies to Wire Printing.", + "unit": "mm/s", + "type": "float", + "default_value": 5, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "100", + "value": "wireframe_printspeed", + "enabled": "wireframe_enabled", + "global_only": "True" + } + } + }, + "wireframe_flow": + { + "label": "WP Flow", + "description": "Flow compensation: the amount of material extruded is multiplied by this value. Only applies to Wire Printing.", + "unit": "%", + "default_value": 100, + "minimum_value": "0", + "maximum_value_warning": "100", + "type": "float", + "enabled": "wireframe_enabled", + "global_only": "True", + "children": + { + "wireframe_flow_connection": + { + "label": "WP Connection Flow", + "description": "Flow compensation when going up or down. Only applies to Wire Printing.", + "unit": "%", + "default_value": 100, + "minimum_value": "0", + "maximum_value_warning": "100", + "type": "float", + "enabled": "wireframe_enabled", + "global_only": "True", + "value": "wireframe_flow" + }, + "wireframe_flow_flat": + { + "label": "WP Flat Flow", + "description": "Flow compensation when printing flat lines. Only applies to Wire Printing.", + "unit": "%", + "default_value": 100, + "minimum_value": "0", + "maximum_value_warning": "100", + "type": "float", + "enabled": "wireframe_enabled", + "global_only": "True", + "value": "wireframe_flow" + } + } + }, + "wireframe_top_delay": + { + "label": "WP Top Delay", + "description": "Delay time after an upward move, so that the upward line can harden. Only applies to Wire Printing.", + "unit": "sec", + "type": "float", + "default_value": 0, + "minimum_value": "0", + "maximum_value_warning": "1", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_bottom_delay": + { + "label": "WP Bottom Delay", + "description": "Delay time after a downward move. Only applies to Wire Printing.", + "unit": "sec", + "type": "float", + "default_value": 0, + "minimum_value": "0", + "maximum_value_warning": "1", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_flat_delay": + { + "label": "WP Flat Delay", + "description": "Delay time between two horizontal segments. Introducing such a delay can cause better adhesion to previous layers at the connection points, while too long delays cause sagging. Only applies to Wire Printing.", + "unit": "sec", + "type": "float", + "default_value": 0.1, + "minimum_value": "0", + "maximum_value_warning": "0.5", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_up_half_speed": + { + "label": "WP Ease Upward", + "description": "Distance of an upward move which is extruded with half speed.\nThis can cause better adhesion to previous layers, while not heating the material in those layers too much. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 0.3, + "minimum_value": "0", + "maximum_value_warning": "5.0", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_top_jump": + { + "label": "WP Knot Size", + "description": "Creates a small knot at the top of an upward line, so that the consecutive horizontal layer has a better chance to connect to it. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 0.6, + "minimum_value": "0", + "maximum_value_warning": "2.0", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_fall_down": + { + "label": "WP Fall Down", + "description": "Distance with which the material falls down after an upward extrusion. This distance is compensated for. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 0.5, + "minimum_value": "0", + "maximum_value_warning": "wireframe_height", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_drag_along": + { + "label": "WP Drag Along", + "description": "Distance with which the material of an upward extrusion is dragged along with the diagonally downward extrusion. This distance is compensated for. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 0.6, + "minimum_value": "0", + "maximum_value_warning": "wireframe_height", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_strategy": + { + "label": "WP Strategy", + "description": "Strategy for making sure two consecutive layers connect at each connection point. Retraction lets the upward lines harden in the right position, but may cause filament grinding. A knot can be made at the end of an upward line to heighten the chance of connecting to it and to let the line cool; however, it may require slow printing speeds. Another strategy is to compensate for the sagging of the top of an upward line; however, the lines won't always fall down as predicted.", + "type": "enum", + "options": + { + "compensate": "Compensate", + "knot": "Knot", + "retract": "Retract" + }, + "default_value": "compensate", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_straight_before_down": + { + "label": "WP Straighten Downward Lines", + "description": "Percentage of a diagonally downward line which is covered by a horizontal line piece. This can prevent sagging of the top most point of upward lines. Only applies to Wire Printing.", + "type": "float", + "unit": "%", + "default_value": 20, + "minimum_value": "0", + "maximum_value": "100", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_roof_fall_down": + { + "label": "WP Roof Fall Down", + "description": "The distance which horizontal roof lines printed 'in thin air' fall down when being printed. This distance is compensated for. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 2, + "minimum_value_warning": "0", + "maximum_value_warning": "wireframe_roof_inset", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_roof_drag_along": + { + "label": "WP Roof Drag Along", + "description": "The distance of the end piece of an inward line which gets dragged along when going back to the outer outline of the roof. This distance is compensated for. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 0.8, + "minimum_value": "0", + "maximum_value_warning": "10", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_roof_outer_delay": + { + "label": "WP Roof Outer Delay", + "description": "Time spent at the outer perimeters of hole which is to become a roof. Longer times can ensure a better connection. Only applies to Wire Printing.", + "type": "float", + "unit": "sec", + "default_value": 0.2, + "minimum_value": "0", + "maximum_value_warning": "2.0", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_nozzle_clearance": + { + "label": "WP Nozzle Clearance", + "description": "Distance between the nozzle and horizontally downward lines. Larger clearance results in diagonally downward lines with a less steep angle, which in turn results in less upward connections with the next layer. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 1, + "minimum_value_warning": "0", + "maximum_value_warning": "10.0", + "enabled": "wireframe_enabled", + "global_only": "True" + } + } + } + } +} From 6dc74768397c1621f02ff5c598ac2ad50b0d4e47 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 9 May 2016 15:45:58 +0200 Subject: [PATCH 012/705] Removed final parent_value from functions CURA-1278 --- resources/definitions/fdmprinter.def.json | 6 +- resources/machines/fdmprinter.def.json | 2468 --------------------- 2 files changed, 3 insertions(+), 2471 deletions(-) delete mode 100644 resources/machines/fdmprinter.def.json diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index cf92aa847f..00895fd056 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -457,7 +457,7 @@ "minimum_value": "0", "maximum_value_warning": "100", "type": "int", - "value": "0 if infill_sparse_density == 100 else math.ceil(round(parent_value / layer_height, 4))" + "value": "0 if infill_sparse_density == 100 else math.ceil(round(top_thickness / layer_height, 4))" } } }, @@ -479,7 +479,7 @@ "minimum_value": "0", "default_value": 6, "type": "int", - "value": "999999 if infill_sparse_density == 100 else math.ceil(round(parent_value / layer_height, 4))" + "value": "999999 if infill_sparse_density == 100 else math.ceil(round(bottom_thickness / layer_height, 4))" } } } @@ -2151,7 +2151,7 @@ "minimum_value": "magic_fuzzy_skin_thickness / 2", "minimum_value_warning": "0.1", "maximum_value_warning": "10", - "value": "10000 if parent_value == 0 else 1 / magic_fuzzy_skin_point_density", + "value": "10000 if magic_fuzzy_skin_point_density == 0 else 1 / magic_fuzzy_skin_point_density", "enabled": "magic_fuzzy_skin_enabled" } } diff --git a/resources/machines/fdmprinter.def.json b/resources/machines/fdmprinter.def.json deleted file mode 100644 index cf92aa847f..0000000000 --- a/resources/machines/fdmprinter.def.json +++ /dev/null @@ -1,2468 +0,0 @@ -{ - "id": "fdmprinter", - "version": 2, - "metadata": - { - "category": "Ultimaker", - "manufacturer": "Ultimaker", - "visible": false - }, - "name": "FDM Printer Base Description", - "author": "Ultimaker B.V.", - "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g", - "settings": - { - "machine_settings": - { - "label": "Machine", - "type": "category", - "description": "Machine specific settings", - "children": - { - "machine_show_variants": - { - "description": "Whether to show the different variants of this machine, which are described in separate json files.", - "default_value": false, - "type": "bool", - "label": "Show machine variants" - }, - "machine_start_gcode": - { - "description": "Gcode commands to be executed at the very start - separated by \\n.", - "default_value": "G28 ;Home\nG1 Z15.0 F6000 ;Move the platform down 15mm\n;Prime the extruder\nG92 E0\nG1 F200 E3\nG92 E0", - "label": "Start GCode", - "global_only": true, - "type": "str" - }, - "machine_end_gcode": - { - "description": "Gcode commands to be executed at the very end - separated by \\n.", - "default_value": "M104 S0\nM140 S0\n;Retract the filament\nG92 E1\nG1 E-1 F300\nG28 X0 Y0\nM84", - "label": "End GCode", - "global_only": true, - "type": "str" - }, - "material_bed_temp_wait": - { - "description": "Whether to insert a command to wait until the bed temperature is reached at the start.", - "label": "Wait for bed heatup", - "default_value": true, - "global_only": true, - "type": "bool" - }, - "material_print_temp_prepend": - { - "description": "Whether to include nozzle temperature commands at the start of the gcode. When the start_gcode already contains nozzle temperature commands Cura frontend will automatically disable this setting.", - "default_value": true, - "global_only": true, - "type": "bool", - "label": "Wait for material heatup" - }, - "machine_width": - { - "description": "The width (X-direction) of the printable area.", - "default_value": 100, - "global_only": true, - "type": "float", - "label": "Machine width" - }, - "machine_depth": - { - "description": "The depth (Y-direction) of the printable area.", - "default_value": 100, - "global_only": true, - "type": "float", - "label": "Machine depth" - }, - "machine_height": - { - "description": "The height (Z-direction) of the printable area.", - "default_value": 100, - "global_only": true, - "type": "float", - "label": "Machine height" - }, - "machine_heated_bed": - { - "description": "Whether the machine has a heated bed present.", - "default_value": false, - "global_only": true, - "label": "Has heated bed", - "type": "bool" - }, - "machine_center_is_zero": - { - "description": "Whether the X/Y coordinates of the zero position of the printer is at the center of the printable area.", - "default_value": false, - "global_only": true, - "type": "bool", - "label": "Is center origin" - }, - "machine_extruder_count": - { - "description": "Number of extruder trains. An extruder train is the combination of a feeder, bowden tube, and nozzle.", - "default_value": 1, - "global_only": true, - "type": "bool", - "label": "Number extruders" - }, - "machine_nozzle_tip_outer_diameter": - { - "description": "The outer diameter of the tip of the nozzle.", - "label": "Outer nozzle diameter", - "default_value": 1, - "global_only": true, - "type": "float" - }, - "machine_nozzle_head_distance": - { - "description": "The height difference between the tip of the nozzle and the lowest part of the print head.", - "default_value": 3, - "global_only": true, - "type": "float", - "label": "Nozzle length" - }, - "machine_nozzle_expansion_angle": - { - "description": "The angle between the horizontal plane and the conical part right above the tip of the nozzle.", - "default_value": 45, - "global_only": true, - "type": "int", - "label": "Nozzle angle" - }, - "machine_heat_zone_length": - { - "description": "The distance from the tip of the nozzle in which heat from the nozzle is transfered to the filament.", - "default_value": 16, - "global_only": true, - "type": "float", - "label": "Heat zone length" - }, - "machine_nozzle_heat_up_speed": - { - "description": "The speed (°C/s) by which the nozzle heats up averaged over the window of normal printing temperatures and the standby temperature.", - "default_value": 2.0, - "global_only": true, - "type": "float", - "label": "Heat up speed" - }, - "machine_nozzle_cool_down_speed": - { - "description": "The speed (°C/s) by which the nozzle cools down averaged over the window of normal printing temperatures and the standby temperature.", - "default_value": 2.0, - "global_only": true, - "type": "float", - "label": "Cool down speed" - }, - "machine_gcode_flavor": - { - "description": "The type of gcode to be generated.", - "default_value": "RepRap", - "global_only": true, - "type": "str", - "label": "Gcode flavour" - }, - "machine_disallowed_areas": - { - "description": "A list of polygons with areas the print head is not allowed to enter.", - "type": "polygons", - "default_value": [], - "global_only": true, - "label": "Disallowed areas" - }, - "machine_head_polygon": - { - "description": "A 2D silhouette of the print head (fan caps excluded).", - "type": "polygon", - "default_value": - [ - [ - -1, - 1 - ], - [ - -1, - -1 - ], - [ - 1, - -1 - ], - [ - 1, - 1 - ] - ], - "global_only": true, - "label": "Machine head polygon" - }, - "machine_head_with_fans_polygon": - { - "description": "A 2D silhouette of the print head (fan caps included).", - "type": "polygon", - "default_value": - [ - [ - -20, - 10 - ], - [ - 10, - 10 - ], - [ - 10, - -10 - ], - [ - -20, - -10 - ] - ], - "global_only": true, - "label": "Machine head & Fan polygon" - }, - "gantry_height": - { - "description": "The height difference between the tip of the nozzle and the gantry system (X and Y axes).", - "default_value": 99999999999, - "global_only": true, - "label": "Gantry height", - "type": "float" - }, - "machine_nozzle_size": - { - "label": "Nozzle Diameter", - "description": "The inner diameter of the nozzle. Change this setting when using a non-standard nozzle size.", - "unit": "mm", - "type": "float", - "default_value": 0.4, - "minimum_value": "0.001", - "maximum_value_warning": "10" - } - } - }, - "resolution": - { - "label": "Quality", - "type": "category", - "icon": "category_layer_height", - "description": "All settings that influence the resolution of the print. These settings have a large impact on the quality (and print time)", - "children": - { - "layer_height": - { - "label": "Layer Height", - "description": "The height of each layer in mm. Higher values produce faster prints in lower resolution, lower values produce slower prints in higher resolution.", - "unit": "mm", - "type": "float", - "default_value": 0.1, - "minimum_value": "0.001", - "minimum_value_warning": "0.04", - "maximum_value_warning": "0.8 * machine_nozzle_size", - "global_only": "True" - }, - "layer_height_0": - { - "label": "Initial Layer Height", - "description": "The height of the initial layer in mm. A thicker initial layer makes adhesion to the build plate easier.", - "unit": "mm", - "type": "float", - "default_value": 0.3, - "minimum_value": "0.001", - "minimum_value_warning": "0.04", - "maximum_value_warning": "0.8 * machine_nozzle_size", - "global_only": "True" - }, - "line_width": - { - "label": "Line Width", - "description": "Width of a single line. Generally, the width of each line should correspond to the width of the nozzle. However, slightly reducing this value could produce better prints.", - "unit": "mm", - "minimum_value": "0.0001", - "minimum_value_warning": "0.2", - "maximum_value_warning": "2 * machine_nozzle_size", - "default_value": 0.4, - "type": "float", - "value": "machine_nozzle_size", - "children": - { - "wall_line_width": - { - "label": "Wall Line Width", - "description": "Width of a single wall line.", - "unit": "mm", - "minimum_value": "0.0001", - "minimum_value_warning": "0.2", - "maximum_value_warning": "5", - "value":"line_width", - "default_value": 0.4, - "type": "float", - "children": - { - "wall_line_width_0": - { - "label": "Outer Wall Line Width", - "description": "Width of the outermost wall line. By lowering this value, higher levels of detail can be printed.", - "unit": "mm", - "minimum_value": "0.0001", - "minimum_value_warning": "0.2", - "maximum_value_warning": "5", - "default_value": 0.4, - "value":"wall_line_width", - "type": "float" - }, - "wall_line_width_x": - { - "label": "Inner Wall(s) Line Width", - "description": "Width of a single wall line for all wall lines except the outermost one.", - "unit": "mm", - "minimum_value": "0.0001", - "minimum_value_warning": "0.2", - "maximum_value_warning": "5", - "default_value": 0.4, - "value":"wall_line_width", - "type": "float" - } - } - }, - "skin_line_width": - { - "label": "Top/bottom Line Width", - "description": "Width of a single top/bottom line.", - "unit": "mm", - "minimum_value": "0.0001", - "minimum_value_warning": "0.2", - "maximum_value_warning": "5", - "default_value": 0.4, - "type": "float", - "value": "line_width" - }, - "infill_line_width": - { - "label": "Infill Line Width", - "description": "Width of a single infill line.", - "unit": "mm", - "minimum_value": "0.0001", - "minimum_value_warning": "0.2", - "maximum_value_warning": "5", - "default_value": 0.4, - "type": "float", - "value": "line_width" - }, - "skirt_line_width": - { - "label": "Skirt Line Width", - "description": "Width of a single skirt line.", - "unit": "mm", - "minimum_value": "0.0001", - "minimum_value_warning": "0.2", - "maximum_value_warning": "5", - "default_value": 0.4, - "type": "float", - "global_only": true, - "value": "line_width" - }, - "support_line_width": - { - "label": "Support Line Width", - "description": "Width of a single support structure line.", - "unit": "mm", - "minimum_value": "0.0001", - "minimum_value_warning": "0.2", - "maximum_value_warning": "5", - "default_value": 0.4, - "type": "float", - "enabled": "support_enable", - "global_only": true, - "value": "line_width" - }, - "support_roof_line_width": - { - "label": "Support Roof Line Width", - "description": "Width of a single support roof line.", - "unit": "mm", - "default_value": 0.4, - "minimum_value": "0.0001", - "maximum_value_warning": "machine_nozzle_size * 2", - "type": "float", - "enabled": "support_roof_enable", - "global_only": true, - "value": "line_width" - } - } - } - } - }, - "shell": - { - "label": "Shell", - "icon": "category_shell", - "description": "Shell", - "type": "category", - "children": - { - "wall_thickness": - { - "label": "Wall Thickness", - "description": "The thickness of the outside walls in the horizontal direction. This value divided by the wall line width defines the number of walls.", - "unit": "mm", - "default_value": 0.8, - "minimum_value": "0", - "minimum_value_warning": "line_width", - "maximum_value_warning": "5 * line_width", - "type": "float", - "children": - { - "wall_line_count": - { - "label": "Wall Line Count", - "description": "The number of walls. When calculated by the wall thickness, this value is rounded to a whole number.", - "default_value": 2, - "minimum_value": "0", - "type": "int", - "value": "1 if magic_spiralize else max(1, round((wall_thickness - wall_line_width_0) / wall_line_width_x) + 1)" - } - } - }, - "top_bottom_thickness": - { - "label": "Top/Bottom Thickness", - "description": "The thickness of the top/bottom layers in the print. This value divided by the layer height defines the number of top/bottom layers.", - "unit": "mm", - "default_value": 0.8, - "minimum_value": "0", - "maximum_value": "5", - "minimum_value_warning": "0.6", - "type": "float", - "children": - { - "top_thickness": - { - "label": "Top Thickness", - "description": "The thickness of the top layers in the print. This value divided by the layer height defines the number of top layers.", - "unit": "mm", - "default_value": 0.8, - "minimum_value": "0", - "maximum_value_warning": "100", - "type": "float", - "value": "top_bottom_thickness", - "children": - { - "top_layers": - { - "label": "Top Layers", - "description": "The number of top layers. When calculated by the top thickness, this value is rounded to a whole number.", - "default_value": 8, - "minimum_value": "0", - "maximum_value_warning": "100", - "type": "int", - "value": "0 if infill_sparse_density == 100 else math.ceil(round(parent_value / layer_height, 4))" - } - } - }, - "bottom_thickness": - { - "label": "Bottom Thickness", - "description": "The thickness of the bottom layers in the print. This value divided by the layer height defines the number of bottom layers.", - "unit": "mm", - "default_value": 0.6, - "minimum_value": "0", - "type": "float", - "value": "top_bottom_thickness", - "children": - { - "bottom_layers": - { - "label": "Bottom Layers", - "description": "The number of bottom layers. When calculated by the bottom thickness, this value is rounded to a whole number.", - "minimum_value": "0", - "default_value": 6, - "type": "int", - "value": "999999 if infill_sparse_density == 100 else math.ceil(round(parent_value / layer_height, 4))" - } - } - } - } - }, - "top_bottom_pattern": - { - "label": "Top/Bottom Pattern", - "description": "The pattern of the top/bottom layers.", - "type": "enum", - "options": - { - "lines": "Lines", - "concentric": "Concentric", - "zigzag": "Zig Zag" - }, - "default_value": "lines" - }, - "wall_0_inset": - { - "label": "Outer Wall Inset", - "description": "Inset applied to the path of the outer wall. If the outer wall is smaller than the nozzle, and printed after the inner walls, use this offset to get the hole in the nozzle to overlap with the inner walls instead of the outside of the object.", - "unit": "mm", - "type": "float", - "default_value": 0.0, - "value": "(machine_nozzle_size - wall_line_width_0) / 2 if wall_line_width_0 < machine_nozzle_size else 0", - "minimum_value_warning": "0", - "maximum_value_warning": "machine_nozzle_size" - }, - "alternate_extra_perimeter": - { - "label": "Alternate Extra Wall", - "description": "Prints an extra wall at every other layer. This way infill gets caught between these extra walls, resulting in stronger prints.", - "type": "bool", - "default_value": false - }, - "remove_overlapping_walls_enabled": - { - "label": "Remove Overlapping Wall Parts", - "description": "Remove parts of a wall which share an overlap which would result in overextrusion in some places. These overlaps occur in thin parts and sharp corners in models.", - "type": "bool", - "default_value": false, - "enabled": "False", - "children": - { - "remove_overlapping_walls_0_enabled": - { - "label": "Remove Overlapping Outer Wall Parts", - "description": "Remove parts of an outer wall which share an overlap which would result in overextrusion in some places. These overlaps occur in thin pieces in a model and sharp corners.", - "type": "bool", - "default_value": false, - "value": "remove_overlapping_walls_enabled", - "enabled": "False" - }, - "remove_overlapping_walls_x_enabled": - { - "label": "Remove Overlapping Inner Wall Parts", - "description": "Remove parts of an inner wall that would otherwise overlap and cause over-extrusion. These overlaps occur in thin pieces in a model and sharp corners.", - "type": "bool", - "default_value": true, - "value": "remove_overlapping_walls_enabled" - } - } - }, - "fill_perimeter_gaps": - { - "label": "Fill Gaps Between Walls", - "description": "Fills the gaps between walls when overlapping inner wall parts are removed.", - "type": "enum", - "options": - { - "nowhere": "Nowhere", - "everywhere": "Everywhere", - "skin": "Skin" - }, - "default_value": "everywhere", - "enabled": "remove_overlapping_walls_x_enabled" - }, - "travel_compensate_overlapping_walls_enabled": - { - "label": "Compensate Wall Overlaps", - "description": "Compensate the flow for parts of a wall being printed where there is already a wall in place.", - "type": "bool", - "default_value": true - }, - "xy_offset": - { - "label": "Horizontal Expansion", - "description": "Amount of offset applied to all polygons in each layer. Positive values can compensate for too big holes; negative values can compensate for too small holes.", - "unit": "mm", - "type": "float", - "minimum_value_warning": "-10", - "maximum_value_warning": "10", - "default_value": 0 - }, - "z_seam_type": - { - "label": "Z Seam Alignment", - "description": "Starting point of each path in a layer. When paths in consecutive layers start at the same point a vertical seam may show on the print. When aligning these at the back, the seam is easiest to remove. When placed randomly the inaccuracies at the paths' start will be less noticeable. When taking the shortest path the print will be quicker.", - "type": "enum", - "options": - { - "back": "Back", - "shortest": "Shortest", - "random": "Random" - }, - "default_value": "shortest" - }, - "skin_no_small_gaps_heuristic": - { - "label": "Ignore Small Z Gaps", - "description": "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such case, disable the setting.", - "type": "bool", - "default_value": true - } - } - }, - "infill": - { - "label": "Infill", - "icon": "category_infill", - "description": "Infill", - "type": "category", - "children": - { - "infill_sparse_density": - { - "label": "Infill Density", - "description": "Adjusts the density of infill of the print.", - "unit": "%", - "type": "float", - "default_value": 20, - "minimum_value": "0", - "maximum_value_warning": "100", - "children": - { - "infill_line_distance": - { - "label": "Infill Line Distance", - "description": "Distance between the printed infill lines. This setting is calculated by the infill density and the infill line width.", - "unit": "mm", - "type": "float", - "default_value": 2, - "minimum_value": "0", - "value": "0 if infill_sparse_density == 0 else (infill_line_width * 100) / infill_sparse_density * (2 if infill_pattern == \"grid\" else (3 if infill_pattern == \"triangles\" else 1))" - } - } - }, - "infill_pattern": - { - "label": "Infill Pattern", - "description": "The pattern of the infill material of the print. The line and zig zag infill swap direction on alternate layers, reducing material cost. The grid, triangle and concentric patterns are fully printed every layer.", - "type": "enum", - "options": - { - "grid": "Grid", - "lines": "Lines", - "triangles": "Triangles", - "concentric": "Concentric", - "zigzag": "Zig Zag" - }, - "default_value": "grid", - "value": "'lines' if infill_sparse_density > 25 else 'grid'" - }, - "infill_overlap": - { - "label": "Infill Overlap Percentage", - "description": "The amount of overlap between the infill and the walls. A slight overlap allows the walls to connect firmly to the infill.", - "unit": "%", - "type": "float", - "default_value": 10, - "value": "10 if infill_sparse_density < 95 else 0", - "minimum_value_warning": "-50", - "maximum_value_warning": "100", - "children": - { - "infill_overlap_mm": - { - "label": "Infill Overlap", - "description": "The amount of overlap between the infill and the walls. A slight overlap allows the walls to connect firmly to the infill.", - "unit": "mm", - "type": "float", - "default_value": 0.04, - "minimum_value_warning": "-0.5 * machine_nozzle_size", - "maximum_value_warning": "machine_nozzle_size", - "value": "infill_line_width * infill_overlap / 100 if infill_sparse_density < 95 else 0" - } - } - }, - "infill_wipe_dist": - { - "label": "Infill Wipe Distance", - "description": "Distance of a travel move inserted after every infill line, to make the infill stick to the walls better. This option is similar to infill overlap, but without extrusion and only on one end of the infill line.", - "unit": "mm", - "type": "float", - "default_value": 0.04, - "value": "wall_line_width_0 / 4 if wall_line_count == 1 else wall_line_width_x / 4", - "minimum_value_warning": "0", - "maximum_value_warning": "machine_nozzle_size" - }, - "infill_sparse_thickness": - { - "label": "Infill Layer Thickness", - "description": "The thickness per layer of infill material. This value should always be a multiple of the layer height and is otherwise rounded.", - "unit": "mm", - "type": "float", - "default_value": 0.1, - "minimum_value": "0.0001", - "maximum_value_warning": "0.32", - "maximum_value": "layer_height * 8", - "value": "layer_height" - }, - "infill_before_walls": - { - "label": "Infill Before Walls", - "description": "Print the infill before printing the walls. Printing the walls first may lead to more accurate walls, but overhangs print worse. Printing the infill first leads to sturdier walls, but the infill pattern might sometimes show through the surface.", - "type": "bool", - "default_value": true - } - } - }, - "material": - { - "label": "Material", - "icon": "category_material", - "description": "Material", - "type": "category", - "children": - { - "material_flow_dependent_temperature": - { - "label": "Auto Temperature", - "description": "Change the temperature for each layer automatically with the average flow speed of that layer.", - "type": "bool", - "default_value": false, - "enabled": "False", - "global_only": true - }, - "material_print_temperature": - { - "label": "Printing Temperature", - "description": "The temperature used for printing. Set at 0 to pre-heat the printer manually.", - "unit": "°C", - "type": "float", - "default_value": 210, - "minimum_value": "0", - "maximum_value_warning": "260", - "enabled": "not (material_flow_dependent_temperature)" - }, - "material_flow_temp_graph": - { - "label": "Flow Temperature Graph", - "description": "Data linking material flow (in mm3 per second) to temperature (degrees Celsius).", - "unit": "", - "type": "str", - "default_value": "[[3.5,200],[7.0,240]]", - "enabled": "False", - "comments": "old enabled function: material_flow_dependent_temperature", - "global_only": true - }, - "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", - "type": "float", - "default_value": 0.5, - "minimum_value": "0", - "maximum_value_warning": "10.0", - "global_only": "True", - "enabled": "False", - "comments": "old enabled function: material_flow_dependent_temperature or machine_extruder_count > 1" - }, - "material_bed_temperature": { - "label": "Bed Temperature", - "description": "The temperature used for the heated bed. Set at 0 to pre-heat the printer manually.", - "unit": "°C", - "type": "float", - "default_value": 60, - "minimum_value": "0", - "maximum_value_warning": "260", - "enabled": "machine_heated_bed", - "global_only": "True" - }, - "material_diameter": { - "label": "Diameter", - "description": "Adjusts the diameter of the filament used. Match this value with the diameter of the used filament.", - "unit": "mm", - "type": "float", - "default_value": 2.85, - "minimum_value": "0.0001", - "minimum_value_warning": "0.4", - "maximum_value_warning": "3.5", - "global_only": "True" - }, - "material_flow": { - "label": "Flow", - "description": "Flow compensation: the amount of material extruded is multiplied by this value.", - "unit": "%", - "default_value": 100, - "type": "float", - "minimum_value": "5", - "minimum_value_warning": "50", - "maximum_value_warning": "150" - }, - "retraction_enable": { - "label": "Enable Retraction", - "description": "Retract the filament when the nozzle is moving over a non-printed area. ", - "type": "bool", - "default_value": true - }, - "retraction_amount": { - "label": "Retraction Distance", - "description": "The length of material retracted during a retraction move.", - "unit": "mm", - "type": "float", - "default_value": 6.5, - "minimum_value_warning": "-0.0001", - "maximum_value_warning": "10.0", - "enabled": "retraction_enable" - }, - "retraction_speed": { - "label": "Retraction Speed", - "description": "The speed at which the filament is retracted and primed during a retraction move.", - "unit": "mm/s", - "type": "float", - "default_value": 25, - "minimum_value": "0", - "maximum_value": "299792458000", - "maximum_value_warning": "100", - "enabled": "retraction_enable", - "children": { - "retraction_retract_speed": { - "label": "Retraction Retract Speed", - "description": "The speed at which the filament is retracted during a retraction move.", - "unit": "mm/s", - "type": "float", - "default_value": 25, - "minimum_value": "0", - "maximum_value": "299792458000", - "maximum_value_warning": "100", - "enabled": "retraction_enable", - "value": "retraction_speed" - }, - "retraction_prime_speed": { - "label": "Retraction Prime Speed", - "description": "The speed at which the filament is primed during a retraction move.", - "unit": "mm/s", - "type": "float", - "default_value": 25, - "minimum_value": "0", - "maximum_value": "299792458000", - "maximum_value_warning": "100", - "enabled": "retraction_enable", - "value": "retraction_speed" - } - } - }, - "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³", - "type": "float", - "default_value": 0, - "minimum_value_warning": "-0.0001", - "maximum_value_warning": "5.0", - "enabled": "retraction_enable" - }, - "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", - "type": "float", - "default_value": 1.5, - "value": "line_width * 2", - "minimum_value": "0", - "maximum_value_warning": "10", - "enabled": "retraction_enable" - }, - "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": 45, - "minimum_value": "0", - "maximum_value_warning": "100", - "type": "int", - "enabled": "retraction_enable" - }, - "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", - "type": "float", - "default_value": 4.5, - "minimum_value": "0", - "maximum_value_warning": "retraction_amount * 2", - "value": "retraction_amount", - "enabled": "retraction_enable" - }, - "retraction_hop": { - "label": "Z Hop when Retracting", - "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.", - "unit": "mm", - "type": "float", - "default_value": 0, - "minimum_value_warning": "-0.0001", - "maximum_value_warning": "10", - "enabled": "retraction_enable" - } - } - }, - "speed": - { - "label": "Speed", - "icon": "category_speed", - "description": "Speed", - "type": "category", - "children": - { - "speed_print": - { - "label": "Print Speed", - "description": "The speed at which printing happens.", - "unit": "mm/s", - "type": "float", - "minimum_value": "0.1", - "maximum_value_warning": "150", - "maximum_value": "299792458000", - "default_value": 60, - "children": - { - "speed_infill": - { - "label": "Infill Speed", - "description": "The speed at which infill is printed.", - "unit": "mm/s", - "type": "float", - "minimum_value": "0.1", - "maximum_value": "299792458000", - "maximum_value_warning": "150", - "default_value": 60, - "value": "speed_print" - }, - "speed_wall": - { - "label": "Wall Speed", - "description": "The speed at which the walls are printed.", - "unit": "mm/s", - "type": "float", - "minimum_value": "0.1", - "maximum_value": "299792458000", - "maximum_value_warning": "150", - "default_value": 30, - "value": "speed_print / 2", - "children": - { - "speed_wall_0": - { - "label": "Outer Wall Speed", - "description": "The speed at which the outermost walls are printed. Printing the outer wall at a lower speed improves the final skin quality. However, having a large difference between the inner wall speed and the outer wall speed will effect quality in a negative way.", - "unit": "mm/s", - "type": "float", - "minimum_value": "0.1", - "maximum_value": "299792458000", - "maximum_value_warning": "150", - "default_value": 30, - "value": "speed_wall" - }, - "speed_wall_x": - { - "label": "Inner Wall Speed", - "description": "The speed at which all inner walls are printed Printing the inner wall faster than the outer wall will reduce printing time. It works well to set this in between the outer wall speed and the infill speed.", - "unit": "mm/s", - "type": "float", - "minimum_value": "0.1", - "maximum_value": "299792458000", - "maximum_value_warning": "150", - "default_value": 60, - "value": "speed_wall * 2" - } - } - }, - "speed_topbottom": - { - "label": "Top/Bottom Speed", - "description": "The speed at which top/bottom layers are printed.", - "unit": "mm/s", - "type": "float", - "minimum_value": "0.1", - "maximum_value": "299792458000", - "maximum_value_warning": "150", - "default_value": 30, - "value": "speed_print / 2" - }, - "speed_support": - { - "label": "Support Speed", - "description": "The speed at which the support structure is printed. Printing support at higher speeds can greatly reduce printing time. The surface quality of the support structure is not important since it is removed after printing.", - "unit": "mm/s", - "type": "float", - "minimum_value": "0.1", - "maximum_value": "299792458000", - "maximum_value_warning": "150", - "default_value": 60, - "value": "speed_print", - "enabled": "support_roof_enable", - "children": - { - "speed_support_infill": - { - "label": "Support Infill Speed", - "description": "The speed at which the infill of support is printed. Printing the infill at lower speeds improves stability.", - "unit": "mm/s", - "type": "float", - "default_value": 60, - "minimum_value": "0.1", - "maximum_value": "299792458000", - "maximum_value_warning": "150", - "value": "speed_support", - "enabled": "support_enable", - "global_only": true - }, - "speed_support_roof": - { - "label": "Support Roof Speed", - "description": "The speed at which the roofs of support are printed. Printing the support roof at lower speeds can improve overhang quality.", - "unit": "mm/s", - "type": "float", - "default_value": 40, - "minimum_value": "0.1", - "maximum_value": "299792458000", - "maximum_value_warning": "150", - "enabled": "support_roof_enable", - "value": "speed_support / 1.5", - "global_only": true - } - } - } - } - }, - "speed_travel": - { - "label": "Travel Speed", - "description": "The speed at which travel moves are made.", - "unit": "mm/s", - "type": "float", - "default_value": 120, - "minimum_value": "0.1", - "maximum_value": "299792458000", - "maximum_value_warning": "300", - "value": "speed_print if magic_spiralize else 120", - "global_only": true - }, - "speed_layer_0": { - "label": "Initial Layer Speed", - "description": "The print speed for the initial layer. A lower value is advised to improve adhesion to the build plate.", - "unit": "mm/s", - "type": "float", - "default_value": 30, - "minimum_value": "0.1", - "maximum_value": "299792458000", - "maximum_value_warning": "300" - }, - "skirt_speed": { - "label": "Skirt 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 at a different speed.", - "unit": "mm/s", - "type": "float", - "default_value": 30, - "minimum_value": "0.1", - "maximum_value": "299792458000", - "maximum_value_warning": "300", - "value": "speed_layer_0", - "global_only": true - }, - "speed_slowdown_layers": - { - "label": "Number of Slower Layers", - "description": "The first few layers are printed slower than the rest of the object, to get better adhesion to the build plate and improve the overall success rate of prints. The speed is gradually increased over these layers.", - "type": "int", - "default_value": 2, - "minimum_value": "0", - "maximum_value": "299792458000", - "maximum_value_warning": "300", - "global_only": true - } - } - }, - "travel": - { - "label": "Travel", - "icon": "category_travel", - "description": "travel", - "type": "category", - "children": - { - "retraction_combing": - { - "label": "Combing Mode", - "description": "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas by combing within the infill only. It is also possible to avoid combing over top/bottom skin areas by combing within the infill only.", - "type": "enum", - "options": - { - "off": "Off", - "all": "All", - "noskin": "No Skin" - }, - "default_value": "all", - "global_only": true - }, - "travel_avoid_other_parts": - { - "label": "Avoid Printed Parts when Traveling", - "description": "The nozzle avoids already printed parts when traveling. This option is only available when combing is enabled.", - "type": "bool", - "default_value": true, - "enabled": "retraction_combing != \"off\"", - "global_only": "True" - }, - "travel_avoid_distance": - { - "label": "Travel Avoid Distance", - "description": "The distance between the nozzle and already printed parts when avoiding during travel moves.", - "unit": "mm", - "type": "float", - "default_value": 1.5, - "value": "machine_nozzle_tip_outer_diameter / 2 * 1.25", - "minimum_value": "0", - "maximum_value_warning": "machine_nozzle_tip_outer_diameter * 5", - "enabled": "retraction_combing != \"off\" and travel_avoid_other_parts", - "global_only": "True" - } - } - }, - "cooling": - { - "label": "Cooling", - "icon": "category_cool", - "description": "Cooling", - "type": "category", - "children": - { - "cool_fan_enabled": - { - "label": "Enable Cooling Fans", - "description": "Enables the cooling fans while printing. The fans improve print quality on layers with short layer times and bridging / overhangs.", - "type": "bool", - "default_value": true, - "global_only": "True" - }, - "cool_fan_speed": - { - "label": "Fan Speed", - "description": "The speed at which the cooling fans spin.", - "unit": "%", - "type": "float", - "minimum_value": "0", - "maximum_value": "100", - "default_value": 100, - "value": "100.0 if cool_fan_enabled else 0.0", - "enabled": "cool_fan_enabled", - "global_only": "True", - "children": - { - "cool_fan_speed_min": - { - "label": "Regular Fan Speed", - "description": "The speed at which the fans spin before hitting the threshold. When a layer prints faster than the threshold, the fan speed gradually inclines towards the maximum fan speed.", - "unit": "%", - "type": "float", - "minimum_value": "0", - "maximum_value": "100", - "value": "cool_fan_speed", - "default_value": 100, - "enabled": "cool_fan_enabled", - "global_only": "True" - }, - "cool_fan_speed_max": - { - "label": "Maximum Fan Speed", - "description": "The speed at which the fans spin on the minimum layer time. The fan speed gradually increases between the regular fan speed and maximum fan speed when the threshold is hit.", - "unit": "%", - "type": "float", - "minimum_value": "max(0, cool_fan_speed_min)", - "maximum_value": "100", - "default_value": 100, - "enabled": "cool_fan_enabled", - "global_only": "True", - "value": "cool_fan_speed" - } - } - }, - "cool_min_layer_time_fan_speed_max": - { - "label": "Regular/Maximum Fan Speed Threshold", - "description": "The layer time which sets the threshold between regular fan speed and maximum fan speed. Layers that print slower than this time use regular fan speed. For faster layers the fan speed gradually increases towards the maximum fan speed.", - "unit": "sec", - "type": "float", - "default_value": 10, - "minimum_value": "cool_min_layer_time", - "maximum_value_warning": "600", - "global_only": "True" - }, - "cool_fan_full_at_height": - { - "label": "Regular Fan Speed at Height", - "description": "The height at which the fans spin on regular fan speed. At the layers below the fan speed gradually increases from zero to regular fan speed.", - "unit": "mm", - "type": "float", - "default_value": 0.5, - "value": "layer_height_0", - "minimum_value": "0", - "maximum_value_warning": "10.0", - "global_only": "True", - "children": - { - "cool_fan_full_layer": - { - "label": "Regular Fan Speed at Layer", - "description": "The layer at which the fans spin on regular fan speed. If regular fan speed at height is set, this value is calculated and rounded to a whole number.", - "type": "int", - "default_value": 1, - "minimum_value": "0", - "maximum_value_warning": "100", - "value": "int((cool_fan_full_at_height - layer_height_0 + 0.001) / layer_height) + 1", - "global_only": "True" - } - } - }, - "cool_min_layer_time": - { - "label": "Minimum Layer Time", - "description": "The minimum time spent in a layer. This forces the printer to slow down, to at least spend the time set here in one layer. This allows the printed material to cool down properly before printing the next layer.", - "unit": "sec", - "type": "float", - "default_value": 5, - "minimum_value": "0", - "maximum_value_warning": "600", - "global_only": "True" - }, - "cool_min_speed": - { - "label": "Minimum Speed", - "description": "The minimum print speed, despite slowing down due to the minimum layer time. When the printer would slow down too much, the pressure in the nozzle would be too low and result in bad print quality.", - "unit": "mm/s", - "type": "float", - "default_value": 10, - "minimum_value": "0", - "maximum_value_warning": "100", - "global_only": "True" - }, - "cool_lift_head": - { - "label": "Lift Head", - "description": "When the minimum speed is hit because of minimum layer time, lift the head away from the print and wait the extra time until the minimum layer time is reached.", - "type": "bool", - "default_value": false, - "global_only": "True" - } - } - }, - "support": - { - "label": "Support", - "type": "category", - "icon": "category_support", - "description": "Support", - "children": - { - "support_enable": - { - "label": "Enable Support", - "description": "Enable support structures. These structures support parts of the model with severe overhangs.", - "type": "bool", - "default_value": false - }, - "support_type": - { - "label": "Support Placement", - "description": "Adjusts the placement of the support structures. The placement can be set to touching build plate or everywhere. When set to everywhere the support structures will also be printed on the model.", - "type": "enum", - "options": - { - "buildplate": "Touching Buildplate", - "everywhere": "Everywhere" - }, - "default_value": "everywhere", - "enabled": "support_enable" - }, - "support_angle": - { - "label": "Support Overhang Angle", - "description": "The minimum angle of overhangs for which support is added. At a value of 0° all overhangs are supported, 90° will not provide any support.", - "unit": "°", - "type": "float", - "minimum_value": "0", - "maximum_value": "90", - "default_value": 50, - "enabled": "support_enable" - }, - "support_pattern": - { - "label": "Support Pattern", - "description": "The pattern of the support structures of the print. The different options available result in sturdy or easy to remove support.", - "type": "enum", - "options": - { - "lines": "Lines", - "grid": "Grid", - "triangles": "Triangles", - "concentric": "Concentric", - "zigzag": "Zig Zag" - }, - "default_value": "zigzag", - "enabled": "support_enable", - "global_only": true - }, - "support_connect_zigzags": - { - "label": "Connect Support ZigZags", - "description": "Connect the ZigZags. This will increase the strength of the zig zag support structure.", - "type": "bool", - "default_value": true, - "enabled": "support_enable and (support_pattern == \"zigzag\")", - "global_only": true - }, - "support_infill_rate": - { - "label": "Support Density", - "description": "Adjusts the density of the support structure. A higher value results in better overhangs, but the supports are harder to remove.", - "unit": "%", - "type": "float", - "minimum_value": "0", - "maximum_value_warning": "100", - "default_value": 15, - "enabled": "support_enable", - "global_only": true, - "children": { - "support_line_distance": - { - "label": "Support Line Distance", - "description": "Distance between the printed support structure lines. This setting is calculated by the support density.", - "unit": "mm", - "type": "float", - "minimum_value": "0", - "default_value": 2.66, - "enabled": "support_enable", - "value": "(support_line_width * 100) / support_infill_rate * (2 if support_pattern == \"grid\" else (3 if support_pattern == \"triangles\" else 1))", - "global_only": true - } - } - }, - "support_xy_distance": - { - "label": "Support X/Y Distance", - "description": "Distance of the support structure from the print in the X/Y directions.", - "unit": "mm", - "type": "float", - "minimum_value": "0", - "maximum_value_warning": "10", - "default_value": 0.7, - "enabled": "support_enable" - }, - "support_z_distance": - { - "label": "Support Z Distance", - "description": "Distance from the top/bottom of the support structure to the print. This gap provides clearance to remove the supports after the model is printed. This value is rounded down to a multiple of the layer height.", - "unit": "mm", - "type": "float", - "minimum_value": "0", - "maximum_value_warning": "10", - "default_value": 0.15, - "enabled": "support_enable", - - "children": - { - "support_top_distance": - { - "label": "Support Top Distance", - "description": "Distance from the top of the support to the print.", - "unit": "mm", - "minimum_value": "0", - "maximum_value_warning": "10", - "default_value": 0.15, - "type": "float", - "enabled": "support_enable", - "value": "support_z_distance" - }, - "support_bottom_distance": - { - "label": "Support Bottom Distance", - "description": "Distance from the print to the bottom of the support.", - "unit": "mm", - "minimum_value": "0", - "maximum_value_warning": "10", - "default_value": 0.1, - "value": "0.1 if support_type == 'everywhere' else 0", - "type": "float", - "enabled": "support_enable and support_type == 'everywhere'" - } - } - }, - "support_bottom_stair_step_height": - { - "label": "Support Stair Step Height", - "description": "The height of the steps of the stair-like bottom of support resting on the model. A low value makes the support harder to remove, but too high values can lead to unstable support structures.", - "unit": "mm", - "type": "float", - "default_value": 0.3, - "minimum_value": "0", - "maximum_value_warning": "1.0", - "enabled": "support_enable" - }, - "support_join_distance": - { - "label": "Support Join Distance", - "description": "The maximum distance between support structures in the X/Y directions. When seperate structures are closer together than this value, the structures merge into one.", - "unit": "mm", - "type": "float", - "default_value": 2.0, - "minimum_value_warning": "0", - "maximum_value_warning": "10", - "enabled": "support_enable" - }, - "support_offset": - { - "label": "Support Horizontal Expansion", - "description": "Amount of offset applied to all support polygons in each layer. Positive values can smooth out the support areas and result in more sturdy support.", - "unit": "mm", - "type": "float", - "default_value": 0.2, - "minimum_value_warning": "-0.5", - "maximum_value_warning": "5.0", - "enabled": "support_enable" - }, - "support_area_smoothing": - { - "label": "Support Area Smoothing", - "description": "Maximum distance in the X/Y directions of a line segment which is to be smoothed out. Ragged lines are introduced by the join distance and support bridge, which cause the machine to resonate. Smoothing the support areas won't cause them to break with the constraints, except it might change the overhang.", - "unit": "mm", - "type": "float", - "default_value": 0.6, - "minimum_value": "0", - "maximum_value_warning": "1.0", - "enabled": "support_enable" - }, - "support_roof_enable": - { - "label": "Enable Support Roof", - "description": "Generate a dense top skin at the top of the support on which the model is printed.", - "type": "bool", - "default_value": false, - "enabled": "support_enable" - }, - "support_roof_height": - { - "label": "Support Roof Thickness", - "description": "The thickness of the support roofs.", - "unit": "mm", - "type": "float", - "default_value": 1, - "minimum_value": "0", - "maximum_value_warning": "10", - "enabled": "support_roof_enable" - }, - "support_roof_density": - { - "label": "Support Roof Density", - "description": "Adjusts the density of the roof of the support structure. A higher value results in better overhangs, but the supports are harder to remove.", - "unit": "%", - "type": "float", - "default_value": 100, - "minimum_value": "0", - "maximum_value_warning": "100", - "enabled":"support_roof_enable", - "global_only": true, - "children": - { - "support_roof_line_distance": - { - "label": "Support Roof Line Distance", - "description": "Distance between the printed support roof lines. This setting is calculated by the support roof Density, but can be adjusted separately.", - "unit": "mm", - "type": "float", - "default_value": 0.4, - "minimum_value": "0", - "value": "0 if support_roof_density == 0 else (support_roof_line_width * 100) / support_roof_density * (2 if support_roof_pattern == \"grid\" else (3 if support_roof_pattern == \"triangles\" else 1))", - "enabled": "support_roof_enable", - "global_only": true - } - } - }, - "support_roof_pattern": - { - "label": "Support Roof Pattern", - "description": "The pattern with which the top of the support is printed.", - "type": "enum", - "options": - { - "lines": "Lines", - "grid": "Grid", - "triangles": "Triangles", - "concentric": "Concentric", - "zigzag": "Zig Zag" - }, - "default_value": "concentric", - "enabled": "support_roof_enable", - "global_only": true - }, - "support_use_towers": - { - "label": "Use Towers", - "description": "Use specialized towers to support tiny overhang areas. These towers have a larger diameter than the region they support. Near the overhang the towers' diameter decreases, forming a roof.", - "type": "bool", - "default_value": true, - "enabled": "support_enable" - }, - "support_tower_diameter": - { - "label": "Tower Diameter", - "description": "The diameter of a special tower.", - "unit": "mm", - "type": "float", - "default_value": 3.0, - "minimum_value": "0", - "maximum_value_warning": "10", - "enabled": "support_enable and support_use_towers" - }, - "support_minimal_diameter": - { - "label": "Minimum Diameter", - "description": "Minimum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower.", - "unit": "mm", - "type": "float", - "default_value": 3.0, - "minimum_value": "0", - "maximum_value_warning": "10", - "maximum_value": "support_tower_diameter", - "enabled": "support_enable and support_use_towers" - }, - "support_tower_roof_angle": - { - "label": "Tower Roof Angle", - "description": "The angle of a rooftop of a tower. A higher value results in pointed tower roofs, a lower value results in flattened tower roofs.", - "unit": "°", - "type": "int", - "minimum_value": "0", - "maximum_value": "90", - "default_value": 65, - "enabled": "support_enable and support_use_towers" - } - } - }, - "platform_adhesion": - { - "label": "Platform Adhesion", - "type": "category", - "icon": "category_adhesion", - "description": "Adhesion", - "children": - { - "adhesion_type": - { - "label": "Platform Adhesion Type", - "description": "Different options that help to improve both priming your extrusion and adhesion to the build plate. Brim adds a single layer flat area around the base of your object to prevent warping. Raft adds a thick grid with a roof below the object. Skirt is a line printed around the object, but not connected to the model.", - "type": "enum", - "options": - { - "skirt": "Skirt", - "brim": "Brim", - "raft": "Raft" - }, - "default_value": "brim", - "global_only": "True" - }, - "skirt_line_count": - { - "label": "Skirt Line Count", - "description": "Multiple skirt lines help to prime your extrusion better for small objects. Setting this to 0 will disable the skirt.", - "type": "int", - "default_value": 1, - "minimum_value": "0", - "maximum_value_warning": "10", - "enabled": "adhesion_type == \"skirt\"", - "global_only": "True" - }, - "skirt_gap": - { - "label": "Skirt Distance", - "description": "The horizontal distance between the skirt and the first layer of the print.\nThis is the minimum distance, multiple skirt lines will extend outwards from this distance.", - "unit": "mm", - "type": "float", - "default_value": 3, - "minimum_value_warning": "0", - "maximum_value_warning": "100", - "enabled": "adhesion_type == \"skirt\"", - "global_only": "True" - }, - "skirt_minimal_length": - { - "label": "Skirt Minimum Length", - "description": "The minimum length of the skirt. If this length is not reached by the skirt line count, more skirt lines will be added until the minimum length is reached. Note: If the line count is set to 0 this is ignored.", - "unit": "mm", - "type": "float", - "default_value": 250, - "minimum_value": "0", - "minimum_value_warning": "25", - "maximum_value_warning": "2500", - "enabled": "adhesion_type == \"skirt\"", - "global_only": "True" - }, - "brim_width": - { - "label": "Brim Width", - "description": "The distance from the model to the outermost brim line. A larger brim enhances adhesion to the build plate, but also reduces the effective print area.", - "type": "float", - "unit": "mm", - "default_value": 8.0, - "minimum_value": "0.0", - "maximum_value_warning": "100.0", - "enabled": "adhesion_type == \"brim\"", - "global_only": "True", - "children": - { - "brim_line_count": - { - "label": "Brim Line Count", - "description": "The number of lines used for a brim. More brim lines enhance adhesion to the build plate, but also reduces the effective print area.", - "type": "int", - "default_value": 20, - "minimum_value": "0", - "maximum_value_warning": "300", - "value": "math.ceil(brim_width / skirt_line_width)", - "enabled": "adhesion_type == \"brim\"", - "global_only": "True" - } - } - }, - "raft_margin": - { - "label": "Raft Extra Margin", - "description": "If the raft is enabled, this is the extra raft area around the object which is also given a raft. Increasing this margin will create a stronger raft while using more material and leaving less area for your print.", - "unit": "mm", - "type": "float", - "default_value": 5, - "minimum_value_warning": "0", - "maximum_value_warning": "10", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True" - }, - "raft_airgap": - { - "label": "Raft Air Gap", - "description": "The gap between the final raft layer and the first layer of the object. Only the first layer is raised by this amount to lower the bonding between the raft layer and the object. Makes it easier to peel off the raft.", - "unit": "mm", - "type": "float", - "default_value": 0.35, - "minimum_value": "0", - "maximum_value_warning": "1.0", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True" - }, - "raft_surface_layers": - { - "label": "Raft Top Layers", - "description": "The number of top layers on top of the 2nd raft layer. These are fully filled layers that the object sits on. 2 layers result in a smoother top surface than 1.", - "type": "int", - "default_value": 2, - "minimum_value": "0", - "maximum_value_warning": "20", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True" - }, - "raft_surface_thickness": - { - "label": "Raft Top Layer Thickness", - "description": "Layer thickness of the top raft layers.", - "unit": "mm", - "type": "float", - "default_value": 0.1, - "minimum_value": "0", - "maximum_value_warning": "2.0", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True" - }, - "raft_surface_line_width": - { - "label": "Raft Top Line Width", - "description": "Width of the lines in the top surface of the raft. These can be thin lines so that the top of the raft becomes smooth.", - "unit": "mm", - "type": "float", - "default_value": 0.3, - "minimum_value": "0.0001", - "maximum_value_warning": "machine_nozzle_size * 2", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True" - }, - "raft_surface_line_spacing": - { - "label": "Raft Top Spacing", - "description": "The distance between the raft lines for the top raft layers. The spacing should be equal to the line width, so that the surface is solid.", - "unit": "mm", - "type": "float", - "default_value": 0.3, - "minimum_value": "0.0001", - "maximum_value_warning": "5.0", - "enabled": "adhesion_type == \"raft\"", - "value": "raft_surface_line_width", - "global_only": "True" - }, - "raft_interface_thickness": - { - "label": "Raft Middle Thickness", - "description": "Layer thickness of the middle raft layer.", - "unit": "mm", - "type": "float", - "default_value": 0.27, - "minimum_value": "0", - "maximum_value_warning": "5.0", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True" - }, - "raft_interface_line_width": - { - "label": "Raft Middle Line Width", - "description": "Width of the lines in the middle raft layer. Making the second layer extrude more causes the lines to stick to the bed.", - "unit": "mm", - "type": "float", - "default_value": 1, - "value": "line_width", - "minimum_value": "0.0001", - "maximum_value_warning": "machine_nozzle_size * 2", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True" - }, - "raft_interface_line_spacing": - { - "label": "Raft Middle Spacing", - "description": "The distance between the raft lines for the middle raft layer. The spacing of the middle should be quite wide, while being dense enough to support the top raft layers.", - "unit": "mm", - "type": "float", - "default_value": 1.0, - "minimum_value": "0", - "maximum_value_warning": "15.0", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True" - }, - "raft_base_thickness": - { - "label": "Raft Base Thickness", - "description": "Layer thickness of the base raft layer. This should be a thick layer which sticks firmly to the printer bed.", - "unit": "mm", - "type": "float", - "default_value": 0.3, - "minimum_value": "0", - "maximum_value_warning": "5.0", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True" - }, - "raft_base_line_width": - { - "label": "Raft Base Line Width", - "description": "Width of the lines in the base raft layer. These should be thick lines to assist in bed adhesion.", - "unit": "mm", - "type": "float", - "default_value": 1, - "minimum_value": "0.0001", - "value": "line_width", - "maximum_value_warning": "machine_nozzle_size * 2", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True" - }, - "raft_base_line_spacing": - { - "label": "Raft Line Spacing", - "description": "The distance between the raft lines for the base raft layer. Wide spacing makes for easy removal of the raft from the build plate.", - "unit": "mm", - "type": "float", - "default_value": 3.0, - "minimum_value": "0.0001", - "maximum_value_warning": "100", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True" - }, - "raft_speed": - { - "label": "Raft Print Speed", - "description": "The speed at which the raft is printed.", - "unit": "mm/s", - "type": "float", - "default_value": 30, - "minimum_value": "0.1", - "maximum_value": "299792458000", - "maximum_value_warning": "200", - "enabled": "adhesion_type == \"raft\"", - "value": "speed_print / 60 * 30", - "global_only": "True", - "children": - { - "raft_surface_speed": - { - "label": "Raft Surface Print Speed", - "description": "The speed at which the surface raft layers are printed. These should be printed a bit slower, so that the nozzle can slowly smooth out adjacent surface lines.", - "unit": "mm/s", - "type": "float", - "default_value": 30, - "minimum_value": "0.1", - "maximum_value": "299792458000", - "maximum_value_warning": "100", - "enabled": "adhesion_type == \"raft\"", - "value": "raft_speed", - "global_only": "True" - }, - "raft_interface_speed": - { - "label": "Raft Interface Print Speed", - "description": "The speed at which the interface raft layer is printed. This should be printed quite slowly, as the volume of material coming out of the nozzle is quite high.", - "unit": "mm/s", - "type": "float", - "default_value": 15, - "minimum_value": "0.1", - "maximum_value": "299792458000", - "maximum_value_warning": "150", - "enabled": "adhesion_type == \"raft\"", - "value": "0.5 * raft_speed", - "global_only": "True" - }, - "raft_base_speed": - { - "label": "Raft Base Print Speed", - "description": "The speed at which the base raft layer is printed. This should be printed quite slowly, as the volume of material coming out of the nozzle is quite high.", - "unit": "mm/s", - "type": "float", - "default_value": 15, - "minimum_value": "0.1", - "maximum_value": "299792458000", - "maximum_value_warning": "200", - "enabled": "adhesion_type == \"raft\"", - "value": "0.5 * raft_speed", - "global_only": "True" - } - } - }, - "raft_fan_speed": - { - "label": "Raft Fan Speed", - "description": "The fan speed for the raft.", - "unit": "%", - "type": "float", - "minimum_value": "0", - "maximum_value": "100", - "default_value": 100, - "global_only": "True", - "enabled": "adhesion_type == \"raft\"", - "children": - { - "raft_surface_fan_speed": - { - "label": "Raft Surface Fan Speed", - "description": "The fan speed for the surface raft layers.", - "unit": "%", - "type": "float", - "minimum_value": "0", - "maximum_value": "100", - "default_value": 100, - "global_only": "True", - "value": "raft_fan_speed", - "enabled": "adhesion_type == \"raft\"" - }, - "raft_interface_fan_speed": - { - "label": "Raft Interface Fan Speed", - "description": "The fan speed for the interface raft layer.", - "unit": "%", - "type": "float", - "minimum_value": "0", - "maximum_value": "100", - "default_value": 100, - "global_only": "True", - "value": "raft_fan_speed", - "enabled": "adhesion_type == \"raft\"" - }, - "raft_base_fan_speed": - { - "label": "Raft Base Fan Speed", - "description": "The fan speed for the base raft layer.", - "unit": "%", - "type": "float", - "minimum_value": "0", - "maximum_value": "100", - "default_value": 100, - "global_only": "True", - "value": "raft_fan_speed", - "enabled": "adhesion_type == \"raft\"" - } - } - } - } - }, - "meshfix": - { - "label": "Mesh Fixes", - "type": "category", - "icon": "category_fixes", - "description": "category_fixes", - "children": - { - "meshfix_union_all": - { - "label": "Union Overlapping Volumes", - "description": "Ignore the internal geometry arising from overlapping volumes and print the volumes as one. This may cause internal cavities to disappear.", - "type": "bool", - "default_value": true - }, - "meshfix_union_all_remove_holes": - { - "label": "Remove All Holes", - "description": "Remove the holes in each layer and keep only the outside shape. This will ignore any invisible internal geometry. However, it also ignores layer holes which can be viewed from above or below.", - "type": "bool", - "default_value": false - }, - "meshfix_extensive_stitching": - { - "label": "Extensive Stitching", - "description": "Extensive stitching tries to stitch up open holes in the mesh by closing the hole with touching polygons. This option can introduce a lot of processing time.", - "type": "bool", - "default_value": false - }, - "meshfix_keep_open_polygons": - { - "label": "Keep Disconnected Faces", - "description": "Normally Cura tries to stitch up small holes in the mesh and remove parts of a layer with big holes. Enabling this option keeps those parts which cannot be stitched. This option should be used as a last resort option when everything else fails to produce proper GCode.", - "type": "bool", - "default_value": false - } - } - }, - "blackmagic": - { - "label": "Special Modes", - "type": "category", - "icon": "category_blackmagic", - "description": "category_blackmagic", - "children": - { - "print_sequence": - { - "label": "Print Sequence", - "description": "Whether to print all objects one layer at a time or to wait for one object to finish, before moving on to the next. One at a time mode is only possible if all models are separated in such a way that the whole print head can move in between and all models are lower than the distance between the nozzle and the X/Y axes.", - "type": "enum", - "options": - { - "all_at_once": "All at Once", - "one_at_a_time": "One at a Time" - }, - "default_value": "all_at_once", - "global_only": true - }, - "magic_mesh_surface_mode": - { - "label": "Surface Mode", - "description": "Treat the model as a surface only, a volume, or volumes with loose surfaces. The normal print mode only prints enclosed volumes. \"Surface\" prints a single wall tracing the mesh surface with no infill and no top/bottom skin. \"Both\" prints enclosed volumes like normal and any remaining polygons as surfaces.", - "type": "enum", - "options": - { - "normal": "Normal", - "surface": "Surface", - "both": "Both" - }, - "default_value": "normal" - }, - "magic_spiralize": - { - "label": "Spiralize Outer Contour", - "description": "Spiralize smooths out the Z move of the outer edge. This will create a steady Z increase over the whole print. This feature turns a solid object into a single walled print with a solid bottom. This feature used to be called Joris in older versions.", - "type": "bool", - "default_value": false, - "global_only": "True" - } - } - }, - "experimental": - { - "label": "Experimental Modes", - "type": "category", - "icon": "category_blackmagic", - "description": "experimental!", - "children": - { - "draft_shield_enabled": - { - "label": "Enable Draft Shield", - "description": "This will create a wall around the object, which traps (hot) air and shields against exterior airflow. Especially useful for materials which warp easily.", - "type": "bool", - "default_value": false, - "global_only": true - }, - "draft_shield_dist": - { - "label": "Draft Shield X/Y Distance", - "description": "Distance of the draft shield from the print, in the X/Y directions.", - "unit": "mm", - "type": "float", - "minimum_value": "0", - "maximum_value_warning": "100", - "default_value": 10, - "enabled": "draft_shield_enabled", - "global_only": true - }, - "draft_shield_height_limitation": - { - "label": "Draft Shield Limitation", - "description": "Set the height of the draft shield. Choose to print the draft shield at the full height of the object or at a limited height.", - "type": "enum", - "options": - { - "full": "Full", - "limited": "Limited" - }, - "default_value": "full", - "enabled": "draft_shield_enabled", - "global_only": true - }, - "draft_shield_height": - { - "label": "Draft Shield Height", - "description": "Height limitation of the draft shield. Above this height no draft shield will be printed.", - "unit": "mm", - "type": "float", - "minimum_value": "0", - "maximum_value_warning": "9999", - "default_value": 0, - "value": "9999 if draft_shield_height_limitation == 'full' and draft_shield_enabled else 0.0", - "enabled": "draft_shield_height_limitation == \"limited\"", - "global_only": true - }, - "coasting_enable": - { - "label": "Enable Coasting", - "description": "Coasting replaces the last part of an extrusion path with a travel path. The oozed material is used to print the last piece of the extrusion path in order to reduce stringing.", - "type": "bool", - "default_value": false, - "global_only": true - }, - "coasting_volume": - { - "label": "Coasting Volume", - "description": "The volume otherwise oozed. This value should generally be close to the nozzle diameter cubed.", - "unit": "mm³", - "type": "float", - "default_value": 0.064, - "minimum_value": "0", - "maximum_value_warning": "2.0", - "enabled": "coasting_enable", - "global_only": true - }, - "coasting_min_volume": - { - "label": "Minimum Volume Before Coasting", - "description": "The smallest volume an extrusion path should have before allowing coasting. For smaller extrusion paths, less pressure has been built up in the bowden tube and so the coasted volume is scaled linearly. This value should always be larger than the Coasting Volume.", - "unit": "mm³", - "type": "float", - "default_value": 0.8, - "minimum_value": "0", - "maximum_value_warning": "10.0", - "enabled": "coasting_enable", - "global_only": true - }, - "coasting_speed": - { - "label": "Coasting Speed", - "description": "The speed by which to move during coasting, relative to the speed of the extrusion path. A value slightly under 100% is advised, since during the coasting move the pressure in the bowden tube drops.", - "unit": "%", - "type": "float", - "default_value": 90, - "minimum_value": "0.0001", - "maximum_value_warning": "100", - "enabled": "coasting_enable", - "global_only": true - }, - "skin_outline_count": - { - "label": "Extra Skin Wall Count", - "description": "Replaces the outermost part of the top/bottom pattern with a number of concentric lines. Using one or two lines improves roofs that start on infill material.", - "default_value": 0, - "minimum_value": "0", - "maximum_value_warning": "10", - "type": "int" - }, - "skin_alternate_rotation": - { - "label": "Alternate Skin Rotation", - "description": "Alternate the direction in which the top/bottom layers are printed. Normally they are printed diagonally only. This setting adds the X-only and Y-only directions.", - "type": "bool", - "default_value": false, - "enabled": "top_bottom_pattern != \"concentric\"" - }, - "support_conical_enabled": - { - "label": "Enable Conical Support", - "description": "Experimental feature: Make support areas smaller at the bottom than at the overhang.", - "type": "bool", - "default_value": false, - "enabled": "support_enable" - }, - "support_conical_angle": - { - "label": "Conical Support Angle", - "description": "The angle of the tilt of conical support. With 0 degrees being vertical, and 90 degrees being horizontal. Smaller angles cause the support to be more sturdy, but consist of more material. Negative angles cause the base of the support to be wider than the top.", - "unit": "°", - "type": "float", - "minimum_value": "-90", - "minimum_value_warning": "-45", - "maximum_value_warning": "45", - "maximum_value": "90", - "default_value": 30, - "enabled": "support_conical_enabled and support_enable" - }, - "support_conical_min_width": - { - "label": "Conical Support Minimum Width", - "description": "Minimum width to which the base of the conical support area is reduced. Small widths can lead to unstable support structures.", - "unit": "mm", - "default_value": 5.0, - "minimum_value": "0", - "minimum_value_warning": "machine_nozzle_size * 3", - "maximum_value_warning": "100.0", - "type": "float", - "enabled": "support_conical_enabled and support_enable" - }, - "magic_fuzzy_skin_enabled": - { - "label": "Fuzzy Skin", - "description": "Randomly jitter while printing the outer wall, so that the surface has a rough and fuzzy look.", - "type": "bool", - "default_value": false - }, - "magic_fuzzy_skin_thickness": - { - "label": "Fuzzy Skin Thickness", - "description": "The width within which to jitter. It's advised to keep this below the outer wall width, since the inner walls are unaltered.", - "type": "float", - "unit": "mm", - "default_value": 0.3, - "minimum_value": "0.001", - "maximum_value_warning": "wall_line_width_0", - "enabled": "magic_fuzzy_skin_enabled" - }, - "magic_fuzzy_skin_point_density": - { - "label": "Fuzzy Skin Density", - "description": "The average density of points introduced on each polygon in a layer. Note that the original points of the polygon are discarded, so a low density results in a reduction of the resolution.", - "type": "float", - "unit": "1/mm", - "default_value": 1.25, - "minimum_value": "0.008", - "minimum_value_warning": "0.1", - "maximum_value_warning": "10", - "maximum_value": "2 / magic_fuzzy_skin_thickness", - "enabled": "magic_fuzzy_skin_enabled", - "children": - { - "magic_fuzzy_skin_point_dist": - { - "label": "Fuzzy Skin Point Distance", - "description": "The average distance between the random points introduced on each line segment. Note that the original points of the polygon are discarded, so a high smoothness results in a reduction of the resolution. This value must be higher than half the Fuzzy Skin Thickness.", - "type": "float", - "unit": "mm", - "default_value": 0.8, - "minimum_value": "magic_fuzzy_skin_thickness / 2", - "minimum_value_warning": "0.1", - "maximum_value_warning": "10", - "value": "10000 if parent_value == 0 else 1 / magic_fuzzy_skin_point_density", - "enabled": "magic_fuzzy_skin_enabled" - } - } - }, - "wireframe_enabled": - { - "label": "Wire Printing", - "description": "Print only the outside surface with a sparse webbed structure, printing 'in thin air'. This is realized by horizontally printing the contours of the model at given Z intervals which are connected via upward and diagonally downward lines.", - "type": "bool", - "default_value": false, - "global_only": "True" - }, - "wireframe_height": - { - "label": "WP Connection Height", - "description": "The height of the upward and diagonally downward lines between two horizontal parts. This determines the overall density of the net structure. Only applies to Wire Printing.", - "type": "float", - "unit": "mm", - "default_value": 3, - "minimum_value": "0.0001", - "maximum_value_warning": "20", - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_roof_inset": - { - "label": "WP Roof Inset Distance", - "description": "The distance covered when making a connection from a roof outline inward. Only applies to Wire Printing.", - "type": "float", - "unit": "mm", - "default_value": 3, - "minimum_value": "0", - "minimum_value_warning": "machine_nozzle_size", - "maximum_value_warning": "20", - "enabled": "wireframe_enabled", - "value": "wireframe_height", - "global_only": "True" - }, - "wireframe_printspeed": - { - "label": "WP Speed", - "description": "Speed at which the nozzle moves when extruding material. Only applies to Wire Printing.", - "unit": "mm/s", - "type": "float", - "default_value": 5, - "minimum_value": "0.1", - "maximum_value": "299792458000", - "maximum_value_warning": "50", - "enabled": "wireframe_enabled", - "global_only": "True", - "children": - { - "wireframe_printspeed_bottom": - { - "label": "WP Bottom Printing Speed", - "description": "Speed of printing the first layer, which is the only layer touching the build platform. Only applies to Wire Printing.", - "unit": "mm/s", - "type": "float", - "default_value": 5, - "minimum_value": "0.1", - "maximum_value": "299792458000", - "maximum_value_warning": "50", - "enabled": "wireframe_enabled", - "global_only": "True", - "value": "wireframe_printspeed" - }, - "wireframe_printspeed_up": - { - "label": "WP Upward Printing Speed", - "description": "Speed of printing a line upward 'in thin air'. Only applies to Wire Printing.", - "unit": "mm/s", - "type": "float", - "default_value": 5, - "minimum_value": "0.1", - "maximum_value": "299792458000", - "maximum_value_warning": "50", - "enabled": "wireframe_enabled", - "global_only": "True", - "value": "wireframe_printspeed" - }, - "wireframe_printspeed_down": - { - "label": "WP Downward Printing Speed", - "description": "Speed of printing a line diagonally downward. Only applies to Wire Printing.", - "unit": "mm/s", - "type": "float", - "default_value": 5, - "minimum_value": "0.1", - "maximum_value": "299792458000", - "maximum_value_warning": "50", - "enabled": "wireframe_enabled", - "global_only": "True", - "value": "wireframe_printspeed" - }, - "wireframe_printspeed_flat": - { - "label": "WP Horizontal Printing Speed", - "description": "Speed of printing the horizontal contours of the object. Only applies to Wire Printing.", - "unit": "mm/s", - "type": "float", - "default_value": 5, - "minimum_value": "0.1", - "maximum_value": "299792458000", - "maximum_value_warning": "100", - "value": "wireframe_printspeed", - "enabled": "wireframe_enabled", - "global_only": "True" - } - } - }, - "wireframe_flow": - { - "label": "WP Flow", - "description": "Flow compensation: the amount of material extruded is multiplied by this value. Only applies to Wire Printing.", - "unit": "%", - "default_value": 100, - "minimum_value": "0", - "maximum_value_warning": "100", - "type": "float", - "enabled": "wireframe_enabled", - "global_only": "True", - "children": - { - "wireframe_flow_connection": - { - "label": "WP Connection Flow", - "description": "Flow compensation when going up or down. Only applies to Wire Printing.", - "unit": "%", - "default_value": 100, - "minimum_value": "0", - "maximum_value_warning": "100", - "type": "float", - "enabled": "wireframe_enabled", - "global_only": "True", - "value": "wireframe_flow" - }, - "wireframe_flow_flat": - { - "label": "WP Flat Flow", - "description": "Flow compensation when printing flat lines. Only applies to Wire Printing.", - "unit": "%", - "default_value": 100, - "minimum_value": "0", - "maximum_value_warning": "100", - "type": "float", - "enabled": "wireframe_enabled", - "global_only": "True", - "value": "wireframe_flow" - } - } - }, - "wireframe_top_delay": - { - "label": "WP Top Delay", - "description": "Delay time after an upward move, so that the upward line can harden. Only applies to Wire Printing.", - "unit": "sec", - "type": "float", - "default_value": 0, - "minimum_value": "0", - "maximum_value_warning": "1", - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_bottom_delay": - { - "label": "WP Bottom Delay", - "description": "Delay time after a downward move. Only applies to Wire Printing.", - "unit": "sec", - "type": "float", - "default_value": 0, - "minimum_value": "0", - "maximum_value_warning": "1", - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_flat_delay": - { - "label": "WP Flat Delay", - "description": "Delay time between two horizontal segments. Introducing such a delay can cause better adhesion to previous layers at the connection points, while too long delays cause sagging. Only applies to Wire Printing.", - "unit": "sec", - "type": "float", - "default_value": 0.1, - "minimum_value": "0", - "maximum_value_warning": "0.5", - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_up_half_speed": - { - "label": "WP Ease Upward", - "description": "Distance of an upward move which is extruded with half speed.\nThis can cause better adhesion to previous layers, while not heating the material in those layers too much. Only applies to Wire Printing.", - "type": "float", - "unit": "mm", - "default_value": 0.3, - "minimum_value": "0", - "maximum_value_warning": "5.0", - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_top_jump": - { - "label": "WP Knot Size", - "description": "Creates a small knot at the top of an upward line, so that the consecutive horizontal layer has a better chance to connect to it. Only applies to Wire Printing.", - "type": "float", - "unit": "mm", - "default_value": 0.6, - "minimum_value": "0", - "maximum_value_warning": "2.0", - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_fall_down": - { - "label": "WP Fall Down", - "description": "Distance with which the material falls down after an upward extrusion. This distance is compensated for. Only applies to Wire Printing.", - "type": "float", - "unit": "mm", - "default_value": 0.5, - "minimum_value": "0", - "maximum_value_warning": "wireframe_height", - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_drag_along": - { - "label": "WP Drag Along", - "description": "Distance with which the material of an upward extrusion is dragged along with the diagonally downward extrusion. This distance is compensated for. Only applies to Wire Printing.", - "type": "float", - "unit": "mm", - "default_value": 0.6, - "minimum_value": "0", - "maximum_value_warning": "wireframe_height", - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_strategy": - { - "label": "WP Strategy", - "description": "Strategy for making sure two consecutive layers connect at each connection point. Retraction lets the upward lines harden in the right position, but may cause filament grinding. A knot can be made at the end of an upward line to heighten the chance of connecting to it and to let the line cool; however, it may require slow printing speeds. Another strategy is to compensate for the sagging of the top of an upward line; however, the lines won't always fall down as predicted.", - "type": "enum", - "options": - { - "compensate": "Compensate", - "knot": "Knot", - "retract": "Retract" - }, - "default_value": "compensate", - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_straight_before_down": - { - "label": "WP Straighten Downward Lines", - "description": "Percentage of a diagonally downward line which is covered by a horizontal line piece. This can prevent sagging of the top most point of upward lines. Only applies to Wire Printing.", - "type": "float", - "unit": "%", - "default_value": 20, - "minimum_value": "0", - "maximum_value": "100", - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_roof_fall_down": - { - "label": "WP Roof Fall Down", - "description": "The distance which horizontal roof lines printed 'in thin air' fall down when being printed. This distance is compensated for. Only applies to Wire Printing.", - "type": "float", - "unit": "mm", - "default_value": 2, - "minimum_value_warning": "0", - "maximum_value_warning": "wireframe_roof_inset", - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_roof_drag_along": - { - "label": "WP Roof Drag Along", - "description": "The distance of the end piece of an inward line which gets dragged along when going back to the outer outline of the roof. This distance is compensated for. Only applies to Wire Printing.", - "type": "float", - "unit": "mm", - "default_value": 0.8, - "minimum_value": "0", - "maximum_value_warning": "10", - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_roof_outer_delay": - { - "label": "WP Roof Outer Delay", - "description": "Time spent at the outer perimeters of hole which is to become a roof. Longer times can ensure a better connection. Only applies to Wire Printing.", - "type": "float", - "unit": "sec", - "default_value": 0.2, - "minimum_value": "0", - "maximum_value_warning": "2.0", - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_nozzle_clearance": - { - "label": "WP Nozzle Clearance", - "description": "Distance between the nozzle and horizontally downward lines. Larger clearance results in diagonally downward lines with a less steep angle, which in turn results in less upward connections with the next layer. Only applies to Wire Printing.", - "type": "float", - "unit": "mm", - "default_value": 1, - "minimum_value_warning": "0", - "maximum_value_warning": "10.0", - "enabled": "wireframe_enabled", - "global_only": "True" - } - } - } - } -} From 9112ce3a4dd1e5505ada685617e55e161af542da Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 9 May 2016 18:30:51 +0200 Subject: [PATCH 013/705] JSON feat: acceleration and jerk settings per feature type (CURA-1443) --- resources/machines/fdmprinter.json | 333 +++++++++++++++++++++++++++++ 1 file changed, 333 insertions(+) diff --git a/resources/machines/fdmprinter.json b/resources/machines/fdmprinter.json index 23f5a67af9..f8d00d1b5b 100644 --- a/resources/machines/fdmprinter.json +++ b/resources/machines/fdmprinter.json @@ -1010,6 +1010,339 @@ "max_value_warning": "300", "visible": false, "global_only": true + }, + + + "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": "boolean", + "default": false, + "visible": false, + "global_only": "True" + }, + "acceleration_print": { + "label": "Print Head Acceleration", + "description": "The acceleration with which printing happens.", + "unit": "mm/s²", + "type": "float", + "min_value": "0.1", + "max_value_warning": "10000", + "min_value_warning": "100", + "default": 3000, + "visible": true, + "enabled_WTF": "acceleration_enabled", + "children": { + "acceleration_infill": { + "label": "Infill Acceleration", + "description": "The acceleration with which infill is printed.", + "unit": "mm/s²", + "type": "float", + "min_value": "0.1", + "min_value_warning": "100", + "max_value_warning": "10000", + "default": 3000, + "visible": false, + "enabled_WTF": "acceleration_enabled" + }, + "acceleration_wall": { + "label": "Wall Acceleration", + "description": "The acceleration with which the walls are printed.", + "unit": "mm/s²", + "type": "float", + "min_value": "0.1", + "min_value_warning": "100", + "max_value_warning": "10000", + "default": 3000, + "visible": false, + "enabled_WTF": "acceleration_enabled", + "children": { + "acceleration_wall_0": { + "label": "Outer Wall Acceleration", + "description": "The acceleration with which the outermost walls are printed.", + "unit": "mm/s²", + "type": "float", + "min_value": "0.1", + "min_value_warning": "100", + "max_value_warning": "10000", + "default": 3000, + "visible": false, + "enabled_WTF": "acceleration_enabled" + }, + "acceleration_wall_x": { + "label": "Inner Wall Acceleration", + "description": "The acceleration with which all inner walls are printed.", + "unit": "mm/s²", + "type": "float", + "min_value": "0.1", + "min_value_warning": "100", + "max_value_warning": "10000", + "default": 3000, + "visible": false, + "enabled_WTF": "acceleration_enabled" + } + } + }, + "acceleration_topbottom": { + "label": "Top/Bottom Acceleration", + "description": "The acceleration with which top/bottom layers are printed.", + "unit": "mm/s²", + "type": "float", + "min_value": "0.1", + "min_value_warning": "100", + "max_value_warning": "10000", + "default": 3000, + "visible": false, + "enabled_WTF": "acceleration_enabled" + }, + "acceleration_support": { + "label": "Support Acceleration", + "description": "The acceleration with which the support structure is printed.", + "unit": "mm/s²", + "type": "float", + "min_value": "0.1", + "min_value_warning": "100", + "max_value_warning": "10000", + "default": 3000, + "visible": false, + "enabled_WTF": "acceleration_enabled and support_roof_enable", + "children": { + "acceleration_support_infill": { + "label": "Support Infill Acceleration", + "description": "The acceleration with which the infill of support is printed.", + "unit": "mm/s²", + "type": "float", + "default": 3000, + "min_value": "0.1", + "min_value_warning": "100", + "max_value_warning": "10000", + "visible": false, + "enabled_WTF": "acceleration_enabled and support_enable", + "global_only": true + }, + "acceleration_support_roof": { + "label": "Support Roof Acceleration", + "description": "The acceleration with which the roofs of support are printed. Printing the support roof at lower accelerations can improve overhang quality.", + "unit": "mm/s²", + "type": "float", + "default": 3000, + "min_value": "0.1", + "min_value_warning": "100", + "max_value_warning": "10000", + "visible": false, + "enabled_WTF": "acceleration_enabled and support_roof_enable", + "global_only": true + } + } + } + } + }, + "acceleration_travel": { + "label": "Travel Acceleration", + "description": "The acceleration with which travel moves are made.", + "unit": "mm/s²", + "type": "float", + "default": 5000, + "min_value": "0.1", + "min_value_warning": "100", + "max_value_warning": "10000", + "inherit_function": "acceleration_print if magic_spiralize else 5000", + "global_only": true, + "visible": true, + "enabled_WTF": "acceleration_enabled" + }, + "acceleration_layer_0": { + "label": "Initial Layer Acceleration", + "description": "The acceleration for the initial layer.", + "unit": "mm/s²", + "type": "float", + "default": 3000, + "min_value": "0.1", + "min_value_warning": "100", + "max_value_warning": "10000", + "visible": false, + "enabled_WTF": "acceleration_enabled" + }, + "acceleration_skirt": { + "label": "Skirt 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 at a different acceleration.", + "unit": "mm/s²", + "type": "float", + "default": 3000, + "min_value": "0.1", + "min_value_warning": "100", + "max_value_warning": "10000", + "visible": false, + "inherit_function": "acceleration_layer_0", + "global_only": true, + "enabled_WTF": "acceleration_enabled" + }, + + + + "jerk_enabled": { + "label": "Enable Jerk Control", + "description": "Enables adjusting the jerk of print head when the X ar Y axis halts or starts to move. Increasing the jerk can reduce printing time at the cost of print quality.", + "type": "boolean", + "default": false, + "visible": false, + "global_only": "True" + }, + "jerk_print": { + "label": "Print Jerk", + "description": "The maximal allowed jerk of the print head when starting to move or when changing direction.", + "unit": "mm/s³", + "type": "float", + "min_value": "0.1", + "min_value_warning": "5", + "max_value_warning": "50", + "default": 20, + "visible": true, + "enabled_WTF": "jerk_enabled", + "children": { + "jerk_infill": { + "label": "Infill Jerk", + "description": "The jerk with which infill is printed.", + "unit": "mm/s³", + "type": "float", + "min_value": "0.1", + "min_value_warning": "5", + "max_value_warning": "50", + "default": 20, + "visible": false, + "enabled_WTF": "jerk_enabled" + }, + "jerk_wall": { + "label": "Wall Jerk", + "description": "The jerk with which the walls are printed.", + "unit": "mm/s³", + "type": "float", + "min_value": "0.1", + "min_value_warning": "5", + "max_value_warning": "50", + "default": 20, + "visible": false, + "enabled_WTF": "jerk_enabled", + "children": { + "jerk_wall_0": { + "label": "Outer Wall Jerk", + "description": "The jerk with which the outermost walls are printed. Printing the outer wall at a lower jerk improves the final skin quality. However, having a large difference between the inner wall jerk and the outer wall jerk will effect quality in a negative way.", + "unit": "mm/s³", + "type": "float", + "min_value": "0.1", + "min_value_warning": "5", + "max_value_warning": "50", + "default": 20, + "visible": false, + "enabled_WTF": "jerk_enabled" + }, + "jerk_wall_x": { + "label": "Inner Wall Jerk", + "description": "The jerk with which all inner walls are printed Printing the inner wall faster than the outer wall will reduce printing time. It works well to set this in between the outer wall jerk and the infill jerk.", + "unit": "mm/s³", + "type": "float", + "min_value": "0.1", + "min_value_warning": "5", + "max_value_warning": "50", + "default": 20, + "visible": false, + "enabled_WTF": "jerk_enabled" + } + } + }, + "jerk_topbottom": { + "label": "Top/Bottom Jerk", + "description": "The jerk with which top/bottom layers are printed.", + "unit": "mm/s³", + "type": "float", + "min_value": "0.1", + "min_value_warning": "5", + "max_value_warning": "50", + "default": 20, + "visible": false, + "enabled_WTF": "jerk_enabled" + }, + "jerk_support": { + "label": "Support Jerk", + "description": "The jerk with which the support structure is printed. Printing support at higher jerks can greatly reduce printing time. The surface quality of the support structure is not important since it is removed after printing.", + "unit": "mm/s³", + "type": "float", + "min_value": "0.1", + "min_value_warning": "5", + "max_value_warning": "50", + "default": 20, + "visible": false, + "enabled_WTF": "jerk_enabled and support_roof_enable", + "children": { + "jerk_support_infill": { + "label": "Support Infill Jerk", + "description": "The jerk with which the infill of support is printed. Printing the infill at lower jerks improves stability.", + "unit": "mm/s³", + "type": "float", + "default": 20, + "min_value": "0.1", + "min_value_warning": "5", + "max_value_warning": "50", + "visible": false, + "enabled_WTF": "jerk_enabled and support_enable", + "global_only": true + }, + "jerk_support_roof": { + "label": "Support Roof Jerk", + "description": "The jerk with which the roofs of support are printed. Printing the support roof at lower jerks can improve overhang quality.", + "unit": "mm/s³", + "type": "float", + "default": 20, + "min_value": "0.1", + "min_value_warning": "5", + "max_value_warning": "50", + "visible": false, + "enabled_WTF": "jerk enabled and support_roof_enable", + "global_only": true + } + } + } + } + }, + "jerk_travel": { + "label": "Travel Jerk", + "description": "The jerk with which travel moves are made.", + "unit": "mm/s³", + "type": "float", + "default": 30, + "min_value": "0.1", + "min_value_warning": "5", + "max_value_warning": "50", + "inherit_function": "jerk_print if magic_spiralize else 30", + "global_only": true, + "visible": true, + "enabled_WTF": "jerk_enabled" + }, + "jerk_layer_0": { + "label": "Initial Layer Jerk", + "description": "The print jerk for the initial layer. A lower value is advised to improve adhesion to the build plate.", + "unit": "mm/s³", + "type": "float", + "default": 20, + "min_value": "0.1", + "min_value_warning": "5", + "max_value_warning": "50", + "visible": false, + "enabled_WTF": "jerk_enabled" + }, + "jerk_skirt": { + "label": "Skirt Jerk", + "description": "The jerk with which the skirt and brim are printed. Normally this is done at the initial layer jerk, but sometimes you might want to print the skirt with a different jerk.", + "unit": "mm/s³", + "type": "float", + "default": 20, + "min_value": "0.1", + "min_value_warning": "5", + "max_value_warning": "50", + "visible": false, + "inherit_function": "jerk_layer_0", + "global_only": true, + "enabled_WTF": "jerk_enabled" } } }, From 1919c63f0c113127b7e5c53f0aa1c36f14c222ad Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 9 May 2016 18:48:45 +0200 Subject: [PATCH 014/705] JSON feat: prime tower and raft acceleration and jerk (CURA-1443) --- .../machines/dual_extrusion_printer.json | 34 +++++ resources/machines/fdmprinter.json | 122 +++++++++++++++++- 2 files changed, 154 insertions(+), 2 deletions(-) diff --git a/resources/machines/dual_extrusion_printer.json b/resources/machines/dual_extrusion_printer.json index 2977345bcb..ccb1d4e96c 100644 --- a/resources/machines/dual_extrusion_printer.json +++ b/resources/machines/dual_extrusion_printer.json @@ -49,6 +49,40 @@ } } }, + "acceleration_print": { + "children": { + "acceleration_prime_tower": { + "label": "Prime Tower Acceleration", + "description": "The acceleration with which the prime tower is printed.", + "unit": "mm/s²", + "type": "float", + "min_value": "0.1", + "min_value_warning": "100", + "max_value_warning": "10000", + "default": 3000, + "visible": false, + "enabled": "prime_tower_enable and acceleration_enabled", + "global_only": true + } + } + }, + "jerk_print": { + "children": { + "jerk_prime_tower": { + "label": "Prime Tower Jerk", + "description": "The jerk with which the prime tower is printed.", + "unit": "mm/s³", + "type": "float", + "min_value": "0.1", + "min_value_warning": "5", + "max_value_warning": "50", + "default": 20, + "visible": false, + "enabled": "prime_tower_enable and jerk_enabled", + "global_only": true + } + } + }, "line_width": { "children": { "prime_tower_line_width": { diff --git a/resources/machines/fdmprinter.json b/resources/machines/fdmprinter.json index f8d00d1b5b..e0b19eb6b5 100644 --- a/resources/machines/fdmprinter.json +++ b/resources/machines/fdmprinter.json @@ -1022,13 +1022,13 @@ "global_only": "True" }, "acceleration_print": { - "label": "Print Head Acceleration", + "label": "Print Acceleration", "description": "The acceleration with which printing happens.", "unit": "mm/s²", "type": "float", "min_value": "0.1", - "max_value_warning": "10000", "min_value_warning": "100", + "max_value_warning": "10000", "default": 3000, "visible": true, "enabled_WTF": "acceleration_enabled", @@ -2097,6 +2097,124 @@ } } }, + + + + "raft_acceleration": { + "label": "Raft Print Acceleration", + "description": "The acceleration with which the raft is printed.", + "unit": "mm/s²", + "type": "float", + "default": 3000, + "min_value": "0.1", + "min_value_warning": "100", + "max_value_warning": "10000", + "inherit_function": "acceleration_print", + "global_only": "True", + "visible": false, + "enabled": "adhesion_type == \"raft\" and acceleration_enabled", + "children": { + "raft_surface_acceleration": { + "label": "Raft Surface Print Acceleration", + "description": "The acceleration with which the surface raft layers are printed.", + "unit": "mm/s²", + "type": "float", + "default": 3000, + "min_value": "0.1", + "min_value_warning": "100", + "max_value_warning": "10000", + "global_only": "True", + "visible": false, + "enabled": "adhesion_type == \"raft\" and acceleration_enabled" + }, + "raft_interface_acceleration": { + "label": "Raft Interface Print Acceleration", + "description": "The acceleration with which the interface raft layer is printed.", + "unit": "mm/s²", + "type": "float", + "default": 3000, + "min_value": "0.1", + "min_value_warning": "100", + "max_value_warning": "10000", + "global_only": "True", + "visible": false, + "enabled": "adhesion_type == \"raft\" and acceleration_enabled" + }, + "raft_base_acceleration": { + "label": "Raft Base Print Acceleration", + "description": "The acceleration with which the base raft layer is printed.", + "unit": "mm/s²", + "type": "float", + "default": 3000, + "min_value": "0.1", + "min_value_warning": "100", + "max_value_warning": "10000", + "global_only": "True", + "visible": false, + "enabled": "adhesion_type == \"raft\" and acceleration_enabled" + } + } + }, + + + + "raft_jerk": { + "label": "Raft Print Jerk", + "description": "The jerk with which the raft is printed.", + "unit": "mm/s³", + "type": "float", + "default": 20, + "min_value": "0.1", + "min_value_warning": "5", + "max_value_warning": "50", + "inherit_function": "jerk_print", + "global_only": "True", + "visible": false, + "enabled": "adhesion_type == \"raft\" and jerk_enabled", + "children": { + "raft_surface_jerk": { + "label": "Raft Surface Print Jerk", + "description": "The jerk with which the surface raft layers are printed.", + "unit": "mm/s³", + "type": "float", + "default": 20, + "min_value": "0.1", + "min_value_warning": "5", + "max_value_warning": "100", + "global_only": "True", + "visible": false, + "enabled": "adhesion_type == \"raft\" and jerk_enabled" + }, + "raft_interface_jerk": { + "label": "Raft Interface Print Jerk", + "description": "The jerk with which the interface raft layer is printed.", + "unit": "mm/s³", + "type": "float", + "default": 20, + "min_value": "0.1", + "min_value_warning": "5", + "max_value_warning": "50", + "global_only": "True", + "visible": false, + "enabled": "adhesion_type == \"raft\" and jerk_enabled" + }, + "raft_base_jerk": { + "label": "Raft Base Print Jerk", + "description": "The jerk with which the base raft layer is printed.", + "unit": "mm/s³", + "type": "float", + "default": 20, + "min_value": "0.1", + "min_value_warning": "5", + "max_value_warning": "50", + "global_only": "True", + "visible": false, + "enabled": "adhesion_type == \"raft\" and jerk_enabled" + } + } + }, + + "raft_fan_speed": { "label": "Raft Fan Speed", "description": "The fan speed for the raft.", From ed0f4e6c6795a3b59a6b78bdc6d821f62abf2e5d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 10 May 2016 09:16:58 +0200 Subject: [PATCH 015/705] Fix grammar mistake Suggested by Jorg. --- plugins/ChangeLogPlugin/ChangeLog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/ChangeLogPlugin/ChangeLog.txt b/plugins/ChangeLogPlugin/ChangeLog.txt index 8dc6a61dd8..d60154d56b 100644 --- a/plugins/ChangeLogPlugin/ChangeLog.txt +++ b/plugins/ChangeLogPlugin/ChangeLog.txt @@ -1,7 +1,7 @@ [2.1.0] *2.1 Beta release -Cura has been completely reengineered from the ground up for an even more seamless integration between hardware, software and materials. Together with its intuitive new user interface, it’s now also ready for any future developments. For the beginner Cura makes 3D printing incredibly easy, and for more advanced users, there are over 140 new customisable settings. +Cura has been completely reengineered from the ground up for an even more seamless integration between hardware, software and materials. Together with its intuitive new user interface, it’s now also ready for any future developments. For the beginner, Cura makes 3D printing incredibly easy, and for more advanced users, there are over 140 new customisable settings. *Select Multiple Objects You now have the freedom to select and manipulate multiple objects at the same time. From c0c24f1f706315583bc5d75a7f2ce2c2548003ef Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 10 May 2016 09:36:48 +0200 Subject: [PATCH 016/705] BuildVolume now uses StackContainer CURA-1278 --- cura/BuildVolume.py | 78 +++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 46 deletions(-) diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index e700b8d7be..351d67c104 100644 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -39,11 +39,8 @@ class BuildVolume(SceneNode): self._active_profile = None self._active_instance = None - Application.getInstance().getMachineManager().activeMachineInstanceChanged.connect(self._onActiveInstanceChanged) - self._onActiveInstanceChanged() - - Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onActiveProfileChanged) - self._onActiveProfileChanged() + Application.getInstance().activeContainerStackChanged.connect(self._onActiveContainerStackChanged) + self._onActiveContainerStackChanged() def setWidth(self, width): if width: self._width = width @@ -148,9 +145,9 @@ class BuildVolume(SceneNode): skirt_size = 0.0 - profile = Application.getInstance().getMachineManager().getWorkingProfile() - if profile: - skirt_size = self._getSkirtSize(profile) + container_stack = Application.getInstance().getActiveContainerStack() + if container_stack: + skirt_size = self._getSkirtSize(container_stack) # As this works better for UM machines, we only add the disallowed_area_size for the z direction. # This is probably wrong in all other cases. TODO! @@ -162,52 +159,41 @@ class BuildVolume(SceneNode): Application.getInstance().getController().getScene()._maximum_bounds = scale_to_max_bounds - def _onActiveInstanceChanged(self): - self._active_instance = Application.getInstance().getMachineManager().getActiveMachineInstance() + def _onActiveContainerStackChanged(self): + self._active_container_stack = Application.getInstance().getActiveContainerStack() - if self._active_instance: - self._width = self._active_instance.getMachineSettingValue("machine_width") - if Application.getInstance().getMachineManager().getWorkingProfile().getSettingValue("print_sequence") == "one_at_a_time": - self._height = Application.getInstance().getMachineManager().getWorkingProfile().getSettingValue("gantry_height") + if self._active_container_stack: + self._width = self._active_container_stack.getValue("machine_width") + if self._active_container_stack.getValue("print_sequence") == "one_at_a_time": + self._height = self._active_container_stack.getValue("gantry_height") else: - self._height = self._active_instance.getMachineSettingValue("machine_height") - self._depth = self._active_instance.getMachineSettingValue("machine_depth") + self._height = self._active_container_stack.getValue("machine_height") + self._depth = self._active_container_stack.getValue("machine_depth") self._updateDisallowedAreas() self.rebuild() - def _onActiveProfileChanged(self): - if self._active_profile: - self._active_profile.settingValueChanged.disconnect(self._onSettingValueChanged) - - self._active_profile = Application.getInstance().getMachineManager().getWorkingProfile() - if self._active_profile: - self._active_profile.settingValueChanged.connect(self._onSettingValueChanged) - self._updateDisallowedAreas() - self.rebuild() - def _onSettingValueChanged(self, setting_key): if setting_key == "print_sequence": - if Application.getInstance().getMachineManager().getWorkingProfile().getSettingValue("print_sequence") == "one_at_a_time": - self._height = Application.getInstance().getMachineManager().getWorkingProfile().getSettingValue("gantry_height") + if Application.getInstance().getActiveContainerStack().getValue("print_sequence") == "one_at_a_time": + self._height = self._active_container_stack.getValue("gantry_height") else: - self._height = self._active_instance.getMachineSettingValue("machine_depth") + self._height = self._active_container_stack.getValue("machine_depth") self.rebuild() if setting_key in self._skirt_settings: self._updateDisallowedAreas() self.rebuild() def _updateDisallowedAreas(self): - if not self._active_instance or not self._active_profile: + if not self._active_container_stack: return - disallowed_areas = self._active_instance.getMachineSettingValue("machine_disallowed_areas") + disallowed_areas = self._active_container_stack.getValue("machine_disallowed_areas") areas = [] skirt_size = 0.0 - if self._active_profile: - skirt_size = self._getSkirtSize(self._active_profile) + skirt_size = self._getSkirtSize(self._active_container_stack) if disallowed_areas: # Extend every area already in the disallowed_areas with the skirt size. @@ -228,8 +214,8 @@ class BuildVolume(SceneNode): # Add the skirt areas around the borders of the build plate. if skirt_size > 0: - half_machine_width = self._active_instance.getMachineSettingValue("machine_width") / 2 - half_machine_depth = self._active_instance.getMachineSettingValue("machine_depth") / 2 + half_machine_width = self._active_container_stack.getValue("machine_width") / 2 + half_machine_depth = self._active_container_stack.getValue("machine_depth") / 2 areas.append(Polygon(numpy.array([ [-half_machine_width, -half_machine_depth], @@ -262,24 +248,24 @@ class BuildVolume(SceneNode): self._disallowed_areas = areas ## Convenience function to calculate the size of the bed adhesion. - def _getSkirtSize(self, profile): + def _getSkirtSize(self, container_stack): skirt_size = 0.0 - adhesion_type = profile.getSettingValue("adhesion_type") + adhesion_type = container_stack.getValue("adhesion_type") if adhesion_type == "skirt": - skirt_distance = profile.getSettingValue("skirt_gap") - skirt_line_count = profile.getSettingValue("skirt_line_count") - skirt_size = skirt_distance + (skirt_line_count * profile.getSettingValue("skirt_line_width")) + skirt_distance = container_stack.getValue("skirt_gap") + skirt_line_count = container_stack.getValue("skirt_line_count") + skirt_size = skirt_distance + (skirt_line_count * container_stack.getValue("skirt_line_width")) elif adhesion_type == "brim": - skirt_size = profile.getSettingValue("brim_line_count") * profile.getSettingValue("skirt_line_width") + skirt_size = container_stack.getValue("brim_line_count") * container_stack.getValue("skirt_line_width") elif adhesion_type == "raft": - skirt_size = profile.getSettingValue("raft_margin") + skirt_size = container_stack.getValue("raft_margin") - if profile.getSettingValue("draft_shield_enabled"): - skirt_size += profile.getSettingValue("draft_shield_dist") + if container_stack.getValue("draft_shield_enabled"): + skirt_size += container_stack.getValue("draft_shield_dist") - if profile.getSettingValue("xy_offset"): - skirt_size += profile.getSettingValue("xy_offset") + if container_stack.getValue("xy_offset"): + skirt_size += container_stack.getValue("xy_offset") return skirt_size From 8785e4cedaac8f3d0454cfe2d25f776e05b5616d Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Tue, 10 May 2016 09:41:23 +0200 Subject: [PATCH 017/705] JSON fix: bug in enabled function (CURA-1443) there was a space instead of an underscore in jerk_enabled --- resources/machines/fdmprinter.json | 48 +++++++++++++++--------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/resources/machines/fdmprinter.json b/resources/machines/fdmprinter.json index e0b19eb6b5..8275ed1945 100644 --- a/resources/machines/fdmprinter.json +++ b/resources/machines/fdmprinter.json @@ -1031,7 +1031,7 @@ "max_value_warning": "10000", "default": 3000, "visible": true, - "enabled_WTF": "acceleration_enabled", + "enabled": "acceleration_enabled", "children": { "acceleration_infill": { "label": "Infill Acceleration", @@ -1043,7 +1043,7 @@ "max_value_warning": "10000", "default": 3000, "visible": false, - "enabled_WTF": "acceleration_enabled" + "enabled": "acceleration_enabled" }, "acceleration_wall": { "label": "Wall Acceleration", @@ -1055,7 +1055,7 @@ "max_value_warning": "10000", "default": 3000, "visible": false, - "enabled_WTF": "acceleration_enabled", + "enabled": "acceleration_enabled", "children": { "acceleration_wall_0": { "label": "Outer Wall Acceleration", @@ -1067,7 +1067,7 @@ "max_value_warning": "10000", "default": 3000, "visible": false, - "enabled_WTF": "acceleration_enabled" + "enabled": "acceleration_enabled" }, "acceleration_wall_x": { "label": "Inner Wall Acceleration", @@ -1079,7 +1079,7 @@ "max_value_warning": "10000", "default": 3000, "visible": false, - "enabled_WTF": "acceleration_enabled" + "enabled": "acceleration_enabled" } } }, @@ -1093,7 +1093,7 @@ "max_value_warning": "10000", "default": 3000, "visible": false, - "enabled_WTF": "acceleration_enabled" + "enabled": "acceleration_enabled" }, "acceleration_support": { "label": "Support Acceleration", @@ -1105,7 +1105,7 @@ "max_value_warning": "10000", "default": 3000, "visible": false, - "enabled_WTF": "acceleration_enabled and support_roof_enable", + "enabled": "acceleration_enabled and support_roof_enable", "children": { "acceleration_support_infill": { "label": "Support Infill Acceleration", @@ -1117,7 +1117,7 @@ "min_value_warning": "100", "max_value_warning": "10000", "visible": false, - "enabled_WTF": "acceleration_enabled and support_enable", + "enabled": "acceleration_enabled and support_enable", "global_only": true }, "acceleration_support_roof": { @@ -1130,7 +1130,7 @@ "min_value_warning": "100", "max_value_warning": "10000", "visible": false, - "enabled_WTF": "acceleration_enabled and support_roof_enable", + "enabled": "acceleration_enabled and support_roof_enable", "global_only": true } } @@ -1149,7 +1149,7 @@ "inherit_function": "acceleration_print if magic_spiralize else 5000", "global_only": true, "visible": true, - "enabled_WTF": "acceleration_enabled" + "enabled": "acceleration_enabled" }, "acceleration_layer_0": { "label": "Initial Layer Acceleration", @@ -1161,7 +1161,7 @@ "min_value_warning": "100", "max_value_warning": "10000", "visible": false, - "enabled_WTF": "acceleration_enabled" + "enabled": "acceleration_enabled" }, "acceleration_skirt": { "label": "Skirt Acceleration", @@ -1175,7 +1175,7 @@ "visible": false, "inherit_function": "acceleration_layer_0", "global_only": true, - "enabled_WTF": "acceleration_enabled" + "enabled": "acceleration_enabled" }, @@ -1198,7 +1198,7 @@ "max_value_warning": "50", "default": 20, "visible": true, - "enabled_WTF": "jerk_enabled", + "enabled": "jerk_enabled", "children": { "jerk_infill": { "label": "Infill Jerk", @@ -1210,7 +1210,7 @@ "max_value_warning": "50", "default": 20, "visible": false, - "enabled_WTF": "jerk_enabled" + "enabled": "jerk_enabled" }, "jerk_wall": { "label": "Wall Jerk", @@ -1222,7 +1222,7 @@ "max_value_warning": "50", "default": 20, "visible": false, - "enabled_WTF": "jerk_enabled", + "enabled": "jerk_enabled", "children": { "jerk_wall_0": { "label": "Outer Wall Jerk", @@ -1234,7 +1234,7 @@ "max_value_warning": "50", "default": 20, "visible": false, - "enabled_WTF": "jerk_enabled" + "enabled": "jerk_enabled" }, "jerk_wall_x": { "label": "Inner Wall Jerk", @@ -1246,7 +1246,7 @@ "max_value_warning": "50", "default": 20, "visible": false, - "enabled_WTF": "jerk_enabled" + "enabled": "jerk_enabled" } } }, @@ -1260,7 +1260,7 @@ "max_value_warning": "50", "default": 20, "visible": false, - "enabled_WTF": "jerk_enabled" + "enabled": "jerk_enabled" }, "jerk_support": { "label": "Support Jerk", @@ -1272,7 +1272,7 @@ "max_value_warning": "50", "default": 20, "visible": false, - "enabled_WTF": "jerk_enabled and support_roof_enable", + "enabled": "jerk_enabled and support_roof_enable", "children": { "jerk_support_infill": { "label": "Support Infill Jerk", @@ -1284,7 +1284,7 @@ "min_value_warning": "5", "max_value_warning": "50", "visible": false, - "enabled_WTF": "jerk_enabled and support_enable", + "enabled": "jerk_enabled and support_enable", "global_only": true }, "jerk_support_roof": { @@ -1297,7 +1297,7 @@ "min_value_warning": "5", "max_value_warning": "50", "visible": false, - "enabled_WTF": "jerk enabled and support_roof_enable", + "enabled": "jerk_enabled and support_roof_enable", "global_only": true } } @@ -1316,7 +1316,7 @@ "inherit_function": "jerk_print if magic_spiralize else 30", "global_only": true, "visible": true, - "enabled_WTF": "jerk_enabled" + "enabled": "jerk_enabled" }, "jerk_layer_0": { "label": "Initial Layer Jerk", @@ -1328,7 +1328,7 @@ "min_value_warning": "5", "max_value_warning": "50", "visible": false, - "enabled_WTF": "jerk_enabled" + "enabled": "jerk_enabled" }, "jerk_skirt": { "label": "Skirt Jerk", @@ -1342,7 +1342,7 @@ "visible": false, "inherit_function": "jerk_layer_0", "global_only": true, - "enabled_WTF": "jerk_enabled" + "enabled": "jerk_enabled" } } }, From dbd2c911ce4cec9d003671c8f91873ff7bd57088 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 10 May 2016 10:34:02 +0200 Subject: [PATCH 018/705] Renamed active containerstack to global containerstac Cura-1278 --- cura/BuildVolume.py | 6 +++--- plugins/SolidView/SolidView.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index 351d67c104..2a84675a48 100644 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -145,7 +145,7 @@ class BuildVolume(SceneNode): skirt_size = 0.0 - container_stack = Application.getInstance().getActiveContainerStack() + container_stack = Application.getInstance().getGlobalContainerStack() if container_stack: skirt_size = self._getSkirtSize(container_stack) @@ -160,7 +160,7 @@ class BuildVolume(SceneNode): Application.getInstance().getController().getScene()._maximum_bounds = scale_to_max_bounds def _onActiveContainerStackChanged(self): - self._active_container_stack = Application.getInstance().getActiveContainerStack() + self._active_container_stack = Application.getInstance().getGlobalContainerStack() if self._active_container_stack: self._width = self._active_container_stack.getValue("machine_width") @@ -176,7 +176,7 @@ class BuildVolume(SceneNode): def _onSettingValueChanged(self, setting_key): if setting_key == "print_sequence": - if Application.getInstance().getActiveContainerStack().getValue("print_sequence") == "one_at_a_time": + if Application.getInstance().getGlobalContainerStack().getValue("print_sequence") == "one_at_a_time": self._height = self._active_container_stack.getValue("gantry_height") else: self._height = self._active_container_stack.getValue("machine_depth") diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 561d194dd3..1c65ea5dfe 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -34,10 +34,10 @@ class SolidView(View): self._disabled_shader.setUniformValue("u_diffuseColor", [0.68, 0.68, 0.68, 1.0]) self._disabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0))) - if Application.getInstance().getActiveContainerStack(): + if Application.getInstance().getGlobalContainerStack(): if Preferences.getInstance().getValue("view/show_overhang"): - angle = Application.getInstance().getActiveContainerStack().getValue("support_angle") + angle = Application.getInstance().getGlobalContainerStack().getValue("support_angle") if angle is not None: self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(90 - angle))) else: From 04f1e8d27cdb56a2e9e6d4d3753b8966cc2dfc96 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 10 May 2016 11:16:35 +0200 Subject: [PATCH 019/705] Renames to from activeStack to global stack CURA-1278 --- cura/BuildVolume.py | 8 +++----- cura/CuraApplication.py | 7 +++---- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index 2a84675a48..4007ee0007 100644 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -37,10 +37,8 @@ class BuildVolume(SceneNode): self.setCalculateBoundingBox(False) - self._active_profile = None - self._active_instance = None - Application.getInstance().activeContainerStackChanged.connect(self._onActiveContainerStackChanged) - self._onActiveContainerStackChanged() + Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged) + self._onGlobalContainerStackChanged() def setWidth(self, width): if width: self._width = width @@ -159,7 +157,7 @@ class BuildVolume(SceneNode): Application.getInstance().getController().getScene()._maximum_bounds = scale_to_max_bounds - def _onActiveContainerStackChanged(self): + def _onGlobalContainerStackChanged(self): self._active_container_stack = Application.getInstance().getGlobalContainerStack() if self._active_container_stack: diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 1f83cd1f3d..fe250aea16 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -101,7 +101,7 @@ class CuraApplication(QtApplication): self._camera_animation = None self._cura_actions = None - #self.getMachineManager().activeMachineInstanceChanged.connect(self._onActiveMachineChanged) + #self.getMachineManager().activeMachineInstanceChanged.connect(self._onGlobalContainerStackChanged) #self.getMachineManager().addMachineRequested.connect(self._onAddMachineRequested) self.getController().getScene().sceneChanged.connect(self.updatePlatformActivity) self.getController().toolOperationStopped.connect(self._onToolOperationStopped) @@ -508,10 +508,9 @@ class CuraApplication(QtApplication): @pyqtSlot(str, result = "QVariant") def getSettingValue(self, key): - if not self.getMachineManager().getWorkingProfile(): + if not self._global_container_stack: return None - return self.getMachineManager().getWorkingProfile().getSettingValue(key) - #return self.getActiveMachine().getSettingValueByKey(key) + return self._global_container_stack.getValue(key) ## Change setting by key value pair @pyqtSlot(str, "QVariant") From 93227c0b560c259bf19d36da1c97e8576c91c512 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 10 May 2016 11:28:57 +0200 Subject: [PATCH 020/705] Updated removabledrive plugin to use metadata CURA-1278 --- .../RemovableDriveOutputDevice.py | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py index 27859bd145..c6fc277234 100644 --- a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py +++ b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py @@ -29,17 +29,26 @@ class RemovableDriveOutputDevice(OutputDevice): if self._writing: raise OutputDeviceError.DeviceBusyError() - file_formats = Application.getInstance().getMeshFileHandler().getSupportedFileTypesWrite() #Formats supported by this application. + # Formats supported by this application (File types that we can actually write) + file_formats = Application.getInstance().getMeshFileHandler().getSupportedFileTypesWrite() if filter_by_machine: - machine_file_formats = Application.getInstance().getMachineManager().getActiveMachineInstance().getMachineDefinition().getFileFormats() - file_formats = list(filter(lambda file_format: file_format["mime_type"] in machine_file_formats, file_formats)) #Take the intersection between file_formats and machine_file_formats. + container = Application.getInstance().getGlobalContainerStack().findContainer({"file_formats": "*"}) + + # Create a list from supported file formats string + machine_file_formats = [file_type.strip() for file_type in container.getMetaDataEntry("file_formats").split(";")] + + # Take the intersection between file_formats and machine_file_formats. + file_formats = list(filter(lambda file_format: file_format["mime_type"] in machine_file_formats, file_formats)) + if len(file_formats) == 0: Logger.log("e", "There are no file formats available to write with!") raise OutputDeviceError.WriteRequestFailedError() - writer = Application.getInstance().getMeshFileHandler().getWriterByMimeType(file_formats[0]["mime_type"]) #Just take the first file format available. + + # Just take the first file format available. + writer = Application.getInstance().getMeshFileHandler().getWriterByMimeType(file_formats[0]["mime_type"]) extension = file_formats[0]["extension"] - if file_name == None: + if file_name is None: for n in BreadthFirstIterator(node): if n.getMeshData(): file_name = n.getName() @@ -50,7 +59,7 @@ class RemovableDriveOutputDevice(OutputDevice): Logger.log("e", "Could not determine a proper file name when trying to write to %s, aborting", self.getName()) raise OutputDeviceError.WriteRequestFailedError() - if extension: #Not empty string. + if extension: # Not empty string. extension = "." + extension file_name = os.path.join(self.getId(), os.path.splitext(file_name)[0] + extension) From 170df747b3710d9491547e874253cc9316d3d1e8 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 10 May 2016 11:40:36 +0200 Subject: [PATCH 021/705] Use globalContainer stack instead of activeInstance CURA-1278 --- cura/CuraApplication.py | 2 -- cura/PrintInformation.py | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index fe250aea16..0fcbeaea5e 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -101,8 +101,6 @@ class CuraApplication(QtApplication): self._camera_animation = None self._cura_actions = None - #self.getMachineManager().activeMachineInstanceChanged.connect(self._onGlobalContainerStackChanged) - #self.getMachineManager().addMachineRequested.connect(self._onAddMachineRequested) self.getController().getScene().sceneChanged.connect(self.updatePlatformActivity) self.getController().toolOperationStopped.connect(self._onToolOperationStopped) diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index d3eaab662c..994dac69d0 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -63,6 +63,6 @@ class PrintInformation(QObject): self.currentPrintTimeChanged.emit() # Material amount is sent as an amount of mm^3, so calculate length from that - r = Application.getInstance().getMachineManager().getWorkingProfile().getSettingValue("material_diameter") / 2 + r = Application.getInstance().getGlobalContainerStack().getValue("material_diameter") / 2 self._material_amount = round((amount / (math.pi * r ** 2)) / 1000, 2) self.materialAmountChanged.emit() From 162295da8e73494411edaea36a11919e9aae76bf Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 10 May 2016 13:31:26 +0200 Subject: [PATCH 022/705] Actually adding a new machine is now possible CURA-1278 --- resources/qml/AddMachineDialog.qml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/resources/qml/AddMachineDialog.qml b/resources/qml/AddMachineDialog.qml index c6e852aa3e..2aa966d5e9 100644 --- a/resources/qml/AddMachineDialog.qml +++ b/resources/qml/AddMachineDialog.qml @@ -152,6 +152,19 @@ UM.Dialog anchors.bottom:parent.bottom } + Button + { + text:"save" + anchors.bottom: parent.bottom + anchors.right: parent.right + onClicked: + { + base.visible = false + var item = machineList.model.getItem(machineList.currentIndex); + machineList.model.setNewGlobalStackFromDefinition(machineName.text, item.id) + } + } + Item { UM.I18nCatalog From 57bc87f25fba274c9797ab1b176ba7c0b6dcb73b Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Tue, 10 May 2016 13:35:49 +0200 Subject: [PATCH 023/705] Listing of all paths for every OS Only cosmetics --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e6425ec8e9..7fc77f9dcf 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,10 @@ Use [this](https://github.com/Ultimaker/Uranium/wiki/Bug-Reporting-Template) tem For crashes and similar issues, please attach the following information: * (On Windows) The log as produced by dxdiag (start -> run -> dxdiag -> save output) -* The Cura GUI log file, located at (Windows) $User/AppData/Local/cura/cura.log, (OSX) $User/.cura/cura.log, (Ubuntu) $USER/.local/share/cura +* The Cura GUI log file, located at + * $User/AppData/Local/cura/cura.log (Windows) + * $User/.cura/cura.log (OSX) + * $USER/.local/share/cura (Ubuntu/Linux) * The Cura Engine log, using Help -> Show Engine Log Dependencies From 67b6c5aa2915979032ef84f9840242fe2c710d03 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 10 May 2016 13:47:27 +0200 Subject: [PATCH 024/705] Re-added platform again CURA-1278 --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 0fcbeaea5e..a9eb3eece4 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -173,7 +173,7 @@ class CuraApplication(QtApplication): Selection.selectionChanged.connect(self.onSelectionChanged) root = controller.getScene().getRoot() - #self._platform = Platform(root) + self._platform = Platform(root) #self._volume = BuildVolume.BuildVolume(root) From 5fdd0e81560fb2c0bae33af62d4fe3dd55b80266 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 10 May 2016 14:34:07 +0200 Subject: [PATCH 025/705] BuildVolume no longer crashes when width/height/depth is None CURA-1278 --- cura/BuildVolume.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index 4007ee0007..4397c798f7 100644 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -71,7 +71,7 @@ class BuildVolume(SceneNode): ## Recalculates the build volume & disallowed areas. def rebuild(self): - if self._width == 0 or self._height == 0 or self._depth == 0: + if not self._width or not self._height or not self._depth: return min_w = -self._width / 2 From bdccab4b600fd3a51a4cc00502f8cea69759ce77 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 10 May 2016 14:35:45 +0200 Subject: [PATCH 026/705] Re-added BuildVolume CURA-1278 --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index a9eb3eece4..ceb7a42b72 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -175,7 +175,7 @@ class CuraApplication(QtApplication): root = controller.getScene().getRoot() self._platform = Platform(root) - #self._volume = BuildVolume.BuildVolume(root) + self._volume = BuildVolume.BuildVolume(root) self.getRenderer().setBackgroundColor(QColor(245, 245, 245)) From fa8fbb25605242407518c7ef7ccaa6f4f843d095 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 10 May 2016 14:42:53 +0200 Subject: [PATCH 027/705] Added global only to setting type for CuraApplication CURA-1278 --- cura/CuraApplication.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index ceb7a42b72..174621be03 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -24,6 +24,8 @@ from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation from UM.Operations.GroupedOperation import GroupedOperation from UM.Operations.SetTransformOperation import SetTransformOperation +from UM.Settings.SettingDefinition import SettingDefinition + from UM.i18n import i18nCatalog from . import PlatformPhysics @@ -160,6 +162,8 @@ class CuraApplication(QtApplication): self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Setting up scene...")) + SettingDefinition.addSupportedProperty("global_only", "bool") + controller = self.getController() controller.setActiveView("SolidView") From 3a99a2bc45888ba03eb496c15d6daad95e80e554 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 10 May 2016 17:28:41 +0200 Subject: [PATCH 028/705] Import the right version of the UM module Since it was changed to 1.2 for the setting models --- resources/qml/AddMachineDialog.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/AddMachineDialog.qml b/resources/qml/AddMachineDialog.qml index 2aa966d5e9..476df2178c 100644 --- a/resources/qml/AddMachineDialog.qml +++ b/resources/qml/AddMachineDialog.qml @@ -8,7 +8,7 @@ import QtQuick.Window 2.1 import QtQuick.Controls.Styles 1.1 -import UM 1.1 as UM +import UM 1.2 as UM import Cura 1.0 as Cura @@ -175,4 +175,4 @@ UM.Dialog SystemPalette { id: palette } ExclusiveGroup { id: printerGroup; } } -} \ No newline at end of file +} From 199a30099efd2614e5f94479f0ea22bf60d17050 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 10 May 2016 17:29:29 +0200 Subject: [PATCH 029/705] Comment away everything related to activeprofile and machine manager in SidebarSimple To make SidebarSimple at least display again --- resources/qml/SidebarSimple.qml | 50 ++++++++++++++++----------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 9387872276..21aa315dd1 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -61,7 +61,7 @@ Item return -1; } - var density = parseInt(UM.ActiveProfile.settingValues.getValue("infill_sparse_density")); +// var density = parseInt(UM.ActiveProfile.settingValues.getValue("infill_sparse_density")); for(var i = 0; i < infillModel.count; ++i) { if(density > infillModel.get(i).percentageMin && density <= infillModel.get(i).percentageMax ) @@ -116,7 +116,7 @@ Item onClicked: { if (infillListView.activeIndex != index) { - UM.MachineManager.setSettingValue("infill_sparse_density", model.percentage) +// UM.MachineManager.setSettingValue("infill_sparse_density", model.percentage) } } onEntered: { @@ -213,13 +213,13 @@ Item text: catalog.i18nc("@option:check","Generate Brim"); style: UM.Theme.styles.checkbox; - checked: UM.ActiveProfile.valid ? UM.ActiveProfile.settingValues.getValue("adhesion_type") == "brim" : false; +// checked: UM.ActiveProfile.valid ? UM.ActiveProfile.settingValues.getValue("adhesion_type") == "brim" : false; MouseArea { anchors.fill: parent hoverEnabled: true onClicked: { - UM.MachineManager.setSettingValue("adhesion_type", !parent.checked?"brim":"skirt") +// UM.MachineManager.setSettingValue("adhesion_type", !parent.checked?"brim":"skirt") } onEntered: { @@ -246,13 +246,13 @@ Item text: catalog.i18nc("@option:check","Generate Support Structure"); style: UM.Theme.styles.checkbox; - checked: UM.ActiveProfile.valid ? UM.ActiveProfile.settingValues.getValue("support_enable") : false; +// checked: UM.ActiveProfile.valid ? UM.ActiveProfile.settingValues.getValue("support_enable") : false; MouseArea { anchors.fill: parent hoverEnabled: true onClicked: { - UM.MachineManager.setSettingValue("support_enable", !parent.checked) +// UM.MachineManager.setSettingValue("support_enable", !parent.checked) } onEntered: { @@ -271,15 +271,15 @@ Item function populateExtruderModel() { - extruderModel.clear() - var extruder_count = UM.MachineManager.getSettingValue("machine_extruder_count"); - for(var extruder = 0; extruder < extruder_count ; extruder++) { - extruderModel.append({ - name: catalog.i18nc("@label", "Extruder %1").arg(extruder), - text: catalog.i18nc("@label", "Extruder %1").arg(extruder), - value: extruder - }) - } +// extruderModel.clear() +// var extruder_count = UM.MachineManager.getSettingValue("machine_extruder_count"); +// for(var extruder = 0; extruder < extruder_count ; extruder++) { +// extruderModel.append({ +// name: catalog.i18nc("@label", "Extruder %1").arg(extruder), +// text: catalog.i18nc("@label", "Extruder %1").arg(extruder), +// value: extruder +// }) +// } } Rectangle { @@ -290,7 +290,7 @@ Item width: parent.width height: childrenRect.height // Use both UM.ActiveProfile and UM.MachineManager to force UM.MachineManager.getSettingValue() to be reevaluated - visible: UM.ActiveProfile.settingValues.getValue("machine_extruder_count") || (UM.MachineManager.getSettingValue("machine_extruder_count") > 1) +// visible: UM.ActiveProfile.settingValues.getValue("machine_extruder_count") || (UM.MachineManager.getSettingValue("machine_extruder_count") > 1) Label { id: mainExtruderLabel @@ -308,9 +308,9 @@ Item anchors.top: parent.top anchors.left: supportExtruderLabel.right style: UM.Theme.styles.combobox - currentIndex: UM.ActiveProfile.valid ? UM.ActiveProfile.settingValues.getValue("extruder_nr") : 0 +// currentIndex: UM.ActiveProfile.valid ? UM.ActiveProfile.settingValues.getValue("extruder_nr") : 0 onActivated: { - UM.MachineManager.setSettingValue("extruder_nr", index) +// UM.MachineManager.setSettingValue("extruder_nr", index) } } @@ -331,7 +331,7 @@ Item anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.left: supportExtruderLabel.right style: UM.Theme.styles.combobox - currentIndex: UM.ActiveProfile.valid ? UM.ActiveProfile.settingValues.getValue("support_extruder_nr") : 0 +// currentIndex: UM.ActiveProfile.valid ? UM.ActiveProfile.settingValues.getValue("support_extruder_nr") : 0 onActivated: { UM.MachineManager.setSettingValue("support_extruder_nr", index) } @@ -341,12 +341,12 @@ Item id: extruderModel Component.onCompleted: populateExtruderModel() } - Connections - { - id: machineChange - target: UM.MachineManager - onActiveMachineInstanceChanged: populateExtruderModel() - } +// Connections +// { +// id: machineChange +// target: UM.MachineManager +// onActiveMachineInstanceChanged: populateExtruderModel() +// } } Rectangle { From fa7e186b2f91d3c575f104f093de2a3216295004 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 10 May 2016 17:31:18 +0200 Subject: [PATCH 030/705] Import Uranium's SettingView related files and start making them work This is too cura-specific now so we should not put it in Uranium. --- resources/qml/Settings/SettingCategory.qml | 79 ++++++++ resources/qml/Settings/SettingCheckBox.qml | 77 ++++++++ resources/qml/Settings/SettingComboBox.qml | 114 ++++++++++++ resources/qml/Settings/SettingItem.qml | 168 ++++++++++++++++++ resources/qml/Settings/SettingTextField.qml | 153 ++++++++++++++++ resources/qml/Settings/SettingUnknown.qml | 13 ++ resources/qml/Settings/SettingView.qml | 92 ++++++++++ .../Settings/SettingsConfigurationPage.qml | 119 +++++++++++++ 8 files changed, 815 insertions(+) create mode 100644 resources/qml/Settings/SettingCategory.qml create mode 100644 resources/qml/Settings/SettingCheckBox.qml create mode 100644 resources/qml/Settings/SettingComboBox.qml create mode 100644 resources/qml/Settings/SettingItem.qml create mode 100644 resources/qml/Settings/SettingTextField.qml create mode 100644 resources/qml/Settings/SettingUnknown.qml create mode 100644 resources/qml/Settings/SettingView.qml create mode 100644 resources/qml/Settings/SettingsConfigurationPage.qml diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml new file mode 100644 index 0000000000..b4c0263149 --- /dev/null +++ b/resources/qml/Settings/SettingCategory.qml @@ -0,0 +1,79 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 +import QtQuick.Layouts 1.1 + +import UM 1.1 as UM + +Button { + id: base; + + style: UM.Theme.styles.sidebar_category; + + signal showTooltip(); + signal hideTooltip(); + signal contextMenuRequested() + + text: definition.label + iconSource: UM.Theme.getIcon(definition.icon) + + checkable: true + checked: definition.expanded + + onClicked: definition.expanded ? settingDefinitionsModel.collapse(definition.key) : settingDefinitionsModel.expandAll(definition.key) + + UM.SimpleButton { + id: settingsButton + + visible: base.hovered || settingsButton.hovered + height: base.height * 0.6 + width: base.height * 0.6 + + anchors { + right: inheritButton.visible ? inheritButton.left : parent.right + rightMargin: inheritButton.visible? UM.Theme.getSize("default_margin").width / 2 : UM.Theme.getSize("setting_preferences_button_margin").width + verticalCenter: parent.verticalCenter; + } + + color: UM.Theme.getColor("setting_control_button"); + hoverColor: UM.Theme.getColor("setting_control_button_hover") + iconSource: UM.Theme.getIcon("settings"); + + onClicked: { + Actions.configureSettingVisibility() + } + } + + UM.SimpleButton + { + // This button shows when the setting has an inherited function, but is overriden by profile. + id: inheritButton; + + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("setting_preferences_button_margin").width + + visible: hiddenValuesCount > 0 + height: parent.height / 2; + width: height; + + onClicked: { + base.showAllHidenInheritedSettings() + } + + color: UM.Theme.getColor("setting_control_button") + hoverColor: UM.Theme.getColor("setting_control_button_hover") + iconSource: UM.Theme.getIcon("notice") + + onEntered: { + base.showTooltip() + } + + onExited: { + base.hideTooltip(); + } + } +} diff --git a/resources/qml/Settings/SettingCheckBox.qml b/resources/qml/Settings/SettingCheckBox.qml new file mode 100644 index 0000000000..b2bbc68ec1 --- /dev/null +++ b/resources/qml/Settings/SettingCheckBox.qml @@ -0,0 +1,77 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 + +import UM 1.2 as UM + +SettingItem +{ + id: base + + MouseArea + { + id: control + + property bool checked: + { + if(value == "True") + { + return true; + } + else if(value == "False") + { + return false; + } + else + { + return value; + } + } + + Rectangle + { + anchors + { + top: parent.top + bottom: parent.bottom + left: parent.left + } + width: height + + color: + { + if (!enabled) + { + return base.style.controlDisabledColor + } + if(base.containsMouse || base.activeFocus) + { + return base.style.controlHighlightColor + } + else + { + return base.style.controlColor + } + } + border.width: base.style.controlBorderWidth; + border.color: !enabled ? base.style.controlDisabledBorderColor : control.containsMouse ? base.style.controlBorderHighlightColor : base.style.controlBorderColor; + + UM.RecolorImage { + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width/2.5 + height: parent.height/2.5 + sourceSize.width: width + sourceSize.height: width + color: !enabled ? base.style.controlDisabledTextColor : base.style.controlTextColor; + source: UM.Theme.getIcon("check") + opacity: control.checked + Behavior on opacity { NumberAnimation { duration: 100; } } + } + } + } +} diff --git a/resources/qml/Settings/SettingComboBox.qml b/resources/qml/Settings/SettingComboBox.qml new file mode 100644 index 0000000000..85935c3471 --- /dev/null +++ b/resources/qml/Settings/SettingComboBox.qml @@ -0,0 +1,114 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 + +import UM 1.1 as UM + +SettingItem +{ + id: base + + ComboBox + { +// signal valueChanged(string value); +// id: base + model: definition.options + textRole: "name"; + + MouseArea + { + anchors.fill: parent; + acceptedButtons: Qt.NoButton; + onWheel: wheel.accepted = true; + } + + style: ComboBoxStyle + { + background: Rectangle + { + color: + { + if (!enabled) + { + return base.style.controlDisabledColor + } + if(control.hovered || base.activeFocus) + { + return base.style.controlHighlightColor + } + else + { + return base.style.controlColor + } + } + border.width: base.style.controlBorderWidth; + border.color: !enabled ? base.style.controlDisabledBorderColor : control.hovered ? base.style.controlBorderHighlightColor : base.style.controlBorderColor; + } + label: Item + { + Label + { + anchors.left: parent.left; + anchors.leftMargin: base.style.controlBorderWidth + anchors.right: downArrow.left; + anchors.rightMargin: base.style.controlBorderWidth; + anchors.verticalCenter: parent.verticalCenter; + + text: control.currentText; + font: base.style.controlFont; + color: !enabled ? base.style.controlDisabledTextColor : base.style.controlTextColor; + + elide: Text.ElideRight; + verticalAlignment: Text.AlignVCenter; + } + + UM.RecolorImage + { + id: downArrow + anchors.right: parent.right; + anchors.rightMargin: base.style.controlBorderWidth * 2; + anchors.verticalCenter: parent.verticalCenter; + + source: UM.Theme.getIcon("arrow_bottom") + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width + 5 + sourceSize.height: width + 5 + + color: base.style.controlTextColor; + + } + } + } +/* + onActivated: { + valueChanged(options.getItem(index).value); + } + + onModelChanged: { + updateCurrentIndex(); + } + + Component.onCompleted: { + parent.parent.valueChanged.connect(updateCurrentIndex) + } + + function updateCurrentIndex() { + if (!options) { + return; + } + + for(var i = 0; i < options.rowCount(); ++i) { + if(options.getItem(i).value == value) { + currentIndex = i; + return; + } + } + + currentIndex = -1; + }*/ + } +} diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml new file mode 100644 index 0000000000..845f35853e --- /dev/null +++ b/resources/qml/Settings/SettingItem.qml @@ -0,0 +1,168 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 + +import UM 1.1 as UM + +import "." + +Item { + id: base; + + height: UM.Theme.getSize("section").height; + + property alias contents: controlContainer.children + + signal contextMenuRequested() + signal showTooltip(var position); + signal hideTooltip(); + + MouseArea + { + id: mouse; + + anchors.fill: parent; + + acceptedButtons: Qt.RightButton; + hoverEnabled: true; + + onClicked: base.contextMenuRequested(); + + onEntered: { + hoverTimer.start(); + } + + onExited: { + if(controlContainer.item && controlContainer.item.hovered) { + return; + } + hoverTimer.stop(); + base.hideTooltip(); + } + + Timer { + id: hoverTimer; + interval: 500; + repeat: false; + + onTriggered: base.showTooltip({ x: mouse.mouseX, y: mouse.mouseY }); + } + } + + Label + { + id: label; + + anchors.left: parent.left; + anchors.leftMargin: (UM.Theme.getSize("section_icon_column").width + 5) + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width) + anchors.right: settingControls.left; + anchors.verticalCenter: parent.verticalCenter + + height: UM.Theme.getSize("section").height; + verticalAlignment: Text.AlignVCenter; + + text: definition.label + elide: Text.ElideMiddle; + + color: UM.Theme.getColor("setting_control_text"); + font: UM.Theme.getFont("default"); + } + + Row + { + id: settingControls + + height: parent.height / 2 + spacing: UM.Theme.getSize("default_margin").width / 2 + + anchors { + right: controlContainer.left + rightMargin: UM.Theme.getSize("default_margin").width / 2 + verticalCenter: parent.verticalCenter + } + + UM.SimpleButton + { + id: revertButton; + +// visible: base.overridden && base.is_enabled + + height: parent.height; + width: height; + + backgroundColor: UM.Theme.getColor("setting_control"); + hoverBackgroundColor: UM.Theme.getColor("setting_control_highlight") + color: UM.Theme.getColor("setting_control_button") + hoverColor: UM.Theme.getColor("setting_control_button_hover") + + iconSource: UM.Theme.getIcon("reset") + + onClicked: { + base.resetRequested() + controlContainer.notifyReset(); + } + + onEntered: base.showResetTooltip({ x: mouse.mouseX, y: mouse.mouseY }) + onExited: + { + if(controlContainer.item && controlContainer.item.hovered) + { + return; + } + + base.hovered = false; + base.hideTooltip(); + } + } + + UM.SimpleButton + { + // This button shows when the setting has an inherited function, but is overriden by profile. + id: inheritButton; + +// visible: has_profile_value && base.has_inherit_function && base.is_enabled + height: parent.height; + width: height; + + onClicked: { + base.resetToDefaultRequested(); + controlContainer.notifyReset(); + } + + backgroundColor: UM.Theme.getColor("setting_control"); + hoverBackgroundColor: UM.Theme.getColor("setting_control_highlight") + color: UM.Theme.getColor("setting_control_button") + hoverColor: UM.Theme.getColor("setting_control_button_hover") + + iconSource: UM.Theme.getIcon("notice"); + + onEntered: base.showInheritanceTooltip({ x: mouse.mouseX, y: mouse.mouseY }) + + onExited: { + if(controlContainer.item && controlContainer.item.hovered) { + return; + } + + base.hovered = false; + base.hideTooltip(); + } + } + + } + + Rectangle + { + id: controlContainer; + + color: "red" + + anchors.right: parent.right; + anchors.verticalCenter: parent.verticalCenter; + width: UM.Theme.getSize("setting_control").width; + height: UM.Theme.getSize("setting_contorl").height + } +} diff --git a/resources/qml/Settings/SettingTextField.qml b/resources/qml/Settings/SettingTextField.qml new file mode 100644 index 0000000000..62f03b087d --- /dev/null +++ b/resources/qml/Settings/SettingTextField.qml @@ -0,0 +1,153 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.2 + +import UM 1.1 as UM + +SettingItem +{ + id: base + + contents: Rectangle + { + id: control + + anchors.fill: parent + + property alias hovered: mouseArea.containsMouse; + + border.width: base.style.controlBorderWidth; + border.color: !enabled ? base.style.controlDisabledBorderColor : hovered ? base.style.controlBorderHighlightColor : base.style.controlBorderColor + + property variant parentValue: value //From parent loader + function notifyReset() { + input.text = format(parentValue) + } + +// color: { +// if (!enabled) +// { +// return base.style.controlDisabledColor +// } +// switch(definition.validationState) //From parent loader +// { +// case 0: +// return base.style.validationErrorColor; +// case 1: +// return base.style.validationErrorColor; +// case 2: +// return base.style.validationErrorColor; +// case 3: +// return base.style.validationWarningColor; +// case 4: +// return base.style.validationWarningColor; +// case 5: +// return base.style.validationOkColor; +// +// default: +// return base.style.controlTextColor; +// } +// } + + Rectangle + { + anchors.fill: parent; + anchors.margins: base.style.controlBorderWidth; + color: base.style.controlHighlightColor; + opacity: 0.35 +// opacity: !control.hovered ? 0 : valid == 5 ? 1.0 : 0.35; + } + + Label + { + anchors.right: parent.right; + anchors.rightMargin: base.style.unitRightMargin; + anchors.verticalCenter: parent.verticalCenter; + + text: definition.unit; + color: base.style.unitColor + font: base.style.unitFont; + } + + MouseArea + { + id: mouseArea + anchors.fill: parent; + hoverEnabled: true; + cursorShape: Qt.IBeamCursor + } + + TextInput + { + id: input + + anchors + { + left: parent.left + leftMargin: base.style.unitRightMargin + right: parent.right + verticalCenter: parent.verticalCenter + } + + Keys.onReleased: + { + text = text.replace(",", ".") // User convenience. We use dots for decimal values + if(parseFloat(text) != base.parentValue) + { + base.valueChanged(parseFloat(text)); + } + } + + onEditingFinished: + { + if(parseFloat(text) != base.parentValue) + { + base.valueChanged(parseFloat(text)); + } + } + + color: !enabled ? base.style.controlDisabledTextColor : base.style.controlTextColor; + font: base.style.controlFont; + + selectByMouse: true; + + maximumLength: 10; + + validator: RegExpValidator { regExp: /[0-9.,-]{0,10}/ } + +// Binding +// { +// target: input +// property: "text" +// value: format(base.parentValue) +// when: !input.activeFocus +// } + } + + //Rounds a floating point number to 4 decimals. This prevents floating + //point rounding errors. + // + //input: The number to round. + //decimals: The number of decimals (digits after the radix) to round to. + //return: The rounded number. + function roundFloat(input, decimals) + { + //First convert to fixed-point notation to round the number to 4 decimals and not introduce new floating point errors. + //Then convert to a string (is implicit). The fixed-point notation will be something like "3.200". + //Then remove any trailing zeroes and the radix. + return input.toFixed(decimals).replace(/\.?0*$/, ""); //Match on periods, if any ( \.? ), followed by any number of zeros ( 0* ), then the end of string ( $ ). + } + + //Formats a value for display in the text field. + // + //This correctly handles formatting of float values. + // + //input: The string value to format. + //return: The formatted string. + function format(inputValue) { + return parseFloat(inputValue) ? roundFloat(parseFloat(inputValue), 4) : inputValue //If it's a float, round to four decimals. + } + } +} diff --git a/resources/qml/Settings/SettingUnknown.qml b/resources/qml/Settings/SettingUnknown.qml new file mode 100644 index 0000000000..4b403e522f --- /dev/null +++ b/resources/qml/Settings/SettingUnknown.qml @@ -0,0 +1,13 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Controls 1.1 + +SettingItem +{ + Label + { + text: value + " " + unit; + } +} diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml new file mode 100644 index 0000000000..49beba0990 --- /dev/null +++ b/resources/qml/Settings/SettingView.qml @@ -0,0 +1,92 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 +import QtQuick.Layouts 1.1 + +import UM 1.2 as UM + +ScrollView +{ + id: base; + + style: UM.Theme.styles.scrollview; + flickableItem.flickableDirection: Flickable.VerticalFlick; + + property Action configureSettings; + signal showTooltip(Item item, point location, string text); + signal hideTooltip(); + + ListView + { + id: contents + spacing: UM.Theme.getSize("default_lining").height; + + model: UM.SettingDefinitionsModel { id: definitionsModel; containerId: "fdmprinter" } + + delegate: Loader + { + id: delegate + + width: ListView.view.width + + property var definition: model + property var settingDefinitionsModel: definitionsModel + + source: + { + switch(model.type) + { + case "int": + return "SettingTextField.qml" + case "float": + return "SettingTextField.qml" + case "double": + return "SettingTextField.qml" + case "enum": + return "SettingComboBox.qml" + case "boolean": + return "SettingCheckBox.qml" + case "string": + return "SettingTextField.qml" + case "category": + return "SettingCategory.qml" + default: + return "SettingUnknown.qml" + } + } + + Connections + { + target: item + onContextMenuRequested: { contextMenu.key = model.key; contextMenu.popup() } + onShowTooltip: base.showTooltip(delegate, position, model.description) + } + } + + UM.I18nCatalog { id: catalog; name: "uranium"; } + + Menu + { + id: contextMenu; + + property string key; + + MenuItem + { + //: Settings context menu action + text: catalog.i18nc("@action:menu", "Hide this setting"); + onTriggered: definitionsModel.hide(contextMenu.key); + } + MenuItem + { + //: Settings context menu action + text: catalog.i18nc("@action:menu", "Configure setting visiblity..."); + + onTriggered: if(base.configureSettings) base.configureSettings.trigger(contextMenu); + } + } + } +} diff --git a/resources/qml/Settings/SettingsConfigurationPage.qml b/resources/qml/Settings/SettingsConfigurationPage.qml new file mode 100644 index 0000000000..a2889d410a --- /dev/null +++ b/resources/qml/Settings/SettingsConfigurationPage.qml @@ -0,0 +1,119 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Layouts 1.1 +import QtQuick.Dialogs 1.1 +import QtQuick.Controls.Styles 1.1 +import QtQml 2.2 + +import UM 1.1 as UM + +import "../Preferences" + +PreferencesPage +{ + //: Machine configuration page title. + title: catalog.i18nc("@title:tab","Machine"); + id: base + + contents: ColumnLayout + { + z: base.z + anchors.fill: parent; + UM.I18nCatalog { id: catalog; name:"uranium"} + RowLayout + { + //: Active machine combo box label + Label { text: catalog.i18nc("@label:listbox","Active Machine:"); } + ComboBox + { + id: machineCombo; + Layout.fillWidth: true; + model: UM.Models.machinesModel; + textRole: "name"; + onActivated: + { + if(index != -1) + UM.Models.machinesModel.setActive(index); + } + + Connections + { + id: machineChange + target: UM.Application + onMachineChanged: machineCombo.currentIndex = machineCombo.find(UM.Application.machineName); + } + + Component.onCompleted: machineCombo.currentIndex = machineCombo.find(UM.Application.machineName); + } + //: Remove active machine button + Button { text: catalog.i18nc("@action:button","Remove"); onClicked: confirmRemoveDialog.open(); } + } + ScrollView + { + id: settingsScrollView + Layout.fillWidth: true; + Layout.fillHeight: true; + + ListView + { + id: settingsListView + delegate: settingDelegate + model: UM.Models.settingsModel + x: 0 + + section.property: "category" + section.delegate: Label { text: section } + } + } + } + + Component + { + id: settingDelegate + CheckBox + { + z:0 + id: settingCheckBox + text: model.name; + x: depth * 25 + checked: model.visibility + onClicked: ListView.view.model.setVisibility(model.key, checked) + //enabled: !model.disabled + + onHoveredChanged: + { + if(hovered) + { + var xPos = parent.x + settingCheckBox.width; + var yPos = parent.y; + toolTip.show(model.description, 1000, 200, undefined, undefined) //tooltip-text, hover-delay in msec, animation-length in msec, position X, position Y (both y en x == undefined: gives the tooltip a standard placement in the right corner) + } else + { + toolTip.hide(0, 0)//hover-delay in msec, animation-length in msec + } + } + } + } + + PreferencesToolTip + { + id: toolTip; + } + + MessageDialog + { + id: confirmRemoveDialog; + + icon: StandardIcon.Question; + //: Remove machine confirmation dialog title + title: catalog.i18nc("@title:window","Confirm Machine Deletion"); + //: Remove machine confirmation dialog text + text: catalog.i18nc("@label","Are you sure you wish to remove the machine?"); + standardButtons: StandardButton.Yes | StandardButton.No; + + onYes: UM.Models.machinesModel.removeMachine(machineCombo.currentIndex); + } +} From 27f31a19b57eecfadae3404b9059e8bec0fdb796 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 10 May 2016 17:31:32 +0200 Subject: [PATCH 031/705] Use the local SettingView in SidebarAdvanced --- resources/qml/SidebarAdvanced.qml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/qml/SidebarAdvanced.qml b/resources/qml/SidebarAdvanced.qml index 8a231aa53d..30f4e74db6 100644 --- a/resources/qml/SidebarAdvanced.qml +++ b/resources/qml/SidebarAdvanced.qml @@ -5,9 +5,9 @@ import QtQuick 2.0 import QtQuick.Controls 1.2 -import UM 1.0 as UM +import "Settings" -UM.SettingView { - expandedCategories: Printer.expandedCategories; - onExpandedCategoriesChanged: Printer.setExpandedCategories(expandedCategories); +SettingView { +// expandedCategories: Printer.expandedCategories; +// onExpandedCategoriesChanged: Printer.setExpandedCategories(expandedCategories); } From 0b0e53dcf5f05a8e78eb30c5b0cb096fe1d9d648 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Wed, 11 May 2016 09:37:21 +0200 Subject: [PATCH 032/705] JSON fix: max infill combine is 8 layers cause of cura statically defined array length (CURA-1255) --- resources/machines/fdmprinter.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/machines/fdmprinter.json b/resources/machines/fdmprinter.json index 23f5a67af9..c4c2253812 100644 --- a/resources/machines/fdmprinter.json +++ b/resources/machines/fdmprinter.json @@ -632,7 +632,7 @@ "default": 0.1, "min_value": "0.0001", "max_value_warning": "0.32", - "max_value": "1000", + "max_value": "layer_height * 8", "visible": false, "inherit_function": "layer_height" }, From 9fcc3930ffb8c7f38b6df07297d3cbe560e048b3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 11 May 2016 14:30:44 +0200 Subject: [PATCH 033/705] ContainerStackModel is now used for listing all added machines CURA-1278 --- resources/qml/SidebarHeader.qml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 1c17233acb..92be44bc51 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -5,7 +5,7 @@ import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 -import UM 1.1 as UM +import UM 1.2 as UM Item { @@ -71,7 +71,10 @@ Item id: machineSelectionMenu Instantiator { -// model: UM.MachineInstancesModel { } + model: UM.ContainerStacksModel + { + filter: {"type": "machine"} + } MenuItem { text: model.name; From 48309431132c7d18aaaca95d78297a05c689ffcc Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 11 May 2016 15:21:01 +0200 Subject: [PATCH 034/705] Refactor grouping/ungrouping into an operation that is undoable CURA-1543 --- cura/CuraApplication.py | 45 +++++++++++++++++----------------- cura/SetParentOperation.py | 50 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 23 deletions(-) create mode 100644 cura/SetParentOperation.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 9b113b7de8..f381faa482 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -23,6 +23,7 @@ from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation from UM.Operations.GroupedOperation import GroupedOperation from UM.Operations.SetTransformOperation import SetTransformOperation +from cura.SetParentOperation import SetParentOperation from UM.i18n import i18nCatalog @@ -540,9 +541,10 @@ class CuraApplication(QtApplication): # Use the previously found center of the group bounding box as the new location of the group group_node.setPosition(group_node.getBoundingBox().center) - + @pyqtSlot() def groupSelected(self): + # Create a group-node group_node = SceneNode() group_decorator = GroupDecorator() group_node.addDecorator(group_decorator) @@ -552,40 +554,37 @@ class CuraApplication(QtApplication): group_node.setPosition(center) group_node.setCenterPosition(center) - for node in Selection.getAllSelectedObjects(): - world = node.getWorldPosition() - node.setParent(group_node) - node.setPosition(world - center) + # Move selected nodes into the group-node + op = GroupedOperation() + nodes = Selection.getAllSelectedObjects() + for node in nodes: + op.addOperation(SetParentOperation(node, group_node)) + op.push() + # Deselect individual nodes and select the groupnode instead for node in group_node.getChildren(): Selection.remove(node) - Selection.add(group_node) @pyqtSlot() def ungroupSelected(self): - ungrouped_nodes = [] selected_objects = Selection.getAllSelectedObjects()[:] #clone the list for node in selected_objects: - if node.callDecoration("isGroup" ): - children_to_move = [] - for child in node.getChildren(): - if type(child) is SceneNode: - children_to_move.append(child) + if node.callDecoration("isGroup"): + op = GroupedOperation() - for child in children_to_move: - position = child.getWorldPosition() - child.setParent(node.getParent()) - child.setPosition(position - node.getParent().getWorldPosition()) - child.scale(node.getScale()) - child.rotate(node.getOrientation()) + group_parent = node.getParent() + children = node.getChildren()[:] #clone the list + for child in children: + # Set the parent of the children to the parent of the group-node + op.addOperation(SetParentOperation(child, group_parent)) + # Add all individual nodes to the selection Selection.add(child) - child.callDecoration("setConvexHull",None) - node.setParent(None) - ungrouped_nodes.append(node) - for node in ungrouped_nodes: - Selection.remove(node) + child.callDecoration("setConvexHull", None) + + op.push() + # Note: The group removes itself from the scene once all its children have left it, see GroupDecorator._onChildrenChanged def _createSplashScreen(self): return CuraSplashScreen.CuraSplashScreen() diff --git a/cura/SetParentOperation.py b/cura/SetParentOperation.py new file mode 100644 index 0000000000..c40ce54909 --- /dev/null +++ b/cura/SetParentOperation.py @@ -0,0 +1,50 @@ +# Copyright (c) 2016 Ultimaker B.V. +# Uranium is released under the terms of the AGPLv3 or higher. + +from UM.Scene.SceneNode import SceneNode +from UM.Operations import Operation + +from UM.Math.Vector import Vector + +## An operation that parents a scene node to another scene node. + +class SetParentOperation(Operation.Operation): + ## Initialises this SetParentOperation. + # + # \param node The node which will be reparented. + # \param parent_node The node which will be the parent. + def __init__(self, node, parent_node): + super().__init__() + self._node = node + self._parent = parent_node + self._old_parent = node.getParent() # To restore the previous parent in case of an undo. + + ## Undoes the set-parent operation, restoring the old parent. + def undo(self): + self._set_parent(self._old_parent) + + ## Re-applies the set-parent operation. + def redo(self): + self._set_parent(self._parent) + + ## Sets the parent of the node while applying transformations to the world-transform of the node stays the same. + # + # \param new_parent The new parent. Note: this argument can be None, which would hide the node from the scene. + def _set_parent(self, new_parent): + if new_parent: + self._node.setPosition(self._node.getWorldPosition() - new_parent.getWorldPosition()) + current_parent = self._node.getParent() + if current_parent: + self._node.scale(current_parent.getScale() / new_parent.getScale()) + self._node.rotate(current_parent.getOrientation()) + else: + self._node.scale(Vector(1, 1, 1) / new_parent.getScale()) + self._node.rotate(new_parent.getOrientation().getInverse()) + + self._node.setParent(new_parent) + + ## Returns a programmer-readable representation of this operation. + # + # \return A programmer-readable representation of this operation. + def __repr__(self): + return "SetParentOperation(node = {0}, parent_node={1})".format(self._node, self._parent) From 573c1c1a5a491fb89e5071f5e682b0bada1fdb45 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 11 May 2016 15:35:41 +0200 Subject: [PATCH 035/705] Added MachineManagerModel to Cura CURA-1278 --- cura/CuraApplication.py | 6 +++++- cura/MachineManagerModel.py | 25 +++++++++++++++++++++++++ resources/qml/SidebarHeader.qml | 5 +++-- 3 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 cura/MachineManagerModel.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 174621be03..9a0071a41f 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -36,10 +36,11 @@ from . import CuraActions from . import MultiMaterialDecorator from . import ZOffsetDecorator from . import CuraSplashScreen +from . import MachineManagerModel from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty, QEvent, Q_ENUMS from PyQt5.QtGui import QColor, QIcon -from PyQt5.QtQml import qmlRegisterUncreatableType +from PyQt5.QtQml import qmlRegisterUncreatableType, qmlRegisterSingletonType import platform import sys @@ -201,6 +202,9 @@ class CuraApplication(QtApplication): self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml")) self.initializeEngine() + qmlRegisterSingletonType(MachineManagerModel.MachineManagerModel, "Cura", 1, 0, "MachineManager", + MachineManagerModel.createMachineManagerModel) + if self._engine.rootObjects: self.closeSplash() diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py new file mode 100644 index 0000000000..3b89ae8048 --- /dev/null +++ b/cura/MachineManagerModel.py @@ -0,0 +1,25 @@ + +from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal +from UM.Application import Application +from UM.Signal import Signal, signalemitter + +class MachineManagerModel(QObject): + def __init__(self, parent = None): + super().__init__(parent) + Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged) + + globalContainerChanged = pyqtSignal() + + def _onGlobalContainerChanged(self): + self.globalContainerChanged.emit() + + @pyqtSlot(str) + def setActiveMachine(self, stack_id): + pass + + @pyqtProperty(str, notify = globalContainerChanged) + def activeMachineId(self): + return Application.getInstance().getGlobalContainerStack().getId() + +def createMachineManagerModel(engine, script_engine): + return MachineManagerModel() \ No newline at end of file diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 92be44bc51..b66aea084a 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -6,6 +6,7 @@ import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 import UM 1.2 as UM +import Cura 1.0 as Cura Item { @@ -79,9 +80,9 @@ Item { text: model.name; checkable: true; - checked: model.active; + checked: Cura.MachineManager.activeMachineId == model.id exclusiveGroup: machineSelectionMenuGroup; - onTriggered: UM.MachineManager.setActiveMachineInstance(model.name); + onTriggered: Cura.MachineManager.setActiveMachine(model.id); } onObjectAdded: machineSelectionMenu.insertItem(index, object) onObjectRemoved: machineSelectionMenu.removeItem(object) From f91a4f9369c0ab24098d1aea42ee4ba741369f46 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 11 May 2016 16:13:30 +0200 Subject: [PATCH 036/705] Moved registration of MachineManager model to before QML is read Else the model is undefined on first run, which caused a number of silly issues. CURA-1278 --- cura/CuraApplication.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 9a0071a41f..17450029a3 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -199,12 +199,12 @@ class CuraApplication(QtApplication): self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Loading interface...")) - self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml")) - self.initializeEngine() - qmlRegisterSingletonType(MachineManagerModel.MachineManagerModel, "Cura", 1, 0, "MachineManager", MachineManagerModel.createMachineManagerModel) + self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml")) + self.initializeEngine() + if self._engine.rootObjects: self.closeSplash() From 66a29a2f1c112d7805091df928df46a73a928db5 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 11 May 2016 16:21:09 +0200 Subject: [PATCH 037/705] Added name for active machine CURA-1278 --- cura/MachineManagerModel.py | 12 ++++++++++-- resources/qml/SidebarHeader.qml | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 3b89ae8048..c5f2fc3fa6 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -1,7 +1,7 @@ from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal from UM.Application import Application -from UM.Signal import Signal, signalemitter +from UM.Settings.ContainerRegistry import ContainerRegistry class MachineManagerModel(QObject): def __init__(self, parent = None): @@ -15,11 +15,19 @@ class MachineManagerModel(QObject): @pyqtSlot(str) def setActiveMachine(self, stack_id): - pass + containers = ContainerRegistry.getInstance().findContainerStacks(id = stack_id) + if containers: + Application.getInstance().setGlobalContainerStack(containers[0]) + + @pyqtProperty(str, notify = globalContainerChanged) + def activeMachineName(self): + return Application.getInstance().getGlobalContainerStack().getName() @pyqtProperty(str, notify = globalContainerChanged) def activeMachineId(self): return Application.getInstance().getGlobalContainerStack().getId() + + def createMachineManagerModel(engine, script_engine): return MachineManagerModel() \ No newline at end of file diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index b66aea084a..83188007cf 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -58,10 +58,10 @@ Item ToolButton { id: machineSelection - text: UM.MachineManager.activeMachineInstance; + text: Cura.MachineManager.activeMachineName; width: parent.width/100*55 height: UM.Theme.getSize("setting_control").height - tooltip: UM.MachineManager.activeMachineInstance; + tooltip: Cura.MachineManager.activeMachineName; anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("default_margin").width anchors.verticalCenter: parent.verticalCenter From 21f57664163e61f97b1912e74722d644de426004 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Wed, 11 May 2016 16:39:44 +0200 Subject: [PATCH 038/705] JSON feat: switch_extruder_retraction_hop (CURA-1061) --- resources/machines/dual_extrusion_printer.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/resources/machines/dual_extrusion_printer.json b/resources/machines/dual_extrusion_printer.json index 2977345bcb..05096ffdd0 100644 --- a/resources/machines/dual_extrusion_printer.json +++ b/resources/machines/dual_extrusion_printer.json @@ -304,6 +304,18 @@ "global_only": true } } + }, + "switch_extruder_retraction_hop": { + "label": "Nozzle Switch Z Hop", + "description": "Whenever the machine switches to another nozzle, the build plate is lowered to create clearance between the nozzle and the print. It prevents the nozzle which has been unused for a while from oozing material on the outside of the print.", + "unit": "mm", + "type": "float", + "default": 1.0, + "min_value_warning": "-0.0001", + "max_value_warning": "10", + "visible": false, + "inherit": false, + "enabled": "retraction_enable" } } } From 9993fcc3cf20e5b1c380c166d708b65475230bab Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Wed, 11 May 2016 17:14:49 +0200 Subject: [PATCH 039/705] JSON feat: layer_0_z_overlap (CURA-1549) --- resources/machines/fdmprinter.json | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/resources/machines/fdmprinter.json b/resources/machines/fdmprinter.json index 638301d4a7..9bb53c89a2 100644 --- a/resources/machines/fdmprinter.json +++ b/resources/machines/fdmprinter.json @@ -1485,13 +1485,26 @@ "description": "The gap between the final raft layer and the first layer of the object. Only the first layer is raised by this amount to lower the bonding between the raft layer and the object. Makes it easier to peel off the raft.", "unit": "mm", "type": "float", - "default": 0.35, + "default": 0.3, "min_value": "0", "max_value_warning": "1.0", "enabled": "adhesion_type == \"raft\"", "global_only": "True", "visible": true }, + "layer_0_z_overlap": { + "label": "First Layer Z Overlap", + "description": "Make the first and second layer of the object 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", + "type": "float", + "default": 0.05, + "inherit_function": "layer_height / 2", + "min_value": "0", + "max_value_warning": "layer_height", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True", + "visible": true + }, "raft_surface_layers": { "label": "Raft Top Layers", "description": "The number of top layers on top of the 2nd raft layer. These are fully filled layers that the object sits on. 2 layers result in a smoother top surface than 1.", From fbbe6cde78479edb07e07cf540d198608778abb2 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 May 2016 16:35:17 +0200 Subject: [PATCH 040/705] Expose the Actions object as a QML singleton This makes it much simpler to use actions from within other objects --- resources/qml/Actions.qml | 2 ++ resources/qml/qmldir | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 resources/qml/qmldir diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index 003a3ceeec..ad88aa3c39 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -1,6 +1,8 @@ // Copyright (c) 2015 Ultimaker B.V. // Cura is released under the terms of the AGPLv3 or higher. +pragma Singleton + import QtQuick 2.2 import QtQuick.Controls 1.1 import UM 1.1 as UM diff --git a/resources/qml/qmldir b/resources/qml/qmldir new file mode 100644 index 0000000000..096561aca5 --- /dev/null +++ b/resources/qml/qmldir @@ -0,0 +1,3 @@ +module Cura + +singleton Actions 1.0 Actions.qml From 207bdb3cd5669e1c7f272d0ee9ee34409c4068f4 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 May 2016 16:37:34 +0200 Subject: [PATCH 041/705] Update Cura.qml to use Actions as singleton instead of instantiating them --- resources/qml/Cura.qml | 287 ++++++++++++++++++++++------------------- 1 file changed, 154 insertions(+), 133 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index e39cd733d9..3b887796eb 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -9,6 +9,8 @@ import QtQuick.Dialogs 1.1 import UM 1.1 as UM +import "." + UM.MainWindow { id: base @@ -53,7 +55,7 @@ UM.MainWindow title: catalog.i18nc("@title:menu menubar:toplevel","&File"); MenuItem { - action: actions.open; + action: Actions.open; } Menu @@ -115,11 +117,11 @@ UM.MainWindow } } - MenuItem { action: actions.reloadAll; } + MenuItem { action: Actions.reloadAll; } MenuSeparator { } - MenuItem { action: actions.quit; } + MenuItem { action: Actions.quit; } } Menu @@ -127,17 +129,17 @@ UM.MainWindow //: Edit menu title: catalog.i18nc("@title:menu menubar:toplevel","&Edit"); - MenuItem { action: actions.undo; } - MenuItem { action: actions.redo; } + MenuItem { action: Actions.undo; } + MenuItem { action: Actions.redo; } MenuSeparator { } - MenuItem { action: actions.deleteSelection; } - MenuItem { action: actions.deleteAll; } - MenuItem { action: actions.resetAllTranslation; } - MenuItem { action: actions.resetAll; } + MenuItem { action: Actions.deleteSelection; } + MenuItem { action: Actions.deleteAll; } + MenuItem { action: Actions.resetAllTranslation; } + MenuItem { action: Actions.resetAll; } MenuSeparator { } - MenuItem { action: actions.groupObjects;} - MenuItem { action: actions.mergeObjects;} - MenuItem { action: actions.unGroupObjects;} + MenuItem { action: Actions.groupObjects;} + MenuItem { action: Actions.mergeObjects;} + MenuItem { action: Actions.unGroupObjects;} } Menu @@ -201,10 +203,10 @@ UM.MainWindow ExclusiveGroup { id: machineVariantsGroup; } - MenuSeparator { visible: UM.MachineManager.hasVariants; } +// MenuSeparator { visible: UM.MachineManager.hasVariants; } - MenuItem { action: actions.addMachine; } - MenuItem { action: actions.configureMachines; } + MenuItem { action: Actions.addMachine; } + MenuItem { action: Actions.configureMachines; } } Menu @@ -277,11 +279,11 @@ UM.MainWindow MenuSeparator { id: profileMenuSeparator } - MenuItem { action: actions.updateProfile; } - MenuItem { action: actions.resetProfile; } - MenuItem { action: actions.addProfile; } + MenuItem { action: Actions.updateProfile; } + MenuItem { action: Actions.resetProfile; } + MenuItem { action: Actions.addProfile; } MenuSeparator { } - MenuItem { action: actions.manageProfiles; } + MenuItem { action: Actions.manageProfiles; } } Menu @@ -323,7 +325,7 @@ UM.MainWindow //: Settings menu title: catalog.i18nc("@title:menu menubar:toplevel","&Settings"); - MenuItem { action: actions.preferences; } + MenuItem { action: Actions.preferences; } } Menu @@ -331,11 +333,11 @@ UM.MainWindow //: Help menu title: catalog.i18nc("@title:menu menubar:toplevel","&Help"); - MenuItem { action: actions.showEngineLog; } - MenuItem { action: actions.documentation; } - MenuItem { action: actions.reportBug; } + MenuItem { action: Actions.showEngineLog; } + MenuItem { action: Actions.documentation; } + MenuItem { action: Actions.reportBug; } MenuSeparator { } - MenuItem { action: actions.about; } + MenuItem { action: Actions.about; } } } @@ -425,7 +427,7 @@ UM.MainWindow left: parent.left; //leftMargin: UM.Theme.getSize("loadfile_margin").width } - action: actions.open; + action: Actions.open; } Image @@ -513,22 +515,12 @@ UM.MainWindow width: UM.Theme.getSize("sidebar").width; - addMachineAction: actions.addMachine; - configureMachinesAction: actions.configureMachines; - addProfileAction: actions.addProfile; - updateProfileAction: actions.updateProfile; - resetProfileAction: actions.resetProfile; - manageProfilesAction: actions.manageProfiles; - - configureSettingsAction: Action - { - onTriggered: - { - preferences.visible = true; - preferences.setPage(2); - preferences.getCurrentItem().scrollToSection(source.key); - } - } + addMachineAction: Actions.addMachine; + configureMachinesAction: Actions.configureMachines; + addProfileAction: Actions.addProfile; + updateProfileAction: Actions.updateProfile; + resetProfileAction: Actions.resetProfile; + manageProfilesAction: Actions.manageProfiles; } } } @@ -561,73 +553,16 @@ UM.MainWindow } } - Actions + Connections { - id: actions; + target: Actions.preferences + onTriggered: preferences.visible = true + } - open.onTriggered: openDialog.open(); - - quit.onTriggered: base.visible = false; - - undo.onTriggered: UM.OperationStack.undo(); - undo.enabled: UM.OperationStack.canUndo; - redo.onTriggered: UM.OperationStack.redo(); - redo.enabled: UM.OperationStack.canRedo; - - deleteSelection.onTriggered: - { - Printer.deleteSelection(); - } - - deleteObject.onTriggered: - { - if(objectContextMenu.objectId != 0) - { - Printer.deleteObject(objectContextMenu.objectId); - objectContextMenu.objectId = 0; - } - } - - multiplyObject.onTriggered: - { - if(objectContextMenu.objectId != 0) - { - Printer.multiplyObject(objectContextMenu.objectId, 1); - objectContextMenu.objectId = 0; - } - } - - centerObject.onTriggered: - { - if(objectContextMenu.objectId != 0) - { - Printer.centerObject(objectContextMenu.objectId); - objectContextMenu.objectId = 0; - } - } - - groupObjects.onTriggered: - { - Printer.groupSelected(); - } - - unGroupObjects.onTriggered: - { - Printer.ungroupSelected(); - } - - mergeObjects.onTriggered: - { - Printer.mergeSelected(); - } - - deleteAll.onTriggered: Printer.deleteAll(); - resetAllTranslation.onTriggered: Printer.resetAllTranslation(); - resetAll.onTriggered: Printer.resetAll(); - reloadAll.onTriggered: Printer.reloadAll(); - - addMachine.onTriggered: addMachineDialog.visible = true; - addProfile.onTriggered: + Connections + { + target: Actions.addProfile + onTriggered: { UM.MachineManager.createProfile(); preferences.setPage(4); @@ -636,26 +571,37 @@ UM.MainWindow // Show the renameDialog after a very short delay so the preference page has time to initiate showProfileNameDialogTimer.start(); } - updateProfile.onTriggered: UM.ActiveProfile.updateProfile(); - resetProfile.onTriggered: UM.ActiveProfile.discardChanges(); + } - preferences.onTriggered: preferences.visible = true; - configureMachines.onTriggered: + Connections + { + target: Actions.configureMachines + onTriggered: { preferences.visible = true; preferences.setPage(3); } - manageProfiles.onTriggered: + } + + Connections + { + target: Actions.manageProfiles + onTriggered: { preferences.visible = true; preferences.setPage(4); } + } - documentation.onTriggered: CuraActions.openDocumentation(); - reportBug.onTriggered: CuraActions.openBugReportPage(); - showEngineLog.onTriggered: engineLog.visible = true; - about.onTriggered: aboutDialog.visible = true; - toggleFullScreen.onTriggered: base.toggleFullscreen(); + Connections + { + target: Actions.configureSettingVisibility + onTriggered: + { + preferences.visible = true; + preferences.setPage(2); + preferences.getCurrentItem().scrollToSection(source.key); + } } Timer @@ -672,29 +618,68 @@ UM.MainWindow id: objectContextMenu; property variant objectId: -1; - MenuItem { action: actions.centerObject; } - MenuItem { action: actions.deleteObject; } - MenuItem { action: actions.multiplyObject; } + MenuItem { action: Actions.centerObject; } + MenuItem { action: Actions.deleteObject; } + MenuItem { action: Actions.multiplyObject; } MenuSeparator { } - MenuItem { action: actions.deleteAll; } - MenuItem { action: actions.reloadAll; } - MenuItem { action: actions.resetAllTranslation; } - MenuItem { action: actions.resetAll; } - MenuItem { action: actions.groupObjects; } - MenuItem { action: actions.mergeObjects; } - MenuItem { action: actions.unGroupObjects; } + MenuItem { action: Actions.deleteAll; } + MenuItem { action: Actions.reloadAll; } + MenuItem { action: Actions.resetAllTranslation; } + MenuItem { action: Actions.resetAll; } + MenuItem { action: Actions.groupObjects; } + MenuItem { action: Actions.mergeObjects; } + MenuItem { action: Actions.unGroupObjects; } + + Connections + { + target: Actions.deleteObject + onTriggered: + { + if(objectContextMenu.objectId != 0) + { + Printer.deleteObject(objectContextMenu.objectId); + objectContextMenu.objectId = 0; + } + } + } + + Connections + { + target: Actions.multiplyObject + onTriggered: + { + if(objectContextMenu.objectId != 0) + { + Printer.multiplyObject(objectContextMenu.objectId, 1); + objectContextMenu.objectId = 0; + } + } + } + + Connections + { + target: Actions.centerObject + onTriggered: + { + if(objectContextMenu.objectId != 0) + { + Printer.centerObject(objectContextMenu.objectId); + objectContextMenu.objectId = 0; + } + } + } } Menu { id: contextMenu; - MenuItem { action: actions.deleteAll; } - MenuItem { action: actions.reloadAll; } - MenuItem { action: actions.resetAllTranslation; } - MenuItem { action: actions.resetAll; } - MenuItem { action: actions.groupObjects; } - MenuItem { action: actions.mergeObjects; } - MenuItem { action: actions.unGroupObjects; } + MenuItem { action: Actions.deleteAll; } + MenuItem { action: Actions.reloadAll; } + MenuItem { action: Actions.resetAllTranslation; } + MenuItem { action: Actions.resetAll; } + MenuItem { action: Actions.groupObjects; } + MenuItem { action: Actions.mergeObjects; } + MenuItem { action: Actions.unGroupObjects; } } Connections @@ -713,6 +698,18 @@ UM.MainWindow } } + Connections + { + target: Actions.quit + onTriggered: base.visible = false; + } + + Connections + { + target: Actions.toggleFullScreen + onTriggered: base.toggleFullscreen(); + } + FileDialog { id: openDialog; @@ -737,21 +734,45 @@ UM.MainWindow } } + Connections + { + target: Actions.open + onTriggered: openDialog.open() + } + EngineLog { id: engineLog; } + Connections + { + target: Actions.showEngineLog + onTriggered: engineLog.visible = true; + } + AddMachineDialog { id: addMachineDialog } + Connections + { + target: Actions.addMachine + onTriggered: addMachineDialog.visible = true; + } + AboutDialog { id: aboutDialog } + Connections + { + target: Actions.about + onTriggered: aboutDialog.visible = true; + } + Connections { target: Printer From 5e226038d94bf3008712fa9efe1048dfa1bc9fba Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 May 2016 16:38:54 +0200 Subject: [PATCH 042/705] Instantiate models instead of using the Models object Since Models has been removed --- resources/qml/Cura.qml | 2 +- resources/qml/Toolbar.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 3b887796eb..6c54c439a9 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -294,7 +294,7 @@ UM.MainWindow Instantiator { - model: UM.Models.extensionModel + model: UM.ExtensionModel { } Menu { diff --git a/resources/qml/Toolbar.qml b/resources/qml/Toolbar.qml index d5274cd873..bde063de10 100644 --- a/resources/qml/Toolbar.qml +++ b/resources/qml/Toolbar.qml @@ -25,7 +25,7 @@ Item { Repeater { id: repeat - model: UM.Models.toolModel + model: UM.ToolModel { } Button { text: model.name From 8c5b3c8b1dfee4a1779288d50ffe73c21de78f3a Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 May 2016 16:40:39 +0200 Subject: [PATCH 043/705] Directly implement onTriggered in Actions for several actions Since they use global objects we can directly call those methods. This makes it simpler to call these actions from other objects. --- resources/qml/Actions.qml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index ad88aa3c39..bc9ef89e24 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -62,6 +62,8 @@ Item text: catalog.i18nc("@action:inmenu menubar:edit","&Undo"); iconName: "edit-undo"; shortcut: StandardKey.Undo; + onTriggered: UM.OperationStack.undo(); + enabled: UM.OperationStack.canUndo; } Action @@ -70,6 +72,8 @@ Item text: catalog.i18nc("@action:inmenu menubar:edit","&Redo"); iconName: "edit-redo"; shortcut: StandardKey.Redo; + onTriggered: UM.OperationStack.redo(); + enabled: UM.OperationStack.canRedo; } Action @@ -105,6 +109,7 @@ Item id: updateProfileAction; enabled: UM.ActiveProfile.valid && !UM.ActiveProfile.readOnly && UM.ActiveProfile.hasCustomisedValues text: catalog.i18nc("@action:inmenu menubar:profile","&Update Current Profile"); + onTriggered: UM.ActiveProfile.updateProfile(); } Action @@ -112,6 +117,7 @@ Item id: resetProfileAction; enabled: UM.ActiveProfile.valid && UM.ActiveProfile.hasCustomisedValues text: catalog.i18nc("@action:inmenu menubar:profile","&Reload Current Profile"); + onTriggered: UM.ActiveProfile.discardChanges(); } Action @@ -134,12 +140,14 @@ Item text: catalog.i18nc("@action:inmenu menubar:help","Show Online &Documentation"); iconName: "help-contents"; shortcut: StandardKey.Help; + onTriggered: CuraActions.openDocumentation(); } Action { id: reportBugAction; text: catalog.i18nc("@action:inmenu menubar:help","Report a &Bug"); iconName: "tools-report-bug"; + onTriggered: CuraActions.openBugReportPage(); } Action @@ -156,6 +164,7 @@ Item enabled: UM.Controller.toolsEnabled; iconName: "edit-delete"; shortcut: StandardKey.Delete; + onTriggered: Printer.deleteSelection(); } Action @@ -178,6 +187,7 @@ Item text: catalog.i18nc("@action:inmenu menubar:edit","&Group Objects"); enabled: UM.Scene.numObjectsSelected > 1 ? true: false iconName: "object-group" + onTriggered: Printer.groupSelected(); } Action @@ -186,6 +196,7 @@ Item text: catalog.i18nc("@action:inmenu menubar:edit","Ungroup Objects"); enabled: UM.Scene.isGroupSelected iconName: "object-ungroup" + onTriggered: Printer.ungroupSelected(); } Action @@ -194,6 +205,7 @@ Item text: catalog.i18nc("@action:inmenu menubar:edit","&Merge Objects"); enabled: UM.Scene.numObjectsSelected > 1 ? true: false iconName: "merge"; + onTriggered: Printer.mergeSelected(); } Action @@ -210,6 +222,7 @@ Item enabled: UM.Controller.toolsEnabled; iconName: "edit-delete"; shortcut: "Ctrl+D"; + onTriggered: Printer.deleteAll(); } Action @@ -217,18 +230,21 @@ Item id: reloadAllAction; text: catalog.i18nc("@action:inmenu menubar:file","Re&load All Objects"); iconName: "document-revert"; + onTriggered: Printer.reloadAll(); } Action { id: resetAllTranslationAction; text: catalog.i18nc("@action:inmenu menubar:edit","Reset All Object Positions"); + onTriggered: Printer.resetAllTranslation(); } Action { id: resetAllAction; text: catalog.i18nc("@action:inmenu menubar:edit","Reset All Object &Transformations"); + onTriggered: Printer.resetAll(); } Action From 3bfe18e76f35a0aea5b129518a1eced0acff0cdc Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 May 2016 16:41:22 +0200 Subject: [PATCH 044/705] Add a configureSettingVisibility action --- resources/qml/Actions.qml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index bc9ef89e24..afb018fa69 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -47,6 +47,8 @@ Item property alias toggleFullScreen: toggleFullScreenAction; + property alias configureSettingVisibility: configureSettingVisibilityAction + UM.I18nCatalog{id: catalog; name:"cura"} Action @@ -262,4 +264,10 @@ Item iconName: "view-list-text"; shortcut: StandardKey.WhatsThis; } + + Action + { + id: configureSettingVisibilityAction + text: catalog.i18nc("@action:menu", "Configure setting visiblity..."); + } } From d761409bf2b1a074850766bbcec2582d96ce5b77 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 May 2016 16:51:09 +0200 Subject: [PATCH 045/705] Remove SettingItemStyle from the cura theme As it is no longer needed --- resources/themes/cura/styles.qml | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/resources/themes/cura/styles.qml b/resources/themes/cura/styles.qml index e536c38ba7..cb85abf0c1 100644 --- a/resources/themes/cura/styles.qml +++ b/resources/themes/cura/styles.qml @@ -280,35 +280,6 @@ QtObject { } } - property variant setting_item: UM.SettingItemStyle { - labelFont: Theme.getFont("default"); - labelColor: Theme.getColor("setting_control_text"); - - spacing: Theme.getSize("default_lining").height; - fixedHeight: Theme.getSize("setting").height; - - controlWidth: Theme.getSize("setting_control").width; - controlRightMargin: Theme.getSize("setting_control_margin").width; - controlColor: Theme.getColor("setting_control"); - controlHighlightColor: Theme.getColor("setting_control_highlight"); - controlBorderColor: Theme.getColor("setting_control_border"); - controlBorderHighlightColor: Theme.getColor("setting_control_border_highlight"); - controlTextColor: Theme.getColor("setting_control_text"); - controlBorderWidth: Theme.getSize("default_lining").width; - controlDisabledColor: Theme.getColor("setting_control_disabled"); - controlDisabledTextColor: Theme.getColor("setting_control_disabled_text"); - controlDisabledBorderColor: Theme.getColor("setting_control_disabled_border"); - controlFont: Theme.getFont("default"); - - validationErrorColor: Theme.getColor("setting_validation_error"); - validationWarningColor: Theme.getColor("setting_validation_warning"); - validationOkColor: Theme.getColor("setting_validation_ok"); - - unitRightMargin: Theme.getSize("setting_unit_margin").width; - unitColor: Theme.getColor("setting_unit"); - unitFont: Theme.getFont("default"); - } - property Component combobox: Component { ComboBoxStyle { background: Rectangle { From fa9f9b41ab9eacf52802ca4c41a315a1bfffac9f Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 May 2016 16:52:27 +0200 Subject: [PATCH 046/705] Fix SettingUnknown setting handler to display correctly --- resources/qml/Settings/SettingUnknown.qml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingUnknown.qml b/resources/qml/Settings/SettingUnknown.qml index 4b403e522f..55e26b6695 100644 --- a/resources/qml/Settings/SettingUnknown.qml +++ b/resources/qml/Settings/SettingUnknown.qml @@ -4,10 +4,16 @@ import QtQuick 2.1 import QtQuick.Controls 1.1 +import UM 1.2 as UM + SettingItem { - Label + contents: Label { + anchors.fill: parent text: value + " " + unit; + color: UM.Theme.getColor("setting_control_text") + + verticalAlignment: Qt.AlignVCenter } } From 4c9b9b68ef8263d2f6f577b16db36a5d0d80b8ba Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 May 2016 16:52:56 +0200 Subject: [PATCH 047/705] Add add/remove transitions so expand/collapse is animated --- resources/qml/Settings/SettingView.qml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 49beba0990..92f228a9d8 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -68,6 +68,28 @@ ScrollView UM.I18nCatalog { id: catalog; name: "uranium"; } + add: Transition { + SequentialAnimation { + NumberAnimation { properties: "height"; from: 0; duration: 100 } + NumberAnimation { properties: "opacity"; from: 0; duration: 100 } + } + } + remove: Transition { + SequentialAnimation { + NumberAnimation { properties: "opacity"; to: 0; duration: 100 } + NumberAnimation { properties: "height"; to: 0; duration: 100 } + } + } + addDisplaced: Transition { + NumberAnimation { properties: "x,y"; duration: 100 } + } + removeDisplaced: Transition { + SequentialAnimation { + PauseAnimation { duration: 100; } + NumberAnimation { properties: "x,y"; duration: 100 } + } + } + Menu { id: contextMenu; From 2abb9a47c127fe9ab982260715d7cbd9f51fe703 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 May 2016 16:55:45 +0200 Subject: [PATCH 048/705] Stop using SettingItemStyle Since everything is now in Cura, using SettingItemStyle does not make a lot of sense anymore --- resources/qml/Settings/SettingCheckBox.qml | 15 ++--- resources/qml/Settings/SettingComboBox.qml | 22 +++---- resources/qml/Settings/SettingTextField.qml | 68 ++++++++++----------- 3 files changed, 53 insertions(+), 52 deletions(-) diff --git a/resources/qml/Settings/SettingCheckBox.qml b/resources/qml/Settings/SettingCheckBox.qml index b2bbc68ec1..37cad7fd4b 100644 --- a/resources/qml/Settings/SettingCheckBox.qml +++ b/resources/qml/Settings/SettingCheckBox.qml @@ -46,19 +46,20 @@ SettingItem { if (!enabled) { - return base.style.controlDisabledColor + return UM.Theme.getColor("setting_control_disabled") } if(base.containsMouse || base.activeFocus) { - return base.style.controlHighlightColor + return UM.Theme.getColor("setting_control_highlight") } else { - return base.style.controlColor + return UM.Theme.getColor("setting_control") } } - border.width: base.style.controlBorderWidth; - border.color: !enabled ? base.style.controlDisabledBorderColor : control.containsMouse ? base.style.controlBorderHighlightColor : base.style.controlBorderColor; + + border.width: UM.Theme.getSize("default_lining").width + border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : control.containsMouse ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border") UM.RecolorImage { anchors.verticalCenter: parent.verticalCenter @@ -67,9 +68,9 @@ SettingItem height: parent.height/2.5 sourceSize.width: width sourceSize.height: width - color: !enabled ? base.style.controlDisabledTextColor : base.style.controlTextColor; + color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text"); source: UM.Theme.getIcon("check") - opacity: control.checked + opacity: control.checked ? 1 : 0 Behavior on opacity { NumberAnimation { duration: 100; } } } } diff --git a/resources/qml/Settings/SettingComboBox.qml b/resources/qml/Settings/SettingComboBox.qml index 85935c3471..6fd4c5621c 100644 --- a/resources/qml/Settings/SettingComboBox.qml +++ b/resources/qml/Settings/SettingComboBox.qml @@ -33,33 +33,33 @@ SettingItem { if (!enabled) { - return base.style.controlDisabledColor + return UM.Theme.getColor("setting_control_disabled") } if(control.hovered || base.activeFocus) { - return base.style.controlHighlightColor + return UM.Theme.getColor("setting_control_highlight") } else { - return base.style.controlColor + return UM.Theme.getColor("setting_control") } } - border.width: base.style.controlBorderWidth; - border.color: !enabled ? base.style.controlDisabledBorderColor : control.hovered ? base.style.controlBorderHighlightColor : base.style.controlBorderColor; + border.width: UM.Theme.getSize("default_lining").width; + border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : control.hovered ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border"); } label: Item { Label { anchors.left: parent.left; - anchors.leftMargin: base.style.controlBorderWidth + anchors.leftMargin: UM.Theme.getSize("default_lining").width anchors.right: downArrow.left; - anchors.rightMargin: base.style.controlBorderWidth; + anchors.rightMargin: UM.Theme.getSize("default_lining").width; anchors.verticalCenter: parent.verticalCenter; text: control.currentText; - font: base.style.controlFont; - color: !enabled ? base.style.controlDisabledTextColor : base.style.controlTextColor; + font: UM.Theme.getFont("default"); + color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text"); elide: Text.ElideRight; verticalAlignment: Text.AlignVCenter; @@ -69,7 +69,7 @@ SettingItem { id: downArrow anchors.right: parent.right; - anchors.rightMargin: base.style.controlBorderWidth * 2; + anchors.rightMargin: UM.Theme.getSize("default_lining").width * 2; anchors.verticalCenter: parent.verticalCenter; source: UM.Theme.getIcon("arrow_bottom") @@ -78,7 +78,7 @@ SettingItem sourceSize.width: width + 5 sourceSize.height: width + 5 - color: base.style.controlTextColor; + color: UM.Theme.getColor("setting_control_text"); } } diff --git a/resources/qml/Settings/SettingTextField.qml b/resources/qml/Settings/SettingTextField.qml index 62f03b087d..1b28ebadcc 100644 --- a/resources/qml/Settings/SettingTextField.qml +++ b/resources/qml/Settings/SettingTextField.qml @@ -18,44 +18,44 @@ SettingItem property alias hovered: mouseArea.containsMouse; - border.width: base.style.controlBorderWidth; - border.color: !enabled ? base.style.controlDisabledBorderColor : hovered ? base.style.controlBorderHighlightColor : base.style.controlBorderColor + border.width: UM.Theme.getSize("default_lining").width + border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : hovered ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border") property variant parentValue: value //From parent loader function notifyReset() { input.text = format(parentValue) } -// color: { -// if (!enabled) -// { -// return base.style.controlDisabledColor -// } -// switch(definition.validationState) //From parent loader -// { -// case 0: -// return base.style.validationErrorColor; -// case 1: -// return base.style.validationErrorColor; -// case 2: -// return base.style.validationErrorColor; -// case 3: -// return base.style.validationWarningColor; -// case 4: -// return base.style.validationWarningColor; -// case 5: -// return base.style.validationOkColor; -// -// default: -// return base.style.controlTextColor; -// } -// } + color: { + if (!enabled) + { + return UM.Theme.getColor("setting_control_disabled") + } + switch(definition.validationState) + { + case 0: + return UM.Theme.getColor("setting_validation_error") + case 1: + return UM.Theme.getColor("setting_validation_error") + case 2: + return UM.Theme.getColor("setting_validation_error") + case 3: + return UM.Theme.getColor("setting_validation_warning") + case 4: + return UM.Theme.getColor("setting_validation_warning") + case 5: + return UM.Theme.getColor("setting_validation_ok") + + default: + return UM.Theme.getColor("setting_control") + } + } Rectangle { anchors.fill: parent; - anchors.margins: base.style.controlBorderWidth; - color: base.style.controlHighlightColor; + anchors.margins: UM.Theme.getSize("default_lining").width; + color: UM.Theme.getColor("setting_control_highlight") opacity: 0.35 // opacity: !control.hovered ? 0 : valid == 5 ? 1.0 : 0.35; } @@ -63,12 +63,12 @@ SettingItem Label { anchors.right: parent.right; - anchors.rightMargin: base.style.unitRightMargin; + anchors.rightMargin: UM.Theme.getSize("setting_unit_margin").width anchors.verticalCenter: parent.verticalCenter; text: definition.unit; - color: base.style.unitColor - font: base.style.unitFont; + color: UM.Theme.getColor("setting_unit") + font: UM.Theme.getFont("default") } MouseArea @@ -86,7 +86,7 @@ SettingItem anchors { left: parent.left - leftMargin: base.style.unitRightMargin + leftMargin: UM.Theme.unitRightMargin right: parent.right verticalCenter: parent.verticalCenter } @@ -108,8 +108,8 @@ SettingItem } } - color: !enabled ? base.style.controlDisabledTextColor : base.style.controlTextColor; - font: base.style.controlFont; + color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text") + font: UM.Theme.getFont("default"); selectByMouse: true; From b7fd97737c9d397cc3a37014be7a13cc843adb25 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 May 2016 17:03:02 +0200 Subject: [PATCH 049/705] Simplify tooltip handling for settings Rather than use three different signals, use a single showTooltip signal with a text property. This makes it possible to show any tooltip from within a setting item. --- resources/qml/Settings/SettingCategory.qml | 6 ++++-- resources/qml/Settings/SettingItem.qml | 4 ++-- resources/qml/Settings/SettingView.qml | 3 ++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index b4c0263149..455ef3d3e1 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -13,7 +13,7 @@ Button { style: UM.Theme.styles.sidebar_category; - signal showTooltip(); + signal showTooltip(string text); signal hideTooltip(); signal contextMenuRequested() @@ -69,11 +69,13 @@ Button { iconSource: UM.Theme.getIcon("notice") onEntered: { - base.showTooltip() + base.showTooltip(catalog.i18nc("@label", "This setting is normally calculated, but it currently has an absolute value set.\n\nClick to restore the calculated value.")) } onExited: { base.hideTooltip(); } + + UM.I18nCatalog { id: catalog; name: "cura" } } } diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index 845f35853e..e8c3b0b7bb 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -18,7 +18,7 @@ Item { property alias contents: controlContainer.children signal contextMenuRequested() - signal showTooltip(var position); + signal showTooltip(string text); signal hideTooltip(); MouseArea @@ -49,7 +49,7 @@ Item { interval: 500; repeat: false; - onTriggered: base.showTooltip({ x: mouse.mouseX, y: mouse.mouseY }); + onTriggered: base.showTooltip(definition.description); } } diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 92f228a9d8..6d0944e1be 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -62,7 +62,8 @@ ScrollView { target: item onContextMenuRequested: { contextMenu.key = model.key; contextMenu.popup() } - onShowTooltip: base.showTooltip(delegate, position, model.description) + onShowTooltip: base.showTooltip(delegate, { x: 0, y: delegate.height / 2 }, text) + onHideTooltip: base.hideTooltip() } } From d68f274a098d7d8669bf90f5416a35c4593b4ff6 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 May 2016 17:03:54 +0200 Subject: [PATCH 050/705] Improve positioning of tooltips in advanced mode --- resources/qml/Sidebar.qml | 2 +- resources/qml/SidebarSimple.qml | 6 +++--- resources/qml/SidebarTooltip.qml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/resources/qml/Sidebar.qml b/resources/qml/Sidebar.qml index 5426125194..b98f3477dc 100644 --- a/resources/qml/Sidebar.qml +++ b/resources/qml/Sidebar.qml @@ -27,7 +27,7 @@ Rectangle function showTooltip(item, position, text) { tooltip.text = text; - position = item.mapToItem(base, position.x, position.y / 2); + position = item.mapToItem(base, position.x, position.y); tooltip.show(position); } diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 21aa315dd1..0e877ab09b 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -120,7 +120,7 @@ Item } } onEntered: { - base.showTooltip(infillCellRight, Qt.point(-infillCellRight.x, parent.height), model.text); + base.showTooltip(infillCellRight, Qt.point(-infillCellRight.x, 0), model.text); } onExited: { base.hideTooltip(); @@ -224,7 +224,7 @@ Item onEntered: { parent.hovered_ex = true - base.showTooltip(brimCheckBox, Qt.point(-helpersCellRight.x, parent.height), + base.showTooltip(brimCheckBox, Qt.point(-helpersCellRight.x, 0), catalog.i18nc("@label", "Enable printing a brim. This will add a single-layer-thick flat area around your object which is easy to cut off afterwards.")); } onExited: @@ -257,7 +257,7 @@ Item onEntered: { parent.hovered_ex = true - base.showTooltip(supportCheckBox, Qt.point(-helpersCellRight.x, parent.height), + base.showTooltip(supportCheckBox, Qt.point(-helpersCellRight.x, 0), catalog.i18nc("@label", "Enable printing support structures. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air.")); } onExited: diff --git a/resources/qml/SidebarTooltip.qml b/resources/qml/SidebarTooltip.qml index 1c7f4bcb76..5cb7ff1f0b 100644 --- a/resources/qml/SidebarTooltip.qml +++ b/resources/qml/SidebarTooltip.qml @@ -31,7 +31,7 @@ UM.PointingRectangle { y = position.y - UM.Theme.getSize("tooltip_arrow_margins").height; } base.opacity = 1; - target = Qt.point(40 , position.y) + target = Qt.point(40 , position.y + UM.Theme.getSize("tooltip_arrow_margins").height / 2) } function hide() { From cdc8b04c5c72cac15357dce9afa14447577de49b Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 May 2016 17:05:26 +0200 Subject: [PATCH 051/705] Use the configureSettingVisiblity action from Actions when needed --- resources/qml/Settings/SettingCategory.qml | 4 +++- resources/qml/Settings/SettingView.qml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index 455ef3d3e1..871b5c0036 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -8,6 +8,8 @@ import QtQuick.Layouts 1.1 import UM 1.1 as UM +import ".." + Button { id: base; @@ -43,7 +45,7 @@ Button { iconSource: UM.Theme.getIcon("settings"); onClicked: { - Actions.configureSettingVisibility() + Actions.configureSettingVisibility.trigger(definition) } } diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 6d0944e1be..76fd232f1a 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -8,6 +8,8 @@ import QtQuick.Layouts 1.1 import UM 1.2 as UM +import ".." + ScrollView { id: base; @@ -108,7 +110,7 @@ ScrollView //: Settings context menu action text: catalog.i18nc("@action:menu", "Configure setting visiblity..."); - onTriggered: if(base.configureSettings) base.configureSettings.trigger(contextMenu); + onTriggered: Actions.configureSettingVisibility.trigger(contextMenu); } } } From 38e9661fe1cb6645f8f076c3b9535af020eb6db0 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 May 2016 17:05:38 +0200 Subject: [PATCH 052/705] Fix setting type names --- resources/qml/Settings/SettingView.qml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 76fd232f1a..6fdc5d5082 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -45,13 +45,11 @@ ScrollView return "SettingTextField.qml" case "float": return "SettingTextField.qml" - case "double": - return "SettingTextField.qml" case "enum": return "SettingComboBox.qml" - case "boolean": + case "bool": return "SettingCheckBox.qml" - case "string": + case "str": return "SettingTextField.qml" case "category": return "SettingCategory.qml" From 89928dc6a957b8de3454141fc266589f2b54f333 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 May 2016 17:06:01 +0200 Subject: [PATCH 053/705] Make Setting item loading asynchronous and fix its size --- resources/qml/Settings/SettingView.qml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 6fdc5d5082..66ff30fa11 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -32,11 +32,14 @@ ScrollView { id: delegate - width: ListView.view.width + width: UM.Theme.getSize("sidebar").width; + height: UM.Theme.getSize("section").height; property var definition: model property var settingDefinitionsModel: definitionsModel + asynchronous: true + source: { switch(model.type) From 4390c6a6ff9a08900f49ffdd663058cd9cf70062 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 May 2016 17:06:48 +0200 Subject: [PATCH 054/705] Remove configureSettingsAction property from sidebar as it is no longer needed --- resources/qml/Sidebar.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/qml/Sidebar.qml b/resources/qml/Sidebar.qml index b98f3477dc..81823f039d 100644 --- a/resources/qml/Sidebar.qml +++ b/resources/qml/Sidebar.qml @@ -247,7 +247,6 @@ Rectangle id: sidebarAdvanced; visible: false; - configureSettings: base.configureSettingsAction; onShowTooltip: base.showTooltip(item, location, text) onHideTooltip: base.hideTooltip() } From 9ec93bedabbea2efbda3e58c4ab143221f02beb9 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 May 2016 17:07:27 +0200 Subject: [PATCH 055/705] Fix type and spacing of SettingItem contents --- resources/qml/Settings/SettingItem.qml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index e8c3b0b7bb..f9dac0b879 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -154,15 +154,14 @@ Item { } - Rectangle + Item { id: controlContainer; - color: "red" - anchors.right: parent.right; + anchors.rightMargin: UM.Theme.getSize("default_margin").width anchors.verticalCenter: parent.verticalCenter; width: UM.Theme.getSize("setting_control").width; - height: UM.Theme.getSize("setting_contorl").height + height: UM.Theme.getSize("setting_control").height } } From 2b479e5651680a8cadab1b5c837f9e046fc291bb Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 May 2016 17:07:42 +0200 Subject: [PATCH 056/705] Add a hovered property to SettingItem --- resources/qml/Settings/SettingItem.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index f9dac0b879..5e31e0c264 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -15,7 +15,8 @@ Item { height: UM.Theme.getSize("section").height; - property alias contents: controlContainer.children + property alias contents: controlContainer.children; + property bool hovered: false signal contextMenuRequested() signal showTooltip(string text); From d4b5cd519b7a03ad35040537c506f8c94d225d6c Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 May 2016 17:10:11 +0200 Subject: [PATCH 057/705] Fix SettingCheckbox so it displays correctly --- resources/qml/Settings/SettingCheckBox.qml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/resources/qml/Settings/SettingCheckBox.qml b/resources/qml/Settings/SettingCheckBox.qml index 37cad7fd4b..0acacb95fb 100644 --- a/resources/qml/Settings/SettingCheckBox.qml +++ b/resources/qml/Settings/SettingCheckBox.qml @@ -12,9 +12,10 @@ SettingItem { id: base - MouseArea + contents: MouseArea { id: control + anchors.fill: parent property bool checked: { @@ -48,7 +49,7 @@ SettingItem { return UM.Theme.getColor("setting_control_disabled") } - if(base.containsMouse || base.activeFocus) + if(control.containsMouse || control.activeFocus) { return UM.Theme.getColor("setting_control_highlight") } From d1d2dc04c5bb16a4ab5a4e7ede5478100062e9ed Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 May 2016 17:13:36 +0200 Subject: [PATCH 058/705] Display the correct tooltips for reset and inherits buttons --- resources/qml/Settings/SettingItem.qml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index 5e31e0c264..d11b0b300a 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -107,7 +107,7 @@ Item { controlContainer.notifyReset(); } - onEntered: base.showResetTooltip({ x: mouse.mouseX, y: mouse.mouseY }) + onEntered: base.showTooltip(catalog.i18nc("@label", "This setting has a value that is different from the profile.\n\nClick to restore the value of the profile.")) onExited: { if(controlContainer.item && controlContainer.item.hovered) @@ -141,7 +141,7 @@ Item { iconSource: UM.Theme.getIcon("notice"); - onEntered: base.showInheritanceTooltip({ x: mouse.mouseX, y: mouse.mouseY }) + onEntered: base.showTooltip(catalog.i18nc("@label", "This setting is normally calculated, but it currently has an absolute value set.\n\nClick to restore the calculated value.")) onExited: { if(controlContainer.item && controlContainer.item.hovered) { @@ -165,4 +165,6 @@ Item { width: UM.Theme.getSize("setting_control").width; height: UM.Theme.getSize("setting_control").height } + + UM.I18nCatalog { id: catalog; name: "cura" } } From 3514d4839d287bd4876c4f4b99b3aec8e289c9de Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 May 2016 17:15:04 +0200 Subject: [PATCH 059/705] Fix combo box setting item so it displays the right things --- resources/qml/Settings/SettingComboBox.qml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/qml/Settings/SettingComboBox.qml b/resources/qml/Settings/SettingComboBox.qml index 6fd4c5621c..0f332b2aee 100644 --- a/resources/qml/Settings/SettingComboBox.qml +++ b/resources/qml/Settings/SettingComboBox.qml @@ -11,12 +11,12 @@ SettingItem { id: base - ComboBox + contents: ComboBox { -// signal valueChanged(string value); -// id: base model: definition.options - textRole: "name"; + textRole: "value"; + + anchors.fill: parent MouseArea { From ac9b391e7fd1c6d868dc4fa0ddb7478fe00e3974 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 11 May 2016 17:20:09 +0200 Subject: [PATCH 060/705] Fixed available printers in dropdown menu CURA-1278 --- resources/qml/Cura.qml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index e39cd733d9..753f856163 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -7,7 +7,8 @@ import QtQuick.Controls.Styles 1.1 import QtQuick.Layouts 1.1 import QtQuick.Dialogs 1.1 -import UM 1.1 as UM +import UM 1.2 as UM +import Cura 1.0 as Cura UM.MainWindow { @@ -168,14 +169,17 @@ UM.MainWindow Instantiator { -// model: UM.MachineInstancesModel { } + model: UM.ContainerStacksModel + { + filter: {"type": "machine"} + } MenuItem { text: model.name; checkable: true; - checked: model.active; - exclusiveGroup: machineMenuGroup; - onTriggered: UM.MachineManager.setActiveMachineInstance(model.name) + checked: Cura.MachineManager.activeMachineId == model.id + exclusiveGroup: machineSelectionMenuGroup; + onTriggered: Cura.MachineManager.setActiveMachine(model.id); } onObjectAdded: machineMenu.insertItem(index, object) onObjectRemoved: machineMenu.removeItem(object) From 5a7486a32e4463aa22831f8139d4228701f38ccf Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 11 May 2016 17:27:14 +0200 Subject: [PATCH 061/705] Add conversion of First Layer Airgap from legacy First Layer Airgap's internal name is raft_airgap (yeah don't ask). Contributes to issue CURA-1549. --- plugins/LegacyProfileReader/DictionaryOfDoom.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/LegacyProfileReader/DictionaryOfDoom.json b/plugins/LegacyProfileReader/DictionaryOfDoom.json index e30460f103..1fe7d7b7a5 100644 --- a/plugins/LegacyProfileReader/DictionaryOfDoom.json +++ b/plugins/LegacyProfileReader/DictionaryOfDoom.json @@ -50,7 +50,8 @@ "skirt_minimal_length": "skirt_minimal_length", "brim_line_count": "brim_line_count", "raft_margin": "raft_margin", - "raft_airgap": "raft_airgap_all", + "raft_airgap": "raft_airgap_all - raft_airgap", + "layer_0_z_overlap": "raft_airgap", "raft_surface_layers": "raft_surface_layers", "raft_surface_thickness": "raft_surface_thickness", "raft_surface_line_width": "raft_surface_linewidth", From 9f2e87fdcb357394fde5072cc620f35a96bab61c Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 11 May 2016 17:44:58 +0200 Subject: [PATCH 062/705] Force updating the convex hull of a group node if one of its children is removed Before this fix, if a subselection of a group was deleted from the group, the convex hull would not update. CURA-1054 --- cura/ConvexHullDecorator.py | 43 +++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/cura/ConvexHullDecorator.py b/cura/ConvexHullDecorator.py index b53737cc80..381b5b2b69 100644 --- a/cura/ConvexHullDecorator.py +++ b/cura/ConvexHullDecorator.py @@ -8,11 +8,11 @@ class ConvexHullDecorator(SceneNodeDecorator): def __init__(self): super().__init__() self._convex_hull = None - + # In case of printing all at once this is the same as the convex hull. # For one at the time this is the area without the head. self._convex_hull_boundary = None - + # In case of printing all at once this is the same as the convex hull. # For one at the time this is area with intersection of mirrored head self._convex_hull_head = None @@ -20,15 +20,23 @@ class ConvexHullDecorator(SceneNodeDecorator): # In case of printing all at once this is the same as the convex hull. # For one at the time this is area with intersection of full head self._convex_hull_head_full = None - + self._convex_hull_node = None self._convex_hull_job = None + # Keep track of the previous parent so we can clear its convex hull when the object is reparented + self._parent_node = None + self._profile = None Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onActiveProfileChanged) Application.getInstance().getMachineManager().activeMachineInstanceChanged.connect(self._onActiveMachineInstanceChanged) self._onActiveProfileChanged() + def setNode(self, node): + super().setNode(node) + self._parent_node = node.getParent() + node.parentChanged.connect(self._onParentChanged) + ## Force that a new (empty) object is created upon copy. def __deepcopy__(self, memo): copy = ConvexHullDecorator() @@ -59,7 +67,7 @@ class ConvexHullDecorator(SceneNodeDecorator): if not self._convex_hull_boundary: return self.getConvexHull() return self._convex_hull_boundary - + def setConvexHullBoundary(self, hull): self._convex_hull_boundary = hull @@ -68,22 +76,25 @@ class ConvexHullDecorator(SceneNodeDecorator): def setConvexHullHead(self, hull): self._convex_hull_head = hull - + def setConvexHull(self, hull): self._convex_hull = hull - + if not hull and self._convex_hull_node: + self._convex_hull_node.setParent(None) + self._convex_hull_node = None + def getConvexHullJob(self): return self._convex_hull_job - + def setConvexHullJob(self, job): self._convex_hull_job = job - + def getConvexHullNode(self): return self._convex_hull_node - + def setConvexHullNode(self, node): self._convex_hull_node = node - + def _onActiveProfileChanged(self): if self._profile: self._profile.settingValueChanged.disconnect(self._onSettingValueChanged) @@ -97,15 +108,15 @@ class ConvexHullDecorator(SceneNodeDecorator): if self._convex_hull_job: self._convex_hull_job.cancel() self.setConvexHull(None) - if self._convex_hull_node: - self._convex_hull_node.setParent(None) - self._convex_hull_node = None def _onSettingValueChanged(self, setting): if setting == "print_sequence": if self._convex_hull_job: self._convex_hull_job.cancel() self.setConvexHull(None) - if self._convex_hull_node: - self._convex_hull_node.setParent(None) - self._convex_hull_node = None + + def _onParentChanged(self, node): + # Force updating the convex hull of the parent group if the object is in a group + if self._parent_node and self._parent_node.callDecoration("isGroup"): + self._parent_node.callDecoration("setConvexHull", None) + self._parent_node = self.getNode().getParent() From 7c154c78bf8eb1c43aa7837ac8cd3e5b84ab6547 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 11 May 2016 17:58:10 +0200 Subject: [PATCH 063/705] Add keyboard shortcuts for grouping/ungrouping Contributes (in a way) to CURA-1054, \sa CURA-1531 --- resources/qml/Actions.qml | 5 ++++- resources/qml/Cura.qml | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index 003a3ceeec..33754c71ab 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -176,6 +176,7 @@ Item text: catalog.i18nc("@action:inmenu menubar:edit","&Group Objects"); enabled: UM.Scene.numObjectsSelected > 1 ? true: false iconName: "object-group" + shortcut: "Ctrl+G"; } Action @@ -184,14 +185,16 @@ Item text: catalog.i18nc("@action:inmenu menubar:edit","Ungroup Objects"); enabled: UM.Scene.isGroupSelected iconName: "object-ungroup" + shortcut: "Ctrl+Shift+G"; } - + Action { id: mergeObjectsAction text: catalog.i18nc("@action:inmenu menubar:edit","&Merge Objects"); enabled: UM.Scene.numObjectsSelected > 1 ? true: false iconName: "merge"; + shortcut: "Ctrl+Alt+G"; } Action diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 1759eabfc6..ccaeb63c4e 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -680,6 +680,7 @@ UM.MainWindow MenuItem { action: actions.reloadAll; } MenuItem { action: actions.resetAllTranslation; } MenuItem { action: actions.resetAll; } + MenuSeparator { } MenuItem { action: actions.groupObjects; } MenuItem { action: actions.mergeObjects; } MenuItem { action: actions.unGroupObjects; } @@ -692,6 +693,7 @@ UM.MainWindow MenuItem { action: actions.reloadAll; } MenuItem { action: actions.resetAllTranslation; } MenuItem { action: actions.resetAll; } + MenuSeparator { } MenuItem { action: actions.groupObjects; } MenuItem { action: actions.mergeObjects; } MenuItem { action: actions.unGroupObjects; } From c79d064107008c1b79e83981001bbe94733f6130 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 11 May 2016 18:26:18 +0200 Subject: [PATCH 064/705] Convert raft_airgap settings to float before computing Can't subtract strings from each other, after all. Contributes to issue CURA-1549. --- plugins/LegacyProfileReader/DictionaryOfDoom.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/LegacyProfileReader/DictionaryOfDoom.json b/plugins/LegacyProfileReader/DictionaryOfDoom.json index 1fe7d7b7a5..8c4b49074b 100644 --- a/plugins/LegacyProfileReader/DictionaryOfDoom.json +++ b/plugins/LegacyProfileReader/DictionaryOfDoom.json @@ -50,7 +50,7 @@ "skirt_minimal_length": "skirt_minimal_length", "brim_line_count": "brim_line_count", "raft_margin": "raft_margin", - "raft_airgap": "raft_airgap_all - raft_airgap", + "raft_airgap": "float(raft_airgap_all) - float(raft_airgap)", "layer_0_z_overlap": "raft_airgap", "raft_surface_layers": "raft_surface_layers", "raft_surface_thickness": "raft_surface_thickness", From 76f78295c4ecbfc278e3a367ab202dfa348cd744 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 12 May 2016 10:28:18 +0200 Subject: [PATCH 065/705] Translation correction suggested by BagelOrb BagelOrb indicated the translation wrongly at first. This is apparently correct. Contributes to issue CURA-1549. --- plugins/LegacyProfileReader/DictionaryOfDoom.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/LegacyProfileReader/DictionaryOfDoom.json b/plugins/LegacyProfileReader/DictionaryOfDoom.json index 8c4b49074b..9dd0c04a05 100644 --- a/plugins/LegacyProfileReader/DictionaryOfDoom.json +++ b/plugins/LegacyProfileReader/DictionaryOfDoom.json @@ -50,7 +50,7 @@ "skirt_minimal_length": "skirt_minimal_length", "brim_line_count": "brim_line_count", "raft_margin": "raft_margin", - "raft_airgap": "float(raft_airgap_all) - float(raft_airgap)", + "raft_airgap": "float(raft_airgap_all) + float(raft_airgap)", "layer_0_z_overlap": "raft_airgap", "raft_surface_layers": "raft_surface_layers", "raft_surface_thickness": "raft_surface_thickness", From 5716069fe47e7a39fae12081d62a88ce54a23732 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 12 May 2016 11:01:46 +0200 Subject: [PATCH 066/705] JSON fix: First Layer Z OVerlap ==> Inital Layer ... (CURA-1549) --- resources/machines/fdmprinter.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/machines/fdmprinter.json b/resources/machines/fdmprinter.json index 9bb53c89a2..44a1ef5291 100644 --- a/resources/machines/fdmprinter.json +++ b/resources/machines/fdmprinter.json @@ -1493,7 +1493,7 @@ "visible": true }, "layer_0_z_overlap": { - "label": "First Layer Z Overlap", + "label": "Initial Layer Z Overlap", "description": "Make the first and second layer of the object 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", "type": "float", From 9b1867cdaf2e0a2bf49b818968291c8f41a28977 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 12 May 2016 11:23:05 +0200 Subject: [PATCH 067/705] Hide output device selection when there is only one option CURA-1539 --- resources/qml/SaveButton.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/qml/SaveButton.qml b/resources/qml/SaveButton.qml index acdb43d67b..64bdcdf540 100644 --- a/resources/qml/SaveButton.qml +++ b/resources/qml/SaveButton.qml @@ -80,8 +80,8 @@ Rectangle { height: UM.Theme.getSize("save_button_save_to_button").height anchors.top: parent.top - anchors.right: deviceSelectionMenu.left; - anchors.rightMargin: -3 * UM.Theme.getSize("default_lining").width; + anchors.right: deviceSelectionMenu.visible ? deviceSelectionMenu.left : parent.right + anchors.rightMargin: deviceSelectionMenu.visible ? -3 * UM.Theme.getSize("default_lining").width : UM.Theme.getSize("default_margin").width text: UM.OutputDeviceManager.activeDeviceShortDescription onClicked: @@ -128,8 +128,8 @@ Rectangle { width: UM.Theme.getSize("save_button_save_to_button").height height: UM.Theme.getSize("save_button_save_to_button").height enabled: base.backendState == 2 && base.activity == true + visible: devicesModel.deviceCount > 1 - //iconSource: UM.Theme.icons[UM.OutputDeviceManager.activeDeviceIconName]; style: ButtonStyle { background: Rectangle { From d8e4aa90788c5ada739b17d8f06d7da392b7e162 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 12 May 2016 11:24:09 +0200 Subject: [PATCH 068/705] Moved machinePage to Cura CURA-1278 --- cura/MachineManagerModel.py | 5 +++ resources/qml/Cura.qml | 2 + resources/qml/MachinesPage.qml | 68 ++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 resources/qml/MachinesPage.qml diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index c5f2fc3fa6..ec346710af 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -27,6 +27,11 @@ class MachineManagerModel(QObject): def activeMachineId(self): return Application.getInstance().getGlobalContainerStack().getId() + @pyqtSlot(str, str) + def renameMachine(self, machine_id, new_name): + containers = ContainerRegistry.getInstance().findContainerStacks(id = machine_id) + if containers: + containers[0].setName(new_name) def createMachineManagerModel(engine, script_engine): diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 134d06c9d7..4314dc21e6 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -542,6 +542,8 @@ UM.MainWindow //: View preferences page title insertPage(1, catalog.i18nc("@title:tab","View"), Qt.resolvedUrl("ViewPage.qml")); + insertPage(2, catalog.i18nc("@title:tab", "Printers"), Qt.resolvedUrl("MachinesPage.qml")); + //Force refresh setPage(0); } diff --git a/resources/qml/MachinesPage.qml b/resources/qml/MachinesPage.qml new file mode 100644 index 0000000000..58a0878019 --- /dev/null +++ b/resources/qml/MachinesPage.qml @@ -0,0 +1,68 @@ +// Copyright (c) 2016 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Controls 1.1 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +UM.ManagementPage +{ + id: base; + + title: catalog.i18nc("@title:tab", "Printers"); + property int numInstances: model.rowCount(); + model: UM.ContainerStacksModel + { + filter: {"type": "machine"} + onDataChanged: numInstances = model.rowCount() + } + + onAddObject: model.requestAddMachine(); + onRemoveObject: confirmDialog.open(); + onRenameObject: renameDialog.open(); + + removeEnabled: numInstances > 1 + renameEnabled: numInstances > 0 + + Flow + { + anchors.fill: parent; + spacing: UM.Theme.getSize("default_margin").height; + + Label + { + text: base.currentItem && base.currentItem.name ? base.currentItem.name : "" + font: UM.Theme.getFont("large") + width: parent.width + elide: Text.ElideRight + } + + Label { text: catalog.i18nc("@label", "Type"); width: parent.width * 0.2; } + Label { text: base.currentItem && base.currentItem.typeName ? base.currentItem.typeName : ""; width: parent.width * 0.7; } + + UM.I18nCatalog { id: catalog; name: "uranium"; } + + UM.ConfirmRemoveDialog + { + id: confirmDialog; + object: base.currentItem && base.currentItem.name ? base.currentItem.name : ""; + onYes: base.model.removeMachineInstance(base.currentItem.name); + } + + UM.RenameDialog + { + id: renameDialog; + object: base.currentItem && base.currentItem.name ? base.currentItem.name : ""; + onAccepted: + { + Cura.MachineManager.renameMachine(base.currentItem.id, newName.trim()); + //Reselect current item to update details panel + var index = objectList.currentIndex + objectList.currentIndex = -1 + objectList.currentIndex = index + } + } + } +} From 78e9545ecea2cbf837402e69221d8a16110fd244 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 12 May 2016 11:46:28 +0200 Subject: [PATCH 069/705] Machines can now be removed CURA-1278 --- cura/MachineManagerModel.py | 5 +++++ resources/qml/MachinesPage.qml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index ec346710af..2df28c1f92 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -33,6 +33,11 @@ class MachineManagerModel(QObject): if containers: containers[0].setName(new_name) + @pyqtSlot(str) + def removeMachine(self, machine_id): + ContainerRegistry.getInstance().removeContainer(machine_id) + + def createMachineManagerModel(engine, script_engine): return MachineManagerModel() \ No newline at end of file diff --git a/resources/qml/MachinesPage.qml b/resources/qml/MachinesPage.qml index 58a0878019..88cfbc740e 100644 --- a/resources/qml/MachinesPage.qml +++ b/resources/qml/MachinesPage.qml @@ -48,7 +48,7 @@ UM.ManagementPage { id: confirmDialog; object: base.currentItem && base.currentItem.name ? base.currentItem.name : ""; - onYes: base.model.removeMachineInstance(base.currentItem.name); + onYes: Cura.MachineManager.removeMachine(base.currentItem.id); } UM.RenameDialog From 65022c3d1806d5a78b31b0580142c42b33038a5d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 12 May 2016 11:53:01 +0200 Subject: [PATCH 070/705] Fixed adding machine in printer dialog CURA-1278 --- resources/qml/MachinesPage.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/MachinesPage.qml b/resources/qml/MachinesPage.qml index 88cfbc740e..14425acc05 100644 --- a/resources/qml/MachinesPage.qml +++ b/resources/qml/MachinesPage.qml @@ -19,7 +19,7 @@ UM.ManagementPage onDataChanged: numInstances = model.rowCount() } - onAddObject: model.requestAddMachine(); + onAddObject: Printer.requestAddPrinter() onRemoveObject: confirmDialog.open(); onRenameObject: renameDialog.open(); From a16acddff1da61fe2bd7759cb3ce9e0ab36c6d61 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 12 May 2016 11:59:23 +0200 Subject: [PATCH 071/705] Removed unused code CURA-1278 --- cura/CuraApplication.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 17450029a3..8c6681de8c 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -638,6 +638,3 @@ class CuraApplication(QtApplication): job = ReadMeshJob(os.path.abspath(file)) job.finished.connect(self._onFileLoaded) job.start() - - def _onAddMachineRequested(self): - self.requestAddPrinter.emit() From 34b257d0f4b447cccd69fc00b786f1db96b9f327 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 12 May 2016 13:41:39 +0200 Subject: [PATCH 072/705] Add translations for Initial Layer Z Overlap setting English is a copy of the original. Dutch, French, Spanish and German translations were made by a native speaker. Italian by a non-native speaker. Finnish is machine-translated. Contributes to issue CURA-1549. --- resources/i18n/de/fdmprinter.json.po | 13 +++++++++++++ resources/i18n/en/fdmprinter.json.po | 13 +++++++++++++ resources/i18n/es/fdmprinter.json.po | 13 +++++++++++++ resources/i18n/fdmprinter.json.pot | 13 +++++++++++++ resources/i18n/fi/fdmprinter.json.po | 13 +++++++++++++ resources/i18n/fr/fdmprinter.json.po | 13 +++++++++++++ resources/i18n/it/fdmprinter.json.po | 15 +++++++++++++++ resources/i18n/nl/fdmprinter.json.po | 13 +++++++++++++ 8 files changed, 106 insertions(+) diff --git a/resources/i18n/de/fdmprinter.json.po b/resources/i18n/de/fdmprinter.json.po index 9ba0fdca1f..e9a04a21ff 100644 --- a/resources/i18n/de/fdmprinter.json.po +++ b/resources/i18n/de/fdmprinter.json.po @@ -2414,3 +2414,16 @@ msgid "" "which in turn results in less upward connections with the next layer. Only " "applies to Wire Printing." msgstr "Der Abstand zwischen der Düse und den horizontalen Abwärtslinien. Bei einem größeren Abstand haben die diagonalen Abwärtslinien einen weniger spitzen Winkel, was wiederum weniger Aufwärtsverbindungen zur nächsten Schicht zur Folge hat. Dies gilt nur für das Drucken mit Drahtstruktur." + +#: fdmprinter.json +msgctxt "layer_0_z_overlap label" +msgid "Initial Layer Z Overlap" +msgstr "Z Überlappung der ersten Schicht" + +#: fdmprinter.json +msgctxt "layer_0_z_overlap description" +msgid "" +"Make the first and second layer of the object overlap in the Z direction to " +"compensate for the filament lost in the airgap. All model pieces above the first " +"model layer will be shifted down by this amount." +msgstr "Die erste und die zweite Schicht des Objekts überlappen sich in der Z-Richtung, um das verlorene Filament in dem Luftspalt zu kompensieren. Alle Schichten über der ersten Schicht, verschieben sich in der Z-Richtung mit gewähltem Abstand nach unten." diff --git a/resources/i18n/en/fdmprinter.json.po b/resources/i18n/en/fdmprinter.json.po index 9ee03631bb..4578306bfb 100644 --- a/resources/i18n/en/fdmprinter.json.po +++ b/resources/i18n/en/fdmprinter.json.po @@ -2483,3 +2483,16 @@ msgid "" "which in turn results in less upward connections with the next layer. Only " "applies to Wire Printing." msgstr "Distance between the nozzle and horizontally downward lines. Larger clearance results in diagonally downward lines with a less steep angle, which in turn results in fewer upward connections with the next layer. Only applies to Wire Printing." + +#: fdmprinter.json +msgctxt "layer_0_z_overlap label" +msgid "Initial Layer Z Overlap" +msgstr "Initial Layer Z Overlap" + +#: fdmprinter.json +msgctxt "layer_0_z_overlap description" +msgid "" +"Make the first and second layer of the object 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." +msgstr "Make the first and second layer of the object 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." diff --git a/resources/i18n/es/fdmprinter.json.po b/resources/i18n/es/fdmprinter.json.po index a3e79fa69a..2c1f044147 100644 --- a/resources/i18n/es/fdmprinter.json.po +++ b/resources/i18n/es/fdmprinter.json.po @@ -2414,3 +2414,16 @@ msgid "" "which in turn results in less upward connections with the next layer. Only " "applies to Wire Printing." msgstr "Distancia entre la tobera y líneas descendentes en horizontal. Cuanto mayor sea la holgura, menos pronunciado será el ángulo de las líneas descendentes en diagonal, lo que a su vez se traduce en menos conexiones ascendentes con la siguiente capa. Solo se aplica a la impresión de alambre." + +#: fdmprinter.json +msgctxt "layer_0_z_overlap label" +msgid "Initial Layer Z Overlap" +msgstr "Superposición de las capas iniciales en Z" + +#: fdmprinter.json +msgctxt "layer_0_z_overlap description" +msgid "" +"Make the first and second layer of the object 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." +msgstr "La superposición entre la primera y segunda capa del objeto para compensar la pérdida de material en el hueco de aire. Todas las capas por encima de la primera capa se desplazan hacia abajo por esta cantidad." diff --git a/resources/i18n/fdmprinter.json.pot b/resources/i18n/fdmprinter.json.pot index b7c6f07b46..b8870ef252 100644 --- a/resources/i18n/fdmprinter.json.pot +++ b/resources/i18n/fdmprinter.json.pot @@ -2414,3 +2414,16 @@ msgid "" "which in turn results in less upward connections with the next layer. Only " "applies to Wire Printing." msgstr "" + +#: fdmprinter.json +msgctxt "layer_0_z_overlap label" +msgid "Initial Layer Z Overlap" +msgstr "" + +#: fdmprinter.json +msgctxt "layer_0_z_overlap description" +msgid "" +"Make the first and second layer of the object 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." +msgstr "" diff --git a/resources/i18n/fi/fdmprinter.json.po b/resources/i18n/fi/fdmprinter.json.po index ad12060cea..cc402b0e54 100644 --- a/resources/i18n/fi/fdmprinter.json.po +++ b/resources/i18n/fi/fdmprinter.json.po @@ -2414,3 +2414,16 @@ msgid "" "which in turn results in less upward connections with the next layer. Only " "applies to Wire Printing." msgstr "Suuttimen ja vaakasuoraan laskevien linjojen välinen etäisyys. Suurempi väli aiheuttaa vähemmän jyrkän kulman diagonaalisesti laskeviin linjoihin, mikä puolestaan johtaa harvempiin yläliitoksiin seuraavan kerroksen kanssa. Koskee vain rautalankamallin tulostusta." + +#: fdmprinter.json +msgctxt "layer_0_z_overlap label" +msgid "Initial Layer Z Overlap" +msgstr "Z Päällekkäisyys Alkukerroksen" + +#: fdmprinter.json +msgctxt "layer_0_z_overlap description" +msgid "" +"Make the first and second layer of the object 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." +msgstr "Tee ensimmäinen ja toinen kerros esineen päällekkäisyys Z-suunnassa kompensoimiseksi filamentti hävisi ilmaväli. Kaikki mallit yläpuolella ensimmäinen malli kerros on siirtynyt alaspäin tämän määrän." diff --git a/resources/i18n/fr/fdmprinter.json.po b/resources/i18n/fr/fdmprinter.json.po index 7a49440b04..f8e10fa5f4 100644 --- a/resources/i18n/fr/fdmprinter.json.po +++ b/resources/i18n/fr/fdmprinter.json.po @@ -2414,3 +2414,16 @@ msgid "" "which in turn results in less upward connections with the next layer. Only " "applies to Wire Printing." msgstr "Distance entre la buse et les lignes descendantes horizontalement. Un espacement plus important génère des lignes diagonalement descendantes avec un angle moins abrupt, qui génère alors des connexions moins ascendantes avec la couche suivante. Uniquement applicable à l'impression filaire." + +#: fdmprinter.json +msgctxt "layer_0_z_overlap label" +msgid "Initial Layer Z Overlap" +msgstr "" + +#: fdmprinter.json +msgctxt "layer_0_z_overlap description" +msgid "" +"Make the first and second layer of the object 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." +msgstr "La première et la deuxième couche de l'objet se chevauchent dans la direction Z pour compenser le filament perdu dans l'entrefer. Toutes les chouches au-dessus de la première couce du modèle seront décalées de ce montant." diff --git a/resources/i18n/it/fdmprinter.json.po b/resources/i18n/it/fdmprinter.json.po index b0e04c4308..40b5e36916 100644 --- a/resources/i18n/it/fdmprinter.json.po +++ b/resources/i18n/it/fdmprinter.json.po @@ -2414,3 +2414,18 @@ msgid "" "which in turn results in less upward connections with the next layer. Only " "applies to Wire Printing." msgstr "Indica la distanza tra l'ugello e le linee diagonali verso il basso. Un maggior gioco risulta in linee diagonali verso il basso con un minor angolo di inclinazione, cosa che a sua volta si traduce in meno collegamenti verso l'alto con lo strato successivo. Applicabile solo alla funzione Wire Printing." + +#: fdmprinter.json +#, fuzzy +msgctxt "layer_0_z_overlap label" +msgid "Initial Layer Z Overlap" +msgstr "Z Sovrapposizione Primo Strato" + +#: fdmprinter.json +#, fuzzy +msgctxt "layer_0_z_overlap description" +msgid "" +"Make the first and second layer of the object 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." +msgstr "Effettuare il primo e secondo strato di sovrapposizione oggetto nella direzione Z per compensare il filamento perso nel traferro. Tutti i modelli sopra il primo strato del modello saranno spostate verso il basso di questa quantità." diff --git a/resources/i18n/nl/fdmprinter.json.po b/resources/i18n/nl/fdmprinter.json.po index ff8f896a74..2c6e8a1df8 100644 --- a/resources/i18n/nl/fdmprinter.json.po +++ b/resources/i18n/nl/fdmprinter.json.po @@ -2414,3 +2414,16 @@ msgid "" "which in turn results in less upward connections with the next layer. Only " "applies to Wire Printing." msgstr "De afstand tussen de nozzle en horizontaal neergaande lijnen. Een grotere tussenruimte zorgt voor diagonaal neerwaarts gaande lijnen met een minder steile hoek. Hierdoor ontstaan minder opwaartse verbindingen met de volgende laag. Alleen van toepassing op Draadprinten." + +#: fdmprinter.json +msgctxt "layer_0_z_overlap label" +msgid "Initial Layer Z Overlap" +msgstr "Z Overlap Eerste Laag" + +#: fdmprinter.json +msgctxt "layer_0_z_overlap description" +msgid "" +"Make the first and second layer of the object 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." +msgstr "Laat de eerste en tweede laag overlappen in de Z-richting om te compenseren voor verloren materiaal in de luchtlaag. Alle stukjes model boven de eerste laag worden met deze hoveelheid naar beneden verschoven." From 021bb97fc4b11cb4d85eafb727fa3955e42301f2 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 12 May 2016 14:03:03 +0200 Subject: [PATCH 073/705] Add a preference for automatic update checking CURA-1540 --- resources/qml/GeneralPage.qml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/resources/qml/GeneralPage.qml b/resources/qml/GeneralPage.qml index b2ff44b15a..9138fffc45 100644 --- a/resources/qml/GeneralPage.qml +++ b/resources/qml/GeneralPage.qml @@ -30,8 +30,10 @@ UM.PreferencesPage UM.Preferences.resetPreference("general/language") UM.Preferences.resetPreference("physics/automatic_push_free") UM.Preferences.resetPreference("mesh/scale_to_fit") + UM.Preferences.resetPreference("info/automatic_update_check") UM.Preferences.resetPreference("info/send_slice_info") pushFreeCheckbox.checked = boolCheck(UM.Preferences.getValue("physics/automatic_push_free")) + checkUpdatesCheckbox.checked = boolCheck(UM.Preferences.getValue("info/automatic_update_check")) sendDataCheckbox.checked = boolCheck(UM.Preferences.getValue("info/send_slice_info")) scaleToFitCheckbox.checked = boolCheck(UM.Preferences.getValue("mesh/scale_to_fit")) var defaultLanguage = UM.Preferences.getValue("general/language") @@ -150,6 +152,20 @@ UM.PreferencesPage } } + UM.TooltipArea { + width: childrenRect.width + height: childrenRect.height + text: catalog.i18nc("@info:tooltip","Should Cura check for updates when the program is started?") + + CheckBox + { + id: checkUpdatesCheckbox + text: catalog.i18nc("@option:check","Check for updates on start") + checked: boolCheck(UM.Preferences.getValue("info/automatic_update_check")) + onCheckedChanged: UM.Preferences.setValue("info/automatic_update_check", checked) + } + } + UM.TooltipArea { width: childrenRect.width height: childrenRect.height From 44f5559db3a54bdbf9d7e9bd01e8a5dacd7e3674 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 12 May 2016 15:18:13 +0200 Subject: [PATCH 074/705] Moved addMachine to machineManager CURA-1278 --- cura/MachineManagerModel.py | 12 ++++++++++++ resources/qml/AddMachineDialog.qml | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 2df28c1f92..da14864118 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -2,6 +2,7 @@ from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal from UM.Application import Application from UM.Settings.ContainerRegistry import ContainerRegistry +from UM.Settings.ContainerStack import ContainerStack class MachineManagerModel(QObject): def __init__(self, parent = None): @@ -19,6 +20,17 @@ class MachineManagerModel(QObject): if containers: Application.getInstance().setGlobalContainerStack(containers[0]) + @pyqtSlot(str, str) + def addMachine(self,name, definition_id): + definitions = ContainerRegistry.getInstance().findDefinitionContainers(id=definition_id) + if definitions: + new_global_stack = ContainerStack(name) + new_global_stack.addMetaDataEntry("type", "machine") + ContainerRegistry.getInstance().addContainer(new_global_stack) + # If a definition is found, its a list. Should only have one item. + new_global_stack.addContainer(definitions[0]) + Application.getInstance().setGlobalContainerStack(new_global_stack) + @pyqtProperty(str, notify = globalContainerChanged) def activeMachineName(self): return Application.getInstance().getGlobalContainerStack().getName() diff --git a/resources/qml/AddMachineDialog.qml b/resources/qml/AddMachineDialog.qml index 476df2178c..4a5e14f183 100644 --- a/resources/qml/AddMachineDialog.qml +++ b/resources/qml/AddMachineDialog.qml @@ -161,7 +161,7 @@ UM.Dialog { base.visible = false var item = machineList.model.getItem(machineList.currentIndex); - machineList.model.setNewGlobalStackFromDefinition(machineName.text, item.id) + Cura.MachineManager.addMachine(machineName.text, item.id) } } From 0de4f466dc1e76420461c3a7afbad21e260d9d11 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 12 May 2016 15:38:59 +0200 Subject: [PATCH 075/705] Codestyle & Documentation --- cura/CuraApplication.py | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index f381faa482..eced8ce42f 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -295,7 +295,9 @@ class CuraApplication(QtApplication): @pyqtSlot(str) def setJobName(self, name): - name = os.path.splitext(name)[0] #when a file is opened using the terminal; the filename comes from _onFileLoaded and still contains its extension. This cuts the extension off if nescessary. + # when a file is opened using the terminal; the filename comes from _onFileLoaded and still contains its + # extension. This cuts the extension off if necessary. + name = os.path.splitext(name)[0] if self._job_name != name: self._job_name = name self.jobNameChanged.emit() @@ -330,7 +332,7 @@ class CuraApplication(QtApplication): node = self.getController().getScene().findObject(object_id) - if not node and object_id != 0: #Workaround for tool handles overlapping the selected object + if not node and object_id != 0: # Workaround for tool handles overlapping the selected object node = Selection.getSelectedObject(0) if node: @@ -349,7 +351,7 @@ class CuraApplication(QtApplication): def multiplyObject(self, object_id, count): node = self.getController().getScene().findObject(object_id) - if not node and object_id != 0: #Workaround for tool handles overlapping the selected object + if not node and object_id != 0: # Workaround for tool handles overlapping the selected object node = Selection.getSelectedObject(0) if node: @@ -371,7 +373,7 @@ class CuraApplication(QtApplication): @pyqtSlot("quint64") def centerObject(self, object_id): node = self.getController().getScene().findObject(object_id) - if not node and object_id != 0: #Workaround for tool handles overlapping the selected object + if not node and object_id != 0: # Workaround for tool handles overlapping the selected object node = Selection.getSelectedObject(0) if not node: @@ -384,7 +386,7 @@ class CuraApplication(QtApplication): op = SetTransformOperation(node, Vector()) op.push() - ## Delete all mesh data on the scene. + ## Delete all nodes containing mesh data in the scene. @pyqtSlot() def deleteAll(self): if not self.getController().getToolsEnabled(): @@ -395,9 +397,9 @@ class CuraApplication(QtApplication): if type(node) is not SceneNode: continue if not node.getMeshData() and not node.callDecoration("isGroup"): - continue #Node that doesnt have a mesh and is not a group. + continue # Node that doesnt have a mesh and is not a group. if node.getParent() and node.getParent().callDecoration("isGroup"): - continue #Grouped nodes don't need resetting as their parent (the group) is resetted) + continue # Grouped nodes don't need resetting as their parent (the group) is resetted) nodes.append(node) if nodes: op = GroupedOperation() @@ -415,9 +417,9 @@ class CuraApplication(QtApplication): if type(node) is not SceneNode: continue if not node.getMeshData() and not node.callDecoration("isGroup"): - continue #Node that doesnt have a mesh and is not a group. + continue # Node that doesnt have a mesh and is not a group. if node.getParent() and node.getParent().callDecoration("isGroup"): - continue #Grouped nodes don't need resetting as their parent (the group) is resetted) + continue # Grouped nodes don't need resetting as their parent (the group) is resetted) nodes.append(node) @@ -437,9 +439,9 @@ class CuraApplication(QtApplication): if type(node) is not SceneNode: continue if not node.getMeshData() and not node.callDecoration("isGroup"): - continue #Node that doesnt have a mesh and is not a group. + continue # Node that doesnt have a mesh and is not a group. if node.getParent() and node.getParent().callDecoration("isGroup"): - continue #Grouped nodes don't need resetting as their parent (the group) is resetted) + continue # Grouped nodes don't need resetting as their parent (the group) is resetted) nodes.append(node) if nodes: @@ -478,7 +480,7 @@ class CuraApplication(QtApplication): ## Get logging data of the backend engine # \returns \type{string} Logging data - @pyqtSlot(result=str) + @pyqtSlot(result = str) def getEngineLog(self): log = "" @@ -513,7 +515,6 @@ class CuraApplication(QtApplication): if not self.getMachineManager().getWorkingProfile(): return None return self.getMachineManager().getWorkingProfile().getSettingValue(key) - #return self.getActiveMachine().getSettingValueByKey(key) ## Change setting by key value pair @pyqtSlot(str, "QVariant") @@ -561,20 +562,20 @@ class CuraApplication(QtApplication): op.addOperation(SetParentOperation(node, group_node)) op.push() - # Deselect individual nodes and select the groupnode instead + # Deselect individual nodes and select the group-node instead for node in group_node.getChildren(): Selection.remove(node) Selection.add(group_node) @pyqtSlot() def ungroupSelected(self): - selected_objects = Selection.getAllSelectedObjects()[:] #clone the list + selected_objects = Selection.getAllSelectedObjects()[:] # clone the list for node in selected_objects: if node.callDecoration("isGroup"): op = GroupedOperation() group_parent = node.getParent() - children = node.getChildren()[:] #clone the list + children = node.getChildren()[:] # clone the list for child in children: # Set the parent of the children to the parent of the group-node op.addOperation(SetParentOperation(child, group_parent)) @@ -584,7 +585,8 @@ class CuraApplication(QtApplication): child.callDecoration("setConvexHull", None) op.push() - # Note: The group removes itself from the scene once all its children have left it, see GroupDecorator._onChildrenChanged + # Note: The group removes itself from the scene once all its children have left it, + # see GroupDecorator._onChildrenChanged def _createSplashScreen(self): return CuraSplashScreen.CuraSplashScreen() @@ -601,7 +603,7 @@ class CuraApplication(QtApplication): op = AddSceneNodeOperation(node, self.getController().getScene().getRoot()) op.push() - self.getController().getScene().sceneChanged.emit(node) #Force scene change. + self.getController().getScene().sceneChanged.emit(node) #F orce scene change. def _onJobFinished(self, job): if type(job) is not ReadMeshJob or not job.getResult(): @@ -625,9 +627,6 @@ class CuraApplication(QtApplication): def _reloadMeshFinished(self, job): # TODO; This needs to be fixed properly. We now make the assumption that we only load a single mesh! job._node.setMeshData(job.getResult().getMeshData()) - #job.getResult().setParent(self.getController().getScene().getRoot()) - #job._node.setParent(self.getController().getScene().getRoot()) - #job._node.meshDataChanged.emit(job._node) def _openFile(self, file): job = ReadMeshJob(os.path.abspath(file)) From 5f0c96d4a56f1cdb1160ac1e1886737525485353 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Thu, 12 May 2016 16:54:34 +0200 Subject: [PATCH 076/705] Correctly filter the input to the convex hull function for duplicates. Contributes to CURA-1512 --- cura/ConvexHullJob.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/cura/ConvexHullJob.py b/cura/ConvexHullJob.py index 2a943253fb..92fcc66ecd 100644 --- a/cura/ConvexHullJob.py +++ b/cura/ConvexHullJob.py @@ -45,10 +45,19 @@ class ConvexHullJob(Job): # This is done to greatly speed up further convex hull calculations as the convex hull # becomes much less complex when dealing with highly detailed models. vertex_data = numpy.round(vertex_data, 1) - duplicates = (vertex_data[:,0] == vertex_data[:,1]) | (vertex_data[:,1] == vertex_data[:,2]) | (vertex_data[:,0] == vertex_data[:,2]) - vertex_data = numpy.delete(vertex_data, numpy.where(duplicates), axis = 0) - hull = Polygon(vertex_data[:, [0, 2]]) + vertex_data = vertex_data[:, [0, 2]] # Drop the Y components to project to 2D. + + # Grab the set of unique points. + # + # This basically finds the unique rows in the array by treating them as opaque groups of bytes + # which are as long as the 2 float64s in each row, and giving this view to numpy.unique() to munch. + # See http://stackoverflow.com/questions/16970982/find-unique-rows-in-numpy-array + tmp = numpy.ascontiguousarray(vertex_data).view(numpy.dtype((numpy.void, vertex_data.dtype.itemsize * vertex_data.shape[1]))) + _, idx = numpy.unique(tmp, return_index=True) + vertex_data = vertex_data[idx] # Select the unique rows by index. + + hull = Polygon(vertex_data) # First, calculate the normal convex hull around the points hull = hull.getConvexHull() From 89c0644e4be66dcab9853321b17fb8710c0b64ec Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 12 May 2016 17:01:47 +0200 Subject: [PATCH 077/705] Added activeMaterial property CURA-1278 --- cura/MachineManagerModel.py | 22 ++++++++++++++++++++++ resources/qml/SidebarHeader.qml | 9 +++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index da14864118..aef7d37af9 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -3,13 +3,18 @@ from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal from UM.Application import Application from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.ContainerStack import ContainerStack +from UM.Settings.InstanceContainer import InstanceContainer class MachineManagerModel(QObject): def __init__(self, parent = None): super().__init__(parent) Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged) + ## When the global container is changed, active material probably needs to be updated. + self.globalContainerChanged.connect(self.activeMaterialChanged) + globalContainerChanged = pyqtSignal() + activeMaterialChanged = pyqtSignal() def _onGlobalContainerChanged(self): self.globalContainerChanged.emit() @@ -27,8 +32,19 @@ class MachineManagerModel(QObject): new_global_stack = ContainerStack(name) new_global_stack.addMetaDataEntry("type", "machine") ContainerRegistry.getInstance().addContainer(new_global_stack) + + variant_instance_container = InstanceContainer(name + "_variant") + material_instance_container = InstanceContainer("test_material") + material_instance_container.addMetaDataEntry("type", "material") + material_instance_container.setDefinition(definitions[0]) + #material_instance_container.setMetaData({"type","material"}) + quality_instance_container = InstanceContainer(name + "_quality") + current_settings_instance_container = InstanceContainer(name + "_current_settings") + ContainerRegistry.getInstance().addContainer(material_instance_container) + # If a definition is found, its a list. Should only have one item. new_global_stack.addContainer(definitions[0]) + new_global_stack.addContainer(material_instance_container) Application.getInstance().setGlobalContainerStack(new_global_stack) @pyqtProperty(str, notify = globalContainerChanged) @@ -39,6 +55,12 @@ class MachineManagerModel(QObject): def activeMachineId(self): return Application.getInstance().getGlobalContainerStack().getId() + @pyqtProperty(str, notify = activeMaterialChanged) + def activeMaterialName(self): + material = Application.getInstance().getGlobalContainerStack().findContainer({"type":"material"}) + if material: + return material.getName() + @pyqtSlot(str, str) def renameMachine(self, machine_id, new_name): containers = ContainerRegistry.getInstance().findContainerStacks(id = machine_id) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 83188007cf..6b1c4166b7 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -172,8 +172,8 @@ Item ToolButton { id: materialSelection - text: UM.MachineManager.activeMaterial - tooltip: UM.MachineManager.activeMaterial + text: Cura.MachineManager.activeMaterialName + tooltip: Cura.MachineManager.activeMaterialName visible: UM.MachineManager.hasMaterials height: UM.Theme.getSize("setting_control").height @@ -187,6 +187,11 @@ Item Instantiator { id: materialSelectionInstantiator + model: UM.InstanceContainersModel + { + filter: {"type": "material"} + } + //model: UM.InstancesModel {filter: {"type":"material"}} // model: UM.MachineMaterialsModel { id: machineMaterialsModel } MenuItem { From f5e63f2e718762e083b7d9fe5efce7731d904c30 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 12 May 2016 17:38:43 +0200 Subject: [PATCH 078/705] Changing the material is now possible CURA-1278 --- cura/MachineManagerModel.py | 13 +++++++++++++ resources/qml/SidebarHeader.qml | 8 ++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index aef7d37af9..49c2288a98 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -17,8 +17,14 @@ class MachineManagerModel(QObject): activeMaterialChanged = pyqtSignal() def _onGlobalContainerChanged(self): + Application.getInstance().getGlobalContainerStack().containersChanged.connect(self._onInstanceContainersChanged) self.globalContainerChanged.emit() + def _onInstanceContainersChanged(self, container): + container_type = container.getMetaDataEntry("type") + if container_type == "material": + self.activeMaterialChanged.emit() + @pyqtSlot(str) def setActiveMachine(self, stack_id): containers = ContainerRegistry.getInstance().findContainerStacks(id = stack_id) @@ -61,6 +67,13 @@ class MachineManagerModel(QObject): if material: return material.getName() + @pyqtSlot(str) + def setActiveMaterial(self, material_id): + containers = ContainerRegistry.getInstance().findInstanceContainers(id=material_id) + old_material = Application.getInstance().getGlobalContainerStack().findContainer({"type":"material"}) + material_index = Application.getInstance().getGlobalContainerStack().getContainerIndex(old_material) + Application.getInstance().getGlobalContainerStack().replaceContainer(material_index, containers[0]) + @pyqtSlot(str, str) def renameMachine(self, machine_id, new_name): containers = ContainerRegistry.getInstance().findContainerStacks(id = machine_id) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 6b1c4166b7..7feeb32d43 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -201,14 +201,14 @@ Item exclusiveGroup: materialSelectionMenuGroup; onTriggered: { - UM.MachineManager.setActiveMaterial(machineMaterialsModel.getItem(index).name); - if (typeof(model) !== "undefined" && !model.active) { + Cura.MachineManager.setActiveMaterial(model.id); + /*if (typeof(model) !== "undefined" && !model.active) { //Selecting a material was canceled; undo menu selection materialSelectionInstantiator.model.setProperty(index, "active", false); - var activeMaterialName = UM.MachineManager.activeMaterial; + var activeMaterialName = Cura.MachineManager.activeMaterialName var activeMaterialIndex = materialSelectionInstantiator.model.find("name", activeMaterialName); materialSelectionInstantiator.model.setProperty(activeMaterialIndex, "active", true); - } + }*/ } } onObjectAdded: materialSelectionMenu.insertItem(index, object) From 8a4fdf8fb345c1ab90d7b6add7293fbce795f62b Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 12 May 2016 17:50:02 +0200 Subject: [PATCH 079/705] JSON remove: removed Remove Overlapping Wall Parts (CURA-996) --- resources/machines/fdmprinter.json | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/resources/machines/fdmprinter.json b/resources/machines/fdmprinter.json index c4c2253812..6527de04d8 100644 --- a/resources/machines/fdmprinter.json +++ b/resources/machines/fdmprinter.json @@ -452,33 +452,6 @@ "visible": false, "inherit": false }, - "remove_overlapping_walls_enabled": { - "label": "Remove Overlapping Wall Parts", - "description": "Remove parts of a wall which share an overlap which would result in overextrusion in some places. These overlaps occur in thin parts and sharp corners in models.", - "type": "boolean", - "default": false, - "visible": false, - "enabled": "False", - "children": { - "remove_overlapping_walls_0_enabled": { - "label": "Remove Overlapping Outer Wall Parts", - "description": "Remove parts of an outer wall which share an overlap which would result in overextrusion in some places. These overlaps occur in thin pieces in a model and sharp corners.", - "type": "boolean", - "default": false, - "visible": false, - "inherit": true, - "enabled": "False" - }, - "remove_overlapping_walls_x_enabled": { - "label": "Remove Overlapping Inner Wall Parts", - "description": "Remove parts of an inner wall that would otherwise overlap and cause over-extrusion. These overlaps occur in thin pieces in a model and sharp corners.", - "type": "boolean", - "default": true, - "visible": false, - "inherit": false - } - } - }, "fill_perimeter_gaps": { "label": "Fill Gaps Between Walls", "description": "Fills the gaps between walls when overlapping inner wall parts are removed.", From e57ca0aa53def8342cfc18971cafbe4b39caffec Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 12 May 2016 17:51:53 +0200 Subject: [PATCH 080/705] JSON remove: removed Fill Gaps Between Walls (CURA-996) --- resources/machines/fdmprinter.json | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/resources/machines/fdmprinter.json b/resources/machines/fdmprinter.json index 6527de04d8..ba374072bc 100644 --- a/resources/machines/fdmprinter.json +++ b/resources/machines/fdmprinter.json @@ -452,19 +452,6 @@ "visible": false, "inherit": false }, - "fill_perimeter_gaps": { - "label": "Fill Gaps Between Walls", - "description": "Fills the gaps between walls when overlapping inner wall parts are removed.", - "type": "enum", - "options": { - "nowhere": "Nowhere", - "everywhere": "Everywhere", - "skin": "Skin" - }, - "default": "everywhere", - "visible": false, - "enabled": "remove_overlapping_walls_x_enabled" - }, "travel_compensate_overlapping_walls_enabled": { "label": "Compensate Wall Overlaps", "description": "Compensate the flow for parts of a wall being printed where there is already a wall in place.", From 52ea8e76d2fd3f9bd915af3e664e9d00258f0d7a Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 12 May 2016 20:12:43 +0200 Subject: [PATCH 081/705] lil: multiple_mesh_overlap can now be changed per object --- resources/machines/dual_extrusion_printer.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/machines/dual_extrusion_printer.json b/resources/machines/dual_extrusion_printer.json index 05096ffdd0..6506f0c7f8 100644 --- a/resources/machines/dual_extrusion_printer.json +++ b/resources/machines/dual_extrusion_printer.json @@ -204,8 +204,7 @@ "unit": "mm", "default": 0.15, "min_value": "0", - "max_value_warning": "1.0", - "global_only": true + "max_value_warning": "1.0" }, "ooze_shield_enabled": { "label": "Enable Ooze Shield", From b3e741e90cba70db672ffb653a1d5f3cb797ee6d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 13 May 2016 10:16:58 +0200 Subject: [PATCH 082/705] Added variant selection CURA-1278 --- cura/MachineManagerModel.py | 33 +++++++++++++++++++++++++++++---- resources/qml/SidebarHeader.qml | 14 +++++++++----- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 49c2288a98..c7cd4a6758 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -12,9 +12,11 @@ class MachineManagerModel(QObject): ## When the global container is changed, active material probably needs to be updated. self.globalContainerChanged.connect(self.activeMaterialChanged) + self.globalContainerChanged.connect(self.activeVariantChanged) globalContainerChanged = pyqtSignal() activeMaterialChanged = pyqtSignal() + activeVariantChanged = pyqtSignal() def _onGlobalContainerChanged(self): Application.getInstance().getGlobalContainerStack().containersChanged.connect(self._onInstanceContainersChanged) @@ -24,6 +26,8 @@ class MachineManagerModel(QObject): container_type = container.getMetaDataEntry("type") if container_type == "material": self.activeMaterialChanged.emit() + elif container_type == "variant": + self.activeVariantChanged.emit() @pyqtSlot(str) def setActiveMachine(self, stack_id): @@ -39,18 +43,24 @@ class MachineManagerModel(QObject): new_global_stack.addMetaDataEntry("type", "machine") ContainerRegistry.getInstance().addContainer(new_global_stack) - variant_instance_container = InstanceContainer(name + "_variant") + ## DEBUG CODE material_instance_container = InstanceContainer("test_material") material_instance_container.addMetaDataEntry("type", "material") material_instance_container.setDefinition(definitions[0]) - #material_instance_container.setMetaData({"type","material"}) + + variant_instance_container = InstanceContainer("test_variant") + variant_instance_container.addMetaDataEntry("type", "variant") + variant_instance_container.setDefinition(definitions[0]) + quality_instance_container = InstanceContainer(name + "_quality") current_settings_instance_container = InstanceContainer(name + "_current_settings") ContainerRegistry.getInstance().addContainer(material_instance_container) + ContainerRegistry.getInstance().addContainer(variant_instance_container) # If a definition is found, its a list. Should only have one item. new_global_stack.addContainer(definitions[0]) new_global_stack.addContainer(material_instance_container) + new_global_stack.addContainer(variant_instance_container) Application.getInstance().setGlobalContainerStack(new_global_stack) @pyqtProperty(str, notify = globalContainerChanged) @@ -71,8 +81,23 @@ class MachineManagerModel(QObject): def setActiveMaterial(self, material_id): containers = ContainerRegistry.getInstance().findInstanceContainers(id=material_id) old_material = Application.getInstance().getGlobalContainerStack().findContainer({"type":"material"}) - material_index = Application.getInstance().getGlobalContainerStack().getContainerIndex(old_material) - Application.getInstance().getGlobalContainerStack().replaceContainer(material_index, containers[0]) + if old_material: + material_index = Application.getInstance().getGlobalContainerStack().getContainerIndex(old_material) + Application.getInstance().getGlobalContainerStack().replaceContainer(material_index, containers[0]) + + @pyqtSlot(str) + def setActiveVariant(self, variant_id): + containers = ContainerRegistry.getInstance().findInstanceContainers(id=variant_id) + old_variant = Application.getInstance().getGlobalContainerStack().findContainer({"type": "variant"}) + if old_variant: + variant_index = Application.getInstance().getGlobalContainerStack().getContainerIndex(old_variant) + Application.getInstance().getGlobalContainerStack().replaceContainer(variant_index, containers[0]) + + @pyqtProperty(str, notify = activeVariantChanged) + def activeVariantName(self): + variant = Application.getInstance().getGlobalContainerStack().findContainer({"type": "variant"}) + if variant: + return variant.getName() @pyqtSlot(str, str) def renameMachine(self, machine_id, new_name): diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 7feeb32d43..e4c8e8bb02 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -128,8 +128,8 @@ Item ToolButton { id: variantSelection - text: UM.MachineManager.activeMachineVariant - tooltip: UM.MachineManager.activeMachineVariant; + text: Cura.MachineManager.activeVariantName + tooltip: Cura.MachineManager.activeVariantName; visible: UM.MachineManager.hasVariants height: UM.Theme.getSize("setting_control").height @@ -143,6 +143,10 @@ Item Instantiator { id: variantSelectionInstantiator + model: UM.InstanceContainersModel + { + filter: {"type": "variant"} + } // model: UM.MachineVariantsModel { id: variantsModel } MenuItem { @@ -152,14 +156,14 @@ Item exclusiveGroup: variantSelectionMenuGroup; onTriggered: { - UM.MachineManager.setActiveMachineVariant(variantsModel.getItem(index).name); - if (typeof(model) !== "undefined" && !model.active) { + Cura.MachineManager.setActiveVariant(model.id); + /*if (typeof(model) !== "undefined" && !model.active) { //Selecting a variant was canceled; undo menu selection variantSelectionInstantiator.model.setProperty(index, "active", false); var activeMachineVariantName = UM.MachineManager.activeMachineVariant; var activeMachineVariantIndex = variantSelectionInstantiator.model.find("name", activeMachineVariantName); variantSelectionInstantiator.model.setProperty(activeMachineVariantIndex, "active", true); - } + }*/ } } onObjectAdded: variantsSelectionMenu.insertItem(index, object) From f3384b043db92bf38d31eb9755c3b527123e6fe0 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 13 May 2016 11:26:08 +0200 Subject: [PATCH 083/705] Only variants of active machine are now shown CURA-1278 --- cura/MachineManagerModel.py | 4 ++++ resources/qml/SidebarHeader.qml | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index c7cd4a6758..53fcd1662e 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -105,6 +105,10 @@ class MachineManagerModel(QObject): if containers: containers[0].setName(new_name) + @pyqtProperty(str, notify=globalContainerChanged) + def activeMachineDefinitionId(self): + return Application.getInstance().getGlobalContainerStack().getContainers()[-1].getId() + @pyqtSlot(str) def removeMachine(self, machine_id): ContainerRegistry.getInstance().removeContainer(machine_id) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index e4c8e8bb02..258ca8221c 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -145,9 +145,12 @@ Item id: variantSelectionInstantiator model: UM.InstanceContainersModel { - filter: {"type": "variant"} + filter: + { + "type": "variant", + "definition": Cura.MachineManager.activeMachineDefinitionId //Only show variants of this machine + } } -// model: UM.MachineVariantsModel { id: variantsModel } MenuItem { text: model.name; From 6ffde62bcf8f7fcecacbd9a7ce3e7591096ddf91 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 13 May 2016 11:40:18 +0200 Subject: [PATCH 084/705] Added stubs for hasVariants & hasMaterials CURA-1278 --- cura/MachineManagerModel.py | 11 +++++++++++ resources/qml/SidebarHeader.qml | 13 +++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 53fcd1662e..28ae06e26b 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -113,6 +113,17 @@ class MachineManagerModel(QObject): def removeMachine(self, machine_id): ContainerRegistry.getInstance().removeContainer(machine_id) + @pyqtProperty(bool) + def hasMaterials(self): + # Todo: Still hardcoded. + # We should implement this properly when it's clear how a machine notifies us if it can handle materials + return True + + @pyqtProperty(bool) + def hasVariants(self): + # Todo: Still hardcoded. + # We should implement this properly when it's clear how a machine notifies us if it can handle variants + return True def createMachineManagerModel(engine, script_engine): diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 258ca8221c..fcf05a49ca 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -104,12 +104,12 @@ Item anchors.topMargin: visible ? UM.Theme.getSize("default_margin").height : 0 width: base.width height: visible ? UM.Theme.getSize("sidebar_setup").height : 0 - visible: UM.MachineManager.hasVariants || UM.MachineManager.hasMaterials + visible: Cura.MachineManager.hasVariants || Cura.MachineManager.hasMaterials Label{ id: variantLabel - text: (UM.MachineManager.hasVariants && UM.MachineManager.hasMaterials) ? catalog.i18nc("@label","Nozzle & Material:"): - UM.MachineManager.hasVariants ? catalog.i18nc("@label","Nozzle:") : catalog.i18nc("@label","Material:"); + text: (Cura.MachineManager.hasVariants && Cura.MachineManager.hasMaterials) ? catalog.i18nc("@label","Nozzle & Material:"): + Cura.MachineManager.hasVariants ? catalog.i18nc("@label","Nozzle:") : catalog.i18nc("@label","Material:"); anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width anchors.verticalCenter: parent.verticalCenter @@ -118,7 +118,8 @@ Item color: UM.Theme.getColor("text"); } - Rectangle { + Rectangle + { anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("default_margin").width anchors.verticalCenter: parent.verticalCenter @@ -130,7 +131,7 @@ Item id: variantSelection text: Cura.MachineManager.activeVariantName tooltip: Cura.MachineManager.activeVariantName; - visible: UM.MachineManager.hasVariants + visible: Cura.MachineManager.hasVariants height: UM.Theme.getSize("setting_control").height width: materialSelection.visible ? (parent.width - UM.Theme.getSize("default_margin").width) / 2 : parent.width @@ -181,7 +182,7 @@ Item id: materialSelection text: Cura.MachineManager.activeMaterialName tooltip: Cura.MachineManager.activeMaterialName - visible: UM.MachineManager.hasMaterials + visible: Cura.MachineManager.hasMaterials height: UM.Theme.getSize("setting_control").height width: variantSelection.visible ? (parent.width - UM.Theme.getSize("default_margin").width) / 2 : parent.width From 5dbe0bdc0379950eb4066afbbf5fdc8864bca2d5 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 13 May 2016 11:46:54 +0200 Subject: [PATCH 085/705] Machine variants can now be selected from dropdown menu CURA-1278 --- resources/qml/Cura.qml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 4314dc21e6..250dcf050e 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -193,13 +193,20 @@ UM.MainWindow Instantiator { -// model: UM.MachineVariantsModel { } + model: UM.InstanceContainersModel + { + filter: + { + "type": "variant", + "definition": Cura.MachineManager.activeMachineDefinitionId //Only show variants of this machine + } + } MenuItem { text: model.name; checkable: true; checked: model.active; exclusiveGroup: machineVariantsGroup; - onTriggered: UM.MachineManager.setActiveMachineVariant(model.name) + onTriggered: Cura.MachineManager.setActiveVariant(model.id) } onObjectAdded: machineMenu.insertItem(index, object) onObjectRemoved: machineMenu.removeItem(object) @@ -207,7 +214,7 @@ UM.MainWindow ExclusiveGroup { id: machineVariantsGroup; } -// MenuSeparator { visible: UM.MachineManager.hasVariants; } + MenuSeparator { visible: Cura.MachineManager.hasVariants; } MenuItem { action: Actions.addMachine; } MenuItem { action: Actions.configureMachines; } From dd24e488a834bc29ab5f096721b2698e3cfd29a3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 13 May 2016 12:04:38 +0200 Subject: [PATCH 086/705] Materials & variants are now correctly checked when active CURA-1278 --- cura/MachineManagerModel.py | 13 +++++++++++++ resources/qml/Cura.qml | 2 +- resources/qml/SidebarHeader.qml | 6 ++---- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 28ae06e26b..2ff80efc3d 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -77,6 +77,12 @@ class MachineManagerModel(QObject): if material: return material.getName() + @pyqtProperty(str, notify=activeMaterialChanged) + def activeMaterialId(self): + material = Application.getInstance().getGlobalContainerStack().findContainer({"type": "material"}) + if material: + return material.getId() + @pyqtSlot(str) def setActiveMaterial(self, material_id): containers = ContainerRegistry.getInstance().findInstanceContainers(id=material_id) @@ -99,6 +105,13 @@ class MachineManagerModel(QObject): if variant: return variant.getName() + @pyqtProperty(str, notify = activeVariantChanged) + def activeVariantId(self): + variant = Application.getInstance().getGlobalContainerStack().findContainer({"type": "variant"}) + if variant: + return variant.getId() + + @pyqtSlot(str, str) def renameMachine(self, machine_id, new_name): containers = ContainerRegistry.getInstance().findContainerStacks(id = machine_id) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 250dcf050e..2d1fbe3305 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -204,7 +204,7 @@ UM.MainWindow MenuItem { text: model.name; checkable: true; - checked: model.active; + checked: model.id == Cura.MachineManager.activeVariantId; exclusiveGroup: machineVariantsGroup; onTriggered: Cura.MachineManager.setActiveVariant(model.id) } diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index fcf05a49ca..ff6db0703b 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -156,7 +156,7 @@ Item { text: model.name; checkable: true; - checked: model.active; + checked: model.id == Cura.MachineManager.activeVariantId; exclusiveGroup: variantSelectionMenuGroup; onTriggered: { @@ -199,13 +199,11 @@ Item { filter: {"type": "material"} } - //model: UM.InstancesModel {filter: {"type":"material"}} -// model: UM.MachineMaterialsModel { id: machineMaterialsModel } MenuItem { text: model.name; checkable: true; - checked: model.active; + checked: model.id == Cura.MachineManager.activeMaterialId; exclusiveGroup: materialSelectionMenuGroup; onTriggered: { From f9adb2c601be147dc9afce75db982cf369998afd Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 13 May 2016 13:05:58 +0200 Subject: [PATCH 087/705] Reset stored layer data as soon as a new slice operation starts This prevents layer view showing a combination of stale and fresh data Fixes CURA-1370 (and CURA-1519) --- plugins/CuraEngineBackend/CuraEngineBackend.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index c5b38034b5..32e9f8da65 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -118,6 +118,7 @@ class CuraEngineBackend(Backend): ## Perform a slice of the scene. def slice(self): + self._stored_layer_data = [] if not self._enabled: return From 3d94d2437274f1bfe001fbb25a3bf4ffdc2a8971 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Fri, 13 May 2016 13:28:00 +0200 Subject: [PATCH 088/705] JSON feat: skin overlap (CURA-967) --- resources/machines/fdmprinter.json | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/resources/machines/fdmprinter.json b/resources/machines/fdmprinter.json index 7171d140ff..53e60beb26 100644 --- a/resources/machines/fdmprinter.json +++ b/resources/machines/fdmprinter.json @@ -573,6 +573,29 @@ } } }, + "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": "%", + "type": "float", + "default": 5, + "min_value_warning": "-50", + "max_value_warning": "100", + "visible": false, + "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", + "type": "float", + "default": 0.02, + "min_value_warning": "-0.5 * machine_nozzle_size", + "max_value_warning": "machine_nozzle_size", + "inherit_function": "skin_line_width * parent_value / 100", + "visible": false + } + } + }, "infill_wipe_dist": { "label": "Infill Wipe Distance", "description": "Distance of a travel move inserted after every infill line, to make the infill stick to the walls better. This option is similar to infill overlap, but without extrusion and only on one end of the infill line.", From c832b92e6f1effada7c044b528272224b51621a7 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Fri, 13 May 2016 13:37:43 +0200 Subject: [PATCH 089/705] JSON fix: made infill/skin overlap disabled for concentric pattern (CURA-967) --- resources/machines/fdmprinter.json | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/resources/machines/fdmprinter.json b/resources/machines/fdmprinter.json index 53e60beb26..c872437f7d 100644 --- a/resources/machines/fdmprinter.json +++ b/resources/machines/fdmprinter.json @@ -555,10 +555,11 @@ "unit": "%", "type": "float", "default": 10, - "inherit_function": "10 if infill_sparse_density < 95 else 0", + "inherit_function": "10 if infill_sparse_density < 95 and infill_pattern != \"concentric\" else 0", "min_value_warning": "-50", "max_value_warning": "100", "visible": false, + "enabled": "infill_pattern != \"concentric\"", "children": { "infill_overlap_mm": { "label": "Infill Overlap", @@ -568,8 +569,9 @@ "default": 0.04, "min_value_warning": "-0.5 * machine_nozzle_size", "max_value_warning": "machine_nozzle_size", - "inherit_function": "infill_line_width * parent_value / 100 if infill_sparse_density < 95 else 0", - "visible": false + "inherit_function": "infill_line_width * parent_value / 100 if infill_sparse_density < 95 and infill_pattern != \"concentric\" else 0", + "visible": false, + "enabled": "infill_pattern != \"concentric\"" } } }, @@ -581,7 +583,9 @@ "default": 5, "min_value_warning": "-50", "max_value_warning": "100", + "inherit_function": "5 if top_bottom_pattern != \"concentric\" else 0", "visible": false, + "enabled": "top_bottom_pattern != \"concentric\"", "children": { "skin_overlap_mm": { "label": "Skin Overlap", @@ -591,8 +595,9 @@ "default": 0.02, "min_value_warning": "-0.5 * machine_nozzle_size", "max_value_warning": "machine_nozzle_size", - "inherit_function": "skin_line_width * parent_value / 100", - "visible": false + "inherit_function": "skin_line_width * parent_value / 100 if top_bottom_pattern != \"concentric\" else 0", + "visible": false, + "enabled": "top_bottom_pattern != \"concentric\"" } } }, From ed498317855ca758faf1272749ade6a33a9ee62e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 13 May 2016 15:24:49 +0200 Subject: [PATCH 090/705] Last active machine is now restored upon restart CURA-1278 --- cura/CuraApplication.py | 1 - cura/MachineManagerModel.py | 12 ++++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 8c6681de8c..e161a242e0 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -110,7 +110,6 @@ class CuraApplication(QtApplication): Resources.addType(self.ResourceTypes.QmlFiles, "qml") Resources.addType(self.ResourceTypes.Firmware, "firmware") - Preferences.getInstance().addPreference("cura/active_machine", "") Preferences.getInstance().addPreference("cura/active_mode", "simple") Preferences.getInstance().addPreference("cura/recent_files", "") Preferences.getInstance().addPreference("cura/categories_expanded", "") diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 2ff80efc3d..dc330ac3bc 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -5,6 +5,8 @@ from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.ContainerStack import ContainerStack from UM.Settings.InstanceContainer import InstanceContainer +from UM.Preferences import Preferences + class MachineManagerModel(QObject): def __init__(self, parent = None): super().__init__(parent) @@ -14,11 +16,21 @@ class MachineManagerModel(QObject): self.globalContainerChanged.connect(self.activeMaterialChanged) self.globalContainerChanged.connect(self.activeVariantChanged) + Preferences.getInstance().addPreference("cura/active_machine", "") + + active_machine_id = Preferences.getInstance().getValue("cura/active_machine") + if active_machine_id != "": + # An active machine was saved, so restore it. + self.setActiveMachine(active_machine_id) + pass + + globalContainerChanged = pyqtSignal() activeMaterialChanged = pyqtSignal() activeVariantChanged = pyqtSignal() def _onGlobalContainerChanged(self): + Preferences.getInstance().setValue("cura/active_machine", Application.getInstance().getGlobalContainerStack().getId()) Application.getInstance().getGlobalContainerStack().containersChanged.connect(self._onInstanceContainersChanged) self.globalContainerChanged.emit() From bfbb48268a19461992db642a02fba1a348fd45fa Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 13 May 2016 15:48:56 +0200 Subject: [PATCH 091/705] Added material stubs CURA-1278 --- resources/instances/abs.inst.cfg | 12 ++++++++++++ resources/instances/cpe.inst.cfg | 11 +++++++++++ resources/instances/pla.inst.cfg | 10 ++++++++++ 3 files changed, 33 insertions(+) create mode 100644 resources/instances/abs.inst.cfg create mode 100644 resources/instances/cpe.inst.cfg create mode 100644 resources/instances/pla.inst.cfg diff --git a/resources/instances/abs.inst.cfg b/resources/instances/abs.inst.cfg new file mode 100644 index 0000000000..0d64e81437 --- /dev/null +++ b/resources/instances/abs.inst.cfg @@ -0,0 +1,12 @@ +[general] +version = 2 +name = ABS +definition = fdmprinter + +[metadata] +type = material + +[values] +material_print_temperature = 250 +material_bed_temperature = 80 +material_flow = 107 diff --git a/resources/instances/cpe.inst.cfg b/resources/instances/cpe.inst.cfg new file mode 100644 index 0000000000..ca30cba046 --- /dev/null +++ b/resources/instances/cpe.inst.cfg @@ -0,0 +1,11 @@ +[general] +version = 2 +name = CPE +definition = fdmprinter + +[metadata] +type = material + +[values] +material_print_temperature = 250 +material_bed_temperature = 70 \ No newline at end of file diff --git a/resources/instances/pla.inst.cfg b/resources/instances/pla.inst.cfg new file mode 100644 index 0000000000..dfa9c62469 --- /dev/null +++ b/resources/instances/pla.inst.cfg @@ -0,0 +1,10 @@ +[general] +version = 2 +name = PLA +definition = fdmprinter + +[metadata] +type = material + +[values] +material_bed_temperature = 60 From ad7531ededf08985f132d14b65b6076601a546cc Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 13 May 2016 15:56:41 +0200 Subject: [PATCH 092/705] Added quality instances stubs CURA_1278 --- resources/instances/high_quality.inst.cfg | 9 +++++++++ resources/instances/normal_quality.inst.cfg | 9 +++++++++ 2 files changed, 18 insertions(+) create mode 100644 resources/instances/high_quality.inst.cfg create mode 100644 resources/instances/normal_quality.inst.cfg diff --git a/resources/instances/high_quality.inst.cfg b/resources/instances/high_quality.inst.cfg new file mode 100644 index 0000000000..2e860cf380 --- /dev/null +++ b/resources/instances/high_quality.inst.cfg @@ -0,0 +1,9 @@ +[general] +version = 2 +name = high +definition = fdmprinter + +[metadata] +type = quality + +[values] diff --git a/resources/instances/normal_quality.inst.cfg b/resources/instances/normal_quality.inst.cfg new file mode 100644 index 0000000000..6bb23d841c --- /dev/null +++ b/resources/instances/normal_quality.inst.cfg @@ -0,0 +1,9 @@ +[general] +version = 2 +name = normal +definition = fdmprinter + +[metadata] +type = quality + +[values] From 5df7c519c20cfc3da470e46499a9b3a87f20d1fe Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 13 May 2016 17:29:49 +0200 Subject: [PATCH 093/705] Removed option to turn off automatic updated check from GeneralPage.qml UpdateChecker is not a required plugin, so we cannot rely on there being functionality to automatically check for updates. Note that the preference is still there, so the user can still turn off automatic update checking by editing the cura.cfg file. CURA-1540 --- resources/qml/GeneralPage.qml | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/resources/qml/GeneralPage.qml b/resources/qml/GeneralPage.qml index 9138fffc45..b2ff44b15a 100644 --- a/resources/qml/GeneralPage.qml +++ b/resources/qml/GeneralPage.qml @@ -30,10 +30,8 @@ UM.PreferencesPage UM.Preferences.resetPreference("general/language") UM.Preferences.resetPreference("physics/automatic_push_free") UM.Preferences.resetPreference("mesh/scale_to_fit") - UM.Preferences.resetPreference("info/automatic_update_check") UM.Preferences.resetPreference("info/send_slice_info") pushFreeCheckbox.checked = boolCheck(UM.Preferences.getValue("physics/automatic_push_free")) - checkUpdatesCheckbox.checked = boolCheck(UM.Preferences.getValue("info/automatic_update_check")) sendDataCheckbox.checked = boolCheck(UM.Preferences.getValue("info/send_slice_info")) scaleToFitCheckbox.checked = boolCheck(UM.Preferences.getValue("mesh/scale_to_fit")) var defaultLanguage = UM.Preferences.getValue("general/language") @@ -152,20 +150,6 @@ UM.PreferencesPage } } - UM.TooltipArea { - width: childrenRect.width - height: childrenRect.height - text: catalog.i18nc("@info:tooltip","Should Cura check for updates when the program is started?") - - CheckBox - { - id: checkUpdatesCheckbox - text: catalog.i18nc("@option:check","Check for updates on start") - checked: boolCheck(UM.Preferences.getValue("info/automatic_update_check")) - onCheckedChanged: UM.Preferences.setValue("info/automatic_update_check", checked) - } - } - UM.TooltipArea { width: childrenRect.width height: childrenRect.height From da872871bd5cbbacf325bb6b006011028b37cd51 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 13 May 2016 18:35:41 +0200 Subject: [PATCH 094/705] Add back option to turn off automatic update check if the UpdateChecker plugin is available CURA-1540 --- resources/qml/GeneralPage.qml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/resources/qml/GeneralPage.qml b/resources/qml/GeneralPage.qml index b2ff44b15a..3db56d4699 100644 --- a/resources/qml/GeneralPage.qml +++ b/resources/qml/GeneralPage.qml @@ -36,6 +36,11 @@ UM.PreferencesPage scaleToFitCheckbox.checked = boolCheck(UM.Preferences.getValue("mesh/scale_to_fit")) var defaultLanguage = UM.Preferences.getValue("general/language") setDefaultLanguage(defaultLanguage) + + if (UM.Models.pluginsModel.find("id", "UpdateChecker") > -1) { + UM.Preferences.resetPreference("info/automatic_update_check") + checkUpdatesCheckbox.checked = boolCheck(UM.Preferences.getValue("info/automatic_update_check")) + } } ColumnLayout @@ -150,6 +155,21 @@ UM.PreferencesPage } } + UM.TooltipArea { + visible: UM.Models.pluginsModel.find("id", "UpdateChecker") > -1 + width: childrenRect.width + height: childrenRect.height + text: catalog.i18nc("@info:tooltip","Should Cura check for updates when the program is started?") + + CheckBox + { + id: checkUpdatesCheckbox + text: catalog.i18nc("@option:check","Check for updates on start") + checked: boolCheck(UM.Preferences.getValue("info/automatic_update_check")) + onCheckedChanged: UM.Preferences.setValue("info/automatic_update_check", checked) + } + } + UM.TooltipArea { width: childrenRect.width height: childrenRect.height From 12638f3601eb95217a9ee74858f19a2ae1bca3ef Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 13 May 2016 19:04:32 +0200 Subject: [PATCH 095/705] Make machine prefix for jobname optional CURA-1480 --- cura/CuraApplication.py | 1 + resources/qml/GeneralPage.qml | 18 +++++++++++++++++- resources/qml/JobSpecs.qml | 6 +++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index f381faa482..996e1f59a3 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -114,6 +114,7 @@ class CuraApplication(QtApplication): Preferences.getInstance().addPreference("cura/active_mode", "simple") Preferences.getInstance().addPreference("cura/recent_files", "") Preferences.getInstance().addPreference("cura/categories_expanded", "") + Preferences.getInstance().addPreference("cura/jobname_prefix", True) Preferences.getInstance().addPreference("view/center_on_select", True) Preferences.getInstance().addPreference("mesh/scale_to_fit", True) Preferences.getInstance().addPreference("mesh/scale_tiny_meshes", True) diff --git a/resources/qml/GeneralPage.qml b/resources/qml/GeneralPage.qml index 3db56d4699..4f597ff32b 100644 --- a/resources/qml/GeneralPage.qml +++ b/resources/qml/GeneralPage.qml @@ -31,9 +31,11 @@ UM.PreferencesPage UM.Preferences.resetPreference("physics/automatic_push_free") UM.Preferences.resetPreference("mesh/scale_to_fit") UM.Preferences.resetPreference("info/send_slice_info") + UM.Preferences.resetPreference("cura/jobname_prefix") pushFreeCheckbox.checked = boolCheck(UM.Preferences.getValue("physics/automatic_push_free")) sendDataCheckbox.checked = boolCheck(UM.Preferences.getValue("info/send_slice_info")) scaleToFitCheckbox.checked = boolCheck(UM.Preferences.getValue("mesh/scale_to_fit")) + prefixJobNameCheckbox.checked = boolCheck(UM.Preferences.getValue("cura/jobname_prefix")) var defaultLanguage = UM.Preferences.getValue("general/language") setDefaultLanguage(defaultLanguage) @@ -116,7 +118,7 @@ UM.PreferencesPage UM.TooltipArea { width: childrenRect.width height: childrenRect.height - text: catalog.i18nc("@info:tooltip", "Should objects on the platform be moved so that they no longer intersect.") + text: catalog.i18nc("@info:tooltip", "Should objects on the platform be moved so that they no longer intersect?") CheckBox { @@ -183,5 +185,19 @@ UM.PreferencesPage onCheckedChanged: UM.Preferences.setValue("info/send_slice_info", checked) } } + + UM.TooltipArea { + width: childrenRect.width + height: childrenRect.height + text: catalog.i18nc("@info:tooltip", "Should a prefix based on the printer name be added to the print job name automatically?") + + CheckBox + { + id: prefixJobNameCheckbox + text: catalog.i18nc("@option:check", "Add machine prefix to job name") + checked: boolCheck(UM.Preferences.getValue("cura/jobname_prefix")) + onCheckedChanged: UM.Preferences.setValue("cura/jobname_prefix", checked) + } + } } } diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml index fac4fd841d..99b2d00c36 100644 --- a/resources/qml/JobSpecs.qml +++ b/resources/qml/JobSpecs.qml @@ -31,6 +31,7 @@ Rectangle { function createFileName(){ var splitMachineName = UM.MachineManager.activeMachineInstance.split(" ") var abbrMachine = '' + if ((UM.Preferences.getValue("cura/jobname_prefix"))) { for (var i = 0; i < splitMachineName.length; i++){ if (splitMachineName[i].search(/ultimaker/i) != -1){ abbrMachine += 'UM' @@ -48,7 +49,10 @@ Rectangle { } } } - printJobTextfield.text = abbrMachine + '_' + base.fileBaseName + printJobTextfield.text = abbrMachine + '_' + base.fileBaseName + } else { + printJobTextfield.text = base.fileBaseName + } } Connections { From 481b350cfd66bb204a5b9a513ca3d1be1a38ab2f Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Sat, 14 May 2016 18:42:23 +0200 Subject: [PATCH 096/705] BQ Hephestos2: Removing override of support_enable "support_enable" is already set as "enabled": false in fdmprinter.json. So this line is unneeded here. --- resources/machines/bq_hephestos_2.json | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/machines/bq_hephestos_2.json b/resources/machines/bq_hephestos_2.json index 8b1ed34caa..1655c28009 100644 --- a/resources/machines/bq_hephestos_2.json +++ b/resources/machines/bq_hephestos_2.json @@ -58,6 +58,5 @@ "skirt_minimal_length": { "default": 30.0, "visible": false }, "skirt_gap": { "default": 6.0 }, "cool_fan_full_at_height": { "default": 0.4, "visible": false }, - "support_enable": { "default": false } } } From c83a5a30cc2e5e9c7500715a12ce9d835a25b43a Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Mon, 16 May 2016 11:13:39 +0200 Subject: [PATCH 097/705] BQ Hephestos2: Removing machine_gcode_flavor This is already default at https://github.com/Ultimaker/Cura/blob/master/resources/machines/fdmprinter.json#L115 --- resources/machines/bq_hephestos_2.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/resources/machines/bq_hephestos_2.json b/resources/machines/bq_hephestos_2.json index 8b1ed34caa..4bb665cdc6 100644 --- a/resources/machines/bq_hephestos_2.json +++ b/resources/machines/bq_hephestos_2.json @@ -30,9 +30,6 @@ "machine_center_is_zero": { "default": false }, - "machine_gcode_flavor": { - "default": "RepRap" - }, "machine_platform_offset": { "default": [6, 1320, 0] }, From adc699c63be3f3ce312d19a40a398382c11288b2 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 12 May 2016 01:41:29 +0200 Subject: [PATCH 098/705] Add a SettingPropertyProvider object to the setting items --- resources/qml/Settings/SettingView.qml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 66ff30fa11..946d995f2a 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -37,6 +37,7 @@ ScrollView property var definition: model property var settingDefinitionsModel: definitionsModel + property var propertyProvider: provider asynchronous: true @@ -61,6 +62,18 @@ ScrollView } } + UM.SettingPropertyProvider + { + id: provider + + containerStackId: "" + + key: model.key + + watchedProperties: [ "value", "enabled", "state", "validationState" ] + + } + Connections { target: item From 08afad8973af1bed559f2040d6444e41840fc44f Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 16 May 2016 17:46:22 +0200 Subject: [PATCH 099/705] Remove get/setSettingValue from CuraApplication They are unused and should not be used anyway --- cura/CuraApplication.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index e161a242e0..e0d086e954 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -511,20 +511,6 @@ class CuraApplication(QtApplication): def expandedCategories(self): return Preferences.getInstance().getValue("cura/categories_expanded").split(";") - @pyqtSlot(str, result = "QVariant") - def getSettingValue(self, key): - if not self._global_container_stack: - return None - return self._global_container_stack.getValue(key) - - ## Change setting by key value pair - @pyqtSlot(str, "QVariant") - def setSettingValue(self, key, value): - if not self.getMachineManager().getWorkingProfile(): - return - - self.getMachineManager().getWorkingProfile().setSettingValue(key, value) - @pyqtSlot() def mergeSelected(self): self.groupSelected() From efdf1d78d1e0930bc50738ac75a874442c4b4b4c Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 16 May 2016 18:11:51 +0200 Subject: [PATCH 100/705] Add a "Current Settings" instance container to the stack on stack creation --- cura/MachineManagerModel.py | 43 ++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index dc330ac3bc..dcdae87dbf 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -1,12 +1,10 @@ from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal from UM.Application import Application -from UM.Settings.ContainerRegistry import ContainerRegistry -from UM.Settings.ContainerStack import ContainerStack -from UM.Settings.InstanceContainer import InstanceContainer - from UM.Preferences import Preferences +import UM.Settings + class MachineManagerModel(QObject): def __init__(self, parent = None): super().__init__(parent) @@ -43,36 +41,42 @@ class MachineManagerModel(QObject): @pyqtSlot(str) def setActiveMachine(self, stack_id): - containers = ContainerRegistry.getInstance().findContainerStacks(id = stack_id) + containers = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = stack_id) if containers: Application.getInstance().setGlobalContainerStack(containers[0]) @pyqtSlot(str, str) def addMachine(self,name, definition_id): - definitions = ContainerRegistry.getInstance().findDefinitionContainers(id=definition_id) + definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id=definition_id) if definitions: - new_global_stack = ContainerStack(name) + new_global_stack = UM.Settings.ContainerStack(name) new_global_stack.addMetaDataEntry("type", "machine") - ContainerRegistry.getInstance().addContainer(new_global_stack) + UM.Settings.ContainerRegistry.getInstance().addContainer(new_global_stack) ## DEBUG CODE - material_instance_container = InstanceContainer("test_material") + material_instance_container = UM.Settings.InstanceContainer("test_material") material_instance_container.addMetaDataEntry("type", "material") material_instance_container.setDefinition(definitions[0]) - variant_instance_container = InstanceContainer("test_variant") + variant_instance_container = UM.Settings.InstanceContainer("test_variant") variant_instance_container.addMetaDataEntry("type", "variant") variant_instance_container.setDefinition(definitions[0]) - quality_instance_container = InstanceContainer(name + "_quality") - current_settings_instance_container = InstanceContainer(name + "_current_settings") - ContainerRegistry.getInstance().addContainer(material_instance_container) - ContainerRegistry.getInstance().addContainer(variant_instance_container) + quality_instance_container = UM.Settings.InstanceContainer(name + "_quality") + UM.Settings.ContainerRegistry.getInstance().addContainer(material_instance_container) + UM.Settings.ContainerRegistry.getInstance().addContainer(variant_instance_container) + + current_settings_instance_container = UM.Settings.InstanceContainer(name + "_current_settings") + current_settings_instance_container.addMetaDataEntry("machine", name) + current_settings_instance_container.setDefinition(definitions[0]) + UM.Settings.ContainerRegistry.getInstance().addContainer(current_settings_instance_container) # If a definition is found, its a list. Should only have one item. new_global_stack.addContainer(definitions[0]) new_global_stack.addContainer(material_instance_container) new_global_stack.addContainer(variant_instance_container) + new_global_stack.addContainer(current_settings_instance_container) + Application.getInstance().setGlobalContainerStack(new_global_stack) @pyqtProperty(str, notify = globalContainerChanged) @@ -97,7 +101,7 @@ class MachineManagerModel(QObject): @pyqtSlot(str) def setActiveMaterial(self, material_id): - containers = ContainerRegistry.getInstance().findInstanceContainers(id=material_id) + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=material_id) old_material = Application.getInstance().getGlobalContainerStack().findContainer({"type":"material"}) if old_material: material_index = Application.getInstance().getGlobalContainerStack().getContainerIndex(old_material) @@ -105,7 +109,7 @@ class MachineManagerModel(QObject): @pyqtSlot(str) def setActiveVariant(self, variant_id): - containers = ContainerRegistry.getInstance().findInstanceContainers(id=variant_id) + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=variant_id) old_variant = Application.getInstance().getGlobalContainerStack().findContainer({"type": "variant"}) if old_variant: variant_index = Application.getInstance().getGlobalContainerStack().getContainerIndex(old_variant) @@ -126,7 +130,7 @@ class MachineManagerModel(QObject): @pyqtSlot(str, str) def renameMachine(self, machine_id, new_name): - containers = ContainerRegistry.getInstance().findContainerStacks(id = machine_id) + containers = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = machine_id) if containers: containers[0].setName(new_name) @@ -136,7 +140,7 @@ class MachineManagerModel(QObject): @pyqtSlot(str) def removeMachine(self, machine_id): - ContainerRegistry.getInstance().removeContainer(machine_id) + UM.Settings.ContainerRegistry.getInstance().removeContainer(machine_id) @pyqtProperty(bool) def hasMaterials(self): @@ -150,6 +154,5 @@ class MachineManagerModel(QObject): # We should implement this properly when it's clear how a machine notifies us if it can handle variants return True - def createMachineManagerModel(engine, script_engine): - return MachineManagerModel() \ No newline at end of file + return MachineManagerModel() From 5ff5ed385654f88ebf9840e85d41085d070e2b04 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 16 May 2016 18:12:10 +0200 Subject: [PATCH 101/705] Add an "activeDefinitionId" property to MachineManager --- cura/MachineManagerModel.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index dcdae87dbf..040625a159 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -127,6 +127,9 @@ class MachineManagerModel(QObject): if variant: return variant.getId() + @pyqtProperty(str, notify = globalContainerChanged) + def activeDefinitionId(self): + return Application.getInstance().getGlobalContainerStack().getBottom().id @pyqtSlot(str, str) def renameMachine(self, machine_id, new_name): From 442d2b6e718ac75f2703bacb8031673d21c9f429 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 16 May 2016 18:12:28 +0200 Subject: [PATCH 102/705] Use the right tooltip for SettingCategory --- resources/qml/Settings/SettingCategory.qml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index 871b5c0036..56a20aec3b 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -51,7 +51,6 @@ Button { UM.SimpleButton { - // This button shows when the setting has an inherited function, but is overriden by profile. id: inheritButton; anchors.verticalCenter: parent.verticalCenter @@ -71,7 +70,7 @@ Button { iconSource: UM.Theme.getIcon("notice") onEntered: { - base.showTooltip(catalog.i18nc("@label", "This setting is normally calculated, but it currently has an absolute value set.\n\nClick to restore the calculated value.")) + base.showTooltip(catalog.i18nc("@label","Some hidden settings use values different from their normal calculated value.\n\nClick to make these settings visible.")) } onExited: { From b1df8e9448ce00f5c63e14468a6e08ff071a2c70 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 16 May 2016 18:13:20 +0200 Subject: [PATCH 103/705] Use MachineManager and PropertyProvider to restore several bits of behavioiur --- resources/qml/Settings/SettingView.qml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 946d995f2a..6b09c8b9a3 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -7,6 +7,7 @@ import QtQuick.Controls.Styles 1.1 import QtQuick.Layouts 1.1 import UM 1.2 as UM +import Cura 1.0 as Cura import ".." @@ -26,14 +27,18 @@ ScrollView id: contents spacing: UM.Theme.getSize("default_lining").height; - model: UM.SettingDefinitionsModel { id: definitionsModel; containerId: "fdmprinter" } + model: UM.SettingDefinitionsModel { id: definitionsModel; containerId: Cura.MachineManager.activeDefinitionId } delegate: Loader { id: delegate width: UM.Theme.getSize("sidebar").width; - height: UM.Theme.getSize("section").height; + height: provider.properties.enabled ? UM.Theme.getSize("section").height : 0 + Behavior on height { NumberAnimation { duration: 100 } } + opacity: provider.properties.enabled ? 1 : 0 + Behavior on opacity { NumberAnimation { duration: 100 } } + enabled: provider.properties.enabled property var definition: model property var settingDefinitionsModel: definitionsModel @@ -66,12 +71,10 @@ ScrollView { id: provider - containerStackId: "" - + containerStackId: Cura.MachineManager.activeMachineId key: model.key - watchedProperties: [ "value", "enabled", "state", "validationState" ] - + storeIndex: 0 } Connections From e4fe1c6e210ff0be5902c701e874322bd51eed24 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 16 May 2016 18:13:46 +0200 Subject: [PATCH 104/705] Add PropertyProviders to SidebarSimple and use them for property values --- resources/qml/SidebarSimple.qml | 53 +++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 0e877ab09b..9c68c2ef81 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -6,7 +6,8 @@ import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 import QtQuick.Layouts 1.1 -import UM 1.1 as UM +import UM 1.2 as UM +import Cura 1.0 as Cura Item { @@ -56,12 +57,7 @@ Item Repeater { id: infillListView property int activeIndex: { - if(!UM.ActiveProfile.valid) - { - return -1; - } - -// var density = parseInt(UM.ActiveProfile.settingValues.getValue("infill_sparse_density")); + var density = parseInt(infillDensity.properties.value) for(var i = 0; i < infillModel.count; ++i) { if(density > infillModel.get(i).percentageMin && density <= infillModel.get(i).percentageMax ) @@ -116,7 +112,7 @@ Item onClicked: { if (infillListView.activeIndex != index) { -// UM.MachineManager.setSettingValue("infill_sparse_density", model.percentage) + infillDensity.setPropertyValue("value", model.percentage) } } onEntered: { @@ -213,13 +209,14 @@ Item text: catalog.i18nc("@option:check","Generate Brim"); style: UM.Theme.styles.checkbox; -// checked: UM.ActiveProfile.valid ? UM.ActiveProfile.settingValues.getValue("adhesion_type") == "brim" : false; + checked: platformAdhesionType.properties.value == "brim" + MouseArea { anchors.fill: parent hoverEnabled: true onClicked: { -// UM.MachineManager.setSettingValue("adhesion_type", !parent.checked?"brim":"skirt") + platformAdhesionType.setPropertyValue("value", !parent.checked ? "brim" : "skirt") } onEntered: { @@ -246,13 +243,13 @@ Item text: catalog.i18nc("@option:check","Generate Support Structure"); style: UM.Theme.styles.checkbox; -// checked: UM.ActiveProfile.valid ? UM.ActiveProfile.settingValues.getValue("support_enable") : false; + checked: supportEnabled.properties.value == "True" MouseArea { anchors.fill: parent hoverEnabled: true onClicked: { -// UM.MachineManager.setSettingValue("support_enable", !parent.checked) + supportEnabled.setPropertyValue("value", !parent.checked) } onEntered: { @@ -371,4 +368,36 @@ Item onLinkActivated: Qt.openUrlExternally(link) } } + + UM.SettingPropertyProvider + { + id: infillDensity + + containerStackId: Cura.MachineManager.activeMachineId + key: "infill_sparse_density" + watchedProperties: [ "value" ] + storeIndex: 0 + + onPropertiesChanged: console.log(properties.value) + } + + UM.SettingPropertyProvider + { + id: platformAdhesionType + + containerStackId: Cura.MachineManager.activeMachineId + key: "adhesion_type" + watchedProperties: [ "value" ] + storeIndex: 0 + } + + UM.SettingPropertyProvider + { + id: supportEnabled + + containerStackId: Cura.MachineManager.activeMachineId + key: "support_enable" + watchedProperties: [ "value" ] + storeIndex: 0 + } } From 5b31634d3ca4010c9712c54aca34448346d51f1d Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 16 May 2016 18:14:21 +0200 Subject: [PATCH 105/705] Make SettingTextField work --- resources/qml/Settings/SettingTextField.qml | 54 +++++++++++---------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/resources/qml/Settings/SettingTextField.qml b/resources/qml/Settings/SettingTextField.qml index 1b28ebadcc..3cbd21387b 100644 --- a/resources/qml/Settings/SettingTextField.qml +++ b/resources/qml/Settings/SettingTextField.qml @@ -31,19 +31,19 @@ SettingItem { return UM.Theme.getColor("setting_control_disabled") } - switch(definition.validationState) + switch(propertyProvider.properties.validationState) { - case 0: + case "ValidatorState.Exception": return UM.Theme.getColor("setting_validation_error") - case 1: + case "ValidatorState.MinimumError": return UM.Theme.getColor("setting_validation_error") - case 2: + case "ValidatorState.MaximumError": return UM.Theme.getColor("setting_validation_error") - case 3: + case "ValidatorState.MinimumWarning": return UM.Theme.getColor("setting_validation_warning") - case 4: + case "ValidatorState.MaximumWarning": return UM.Theme.getColor("setting_validation_warning") - case 5: + case "ValidatorState.Valid": return UM.Theme.getColor("setting_validation_ok") default: @@ -56,8 +56,7 @@ SettingItem anchors.fill: parent; anchors.margins: UM.Theme.getSize("default_lining").width; color: UM.Theme.getColor("setting_control_highlight") - opacity: 0.35 -// opacity: !control.hovered ? 0 : valid == 5 ? 1.0 : 0.35; + opacity: !control.hovered ? 0 : propertyProvider.properties.validationState == "ValidatorState.Valid" ? 1.0 : 0.35; } Label @@ -93,19 +92,22 @@ SettingItem Keys.onReleased: { - text = text.replace(",", ".") // User convenience. We use dots for decimal values - if(parseFloat(text) != base.parentValue) - { - base.valueChanged(parseFloat(text)); - } +// text = text.replace(",", ".") // User convenience. We use dots for decimal values +// if(parseFloat(text) != base.parentValue) +// { +// base.valueChanged(parseFloat(text)); +// } + + propertyProvider.setPropertyValue("value", text) } onEditingFinished: { - if(parseFloat(text) != base.parentValue) - { - base.valueChanged(parseFloat(text)); - } +// if(parseFloat(text) != base.parentValue) +// { +// base.valueChanged(parseFloat(text)); +// } + propertyProvider.setPropertyValue("value", text) } color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text") @@ -117,13 +119,13 @@ SettingItem validator: RegExpValidator { regExp: /[0-9.,-]{0,10}/ } -// Binding -// { -// target: input -// property: "text" -// value: format(base.parentValue) -// when: !input.activeFocus -// } + Binding + { + target: input + property: "text" + value: control.format(propertyProvider.properties.value) + when: !input.activeFocus + } } //Rounds a floating point number to 4 decimals. This prevents floating @@ -147,7 +149,7 @@ SettingItem //input: The string value to format. //return: The formatted string. function format(inputValue) { - return parseFloat(inputValue) ? roundFloat(parseFloat(inputValue), 4) : inputValue //If it's a float, round to four decimals. + return parseFloat(inputValue) ? roundFloat(parseFloat(inputValue), 4) : inputValue //If it's a float, round to four decimals. } } } From 06432c3b0b8a12238c6a79fd1e5535dbb51791ac Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 16 May 2016 18:14:39 +0200 Subject: [PATCH 106/705] Make SettingCheckBox properly handle the value --- resources/qml/Settings/SettingCheckBox.qml | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/resources/qml/Settings/SettingCheckBox.qml b/resources/qml/Settings/SettingCheckBox.qml index 0acacb95fb..6f0314160e 100644 --- a/resources/qml/Settings/SettingCheckBox.qml +++ b/resources/qml/Settings/SettingCheckBox.qml @@ -19,20 +19,19 @@ SettingItem property bool checked: { - if(value == "True") + switch(propertyProvider.properties.value) { - return true; - } - else if(value == "False") - { - return false; - } - else - { - return value; + case "True": + return true + case "False": + return false + default: + return propertyProvider.properties.value } } + onClicked: propertyProvider.setPropertyValue("value", !checked) + Rectangle { anchors From f5e97c50012e9ff55f3360fec8c0a72b3348a998 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 16 May 2016 18:15:14 +0200 Subject: [PATCH 107/705] Make SettingComboBox work (mostly) properly = --- resources/qml/Settings/SettingComboBox.qml | 27 +++++++++------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/resources/qml/Settings/SettingComboBox.qml b/resources/qml/Settings/SettingComboBox.qml index 0f332b2aee..c9f3cb727b 100644 --- a/resources/qml/Settings/SettingComboBox.qml +++ b/resources/qml/Settings/SettingComboBox.qml @@ -13,6 +13,8 @@ SettingItem contents: ComboBox { + id: control + model: definition.options textRole: "value"; @@ -83,32 +85,25 @@ SettingItem } } } -/* - onActivated: { - valueChanged(options.getItem(index).value); - } - onModelChanged: { - updateCurrentIndex(); - } + onActivated: provider.setPropertyValue("value", definition.options[index].key) + onModelChanged: updateCurrentIndex(); - Component.onCompleted: { - parent.parent.valueChanged.connect(updateCurrentIndex) + Connections + { + target: provider + onPropertiesChanged: control.updateCurrentIndex() } function updateCurrentIndex() { - if (!options) { - return; - } - - for(var i = 0; i < options.rowCount(); ++i) { - if(options.getItem(i).value == value) { + for(var i = 0; i < definition.options.length; ++i) { + if(definition.options[i].key == provider.properties.value) { currentIndex = i; return; } } currentIndex = -1; - }*/ + } } } From 3531e4c3e8671fb959fd677912b62b98075711ee Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 16 May 2016 18:16:08 +0200 Subject: [PATCH 108/705] Nest all controls inside the mousearea of SettingItem This makes hover events work properly without all the hassle --- resources/qml/Settings/SettingItem.qml | 169 +++++++++++-------------- 1 file changed, 77 insertions(+), 92 deletions(-) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index d11b0b300a..ebbf93af84 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -16,7 +16,7 @@ Item { height: UM.Theme.getSize("section").height; property alias contents: controlContainer.children; - property bool hovered: false + property alias hovered: mouse.containsMouse signal contextMenuRequested() signal showTooltip(string text); @@ -52,118 +52,103 @@ Item { onTriggered: base.showTooltip(definition.description); } - } - Label - { - id: label; + Label + { + id: label; - anchors.left: parent.left; - anchors.leftMargin: (UM.Theme.getSize("section_icon_column").width + 5) + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width) - anchors.right: settingControls.left; - anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left; + anchors.leftMargin: (UM.Theme.getSize("section_icon_column").width + 5) + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width) + anchors.right: settingControls.left; + anchors.verticalCenter: parent.verticalCenter - height: UM.Theme.getSize("section").height; - verticalAlignment: Text.AlignVCenter; + height: UM.Theme.getSize("section").height; + verticalAlignment: Text.AlignVCenter; - text: definition.label - elide: Text.ElideMiddle; + text: definition.label + elide: Text.ElideMiddle; - color: UM.Theme.getColor("setting_control_text"); - font: UM.Theme.getFont("default"); - } - - Row - { - id: settingControls - - height: parent.height / 2 - spacing: UM.Theme.getSize("default_margin").width / 2 - - anchors { - right: controlContainer.left - rightMargin: UM.Theme.getSize("default_margin").width / 2 - verticalCenter: parent.verticalCenter + color: UM.Theme.getColor("setting_control_text"); + font: UM.Theme.getFont("default"); } - UM.SimpleButton + Row { - id: revertButton; + id: settingControls -// visible: base.overridden && base.is_enabled + height: parent.height / 2 + spacing: UM.Theme.getSize("default_margin").width / 2 - height: parent.height; - width: height; - - backgroundColor: UM.Theme.getColor("setting_control"); - hoverBackgroundColor: UM.Theme.getColor("setting_control_highlight") - color: UM.Theme.getColor("setting_control_button") - hoverColor: UM.Theme.getColor("setting_control_button_hover") - - iconSource: UM.Theme.getIcon("reset") - - onClicked: { - base.resetRequested() - controlContainer.notifyReset(); + anchors { + right: controlContainer.left + rightMargin: UM.Theme.getSize("default_margin").width / 2 + verticalCenter: parent.verticalCenter } - onEntered: base.showTooltip(catalog.i18nc("@label", "This setting has a value that is different from the profile.\n\nClick to restore the value of the profile.")) - onExited: + UM.SimpleButton { - if(controlContainer.item && controlContainer.item.hovered) - { - return; + id: revertButton; + + visible: propertyProvider.properties.state == "InstanceState.User" + + height: parent.height; + width: height; + + backgroundColor: UM.Theme.getColor("setting_control"); + hoverBackgroundColor: UM.Theme.getColor("setting_control_highlight") + color: UM.Theme.getColor("setting_control_button") + hoverColor: UM.Theme.getColor("setting_control_button_hover") + + iconSource: UM.Theme.getIcon("reset") + + onClicked: { + base.resetRequested() + controlContainer.notifyReset(); } - base.hovered = false; - base.hideTooltip(); + onEntered: base.showTooltip(catalog.i18nc("@label", "This setting has a value that is different from the profile.\n\nClick to restore the value of the profile.")) + onExited: base.showTooltip(definition.description); } + + UM.SimpleButton + { + // This button shows when the setting has an inherited function, but is overriden by profile. + id: inheritButton; + + //visible: has_profile_value && base.has_inherit_function && base.is_enabled + visible: propertyProvider.properties.state == "InstanceState.User" + + height: parent.height; + width: height; + + onClicked: { + base.resetToDefaultRequested(); + controlContainer.notifyReset(); + } + + backgroundColor: UM.Theme.getColor("setting_control"); + hoverBackgroundColor: UM.Theme.getColor("setting_control_highlight") + color: UM.Theme.getColor("setting_control_button") + hoverColor: UM.Theme.getColor("setting_control_button_hover") + + iconSource: UM.Theme.getIcon("notice"); + + onEntered: base.showTooltip(catalog.i18nc("@label", "This setting is normally calculated, but it currently has an absolute value set.\n\nClick to restore the calculated value.")) + onExited: base.showTooltip(definition.description); + } + } - UM.SimpleButton + Item { - // This button shows when the setting has an inherited function, but is overriden by profile. - id: inheritButton; + id: controlContainer; -// visible: has_profile_value && base.has_inherit_function && base.is_enabled - height: parent.height; - width: height; - - onClicked: { - base.resetToDefaultRequested(); - controlContainer.notifyReset(); - } - - backgroundColor: UM.Theme.getColor("setting_control"); - hoverBackgroundColor: UM.Theme.getColor("setting_control_highlight") - color: UM.Theme.getColor("setting_control_button") - hoverColor: UM.Theme.getColor("setting_control_button_hover") - - iconSource: UM.Theme.getIcon("notice"); - - onEntered: base.showTooltip(catalog.i18nc("@label", "This setting is normally calculated, but it currently has an absolute value set.\n\nClick to restore the calculated value.")) - - onExited: { - if(controlContainer.item && controlContainer.item.hovered) { - return; - } - - base.hovered = false; - base.hideTooltip(); - } + anchors.right: parent.right; + anchors.rightMargin: UM.Theme.getSize("default_margin").width + anchors.verticalCenter: parent.verticalCenter; + width: UM.Theme.getSize("setting_control").width; + height: UM.Theme.getSize("setting_control").height } - - } - - Item - { - id: controlContainer; - - anchors.right: parent.right; - anchors.rightMargin: UM.Theme.getSize("default_margin").width - anchors.verticalCenter: parent.verticalCenter; - width: UM.Theme.getSize("setting_control").width; - height: UM.Theme.getSize("setting_control").height } UM.I18nCatalog { id: catalog; name: "cura" } From d1d2e1cea7f0e5f79dfa1bcea7d68a957fa7b289 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 16 May 2016 18:16:28 +0200 Subject: [PATCH 109/705] Set the right defaults for setting visibility in Cura --- cura/CuraApplication.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index e0d086e954..5620d039c9 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -117,6 +117,39 @@ class CuraApplication(QtApplication): Preferences.getInstance().addPreference("mesh/scale_to_fit", True) Preferences.getInstance().setDefault("local_file/last_used_type", "text/x-gcode") + Preferences.getInstance().setDefault("general/visible_settings", """ + resolution + layer_height + shell + wall_thickness + top_bottom_thickness + infill + infill_sparse_density + material + material_print_temperature + material_bed_temperature + material_diameter + material_flow + retraction_enable + speed + speed_print + speed_travel + cooling + cool_fan_enabled + support + support_enable + support_type + support_roof_density + platform_adhesion + adhesion_type + brim_width + raft_airgap + layer_0_z_overlap + raft_surface_layers + blackmagic + print_sequence + """) + JobQueue.getInstance().jobFinished.connect(self._onJobFinished) self._recent_files = [] From 442b9f2af32dda8cf2e901a8df8e7d3baf44fb91 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Tue, 17 May 2016 09:43:14 +0200 Subject: [PATCH 110/705] Rename 'tmp' to something a bit more meaningful. Contributes to CURA-1512 --- cura/ConvexHullJob.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/ConvexHullJob.py b/cura/ConvexHullJob.py index 92fcc66ecd..a60e6d339a 100644 --- a/cura/ConvexHullJob.py +++ b/cura/ConvexHullJob.py @@ -53,8 +53,8 @@ class ConvexHullJob(Job): # This basically finds the unique rows in the array by treating them as opaque groups of bytes # which are as long as the 2 float64s in each row, and giving this view to numpy.unique() to munch. # See http://stackoverflow.com/questions/16970982/find-unique-rows-in-numpy-array - tmp = numpy.ascontiguousarray(vertex_data).view(numpy.dtype((numpy.void, vertex_data.dtype.itemsize * vertex_data.shape[1]))) - _, idx = numpy.unique(tmp, return_index=True) + vertex_byte_view = numpy.ascontiguousarray(vertex_data).view(numpy.dtype((numpy.void, vertex_data.dtype.itemsize * vertex_data.shape[1]))) + _, idx = numpy.unique(vertex_byte_view, return_index=True) vertex_data = vertex_data[idx] # Select the unique rows by index. hull = Polygon(vertex_data) From 9bfe31aeef8b3646ba04050486ebe4141890da05 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 17 May 2016 10:39:10 +0200 Subject: [PATCH 111/705] Added quality type to setting stack CURA-1278 --- cura/MachineManagerModel.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 040625a159..08393ac829 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -13,10 +13,12 @@ class MachineManagerModel(QObject): ## When the global container is changed, active material probably needs to be updated. self.globalContainerChanged.connect(self.activeMaterialChanged) self.globalContainerChanged.connect(self.activeVariantChanged) + self.globalContainerChanged.connect(self.activeQualityChanged) Preferences.getInstance().addPreference("cura/active_machine", "") active_machine_id = Preferences.getInstance().getValue("cura/active_machine") + if active_machine_id != "": # An active machine was saved, so restore it. self.setActiveMachine(active_machine_id) @@ -26,6 +28,7 @@ class MachineManagerModel(QObject): globalContainerChanged = pyqtSignal() activeMaterialChanged = pyqtSignal() activeVariantChanged = pyqtSignal() + activeQualityChanged = pyqtSignal() def _onGlobalContainerChanged(self): Preferences.getInstance().setValue("cura/active_machine", Application.getInstance().getGlobalContainerStack().getId()) @@ -38,6 +41,8 @@ class MachineManagerModel(QObject): self.activeMaterialChanged.emit() elif container_type == "variant": self.activeVariantChanged.emit() + elif container_type == "quality": + self.activeQualityChanged.emit() @pyqtSlot(str) def setActiveMachine(self, stack_id): @@ -99,6 +104,18 @@ class MachineManagerModel(QObject): if material: return material.getId() + @pyqtProperty(str, notify=activeQualityChanged) + def activeQualityName(self): + quality = Application.getInstance().getGlobalContainerStack().findContainer({"type": "quality"}) + if quality: + return quality.getName() + + @pyqtProperty(str, notify=activeQualityChanged) + def activeQualityId(self): + quality = Application.getInstance().getGlobalContainerStack().findContainer({"type": "quality"}) + if quality: + return quality.getId() + @pyqtSlot(str) def setActiveMaterial(self, material_id): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=material_id) From 59ec593db5632234de15876d662ab17aced33533 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 17 May 2016 10:49:06 +0200 Subject: [PATCH 112/705] Added way to change active quality CURA-1278 --- cura/MachineManagerModel.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 08393ac829..0109f5d261 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -70,6 +70,9 @@ class MachineManagerModel(QObject): quality_instance_container = UM.Settings.InstanceContainer(name + "_quality") UM.Settings.ContainerRegistry.getInstance().addContainer(material_instance_container) UM.Settings.ContainerRegistry.getInstance().addContainer(variant_instance_container) + UM.Settings.ContainerRegistry.getInstance().addContainer(quality_instance_container) + quality_instance_container.addMetaDataEntry("type", "quality") + quality_instance_container.setDefinition(definitions[0]) current_settings_instance_container = UM.Settings.InstanceContainer(name + "_current_settings") current_settings_instance_container.addMetaDataEntry("machine", name) @@ -80,6 +83,7 @@ class MachineManagerModel(QObject): new_global_stack.addContainer(definitions[0]) new_global_stack.addContainer(material_instance_container) new_global_stack.addContainer(variant_instance_container) + new_global_stack.addContainer(quality_instance_container) new_global_stack.addContainer(current_settings_instance_container) Application.getInstance().setGlobalContainerStack(new_global_stack) @@ -132,6 +136,14 @@ class MachineManagerModel(QObject): variant_index = Application.getInstance().getGlobalContainerStack().getContainerIndex(old_variant) Application.getInstance().getGlobalContainerStack().replaceContainer(variant_index, containers[0]) + @pyqtSlot(str) + def setActiveQuality(self, quality_id): + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = quality_id) + old_quality = Application.getInstance().getGlobalContainerStack().findContainer({"type": "quality"}) + if old_quality: + quality_index = Application.getInstance().getGlobalContainerStack().getContainerIndex(old_quality) + Application.getInstance().getGlobalContainerStack().replaceContainer(quality_index, containers[0]) + @pyqtProperty(str, notify = activeVariantChanged) def activeVariantName(self): variant = Application.getInstance().getGlobalContainerStack().findContainer({"type": "variant"}) From 12fd002e67660d052482c6b9849c55b7e5b85b85 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 17 May 2016 10:50:01 +0200 Subject: [PATCH 113/705] Active quality is now displayed (and changable) again CURA-1278 --- resources/qml/ProfileSetup.qml | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/resources/qml/ProfileSetup.qml b/resources/qml/ProfileSetup.qml index 24668f43b0..95aed3685c 100644 --- a/resources/qml/ProfileSetup.qml +++ b/resources/qml/ProfileSetup.qml @@ -6,7 +6,8 @@ import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 import QtQuick.Layouts 1.1 -import UM 1.1 as UM +import UM 1.2 as UM +import Cura 1.0 as Cura Item{ id: base; @@ -41,13 +42,13 @@ Item{ property int rightMargin: customisedSettings.visible ? customisedSettings.width + UM.Theme.getSize("default_margin").width / 2 : 0 id: globalProfileSelection - text: UM.MachineManager.activeProfile + text: Cura.MachineManager.activeQualityName width: parent.width/100*55 height: UM.Theme.getSize("setting_control").height anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("default_margin").width anchors.verticalCenter: parent.verticalCenter - tooltip: UM.MachineManager.activeProfile + tooltip: Cura.MachineManager.activeQualityName style: UM.Theme.styles.sidebar_header_button menu: Menu @@ -56,7 +57,10 @@ Item{ Instantiator { id: profileSelectionInstantiator -// model: UM.ProfilesModel {} + model: UM.InstanceContainersModel + { + filter: {"type": "quality"} + } property int separatorIndex: -1 Loader { @@ -98,18 +102,18 @@ Item{ id: item text: model_data ? model_data.name : "" checkable: true; - checked: model_data ? model_data.active : false; + checked: Cura.MachineManager.activeQualityId == model_data.id exclusiveGroup: profileSelectionMenuGroup; onTriggered: { - UM.MachineManager.setActiveProfile(model_data.name); - if (!model_data.active) { + Cura.MachineManager.setActiveQuality(model_data.id); + /*if (!model_data.active) { //Selecting a profile was canceled; undo menu selection profileSelectionInstantiator.model.setProperty(model_index, "active", false); var activeProfileName = UM.MachineManager.activeProfile; var activeProfileIndex = profileSelectionInstantiator.model.find("name", activeProfileName); profileSelectionInstantiator.model.setProperty(activeProfileIndex, "active", true); - } + }*/ } } } From f24b56dc85d75dfd30fade67505d96fee0a1abdb Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 11:19:58 +0200 Subject: [PATCH 114/705] Move author and file formats to metadata The name can't be moved since it is not optional. Contributes to issue CURA-1278. --- resources/definitions/fdmprinter.def.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 00895fd056..11436bdcce 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1,15 +1,15 @@ { "id": "fdmprinter", + "name": "FDM Printer Base Description", "version": 2, "metadata": { + "author": "Ultimaker B.V.", "category": "Ultimaker", "manufacturer": "Ultimaker", + "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g", "visible": false }, - "name": "FDM Printer Base Description", - "author": "Ultimaker B.V.", - "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g", "settings": { "machine_settings": From 6d25d2112662b1c9df2f8a62f58a2ce5acbc6bcc Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 17 May 2016 12:55:40 +0200 Subject: [PATCH 115/705] getting id of definition when none was found no longer causes exception CURA-1278 --- cura/MachineManagerModel.py | 9 ++++----- resources/qml/Cura.qml | 2 +- resources/qml/SidebarHeader.qml | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 0109f5d261..82c8cd1328 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -158,7 +158,10 @@ class MachineManagerModel(QObject): @pyqtProperty(str, notify = globalContainerChanged) def activeDefinitionId(self): - return Application.getInstance().getGlobalContainerStack().getBottom().id + definition = Application.getInstance().getGlobalContainerStack().getBottom() + if definition: + return definition.id + return None @pyqtSlot(str, str) def renameMachine(self, machine_id, new_name): @@ -166,10 +169,6 @@ class MachineManagerModel(QObject): if containers: containers[0].setName(new_name) - @pyqtProperty(str, notify=globalContainerChanged) - def activeMachineDefinitionId(self): - return Application.getInstance().getGlobalContainerStack().getContainers()[-1].getId() - @pyqtSlot(str) def removeMachine(self, machine_id): UM.Settings.ContainerRegistry.getInstance().removeContainer(machine_id) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 2d1fbe3305..ba42bdc051 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -198,7 +198,7 @@ UM.MainWindow filter: { "type": "variant", - "definition": Cura.MachineManager.activeMachineDefinitionId //Only show variants of this machine + "definition": Cura.MachineManager.activeDefinitionId //Only show variants of this machine } } MenuItem { diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index ff6db0703b..5284178ba7 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -149,7 +149,7 @@ Item filter: { "type": "variant", - "definition": Cura.MachineManager.activeMachineDefinitionId //Only show variants of this machine + "definition": Cura.MachineManager.activeDefinitionId //Only show variants of this machine } } MenuItem From 0e5dcca81d4fe3bcf7351ff006343d99b9e5adbb Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 11:46:25 +0200 Subject: [PATCH 116/705] Add definition for BQ Prusa i3 Hephestos Contributes to issue CURA-1278. --- resources/definitions/bq_hephestos.def.json | 88 +++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 resources/definitions/bq_hephestos.def.json diff --git a/resources/definitions/bq_hephestos.def.json b/resources/definitions/bq_hephestos.def.json new file mode 100644 index 0000000000..22655a24f0 --- /dev/null +++ b/resources/definitions/bq_hephestos.def.json @@ -0,0 +1,88 @@ +{ + "id": "bq_hephestos", + "name": "BQ Prusa i3 Hephestos", + "version": 2, + "inherits": "fdmprinter", + "metadata": + { + "author": "BQ", + "manufacturer": "BQ", + "category": "Other", + "file_formats": "text/x-gcode" + }, + + "settings": { + "machine_start_gcode": { + "value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" + }, + "machine_width": { + "value": 215 + }, + "machine_depth": { + "value": 210 + }, + "machine_height": { + "value": 180 + }, + "machine_heated_bed": { + "value": false + }, + "machine_center_is_zero": { + "value": false + }, + "machine_gcode_flavor": { + "value": "RepRap" + }, + "machine_platform_offset": { + "value": [0, -82, 0] + }, + "layer_height": { + "value": 0.2 + }, + "layer_height_0": { + "value": 0.2 + }, + "wall_thickness": { + "value": 1.0 + }, + "top_bottom_thickness": { + "value": 1.0 + }, + "bottom_thickness": { + "value": 1.0 + }, + "material_print_temperature": { + "value": 220 + }, + "material_bed_temperature": { + "value": 0 + }, + "material_diameter": { + "value": 1.75 + }, + "speed_print": { + "value": 40.0 + }, + "speed_infill": { + "value": 40.0 + }, + "speed_wall": { + "value": 35.0 + }, + "speed_topbottom": { + "value": 35.0 + }, + "speed_travel": { + "value": 120.0 + }, + "speed_layer_0": { + "value": 20.0 + }, + "support_enable": { + "value": true + } + } +} \ No newline at end of file From b62e382cf2964e768082dff6f8b84e76a6eb5d34 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 11:52:28 +0200 Subject: [PATCH 117/705] Add platform for BQ Prusa i3 Hephestos Forgot this one when converting it. Contributes to issue CURA-1278. --- resources/definitions/bq_hephestos.def.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/definitions/bq_hephestos.def.json b/resources/definitions/bq_hephestos.def.json index 22655a24f0..9958ef2b86 100644 --- a/resources/definitions/bq_hephestos.def.json +++ b/resources/definitions/bq_hephestos.def.json @@ -8,7 +8,8 @@ "author": "BQ", "manufacturer": "BQ", "category": "Other", - "file_formats": "text/x-gcode" + "file_formats": "text/x-gcode", + "platform": "bq_hephestos_platform.stl" }, "settings": { From 0b2b9bd332de6922c1b0219370ff6fa3d565f7f8 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 11:55:56 +0200 Subject: [PATCH 118/705] Add definition for BQ Hephestos 2 Contributes to issue CURA-1278. --- resources/definitions/bq_hephestos_2.def.json | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 resources/definitions/bq_hephestos_2.def.json diff --git a/resources/definitions/bq_hephestos_2.def.json b/resources/definitions/bq_hephestos_2.def.json new file mode 100644 index 0000000000..cbaa41fb82 --- /dev/null +++ b/resources/definitions/bq_hephestos_2.def.json @@ -0,0 +1,117 @@ +{ + "id": "bq_hephestos_2", + "version": 1, + "name": "BQ Hephestos 2", + "inherits": "fdmprinter", + "metadata": { + "author": "BQ", + "manufacturer": "BQ", + "category": "Other", + "platform": "bq_hephestos_2_platform.stl", + "file_formats": "text/x-gcode" + }, + "manufacturer": "BQ", + "author": "BQ", + "platform": "bq_hephestos_2_platform.stl", + "file_formats": "text/x-gcode", + "inherits": "fdmprinter.json", + + "settings": { + "machine_start_gcode": { + "value": "; -- START GCODE --\nM800 ; Custom GCODE to fire start print procedure\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "value": "; -- END GCODE --\nM801 ; Custom GCODE to fire end print procedure\n; -- end of END GCODE --" + }, + "machine_width": { + "value": 210 + }, + "machine_depth": { + "value": 297 + }, + "machine_height": { + "value": 220 + }, + "machine_heated_bed": { + "value": false + }, + "machine_center_is_zero": { + "value": false + }, + "machine_gcode_flavor": { + "value": "RepRap" + }, + "machine_platform_offset": { + "value": [6, 1320, 0] + }, + "material_print_temperature": { + "value": 210.0 + }, + "material_bed_temperature": { + "value": 0 + }, + "material_diameter": { + "value": 1.75 + }, + "layer_height": { + "value": 0.2 + }, + "layer_height_0": { + "value": 0.2 + }, + "wall_line_count": { + "value": 3 + }, + "wall_thickness": { + "value": 1.2 + }, + "top_bottom_thickness": { + "value": 1.2 + }, + "infill_sparse_density": { + "value": 20.0 + }, + "infill_overlap": { + "value": 15.0 + }, + "speed_print": { + "value": 60.0 + }, + "speed_travel": { + "value": 160.0 + }, + "speed_layer_0": { + "value": 30.0 + }, + "speed_wall_x": { + "value": 35.0 + }, + "speed_wall_0": { + "value": 30.0 + }, + "speed_infill": { + "value": 80.0 + }, + "speed_topbottom": { + "value": 35.0 + }, + "skirt_speed": { + "value": 35.0 + }, + "skirt_line_count": { + "value": 4 + }, + "skirt_minimal_length": { + "value": 30.0 + }, + "skirt_gap": { + "value": 6.0 + }, + "cool_fan_full_at_height": { + "value": 0.4 + }, + "support_enable": { + "value": false + } + } +} From 53c6ce11e708ed0c97b18a17c826935877d4b0e9 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 11:57:31 +0200 Subject: [PATCH 119/705] Correct version number I should've changed this when converting the definition. Contributes to issue CURA-1278. --- resources/definitions/bq_hephestos_2.def.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/definitions/bq_hephestos_2.def.json b/resources/definitions/bq_hephestos_2.def.json index cbaa41fb82..2e084518ba 100644 --- a/resources/definitions/bq_hephestos_2.def.json +++ b/resources/definitions/bq_hephestos_2.def.json @@ -1,6 +1,6 @@ { "id": "bq_hephestos_2", - "version": 1, + "version": 2, "name": "BQ Hephestos 2", "inherits": "fdmprinter", "metadata": { From 6449062332e7204b81eefc3c128add8da7d6bc2e Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 12:12:59 +0200 Subject: [PATCH 120/705] Add definition for BQ Prusa i3 Hephestos XL Contributes to issue CURA-1278. --- .../definitions/bq_hephestos_xl.def.json | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 resources/definitions/bq_hephestos_xl.def.json diff --git a/resources/definitions/bq_hephestos_xl.def.json b/resources/definitions/bq_hephestos_xl.def.json new file mode 100644 index 0000000000..c79227faea --- /dev/null +++ b/resources/definitions/bq_hephestos_xl.def.json @@ -0,0 +1,88 @@ +{ + "id": "bq_hephestos_xl", + "version": 2, + "name": "BQ Prusa i3 Hephestos XL", + "inherits": "fdmprinter", + "metadata": { + "manufacturer": "BQ", + "author": "BQ", + "category": "Other", + "file_formats": "text/x-code", + "platform": "bq_hephestos_platform.stl" + }, + + "settings": { + "machine_start_gcode": { + "default": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "default": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" + }, + "machine_width": { + "default": 200 + }, + "machine_depth": { + "default": 300 + }, + "machine_height": { + "default": 180 + }, + "machine_heated_bed": { + "default": false + }, + "machine_center_is_zero": { + "default": false + }, + "machine_gcode_flavor": { + "default": "RepRap" + }, + "machine_platform_offset": { + "default": [0, -82, 0] + }, + "layer_height": { + "default": 0.2 + }, + "layer_height_0": { + "default": 0.2 + }, + "wall_thickness": { + "default": 1.0 + }, + "top_bottom_thickness": { + "default": 1.0 + }, + "bottom_thickness": { + "default": 1.0 + }, + "material_print_temperature": { + "default": 220 + }, + "material_bed_temperature": { + "default": 0 + }, + "material_diameter": { + "default": 1.75 + }, + "speed_print": { + "default": 40.0 + }, + "speed_infill": { + "default": 40.0 + }, + "speed_wall": { + "default": 35.0 + }, + "speed_topbottom": { + "default": 35.0 + }, + "speed_travel": { + "default": 120.0 + }, + "speed_layer_0": { + "default": 20.0 + }, + "support_enable": { + "default": true + } + } +} \ No newline at end of file From a16ff27ed69f3cf7318f3db529357b4b90058982 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 12:16:22 +0200 Subject: [PATCH 121/705] Fix definition 'default' -> 'value' Forgot that. Sorry. Contributes to issue CURA-1278. --- .../definitions/bq_hephestos_xl.def.json | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/resources/definitions/bq_hephestos_xl.def.json b/resources/definitions/bq_hephestos_xl.def.json index c79227faea..0d4bc13ea1 100644 --- a/resources/definitions/bq_hephestos_xl.def.json +++ b/resources/definitions/bq_hephestos_xl.def.json @@ -13,76 +13,76 @@ "settings": { "machine_start_gcode": { - "default": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" + "value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" }, "machine_end_gcode": { - "default": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" + "value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" }, "machine_width": { - "default": 200 + "value": 200 }, "machine_depth": { - "default": 300 + "value": 300 }, "machine_height": { - "default": 180 + "value": 180 }, "machine_heated_bed": { - "default": false + "value": false }, "machine_center_is_zero": { - "default": false + "value": false }, "machine_gcode_flavor": { - "default": "RepRap" + "value": "RepRap" }, "machine_platform_offset": { - "default": [0, -82, 0] + "value": [0, -82, 0] }, "layer_height": { - "default": 0.2 + "value": 0.2 }, "layer_height_0": { - "default": 0.2 + "value": 0.2 }, "wall_thickness": { - "default": 1.0 + "value": 1.0 }, "top_bottom_thickness": { - "default": 1.0 + "value": 1.0 }, "bottom_thickness": { - "default": 1.0 + "value": 1.0 }, "material_print_temperature": { - "default": 220 + "value": 220 }, "material_bed_temperature": { - "default": 0 + "value": 0 }, "material_diameter": { - "default": 1.75 + "value": 1.75 }, "speed_print": { - "default": 40.0 + "value": 40.0 }, "speed_infill": { - "default": 40.0 + "value": 40.0 }, "speed_wall": { - "default": 35.0 + "value": 35.0 }, "speed_topbottom": { - "default": 35.0 + "value": 35.0 }, "speed_travel": { - "default": 120.0 + "value": 120.0 }, "speed_layer_0": { - "default": 20.0 + "value": 20.0 }, "support_enable": { - "default": true + "value": true } } } \ No newline at end of file From 1c01eef409c599f43f4d597f7893f3cef1693052 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 12:20:35 +0200 Subject: [PATCH 122/705] Add definition for BQ Witbox Contributes to issue CURA-1278. --- resources/definitions/bq_witbox.def.json | 87 ++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 resources/definitions/bq_witbox.def.json diff --git a/resources/definitions/bq_witbox.def.json b/resources/definitions/bq_witbox.def.json new file mode 100644 index 0000000000..dfa8eb5712 --- /dev/null +++ b/resources/definitions/bq_witbox.def.json @@ -0,0 +1,87 @@ +{ + "id": "bq_witbox", + "version": 2, + "name": "BQ Witbox", + "inherits": "fdmprinter", + "metadata": { + "author": "BQ", + "manufacturer": "BQ", + "category": "Other", + "file_formats": "text/x-gcode", + "platform": "bq_witbox_platform.stl" + }, + "settings": { + "machine_start_gcode": { + "value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG90 ;set to absolute positioning\nG1 Z200 ;move the platform to the bottom\nG28 X0 Y0 ;move to the X/Y origin (Home)\nM84 ;turn off steppers\n; -- end of END GCODE --" + }, + "machine_width": { + "value": 297 + }, + "machine_depth": { + "value": 210 + }, + "machine_height": { + "value": 200 + }, + "machine_heated_bed": { + "value": false + }, + "machine_center_is_zero": { + "value": false + }, + "machine_gcode_flavor": { + "value": "RepRap" + }, + "machine_platform_offset": { + "value": [0, -145, -38] + }, + "layer_height": { + "value": 0.2 + }, + "layer_height_0": { + "value": 0.2 + }, + "wall_thickness": { + "value": 1 + }, + "top_bottom_thickness": { + "value": 1 + }, + "bottom_thickness": { + "value": 1 + }, + "material_print_temperature": { + "value": 220 + }, + "material_bed_temperature": { + "value": 0 + }, + "material_diameter": { + "value": 1.75 + }, + "speed_print": { + "value": 40 + }, + "speed_infill": { + "value": 40 + }, + "speed_wall": { + "value": 35 + }, + "speed_topbottom": { + "value": 35 + }, + "speed_travel": { + "value": 120 + }, + "speed_layer_0": { + "value": 20 + }, + "support_enable": { + "value": true + } + } +} \ No newline at end of file From ffcfba2caa87b120af44c54721c5ffda3ef491c3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 17 May 2016 14:46:51 +0200 Subject: [PATCH 123/705] Cura now handles saving of instances & stacks This is done because Cura has a fundamentally different strategy for this than Uranium. CURA-1278 --- cura/CuraApplication.py | 59 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 5620d039c9..39a25c34ad 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -15,7 +15,7 @@ from UM.Mesh.ReadMeshJob import ReadMeshJob from UM.Logger import Logger from UM.Preferences import Preferences from UM.JobQueue import JobQueue - +from UM.SaveFile import SaveFile from UM.Scene.Selection import Selection from UM.Scene.GroupDecorator import GroupDecorator @@ -25,6 +25,7 @@ from UM.Operations.GroupedOperation import GroupedOperation from UM.Operations.SetTransformOperation import SetTransformOperation from UM.Settings.SettingDefinition import SettingDefinition +from UM.Settings.ContainerRegistry import ContainerRegistry from UM.i18n import i18nCatalog @@ -47,6 +48,7 @@ import sys import os.path import numpy import copy +import urllib numpy.seterr(all="ignore") #WORKAROUND: GITHUB-88 GITHUB-385 GITHUB-612 @@ -67,6 +69,12 @@ class CuraApplication(QtApplication): class ResourceTypes: QmlFiles = Resources.UserType + 1 Firmware = Resources.UserType + 2 + QualityInstanceContainer = Resources.UserType + 3 + MaterialInstanceContainer = Resources.UserType + 4 + VariantInstanceContainer = Resources.UserType + 5 + UserInstanceContainer = Resources.UserType + 6 + MachineStack = Resources.UserType + 7 + Q_ENUMS(ResourceTypes) def __init__(self): @@ -110,6 +118,23 @@ class CuraApplication(QtApplication): Resources.addType(self.ResourceTypes.QmlFiles, "qml") Resources.addType(self.ResourceTypes.Firmware, "firmware") + SettingDefinition.addSupportedProperty("global_only", "bool") + + ## Add the 4 types of profiles to storage. + Resources.addStorageType(self.ResourceTypes.QualityInstanceContainer, "quality") + Resources.addStorageType(self.ResourceTypes.VariantInstanceContainer, "variants") + Resources.addStorageType(self.ResourceTypes.MaterialInstanceContainer, "materials") + Resources.addStorageType(self.ResourceTypes.UserInstanceContainer, "user") + Resources.addStorageType(self.ResourceTypes.MachineStack, "machine_instances") + + ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.QualityInstanceContainer) + ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.VariantInstanceContainer) + ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MaterialInstanceContainer) + ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.UserInstanceContainer) + ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MachineStack) + + ContainerRegistry.getInstance().load() + Preferences.getInstance().addPreference("cura/active_mode", "simple") Preferences.getInstance().addPreference("cura/recent_files", "") Preferences.getInstance().addPreference("cura/categories_expanded", "") @@ -152,6 +177,8 @@ class CuraApplication(QtApplication): JobQueue.getInstance().jobFinished.connect(self._onJobFinished) + self.applicationShuttingDown.connect(self._onExit) + self._recent_files = [] files = Preferences.getInstance().getValue("cura/recent_files").split(";") for f in files: @@ -160,6 +187,34 @@ class CuraApplication(QtApplication): self._recent_files.append(QUrl.fromLocalFile(f)) + ## Cura has multiple locations where instance containers need to be saved, so we need to handle this differently. + def _onExit(self): + for instance in ContainerRegistry.getInstance().findInstanceContainers(): + data = instance.serialize() + file_name = urllib.parse.quote_plus(instance.getId()) + ".inst.cfg" + instance_type = instance.getMetaDataEntry("type") + path = None + if instance_type == "material": + path = Resources.getStoragePath(self.ResourceTypes.MaterialInstanceContainer, file_name) + elif instance_type == "quality": + path = Resources.getStoragePath(self.ResourceTypes.QualityInstanceContainer, file_name) + elif instance_type == "user": + path = Resources.getStoragePath(self.ResourceTypes.UserInstanceContainer, file_name) + elif instance_type == "variant": + path = Resources.getStoragePath(self.ResourceTypes.VariantInstanceContainer, file_name) + + if path: + with SaveFile(path, "wt", -1, "utf-8") as f: + f.write(data) + + for stack in ContainerRegistry.getInstance().findContainerStacks(): + data = stack.serialize() + file_name = urllib.parse.quote_plus(stack.getId()) + ".stack.cfg" + path = Resources.getStoragePath(self.ResourceTypes.MachineStack, file_name) + with SaveFile(path, "wt", -1, "utf-8") as f: + f.write(data) + + @pyqtSlot(result = QUrl) def getDefaultPath(self): return QUrl.fromLocalFile(os.path.expanduser("~/")) @@ -195,8 +250,6 @@ class CuraApplication(QtApplication): self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Setting up scene...")) - SettingDefinition.addSupportedProperty("global_only", "bool") - controller = self.getController() controller.setActiveView("SolidView") From c4c6be7c34e4d95129fb0e4645a8642b3bbe630c Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 17 May 2016 14:56:05 +0200 Subject: [PATCH 124/705] Improve code legibility CURA-1543 --- cura/CuraApplication.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 28a19a7718..de922d1984 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -557,11 +557,7 @@ class CuraApplication(QtApplication): group_node.setCenterPosition(center) # Move selected nodes into the group-node - op = GroupedOperation() - nodes = Selection.getAllSelectedObjects() - for node in nodes: - op.addOperation(SetParentOperation(node, group_node)) - op.push() + Selection.applyOperation(SetParentOperation, group_node) # Deselect individual nodes and select the group-node instead for node in group_node.getChildren(): @@ -570,13 +566,13 @@ class CuraApplication(QtApplication): @pyqtSlot() def ungroupSelected(self): - selected_objects = Selection.getAllSelectedObjects()[:] # clone the list + selected_objects = Selection.getAllSelectedObjects().copy() for node in selected_objects: if node.callDecoration("isGroup"): op = GroupedOperation() group_parent = node.getParent() - children = node.getChildren()[:] # clone the list + children = node.getChildren().copy() for child in children: # Set the parent of the children to the parent of the group-node op.addOperation(SetParentOperation(child, group_parent)) From f66f0658d9bd7305cdcb805dea7fdced02c78554 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 17 May 2016 15:45:21 +0200 Subject: [PATCH 125/705] Fixed mistakes in the definitions CURA-1278 --- resources/definitions/bq_hephestos.def.json | 150 ++++++------- resources/definitions/bq_hephestos_2.def.json | 199 +++++++++--------- .../definitions/bq_hephestos_xl.def.json | 151 ++++++------- resources/definitions/bq_witbox.def.json | 150 ++++++------- 4 files changed, 336 insertions(+), 314 deletions(-) diff --git a/resources/definitions/bq_hephestos.def.json b/resources/definitions/bq_hephestos.def.json index 9958ef2b86..3b5b68c021 100644 --- a/resources/definitions/bq_hephestos.def.json +++ b/resources/definitions/bq_hephestos.def.json @@ -12,78 +12,84 @@ "platform": "bq_hephestos_platform.stl" }, - "settings": { - "machine_start_gcode": { - "value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" - }, - "machine_end_gcode": { - "value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" - }, - "machine_width": { - "value": 215 - }, - "machine_depth": { - "value": 210 - }, - "machine_height": { - "value": 180 - }, - "machine_heated_bed": { - "value": false - }, - "machine_center_is_zero": { - "value": false - }, - "machine_gcode_flavor": { - "value": "RepRap" - }, - "machine_platform_offset": { - "value": [0, -82, 0] - }, - "layer_height": { - "value": 0.2 - }, - "layer_height_0": { - "value": 0.2 - }, - "wall_thickness": { - "value": 1.0 - }, - "top_bottom_thickness": { - "value": 1.0 - }, - "bottom_thickness": { - "value": 1.0 - }, - "material_print_temperature": { - "value": 220 - }, - "material_bed_temperature": { - "value": 0 - }, - "material_diameter": { - "value": 1.75 - }, - "speed_print": { - "value": 40.0 - }, - "speed_infill": { - "value": 40.0 - }, - "speed_wall": { - "value": 35.0 - }, - "speed_topbottom": { - "value": 35.0 - }, - "speed_travel": { - "value": 120.0 - }, - "speed_layer_0": { - "value": 20.0 - }, - "support_enable": { - "value": true + "overrides": { + "settings": { + "machine_start_gcode": { + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "default_value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" + }, + "machine_width": { + "value": 215 + }, + "machine_depth": { + "value": 210 + }, + "machine_height": { + "value": 180 + }, + "machine_heated_bed": { + "value": false + }, + "machine_center_is_zero": { + "value": false + }, + "machine_gcode_flavor": { + "value": "RepRap" + }, + "machine_platform_offset": { + "value": [ + 0, + -82, + 0 + ] + }, + "layer_height": { + "value": 0.2 + }, + "layer_height_0": { + "value": 0.2 + }, + "wall_thickness": { + "value": 1.0 + }, + "top_bottom_thickness": { + "value": 1.0 + }, + "bottom_thickness": { + "value": 1.0 + }, + "material_print_temperature": { + "value": 220 + }, + "material_bed_temperature": { + "value": 0 + }, + "material_diameter": { + "value": 1.75 + }, + "speed_print": { + "value": 40.0 + }, + "speed_infill": { + "value": 40.0 + }, + "speed_wall": { + "value": 35.0 + }, + "speed_topbottom": { + "value": 35.0 + }, + "speed_travel": { + "value": 120.0 + }, + "speed_layer_0": { + "value": 20.0 + }, + "support_enable": { + "value": true + } } } } \ No newline at end of file diff --git a/resources/definitions/bq_hephestos_2.def.json b/resources/definitions/bq_hephestos_2.def.json index 2e084518ba..3e9b640586 100644 --- a/resources/definitions/bq_hephestos_2.def.json +++ b/resources/definitions/bq_hephestos_2.def.json @@ -14,104 +14,109 @@ "author": "BQ", "platform": "bq_hephestos_2_platform.stl", "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - "settings": { - "machine_start_gcode": { - "value": "; -- START GCODE --\nM800 ; Custom GCODE to fire start print procedure\n; -- end of START GCODE --" - }, - "machine_end_gcode": { - "value": "; -- END GCODE --\nM801 ; Custom GCODE to fire end print procedure\n; -- end of END GCODE --" - }, - "machine_width": { - "value": 210 - }, - "machine_depth": { - "value": 297 - }, - "machine_height": { - "value": 220 - }, - "machine_heated_bed": { - "value": false - }, - "machine_center_is_zero": { - "value": false - }, - "machine_gcode_flavor": { - "value": "RepRap" - }, - "machine_platform_offset": { - "value": [6, 1320, 0] - }, - "material_print_temperature": { - "value": 210.0 - }, - "material_bed_temperature": { - "value": 0 - }, - "material_diameter": { - "value": 1.75 - }, - "layer_height": { - "value": 0.2 - }, - "layer_height_0": { - "value": 0.2 - }, - "wall_line_count": { - "value": 3 - }, - "wall_thickness": { - "value": 1.2 - }, - "top_bottom_thickness": { - "value": 1.2 - }, - "infill_sparse_density": { - "value": 20.0 - }, - "infill_overlap": { - "value": 15.0 - }, - "speed_print": { - "value": 60.0 - }, - "speed_travel": { - "value": 160.0 - }, - "speed_layer_0": { - "value": 30.0 - }, - "speed_wall_x": { - "value": 35.0 - }, - "speed_wall_0": { - "value": 30.0 - }, - "speed_infill": { - "value": 80.0 - }, - "speed_topbottom": { - "value": 35.0 - }, - "skirt_speed": { - "value": 35.0 - }, - "skirt_line_count": { - "value": 4 - }, - "skirt_minimal_length": { - "value": 30.0 - }, - "skirt_gap": { - "value": 6.0 - }, - "cool_fan_full_at_height": { - "value": 0.4 - }, - "support_enable": { - "value": false + "overrides": { + "settings": { + "machine_start_gcode": { + "default_value": "; -- START GCODE --\nM800 ; Custom GCODE to fire start print procedure\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "default_value": "; -- END GCODE --\nM801 ; Custom GCODE to fire end print procedure\n; -- end of END GCODE --" + }, + "machine_width": { + "value": 210 + }, + "machine_depth": { + "value": 297 + }, + "machine_height": { + "value": 220 + }, + "machine_heated_bed": { + "value": false + }, + "machine_center_is_zero": { + "value": false + }, + "machine_gcode_flavor": { + "value": "RepRap" + }, + "machine_platform_offset": { + "value": [ + 6, + 1320, + 0 + ] + }, + "material_print_temperature": { + "value": 210.0 + }, + "material_bed_temperature": { + "value": 0 + }, + "material_diameter": { + "value": 1.75 + }, + "layer_height": { + "value": 0.2 + }, + "layer_height_0": { + "value": 0.2 + }, + "wall_line_count": { + "value": 3 + }, + "wall_thickness": { + "value": 1.2 + }, + "top_bottom_thickness": { + "value": 1.2 + }, + "infill_sparse_density": { + "value": 20.0 + }, + "infill_overlap": { + "value": 15.0 + }, + "speed_print": { + "value": 60.0 + }, + "speed_travel": { + "value": 160.0 + }, + "speed_layer_0": { + "value": 30.0 + }, + "speed_wall_x": { + "value": 35.0 + }, + "speed_wall_0": { + "value": 30.0 + }, + "speed_infill": { + "value": 80.0 + }, + "speed_topbottom": { + "value": 35.0 + }, + "skirt_speed": { + "value": 35.0 + }, + "skirt_line_count": { + "value": 4 + }, + "skirt_minimal_length": { + "value": 30.0 + }, + "skirt_gap": { + "value": 6.0 + }, + "cool_fan_full_at_height": { + "value": 0.4 + }, + "support_enable": { + "value": false + } } } } diff --git a/resources/definitions/bq_hephestos_xl.def.json b/resources/definitions/bq_hephestos_xl.def.json index 0d4bc13ea1..d810c49ea5 100644 --- a/resources/definitions/bq_hephestos_xl.def.json +++ b/resources/definitions/bq_hephestos_xl.def.json @@ -10,79 +10,84 @@ "file_formats": "text/x-code", "platform": "bq_hephestos_platform.stl" }, - - "settings": { - "machine_start_gcode": { - "value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" - }, - "machine_end_gcode": { - "value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" - }, - "machine_width": { - "value": 200 - }, - "machine_depth": { - "value": 300 - }, - "machine_height": { - "value": 180 - }, - "machine_heated_bed": { - "value": false - }, - "machine_center_is_zero": { - "value": false - }, - "machine_gcode_flavor": { - "value": "RepRap" - }, - "machine_platform_offset": { - "value": [0, -82, 0] - }, - "layer_height": { - "value": 0.2 - }, - "layer_height_0": { - "value": 0.2 - }, - "wall_thickness": { - "value": 1.0 - }, - "top_bottom_thickness": { - "value": 1.0 - }, - "bottom_thickness": { - "value": 1.0 - }, - "material_print_temperature": { - "value": 220 - }, - "material_bed_temperature": { - "value": 0 - }, - "material_diameter": { - "value": 1.75 - }, - "speed_print": { - "value": 40.0 - }, - "speed_infill": { - "value": 40.0 - }, - "speed_wall": { - "value": 35.0 - }, - "speed_topbottom": { - "value": 35.0 - }, - "speed_travel": { - "value": 120.0 - }, - "speed_layer_0": { - "value": 20.0 - }, - "support_enable": { - "value": true + "overrides": { + "settings": { + "machine_start_gcode": { + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "default_value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" + }, + "machine_width": { + "value": 200 + }, + "machine_depth": { + "value": 300 + }, + "machine_height": { + "value": 180 + }, + "machine_heated_bed": { + "value": false + }, + "machine_center_is_zero": { + "value": false + }, + "machine_gcode_flavor": { + "value": "RepRap" + }, + "machine_platform_offset": { + "value": [ + 0, + -82, + 0 + ] + }, + "layer_height": { + "value": 0.2 + }, + "layer_height_0": { + "value": 0.2 + }, + "wall_thickness": { + "value": 1.0 + }, + "top_bottom_thickness": { + "value": 1.0 + }, + "bottom_thickness": { + "value": 1.0 + }, + "material_print_temperature": { + "value": 220 + }, + "material_bed_temperature": { + "value": 0 + }, + "material_diameter": { + "value": 1.75 + }, + "speed_print": { + "value": 40.0 + }, + "speed_infill": { + "value": 40.0 + }, + "speed_wall": { + "value": 35.0 + }, + "speed_topbottom": { + "value": 35.0 + }, + "speed_travel": { + "value": 120.0 + }, + "speed_layer_0": { + "value": 20.0 + }, + "support_enable": { + "value": true + } } } } \ No newline at end of file diff --git a/resources/definitions/bq_witbox.def.json b/resources/definitions/bq_witbox.def.json index dfa8eb5712..15ab9318ef 100644 --- a/resources/definitions/bq_witbox.def.json +++ b/resources/definitions/bq_witbox.def.json @@ -10,78 +10,84 @@ "file_formats": "text/x-gcode", "platform": "bq_witbox_platform.stl" }, - "settings": { - "machine_start_gcode": { - "value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" - }, - "machine_end_gcode": { - "value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG90 ;set to absolute positioning\nG1 Z200 ;move the platform to the bottom\nG28 X0 Y0 ;move to the X/Y origin (Home)\nM84 ;turn off steppers\n; -- end of END GCODE --" - }, - "machine_width": { - "value": 297 - }, - "machine_depth": { - "value": 210 - }, - "machine_height": { - "value": 200 - }, - "machine_heated_bed": { - "value": false - }, - "machine_center_is_zero": { - "value": false - }, - "machine_gcode_flavor": { - "value": "RepRap" - }, - "machine_platform_offset": { - "value": [0, -145, -38] - }, - "layer_height": { - "value": 0.2 - }, - "layer_height_0": { - "value": 0.2 - }, - "wall_thickness": { - "value": 1 - }, - "top_bottom_thickness": { - "value": 1 - }, - "bottom_thickness": { - "value": 1 - }, - "material_print_temperature": { - "value": 220 - }, - "material_bed_temperature": { - "value": 0 - }, - "material_diameter": { - "value": 1.75 - }, - "speed_print": { - "value": 40 - }, - "speed_infill": { - "value": 40 - }, - "speed_wall": { - "value": 35 - }, - "speed_topbottom": { - "value": 35 - }, - "speed_travel": { - "value": 120 - }, - "speed_layer_0": { - "value": 20 - }, - "support_enable": { - "value": true + "overrides": { + "settings": { + "machine_start_gcode": { + "value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG90 ;set to absolute positioning\nG1 Z200 ;move the platform to the bottom\nG28 X0 Y0 ;move to the X/Y origin (Home)\nM84 ;turn off steppers\n; -- end of END GCODE --" + }, + "machine_width": { + "value": 297 + }, + "machine_depth": { + "value": 210 + }, + "machine_height": { + "value": 200 + }, + "machine_heated_bed": { + "value": false + }, + "machine_center_is_zero": { + "value": false + }, + "machine_gcode_flavor": { + "value": "RepRap" + }, + "machine_platform_offset": { + "value": [ + 0, + -145, + -38 + ] + }, + "layer_height": { + "value": 0.2 + }, + "layer_height_0": { + "value": 0.2 + }, + "wall_thickness": { + "value": 1 + }, + "top_bottom_thickness": { + "value": 1 + }, + "bottom_thickness": { + "value": 1 + }, + "material_print_temperature": { + "value": 220 + }, + "material_bed_temperature": { + "value": 0 + }, + "material_diameter": { + "value": 1.75 + }, + "speed_print": { + "value": 40 + }, + "speed_infill": { + "value": 40 + }, + "speed_wall": { + "value": 35 + }, + "speed_topbottom": { + "value": 35 + }, + "speed_travel": { + "value": 120 + }, + "speed_layer_0": { + "value": 20 + }, + "support_enable": { + "value": true + } } } } \ No newline at end of file From 5c1210dddf545aaa153c45d11791a61cf1892c6b Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 17 May 2016 16:39:10 +0200 Subject: [PATCH 126/705] Removed settings subobject in overrides CURA-1278 --- resources/definitions/bq_hephestos.def.json | 152 +++++++------ resources/definitions/bq_hephestos_2.def.json | 200 +++++++++--------- .../definitions/bq_hephestos_xl.def.json | 152 +++++++------ resources/definitions/bq_witbox.def.json | 153 +++++++------- 4 files changed, 325 insertions(+), 332 deletions(-) diff --git a/resources/definitions/bq_hephestos.def.json b/resources/definitions/bq_hephestos.def.json index 3b5b68c021..45bf520a14 100644 --- a/resources/definitions/bq_hephestos.def.json +++ b/resources/definitions/bq_hephestos.def.json @@ -13,83 +13,81 @@ }, "overrides": { - "settings": { - "machine_start_gcode": { - "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" - }, - "machine_end_gcode": { - "default_value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" - }, - "machine_width": { - "value": 215 - }, - "machine_depth": { - "value": 210 - }, - "machine_height": { - "value": 180 - }, - "machine_heated_bed": { - "value": false - }, - "machine_center_is_zero": { - "value": false - }, - "machine_gcode_flavor": { - "value": "RepRap" - }, - "machine_platform_offset": { - "value": [ - 0, - -82, - 0 - ] - }, - "layer_height": { - "value": 0.2 - }, - "layer_height_0": { - "value": 0.2 - }, - "wall_thickness": { - "value": 1.0 - }, - "top_bottom_thickness": { - "value": 1.0 - }, - "bottom_thickness": { - "value": 1.0 - }, - "material_print_temperature": { - "value": 220 - }, - "material_bed_temperature": { - "value": 0 - }, - "material_diameter": { - "value": 1.75 - }, - "speed_print": { - "value": 40.0 - }, - "speed_infill": { - "value": 40.0 - }, - "speed_wall": { - "value": 35.0 - }, - "speed_topbottom": { - "value": 35.0 - }, - "speed_travel": { - "value": 120.0 - }, - "speed_layer_0": { - "value": 20.0 - }, - "support_enable": { - "value": true - } + "machine_start_gcode": { + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "default_value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" + }, + "machine_width": { + "value": 215 + }, + "machine_depth": { + "value": 210 + }, + "machine_height": { + "value": 180 + }, + "machine_heated_bed": { + "value": false + }, + "machine_center_is_zero": { + "value": false + }, + "machine_gcode_flavor": { + "value": "RepRap" + }, + "machine_platform_offset": { + "value": [ + 0, + -82, + 0 + ] + }, + "layer_height": { + "value": 0.2 + }, + "layer_height_0": { + "value": 0.2 + }, + "wall_thickness": { + "value": 1.0 + }, + "top_bottom_thickness": { + "value": 1.0 + }, + "bottom_thickness": { + "value": 1.0 + }, + "material_print_temperature": { + "value": 220 + }, + "material_bed_temperature": { + "value": 0 + }, + "material_diameter": { + "value": 1.75 + }, + "speed_print": { + "value": 40.0 + }, + "speed_infill": { + "value": 40.0 + }, + "speed_wall": { + "value": 35.0 + }, + "speed_topbottom": { + "value": 35.0 + }, + "speed_travel": { + "value": 120.0 + }, + "speed_layer_0": { + "value": 20.0 + }, + "support_enable": { + "value": true } } } \ No newline at end of file diff --git a/resources/definitions/bq_hephestos_2.def.json b/resources/definitions/bq_hephestos_2.def.json index 3e9b640586..7f92e081ff 100644 --- a/resources/definitions/bq_hephestos_2.def.json +++ b/resources/definitions/bq_hephestos_2.def.json @@ -16,107 +16,105 @@ "file_formats": "text/x-gcode", "overrides": { - "settings": { - "machine_start_gcode": { - "default_value": "; -- START GCODE --\nM800 ; Custom GCODE to fire start print procedure\n; -- end of START GCODE --" - }, - "machine_end_gcode": { - "default_value": "; -- END GCODE --\nM801 ; Custom GCODE to fire end print procedure\n; -- end of END GCODE --" - }, - "machine_width": { - "value": 210 - }, - "machine_depth": { - "value": 297 - }, - "machine_height": { - "value": 220 - }, - "machine_heated_bed": { - "value": false - }, - "machine_center_is_zero": { - "value": false - }, - "machine_gcode_flavor": { - "value": "RepRap" - }, - "machine_platform_offset": { - "value": [ - 6, - 1320, - 0 - ] - }, - "material_print_temperature": { - "value": 210.0 - }, - "material_bed_temperature": { - "value": 0 - }, - "material_diameter": { - "value": 1.75 - }, - "layer_height": { - "value": 0.2 - }, - "layer_height_0": { - "value": 0.2 - }, - "wall_line_count": { - "value": 3 - }, - "wall_thickness": { - "value": 1.2 - }, - "top_bottom_thickness": { - "value": 1.2 - }, - "infill_sparse_density": { - "value": 20.0 - }, - "infill_overlap": { - "value": 15.0 - }, - "speed_print": { - "value": 60.0 - }, - "speed_travel": { - "value": 160.0 - }, - "speed_layer_0": { - "value": 30.0 - }, - "speed_wall_x": { - "value": 35.0 - }, - "speed_wall_0": { - "value": 30.0 - }, - "speed_infill": { - "value": 80.0 - }, - "speed_topbottom": { - "value": 35.0 - }, - "skirt_speed": { - "value": 35.0 - }, - "skirt_line_count": { - "value": 4 - }, - "skirt_minimal_length": { - "value": 30.0 - }, - "skirt_gap": { - "value": 6.0 - }, - "cool_fan_full_at_height": { - "value": 0.4 - }, - "support_enable": { - "value": false - } + "machine_start_gcode": { + "default_value": "; -- START GCODE --\nM800 ; Custom GCODE to fire start print procedure\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "default_value": "; -- END GCODE --\nM801 ; Custom GCODE to fire end print procedure\n; -- end of END GCODE --" + }, + "machine_width": { + "value": 210 + }, + "machine_depth": { + "value": 297 + }, + "machine_height": { + "value": 220 + }, + "machine_heated_bed": { + "value": false + }, + "machine_center_is_zero": { + "value": false + }, + "machine_gcode_flavor": { + "value": "RepRap" + }, + "machine_platform_offset": { + "value": [ + 6, + 1320, + 0 + ] + }, + "material_print_temperature": { + "value": 210.0 + }, + "material_bed_temperature": { + "value": 0 + }, + "material_diameter": { + "value": 1.75 + }, + "layer_height": { + "value": 0.2 + }, + "layer_height_0": { + "value": 0.2 + }, + "wall_line_count": { + "value": 3 + }, + "wall_thickness": { + "value": 1.2 + }, + "top_bottom_thickness": { + "value": 1.2 + }, + "infill_sparse_density": { + "value": 20.0 + }, + "infill_overlap": { + "value": 15.0 + }, + "speed_print": { + "value": 60.0 + }, + "speed_travel": { + "value": 160.0 + }, + "speed_layer_0": { + "value": 30.0 + }, + "speed_wall_x": { + "value": 35.0 + }, + "speed_wall_0": { + "value": 30.0 + }, + "speed_infill": { + "value": 80.0 + }, + "speed_topbottom": { + "value": 35.0 + }, + "skirt_speed": { + "value": 35.0 + }, + "skirt_line_count": { + "value": 4 + }, + "skirt_minimal_length": { + "value": 30.0 + }, + "skirt_gap": { + "value": 6.0 + }, + "cool_fan_full_at_height": { + "value": 0.4 + }, + "support_enable": { + "value": false } } } diff --git a/resources/definitions/bq_hephestos_xl.def.json b/resources/definitions/bq_hephestos_xl.def.json index d810c49ea5..a0d8caa62e 100644 --- a/resources/definitions/bq_hephestos_xl.def.json +++ b/resources/definitions/bq_hephestos_xl.def.json @@ -11,83 +11,81 @@ "platform": "bq_hephestos_platform.stl" }, "overrides": { - "settings": { - "machine_start_gcode": { - "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" - }, - "machine_end_gcode": { - "default_value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" - }, - "machine_width": { - "value": 200 - }, - "machine_depth": { - "value": 300 - }, - "machine_height": { - "value": 180 - }, - "machine_heated_bed": { - "value": false - }, - "machine_center_is_zero": { - "value": false - }, - "machine_gcode_flavor": { - "value": "RepRap" - }, - "machine_platform_offset": { - "value": [ - 0, - -82, - 0 - ] - }, - "layer_height": { - "value": 0.2 - }, - "layer_height_0": { - "value": 0.2 - }, - "wall_thickness": { - "value": 1.0 - }, - "top_bottom_thickness": { - "value": 1.0 - }, - "bottom_thickness": { - "value": 1.0 - }, - "material_print_temperature": { - "value": 220 - }, - "material_bed_temperature": { - "value": 0 - }, - "material_diameter": { - "value": 1.75 - }, - "speed_print": { - "value": 40.0 - }, - "speed_infill": { - "value": 40.0 - }, - "speed_wall": { - "value": 35.0 - }, - "speed_topbottom": { - "value": 35.0 - }, - "speed_travel": { - "value": 120.0 - }, - "speed_layer_0": { - "value": 20.0 - }, - "support_enable": { - "value": true - } + "machine_start_gcode": { + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "default_value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" + }, + "machine_width": { + "value": 200 + }, + "machine_depth": { + "value": 300 + }, + "machine_height": { + "value": 180 + }, + "machine_heated_bed": { + "value": false + }, + "machine_center_is_zero": { + "value": false + }, + "machine_gcode_flavor": { + "value": "RepRap" + }, + "machine_platform_offset": { + "value": [ + 0, + -82, + 0 + ] + }, + "layer_height": { + "value": 0.2 + }, + "layer_height_0": { + "value": 0.2 + }, + "wall_thickness": { + "value": 1.0 + }, + "top_bottom_thickness": { + "value": 1.0 + }, + "bottom_thickness": { + "value": 1.0 + }, + "material_print_temperature": { + "value": 220 + }, + "material_bed_temperature": { + "value": 0 + }, + "material_diameter": { + "value": 1.75 + }, + "speed_print": { + "value": 40.0 + }, + "speed_infill": { + "value": 40.0 + }, + "speed_wall": { + "value": 35.0 + }, + "speed_topbottom": { + "value": 35.0 + }, + "speed_travel": { + "value": 120.0 + }, + "speed_layer_0": { + "value": 20.0 + }, + "support_enable": { + "value": true } } } \ No newline at end of file diff --git a/resources/definitions/bq_witbox.def.json b/resources/definitions/bq_witbox.def.json index 15ab9318ef..e0d8bf774e 100644 --- a/resources/definitions/bq_witbox.def.json +++ b/resources/definitions/bq_witbox.def.json @@ -11,83 +11,82 @@ "platform": "bq_witbox_platform.stl" }, "overrides": { - "settings": { - "machine_start_gcode": { - "value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" - }, - "machine_end_gcode": { - "value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG90 ;set to absolute positioning\nG1 Z200 ;move the platform to the bottom\nG28 X0 Y0 ;move to the X/Y origin (Home)\nM84 ;turn off steppers\n; -- end of END GCODE --" - }, - "machine_width": { - "value": 297 - }, - "machine_depth": { - "value": 210 - }, - "machine_height": { - "value": 200 - }, - "machine_heated_bed": { - "value": false - }, - "machine_center_is_zero": { - "value": false - }, - "machine_gcode_flavor": { - "value": "RepRap" - }, - "machine_platform_offset": { - "value": [ - 0, - -145, - -38 - ] - }, - "layer_height": { - "value": 0.2 - }, - "layer_height_0": { - "value": 0.2 - }, - "wall_thickness": { - "value": 1 - }, - "top_bottom_thickness": { - "value": 1 - }, - "bottom_thickness": { - "value": 1 - }, - "material_print_temperature": { - "value": 220 - }, - "material_bed_temperature": { - "value": 0 - }, - "material_diameter": { - "value": 1.75 - }, - "speed_print": { - "value": 40 - }, - "speed_infill": { - "value": 40 - }, - "speed_wall": { - "value": 35 - }, - "speed_topbottom": { - "value": 35 - }, - "speed_travel": { - "value": 120 - }, - "speed_layer_0": { - "value": 20 - }, - "support_enable": { - "value": true - } + "machine_start_gcode": { + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "default_value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG90 ;set to absolute positioning\nG1 Z200 ;move the platform to the bottom\nG28 X0 Y0 ;move to the X/Y origin (Home)\nM84 ;turn off steppers\n; -- end of END GCODE --" + }, + "machine_width": { + "value": 297 + }, + "machine_depth": { + "value": 210 + }, + "machine_height": { + "value": 200 + }, + "machine_heated_bed": { + "value": false + }, + "machine_center_is_zero": { + "value": false + }, + "machine_gcode_flavor": { + "value": "RepRap" + }, + "machine_platform_offset": { + "value": [ + 0, + -145, + -38 + ] + }, + "layer_height": { + "value": 0.2 + }, + "layer_height_0": { + "value": 0.2 + }, + "wall_thickness": { + "value": 1 + }, + "top_bottom_thickness": { + "value": 1 + }, + "bottom_thickness": { + "value": 1 + }, + "material_print_temperature": { + "value": 220 + }, + "material_bed_temperature": { + "value": 0 + }, + "material_diameter": { + "value": 1.75 + }, + "speed_print": { + "value": 40 + }, + "speed_infill": { + "value": 40 + }, + "speed_wall": { + "value": 35 + }, + "speed_topbottom": { + "value": 35 + }, + "speed_travel": { + "value": 120 + }, + "speed_layer_0": { + "value": 20 + }, + "support_enable": { + "value": true } + } } \ No newline at end of file From a2862d8c24001c419ab834a9b5089d871d97946f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 17 May 2016 16:49:59 +0200 Subject: [PATCH 127/705] Moved offset to meta-data CURA-1278 --- resources/definitions/bq_hephestos.def.json | 16 ++++++++-------- resources/definitions/bq_hephestos_2.def.json | 14 +++++++------- resources/definitions/bq_hephestos_xl.def.json | 16 ++++++++-------- resources/definitions/bq_witbox.def.json | 16 ++++++++-------- 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/resources/definitions/bq_hephestos.def.json b/resources/definitions/bq_hephestos.def.json index 45bf520a14..57fa85ab89 100644 --- a/resources/definitions/bq_hephestos.def.json +++ b/resources/definitions/bq_hephestos.def.json @@ -9,7 +9,14 @@ "manufacturer": "BQ", "category": "Other", "file_formats": "text/x-gcode", - "platform": "bq_hephestos_platform.stl" + "platform": "bq_hephestos_platform.stl", + "platform_offset": { + "value": [ + 0, + -82, + 0 + ] + } }, "overrides": { @@ -37,13 +44,6 @@ "machine_gcode_flavor": { "value": "RepRap" }, - "machine_platform_offset": { - "value": [ - 0, - -82, - 0 - ] - }, "layer_height": { "value": 0.2 }, diff --git a/resources/definitions/bq_hephestos_2.def.json b/resources/definitions/bq_hephestos_2.def.json index 7f92e081ff..dba849ac7e 100644 --- a/resources/definitions/bq_hephestos_2.def.json +++ b/resources/definitions/bq_hephestos_2.def.json @@ -8,6 +8,13 @@ "manufacturer": "BQ", "category": "Other", "platform": "bq_hephestos_2_platform.stl", + "platform_offset": { + "value": [ + 6, + 1320, + 0 + ] + }, "file_formats": "text/x-gcode" }, "manufacturer": "BQ", @@ -40,13 +47,6 @@ "machine_gcode_flavor": { "value": "RepRap" }, - "machine_platform_offset": { - "value": [ - 6, - 1320, - 0 - ] - }, "material_print_temperature": { "value": 210.0 }, diff --git a/resources/definitions/bq_hephestos_xl.def.json b/resources/definitions/bq_hephestos_xl.def.json index a0d8caa62e..6d4c7fdd52 100644 --- a/resources/definitions/bq_hephestos_xl.def.json +++ b/resources/definitions/bq_hephestos_xl.def.json @@ -8,7 +8,14 @@ "author": "BQ", "category": "Other", "file_formats": "text/x-code", - "platform": "bq_hephestos_platform.stl" + "platform": "bq_hephestos_platform.stl", + "platform_offset": { + "value": [ + 0, + -82, + 0 + ] + } }, "overrides": { "machine_start_gcode": { @@ -35,13 +42,6 @@ "machine_gcode_flavor": { "value": "RepRap" }, - "machine_platform_offset": { - "value": [ - 0, - -82, - 0 - ] - }, "layer_height": { "value": 0.2 }, diff --git a/resources/definitions/bq_witbox.def.json b/resources/definitions/bq_witbox.def.json index e0d8bf774e..d9529cdae6 100644 --- a/resources/definitions/bq_witbox.def.json +++ b/resources/definitions/bq_witbox.def.json @@ -8,7 +8,14 @@ "manufacturer": "BQ", "category": "Other", "file_formats": "text/x-gcode", - "platform": "bq_witbox_platform.stl" + "platform": "bq_witbox_platform.stl", + "platform_offset": { + "value": [ + 0, + -145, + -38 + ] + } }, "overrides": { "machine_start_gcode": { @@ -35,13 +42,6 @@ "machine_gcode_flavor": { "value": "RepRap" }, - "machine_platform_offset": { - "value": [ - 0, - -145, - -38 - ] - }, "layer_height": { "value": 0.2 }, From 20c7ce404de14e838f6418bcaad12ba548aa2734 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 13:43:34 +0200 Subject: [PATCH 128/705] Add definition for BQ Witbox 2 Contributes to issue CURA-1278. --- resources/definitions/bq_witbox_2.def.json | 113 +++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 resources/definitions/bq_witbox_2.def.json diff --git a/resources/definitions/bq_witbox_2.def.json b/resources/definitions/bq_witbox_2.def.json new file mode 100644 index 0000000000..43e6968aba --- /dev/null +++ b/resources/definitions/bq_witbox_2.def.json @@ -0,0 +1,113 @@ +{ + "id": "bq_witbox_2", + "version": 2, + "name": "BQ Witbox 2", + "inherits": "fdmprinter", + "metadata": + { + "author": "BQ", + "manufacturer": "BQ", + "category": "Other", + "file_formats": "text/x-gcode", + "platform": "bq_witbox_platform.stl" + }, + + "settings": { + "machine_start_gcode": { + "value": "; -- START GCODE --\nM800 ; Custom GCODE to fire start print procedure\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "value": "; -- END GCODE --\nM801 ; Custom GCODE to fire end print procedure\n; -- end of END GCODE --" + }, + "machine_width": { + "value": 297 + }, + "machine_depth": { + "value": 210 + }, + "machine_height": { + "value": 200 + }, + "machine_heated_bed": { + "value": false + }, + "machine_center_is_zero": { + "value": false + }, + "machine_gcode_flavor": { + "value": "RepRap" + }, + "machine_platform_offset": { + "value": [0, -145, -38] + }, + "material_print_temperature": { + "value": 210.0 + }, + "material_bed_temperature": { + "value": 0 + }, + "material_diameter": { + "value": 1.75 + }, + "layer_height": { + "value": 0.2 + }, + "layer_height_0": { + "value": 0.2 + }, + "wall_line_count": { + "value": 3 + }, + "wall_thickness": { + "value": 1.2 + }, + "top_bottom_thickness": { + "value": 1.2 + }, + "infill_sparse_density": { + "value": 20.0 + }, + "infill_overlap": { + "value": 15.0 + }, + "speed_print": { + "value": 60.0 + }, + "speed_travel": { + "value": 160.0 + }, + "speed_layer_0": { + "value": 30.0 + }, + "speed_wall_x": { + "value": 35.0 + }, + "speed_wall_0": { + "value": 30.0 + }, + "speed_infill": { + "value": 80.0 + }, + "speed_topbottom": { + "value": 35.0 + }, + "skirt_speed": { + "value": 35.0 + }, + "skirt_line_count": { + "value": 4 + }, + "skirt_minimal_length": { + "value": 30.0 + }, + "skirt_gap": { + "value": 6.0 + }, + "cool_fan_full_at_height": { + "value": 0.4 + }, + "support_enable": { + "value": false + } + } +} \ No newline at end of file From f0e99122c7f98ca700c6965ee81d5f945e00f3fc Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 13:57:07 +0200 Subject: [PATCH 129/705] Add definition for German RepRap Neo Contributes to issue CURA-1278. --- resources/definitions/grr_neo.def.json | 62 ++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 resources/definitions/grr_neo.def.json diff --git a/resources/definitions/grr_neo.def.json b/resources/definitions/grr_neo.def.json new file mode 100644 index 0000000000..710303383b --- /dev/null +++ b/resources/definitions/grr_neo.def.json @@ -0,0 +1,62 @@ +{ + "id": "grr_neo", + "version": 2, + "name": "German RepRap Neo", + "inherits": "fdmprinter", + "metadata": { + "author": "Simon Cor", + "manufacturer": "German RepRap", + "category": "Other", + "file_formats": "text/x-gcode", + "icon": "icon_ultimaker.png", + "platform": "grr_neo_platform.stl" + }, + + "overrides": { + "machine_width": { + "value": 150 + }, + "machine_height": { + "value": 150 + }, + "machine_depth": { + "value": 150 + }, + "machine_center_is_zero": { + "value": false + }, + "machine_nozzle_size": { + "value": 0.5 + }, + "machine_nozzle_heat_up_speed": { + "value": 2 + }, + "machine_nozzle_cool_down_speed": { + "value": 2 + }, + "machine_head_shape_min_x": { + "value": 75 + }, + "machine_head_shape_min_y": { + "value": 18 + }, + "machine_head_shape_max_x": { + "value": 18 + }, + "machine_head_shape_max_y": { + "value": 35 + }, + "machine_nozzle_gantry_distance": { + "value": 55 + }, + "machine_gcode_flavor": { + "value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." + }, + "machine_end_gcode": { + "value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" + } + } +} \ No newline at end of file From fea09482b58418c0699187ffd37c83cfde2a19b5 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 14:39:28 +0200 Subject: [PATCH 130/705] Translate definition for Innovo INVENTOR Contributes to issue CURA-1278. --- .../definitions/innovo_inventor.def.json | 103 ++++++++++++++++++ resources/machines/innovo-inventor.json | 44 -------- 2 files changed, 103 insertions(+), 44 deletions(-) create mode 100644 resources/definitions/innovo_inventor.def.json delete mode 100644 resources/machines/innovo-inventor.json diff --git a/resources/definitions/innovo_inventor.def.json b/resources/definitions/innovo_inventor.def.json new file mode 100644 index 0000000000..30e5a53094 --- /dev/null +++ b/resources/definitions/innovo_inventor.def.json @@ -0,0 +1,103 @@ +{ + "id": "innovo-inventor", + "version": 2, + "name": "Innovo INVENTOR", + "inherits": "fdmprinter", + "metadata": { + "author": "AR", + "manufacturer": "Innovo", + "category": "Other", + "file_formats": "text/x-gcode", + "platform": "inventor_platform.stl" + }, + "settings": { + "machine_width": { + "value": 340 + }, + "machine_height": { + "value": 290 + }, + "machine_depth": { + "value": 300 + }, + "machine_heated_bed": { + "value": true + }, + "machine_center_is_zero": { + "value": false + }, + "machine_nozzle_size": { + "value": 0.4 + }, + "machine_head_shape_min_x": { + "value": 43.7 + }, + "machine_head_shape_min_y": { + "value": 19.2 + }, + "machine_head_shape_max_x": { + "value": 43.7 + }, + "machine_head_shape_max_y": { + "value": 55 + }, + "machine_nozzle_gantry_distance": { + "value": 82.3 + }, + "machine_nozzle_offset_x_1": { + "value": 0 + }, + "machine_nozzle_offset_y_1": { + "value": 15 + }, + "machine_gcode_flavor": { + "value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "value": "G28 ; Home extruder\nM107 ; Turn off fan\nG90 ; Absolute positioning\nM82 ; Extruder in absolute mode\n{IF_BED}M190 S{BED}\n{IF_EXT0}M104 T0 S{TEMP0}\n{IF_EXT0}M109 T0 S{TEMP0}\n{IF_EXT1}M104 T1 S{TEMP1}\n{IF_EXT1}M109 T1 S{TEMP1}\nG32 S3 ; auto level\nG92 E0 ; Reset extruder position" + }, + "machine_end_gcode": { + "value": "M104 S0\nG91 ; relative positioning\nG1 E-2 F5000; retract 2mm\nG28 Z; move bed down\nG90 ; absolute positioning\nM84 ; disable motors" + }, + "machine_platform_offset": { + "value": [-180, -0.25, 160] + }, + "layer_height": { + "value": 0.15 + }, + "wall_thickness": { + "value": 0.8 + }, + "top_bottom_thickness": { + "value": 0.3 + }, + "material_print_temperature": { + "value": 215 + }, + "material_bed_temperature": { + "value": 60 + }, + "material_diameter": { + "value": 1.75 + }, + "speed_print": { + "value": 60 + }, + "speed_infill": { + "value": 100 + }, + "speed_topbottom": { + "value": 30 + }, + "speed_travel": { + "value": 150 + }, + "speed_layer_0": { + "value": 30.0, + "min_value": 0.1 + }, + "infill_overlap": { + "value": 10.0 + } + } +} \ No newline at end of file diff --git a/resources/machines/innovo-inventor.json b/resources/machines/innovo-inventor.json deleted file mode 100644 index a37143a8d7..0000000000 --- a/resources/machines/innovo-inventor.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "id": "innovo-inventor", - "version": 1, - "name": "Innovo INVENTOR", - "manufacturer": "Other", - "author": "AR", - "platform": "inventor_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "machine_settings": { - "machine_width": {"default": 340}, - "machine_height": {"default": 290}, - "machine_depth": {"default": 300}, - "machine_heated_bed": { "default": true}, - "machine_center_is_zero": {"default": false}, - "machine_nozzle_size": {"default": 0.4}, - "machine_head_shape_min_x": {"default": 43.7}, - "machine_head_shape_min_y": {"default": 19.2}, - "machine_head_shape_max_x": {"default": 43.7}, - "machine_head_shape_max_y": {"default": 55}, - "machine_nozzle_gantry_distance": {"default": 82.3}, - "machine_nozzle_offset_x_1": {"default": 0}, - "machine_nozzle_offset_y_1": {"default": 15}, - "machine_gcode_flavor": {"default": "RepRap (Marlin/Sprinter)"}, - "machine_start_gcode": {"default": "G28 ; Home extruder\nM107 ; Turn off fan\nG90 ; Absolute positioning\nM82 ; Extruder in absolute mode\n{IF_BED}M190 S{BED}\n{IF_EXT0}M104 T0 S{TEMP0}\n{IF_EXT0}M109 T0 S{TEMP0}\n{IF_EXT1}M104 T1 S{TEMP1}\n{IF_EXT1}M109 T1 S{TEMP1}\nG32 S3 ; auto level\nG92 E0 ; Reset extruder position"}, - "machine_end_gcode": {"default": "M104 S0\nG91 ; relative positioning\nG1 E-2 F5000; retract 2mm\nG28 Z; move bed down\nG90 ; absolute positioning\nM84 ; disable motors"}, - "machine_platform_offset": {"default": [-180, -0.25, 160]} - }, - "overrides": { - "layer_height": { "default": 0.15}, - "wall_thickness": { "default": 0.8}, - "top_bottom_thickness": { "default": 0.3, "visible": true}, - "material_print_temperature": { "default": 215, "visible": true}, - "material_bed_temperature": { "default": 60, "visible": true}, - "material_diameter": { "default": 1.75, "visible": true}, - "speed_print": { "default": 60.0, "visible": true}, - "speed_infill": { "default": 100.0, "visible": true }, - "speed_topbottom": { "default": 30.0, "visible": true }, - "speed_travel": { "default": 150.0, "visible": true }, - "speed_layer_0": { "min_value": 0.1, "default": 30.0, "visible": true }, - "infill_overlap": { "default": 10.0 } - } -} \ No newline at end of file From 8cf05fd2fc1f20cf924703041b97eb1f8b7d5465 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 14:40:22 +0200 Subject: [PATCH 131/705] Remove old machine definitions These have already been translated. I should've added these to their respective commits, I guess. Contributes to issue CURA-1278. --- resources/machines/bq_hephestos.json | 55 --------------------- resources/machines/bq_hephestos_2.json | 63 ------------------------- resources/machines/bq_hephestos_xl.json | 55 --------------------- resources/machines/bq_witbox.json | 55 --------------------- resources/machines/bq_witbox_2.json | 63 ------------------------- resources/machines/grr_neo.json | 37 --------------- 6 files changed, 328 deletions(-) delete mode 100644 resources/machines/bq_hephestos.json delete mode 100644 resources/machines/bq_hephestos_2.json delete mode 100644 resources/machines/bq_hephestos_xl.json delete mode 100644 resources/machines/bq_witbox.json delete mode 100644 resources/machines/bq_witbox_2.json delete mode 100644 resources/machines/grr_neo.json diff --git a/resources/machines/bq_hephestos.json b/resources/machines/bq_hephestos.json deleted file mode 100644 index e3aa354b75..0000000000 --- a/resources/machines/bq_hephestos.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "id": "bq_hephestos", - "version": 1, - "name": "BQ Prusa i3 Hephestos", - "manufacturer": "Other", - "author": "BQ", - "platform": "bq_hephestos_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "overrides": { - "machine_start_gcode": { - "default": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" - }, - "machine_end_gcode": { - "default": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" - }, - "machine_width": { - "default": 215 - }, - "machine_depth": { - "default": 210 - }, - "machine_height": { - "default": 180 - }, - "machine_heated_bed": { - "default": false - }, - "machine_center_is_zero": { - "default": false - }, - "machine_gcode_flavor": { - "default": "RepRap" - }, - "machine_platform_offset": { - "default": [0, -82, 0] - }, - "layer_height": { "default": 0.2 }, - "layer_height_0": { "default": 0.2, "visible": false }, - "wall_thickness": { "default": 1.0, "visible": false }, - "top_bottom_thickness": { "default": 1.0, "visible": false}, - "bottom_thickness": { "default": 1.0, "visible": false }, - "material_print_temperature": { "default": 220, "visible": true }, - "material_bed_temperature": { "default": 0, "visible": false }, - "material_diameter": { "default": 1.75, "visible": true }, - "speed_print": { "default": 40.0}, - "speed_infill": { "default": 40.0, "visible": true }, - "speed_wall": { "default": 35.0, "visible": true}, - "speed_topbottom": { "default": 35.0, "visible": true }, - "speed_travel": { "default": 120.0 }, - "speed_layer_0": { "default": 20.0, "visible": false }, - "support_enable": { "default": true } - } -} diff --git a/resources/machines/bq_hephestos_2.json b/resources/machines/bq_hephestos_2.json deleted file mode 100644 index 8b1ed34caa..0000000000 --- a/resources/machines/bq_hephestos_2.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "id": "bq_hephestos_2", - "version": 1, - "name": "BQ Hephestos 2", - "manufacturer": "Other", - "author": "BQ", - "platform": "bq_hephestos_2_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "overrides": { - "machine_start_gcode": { - "default": "; -- START GCODE --\nM800 ; Custom GCODE to fire start print procedure\n; -- end of START GCODE --" - }, - "machine_end_gcode": { - "default": "; -- END GCODE --\nM801 ; Custom GCODE to fire end print procedure\n; -- end of END GCODE --" - }, - "machine_width": { - "default": 210 - }, - "machine_depth": { - "default": 297 - }, - "machine_height": { - "default": 220 - }, - "machine_heated_bed": { - "default": false - }, - "machine_center_is_zero": { - "default": false - }, - "machine_gcode_flavor": { - "default": "RepRap" - }, - "machine_platform_offset": { - "default": [6, 1320, 0] - }, - "material_print_temperature": { "default": 210.0, "visible": true }, - "material_bed_temperature": { "default": 0 }, - "material_diameter": { "default": 1.75 }, - "layer_height": { "default": 0.2 }, - "layer_height_0": { "default": 0.2, "visible": true }, - "wall_line_count": { "default": 3, "visible": false }, - "wall_thickness": { "default": 1.2, "visible": false }, - "top_bottom_thickness": { "default": 1.2, "visible": false }, - "infill_sparse_density": { "default": 20.0 }, - "infill_overlap": { "default": 15.0, "visible": false }, - "speed_print": { "default": 60.0 }, - "speed_travel": { "default": 160.0 }, - "speed_layer_0": { "default": 30.0, "visible": true }, - "speed_wall_x": { "default": 35.0, "visible": false }, - "speed_wall_0": { "default": 30.0, "visible": false }, - "speed_infill": { "default": 80.0, "visible": true }, - "speed_topbottom": { "default": 35.0, "visible": false }, - "skirt_speed": { "default": 35.0, "visible": false }, - "skirt_line_count": { "default": 4 }, - "skirt_minimal_length": { "default": 30.0, "visible": false }, - "skirt_gap": { "default": 6.0 }, - "cool_fan_full_at_height": { "default": 0.4, "visible": false }, - "support_enable": { "default": false } - } -} diff --git a/resources/machines/bq_hephestos_xl.json b/resources/machines/bq_hephestos_xl.json deleted file mode 100644 index 5ce1dc3a7f..0000000000 --- a/resources/machines/bq_hephestos_xl.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "id": "bq_hephestos_xl", - "version": 1, - "name": "BQ Prusa i3 Hephestos XL", - "manufacturer": "Other", - "author": "BQ", - "platform": "bq_hephestos_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "overrides": { - "machine_start_gcode": { - "default": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" - }, - "machine_end_gcode": { - "default": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" - }, - "machine_width": { - "default": 200 - }, - "machine_depth": { - "default": 300 - }, - "machine_height": { - "default": 180 - }, - "machine_heated_bed": { - "default": false - }, - "machine_center_is_zero": { - "default": false - }, - "machine_gcode_flavor": { - "default": "RepRap" - }, - "machine_platform_offset": { - "default": [0, -82, 0] - }, - "layer_height": { "default": 0.2 }, - "layer_height_0": { "default": 0.2, "visible": false }, - "wall_thickness": { "default": 1.0, "visible": false }, - "top_bottom_thickness": { "default": 1.0, "visible": false}, - "bottom_thickness": { "default": 1.0, "visible": false }, - "material_print_temperature": { "default": 220, "visible": true }, - "material_bed_temperature": { "default": 0, "visible": false }, - "material_diameter": { "default": 1.75, "visible": true }, - "speed_print": { "default": 40.0}, - "speed_infill": { "default": 40.0, "visible": true }, - "speed_wall": { "default": 35.0, "visible": true}, - "speed_topbottom": { "default": 35.0, "visible": true }, - "speed_travel": { "default": 120.0 }, - "speed_layer_0": { "default": 20.0, "visible": false }, - "support_enable": { "default": true } - } -} diff --git a/resources/machines/bq_witbox.json b/resources/machines/bq_witbox.json deleted file mode 100644 index 83ac707ff6..0000000000 --- a/resources/machines/bq_witbox.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "id": "bq_witbox", - "version": 1, - "name": "BQ Witbox", - "manufacturer": "Other", - "author": "BQ", - "platform": "bq_witbox_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "overrides": { - "machine_start_gcode": { - "default": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" - }, - "machine_end_gcode": { - "default": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG90 ;set to absolute positioning\nG1 Z200 ;move the platform to the bottom\nG28 X0 Y0 ;move to the X/Y origin (Home)\nM84 ;turn off steppers\n; -- end of END GCODE --" - }, - "machine_width": { - "default": 297 - }, - "machine_depth": { - "default": 210 - }, - "machine_height": { - "default": 200 - }, - "machine_heated_bed": { - "default": false - }, - "machine_center_is_zero": { - "default": false - }, - "machine_gcode_flavor": { - "default": "RepRap" - }, - "machine_platform_offset": { - "default": [0, -145, -38] - }, - "layer_height": { "default": 0.2 }, - "layer_height_0": { "default": 0.2, "visible": false }, - "wall_thickness": { "default": 1.0, "visible": false }, - "top_bottom_thickness": { "default": 1.0, "visible": false}, - "bottom_thickness": { "default": 1.0, "visible": false }, - "material_print_temperature": { "default": 220, "visible": true }, - "material_bed_temperature": { "default": 0, "visible": false }, - "material_diameter": { "default": 1.75, "visible": true }, - "speed_print": { "default": 40.0}, - "speed_infill": { "default": 40.0, "visible": true }, - "speed_wall": { "default": 35.0, "visible": true}, - "speed_topbottom": { "default": 35.0, "visible": true }, - "speed_travel": { "default": 120.0 }, - "speed_layer_0": { "default": 20.0, "visible": false }, - "support_enable": { "default": true } - } -} diff --git a/resources/machines/bq_witbox_2.json b/resources/machines/bq_witbox_2.json deleted file mode 100644 index 61ce18a161..0000000000 --- a/resources/machines/bq_witbox_2.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "id": "bq_witbox_2", - "version": 1, - "name": "BQ Witbox 2", - "manufacturer": "Other", - "author": "BQ", - "platform": "bq_witbox_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "overrides": { - "machine_start_gcode": { - "default": "; -- START GCODE --\nM800 ; Custom GCODE to fire start print procedure\n; -- end of START GCODE --" - }, - "machine_end_gcode": { - "default": "; -- END GCODE --\nM801 ; Custom GCODE to fire end print procedure\n; -- end of END GCODE --" - }, - "machine_width": { - "default": 297 - }, - "machine_depth": { - "default": 210 - }, - "machine_height": { - "default": 200 - }, - "machine_heated_bed": { - "default": false - }, - "machine_center_is_zero": { - "default": false - }, - "machine_gcode_flavor": { - "default": "RepRap" - }, - "machine_platform_offset": { - "default": [0, -145, -38] - }, - "material_print_temperature": { "default": 210.0, "visible": true }, - "material_bed_temperature": { "default": 0 }, - "material_diameter": { "default": 1.75 }, - "layer_height": { "default": 0.2 }, - "layer_height_0": { "default": 0.2, "visible": true }, - "wall_line_count": { "default": 3, "visible": false }, - "wall_thickness": { "default": 1.2, "visible": false }, - "top_bottom_thickness": { "default": 1.2, "visible": false }, - "infill_sparse_density": { "default": 20.0 }, - "infill_overlap": { "default": 15.0, "visible": false }, - "speed_print": { "default": 60.0 }, - "speed_travel": { "default": 160.0 }, - "speed_layer_0": { "default": 30.0, "visible": true }, - "speed_wall_x": { "default": 35.0, "visible": false }, - "speed_wall_0": { "default": 30.0, "visible": false }, - "speed_infill": { "default": 80.0, "visible": true }, - "speed_topbottom": { "default": 35.0, "visible": false }, - "skirt_speed": { "default": 35.0, "visible": false }, - "skirt_line_count": { "default": 4 }, - "skirt_minimal_length": { "default": 30.0, "visible": false }, - "skirt_gap": { "default": 6.0 }, - "cool_fan_full_at_height": { "default": 0.4, "visible": false }, - "support_enable": { "default": false } - } -} diff --git a/resources/machines/grr_neo.json b/resources/machines/grr_neo.json deleted file mode 100644 index e2eb9aae73..0000000000 --- a/resources/machines/grr_neo.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "id": "grr_neo", - "version": 1, - "name": "German RepRap Neo", - "manufacturer": "Other", - "author": "Other", - "icon": "icon_ultimaker.png", - "platform": "grr_neo_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - "visible": "true", - - "overrides": { - "machine_width": { "default": 150 }, - "machine_height": { "default": 150 }, - "machine_depth": { "default": 150 }, - "machine_center_is_zero": { "default": false }, - "machine_nozzle_size": { "default": 0.5 }, - "machine_nozzle_heat_up_speed": { "default": 2.0 }, - "machine_nozzle_cool_down_speed": { "default": 2.0 }, - "machine_head_shape_min_x": { "default": 75 }, - "machine_head_shape_min_y": { "default": 18 }, - "machine_head_shape_max_x": { "default": 18 }, - "machine_head_shape_max_y": { "default": 35 }, - "machine_nozzle_gantry_distance": { "default": 55 }, - "machine_gcode_flavor": { "default": "RepRap (Marlin/Sprinter)" }, - - "machine_start_gcode": { - "default": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." - }, - "machine_end_gcode": { - "default": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" - }, - - "material_bed_temperature": { "visible": false } - } -} From 8606961c3fcae83abffa2b28d1dc23e2126d978c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 14:42:01 +0200 Subject: [PATCH 132/705] Fix name of author Contributes to issue CURA-1278. --- resources/definitions/innovo_inventor.def.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/definitions/innovo_inventor.def.json b/resources/definitions/innovo_inventor.def.json index 30e5a53094..ce3c27ee14 100644 --- a/resources/definitions/innovo_inventor.def.json +++ b/resources/definitions/innovo_inventor.def.json @@ -4,7 +4,7 @@ "name": "Innovo INVENTOR", "inherits": "fdmprinter", "metadata": { - "author": "AR", + "author": "Adam Rumjahn", "manufacturer": "Innovo", "category": "Other", "file_formats": "text/x-gcode", From 2cf025c91aefa56cb59643b96e3945dbb220248a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 15:50:41 +0200 Subject: [PATCH 133/705] Translate definition for M180 Contributes to issue CURA-1278. --- resources/definitions/m180.def.json | 58 +++++++++++++++++++++++++++++ resources/machines/m180.json | 39 ------------------- 2 files changed, 58 insertions(+), 39 deletions(-) create mode 100644 resources/definitions/m180.def.json delete mode 100644 resources/machines/m180.json diff --git a/resources/definitions/m180.def.json b/resources/definitions/m180.def.json new file mode 100644 index 0000000000..7938ff79cb --- /dev/null +++ b/resources/definitions/m180.def.json @@ -0,0 +1,58 @@ +{ + "id": "m180", + "version": 2, + "name": "Malyan M180", + "inherits": "fdmprinter", + "metadata": { + "author": "Ruben Dulek", + "manufacturer": "Malyan", + "category": "Other", + "file_formats": "application/x3g" + }, + + "overrides": { + "settings": { + "machine_width": { + "default_value": 230 + }, + "machine_height": { + "default_value": 165 + }, + "machine_depth": { + "default_value": 145 + }, + "machine_center_is_zero": { + "default_value": true + }, + "machine_nozzle_size": { + "default_value": 0.4, + "min_value": "0.001" + }, + "machine_head_with_fans_polygon": { + "default_value": [ + [ -75, 35 ], + [ -75, -18 ], + [ 18, -18 ], + [ 18, 35 ] + ] + }, + "gantry_height": { + "default_value": 55 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "default_value": "M136\nM73 P0\nM103\nG21\nG90\nM320\n;(**** begin homing ****)\nG162 X Y F4000\nG161 Z F3500\nG92 Z-5\nG1 Z0.0\nG161 Z F100\nM132 X Y Z A B\n;(**** end homing ****)\nG92 X147 Y66 Z5\nG1 X105 Y-60 Z10 F4000.0\nG130 X127 Y127 A127 B127\nG0 X105 Y-60\nG1 Z0.3 F300\nG92 E0\nG1 X100 E10 F300\nG92 E0\nG1 Z0.0 F300\nM320" + }, + "machine_end_gcode": { + "default_value": "G92 Z0\nG1 Z10 F400\nM18\nM109 S0 T0\nM104 S0 T0\nM73 P100 (end build progress)\nG162 X Y F3000\nM18" + }, + "material_diameter": { + "default_value": 1.75, + "min_value_warning": "1.5", + "max_value_warning": "2.0" + } + } + } +} \ No newline at end of file diff --git a/resources/machines/m180.json b/resources/machines/m180.json deleted file mode 100644 index 7e31577ac2..0000000000 --- a/resources/machines/m180.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "id": "m180", - "version": 1, - "name": "Malyan M180", - "manufacturer": "Other", - "icon": "icon_ultimaker.png", - "platform": "", - "file_formats": "application/x3g", - "inherits": "fdmprinter.json", - - "machine_settings": { - "machine_width": { "default": 230 }, - "machine_height": { "default": 165 }, - "machine_depth": { "default": 145 }, - "machine_center_is_zero": { "default": true }, - "machine_nozzle_size": { "default": 0.4, "min_value": "0.001" }, - "machine_head_with_fans_polygon": { - "default": [ - [ -75, 35 ], - [ -75, -18 ], - [ 18, -18 ], - [ 18, 35 ] - ] - }, - "gantry_height": { "default": 55 }, - "machine_gcode_flavor": { "default": "RepRap (Marlin/Sprinter)" }, - "machine_start_gcode": { "default": "M136\nM73 P0\nM103\nG21\nG90\nM320\n;(**** begin homing ****)\nG162 X Y F4000\nG161 Z F3500\nG92 Z-5\nG1 Z0.0\nG161 Z F100\nM132 X Y Z A B\n;(**** end homing ****)\nG92 X147 Y66 Z5\nG1 X105 Y-60 Z10 F4000.0\nG130 X127 Y127 A127 B127\nG0 X105 Y-60\nG1 Z0.3 F300\nG92 E0\nG1 X100 E10 F300\nG92 E0\nG1 Z0.0 F300\nM320" }, - "machine_end_gcode": { "default": "G92 Z0\nG1 Z10 F400\nM18\nM109 S0 T0\nM104 S0 T0\nM73 P100 (end build progress)\nG162 X Y F3000\nM18" } - }, - - "overrides": { - "material_bed_temperature": { "visible": "True" }, - "material_diameter": { - "default": 1.75, - "min_value_warning": "1.5", - "max_value_warning": "2.0" - } - } -} From 6c74350c6e0cc0bc26db7a6a0c54d82b3e6066e1 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 17:40:56 +0200 Subject: [PATCH 134/705] Merge Contributes to issue CURA-1278. --- resources/definitions/bq_hephestos.def.json | 45 ++++++++++----------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/resources/definitions/bq_hephestos.def.json b/resources/definitions/bq_hephestos.def.json index 57fa85ab89..ad2fe851bb 100644 --- a/resources/definitions/bq_hephestos.def.json +++ b/resources/definitions/bq_hephestos.def.json @@ -3,8 +3,7 @@ "name": "BQ Prusa i3 Hephestos", "version": 2, "inherits": "fdmprinter", - "metadata": - { + "metadata": { "author": "BQ", "manufacturer": "BQ", "category": "Other", @@ -27,67 +26,67 @@ "default_value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" }, "machine_width": { - "value": 215 + "default_value": 215 }, "machine_depth": { - "value": 210 + "default_value": 210 }, "machine_height": { - "value": 180 + "default_value": 180 }, "machine_heated_bed": { - "value": false + "default_value": false }, "machine_center_is_zero": { - "value": false + "default_value": false }, "machine_gcode_flavor": { - "value": "RepRap" + "default_value": "RepRap" }, "layer_height": { - "value": 0.2 + "default_value": 0.2 }, "layer_height_0": { - "value": 0.2 + "default_value": 0.2 }, "wall_thickness": { - "value": 1.0 + "default_value": 1.0 }, "top_bottom_thickness": { - "value": 1.0 + "default_value": 1.0 }, "bottom_thickness": { - "value": 1.0 + "default_value": 1.0 }, "material_print_temperature": { - "value": 220 + "default_value": 220 }, "material_bed_temperature": { - "value": 0 + "default_value": 0 }, "material_diameter": { - "value": 1.75 + "default_value": 1.75 }, "speed_print": { - "value": 40.0 + "default_value": 40.0 }, "speed_infill": { - "value": 40.0 + "default_value": 40.0 }, "speed_wall": { - "value": 35.0 + "default_value": 35.0 }, "speed_topbottom": { - "value": 35.0 + "default_value": 35.0 }, "speed_travel": { - "value": 120.0 + "default_value": 120.0 }, "speed_layer_0": { - "value": 20.0 + "default_value": 20.0 }, "support_enable": { - "value": true + "default_value": true } } } \ No newline at end of file From ad1b08c080886573539e130d87777c305fead41f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 16:01:02 +0200 Subject: [PATCH 135/705] Put settings in overrides JSON category Not in a subcategory of settings or anything. Contributes to issue CURA-1278. --- resources/definitions/m180.def.json | 82 ++++++++++++++--------------- 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/resources/definitions/m180.def.json b/resources/definitions/m180.def.json index 7938ff79cb..36d8be6e1f 100644 --- a/resources/definitions/m180.def.json +++ b/resources/definitions/m180.def.json @@ -11,48 +11,46 @@ }, "overrides": { - "settings": { - "machine_width": { - "default_value": 230 - }, - "machine_height": { - "default_value": 165 - }, - "machine_depth": { - "default_value": 145 - }, - "machine_center_is_zero": { - "default_value": true - }, - "machine_nozzle_size": { - "default_value": 0.4, - "min_value": "0.001" - }, - "machine_head_with_fans_polygon": { - "default_value": [ - [ -75, 35 ], - [ -75, -18 ], - [ 18, -18 ], - [ 18, 35 ] - ] - }, - "gantry_height": { - "default_value": 55 - }, - "machine_gcode_flavor": { - "default_value": "RepRap (Marlin/Sprinter)" - }, - "machine_start_gcode": { - "default_value": "M136\nM73 P0\nM103\nG21\nG90\nM320\n;(**** begin homing ****)\nG162 X Y F4000\nG161 Z F3500\nG92 Z-5\nG1 Z0.0\nG161 Z F100\nM132 X Y Z A B\n;(**** end homing ****)\nG92 X147 Y66 Z5\nG1 X105 Y-60 Z10 F4000.0\nG130 X127 Y127 A127 B127\nG0 X105 Y-60\nG1 Z0.3 F300\nG92 E0\nG1 X100 E10 F300\nG92 E0\nG1 Z0.0 F300\nM320" - }, - "machine_end_gcode": { - "default_value": "G92 Z0\nG1 Z10 F400\nM18\nM109 S0 T0\nM104 S0 T0\nM73 P100 (end build progress)\nG162 X Y F3000\nM18" - }, - "material_diameter": { - "default_value": 1.75, - "min_value_warning": "1.5", - "max_value_warning": "2.0" - } + "machine_width": { + "default_value": 230 + }, + "machine_height": { + "default_value": 165 + }, + "machine_depth": { + "default_value": 145 + }, + "machine_center_is_zero": { + "default_value": true + }, + "machine_nozzle_size": { + "default_value": 0.4, + "min_value": "0.001" + }, + "machine_head_with_fans_polygon": { + "default_value": [ + [ -75, 35 ], + [ -75, -18 ], + [ 18, -18 ], + [ 18, 35 ] + ] + }, + "gantry_height": { + "default_value": 55 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "default_value": "M136\nM73 P0\nM103\nG21\nG90\nM320\n;(**** begin homing ****)\nG162 X Y F4000\nG161 Z F3500\nG92 Z-5\nG1 Z0.0\nG161 Z F100\nM132 X Y Z A B\n;(**** end homing ****)\nG92 X147 Y66 Z5\nG1 X105 Y-60 Z10 F4000.0\nG130 X127 Y127 A127 B127\nG0 X105 Y-60\nG1 Z0.3 F300\nG92 E0\nG1 X100 E10 F300\nG92 E0\nG1 Z0.0 F300\nM320" + }, + "machine_end_gcode": { + "default_value": "G92 Z0\nG1 Z10 F400\nM18\nM109 S0 T0\nM104 S0 T0\nM73 P100 (end build progress)\nG162 X Y F3000\nM18" + }, + "material_diameter": { + "default_value": 1.75, + "min_value_warning": "1.5", + "max_value_warning": "2.0" } } } \ No newline at end of file From 232e4fbe0df3f73834aadd2c81f8ebaafbd10c33 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 16:01:42 +0200 Subject: [PATCH 136/705] Put settings in overrides JSON category Not in a subcategory of settings or anything. Contributes to issue CURA-1278. --- resources/definitions/bq_hephestos.def.json | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/resources/definitions/bq_hephestos.def.json b/resources/definitions/bq_hephestos.def.json index ad2fe851bb..09081f4814 100644 --- a/resources/definitions/bq_hephestos.def.json +++ b/resources/definitions/bq_hephestos.def.json @@ -43,6 +43,9 @@ "machine_gcode_flavor": { "default_value": "RepRap" }, + "machine_platform_offset": { + "default_value": [ 0, -82, 0 ] + }, "layer_height": { "default_value": 0.2 }, @@ -50,13 +53,13 @@ "default_value": 0.2 }, "wall_thickness": { - "default_value": 1.0 + "default_value": 1 }, "top_bottom_thickness": { - "default_value": 1.0 + "default_value": 1 }, "bottom_thickness": { - "default_value": 1.0 + "default_value": 1 }, "material_print_temperature": { "default_value": 220 @@ -68,22 +71,22 @@ "default_value": 1.75 }, "speed_print": { - "default_value": 40.0 + "default_value": 40 }, "speed_infill": { - "default_value": 40.0 + "default_value": 40 }, "speed_wall": { - "default_value": 35.0 + "default_value": 35 }, "speed_topbottom": { - "default_value": 35.0 + "default_value": 35 }, "speed_travel": { - "default_value": 120.0 + "default_value": 120 }, "speed_layer_0": { - "default_value": 20.0 + "default_value": 20 }, "support_enable": { "default_value": true From d29e36694586188b4b7ba10826dd71afc00a2819 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 16:10:12 +0200 Subject: [PATCH 137/705] Fix BQ Hephestos 2 definition The settings were in the wrong category. They were defined by value instead of default value, and the metadata was in there double. Contributes to issue CURA-1278. --- resources/definitions/bq_hephestos_2.def.json | 65 +++++++++---------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/resources/definitions/bq_hephestos_2.def.json b/resources/definitions/bq_hephestos_2.def.json index dba849ac7e..578f166bcb 100644 --- a/resources/definitions/bq_hephestos_2.def.json +++ b/resources/definitions/bq_hephestos_2.def.json @@ -17,10 +17,6 @@ }, "file_formats": "text/x-gcode" }, - "manufacturer": "BQ", - "author": "BQ", - "platform": "bq_hephestos_2_platform.stl", - "file_formats": "text/x-gcode", "overrides": { "machine_start_gcode": { @@ -30,91 +26,94 @@ "default_value": "; -- END GCODE --\nM801 ; Custom GCODE to fire end print procedure\n; -- end of END GCODE --" }, "machine_width": { - "value": 210 + "default_value": 210 }, "machine_depth": { - "value": 297 + "default_value": 297 }, "machine_height": { - "value": 220 + "default_value": 220 }, "machine_heated_bed": { - "value": false + "default_value": false }, "machine_center_is_zero": { - "value": false + "default_value": false }, "machine_gcode_flavor": { - "value": "RepRap" + "default_value": "RepRap" + }, + "machine_platform_offset": { + "default_value": [6, 1320, 0] }, "material_print_temperature": { - "value": 210.0 + "default_value": 210 }, "material_bed_temperature": { - "value": 0 + "default_value": 0 }, "material_diameter": { - "value": 1.75 + "default_value": 1.75 }, "layer_height": { - "value": 0.2 + "default_value": 0.2 }, "layer_height_0": { - "value": 0.2 + "default_value": 0.2 }, "wall_line_count": { - "value": 3 + "default_value": 3 }, "wall_thickness": { - "value": 1.2 + "default_value": 1.2 }, "top_bottom_thickness": { - "value": 1.2 + "default_value": 1.2 }, "infill_sparse_density": { - "value": 20.0 + "default_value": 20 }, "infill_overlap": { - "value": 15.0 + "default_value": 15 }, "speed_print": { - "value": 60.0 + "default_value": 60 }, "speed_travel": { - "value": 160.0 + "default_value": 160 }, "speed_layer_0": { - "value": 30.0 + "default_value": 30 }, "speed_wall_x": { - "value": 35.0 + "default_value": 35 }, "speed_wall_0": { - "value": 30.0 + "default_value": 30 }, "speed_infill": { - "value": 80.0 + "default_value": 80 }, "speed_topbottom": { - "value": 35.0 + "default_value": 35 }, "skirt_speed": { - "value": 35.0 + "default_value": 35 }, "skirt_line_count": { - "value": 4 + "default_value": 4 }, "skirt_minimal_length": { - "value": 30.0 + "default_value": 30 }, "skirt_gap": { - "value": 6.0 + "default_value": 6 }, "cool_fan_full_at_height": { - "value": 0.4 + "default_value": 0.4 }, "support_enable": { - "value": false + "default_value": false } } } From caa108c3cfda8d803bf5613355baae4ebbd8b34a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 16:12:52 +0200 Subject: [PATCH 138/705] Default value and overrides category The settings must be in the 'overrides' category, not in the 'settings' category. Also, define a default value rather than a value. Contributes to issue CURA-1278. --- .../definitions/bq_hephestos_xl.def.json | 46 ++++++++++--------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/resources/definitions/bq_hephestos_xl.def.json b/resources/definitions/bq_hephestos_xl.def.json index 6d4c7fdd52..ce7a95b799 100644 --- a/resources/definitions/bq_hephestos_xl.def.json +++ b/resources/definitions/bq_hephestos_xl.def.json @@ -17,6 +17,7 @@ ] } }, + "overrides": { "machine_start_gcode": { "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" @@ -25,67 +26,70 @@ "default_value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" }, "machine_width": { - "value": 200 + "default_value": 200 }, "machine_depth": { - "value": 300 + "default_value": 300 }, "machine_height": { - "value": 180 + "default_value": 180 }, "machine_heated_bed": { - "value": false + "default_value": false }, "machine_center_is_zero": { - "value": false + "default_value": false }, "machine_gcode_flavor": { - "value": "RepRap" + "default_value": "RepRap" + }, + "machine_platform_offset": { + "default_value": [0, -82, 0] }, "layer_height": { - "value": 0.2 + "default_value": 0.2 }, "layer_height_0": { - "value": 0.2 + "default_value": 0.2 }, "wall_thickness": { - "value": 1.0 + "default_value": 1 }, "top_bottom_thickness": { - "value": 1.0 + "default_value": 1 }, "bottom_thickness": { - "value": 1.0 + "default_value": 1 }, "material_print_temperature": { - "value": 220 + "default_value": 220 }, "material_bed_temperature": { - "value": 0 + "default_value": 0 }, "material_diameter": { - "value": 1.75 + "default_value": 1.75 }, "speed_print": { - "value": 40.0 + "default_value": 40 }, "speed_infill": { - "value": 40.0 + "default_value": 40 }, "speed_wall": { - "value": 35.0 + "default_value": 35 }, "speed_topbottom": { - "value": 35.0 + "default_value": 35 }, "speed_travel": { - "value": 120.0 + "default_value": 120 }, "speed_layer_0": { - "value": 20.0 + "default_value": 20 }, "support_enable": { - "value": true + "default_value": true } } } \ No newline at end of file From dc82a9004797b9dd13812e0e4d740509194ad0b2 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 16:14:12 +0200 Subject: [PATCH 139/705] Default value and overrides category The settings must be in the 'overrides' category, not in the 'settings' category. Also, define a default value rather than a value. Contributes to issue CURA-1278. --- resources/definitions/bq_hephestos.def.json | 3 -- resources/definitions/bq_hephestos_2.def.json | 3 -- .../definitions/bq_hephestos_xl.def.json | 3 -- resources/definitions/bq_witbox.def.json | 43 ++++++++++--------- 4 files changed, 22 insertions(+), 30 deletions(-) diff --git a/resources/definitions/bq_hephestos.def.json b/resources/definitions/bq_hephestos.def.json index 09081f4814..b9f0f3dca5 100644 --- a/resources/definitions/bq_hephestos.def.json +++ b/resources/definitions/bq_hephestos.def.json @@ -43,9 +43,6 @@ "machine_gcode_flavor": { "default_value": "RepRap" }, - "machine_platform_offset": { - "default_value": [ 0, -82, 0 ] - }, "layer_height": { "default_value": 0.2 }, diff --git a/resources/definitions/bq_hephestos_2.def.json b/resources/definitions/bq_hephestos_2.def.json index 578f166bcb..e072fbf1db 100644 --- a/resources/definitions/bq_hephestos_2.def.json +++ b/resources/definitions/bq_hephestos_2.def.json @@ -43,9 +43,6 @@ "machine_gcode_flavor": { "default_value": "RepRap" }, - "machine_platform_offset": { - "default_value": [6, 1320, 0] - }, "material_print_temperature": { "default_value": 210 }, diff --git a/resources/definitions/bq_hephestos_xl.def.json b/resources/definitions/bq_hephestos_xl.def.json index ce7a95b799..224d219504 100644 --- a/resources/definitions/bq_hephestos_xl.def.json +++ b/resources/definitions/bq_hephestos_xl.def.json @@ -43,9 +43,6 @@ "machine_gcode_flavor": { "default_value": "RepRap" }, - "machine_platform_offset": { - "default_value": [0, -82, 0] - }, "layer_height": { "default_value": 0.2 }, diff --git a/resources/definitions/bq_witbox.def.json b/resources/definitions/bq_witbox.def.json index d9529cdae6..3d021cc529 100644 --- a/resources/definitions/bq_witbox.def.json +++ b/resources/definitions/bq_witbox.def.json @@ -17,6 +17,7 @@ ] } }, + "overrides": { "machine_start_gcode": { "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" @@ -25,67 +26,67 @@ "default_value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG90 ;set to absolute positioning\nG1 Z200 ;move the platform to the bottom\nG28 X0 Y0 ;move to the X/Y origin (Home)\nM84 ;turn off steppers\n; -- end of END GCODE --" }, "machine_width": { - "value": 297 + "default_value": 297 }, "machine_depth": { - "value": 210 + "default_value": 210 }, "machine_height": { - "value": 200 + "default_value": 200 }, "machine_heated_bed": { - "value": false + "default_value": false }, "machine_center_is_zero": { - "value": false + "default_value": false }, "machine_gcode_flavor": { - "value": "RepRap" + "default_value": "RepRap" }, "layer_height": { - "value": 0.2 + "default_value": 0.2 }, "layer_height_0": { - "value": 0.2 + "default_value": 0.2 }, "wall_thickness": { - "value": 1 + "default_value": 1 }, "top_bottom_thickness": { - "value": 1 + "default_value": 1 }, "bottom_thickness": { - "value": 1 + "default_value": 1 }, "material_print_temperature": { - "value": 220 + "default_value": 220 }, "material_bed_temperature": { - "value": 0 + "default_value": 0 }, "material_diameter": { - "value": 1.75 + "default_value": 1.75 }, "speed_print": { - "value": 40 + "default_value": 40 }, "speed_infill": { - "value": 40 + "default_value": 40 }, "speed_wall": { - "value": 35 + "default_value": 35 }, "speed_topbottom": { - "value": 35 + "default_value": 35 }, "speed_travel": { - "value": 120 + "default_value": 120 }, "speed_layer_0": { - "value": 20 + "default_value": 20 }, "support_enable": { - "value": true + "default_value": true } } From 9aaa81be50704e7a0835444ec922b349247196df Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 16:15:43 +0200 Subject: [PATCH 140/705] Default value and overrides category The settings must be in the 'overrides' category, not in the 'settings' category. Also, define a default value rather than a value. Contributes to issue CURA-1278. --- resources/definitions/bq_witbox_2.def.json | 69 +++++++++++----------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/resources/definitions/bq_witbox_2.def.json b/resources/definitions/bq_witbox_2.def.json index 43e6968aba..58f70c95b7 100644 --- a/resources/definitions/bq_witbox_2.def.json +++ b/resources/definitions/bq_witbox_2.def.json @@ -3,8 +3,7 @@ "version": 2, "name": "BQ Witbox 2", "inherits": "fdmprinter", - "metadata": - { + "metadata": { "author": "BQ", "manufacturer": "BQ", "category": "Other", @@ -12,102 +11,102 @@ "platform": "bq_witbox_platform.stl" }, - "settings": { + "overrides": { "machine_start_gcode": { - "value": "; -- START GCODE --\nM800 ; Custom GCODE to fire start print procedure\n; -- end of START GCODE --" + "default_value": "; -- START GCODE --\nM800 ; Custom GCODE to fire start print procedure\n; -- end of START GCODE --" }, "machine_end_gcode": { - "value": "; -- END GCODE --\nM801 ; Custom GCODE to fire end print procedure\n; -- end of END GCODE --" + "default_value": "; -- END GCODE --\nM801 ; Custom GCODE to fire end print procedure\n; -- end of END GCODE --" }, "machine_width": { - "value": 297 + "default_value": 297 }, "machine_depth": { - "value": 210 + "default_value": 210 }, "machine_height": { - "value": 200 + "default_value": 200 }, "machine_heated_bed": { - "value": false + "default_value": false }, "machine_center_is_zero": { - "value": false + "default_value": false }, "machine_gcode_flavor": { - "value": "RepRap" + "default_value": "RepRap" }, "machine_platform_offset": { - "value": [0, -145, -38] + "default_value": [0, -145, -38] }, "material_print_temperature": { - "value": 210.0 + "default_value": 210 }, "material_bed_temperature": { - "value": 0 + "default_value": 0 }, "material_diameter": { - "value": 1.75 + "default_value": 1.75 }, "layer_height": { - "value": 0.2 + "default_value": 0.2 }, "layer_height_0": { - "value": 0.2 + "default_value": 0.2 }, "wall_line_count": { - "value": 3 + "default_value": 3 }, "wall_thickness": { - "value": 1.2 + "default_value": 1.2 }, "top_bottom_thickness": { - "value": 1.2 + "default_value": 1.2 }, "infill_sparse_density": { - "value": 20.0 + "default_value": 20 }, "infill_overlap": { - "value": 15.0 + "default_value": 15 }, "speed_print": { - "value": 60.0 + "default_value": 60 }, "speed_travel": { - "value": 160.0 + "default_value": 160 }, "speed_layer_0": { - "value": 30.0 + "default_value": 30 }, "speed_wall_x": { - "value": 35.0 + "default_value": 35 }, "speed_wall_0": { - "value": 30.0 + "default_value": 30 }, "speed_infill": { - "value": 80.0 + "default_value": 80 }, "speed_topbottom": { - "value": 35.0 + "default_value": 35 }, "skirt_speed": { - "value": 35.0 + "default_value": 35 }, "skirt_line_count": { - "value": 4 + "default_value": 4 }, "skirt_minimal_length": { - "value": 30.0 + "default_value": 30 }, "skirt_gap": { - "value": 6.0 + "default_value": 6 }, "cool_fan_full_at_height": { - "value": 0.4 + "default_value": 0.4 }, "support_enable": { - "value": false + "default_value": false } } } \ No newline at end of file From 0298e3adcae95f72554e0b4aff3918b86817e6ad Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 16:16:43 +0200 Subject: [PATCH 141/705] Use default value instead of value Contributes to issue CURA-1278. --- resources/definitions/grr_neo.def.json | 30 +++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/resources/definitions/grr_neo.def.json b/resources/definitions/grr_neo.def.json index 710303383b..3fb6804c40 100644 --- a/resources/definitions/grr_neo.def.json +++ b/resources/definitions/grr_neo.def.json @@ -14,49 +14,49 @@ "overrides": { "machine_width": { - "value": 150 + "default_value": 150 }, "machine_height": { - "value": 150 + "default_value": 150 }, "machine_depth": { - "value": 150 + "default_value": 150 }, "machine_center_is_zero": { - "value": false + "default_value": false }, "machine_nozzle_size": { - "value": 0.5 + "default_value": 0.5 }, "machine_nozzle_heat_up_speed": { - "value": 2 + "default_value": 2 }, "machine_nozzle_cool_down_speed": { - "value": 2 + "default_value": 2 }, "machine_head_shape_min_x": { - "value": 75 + "default_value": 75 }, "machine_head_shape_min_y": { - "value": 18 + "default_value": 18 }, "machine_head_shape_max_x": { - "value": 18 + "default_value": 18 }, "machine_head_shape_max_y": { - "value": 35 + "default_value": 35 }, "machine_nozzle_gantry_distance": { - "value": 55 + "default_value": 55 }, "machine_gcode_flavor": { - "value": "RepRap (Marlin/Sprinter)" + "default_value": "RepRap (Marlin/Sprinter)" }, "machine_start_gcode": { - "value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." + "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." }, "machine_end_gcode": { - "value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" + "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" } } } \ No newline at end of file From 45382dc088a33bcced404fd5088be63fa8db70b5 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 16:17:44 +0200 Subject: [PATCH 142/705] Default value and overrides category The settings must be in the 'overrides' category, not in the 'settings' category. Also, define a default value rather than a value. Contributes to issue CURA-1278. --- .../definitions/innovo_inventor.def.json | 61 ++++++++++--------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/resources/definitions/innovo_inventor.def.json b/resources/definitions/innovo_inventor.def.json index ce3c27ee14..5ab8d4f2e1 100644 --- a/resources/definitions/innovo_inventor.def.json +++ b/resources/definitions/innovo_inventor.def.json @@ -10,94 +10,95 @@ "file_formats": "text/x-gcode", "platform": "inventor_platform.stl" }, - "settings": { + + "overrides": { "machine_width": { - "value": 340 + "default_value": 340 }, "machine_height": { - "value": 290 + "default_value": 290 }, "machine_depth": { - "value": 300 + "default_value": 300 }, "machine_heated_bed": { - "value": true + "default_value": true }, "machine_center_is_zero": { - "value": false + "default_value": false }, "machine_nozzle_size": { - "value": 0.4 + "default_value": 0.4 }, "machine_head_shape_min_x": { - "value": 43.7 + "default_value": 43.7 }, "machine_head_shape_min_y": { - "value": 19.2 + "default_value": 19.2 }, "machine_head_shape_max_x": { - "value": 43.7 + "default_value": 43.7 }, "machine_head_shape_max_y": { - "value": 55 + "default_value": 55 }, "machine_nozzle_gantry_distance": { - "value": 82.3 + "default_value": 82.3 }, "machine_nozzle_offset_x_1": { - "value": 0 + "default_value": 0 }, "machine_nozzle_offset_y_1": { - "value": 15 + "default_value": 15 }, "machine_gcode_flavor": { - "value": "RepRap (Marlin/Sprinter)" + "default_value": "RepRap (Marlin/Sprinter)" }, "machine_start_gcode": { - "value": "G28 ; Home extruder\nM107 ; Turn off fan\nG90 ; Absolute positioning\nM82 ; Extruder in absolute mode\n{IF_BED}M190 S{BED}\n{IF_EXT0}M104 T0 S{TEMP0}\n{IF_EXT0}M109 T0 S{TEMP0}\n{IF_EXT1}M104 T1 S{TEMP1}\n{IF_EXT1}M109 T1 S{TEMP1}\nG32 S3 ; auto level\nG92 E0 ; Reset extruder position" + "default_value": "G28 ; Home extruder\nM107 ; Turn off fan\nG90 ; Absolute positioning\nM82 ; Extruder in absolute mode\n{IF_BED}M190 S{BED}\n{IF_EXT0}M104 T0 S{TEMP0}\n{IF_EXT0}M109 T0 S{TEMP0}\n{IF_EXT1}M104 T1 S{TEMP1}\n{IF_EXT1}M109 T1 S{TEMP1}\nG32 S3 ; auto level\nG92 E0 ; Reset extruder position" }, "machine_end_gcode": { - "value": "M104 S0\nG91 ; relative positioning\nG1 E-2 F5000; retract 2mm\nG28 Z; move bed down\nG90 ; absolute positioning\nM84 ; disable motors" + "default_value": "M104 S0\nG91 ; relative positioning\nG1 E-2 F5000; retract 2mm\nG28 Z; move bed down\nG90 ; absolute positioning\nM84 ; disable motors" }, "machine_platform_offset": { - "value": [-180, -0.25, 160] + "default_value": [-180, -0.25, 160] }, "layer_height": { - "value": 0.15 + "default_value": 0.15 }, "wall_thickness": { - "value": 0.8 + "default_value": 0.8 }, "top_bottom_thickness": { - "value": 0.3 + "default_value": 0.3 }, "material_print_temperature": { - "value": 215 + "default_value": 215 }, "material_bed_temperature": { - "value": 60 + "default_value": 60 }, "material_diameter": { - "value": 1.75 + "default_value": 1.75 }, "speed_print": { - "value": 60 + "default_value": 60 }, "speed_infill": { - "value": 100 + "default_value": 100 }, "speed_topbottom": { - "value": 30 + "default_value": 30 }, "speed_travel": { - "value": 150 + "default_value": 150 }, "speed_layer_0": { - "value": 30.0, + "default_value": 30.0, "min_value": 0.1 }, "infill_overlap": { - "value": 10.0 + "default_value": 10.0 } } } \ No newline at end of file From e13878b3436d5472bb3d53f433412d676e535d31 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 16:27:35 +0200 Subject: [PATCH 143/705] Translate definition for 3DMaker Starter Contributes to issue CURA-1278. --- resources/definitions/maker_starter.def.json | 190 +++++++++++++++++++ resources/machines/maker_starter.json | 81 -------- 2 files changed, 190 insertions(+), 81 deletions(-) create mode 100644 resources/definitions/maker_starter.def.json delete mode 100644 resources/machines/maker_starter.json diff --git a/resources/definitions/maker_starter.def.json b/resources/definitions/maker_starter.def.json new file mode 100644 index 0000000000..81ad45698e --- /dev/null +++ b/resources/definitions/maker_starter.def.json @@ -0,0 +1,190 @@ +{ + "id": "maker_starter", + "version": 2, + "name": "3DMaker Starter", + "inherits": "fdmprinter", + "metadata": { + "author": "tvlgiao", + "manufacturer": "3DMaker", + "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj", + "icon": "icon_ultimaker2.png", + "platform": "makerstarter_platform.stl" + }, + + "overrides": { + "machine_width": { + "default": 210 + }, + "machine_depth": { + "default": 185 + }, + "machine_height": { + "default": 200 + }, + "machine_heated_bed": { + "default": false + }, + "machine_center_is_zero": { + "default": false + }, + "machine_nozzle_size": { + "default": 0.4 + }, + "machine_nozzle_heat_up_speed": { + "default": 2 + }, + "machine_nozzle_cool_down_speed": { + "default": 2 + }, + "machine_head_shape_min_x": { + "default": 0 + }, + "machine_head_shape_min_y": { + "default": 0 + }, + "machine_head_shape_max_x": { + "default": 0 + }, + "machine_head_shape_max_y": { + "default": 0 + }, + "machine_nozzle_gantry_distance": { + "default": 55 + }, + "machine_gcode_flavor": { + "default": "RepRap" + }, + "machine_disallowed_areas": { + "default": [] + }, + "machine_platform_offset": { + "default": [0, 0, 0] + }, + "machine_nozzle_tip_outer_diameter": { + "default": 1 + }, + "machine_nozzle_head_distance": { + "default": 3 + }, + "machine_nozzle_expansion_angle": { + "default": 45 + }, + "layer_height": { + "default": 0.2 + }, + "layer_height_0": { + "default": 0.2 + }, + "wall_line_count": { + "default": 2 + }, + "top_layers": { + "default": 4 + }, + "bottom_layers": { + "default": 4 + }, + "speed_print": { + "default": 50 + }, + "speed_wall": { + "default": 30 + }, + "speed_wall_0": { + "default": 30 + }, + "speed_wall_x": { + "default": 30 + }, + "speed_topbottom": { + "default": 50 + }, + "speed_support": { + "default": 50 + }, + "speed_travel": { + "default": 120 + }, + "speed_layer_0": { + "default": 20 + }, + "skirt_speed": { + "default": 15 + }, + "speed_slowdown_layers": { + "default": 4 + }, + "infill_sparse_density": { + "default": 20 + }, + "cool_fan_speed_min": { + "default": 50 + }, + "cool_fan_speed_max": { + "default": 100 + }, + "cool_fan_full_layer": { + "default": 4 + }, + "cool_min_layer_time": { + "default": 5 + }, + "cool_min_layer_time_fan_speed_max": { + "default": 10 + }, + "support_type": { + "default": "Everywhere" + }, + "support_angle": { + "default": 45 + }, + "support_xy_distance": { + "default": 1 + }, + "support_z_distance": { + "default": 0.2 + }, + "support_top_distance": { + "default": 0.2 + }, + "support_bottom_distance": { + "default": 0.24 + }, + "support_pattern": { + "default": "ZigZag" + }, + "support_infill_rate": { + "default": 15 + }, + "adhesion_type": { + "default": "Raft" + }, + "skirt_minimal_length": { + "default": 100 + }, + "raft_base_line_spacing": { + "default": 2 + }, + "raft_base_thickness": { + "default": 0.3 + }, + "raft_base_line_width": { + "default": 2 + }, + "raft_base_speed": { + "default": 15 + }, + "raft_interface_thickness": { + "default": 0.24 + }, + "raft_interface_line_width": { + "default": 0.6 + }, + "raft_airgap": { + "default": 0.2 + }, + "raft_surface_layers": { + "default": 2 + } + } +} \ No newline at end of file diff --git a/resources/machines/maker_starter.json b/resources/machines/maker_starter.json deleted file mode 100644 index 1d6dfa6a18..0000000000 --- a/resources/machines/maker_starter.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "id": "maker_starter", - "version": 1, - "name": "3DMaker Starter", - "manufacturer": "Other", - "author": "Other", - "icon": "icon_ultimaker2.png", - "platform": "makerstarter_platform.stl", - "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj", - "inherits": "fdmprinter.json", - - "overrides": { - "machine_width": { "default": 210 }, - "machine_depth": { "default": 185 }, - "machine_height": { "default": 200 }, - "machine_heated_bed": { "default": false }, - - "machine_center_is_zero": { "default": false }, - "machine_nozzle_size": { "default": 0.4 }, - "machine_nozzle_heat_up_speed": { "default": 2.0 }, - "machine_nozzle_cool_down_speed": { "default": 2.0 }, - "machine_head_shape_min_x": { "default": 0 }, - "machine_head_shape_min_y": { "default": 0 }, - "machine_head_shape_max_x": { "default": 0 }, - "machine_head_shape_max_y": { "default": 0 }, - "machine_nozzle_gantry_distance": { "default": 55 }, - "machine_gcode_flavor": { "default": "RepRap" }, - "machine_disallowed_areas": { "default": []}, - "machine_platform_offset": { "default": [0.0, 0.0, 0.0] }, - - "machine_nozzle_tip_outer_diameter": { "default": 1.0 }, - "machine_nozzle_head_distance": { "default": 3.0 }, - "machine_nozzle_expansion_angle": { "default": 45 }, - - "layer_height": { "default": 0.2 }, - "layer_height_0": { "default": 0.2, "visible": false }, - "wall_line_count": { "default": 2, "visible": true }, - "top_layers": { "default": 4, "visible": true }, - "bottom_layers": { "default": 4, "visible": true }, - "material_print_temperature": { "visible": false }, - "material_bed_temperature": { "visible": false }, - "material_diameter": { "default": 1.75, "visible": false }, - "material_flow": { "visible": false }, - "speed_print": { "default": 50.0 }, - "speed_wall": { "default": 30.0 }, - "speed_wall_0": { "default": 30.0 }, - "speed_wall_x": { "default": 30.0 }, - "speed_topbottom": { "default": 50.0 }, - "speed_support": { "default": 50.0 }, - "speed_travel": { "default": 120.0 }, - "speed_layer_0": { "default": 20.0 }, - "skirt_speed": { "default": 15.0 }, - "speed_slowdown_layers": { "default": 4 }, - "infill_sparse_density": { "default": 20.0 }, - "cool_fan_speed_min": { "default": 50.0 }, - "cool_fan_speed_max": { "default": 100.0 }, - "cool_fan_full_layer": { "default": 4, "visible": true }, - "cool_min_layer_time": { "default": 5.0 }, - "cool_min_layer_time_fan_speed_max": { "default": 10.0 }, - "support_type": { "default": "Everywhere" }, - "support_angle": { "default": 45.0, "visible": true }, - "support_xy_distance": { "default": 1 }, - "support_z_distance": { "default": 0.2 }, - "support_top_distance": { "default": 0.2 }, - "support_bottom_distance": { "default": 0.24 }, - "support_pattern": { "default": "ZigZag" }, - "support_infill_rate": { "default": 15, "visible": true }, - "adhesion_type": { "default": "Raft" }, - "skirt_minimal_length": { "default": 100.0 }, - "raft_base_line_spacing": { "default": 2.0 }, - "raft_base_thickness": { "default": 0.3 }, - "raft_base_line_width": { "default": 2.0 }, - "raft_base_speed": { "default": 15.0 }, - "raft_interface_thickness": { "default": 0.24 }, - "raft_interface_line_width": { "default": 0.6 }, - "raft_airgap": { "default": 0.2 }, - "raft_surface_layers": { "default": 2 } - } -} - - From da03eab355d3fed2d0dea94d1e5dd36f0f8dceec Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 16:30:28 +0200 Subject: [PATCH 144/705] Use default value rather than 'default' Default is outdated. Contributes to issue CURA-1278. --- resources/definitions/maker_starter.def.json | 116 +++++++++---------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/resources/definitions/maker_starter.def.json b/resources/definitions/maker_starter.def.json index 81ad45698e..376fea8c29 100644 --- a/resources/definitions/maker_starter.def.json +++ b/resources/definitions/maker_starter.def.json @@ -13,178 +13,178 @@ "overrides": { "machine_width": { - "default": 210 + "default_value": 210 }, "machine_depth": { - "default": 185 + "default_value": 185 }, "machine_height": { - "default": 200 + "default_value": 200 }, "machine_heated_bed": { - "default": false + "default_value": false }, "machine_center_is_zero": { - "default": false + "default_value": false }, "machine_nozzle_size": { - "default": 0.4 + "default_value": 0.4 }, "machine_nozzle_heat_up_speed": { - "default": 2 + "default_value": 2 }, "machine_nozzle_cool_down_speed": { - "default": 2 + "default_value": 2 }, "machine_head_shape_min_x": { - "default": 0 + "default_value": 0 }, "machine_head_shape_min_y": { - "default": 0 + "default_value": 0 }, "machine_head_shape_max_x": { - "default": 0 + "default_value": 0 }, "machine_head_shape_max_y": { - "default": 0 + "default_value": 0 }, "machine_nozzle_gantry_distance": { - "default": 55 + "default_value": 55 }, "machine_gcode_flavor": { - "default": "RepRap" + "default_value": "RepRap" }, "machine_disallowed_areas": { - "default": [] + "default_value": [] }, "machine_platform_offset": { - "default": [0, 0, 0] + "default_value": [0, 0, 0] }, "machine_nozzle_tip_outer_diameter": { - "default": 1 + "default_value": 1 }, "machine_nozzle_head_distance": { - "default": 3 + "default_value": 3 }, "machine_nozzle_expansion_angle": { - "default": 45 + "default_value": 45 }, "layer_height": { - "default": 0.2 + "default_value": 0.2 }, "layer_height_0": { - "default": 0.2 + "default_value": 0.2 }, "wall_line_count": { - "default": 2 + "default_value": 2 }, "top_layers": { - "default": 4 + "default_value": 4 }, "bottom_layers": { - "default": 4 + "default_value": 4 }, "speed_print": { - "default": 50 + "default_value": 50 }, "speed_wall": { - "default": 30 + "default_value": 30 }, "speed_wall_0": { - "default": 30 + "default_value": 30 }, "speed_wall_x": { - "default": 30 + "default_value": 30 }, "speed_topbottom": { - "default": 50 + "default_value": 50 }, "speed_support": { - "default": 50 + "default_value": 50 }, "speed_travel": { - "default": 120 + "default_value": 120 }, "speed_layer_0": { - "default": 20 + "default_value": 20 }, "skirt_speed": { - "default": 15 + "default_value": 15 }, "speed_slowdown_layers": { - "default": 4 + "default_value": 4 }, "infill_sparse_density": { - "default": 20 + "default_value": 20 }, "cool_fan_speed_min": { - "default": 50 + "default_value": 50 }, "cool_fan_speed_max": { - "default": 100 + "default_value": 100 }, "cool_fan_full_layer": { - "default": 4 + "default_value": 4 }, "cool_min_layer_time": { - "default": 5 + "default_value": 5 }, "cool_min_layer_time_fan_speed_max": { - "default": 10 + "default_value": 10 }, "support_type": { - "default": "Everywhere" + "default_value": "Everywhere" }, "support_angle": { - "default": 45 + "default_value": 45 }, "support_xy_distance": { - "default": 1 + "default_value": 1 }, "support_z_distance": { - "default": 0.2 + "default_value": 0.2 }, "support_top_distance": { - "default": 0.2 + "default_value": 0.2 }, "support_bottom_distance": { - "default": 0.24 + "default_value": 0.24 }, "support_pattern": { - "default": "ZigZag" + "default_value": "ZigZag" }, "support_infill_rate": { - "default": 15 + "default_value": 15 }, "adhesion_type": { - "default": "Raft" + "default_value": "Raft" }, "skirt_minimal_length": { - "default": 100 + "default_value": 100 }, "raft_base_line_spacing": { - "default": 2 + "default_value": 2 }, "raft_base_thickness": { - "default": 0.3 + "default_value": 0.3 }, "raft_base_line_width": { - "default": 2 + "default_value": 2 }, "raft_base_speed": { - "default": 15 + "default_value": 15 }, "raft_interface_thickness": { - "default": 0.24 + "default_value": 0.24 }, "raft_interface_line_width": { - "default": 0.6 + "default_value": 0.6 }, "raft_airgap": { - "default": 0.2 + "default_value": 0.2 }, "raft_surface_layers": { - "default": 2 + "default_value": 2 } } } \ No newline at end of file From 28703981d5df0ac7f36b24887711187581345580 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 16:42:33 +0200 Subject: [PATCH 145/705] Translate definition for Prusa i3 Contributes to issue CURA-1278. --- resources/definitions/prusa_i3.def.json | 68 +++++++++++++++++++++++++ resources/machines/prusa_i3.json | 36 ------------- 2 files changed, 68 insertions(+), 36 deletions(-) create mode 100644 resources/definitions/prusa_i3.def.json delete mode 100644 resources/machines/prusa_i3.json diff --git a/resources/definitions/prusa_i3.def.json b/resources/definitions/prusa_i3.def.json new file mode 100644 index 0000000000..26c36b605e --- /dev/null +++ b/resources/definitions/prusa_i3.def.json @@ -0,0 +1,68 @@ +{ + "id": "prusa_i3", + "version": 2, + "name": "Prusa i3", + "inherits": "fdmprinter", + "metadata": { + "author": "Quillford", + "manufacturer": "Prusajr", + "category": "Other", + "file_formats": "text/x-gcode", + "icon": "icon_ultimaker2", + "platform": "prusai3_platform.stl" + }, + + "overrides": { + "machine_heated_bed": { + "default_value": true + }, + "machine_width": { + "default_value": 200 + }, + "machine_height": { + "default_value": 200 + }, + "machine_depth": { + "default_value": 200 + }, + "machine_center_is_zero": { + "default_value": false + }, + "machine_nozzle_size": { + "default_value": 0.4 + }, + "material_diameter": { + "default_value": 1.75 + }, + "machine_nozzle_heat_up_speed": { + "default_value": 2 + }, + "machine_nozzle_cool_down_speed": { + "default_value": 2 + }, + "machine_head_shape_min_x": { + "default_value": 75 + }, + "machine_head_shape_min_y": { + "default_value": 18 + }, + "machine_head_shape_max_x": { + "default_value": 18 + }, + "machine_head_shape_max_y": { + "default_value": 35 + }, + "machine_nozzle_gantry_distance": { + "default_value": 55 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." + }, + "machine_end_gcode": { + "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" + } + } +} \ No newline at end of file diff --git a/resources/machines/prusa_i3.json b/resources/machines/prusa_i3.json deleted file mode 100644 index dcbca32801..0000000000 --- a/resources/machines/prusa_i3.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "id": "prusa_i3", - "version": 1, - "name": "Prusa i3", - "manufacturer": "Other", - "author": "Other", - "icon": "icon_ultimaker2.png", - "platform": "prusai3_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "overrides": { - "machine_heated_bed": { "default": true }, - "machine_width": { "default": 200 }, - "machine_height": { "default": 200 }, - "machine_depth": { "default": 200 }, - "machine_center_is_zero": { "default": false }, - "machine_nozzle_size": { "default": 0.4 }, - "material_diameter": { "default": 1.75 }, - "machine_nozzle_heat_up_speed": { "default": 2.0 }, - "machine_nozzle_cool_down_speed": { "default": 2.0 }, - "machine_head_shape_min_x": { "default": 75 }, - "machine_head_shape_min_y": { "default": 18 }, - "machine_head_shape_max_x": { "default": 18 }, - "machine_head_shape_max_y": { "default": 35 }, - "machine_nozzle_gantry_distance": { "default": 55 }, - "machine_gcode_flavor": { "default": "RepRap (Marlin/Sprinter)" }, - - "machine_start_gcode": { - "default": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." - }, - "machine_end_gcode": { - "default": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" - } - } -} From 319eef1384c2aff41def14df9f699430cc0d3615 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 16:49:54 +0200 Subject: [PATCH 146/705] Translate definition for Prusa i3 XL Contributes to issue CURA-1278. --- resources/definitions/prusa_i3_xl.def.json | 68 ++++++++++++++++++++++ resources/machines/prusa_i3_xl.json | 36 ------------ 2 files changed, 68 insertions(+), 36 deletions(-) create mode 100644 resources/definitions/prusa_i3_xl.def.json delete mode 100644 resources/machines/prusa_i3_xl.json diff --git a/resources/definitions/prusa_i3_xl.def.json b/resources/definitions/prusa_i3_xl.def.json new file mode 100644 index 0000000000..0c2b9e823f --- /dev/null +++ b/resources/definitions/prusa_i3_xl.def.json @@ -0,0 +1,68 @@ +{ + "id": "prusa_i3_xl", + "version": 2, + "name": "Prusa i3 xl", + "inherits": "fdmprinter.json", + "metadata": { + "author": "guigashm", + "manufacturer": "Prusajr", + "category": "Other", + "file_formats": "text/x-gcode", + "icon": "icon_ultimaker2.png", + "platform": "prusai3_xl_platform.stl" + }, + + "overrides": { + "machine_heated_bed": { + "default_value": true + }, + "machine_width": { + "default_value": 200 + }, + "machine_height": { + "default_value": 200 + }, + "machine_depth": { + "default_value": 270 + }, + "machine_center_is_zero": { + "default_value": false + }, + "machine_nozzle_size": { + "default_value": 0.4 + }, + "material_diameter": { + "default_value": 1.75 + }, + "machine_nozzle_heat_up_speed": { + "default_value": 2.0 + }, + "machine_nozzle_cool_down_speed": { + "default_value": 2.0 + }, + "machine_head_shape_min_x": { + "default_value": 75 + }, + "machine_head_shape_min_y": { + "default_value": 18 + }, + "machine_head_shape_max_x": { + "default_value": 18 + }, + "machine_head_shape_max_y": { + "default_value": 35 + }, + "machine_nozzle_gantry_distance": { + "default_value": 55 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." + }, + "machine_end_gcode": { + "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" + } + } +} \ No newline at end of file diff --git a/resources/machines/prusa_i3_xl.json b/resources/machines/prusa_i3_xl.json deleted file mode 100644 index b66b974983..0000000000 --- a/resources/machines/prusa_i3_xl.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "id": "prusa_i3_xl", - "version": 1, - "name": "Prusa i3 xl", - "manufacturer": "Other", - "author": "Other", - "icon": "icon_ultimaker2.png", - "platform": "prusai3_xl_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "overrides": { - "machine_heated_bed": { "default": true }, - "machine_width": { "default": 200 }, - "machine_height": { "default": 200 }, - "machine_depth": { "default": 270 }, - "machine_center_is_zero": { "default": false }, - "machine_nozzle_size": { "default": 0.4 }, - "material_diameter": { "default": 1.75 }, - "machine_nozzle_heat_up_speed": { "default": 2.0 }, - "machine_nozzle_cool_down_speed": { "default": 2.0 }, - "machine_head_shape_min_x": { "default": 75 }, - "machine_head_shape_min_y": { "default": 18 }, - "machine_head_shape_max_x": { "default": 18 }, - "machine_head_shape_max_y": { "default": 35 }, - "machine_nozzle_gantry_distance": { "default": 55 }, - "machine_gcode_flavor": { "default": "RepRap (Marlin/Sprinter)" }, - - "machine_start_gcode": { - "default": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." - }, - "machine_end_gcode": { - "default": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" - } - } -} From 35dda003c7791524d9ee975bbf3557b17a358e4c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 17:06:32 +0200 Subject: [PATCH 147/705] Translate definition for RigidBot Also translated the very old active_if properties! Contributes to issue CURA-1278. --- resources/definitions/rigidbot.def.json | 113 ++++++++++++++++++++++++ resources/machines/RigidBot.json | 57 ------------ 2 files changed, 113 insertions(+), 57 deletions(-) create mode 100644 resources/definitions/rigidbot.def.json delete mode 100644 resources/machines/RigidBot.json diff --git a/resources/definitions/rigidbot.def.json b/resources/definitions/rigidbot.def.json new file mode 100644 index 0000000000..0de11f09b8 --- /dev/null +++ b/resources/definitions/rigidbot.def.json @@ -0,0 +1,113 @@ +{ + "id": "rigidbot", + "version": 2, + "name": "RigidBot", + "inherits": "fdmprinter", + "metadata": { + "author": "RBC", + "manufacturer": "RigidBot", + "category": "Other", + "file_formats": "text/x-gcode", + "platform": "rigidbot_platform.stl" + }, + + "overrides": { + "machine_width": { + "default_value": 254 + }, + "machine_depth": { + "default_value": 254 + }, + "machine_height": { + "default_value": 254 + }, + "machine_heated_bed": { + "default_value": true + }, + "machine_nozzle_heat_up_speed": { + "default_value": 2 + }, + "machine_nozzle_cool_down_speed": { + "default_value": 2 + }, + "machine_head_shape_min_x": { + "default_value": 0 + }, + "machine_head_shape_min_y": { + "default_value": 0 + }, + "machine_head_shape_max_x": { + "default_value": 0 + }, + "machine_head_shape_max_y": { + "default_value": 0 + }, + "machine_nozzle_gantry_distance": { + "default_value": 0 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "default_value": ";Sliced at: {day} {date} {time}\n;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {infill_sparse_density}\n;Print time: {print_time}\n;Filament used: {filament_amount}m {filament_weight}g\n;Filament cost: {filament_cost}\n;M190 S{print_bed_temperature} ;Uncomment to add your own bed temperature line\n;M109 S{print_temperature} ;Uncomment to add your own temperature line\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nM205 X8 ;X/Y Jerk settings\nG1 Z15.0 F{travel_speed} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E7 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{travel_speed}\n;Put printing message on LCD screen\nM117 Rigibot Printing..." + }, + "machine_end_gcode": { + "default_value": ";End GCode\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+10 E-1 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG1 Y230 F3000 ;move Y so the head is out of the way and Plate is moved forward\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}" + }, + "layer_height": { + "default_value": 0.2 + }, + "wall_thickness": { + "default_value": 0.8 + }, + "top_bottom_thickness": { + "default_value": 0.3 + }, + "material_print_temperature": { + "default_value": 195 + }, + "material_bed_temperature": { + "default_value": 60 + }, + "material_diameter": { + "default_value": 1.75 + }, + "speed_print": { + "default_value": 60 + }, + "speed_infill": { + "default_value": 100 + }, + "speed_topbottom": { + "default_value": 15 + }, + "speed_travel": { + "default_value": 150 + }, + "speed_layer_0": { + "default_value": 15, + "min_value": "0.1" + }, + "infill_overlap": { + "default_value": 10 + }, + "cool_fan_enabled": { + "default_value": false + }, + "cool_fan_speed": { + "default_value": 0 + }, + "skirt_line_count": { + "default_value": 3, + "enabled": "adhesion_type == \"Skirt\"" + }, + "skirt_gap": { + "default_value": 4, + "enabled": "adhesion_type == \"Skirt\"" + }, + "skirt_minimal_length": { + "default_value": 200, + "enabled": "adhesion_type == \"Skirt\"" + } + } +} diff --git a/resources/machines/RigidBot.json b/resources/machines/RigidBot.json deleted file mode 100644 index efd5a6e72c..0000000000 --- a/resources/machines/RigidBot.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "id": "rigidbot", - "version": 1, - "name": "RigidBot", - "manufacturer": "Other", - "author": "RBC", - "platform": "rigidbot_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "machine_settings": { - - "machine_width": { "default": 254 }, - "machine_depth": { "default": 254 }, - "machine_height": { "default": 254 }, - "machine_heated_bed": { "default": true }, - - "machine_nozzle_size": { "default": 0.4, - "visible": true - }, - "machine_nozzle_heat_up_speed": { "default": 2.0 }, - "machine_nozzle_cool_down_speed": { "default": 2.0 }, - "machine_head_shape_min_x": { "default": 0 }, - "machine_head_shape_min_y": { "default": 0 }, - "machine_head_shape_max_x": { "default": 0 }, - "machine_head_shape_max_y": { "default": 0 }, - "machine_nozzle_gantry_distance": { "default": 0 }, - "machine_gcode_flavor": { "default": "RepRap (Marlin/Sprinter)" }, - - "machine_start_gcode": { - "default": ";Sliced at: {day} {date} {time}\n;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {infill_sparse_density}\n;Print time: {print_time}\n;Filament used: {filament_amount}m {filament_weight}g\n;Filament cost: {filament_cost}\n;M190 S{print_bed_temperature} ;Uncomment to add your own bed temperature line\n;M109 S{print_temperature} ;Uncomment to add your own temperature line\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nM205 X8 ;X/Y Jerk settings\nG1 Z15.0 F{travel_speed} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E7 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{travel_speed}\n;Put printing message on LCD screen\nM117 Rigibot Printing..." - }, - "machine_end_gcode": { - "default": ";End GCode\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+10 E-1 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG1 Y230 F3000 ;move Y so the head is out of the way and Plate is moved forward\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}" - } - }, - - "overrides": { - "layer_height": { "default": 0.2 }, - "wall_thickness": { "default": 0.8 }, - "top_bottom_thickness": { "default": 0.3, "visible": true }, - "material_print_temperature": { "default": 195, "visible": true }, - "material_bed_temperature": { "default": 60, "visible": true }, - "material_diameter": { "default": 1.75, "visible": true }, - "speed_print": { "default": 60.0, "visible": true }, - "speed_infill": { "default": 100.0, "visible": true }, - "speed_topbottom": { "default": 15.0, "visible": true }, - "speed_travel": { "default": 150.0, "visible": true }, - "speed_layer_0": { "min_value": "0.1", "default": 15.0, "visible": true }, - "infill_overlap": { "default": 10.0 }, - "cool_fan_enabled": { "default": false, "visible": true }, - "cool_fan_speed": { "default": 0.0, "visible": true }, - "skirt_line_count": { "default": 3, "active_if": { "setting": "adhesion_type", "value": "None" } }, - "skirt_gap": { "default": 4.0, "active_if": { "setting": "adhesion_type", "value": "None" } }, - "skirt_minimal_length": { "default": 200.0, "active_if": { "setting": "adhesion_type", "value": "None" } } - } -} From eb11067d1574e2072718aec161f4d4e96b8c8f15 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 17:14:10 +0200 Subject: [PATCH 148/705] Translate definition for RigidBotBig Also translated the very old active_if properties! Contributes to issue CURA-1278. --- resources/definitions/rigidbot_big.def.json | 116 ++++++++++++++++++++ resources/machines/RigidBotBig.json | 55 ---------- 2 files changed, 116 insertions(+), 55 deletions(-) create mode 100644 resources/definitions/rigidbot_big.def.json delete mode 100644 resources/machines/RigidBotBig.json diff --git a/resources/definitions/rigidbot_big.def.json b/resources/definitions/rigidbot_big.def.json new file mode 100644 index 0000000000..045f86fafe --- /dev/null +++ b/resources/definitions/rigidbot_big.def.json @@ -0,0 +1,116 @@ +{ + "id": "rigidbotbig", + "version": 2, + "name": "RigidBotBig", + "inherits": "fdmprinter", + "metadata": { + "author": "RBC", + "manufacturer": "RigidBot", + "category": "Other", + "file_formats": "text/x-gcode", + "platform": "rigidbotbig_platform.stl" + }, + + "overrides": { + "machine_width": { + "default_value": 400 + }, + "machine_depth": { + "default_value": 300 + }, + "machine_height": { + "default_value": 254 + }, + "machine_heated_bed": { + "default_value": true + }, + "machine_nozzle_size": { + "default_value": 0.4 + }, + "machine_nozzle_heat_up_speed": { + "default_value": 2 + }, + "machine_nozzle_cool_down_speed": { + "default_value": 2 + }, + "machine_head_shape_min_x": { + "default_value": 0 + }, + "machine_head_shape_min_y": { + "default_value": 0 + }, + "machine_head_shape_max_x": { + "default_value": 0 + }, + "machine_head_shape_max_y": { + "default_value": 0 + }, + "machine_nozzle_gantry_distance": { + "default_value": 0 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "default_value": ";Sliced at: {day} {date} {time}\n;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {infill_sparse_density}\n;Print time: {print_time}\n;Filament used: {filament_amount}m {filament_weight}g\n;Filament cost: {filament_cost}\n;M190 S{print_bed_temperature} ;Uncomment to add your own bed temperature line\n;M109 S{print_temperature} ;Uncomment to add your own temperature line\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nM205 X8 ;X/Y Jerk settings\nG1 Z15.0 F{travel_speed} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E7 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{travel_speed}\n;Put printing message on LCD screen\nM117 Rigibot Printing..." + }, + "machine_end_gcode": { + "default_value": ";End GCode\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+10 E-1 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG1 Y230 F3000 ;move Y so the head is out of the way and Plate is moved forward\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}" + }, + "layer_height": { + "default_value": 0.2 + }, + "wall_thickness": { + "default_value": 0.8 + }, + "top_bottom_thickness": { + "default_value": 0.3 + }, + "material_print_temperature": { + "default_value": 195 + }, + "material_bed_temperature": { + "default_value": 60 + }, + "material_diameter": { + "default_value": 1.75 + }, + "speed_print": { + "default_value": 60 + }, + "speed_infill": { + "default_value": 100 + }, + "speed_topbottom": { + "default_value": 15 + }, + "speed_travel": { + "default_value": 150 + }, + "speed_layer_0": { + "default_value": 15, + "min_value": "0.1" + }, + "infill_overlap": { + "default_value": 10 + }, + "cool_fan_enabled": { + "default_value": false + }, + "cool_fan_speed": { + "default_value": 0 + }, + "skirt_line_count": { + "default_value": 3, + "enabled": "adhesion_type == \"Skirt\"" + }, + "skirt_gap": { + "default_value": 4, + "enabled": "adhesion_type == \"Skirt\"" + }, + "skirt_minimal_length": { + "default_value": 200, + "enabled": "adhesion_type == \"Skirt\"" + } + } +} \ No newline at end of file diff --git a/resources/machines/RigidBotBig.json b/resources/machines/RigidBotBig.json deleted file mode 100644 index 0f8fdb1481..0000000000 --- a/resources/machines/RigidBotBig.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "id": "rigidbotbig", - "version": 1, - "name": "RigidBotBig", - "manufacturer": "Other", - "author": "RBC", - "platform": "rigidbotbig_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "machine_settings": { - - "machine_width": { "default": 400 }, - "machine_depth": { "default": 300 }, - "machine_height": { "default": 254 }, - "machine_heated_bed": { "default": true }, - - "machine_nozzle_size": { "default": 0.4}, - "machine_nozzle_heat_up_speed": { "default": 2.0 }, - "machine_nozzle_cool_down_speed": { "default": 2.0 }, - "machine_head_shape_min_x": { "default": 0 }, - "machine_head_shape_min_y": { "default": 0 }, - "machine_head_shape_max_x": { "default": 0 }, - "machine_head_shape_max_y": { "default": 0 }, - "machine_nozzle_gantry_distance": { "default": 0 }, - "machine_gcode_flavor": { "default": "RepRap (Marlin/Sprinter)" }, - - "machine_start_gcode": { - "default": ";Sliced at: {day} {date} {time}\n;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {infill_sparse_density}\n;Print time: {print_time}\n;Filament used: {filament_amount}m {filament_weight}g\n;Filament cost: {filament_cost}\n;M190 S{print_bed_temperature} ;Uncomment to add your own bed temperature line\n;M109 S{print_temperature} ;Uncomment to add your own temperature line\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nM205 X8 ;X/Y Jerk settings\nG1 Z15.0 F{travel_speed} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E7 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{travel_speed}\n;Put printing message on LCD screen\nM117 Rigibot Printing..." - }, - "machine_end_gcode": { - "default": ";End GCode\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+10 E-1 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG1 Y230 F3000 ;move Y so the head is out of the way and Plate is moved forward\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}" - } - }, - - "overrides": { - "layer_height": { "default": 0.2 }, - "wall_thickness": { "default": 0.8 }, - "top_bottom_thickness": { "default": 0.3, "visible": true }, - "material_print_temperature": { "default": 195, "visible": true }, - "material_bed_temperature": { "default": 60, "visible": true }, - "material_diameter": { "default": 1.75, "visible": true }, - "speed_print": { "default": 60.0, "visible": true}, - "speed_infill": { "default": 100.0, "visible": true }, - "speed_topbottom": { "default": 15.0, "visible": true }, - "speed_travel": { "default": 150.0, "visible": true }, - "speed_layer_0": { "min_value": "0.1", "default": 15.0, "visible": true }, - "infill_overlap": { "default": 10.0 }, - "cool_fan_enabled": { "default": false, "visible": true}, - "cool_fan_speed": { "default": 0.0, "visible": true }, - "skirt_line_count": { "default": 3, "active_if": { "setting": "adhesion_type", "value": "None" } }, - "skirt_gap": { "default": 4.0, "active_if": { "setting": "adhesion_type", "value": "None" } }, - "skirt_minimal_length": { "default": 200.0, "active_if": { "setting": "adhesion_type", "value": "None" } } - } -} From f15445b1a3f2de6d5e191341059d3c707b628230 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 17:26:01 +0200 Subject: [PATCH 149/705] Translate definition for Ultimaker The preferred variant/profile/material has moved to the metadata. Contributes to issue CURA-1278. --- resources/definitions/ultimaker.def.json | 14 ++++++++++++++ resources/machines/ultimaker.json | 15 --------------- 2 files changed, 14 insertions(+), 15 deletions(-) create mode 100644 resources/definitions/ultimaker.def.json delete mode 100644 resources/machines/ultimaker.json diff --git a/resources/definitions/ultimaker.def.json b/resources/definitions/ultimaker.def.json new file mode 100644 index 0000000000..60e4dbbf40 --- /dev/null +++ b/resources/definitions/ultimaker.def.json @@ -0,0 +1,14 @@ +{ + "id": "ultimaker_base", + "version": 2, + "visible": false, + "name": "Ultimaker", + "inherits": "fdmprinter", + "metadata": { + "author": "Ultimaker", + "manufacturer": "Ultimaker", + "preferred_profile": "Normal Quality", + "preferred_nozzle": "0.4 mm", + "preferred_material": "PLA" + } +} diff --git a/resources/machines/ultimaker.json b/resources/machines/ultimaker.json deleted file mode 100644 index a7a9cd3994..0000000000 --- a/resources/machines/ultimaker.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "id": "ultimaker_base", - "version": 1, - "visible": false, - "name": "Ultimaker", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "inherits": "fdmprinter.json", - - "machine_preferences": { - "prefered_profile": "Normal Quality", - "prefered_variant": "0.4 mm", - "prefered_material": "PLA" - } -} From de7fe1185ed484380405cfd3aed3c5de662c2e05 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 17 May 2016 17:39:06 +0200 Subject: [PATCH 150/705] Translate definition for Ultimaker2 The extruder trains setting has been moved to dual_extrusion_printer.json. It must be merged into fdmprinter later. Contributes to issue CURA-1278. --- resources/definitions/ultimaker2.def.json | 108 ++++++++++++++++++ .../machines/dual_extrusion_printer.json | 58 +++++++++- resources/machines/ultimaker2.json | 95 --------------- 3 files changed, 162 insertions(+), 99 deletions(-) create mode 100644 resources/definitions/ultimaker2.def.json delete mode 100644 resources/machines/ultimaker2.json diff --git a/resources/definitions/ultimaker2.def.json b/resources/definitions/ultimaker2.def.json new file mode 100644 index 0000000000..10b6041f0f --- /dev/null +++ b/resources/definitions/ultimaker2.def.json @@ -0,0 +1,108 @@ +{ + "id": "ultimaker2", + "version": 2, + "name": "Ultimaker 2", + "inherits": "ultimaker", + "metadata": { + "author": "Ultimaker", + "manufacturer": "Ultimaker", + "file_formats": "text/x-gcode", + "icon": "icon_ultimaker2.png", + "platform": "ultimaker2_platform.obj", + "platform_texture": "Ultimaker2backplate.png" + }, + "overrides": { + "machine_start_gcode" : { + "default": "" + }, + "machine_end_gcode" : { + "default": "" + }, + "machine_width": { + "default": 223 + }, + "machine_depth": { + "default": 223 + }, + "machine_height": { + "default": 205 + }, + "machine_heated_bed": { + "default": true + }, + "machine_head_with_fans_polygon": + { + "default": [ + [ -42, 12 ], + [ -42, -32 ], + [ 62, 12 ], + [ 62, -32 ] + ] + }, + "machine_center_is_zero": { + "default": false + }, + "machine_nozzle_size": { + "default": 0.4, + "min_value": "0.001" + }, + "machine_nozzle_heat_up_speed": { + "default": 2 + }, + "machine_nozzle_cool_down_speed": { + "default": 2 + }, + "gantry_height": { + "default": 55 + }, + "machine_use_extruder_offset_to_offset_coords": { + "default": true + }, + "machine_gcode_flavor": { + "default": "UltiGCode" + }, + "machine_disallowed_areas": { + "default": [ + [[-115, 112.5], [ -82, 112.5], [ -84, 102.5], [-115, 102.5]], + [[ 115, 112.5], [ 115, 102.5], [ 110, 102.5], [ 108, 112.5]], + [[-115, -112.5], [-115, -104.5], [ -84, -104.5], [ -82, -112.5]], + [[ 115, -112.5], [ 108, -112.5], [ 110, -104.5], [ 115, -104.5]] + ]}, + "machine_platform_offset": { + "default": [9, 0, 0] + }, + "machine_nozzle_tip_outer_diameter": { + "default": 1 + }, + "machine_nozzle_head_distance": { + "default": 3 + }, + "machine_nozzle_expansion_angle": { + "default": 45 + }, + "material_print_temperature": { + "enabled": "False" + }, + "material_bed_temperature": { + "enabled": "False" + }, + "material_diameter": { + "enabled": "False" + }, + "material_flow": { + "enabled": "False" + }, + "retraction_amount": { + "enabled": "False" + }, + "retraction_speed": { + "enabled": "False" + }, + "retraction_retract_speed": { + "enabled": "False" + }, + "retraction_prime_speed": { + "enabled": "False" + } + } +} \ No newline at end of file diff --git a/resources/machines/dual_extrusion_printer.json b/resources/machines/dual_extrusion_printer.json index 2977345bcb..57ad490cdd 100644 --- a/resources/machines/dual_extrusion_printer.json +++ b/resources/machines/dual_extrusion_printer.json @@ -9,12 +9,62 @@ "machine_extruder_trains": { "0": { - "extruder_nr": { "default": 0 }, - "machine_nozzle_offset_x": { "default": 0.0 }, - "machine_nozzle_offset_y": { "default": 0.0 } + "extruder_nr": { + "default": 0 + }, + "machine_nozzle_offset_x": { + "default": 0 + }, + "machine_nozzle_offset_y": { + "default": 0 + }, + "machine_nozzle_heat_up_speed": { + "default": 2 + }, + "machine_nozzle_cool_down_speed": { + "default": 2 + }, + "machine_nozzle_tip_outer_diameter": { + "default": 1 + }, + "machine_nozzle_head_distance": { + "default": 3 + }, + "machine_nozzle_expansion_angle": { + "default": 45 + }, + "machine_heat_zone_length": { + "default": 16 + } }, "1": { - "extruder_nr": { "default": 1 } + "extruder_nr": { + "default": 1 + }, + "machine_nozzle_offset_x": { + "default": 0 + }, + "machine_nozzle_offset_y": { + "default": 0 + }, + "machine_nozzle_heat_up_speed": { + "default": 2 + }, + "machine_nozzle_cool_down_speed": { + "default": 2 + }, + "machine_nozzle_tip_outer_diameter": { + "default": 1 + }, + "machine_nozzle_head_distance": { + "default": 3 + }, + "machine_nozzle_expansion_angle": { + "default": 45 + }, + "machine_heat_zone_length": { + "default": 16 + } } }, diff --git a/resources/machines/ultimaker2.json b/resources/machines/ultimaker2.json deleted file mode 100644 index e19aec1336..0000000000 --- a/resources/machines/ultimaker2.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "id": "ultimaker2", - "version": 1, - "name": "Ultimaker 2", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "icon": "icon_ultimaker2.png", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2backplate.png", - "file_formats": "text/x-gcode", - - "inherits": "ultimaker.json", - - "machine_extruder_trains": { - "0": { - "machine_nozzle_heat_up_speed": { - "default": 2.0 - }, - "machine_nozzle_cool_down_speed": { - "default": 2.0 - }, - "machine_nozzle_tip_outer_diameter": { - "default": 1 - }, - "machine_nozzle_head_distance": { - "default": 3 - }, - "machine_nozzle_expansion_angle": { - "default": 45 - }, - "machine_heat_zone_length": { - "default": 16 - } - } - }, - "machine_settings": { - "machine_start_gcode" : { "default": "" }, - "machine_end_gcode" : { "default": "" }, - "machine_width": { "default": 223 }, - "machine_depth": { "default": 223 }, - "machine_height": { "default": 205 }, - "machine_heated_bed": { "default": true }, - - "machine_head_with_fans_polygon": - { - "default": [ - [ - -42, - 12 - ], - [ - -42, - -32 - ], - [ - 62, - 12 - ], - [ - 62, - -32 - ] - ] - }, - "machine_center_is_zero": { "default": false }, - "machine_nozzle_size": { "default": 0.4, "min_value": "0.001"}, - "machine_nozzle_heat_up_speed": { "default": 2.0 }, - "machine_nozzle_cool_down_speed": { "default": 2.0 }, - "gantry_height": { "default": 55 }, - "machine_use_extruder_offset_to_offset_coords": { "default": true }, - "machine_gcode_flavor": { "default": "UltiGCode" }, - "machine_disallowed_areas": { "default": [ - [[-115.0, 112.5], [ -82.0, 112.5], [ -84.0, 102.5], [-115.0, 102.5]], - [[ 115.0, 112.5], [ 115.0, 102.5], [ 110.0, 102.5], [ 108.0, 112.5]], - [[-115.0, -112.5], [-115.0, -104.5], [ -84.0, -104.5], [ -82.0, -112.5]], - [[ 115.0, -112.5], [ 108.0, -112.5], [ 110.0, -104.5], [ 115.0, -104.5]] - ]}, - "machine_platform_offset": { "default": [9.0, 0.0, 0.0] }, - - "machine_nozzle_tip_outer_diameter": { "default": 1.0 }, - "machine_nozzle_head_distance": { "default": 3.0 }, - "machine_nozzle_expansion_angle": { "default": 45 } - }, - - "overrides": { - "material_print_temperature": { "enabled": "False" }, - "material_bed_temperature": { "enabled": "False" }, - "material_diameter": { "enabled": "False" }, - "material_flow": { "enabled": "False" }, - "retraction_amount": { "enabled": "False" }, - "retraction_speed": { "enabled": "False" }, - "retraction_retract_speed": { "enabled": "False" }, - "retraction_prime_speed": { "enabled": "False" } - } -} From 0664cbd2f6ddf20aa7738a600ccd02576d005a8a Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 17 May 2016 18:37:18 +0200 Subject: [PATCH 151/705] Make sure to set the right type for the "current settings" instance container --- cura/MachineManagerModel.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 82c8cd1328..0d3540475e 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -76,6 +76,7 @@ class MachineManagerModel(QObject): current_settings_instance_container = UM.Settings.InstanceContainer(name + "_current_settings") current_settings_instance_container.addMetaDataEntry("machine", name) + current_settings_instance_container.addMetaDataEntry("type", "user") current_settings_instance_container.setDefinition(definitions[0]) UM.Settings.ContainerRegistry.getInstance().addContainer(current_settings_instance_container) From 9bfb98e75f04bfef75172222bddfb8710e9d7755 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 17 May 2016 18:38:06 +0200 Subject: [PATCH 152/705] Make ultimaker2 definition visible in the add machine dialog --- resources/definitions/ultimaker2.def.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/definitions/ultimaker2.def.json b/resources/definitions/ultimaker2.def.json index 10b6041f0f..c61f43c37c 100644 --- a/resources/definitions/ultimaker2.def.json +++ b/resources/definitions/ultimaker2.def.json @@ -4,6 +4,7 @@ "name": "Ultimaker 2", "inherits": "ultimaker", "metadata": { + "visible": true, "author": "Ultimaker", "manufacturer": "Ultimaker", "file_formats": "text/x-gcode", @@ -105,4 +106,4 @@ "enabled": "False" } } -} \ No newline at end of file +} From a187747bdc6df2e6980c40d3b545efcb6d7ca5e5 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 18 May 2016 09:35:05 +0200 Subject: [PATCH 153/705] prusa_i3_xl now inherits correct base file CURA-1278 --- resources/definitions/prusa_i3_xl.def.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/definitions/prusa_i3_xl.def.json b/resources/definitions/prusa_i3_xl.def.json index 0c2b9e823f..4017eda0f4 100644 --- a/resources/definitions/prusa_i3_xl.def.json +++ b/resources/definitions/prusa_i3_xl.def.json @@ -2,7 +2,7 @@ "id": "prusa_i3_xl", "version": 2, "name": "Prusa i3 xl", - "inherits": "fdmprinter.json", + "inherits": "fdmprinter", "metadata": { "author": "guigashm", "manufacturer": "Prusajr", From 43d42405b2c40287d39ff3034f34a07fb68ea38e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 18 May 2016 09:39:04 +0200 Subject: [PATCH 154/705] Updated property names to new API CURA-1278 --- .../definitions/innovo_inventor.def.json | 2 +- resources/definitions/m180.def.json | 6 +-- resources/definitions/rigidbot.def.json | 2 +- resources/definitions/rigidbot_big.def.json | 2 +- resources/definitions/ultimaker2.def.json | 40 +++++++++---------- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/resources/definitions/innovo_inventor.def.json b/resources/definitions/innovo_inventor.def.json index 5ab8d4f2e1..c2ccbdbc71 100644 --- a/resources/definitions/innovo_inventor.def.json +++ b/resources/definitions/innovo_inventor.def.json @@ -95,7 +95,7 @@ }, "speed_layer_0": { "default_value": 30.0, - "min_value": 0.1 + "minimum_value": 0.1 }, "infill_overlap": { "default_value": 10.0 diff --git a/resources/definitions/m180.def.json b/resources/definitions/m180.def.json index 36d8be6e1f..e339dbddee 100644 --- a/resources/definitions/m180.def.json +++ b/resources/definitions/m180.def.json @@ -25,7 +25,7 @@ }, "machine_nozzle_size": { "default_value": 0.4, - "min_value": "0.001" + "minimum_value": "0.001" }, "machine_head_with_fans_polygon": { "default_value": [ @@ -49,8 +49,8 @@ }, "material_diameter": { "default_value": 1.75, - "min_value_warning": "1.5", - "max_value_warning": "2.0" + "minimum_value_warning": "1.5", + "maximum_value_warning": "2.0" } } } \ No newline at end of file diff --git a/resources/definitions/rigidbot.def.json b/resources/definitions/rigidbot.def.json index 0de11f09b8..cf71508f3d 100644 --- a/resources/definitions/rigidbot.def.json +++ b/resources/definitions/rigidbot.def.json @@ -86,7 +86,7 @@ }, "speed_layer_0": { "default_value": 15, - "min_value": "0.1" + "minimum_value": "0.1" }, "infill_overlap": { "default_value": 10 diff --git a/resources/definitions/rigidbot_big.def.json b/resources/definitions/rigidbot_big.def.json index 045f86fafe..ef2c93015d 100644 --- a/resources/definitions/rigidbot_big.def.json +++ b/resources/definitions/rigidbot_big.def.json @@ -89,7 +89,7 @@ }, "speed_layer_0": { "default_value": 15, - "min_value": "0.1" + "minimum_value": "0.1" }, "infill_overlap": { "default_value": 10 diff --git a/resources/definitions/ultimaker2.def.json b/resources/definitions/ultimaker2.def.json index c61f43c37c..ae35858730 100644 --- a/resources/definitions/ultimaker2.def.json +++ b/resources/definitions/ultimaker2.def.json @@ -14,26 +14,26 @@ }, "overrides": { "machine_start_gcode" : { - "default": "" + "default_value": "" }, "machine_end_gcode" : { - "default": "" + "default_value": "" }, "machine_width": { - "default": 223 + "default_value": 223 }, "machine_depth": { - "default": 223 + "default_value": 223 }, "machine_height": { - "default": 205 + "default_value": 205 }, "machine_heated_bed": { - "default": true + "default_value": true }, "machine_head_with_fans_polygon": { - "default": [ + "default_value": [ [ -42, 12 ], [ -42, -32 ], [ 62, 12 ], @@ -41,45 +41,45 @@ ] }, "machine_center_is_zero": { - "default": false + "default_value": false }, "machine_nozzle_size": { - "default": 0.4, - "min_value": "0.001" + "default_value": 0.4, + "minimum_value": "0.001" }, "machine_nozzle_heat_up_speed": { - "default": 2 + "default_value": 2 }, "machine_nozzle_cool_down_speed": { - "default": 2 + "default_value": 2 }, "gantry_height": { - "default": 55 + "default_value": 55 }, "machine_use_extruder_offset_to_offset_coords": { - "default": true + "default_value": true }, "machine_gcode_flavor": { - "default": "UltiGCode" + "default_value": "UltiGCode" }, "machine_disallowed_areas": { - "default": [ + "default_value": [ [[-115, 112.5], [ -82, 112.5], [ -84, 102.5], [-115, 102.5]], [[ 115, 112.5], [ 115, 102.5], [ 110, 102.5], [ 108, 112.5]], [[-115, -112.5], [-115, -104.5], [ -84, -104.5], [ -82, -112.5]], [[ 115, -112.5], [ 108, -112.5], [ 110, -104.5], [ 115, -104.5]] ]}, "machine_platform_offset": { - "default": [9, 0, 0] + "default_value": [9, 0, 0] }, "machine_nozzle_tip_outer_diameter": { - "default": 1 + "default_value": 1 }, "machine_nozzle_head_distance": { - "default": 3 + "default_value": 3 }, "machine_nozzle_expansion_angle": { - "default": 45 + "default_value": 45 }, "material_print_temperature": { "enabled": "False" From 51e57b1f91f53729b7d66c33a404785c09e3ce63 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 18 May 2016 09:44:53 +0200 Subject: [PATCH 155/705] Added visibility meta data CURA-1278 --- resources/definitions/bq_hephestos.def.json | 1 + resources/definitions/bq_hephestos_2.def.json | 1 + resources/definitions/bq_hephestos_xl.def.json | 1 + resources/definitions/bq_witbox.def.json | 1 + resources/definitions/bq_witbox_2.def.json | 1 + resources/definitions/grr_neo.def.json | 1 + resources/definitions/innovo_inventor.def.json | 1 + resources/definitions/m180.def.json | 1 + resources/definitions/maker_starter.def.json | 1 + resources/definitions/prusa_i3.def.json | 1 + resources/definitions/prusa_i3_xl.def.json | 1 + resources/definitions/rigidbot.def.json | 1 + resources/definitions/rigidbot_big.def.json | 1 + 13 files changed, 13 insertions(+) diff --git a/resources/definitions/bq_hephestos.def.json b/resources/definitions/bq_hephestos.def.json index b9f0f3dca5..65d6fc38a3 100644 --- a/resources/definitions/bq_hephestos.def.json +++ b/resources/definitions/bq_hephestos.def.json @@ -4,6 +4,7 @@ "version": 2, "inherits": "fdmprinter", "metadata": { + "visible": true, "author": "BQ", "manufacturer": "BQ", "category": "Other", diff --git a/resources/definitions/bq_hephestos_2.def.json b/resources/definitions/bq_hephestos_2.def.json index e072fbf1db..959b53bd48 100644 --- a/resources/definitions/bq_hephestos_2.def.json +++ b/resources/definitions/bq_hephestos_2.def.json @@ -4,6 +4,7 @@ "name": "BQ Hephestos 2", "inherits": "fdmprinter", "metadata": { + "visible": true, "author": "BQ", "manufacturer": "BQ", "category": "Other", diff --git a/resources/definitions/bq_hephestos_xl.def.json b/resources/definitions/bq_hephestos_xl.def.json index 224d219504..9cf5b685db 100644 --- a/resources/definitions/bq_hephestos_xl.def.json +++ b/resources/definitions/bq_hephestos_xl.def.json @@ -4,6 +4,7 @@ "name": "BQ Prusa i3 Hephestos XL", "inherits": "fdmprinter", "metadata": { + "visible": true, "manufacturer": "BQ", "author": "BQ", "category": "Other", diff --git a/resources/definitions/bq_witbox.def.json b/resources/definitions/bq_witbox.def.json index 3d021cc529..77826a1576 100644 --- a/resources/definitions/bq_witbox.def.json +++ b/resources/definitions/bq_witbox.def.json @@ -4,6 +4,7 @@ "name": "BQ Witbox", "inherits": "fdmprinter", "metadata": { + "visible": true, "author": "BQ", "manufacturer": "BQ", "category": "Other", diff --git a/resources/definitions/bq_witbox_2.def.json b/resources/definitions/bq_witbox_2.def.json index 58f70c95b7..a98a8b909d 100644 --- a/resources/definitions/bq_witbox_2.def.json +++ b/resources/definitions/bq_witbox_2.def.json @@ -4,6 +4,7 @@ "name": "BQ Witbox 2", "inherits": "fdmprinter", "metadata": { + "visible": true, "author": "BQ", "manufacturer": "BQ", "category": "Other", diff --git a/resources/definitions/grr_neo.def.json b/resources/definitions/grr_neo.def.json index 3fb6804c40..9fc5d2121e 100644 --- a/resources/definitions/grr_neo.def.json +++ b/resources/definitions/grr_neo.def.json @@ -4,6 +4,7 @@ "name": "German RepRap Neo", "inherits": "fdmprinter", "metadata": { + "visible": true, "author": "Simon Cor", "manufacturer": "German RepRap", "category": "Other", diff --git a/resources/definitions/innovo_inventor.def.json b/resources/definitions/innovo_inventor.def.json index c2ccbdbc71..d40256813b 100644 --- a/resources/definitions/innovo_inventor.def.json +++ b/resources/definitions/innovo_inventor.def.json @@ -4,6 +4,7 @@ "name": "Innovo INVENTOR", "inherits": "fdmprinter", "metadata": { + "visible": true, "author": "Adam Rumjahn", "manufacturer": "Innovo", "category": "Other", diff --git a/resources/definitions/m180.def.json b/resources/definitions/m180.def.json index e339dbddee..bb027d33bc 100644 --- a/resources/definitions/m180.def.json +++ b/resources/definitions/m180.def.json @@ -4,6 +4,7 @@ "name": "Malyan M180", "inherits": "fdmprinter", "metadata": { + "visible": true, "author": "Ruben Dulek", "manufacturer": "Malyan", "category": "Other", diff --git a/resources/definitions/maker_starter.def.json b/resources/definitions/maker_starter.def.json index 376fea8c29..797b57f771 100644 --- a/resources/definitions/maker_starter.def.json +++ b/resources/definitions/maker_starter.def.json @@ -4,6 +4,7 @@ "name": "3DMaker Starter", "inherits": "fdmprinter", "metadata": { + "visible": true, "author": "tvlgiao", "manufacturer": "3DMaker", "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj", diff --git a/resources/definitions/prusa_i3.def.json b/resources/definitions/prusa_i3.def.json index 26c36b605e..21db84838a 100644 --- a/resources/definitions/prusa_i3.def.json +++ b/resources/definitions/prusa_i3.def.json @@ -4,6 +4,7 @@ "name": "Prusa i3", "inherits": "fdmprinter", "metadata": { + "visible": true, "author": "Quillford", "manufacturer": "Prusajr", "category": "Other", diff --git a/resources/definitions/prusa_i3_xl.def.json b/resources/definitions/prusa_i3_xl.def.json index 4017eda0f4..ddd1796eb7 100644 --- a/resources/definitions/prusa_i3_xl.def.json +++ b/resources/definitions/prusa_i3_xl.def.json @@ -4,6 +4,7 @@ "name": "Prusa i3 xl", "inherits": "fdmprinter", "metadata": { + "visible": true, "author": "guigashm", "manufacturer": "Prusajr", "category": "Other", diff --git a/resources/definitions/rigidbot.def.json b/resources/definitions/rigidbot.def.json index cf71508f3d..e70c407463 100644 --- a/resources/definitions/rigidbot.def.json +++ b/resources/definitions/rigidbot.def.json @@ -4,6 +4,7 @@ "name": "RigidBot", "inherits": "fdmprinter", "metadata": { + "visible": true, "author": "RBC", "manufacturer": "RigidBot", "category": "Other", diff --git a/resources/definitions/rigidbot_big.def.json b/resources/definitions/rigidbot_big.def.json index ef2c93015d..f4b282d9db 100644 --- a/resources/definitions/rigidbot_big.def.json +++ b/resources/definitions/rigidbot_big.def.json @@ -4,6 +4,7 @@ "name": "RigidBotBig", "inherits": "fdmprinter", "metadata": { + "visible": true, "author": "RBC", "manufacturer": "RigidBot", "category": "Other", From b635b075690938f85a2b63071c91575d36352d28 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 09:47:15 +0200 Subject: [PATCH 156/705] Translate definition for Ultimaker 2 Extended Contributes to issue CURA-1278. --- .../definitions/ultimaker2_extended.def.json | 20 +++++++++++++++++++ resources/machines/ultimaker2_extended.json | 16 --------------- 2 files changed, 20 insertions(+), 16 deletions(-) create mode 100644 resources/definitions/ultimaker2_extended.def.json delete mode 100644 resources/machines/ultimaker2_extended.json diff --git a/resources/definitions/ultimaker2_extended.def.json b/resources/definitions/ultimaker2_extended.def.json new file mode 100644 index 0000000000..1d7ef8bbd2 --- /dev/null +++ b/resources/definitions/ultimaker2_extended.def.json @@ -0,0 +1,20 @@ +{ + "id": "ultimaker2_extended", + "version": 2, + "name": "Ultimaker 2 Extended", + "inherits": "ultimaker2", + "metadata": { + "author": "Ultimaker", + "manufacturer": "Ultimaker", + "file_formats": "text/x-gcode", + "icon": "icon_ultimaker2.png", + "platform": "ultimaker2_platform.obj", + "platform_texture": "Ultimaker2Extendedbackplate.png" + }, + + "overrides": { + "machine_height": { + "default": 315 + } + } +} diff --git a/resources/machines/ultimaker2_extended.json b/resources/machines/ultimaker2_extended.json deleted file mode 100644 index 0cd5ff0002..0000000000 --- a/resources/machines/ultimaker2_extended.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "id": "ultimaker2_extended", - "version": 1, - "name": "Ultimaker 2 Extended", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "icon": "icon_ultimaker2.png", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2Extendedbackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker2.json", - - "machine_settings": { - "machine_height": { "default": 315 } - } -} From 34632a762a44512ef409eb0f11d339b925723b15 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 09:48:44 +0200 Subject: [PATCH 157/705] Use default_value instead of default Forgot this again. Good morning Ghostkeeper. Contributes to issue CURA-1278. --- resources/definitions/ultimaker2_extended.def.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/definitions/ultimaker2_extended.def.json b/resources/definitions/ultimaker2_extended.def.json index 1d7ef8bbd2..361132ea95 100644 --- a/resources/definitions/ultimaker2_extended.def.json +++ b/resources/definitions/ultimaker2_extended.def.json @@ -14,7 +14,7 @@ "overrides": { "machine_height": { - "default": 315 + "default_value": 315 } } } From a7f93b2a922dce298fca3894e57aa6368c955939 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 09:50:04 +0200 Subject: [PATCH 158/705] Add category to metadata Also forgot that. Good morning, Ghost. Contributes to issue CURA-1278. --- resources/definitions/ultimaker2_extended.def.json | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/definitions/ultimaker2_extended.def.json b/resources/definitions/ultimaker2_extended.def.json index 361132ea95..e3c7d1fd01 100644 --- a/resources/definitions/ultimaker2_extended.def.json +++ b/resources/definitions/ultimaker2_extended.def.json @@ -6,6 +6,7 @@ "metadata": { "author": "Ultimaker", "manufacturer": "Ultimaker", + "category": "Ultimaker", "file_formats": "text/x-gcode", "icon": "icon_ultimaker2.png", "platform": "ultimaker2_platform.obj", From 4947dfffb8e27e8c70c6f14f9c10cb6649557f03 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 09:52:54 +0200 Subject: [PATCH 159/705] Translate definition for Ultimaker 2 Extended+ It remains to be seen what we do with the variants of this machine and consequently the visibility of this machine. Contributes to issue CURA-1278. --- .../ultimaker2_extended_plus.def.json | 30 +++++++++++++++++++ .../machines/ultimaker2_extended_plus.json | 19 ------------ 2 files changed, 30 insertions(+), 19 deletions(-) create mode 100644 resources/definitions/ultimaker2_extended_plus.def.json delete mode 100644 resources/machines/ultimaker2_extended_plus.json diff --git a/resources/definitions/ultimaker2_extended_plus.def.json b/resources/definitions/ultimaker2_extended_plus.def.json new file mode 100644 index 0000000000..5283209745 --- /dev/null +++ b/resources/definitions/ultimaker2_extended_plus.def.json @@ -0,0 +1,30 @@ +{ + "id": "ultimaker2_extended_plus_base", + "version": 2, + "name": "Ultimaker 2 Extended+", + "inherits": "ultimaker2plus", + "visible": false, + "metadata": { + "author": "Ultimaker", + "manufacturer": "Ultimaker", + "category": "Ultimaker", + "file_formats": "text/x-gcode", + "platform": "ultimaker2_platform.obj", + "platform_texture": "Ultimaker2ExtendedPlusbackplate.png" + }, + + "overrides": { + "machine_height": { + "default_value": 313 + }, + "machine_show_variants": { + "default_value": true + }, + "machine_nozzle_head_distance": { + "default_value": 5 + }, + "machine_nozzle_expansion_angle": { + "default_value": 45 + } + } +} diff --git a/resources/machines/ultimaker2_extended_plus.json b/resources/machines/ultimaker2_extended_plus.json deleted file mode 100644 index 318361a894..0000000000 --- a/resources/machines/ultimaker2_extended_plus.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "id": "ultimaker2_extended_plus_base", - "version": 1, - "name": "Ultimaker 2 Extended+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2ExtendedPlusbackplate.png", - "visible": false, - "file_formats": "text/x-gcode", - "inherits": "ultimaker2plus.json", - - "machine_settings": { - "machine_height": { "default": 313 }, - "machine_show_variants": { "default": true }, - "machine_nozzle_head_distance": { "default": 5 }, - "machine_nozzle_expansion_angle": { "default": 45 } - } -} From d0c9b964167678c05efcb5f5c7f9cb0a9beb4d07 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 09:57:25 +0200 Subject: [PATCH 160/705] Translate definition for Ultimaker 2 Go Contributes to issue CURA-1278. --- resources/definitions/ultimaker2_go.def.json | 41 ++++++++++++++++++++ resources/machines/ultimaker2_go.json | 26 ------------- 2 files changed, 41 insertions(+), 26 deletions(-) create mode 100644 resources/definitions/ultimaker2_go.def.json delete mode 100644 resources/machines/ultimaker2_go.json diff --git a/resources/definitions/ultimaker2_go.def.json b/resources/definitions/ultimaker2_go.def.json new file mode 100644 index 0000000000..e439006170 --- /dev/null +++ b/resources/definitions/ultimaker2_go.def.json @@ -0,0 +1,41 @@ +{ + "id": "ultimaker2_go", + "version": 2, + "name": "Ultimaker 2 Go", + "inherits": "ultimaker2", + "metadata": { + "author": "Ultimaker", + "manufacturer": "Ultimaker", + "category": "Ultimaker", + "file_formats": "text/x-gcode", + "icon": "icon_ultimaker2.png", + "platform": "ultimaker2go_platform.obj", + "platform_texture": "Ultimaker2Gobackplate.png" + }, + + "overrides": { + "machine_width": { + "default_value": 120 + }, + "machine_depth": { + "default_value": 120 + }, + "machine_height": { + "default_value": 115 + }, + "machine_heated_bed": { + "default_value": false + }, + "machine_disallowed_areas": { + "default_value": [ + [[-60, 60], [-33, 60], [-35, 52], [-60, 52]], + [[ 60, 60], [ 60, 52], [ 35, 52], [ 33, 60]], + [[-60, -60], [-60, -52], [-35, -52], [-33, -60]], + [[ 60, -60], [ 33, -60], [ 35, -52], [ 60, -52]] + ] + }, + "machine_platform_offset": { + "default_value": [0, 0, 0] + } + } +} diff --git a/resources/machines/ultimaker2_go.json b/resources/machines/ultimaker2_go.json deleted file mode 100644 index cc2cde09d7..0000000000 --- a/resources/machines/ultimaker2_go.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "id": "ultimaker2_go", - "version": 1, - "name": "Ultimaker 2 Go", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "icon": "icon_ultimaker2.png", - "platform": "ultimaker2go_platform.obj", - "platform_texture": "Ultimaker2Gobackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker2.json", - - "overrides": { - "machine_width": { "default": 120 }, - "machine_depth": { "default": 120 }, - "machine_height": { "default": 115 }, - "machine_heated_bed": { "default": false }, - "machine_disallowed_areas": { "default": [ - [[-60.0, 60.0], [-33.0, 60.0], [-35.0, 52.0], [-60.0, 52.0]], - [[ 60.0, 60.0], [ 60.0, 52.0], [ 35.0, 52.0], [ 33.0, 60.0]], - [[-60.0, -60.0], [-60.0, -52.0], [-35.0, -52.0], [-33.0, -60.0]], - [[ 60.0, -60.0], [ 33.0, -60.0], [ 35.0, -52.0], [ 60.0, -52.0]] - ]}, - "machine_platform_offset": { "default": [0.0, 0.0, 0.0] } - } -} From 2b47fc738b3c5cf5af936ef793a5a0bbac6befbc Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 10:16:54 +0200 Subject: [PATCH 161/705] Translate definition for Ultimaker 2+ I've translated the inherit functions as values. Contributes to issue CURA-1278. --- .../definitions/ultimaker2_plus.def.json | 71 +++++++++++++++++++ resources/machines/ultimaker2plus.json | 54 -------------- 2 files changed, 71 insertions(+), 54 deletions(-) create mode 100644 resources/definitions/ultimaker2_plus.def.json delete mode 100644 resources/machines/ultimaker2plus.json diff --git a/resources/definitions/ultimaker2_plus.def.json b/resources/definitions/ultimaker2_plus.def.json new file mode 100644 index 0000000000..6a61d18d3c --- /dev/null +++ b/resources/definitions/ultimaker2_plus.def.json @@ -0,0 +1,71 @@ +{ + "id": "ultimaker2plus_base", + "version": 2, + "name": "Ultimaker 2+", + "inherits": "ultimaker2", + "visible": "false", + "metadata": { + "author": "Ultimaker", + "manufacturer": "Ultimaker", + "category": "Ultimaker", + "file_formats": "text/x-gcode", + "platform": "ultimaker2_platform.obj", + "platform_texture": "Ultimaker2Plusbackplate.png" + }, + + "overrides": { + "speed_infill": { + "value": "speed_print" + }, + "speed_wall_x": { + "value": "speed_wall" + }, + "layer_height_0": { + "value": "round(machine_nozzle_size / 1.5, 2)" + }, + "line_width": { + "value": "round(machine_nozzle_size * 0.875, 2)" + }, + "speed_layer_0": { + "default_value": 20 + }, + "speed_support": { + "value": "speed_wall_0" + }, + "machine_height": { + "default_value": 203 + }, + "machine_show_variants": { + "default_value": true + }, + "gantry_height": { + "default_value": 52 + }, + "machine_nozzle_head_distance": { + "default_value": 5 + }, + "machine_nozzle_expansion_angle": { + "default_value": 45 + }, + "machine_heat_zone_length": { + "default_value": 20 + }, + "machine_head_with_fans_polygon": + { + "default_value": [ + [ -44, 14 ], + [ -44, -34 ], + [ 64, 14 ], + [ 64, -34 ] + ] + }, + "machine_disallowed_areas": { + "default_value": [ + [[-115, 112.5], [ -78, 112.5], [ -80, 102.5], [-115, 102.5]], + [[ 115, 112.5], [ 115, 102.5], [ 105, 102.5], [ 103, 112.5]], + [[-115, -112.5], [-115, -104.5], [ -84, -104.5], [ -82, -112.5]], + [[ 115, -112.5], [ 108, -112.5], [ 110, -104.5], [ 115, -104.5]] + ] + } + } +} diff --git a/resources/machines/ultimaker2plus.json b/resources/machines/ultimaker2plus.json deleted file mode 100644 index cc86bd8ce3..0000000000 --- a/resources/machines/ultimaker2plus.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "id": "ultimaker2plus_base", - "version": 1, - "name": "Ultimaker 2+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2Plusbackplate.png", - "visible": false, - "file_formats": "text/x-gcode", - "inherits": "ultimaker2.json", - - "overrides": { - "speed_infill": { "inherit_function": "speed_print" }, - "speed_wall_x": { "inherit_function": "speed_wall" }, - "layer_height_0": { "inherit_function": "round(machine_nozzle_size / 1.5, 2)" }, - "line_width": { "inherit_function": "round(machine_nozzle_size * 0.875, 2)" }, - "speed_layer_0": { "default": "20" }, - "speed_support": { "inherit_function": "speed_wall_0" }, - "machine_height": { "default": 203 }, - "machine_show_variants": { "default": true }, - "gantry_height": { "default": 52 }, - "machine_nozzle_head_distance": { "default": 5 }, - "machine_nozzle_expansion_angle": { "default": 45 }, - "machine_heat_zone_length": { "default": 20 }, - "machine_head_with_fans_polygon": - { - "default": [ - [ - -44, - 14 - ], - [ - -44, - -34 - ], - [ - 64, - 14 - ], - [ - 64, - -34 - ] - ] - }, - "machine_disallowed_areas": { "default": [ - [[-115.0, 112.5], [ -78.0, 112.5], [ -80.0, 102.5], [-115.0, 102.5]], - [[ 115.0, 112.5], [ 115.0, 102.5], [ 105.0, 102.5], [ 103.0, 112.5]], - [[-115.0, -112.5], [-115.0, -104.5], [ -84.0, -104.5], [ -82.0, -112.5]], - [[ 115.0, -112.5], [ 108.0, -112.5], [ 110.0, -104.5], [ 115.0, -104.5]] - ]} - } -} From 7714d6f720b4cdeedce8fc4b934964c5c0d5f4bc Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 10:21:30 +0200 Subject: [PATCH 162/705] Translate definition for Ultimaker Original Contributes to issue CURA-1278. --- .../definitions/ultimaker_original.def.json | 70 ++++++++++++++++ resources/machines/ultimaker_original.json | 83 ------------------- 2 files changed, 70 insertions(+), 83 deletions(-) create mode 100644 resources/definitions/ultimaker_original.def.json delete mode 100644 resources/machines/ultimaker_original.json diff --git a/resources/definitions/ultimaker_original.def.json b/resources/definitions/ultimaker_original.def.json new file mode 100644 index 0000000000..8f47962be9 --- /dev/null +++ b/resources/definitions/ultimaker_original.def.json @@ -0,0 +1,70 @@ +{ + "id": "ultimaker_original", + "version": 2, + "name": "Ultimaker Original", + "inherits": "ultimaker", + "metadata": { + "author": "Ultimaker", + "manufacturer": "Ultimaker", + "file_formats": "text/x-gcode", + "icon": "icon_ultimaker.png", + "platform": "ultimaker_platform.stl", + "pages": [ + "SelectUpgradedParts", + "UpgradeFirmware", + "UltimakerCheckup", + "BedLeveling" + ] + }, + + "overrides": { + "machine_width": { + "default": 205 + }, + "machine_height": { + "default": 200 + }, + "machine_depth": { + "default": 205 + }, + "machine_center_is_zero": { + "default": false + }, + "machine_nozzle_size": { + "default": 0.4 + }, + "machine_nozzle_heat_up_speed": { + "default": 2 + }, + "machine_nozzle_cool_down_speed": { + "default": 2 + }, + "machine_head_with_fans_polygon": + { + "default": [ + [ -75, 35 ], + [ -75, -18 ], + [ 18, 35 ], + [ 18, -18 ] + ] + }, + "gantry_height": { + "default": 55 + }, + "machine_use_extruder_offset_to_offset_coords": { + "default": true + }, + "machine_gcode_flavor": { + "default": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "default": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E6 ;extrude 6 mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." + }, + "machine_end_gcode": { + "default": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" + }, + "machine_extruder_drive_upgrade": { + "default": false + } + } +} diff --git a/resources/machines/ultimaker_original.json b/resources/machines/ultimaker_original.json deleted file mode 100644 index 3e694c1b8e..0000000000 --- a/resources/machines/ultimaker_original.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "id": "ultimaker_original", - "version": 1, - "name": "Ultimaker Original", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "icon": "icon_ultimaker.png", - "platform": "ultimaker_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "ultimaker.json", - - "pages": [ - "SelectUpgradedParts", - "UpgradeFirmware", - "UltimakerCheckup", - "BedLeveling" - ], - - "machine_extruder_trains": { - "0": { - "machine_nozzle_heat_up_speed": { - "default": 2.0 - }, - "machine_nozzle_cool_down_speed": { - "default": 2.0 - }, - "machine_nozzle_tip_outer_diameter": { - "default": 1 - }, - "machine_nozzle_head_distance": { - "default": 3 - }, - "machine_nozzle_expansion_angle": { - "default": 45 - }, - "machine_heat_zone_length": { - "default": 16 - } - } - }, - "overrides": { - "machine_width": { "default": 205 }, - "machine_height": { "default": 200 }, - "machine_depth": { "default": 205 }, - "machine_center_is_zero": { "default": false }, - "machine_nozzle_size": { "default": 0.4 }, - "machine_nozzle_heat_up_speed": { "default": 2.0 }, - "machine_nozzle_cool_down_speed": { "default": 2.0 }, - "machine_head_with_fans_polygon": - { - "default": [ - [ - -75, - 35 - ], - [ - -75, - -18 - ], - [ - 18, - 35 - ], - [ - 18, - -18 - ] - ] - }, - "gantry_height": { "default": 55 }, - "machine_use_extruder_offset_to_offset_coords": { "default": true }, - "machine_gcode_flavor": { "default": "RepRap (Marlin/Sprinter)" }, - - "machine_start_gcode": { - "default": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E6 ;extrude 6 mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." - }, - "machine_end_gcode": { - "default": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" - }, - - "machine_extruder_drive_upgrade": { "default": false } - } -} From 13726f1ec1444e1a5f0fc9bf35daee9060d3db31 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 10:24:18 +0200 Subject: [PATCH 163/705] Use default_value instead of default D'oh. Contributes to issue CURA-1278. --- .../definitions/ultimaker_original.def.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/resources/definitions/ultimaker_original.def.json b/resources/definitions/ultimaker_original.def.json index 8f47962be9..cd2fac4599 100644 --- a/resources/definitions/ultimaker_original.def.json +++ b/resources/definitions/ultimaker_original.def.json @@ -19,29 +19,29 @@ "overrides": { "machine_width": { - "default": 205 + "default_value": 205 }, "machine_height": { - "default": 200 + "default_value": 200 }, "machine_depth": { - "default": 205 + "default_value": 205 }, "machine_center_is_zero": { - "default": false + "default_value": false }, "machine_nozzle_size": { - "default": 0.4 + "default_value": 0.4 }, "machine_nozzle_heat_up_speed": { - "default": 2 + "default_value": 2 }, "machine_nozzle_cool_down_speed": { - "default": 2 + "default_value": 2 }, "machine_head_with_fans_polygon": { - "default": [ + "default_value": [ [ -75, 35 ], [ -75, -18 ], [ 18, 35 ], @@ -49,22 +49,22 @@ ] }, "gantry_height": { - "default": 55 + "default_value": 55 }, "machine_use_extruder_offset_to_offset_coords": { - "default": true + "default_value": true }, "machine_gcode_flavor": { - "default": "RepRap (Marlin/Sprinter)" + "default_value": "RepRap (Marlin/Sprinter)" }, "machine_start_gcode": { - "default": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E6 ;extrude 6 mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." + "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E6 ;extrude 6 mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." }, "machine_end_gcode": { - "default": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" + "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" }, "machine_extruder_drive_upgrade": { - "default": false + "default_value": false } } } From 39907c23db19c16f1922ccdc484a1477369c60c7 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 10:25:03 +0200 Subject: [PATCH 164/705] Translate definition for Ultimaker Original+ Contributes to issue CURA-1278. --- .../ultimaker_original_plus.def.json | 26 +++++++++++++++++++ .../machines/ultimaker_original_plus.json | 22 ---------------- 2 files changed, 26 insertions(+), 22 deletions(-) create mode 100644 resources/definitions/ultimaker_original_plus.def.json delete mode 100644 resources/machines/ultimaker_original_plus.json diff --git a/resources/definitions/ultimaker_original_plus.def.json b/resources/definitions/ultimaker_original_plus.def.json new file mode 100644 index 0000000000..830050beb0 --- /dev/null +++ b/resources/definitions/ultimaker_original_plus.def.json @@ -0,0 +1,26 @@ +{ + "id": "ultimaker_original_plus", + "version": 2, + "name": "Ultimaker Original+", + "inherits": "ultimaker_original", + "metadata": { + "author": "Ultimaker", + "manufacturer": "Ultimaker", + "category": "Ultimaker", + "file_formats": "text/x-gcode", + "icon": "icon_ultimaker.png", + "platform": "ultimaker2_platform.obj", + "platform_texture": "UltimakerPlusbackplate.png", + "pages": [ + "UpgradeFirmware", + "UltimakerCheckup", + "BedLeveling" + ] + }, + + "overrides": { + "machine_heated_bed": { + "default_value": true + } + } +} diff --git a/resources/machines/ultimaker_original_plus.json b/resources/machines/ultimaker_original_plus.json deleted file mode 100644 index 07c5a04549..0000000000 --- a/resources/machines/ultimaker_original_plus.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "id": "ultimaker_original_plus", - "version": 1, - "name": "Ultimaker Original+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "icon": "icon_ultimaker.png", - "platform": "ultimaker2_platform.obj", - "platform_texture": "UltimakerPlusbackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker_original.json", - - "pages": [ - "UpgradeFirmware", - "UltimakerCheckup", - "BedLeveling" - ], - - "overrides": { - "machine_heated_bed": { "default": true } - } -} From 07fea431c7946d0e555c36606390d2c7f5ff6e40 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 10:28:23 +0200 Subject: [PATCH 165/705] Translate definition for Uniqbot One Contributes to issue CURA-1278. --- resources/definitions/uniqbot_one.def.json | 55 ++++++++++++++++++++++ resources/machines/uniqbot_one.json | 31 ------------ 2 files changed, 55 insertions(+), 31 deletions(-) create mode 100644 resources/definitions/uniqbot_one.def.json delete mode 100644 resources/machines/uniqbot_one.json diff --git a/resources/definitions/uniqbot_one.def.json b/resources/definitions/uniqbot_one.def.json new file mode 100644 index 0000000000..ee536edfb0 --- /dev/null +++ b/resources/definitions/uniqbot_one.def.json @@ -0,0 +1,55 @@ +{ + "id": "uniqbot_one", + "version": 2, + "name": "Uniqbot", + "inherits": "fdmprinter", + "metadata": { + "author": "Unimatech", + "manufacturer": "Unimatech", + "category": "Other", + "file_formats": "text/x-gcode", + "icon": "icon_ultimaker2.png" + }, + + "overrides": { + "machine_heated_bed": { + "default_value": false + }, + "machine_width": { + "default_value": 140 + }, + "machine_height": { + "default_value": 120 + }, + "machine_depth": { + "default_value": 160 + }, + "machine_center_is_zero": { + "default_value": false + }, + "machine_nozzle_size": { + "default_value": 0.5 + }, + "material_diameter": { + "default_value": 1.75 + }, + "machine_nozzle_heat_up_speed": { + "default_value": 2 + }, + "machine_nozzle_cool_down_speed": { + "default_value": 2 + }, + "machine_nozzle_gantry_distance": { + "default_value": 55 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." + }, + "machine_end_gcode": { + "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" + } + } +} \ No newline at end of file diff --git a/resources/machines/uniqbot_one.json b/resources/machines/uniqbot_one.json deleted file mode 100644 index f07dae9b24..0000000000 --- a/resources/machines/uniqbot_one.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "id": "uniqbot_one", - "version": 1, - "name": "Uniqbot", - "manufacturer": "Unimatech", - "author": "Unimatech", - "icon": "icon_ultimaker2.png", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "overrides": { - "machine_heated_bed": { "default": false }, - "machine_width": { "default": 140 }, - "machine_height": { "default": 120 }, - "machine_depth": { "default": 160 }, - "machine_center_is_zero": { "default": false }, - "machine_nozzle_size": { "default": 0.5 }, - "material_diameter": { "default": 1.75 }, - "machine_nozzle_heat_up_speed": { "default": 2.0 }, - "machine_nozzle_cool_down_speed": { "default": 2.0 }, - "machine_nozzle_gantry_distance": { "default": 55 }, - "machine_gcode_flavor": { "default": "RepRap (Marlin/Sprinter)" }, - - "machine_start_gcode": { - "default": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." - }, - "machine_end_gcode": { - "default": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" - } - } -} From 4e3e466a11e8c063cf64cc4426c19fa4a36276e3 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 10:34:28 +0200 Subject: [PATCH 166/705] Move platform offset to metadata Also removed the setting from fdmprinter just to be clear. Contributes to issue CURA-1278. --- resources/definitions/bq_witbox_2.def.json | 6 ++---- resources/definitions/innovo_inventor.def.json | 6 ++---- resources/definitions/maker_starter.def.json | 5 +---- resources/definitions/ultimaker2.def.json | 6 ++---- resources/definitions/ultimaker2_go.def.json | 6 ++---- resources/machines/fdmprinter.json | 9 --------- 6 files changed, 9 insertions(+), 29 deletions(-) diff --git a/resources/definitions/bq_witbox_2.def.json b/resources/definitions/bq_witbox_2.def.json index a98a8b909d..b9d9b497cd 100644 --- a/resources/definitions/bq_witbox_2.def.json +++ b/resources/definitions/bq_witbox_2.def.json @@ -9,7 +9,8 @@ "manufacturer": "BQ", "category": "Other", "file_formats": "text/x-gcode", - "platform": "bq_witbox_platform.stl" + "platform": "bq_witbox_platform.stl", + "platform_offset": [0, -145, -38] }, "overrides": { @@ -37,9 +38,6 @@ "machine_gcode_flavor": { "default_value": "RepRap" }, - "machine_platform_offset": { - "default_value": [0, -145, -38] - }, "material_print_temperature": { "default_value": 210 }, diff --git a/resources/definitions/innovo_inventor.def.json b/resources/definitions/innovo_inventor.def.json index d40256813b..cd63423094 100644 --- a/resources/definitions/innovo_inventor.def.json +++ b/resources/definitions/innovo_inventor.def.json @@ -9,7 +9,8 @@ "manufacturer": "Innovo", "category": "Other", "file_formats": "text/x-gcode", - "platform": "inventor_platform.stl" + "platform": "inventor_platform.stl", + "platform_offset": [-180, -0.25, 160] }, "overrides": { @@ -61,9 +62,6 @@ "machine_end_gcode": { "default_value": "M104 S0\nG91 ; relative positioning\nG1 E-2 F5000; retract 2mm\nG28 Z; move bed down\nG90 ; absolute positioning\nM84 ; disable motors" }, - "machine_platform_offset": { - "default_value": [-180, -0.25, 160] - }, "layer_height": { "default_value": 0.15 }, diff --git a/resources/definitions/maker_starter.def.json b/resources/definitions/maker_starter.def.json index 797b57f771..24033d8968 100644 --- a/resources/definitions/maker_starter.def.json +++ b/resources/definitions/maker_starter.def.json @@ -4,9 +4,9 @@ "name": "3DMaker Starter", "inherits": "fdmprinter", "metadata": { - "visible": true, "author": "tvlgiao", "manufacturer": "3DMaker", + "category": "Other", "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj", "icon": "icon_ultimaker2.png", "platform": "makerstarter_platform.stl" @@ -58,9 +58,6 @@ "machine_disallowed_areas": { "default_value": [] }, - "machine_platform_offset": { - "default_value": [0, 0, 0] - }, "machine_nozzle_tip_outer_diameter": { "default_value": 1 }, diff --git a/resources/definitions/ultimaker2.def.json b/resources/definitions/ultimaker2.def.json index ae35858730..606d51c545 100644 --- a/resources/definitions/ultimaker2.def.json +++ b/resources/definitions/ultimaker2.def.json @@ -10,7 +10,8 @@ "file_formats": "text/x-gcode", "icon": "icon_ultimaker2.png", "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2backplate.png" + "platform_texture": "Ultimaker2backplate.png", + "platform_offset": [9, 0, 0] }, "overrides": { "machine_start_gcode" : { @@ -69,9 +70,6 @@ [[-115, -112.5], [-115, -104.5], [ -84, -104.5], [ -82, -112.5]], [[ 115, -112.5], [ 108, -112.5], [ 110, -104.5], [ 115, -104.5]] ]}, - "machine_platform_offset": { - "default_value": [9, 0, 0] - }, "machine_nozzle_tip_outer_diameter": { "default_value": 1 }, diff --git a/resources/definitions/ultimaker2_go.def.json b/resources/definitions/ultimaker2_go.def.json index e439006170..7bedb70add 100644 --- a/resources/definitions/ultimaker2_go.def.json +++ b/resources/definitions/ultimaker2_go.def.json @@ -10,7 +10,8 @@ "file_formats": "text/x-gcode", "icon": "icon_ultimaker2.png", "platform": "ultimaker2go_platform.obj", - "platform_texture": "Ultimaker2Gobackplate.png" + "platform_texture": "Ultimaker2Gobackplate.png", + "platform_offset": [0, 0, 0] }, "overrides": { @@ -34,8 +35,5 @@ [[ 60, -60], [ 33, -60], [ 35, -52], [ 60, -52]] ] }, - "machine_platform_offset": { - "default_value": [0, 0, 0] - } } } diff --git a/resources/machines/fdmprinter.json b/resources/machines/fdmprinter.json index 2751c69db2..955bb36c5a 100644 --- a/resources/machines/fdmprinter.json +++ b/resources/machines/fdmprinter.json @@ -121,15 +121,6 @@ "default": [], "global_only": true }, - "machine_platform_offset": { - "description": "Where to display the platform mesh.", - "default": [ - 0, - 0, - 0 - ], - "global_only": true - }, "machine_head_polygon": { "description": "A 2D silhouette of the print head (fan caps excluded).", "type": "polygon", From dafff9159e5130ba2c5f7cb834bce906d28e6e3b Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 18 May 2016 11:03:44 +0200 Subject: [PATCH 167/705] Added materials & qualities CURA-1278 --- cura/MachineManagerModel.py | 32 ++++++++++++------- resources/definitions/fdmprinter.def.json | 4 ++- .../{instances => materials}/abs.inst.cfg | 0 .../{instances => materials}/cpe.inst.cfg | 0 .../{instances => materials}/pla.inst.cfg | 0 resources/quality/high.inst.cfg | 9 ++++++ resources/quality/normal.inst.cfg | 9 ++++++ 7 files changed, 42 insertions(+), 12 deletions(-) rename resources/{instances => materials}/abs.inst.cfg (100%) rename resources/{instances => materials}/cpe.inst.cfg (100%) rename resources/{instances => materials}/pla.inst.cfg (100%) create mode 100644 resources/quality/high.inst.cfg create mode 100644 resources/quality/normal.inst.cfg diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 0d3540475e..0f45f0a7b1 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -58,21 +58,29 @@ class MachineManagerModel(QObject): new_global_stack.addMetaDataEntry("type", "machine") UM.Settings.ContainerRegistry.getInstance().addContainer(new_global_stack) - ## DEBUG CODE - material_instance_container = UM.Settings.InstanceContainer("test_material") - material_instance_container.addMetaDataEntry("type", "material") - material_instance_container.setDefinition(definitions[0]) + preferred_material_id = definitions[0].getMetaDataEntry("preferred_material") + material_instance_container = None + if preferred_material_id: + preferred_material_id = preferred_material_id.lower() + container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = preferred_material_id) + if container: + material_instance_container = container[0] + + preferred_quality_id = definitions[0].getMetaDataEntry("preferred_quality") + quality_instance_container = None + if preferred_quality_id: + preferred_quality_id = preferred_quality_id.lower() + container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = preferred_quality_id) + if container: + quality_instance_container = container[0] + + ## DEBUG CODE variant_instance_container = UM.Settings.InstanceContainer("test_variant") variant_instance_container.addMetaDataEntry("type", "variant") variant_instance_container.setDefinition(definitions[0]) - quality_instance_container = UM.Settings.InstanceContainer(name + "_quality") - UM.Settings.ContainerRegistry.getInstance().addContainer(material_instance_container) UM.Settings.ContainerRegistry.getInstance().addContainer(variant_instance_container) - UM.Settings.ContainerRegistry.getInstance().addContainer(quality_instance_container) - quality_instance_container.addMetaDataEntry("type", "quality") - quality_instance_container.setDefinition(definitions[0]) current_settings_instance_container = UM.Settings.InstanceContainer(name + "_current_settings") current_settings_instance_container.addMetaDataEntry("machine", name) @@ -82,9 +90,11 @@ class MachineManagerModel(QObject): # If a definition is found, its a list. Should only have one item. new_global_stack.addContainer(definitions[0]) - new_global_stack.addContainer(material_instance_container) + if material_instance_container: + new_global_stack.addContainer(material_instance_container) new_global_stack.addContainer(variant_instance_container) - new_global_stack.addContainer(quality_instance_container) + if quality_instance_container: + new_global_stack.addContainer(quality_instance_container) new_global_stack.addContainer(current_settings_instance_container) Application.getInstance().setGlobalContainerStack(new_global_stack) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 11436bdcce..603dc18e92 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -8,7 +8,9 @@ "category": "Ultimaker", "manufacturer": "Ultimaker", "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g", - "visible": false + "visible": false, + "preferred_material": "pla", + "preferred_quality": "normal" }, "settings": { diff --git a/resources/instances/abs.inst.cfg b/resources/materials/abs.inst.cfg similarity index 100% rename from resources/instances/abs.inst.cfg rename to resources/materials/abs.inst.cfg diff --git a/resources/instances/cpe.inst.cfg b/resources/materials/cpe.inst.cfg similarity index 100% rename from resources/instances/cpe.inst.cfg rename to resources/materials/cpe.inst.cfg diff --git a/resources/instances/pla.inst.cfg b/resources/materials/pla.inst.cfg similarity index 100% rename from resources/instances/pla.inst.cfg rename to resources/materials/pla.inst.cfg diff --git a/resources/quality/high.inst.cfg b/resources/quality/high.inst.cfg new file mode 100644 index 0000000000..2e860cf380 --- /dev/null +++ b/resources/quality/high.inst.cfg @@ -0,0 +1,9 @@ +[general] +version = 2 +name = high +definition = fdmprinter + +[metadata] +type = quality + +[values] diff --git a/resources/quality/normal.inst.cfg b/resources/quality/normal.inst.cfg new file mode 100644 index 0000000000..6bb23d841c --- /dev/null +++ b/resources/quality/normal.inst.cfg @@ -0,0 +1,9 @@ +[general] +version = 2 +name = normal +definition = fdmprinter + +[metadata] +type = quality + +[values] From 1578fdee98532868be4698c2d0c14ecb46f805e9 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 18 May 2016 11:06:39 +0200 Subject: [PATCH 168/705] Fixed minor errors in definitions CURA-1278 --- resources/definitions/ultimaker2_extended_plus.def.json | 2 +- resources/definitions/ultimaker2_go.def.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/definitions/ultimaker2_extended_plus.def.json b/resources/definitions/ultimaker2_extended_plus.def.json index 5283209745..d4220927e3 100644 --- a/resources/definitions/ultimaker2_extended_plus.def.json +++ b/resources/definitions/ultimaker2_extended_plus.def.json @@ -2,7 +2,7 @@ "id": "ultimaker2_extended_plus_base", "version": 2, "name": "Ultimaker 2 Extended+", - "inherits": "ultimaker2plus", + "inherits": "ultimaker2_plus", "visible": false, "metadata": { "author": "Ultimaker", diff --git a/resources/definitions/ultimaker2_go.def.json b/resources/definitions/ultimaker2_go.def.json index 7bedb70add..d3ef53d633 100644 --- a/resources/definitions/ultimaker2_go.def.json +++ b/resources/definitions/ultimaker2_go.def.json @@ -34,6 +34,6 @@ [[-60, -60], [-60, -52], [-35, -52], [-33, -60]], [[ 60, -60], [ 33, -60], [ 35, -52], [ 60, -52]] ] - }, + } } } From cbf3fe0ddf970d31a0cab50529a2db242f14e905 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 10:59:10 +0200 Subject: [PATCH 169/705] Add variants for Ultimaker 2+ Contributes to issue CURA-1278. --- resources/variants/ultimaker2_plus_0.25.cfg | 16 ++++++++++++++++ resources/variants/ultimaker2_plus_0.4.cfg | 14 ++++++++++++++ resources/variants/ultimaker2_plus_0.6.cfg | 15 +++++++++++++++ resources/variants/ultimaker2_plus_0.8.cfg | 15 +++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 resources/variants/ultimaker2_plus_0.25.cfg create mode 100644 resources/variants/ultimaker2_plus_0.4.cfg create mode 100644 resources/variants/ultimaker2_plus_0.6.cfg create mode 100644 resources/variants/ultimaker2_plus_0.8.cfg diff --git a/resources/variants/ultimaker2_plus_0.25.cfg b/resources/variants/ultimaker2_plus_0.25.cfg new file mode 100644 index 0000000000..18839a8871 --- /dev/null +++ b/resources/variants/ultimaker2_plus_0.25.cfg @@ -0,0 +1,16 @@ +[general] +name = 0.25 mm +version = 2 +definition = ultimaker2_plus + +[metadata] +author = Ultimaker + +[values] +machine_nozzle_size = 0.25 +machine_nozzle_tip_outer_diameter = 0.8 +coasting_volume = 0.1 +coasting_min_volume = 0.17 +speed_wall = round(speed_print / 1.2, 1) +speed_wall_0 = 1 if speed_wall < 5 else (speed_wall - 5) +speed_topbottom = round(speed_print / 1.5, 1) \ No newline at end of file diff --git a/resources/variants/ultimaker2_plus_0.4.cfg b/resources/variants/ultimaker2_plus_0.4.cfg new file mode 100644 index 0000000000..b7dc47ea6e --- /dev/null +++ b/resources/variants/ultimaker2_plus_0.4.cfg @@ -0,0 +1,14 @@ +[general] +name = 0.4 mm +version = 2 +definition = ultimaker2_plus + +[metadata] +author = Ultimaker + +[values] +machine_nozzle_size = 0.4 +machine_nozzle_tip_outer_diameter = 1.05 +speed_wall = round(speed_print / 1.25, 1) +speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) +speed_topbottom = round(speed_print / 2.25, 1) \ No newline at end of file diff --git a/resources/variants/ultimaker2_plus_0.6.cfg b/resources/variants/ultimaker2_plus_0.6.cfg new file mode 100644 index 0000000000..d6a7da7437 --- /dev/null +++ b/resources/variants/ultimaker2_plus_0.6.cfg @@ -0,0 +1,15 @@ +[general] +name = 0.6 mm +version = 2 +definition = ultimaker2_plus + +[metadata] +author = Ultimaker + +[values] +machine_nozzle_size = 0.6 +machine_nozzle_tip_outer_diameter = 1.25 +coasting_volume = 1.36 +speed_wall = round(speed_print * 4 / 3, 1) +speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) +speed_topbottom = round(speed_print / 2, 1) \ No newline at end of file diff --git a/resources/variants/ultimaker2_plus_0.8.cfg b/resources/variants/ultimaker2_plus_0.8.cfg new file mode 100644 index 0000000000..cb97151642 --- /dev/null +++ b/resources/variants/ultimaker2_plus_0.8.cfg @@ -0,0 +1,15 @@ +[general] +name = 0.8 mm +version = 2 +definition = ultimaker2_plus + +[metadata] +author = Ultimaker + +[values] +machine_nozzle_size = 0.8 +machine_nozzle_tip_outer_diameter = 1.35 +coasting_volume = 3.22 +speed_wall = round(speed_print * 4 / 3, 1) +speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) +speed_topbottom = round(speed_print / 2, 1) \ No newline at end of file From 5ed881859d34a2955f90ccc2493a1c985fe973a5 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 11:01:38 +0200 Subject: [PATCH 170/705] Fix ID of Ultimaker 2+ It's no longer necessary to append '_base' to the ID of printers with variants. Contributes to issue CURA-1278. --- resources/definitions/ultimaker2_plus.def.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/definitions/ultimaker2_plus.def.json b/resources/definitions/ultimaker2_plus.def.json index 6a61d18d3c..646b424c5c 100644 --- a/resources/definitions/ultimaker2_plus.def.json +++ b/resources/definitions/ultimaker2_plus.def.json @@ -1,5 +1,5 @@ { - "id": "ultimaker2plus_base", + "id": "ultimaker2_plus", "version": 2, "name": "Ultimaker 2+", "inherits": "ultimaker2", From 25c9c95e105851548a5d3d559160c547930c9fe6 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 11:02:31 +0200 Subject: [PATCH 171/705] Fix ID of Ultimaker 2 Extended+ It's no longer necessary to append '_base' to the ID of printers with variants. Contributes to issue CURA-1278. --- resources/definitions/ultimaker2_extended_plus.def.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/definitions/ultimaker2_extended_plus.def.json b/resources/definitions/ultimaker2_extended_plus.def.json index d4220927e3..eae48773b6 100644 --- a/resources/definitions/ultimaker2_extended_plus.def.json +++ b/resources/definitions/ultimaker2_extended_plus.def.json @@ -1,5 +1,5 @@ { - "id": "ultimaker2_extended_plus_base", + "id": "ultimaker2_extended_plus", "version": 2, "name": "Ultimaker 2 Extended+", "inherits": "ultimaker2_plus", From dce4b71f63fb6c502583dca14e0078bd919d462e Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 11:06:16 +0200 Subject: [PATCH 172/705] Add variants for Ultimaker 2 Extended+ Contributes to issue CURA-1278. --- resources/variants/ultimaker2_extended_plus_0.25.cfg | 11 +++++++++++ resources/variants/ultimaker2_extended_plus_0.4.cfg | 11 +++++++++++ resources/variants/ultimaker2_extended_plus_0.6.cfg | 11 +++++++++++ resources/variants/ultimaker2_extended_plus_0.8.cfg | 11 +++++++++++ 4 files changed, 44 insertions(+) create mode 100644 resources/variants/ultimaker2_extended_plus_0.25.cfg create mode 100644 resources/variants/ultimaker2_extended_plus_0.4.cfg create mode 100644 resources/variants/ultimaker2_extended_plus_0.6.cfg create mode 100644 resources/variants/ultimaker2_extended_plus_0.8.cfg diff --git a/resources/variants/ultimaker2_extended_plus_0.25.cfg b/resources/variants/ultimaker2_extended_plus_0.25.cfg new file mode 100644 index 0000000000..0d358821c0 --- /dev/null +++ b/resources/variants/ultimaker2_extended_plus_0.25.cfg @@ -0,0 +1,11 @@ +[general] +name = 0.25 mm +version = 2 +definition = ultimaker2_extended_plus + +[metadata] +author = Ultimaker + +[values] +machine_nozzle_size = 0.25 +machine_nozzle_tip_outer_diameter = 0.8 \ No newline at end of file diff --git a/resources/variants/ultimaker2_extended_plus_0.4.cfg b/resources/variants/ultimaker2_extended_plus_0.4.cfg new file mode 100644 index 0000000000..e0ab37c06b --- /dev/null +++ b/resources/variants/ultimaker2_extended_plus_0.4.cfg @@ -0,0 +1,11 @@ +[general] +name = 0.4 mm +version = 2 +definition = ultimaker2_extended_plus + +[metadata] +author = Ultimaker + +[values] +machine_nozzle_size = 0.4 +machine_nozzle_tip_outer_diameter = 1.05 \ No newline at end of file diff --git a/resources/variants/ultimaker2_extended_plus_0.6.cfg b/resources/variants/ultimaker2_extended_plus_0.6.cfg new file mode 100644 index 0000000000..2b65b472b8 --- /dev/null +++ b/resources/variants/ultimaker2_extended_plus_0.6.cfg @@ -0,0 +1,11 @@ +[general] +name = 0.6 mm +version = 2 +definition = ultimaker2_extended_plus + +[metadata] +author = Ultimaker + +[values] +machine_nozzle_size = 0.6 +machine_nozzle_tip_outer_diameter = 1.25 \ No newline at end of file diff --git a/resources/variants/ultimaker2_extended_plus_0.8.cfg b/resources/variants/ultimaker2_extended_plus_0.8.cfg new file mode 100644 index 0000000000..7a879977c7 --- /dev/null +++ b/resources/variants/ultimaker2_extended_plus_0.8.cfg @@ -0,0 +1,11 @@ +[general] +name = 0.8 mm +version = 2 +definition = ultimaker2_extended_plus + +[metadata] +author = Ultimaker + +[values] +machine_nozzle_size = 0.8 +machine_nozzle_tip_outer_diameter = 1.35 \ No newline at end of file From 1e1aec57460d0dbc8a6207bf043c0ee2739905ec Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 11:07:02 +0200 Subject: [PATCH 173/705] Remove superfluous variants These are now in the resources/variants folder in the translated form. Contributes to issue CURA-1278. --- .../ultimaker2_extended_plus_025.json | 17 -------------- .../ultimaker2_extended_plus_040.json | 17 -------------- .../ultimaker2_extended_plus_060.json | 17 -------------- .../ultimaker2_extended_plus_080.json | 17 -------------- resources/machines/ultimaker2plus_025.json | 23 ------------------- resources/machines/ultimaker2plus_040.json | 21 ----------------- resources/machines/ultimaker2plus_060.json | 22 ------------------ resources/machines/ultimaker2plus_080.json | 22 ------------------ 8 files changed, 156 deletions(-) delete mode 100644 resources/machines/ultimaker2_extended_plus_025.json delete mode 100644 resources/machines/ultimaker2_extended_plus_040.json delete mode 100644 resources/machines/ultimaker2_extended_plus_060.json delete mode 100644 resources/machines/ultimaker2_extended_plus_080.json delete mode 100644 resources/machines/ultimaker2plus_025.json delete mode 100644 resources/machines/ultimaker2plus_040.json delete mode 100644 resources/machines/ultimaker2plus_060.json delete mode 100644 resources/machines/ultimaker2plus_080.json diff --git a/resources/machines/ultimaker2_extended_plus_025.json b/resources/machines/ultimaker2_extended_plus_025.json deleted file mode 100644 index 187079aa33..0000000000 --- a/resources/machines/ultimaker2_extended_plus_025.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "id": "ultimaker2_extended_plus", - "version": 1, - "name": "Ultimaker 2 Extended+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2ExtendedPlusbackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker2_extended_plus.json", - "variant": "0.25 mm", - "profiles_machine": "ultimaker2plus", - "machine_settings": { - "machine_nozzle_size": { "default": 0.25 }, - "machine_nozzle_tip_outer_diameter": { "default": 0.8 } - } -} diff --git a/resources/machines/ultimaker2_extended_plus_040.json b/resources/machines/ultimaker2_extended_plus_040.json deleted file mode 100644 index b548bbe423..0000000000 --- a/resources/machines/ultimaker2_extended_plus_040.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "id": "ultimaker2_extended_plus", - "version": 1, - "name": "Ultimaker 2 Extended+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2ExtendedPlusbackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker2_extended_plus.json", - "variant": "0.4 mm", - "profiles_machine": "ultimaker2plus", - "machine_settings": { - "machine_nozzle_size": { "default": 0.40 }, - "machine_nozzle_tip_outer_diameter": { "default": 1.05 } - } -} diff --git a/resources/machines/ultimaker2_extended_plus_060.json b/resources/machines/ultimaker2_extended_plus_060.json deleted file mode 100644 index 9d39c267ba..0000000000 --- a/resources/machines/ultimaker2_extended_plus_060.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "id": "ultimaker2_extended_plus", - "version": 1, - "name": "Ultimaker 2 Extended+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2ExtendedPlusbackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker2_extended_plus.json", - "variant": "0.6 mm", - "profiles_machine": "ultimaker2plus", - "machine_settings": { - "machine_nozzle_size": { "default": 0.60 }, - "machine_nozzle_tip_outer_diameter": { "default": 1.25 } - } -} diff --git a/resources/machines/ultimaker2_extended_plus_080.json b/resources/machines/ultimaker2_extended_plus_080.json deleted file mode 100644 index bf74998f57..0000000000 --- a/resources/machines/ultimaker2_extended_plus_080.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "id": "ultimaker2_extended_plus", - "version": 1, - "name": "Ultimaker 2 Extended+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2ExtendedPlusbackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker2_extended_plus.json", - "variant": "0.8 mm", - "profiles_machine": "ultimaker2plus", - "machine_settings": { - "machine_nozzle_size": { "default": 0.80 }, - "machine_nozzle_tip_outer_diameter": { "default": 1.35 } - } -} diff --git a/resources/machines/ultimaker2plus_025.json b/resources/machines/ultimaker2plus_025.json deleted file mode 100644 index 2c022f8448..0000000000 --- a/resources/machines/ultimaker2plus_025.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "id": "ultimaker2plus", - "version": 1, - "name": "Ultimaker 2+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2Plusbackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker2plus.json", - - "variant": "0.25 mm", - - "overrides": { - "speed_wall": { "inherit_function": "round(speed_print / 1.2, 1)" }, - "speed_wall_0": { "inherit_function": "1 if speed_wall < 5 else (speed_wall - 5)" }, - "speed_topbottom": { "inherit_function": "round(speed_print / 1.5, 1)" }, - "machine_nozzle_size": { "default": 0.25 }, - "machine_nozzle_tip_outer_diameter": { "default": 0.8 }, - "coasting_volume": { "default": 0.1 }, - "coasting_min_volume": { "default": 0.17 } - } -} diff --git a/resources/machines/ultimaker2plus_040.json b/resources/machines/ultimaker2plus_040.json deleted file mode 100644 index f5a0f5a710..0000000000 --- a/resources/machines/ultimaker2plus_040.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "id": "ultimaker2plus", - "version": 1, - "name": "Ultimaker 2+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2Plusbackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker2plus.json", - - "variant": "0.4 mm", - - "overrides": { - "speed_wall": { "inherit_function": "round(speed_print / 1.25, 1)" }, - "speed_wall_0": { "inherit_function": "1 if speed_wall < 10 else (speed_wall - 10)" }, - "speed_topbottom": { "inherit_function": "round(speed_print / 2.25, 1)" }, - "machine_nozzle_size": { "default": 0.40 }, - "machine_nozzle_tip_outer_diameter": { "default": 1.05 } - } -} diff --git a/resources/machines/ultimaker2plus_060.json b/resources/machines/ultimaker2plus_060.json deleted file mode 100644 index 89538f2fd0..0000000000 --- a/resources/machines/ultimaker2plus_060.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "id": "ultimaker2plus", - "version": 1, - "name": "Ultimaker 2+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2Plusbackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker2plus.json", - - "variant": "0.6 mm", - - "overrides": { - "speed_wall": { "inherit_function": "round(speed_print / 1.333333, 1)" }, - "speed_wall_0": { "inherit_function": "1 if speed_wall < 10 else (speed_wall - 10)" }, - "speed_topbottom": { "inherit_function": "round(speed_print / 2, 1)" }, - "machine_nozzle_size": { "default": 0.60 }, - "machine_nozzle_tip_outer_diameter": { "default": 1.25 }, - "coasting_volume": { "default": 1.36 } - } -} diff --git a/resources/machines/ultimaker2plus_080.json b/resources/machines/ultimaker2plus_080.json deleted file mode 100644 index e231fbb9f5..0000000000 --- a/resources/machines/ultimaker2plus_080.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "id": "ultimaker2plus", - "version": 1, - "name": "Ultimaker 2+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2Plusbackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker2plus.json", - - "variant": "0.8 mm", - - "overrides": { - "speed_wall": { "inherit_function": "round(speed_print / 1.333333, 1)" }, - "speed_wall_0": { "inherit_function": "1 if speed_wall < 10 else (speed_wall - 10)" }, - "speed_topbottom": { "inherit_function": "round(speed_print / 2, 1)" }, - "machine_nozzle_size": { "default": 0.80 }, - "machine_nozzle_tip_outer_diameter": { "default": 1.35 }, - "coasting_volume": { "default": 3.22 } - } -} From 54c29187c9d5c413ef5791688fbfa0de58071c77 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 11:16:22 +0200 Subject: [PATCH 174/705] Also use different speeds and coast volumes for UME+ variants I've discussed this with Paul and he confirms that they should also be different for Extended just like not-Extended. Contributes to issue CURA-1278. --- resources/variants/ultimaker2_extended_plus_0.25.cfg | 7 ++++++- resources/variants/ultimaker2_extended_plus_0.4.cfg | 5 ++++- resources/variants/ultimaker2_extended_plus_0.6.cfg | 6 +++++- resources/variants/ultimaker2_extended_plus_0.8.cfg | 6 +++++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/resources/variants/ultimaker2_extended_plus_0.25.cfg b/resources/variants/ultimaker2_extended_plus_0.25.cfg index 0d358821c0..2bc14d7588 100644 --- a/resources/variants/ultimaker2_extended_plus_0.25.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.25.cfg @@ -8,4 +8,9 @@ author = Ultimaker [values] machine_nozzle_size = 0.25 -machine_nozzle_tip_outer_diameter = 0.8 \ No newline at end of file +machine_nozzle_tip_outer_diameter = 0.8 +coasting_volume = 0.1 +coasting_min_volume = 0.17 +speed_wall = round(speed_print / 1.2, 1) +speed_wall_0 = 1 if speed_wall < 5 else (speed_wall - 5) +speed_topbottom = round(speed_print / 1.5, 1) \ No newline at end of file diff --git a/resources/variants/ultimaker2_extended_plus_0.4.cfg b/resources/variants/ultimaker2_extended_plus_0.4.cfg index e0ab37c06b..a0de0ad2d7 100644 --- a/resources/variants/ultimaker2_extended_plus_0.4.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.4.cfg @@ -8,4 +8,7 @@ author = Ultimaker [values] machine_nozzle_size = 0.4 -machine_nozzle_tip_outer_diameter = 1.05 \ No newline at end of file +machine_nozzle_tip_outer_diameter = 1.05 +speed_wall = round(speed_print / 1.25, 1) +speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) +speed_topbottom = round(speed_print / 2.25, 1) \ No newline at end of file diff --git a/resources/variants/ultimaker2_extended_plus_0.6.cfg b/resources/variants/ultimaker2_extended_plus_0.6.cfg index 2b65b472b8..10fa9dd4de 100644 --- a/resources/variants/ultimaker2_extended_plus_0.6.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.6.cfg @@ -8,4 +8,8 @@ author = Ultimaker [values] machine_nozzle_size = 0.6 -machine_nozzle_tip_outer_diameter = 1.25 \ No newline at end of file +machine_nozzle_tip_outer_diameter = 1.25 +coasting_volume = 1.36 +speed_wall = round(speed_print * 4 / 3, 1) +speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) +speed_topbottom = round(speed_print / 2, 1) \ No newline at end of file diff --git a/resources/variants/ultimaker2_extended_plus_0.8.cfg b/resources/variants/ultimaker2_extended_plus_0.8.cfg index 7a879977c7..2980215ebd 100644 --- a/resources/variants/ultimaker2_extended_plus_0.8.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.8.cfg @@ -8,4 +8,8 @@ author = Ultimaker [values] machine_nozzle_size = 0.8 -machine_nozzle_tip_outer_diameter = 1.35 \ No newline at end of file +machine_nozzle_tip_outer_diameter = 1.35 +coasting_volume = 3.22 +speed_wall = round(speed_print * 4 / 3, 1) +speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) +speed_topbottom = round(speed_print / 2, 1) \ No newline at end of file From a8fc830f2b1154abc3aa934311d5a538bd36a9ee Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 11:36:45 +0200 Subject: [PATCH 175/705] Translate ancient machine_head_shape settings It has been machine_head_polygon for a while. Contributes to issue CURA-1278. --- resources/definitions/grr_neo.def.json | 18 +++++++----------- resources/definitions/innovo_inventor.def.json | 18 +++++++----------- resources/definitions/maker_starter.def.json | 12 ------------ resources/definitions/prusa_i3.def.json | 18 +++++++----------- resources/definitions/prusa_i3_xl.def.json | 18 +++++++----------- resources/definitions/rigidbot.def.json | 12 ------------ resources/definitions/rigidbot_big.def.json | 12 ------------ 7 files changed, 28 insertions(+), 80 deletions(-) diff --git a/resources/definitions/grr_neo.def.json b/resources/definitions/grr_neo.def.json index 9fc5d2121e..76ae73540f 100644 --- a/resources/definitions/grr_neo.def.json +++ b/resources/definitions/grr_neo.def.json @@ -35,17 +35,13 @@ "machine_nozzle_cool_down_speed": { "default_value": 2 }, - "machine_head_shape_min_x": { - "default_value": 75 - }, - "machine_head_shape_min_y": { - "default_value": 18 - }, - "machine_head_shape_max_x": { - "default_value": 18 - }, - "machine_head_shape_max_y": { - "default_value": 35 + "machine_head_polygon": { + "default_value": [ + [-75, -18], + [-75, 35], + [18, 35], + [18, -18] + ] }, "machine_nozzle_gantry_distance": { "default_value": 55 diff --git a/resources/definitions/innovo_inventor.def.json b/resources/definitions/innovo_inventor.def.json index cd63423094..a0e8bd8b8f 100644 --- a/resources/definitions/innovo_inventor.def.json +++ b/resources/definitions/innovo_inventor.def.json @@ -32,17 +32,13 @@ "machine_nozzle_size": { "default_value": 0.4 }, - "machine_head_shape_min_x": { - "default_value": 43.7 - }, - "machine_head_shape_min_y": { - "default_value": 19.2 - }, - "machine_head_shape_max_x": { - "default_value": 43.7 - }, - "machine_head_shape_max_y": { - "default_value": 55 + "machine_head_polygon": { + "default_value": [ + [-43.7, -19.2], + [-43.7, 55], + [43.7, 55], + [43.7, -19.2] + ] }, "machine_nozzle_gantry_distance": { "default_value": 82.3 diff --git a/resources/definitions/maker_starter.def.json b/resources/definitions/maker_starter.def.json index 24033d8968..94caa5d789 100644 --- a/resources/definitions/maker_starter.def.json +++ b/resources/definitions/maker_starter.def.json @@ -37,18 +37,6 @@ "machine_nozzle_cool_down_speed": { "default_value": 2 }, - "machine_head_shape_min_x": { - "default_value": 0 - }, - "machine_head_shape_min_y": { - "default_value": 0 - }, - "machine_head_shape_max_x": { - "default_value": 0 - }, - "machine_head_shape_max_y": { - "default_value": 0 - }, "machine_nozzle_gantry_distance": { "default_value": 55 }, diff --git a/resources/definitions/prusa_i3.def.json b/resources/definitions/prusa_i3.def.json index 21db84838a..dbd5877248 100644 --- a/resources/definitions/prusa_i3.def.json +++ b/resources/definitions/prusa_i3.def.json @@ -41,17 +41,13 @@ "machine_nozzle_cool_down_speed": { "default_value": 2 }, - "machine_head_shape_min_x": { - "default_value": 75 - }, - "machine_head_shape_min_y": { - "default_value": 18 - }, - "machine_head_shape_max_x": { - "default_value": 18 - }, - "machine_head_shape_max_y": { - "default_value": 35 + "machine_head_polygon": { + "default_value": [ + [-75, -18], + [-75, 35], + [18, 35], + [18, -18] + ] }, "machine_nozzle_gantry_distance": { "default_value": 55 diff --git a/resources/definitions/prusa_i3_xl.def.json b/resources/definitions/prusa_i3_xl.def.json index ddd1796eb7..049705abd4 100644 --- a/resources/definitions/prusa_i3_xl.def.json +++ b/resources/definitions/prusa_i3_xl.def.json @@ -41,17 +41,13 @@ "machine_nozzle_cool_down_speed": { "default_value": 2.0 }, - "machine_head_shape_min_x": { - "default_value": 75 - }, - "machine_head_shape_min_y": { - "default_value": 18 - }, - "machine_head_shape_max_x": { - "default_value": 18 - }, - "machine_head_shape_max_y": { - "default_value": 35 + "machine_head_polygon": { + "default_value": [ + [-75, -18], + [-75, 35], + [18, 35], + [18, -18] + ] }, "machine_nozzle_gantry_distance": { "default_value": 55 diff --git a/resources/definitions/rigidbot.def.json b/resources/definitions/rigidbot.def.json index e70c407463..f8b8801395 100644 --- a/resources/definitions/rigidbot.def.json +++ b/resources/definitions/rigidbot.def.json @@ -31,18 +31,6 @@ "machine_nozzle_cool_down_speed": { "default_value": 2 }, - "machine_head_shape_min_x": { - "default_value": 0 - }, - "machine_head_shape_min_y": { - "default_value": 0 - }, - "machine_head_shape_max_x": { - "default_value": 0 - }, - "machine_head_shape_max_y": { - "default_value": 0 - }, "machine_nozzle_gantry_distance": { "default_value": 0 }, diff --git a/resources/definitions/rigidbot_big.def.json b/resources/definitions/rigidbot_big.def.json index f4b282d9db..1037e3ea12 100644 --- a/resources/definitions/rigidbot_big.def.json +++ b/resources/definitions/rigidbot_big.def.json @@ -34,18 +34,6 @@ "machine_nozzle_cool_down_speed": { "default_value": 2 }, - "machine_head_shape_min_x": { - "default_value": 0 - }, - "machine_head_shape_min_y": { - "default_value": 0 - }, - "machine_head_shape_max_x": { - "default_value": 0 - }, - "machine_head_shape_max_y": { - "default_value": 0 - }, "machine_nozzle_gantry_distance": { "default_value": 0 }, From afb7a45bb07b99c9209922685ecc56e8d9bab392 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 11:48:43 +0200 Subject: [PATCH 176/705] Translate ancient machine_nozzle_gantry_distance setting It was changed to gantry_height long ago but not updated in these definitions. Contributes to issue CURA-1278. --- resources/definitions/grr_neo.def.json | 2 +- resources/definitions/innovo_inventor.def.json | 2 +- resources/definitions/maker_starter.def.json | 2 +- resources/definitions/prusa_i3.def.json | 2 +- resources/definitions/prusa_i3_xl.def.json | 2 +- resources/definitions/rigidbot.def.json | 2 +- resources/definitions/rigidbot_big.def.json | 2 +- resources/definitions/uniqbot_one.def.json | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/resources/definitions/grr_neo.def.json b/resources/definitions/grr_neo.def.json index 76ae73540f..563bdd1a67 100644 --- a/resources/definitions/grr_neo.def.json +++ b/resources/definitions/grr_neo.def.json @@ -43,7 +43,7 @@ [18, -18] ] }, - "machine_nozzle_gantry_distance": { + "gantry_height": { "default_value": 55 }, "machine_gcode_flavor": { diff --git a/resources/definitions/innovo_inventor.def.json b/resources/definitions/innovo_inventor.def.json index a0e8bd8b8f..14619833a7 100644 --- a/resources/definitions/innovo_inventor.def.json +++ b/resources/definitions/innovo_inventor.def.json @@ -40,7 +40,7 @@ [43.7, -19.2] ] }, - "machine_nozzle_gantry_distance": { + "gantry_height": { "default_value": 82.3 }, "machine_nozzle_offset_x_1": { diff --git a/resources/definitions/maker_starter.def.json b/resources/definitions/maker_starter.def.json index 94caa5d789..a26ca058f0 100644 --- a/resources/definitions/maker_starter.def.json +++ b/resources/definitions/maker_starter.def.json @@ -37,7 +37,7 @@ "machine_nozzle_cool_down_speed": { "default_value": 2 }, - "machine_nozzle_gantry_distance": { + "gantry_height": { "default_value": 55 }, "machine_gcode_flavor": { diff --git a/resources/definitions/prusa_i3.def.json b/resources/definitions/prusa_i3.def.json index dbd5877248..12e7054694 100644 --- a/resources/definitions/prusa_i3.def.json +++ b/resources/definitions/prusa_i3.def.json @@ -49,7 +49,7 @@ [18, -18] ] }, - "machine_nozzle_gantry_distance": { + "gantry_height": { "default_value": 55 }, "machine_gcode_flavor": { diff --git a/resources/definitions/prusa_i3_xl.def.json b/resources/definitions/prusa_i3_xl.def.json index 049705abd4..819a93b860 100644 --- a/resources/definitions/prusa_i3_xl.def.json +++ b/resources/definitions/prusa_i3_xl.def.json @@ -49,7 +49,7 @@ [18, -18] ] }, - "machine_nozzle_gantry_distance": { + "gantry_height": { "default_value": 55 }, "machine_gcode_flavor": { diff --git a/resources/definitions/rigidbot.def.json b/resources/definitions/rigidbot.def.json index f8b8801395..ace8300d5d 100644 --- a/resources/definitions/rigidbot.def.json +++ b/resources/definitions/rigidbot.def.json @@ -31,7 +31,7 @@ "machine_nozzle_cool_down_speed": { "default_value": 2 }, - "machine_nozzle_gantry_distance": { + "gantry_height": { "default_value": 0 }, "machine_gcode_flavor": { diff --git a/resources/definitions/rigidbot_big.def.json b/resources/definitions/rigidbot_big.def.json index 1037e3ea12..ce27d36745 100644 --- a/resources/definitions/rigidbot_big.def.json +++ b/resources/definitions/rigidbot_big.def.json @@ -34,7 +34,7 @@ "machine_nozzle_cool_down_speed": { "default_value": 2 }, - "machine_nozzle_gantry_distance": { + "gantry_height": { "default_value": 0 }, "machine_gcode_flavor": { diff --git a/resources/definitions/uniqbot_one.def.json b/resources/definitions/uniqbot_one.def.json index ee536edfb0..d6410a26e7 100644 --- a/resources/definitions/uniqbot_one.def.json +++ b/resources/definitions/uniqbot_one.def.json @@ -39,7 +39,7 @@ "machine_nozzle_cool_down_speed": { "default_value": 2 }, - "machine_nozzle_gantry_distance": { + "gantry_height": { "default_value": 55 }, "machine_gcode_flavor": { From fa81604b89e10845098fc00c428fbfc9bde63124 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 12:34:10 +0200 Subject: [PATCH 177/705] Set default raft fan speed to 0 This makes layer adhesion better. Contributes to issues PL-162, PL-163, PL-164 and PL-165. --- resources/machines/fdmprinter.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/machines/fdmprinter.json b/resources/machines/fdmprinter.json index 44a1ef5291..bf53ede906 100644 --- a/resources/machines/fdmprinter.json +++ b/resources/machines/fdmprinter.json @@ -1686,7 +1686,7 @@ "type": "float", "min_value": "0", "max_value": "100", - "default": 100, + "default": 0, "global_only": "True", "visible": false, "enabled": "adhesion_type == \"raft\"", From cad6d87a0c455148b03a4534622e4144048bc446 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 12:36:22 +0200 Subject: [PATCH 178/705] Change inheritance for initial layer z overlap This makes the defaults more accurate. The overlap is a little bigger now. Contributes to issues PL-162, PL-163, PL-164 and PL-165. --- resources/machines/fdmprinter.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/machines/fdmprinter.json b/resources/machines/fdmprinter.json index bf53ede906..2a24304146 100644 --- a/resources/machines/fdmprinter.json +++ b/resources/machines/fdmprinter.json @@ -1497,8 +1497,8 @@ "description": "Make the first and second layer of the object 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", "type": "float", - "default": 0.05, - "inherit_function": "layer_height / 2", + "default": 0.22, + "inherit_function": "raft_airgap / 2", "min_value": "0", "max_value_warning": "layer_height", "enabled": "adhesion_type == \"raft\"", From 14f860f8ae3021d40fabde553768b7665b8ec960 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 12:39:39 +0200 Subject: [PATCH 179/705] Also change default raft fan speed for subsettings Contributes to issues PL-162, PL-163, PL-164 and PL-165. --- resources/machines/fdmprinter.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/machines/fdmprinter.json b/resources/machines/fdmprinter.json index 2a24304146..2b172d1720 100644 --- a/resources/machines/fdmprinter.json +++ b/resources/machines/fdmprinter.json @@ -1698,7 +1698,7 @@ "type": "float", "min_value": "0", "max_value": "100", - "default": 100, + "default": 0, "global_only": "True", "visible": false, "inherit": true, @@ -1711,7 +1711,7 @@ "type": "float", "min_value": "0", "max_value": "100", - "default": 100, + "default": 0, "global_only": "True", "visible": false, "inherit": true, @@ -1724,7 +1724,7 @@ "type": "float", "min_value": "0", "max_value": "100", - "default": 100, + "default": 0, "global_only": "True", "visible": false, "inherit": true, From a5f8546d698d31c9f9840a7ff4b50aa7d0968dc7 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 18 May 2016 16:29:57 +0200 Subject: [PATCH 180/705] Fixed cases where getValue was still used. We now use getProperty instead CURA-1278 --- cura/BuildVolume.py | 42 +++++++++++++++++----------------- plugins/SolidView/SolidView.py | 2 +- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index 4397c798f7..77bda87825 100644 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -161,12 +161,12 @@ class BuildVolume(SceneNode): self._active_container_stack = Application.getInstance().getGlobalContainerStack() if self._active_container_stack: - self._width = self._active_container_stack.getValue("machine_width") - if self._active_container_stack.getValue("print_sequence") == "one_at_a_time": - self._height = self._active_container_stack.getValue("gantry_height") + self._width = self._active_container_stack.getProperty("machine_width", "value") + if self._active_container_stack.getProperty("print_sequence", "value") == "one_at_a_time": + self._height = self._active_container_stack.getProperty("gantry_height", "value") else: - self._height = self._active_container_stack.getValue("machine_height") - self._depth = self._active_container_stack.getValue("machine_depth") + self._height = self._active_container_stack.getProperty("machine_height", "value") + self._depth = self._active_container_stack.getProperty("machine_depth", "value") self._updateDisallowedAreas() @@ -174,10 +174,10 @@ class BuildVolume(SceneNode): def _onSettingValueChanged(self, setting_key): if setting_key == "print_sequence": - if Application.getInstance().getGlobalContainerStack().getValue("print_sequence") == "one_at_a_time": - self._height = self._active_container_stack.getValue("gantry_height") + if Application.getInstance().getGlobalContainerStack().getProperty("print_sequence", "value") == "one_at_a_time": + self._height = self._active_container_stack.getProperty("gantry_height", "value") else: - self._height = self._active_container_stack.getValue("machine_depth") + self._height = self._active_container_stack.getProperty("machine_depth", "value") self.rebuild() if setting_key in self._skirt_settings: self._updateDisallowedAreas() @@ -187,7 +187,7 @@ class BuildVolume(SceneNode): if not self._active_container_stack: return - disallowed_areas = self._active_container_stack.getValue("machine_disallowed_areas") + disallowed_areas = self._active_container_stack.getProperty("machine_disallowed_areas", "value") areas = [] skirt_size = 0.0 @@ -212,8 +212,8 @@ class BuildVolume(SceneNode): # Add the skirt areas around the borders of the build plate. if skirt_size > 0: - half_machine_width = self._active_container_stack.getValue("machine_width") / 2 - half_machine_depth = self._active_container_stack.getValue("machine_depth") / 2 + half_machine_width = self._active_container_stack.getProperty("machine_width", "value") / 2 + half_machine_depth = self._active_container_stack.getProperty("machine_depth", "value") / 2 areas.append(Polygon(numpy.array([ [-half_machine_width, -half_machine_depth], @@ -249,21 +249,21 @@ class BuildVolume(SceneNode): def _getSkirtSize(self, container_stack): skirt_size = 0.0 - adhesion_type = container_stack.getValue("adhesion_type") + adhesion_type = container_stack.getProperty("adhesion_type", "value") if adhesion_type == "skirt": - skirt_distance = container_stack.getValue("skirt_gap") - skirt_line_count = container_stack.getValue("skirt_line_count") - skirt_size = skirt_distance + (skirt_line_count * container_stack.getValue("skirt_line_width")) + skirt_distance = container_stack.getProperty("skirt_gap", "value") + skirt_line_count = container_stack.getProperty("skirt_line_count", "value") + skirt_size = skirt_distance + (skirt_line_count * container_stack.getProperty("skirt_line_width", "value")) elif adhesion_type == "brim": - skirt_size = container_stack.getValue("brim_line_count") * container_stack.getValue("skirt_line_width") + skirt_size = container_stack.getProperty("brim_line_count", "value") * container_stack.getProperty("skirt_line_width", "value") elif adhesion_type == "raft": - skirt_size = container_stack.getValue("raft_margin") + skirt_size = container_stack.getProperty("raft_margin", "value") - if container_stack.getValue("draft_shield_enabled"): - skirt_size += container_stack.getValue("draft_shield_dist") + if container_stack.getProperty("draft_shield_enabled", "value"): + skirt_size += container_stack.getProperty("draft_shield_dist", "value") - if container_stack.getValue("xy_offset"): - skirt_size += container_stack.getValue("xy_offset") + if container_stack.getProperty("xy_offset", "value"): + skirt_size += container_stack.getProperty("xy_offset", "value") return skirt_size diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 1c65ea5dfe..9aec1a7290 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -37,7 +37,7 @@ class SolidView(View): if Application.getInstance().getGlobalContainerStack(): if Preferences.getInstance().getValue("view/show_overhang"): - angle = Application.getInstance().getGlobalContainerStack().getValue("support_angle") + angle = Application.getInstance().getGlobalContainerStack().getProperty("support_angle", "value") if angle is not None: self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(90 - angle))) else: From 3313286ea978fc53c25599d296ab1731ef62fe29 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 16:36:52 +0200 Subject: [PATCH 181/705] Update OSX log location Changed in https://github.com/Ultimaker/Uranium/commit/9cc143057963937fa17b4c046d33e8b214c11abe --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7fc77f9dcf..b56a5ea345 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ For crashes and similar issues, please attach the following information: * (On Windows) The log as produced by dxdiag (start -> run -> dxdiag -> save output) * The Cura GUI log file, located at * $User/AppData/Local/cura/cura.log (Windows) - * $User/.cura/cura.log (OSX) + * $User/Library/Application Support/cura (OSX) * $USER/.local/share/cura (Ubuntu/Linux) * The Cura Engine log, using Help -> Show Engine Log From b621958098a7d4080de1b366d6bc1fd819423aa4 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 18 May 2016 16:33:10 +0200 Subject: [PATCH 182/705] Fix uses of getValue after its removal from Uranium API --- cura/BuildVolume.py | 13 +++++++++++-- plugins/SolidView/SolidView.py | 1 - 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index 77bda87825..61802167a7 100644 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -37,6 +37,7 @@ class BuildVolume(SceneNode): self.setCalculateBoundingBox(False) + self._active_container_stack = None Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged) self._onGlobalContainerStackChanged() @@ -158,9 +159,14 @@ class BuildVolume(SceneNode): Application.getInstance().getController().getScene()._maximum_bounds = scale_to_max_bounds def _onGlobalContainerStackChanged(self): + if self._active_container_stack: + self._active_container_stack.propertyChanged.disconnect(self._onSettingPropertyChanged) + self._active_container_stack = Application.getInstance().getGlobalContainerStack() if self._active_container_stack: + self._active_container_stack.propertyChanged.connect(self._onSettingPropertyChanged) + self._width = self._active_container_stack.getProperty("machine_width", "value") if self._active_container_stack.getProperty("print_sequence", "value") == "one_at_a_time": self._height = self._active_container_stack.getProperty("gantry_height", "value") @@ -172,12 +178,15 @@ class BuildVolume(SceneNode): self.rebuild() - def _onSettingValueChanged(self, setting_key): + def _onSettingPropertyChanged(self, setting_key, property_name): + if property_name != "value": + return + if setting_key == "print_sequence": if Application.getInstance().getGlobalContainerStack().getProperty("print_sequence", "value") == "one_at_a_time": self._height = self._active_container_stack.getProperty("gantry_height", "value") else: - self._height = self._active_container_stack.getProperty("machine_depth", "value") + self._height = self._active_container_stack.getProperty("machine_height", "value") self.rebuild() if setting_key in self._skirt_settings: self._updateDisallowedAreas() diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 9aec1a7290..71b29c8186 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -35,7 +35,6 @@ class SolidView(View): self._disabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0))) if Application.getInstance().getGlobalContainerStack(): - if Preferences.getInstance().getValue("view/show_overhang"): angle = Application.getInstance().getGlobalContainerStack().getProperty("support_angle", "value") if angle is not None: From 3b5a74047bcb64890480cc9fc4f951c247d44ca8 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 13:40:42 +0200 Subject: [PATCH 183/705] Add setting instance type for extruder This type is not included in the global stack structure yet since there is no global stack structure per extruder yet. Contributes to issue CURA-1278. --- cura/CuraApplication.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 39a25c34ad..ee9b71dd33 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -74,6 +74,7 @@ class CuraApplication(QtApplication): VariantInstanceContainer = Resources.UserType + 5 UserInstanceContainer = Resources.UserType + 6 MachineStack = Resources.UserType + 7 + ExtruderInstanceContainer = Resources.UserType + 8 Q_ENUMS(ResourceTypes) @@ -124,6 +125,7 @@ class CuraApplication(QtApplication): Resources.addStorageType(self.ResourceTypes.QualityInstanceContainer, "quality") Resources.addStorageType(self.ResourceTypes.VariantInstanceContainer, "variants") Resources.addStorageType(self.ResourceTypes.MaterialInstanceContainer, "materials") + Resources.addStorageType(self.ResourceTypes.ExtruderInstanceContainer, "extruder") Resources.addStorageType(self.ResourceTypes.UserInstanceContainer, "user") Resources.addStorageType(self.ResourceTypes.MachineStack, "machine_instances") From 6b0a33e166c4d916852a17a5edb70ce19150d90d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 18 May 2016 17:53:27 +0200 Subject: [PATCH 184/705] Move dual extrusion settings into FDMPrinter This involves making labels and descriptions for some dual-extrusion machine settings, and default values for everything, making sure inheritance is correct, etc. Contributes to issue CURA-1278. --- cura/CuraApplication.py | 2 +- resources/definitions/fdmprinter.def.json | 362 ++++++++++++++++++ .../machines/dual_extrusion_printer.json | 361 ----------------- 3 files changed, 363 insertions(+), 362 deletions(-) delete mode 100644 resources/machines/dual_extrusion_printer.json diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index ee9b71dd33..eee0807161 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -125,7 +125,7 @@ class CuraApplication(QtApplication): Resources.addStorageType(self.ResourceTypes.QualityInstanceContainer, "quality") Resources.addStorageType(self.ResourceTypes.VariantInstanceContainer, "variants") Resources.addStorageType(self.ResourceTypes.MaterialInstanceContainer, "materials") - Resources.addStorageType(self.ResourceTypes.ExtruderInstanceContainer, "extruder") + Resources.addStorageType(self.ResourceTypes.ExtruderInstanceContainer, "extruders") Resources.addStorageType(self.ResourceTypes.UserInstanceContainer, "user") Resources.addStorageType(self.ResourceTypes.MachineStack, "machine_instances") diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 603dc18e92..cd997c3f34 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -241,6 +241,92 @@ "default_value": 0.4, "minimum_value": "0.001", "maximum_value_warning": "10" + }, + "machine_nozzle_offset_x": + { + "label": "Nozzle X Offset", + "description": "The x-coordinate of the offset of the nozzle.", + "type": "float", + "unit": "mm", + "default_value": 0, + "global_only": "True" + }, + "machine_nozzle_offset_y": + { + "label": "Nozzle Y Offset", + "description": "The y-coordinate of the offset of the nozzle.", + "type": "float", + "unit": "mm", + "default_value": 0, + "global_only": "True" + }, + "machine_extruder_start_code": + { + "label": "Extruder Start G-Code", + "description": "Start g-code to execute whenever turning the extruder on.", + "type": "str", + "default_value": "", + "global_only": "True" + }, + "machine_extruder_start_pos_abs": + { + "label": "Extruder Start Position Absolute", + "description": "Make the extruder starting position absolute rather than relative to the last-known location of the head.", + "type": "bool", + "default_value": false, + "global_only": "True" + }, + "machine_extruder_start_pos_x": + { + "label": "Extruder Start Position X", + "description": "The x-coordinate of the starting position when turning the extruder on.", + "type": "float", + "unit": "mm", + "default_value": 0, + "global_only": "True" + }, + "machine_extruder_start_pos_y": + { + "label": "Extruder Start Position Y", + "description": "The y-coordinate of the starting position when turning the extruder on.", + "type": "float", + "unit": "mm", + "default_value": 0, + "global_only": "True" + }, + "machine_extruder_end_code": + { + "label": "Extruder End G-Code", + "description": "End g-code to execute whenever turning the extruder off.", + "type": "str", + "default_value": "", + "global_only": "True" + }, + "machine_extruder_end_pos_abs": + { + "label": "Extruder End Position Absolute", + "description": "Make the extruder ending position absolute rather than relative to the last-known location of the head.", + "type": "bool", + "default_value": false, + "global_only": "True" + }, + "machine_extruder_end_pos_x": + { + "label": "Extruder End Position X", + "description": "The x-coordinate of the ending position when turning the extruder off.", + "type": "float", + "unit": "mm", + "default_value": 0, + "global_only": "True" + }, + "machine_extruder_end_pos_y": + { + "label": "Extruder End Position Y", + "description": "The y-coordinate of the ending position when turning the extruder off.", + "type": "float", + "unit": "mm", + "default_value": 0, + "global_only": "True" } } }, @@ -391,6 +477,20 @@ "enabled": "support_roof_enable", "global_only": true, "value": "line_width" + }, + "prime_tower_line_width": + { + "label": "Prime Tower Line Width", + "description": "Width of a single prime tower line.", + "type": "float", + "unit": "mm", + "enabled": "prime_tower_enable", + "default_value": 0.4, + "value": "line_width", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "global_only": "True" } } } @@ -889,6 +989,71 @@ "minimum_value_warning": "-0.0001", "maximum_value_warning": "10", "enabled": "retraction_enable" + }, + "material_standby_temperature": + { + "label": "Standby Temperature", + "description": "The temperature of the nozzle when another nozzle is currently used for printing.", + "type": "float", + "unit": "°C", + "default_value": 150, + "minimum_value": "0", + "maximum_value_warning": "260", + "global_only": "True" + }, + "switch_extruder_retraction_amount": + { + "label": "Nozzle Switch Retraction Distance", + "description": "The amount of retraction: Set at 0 for no retraction at all. This should generally be the same as the length of the heat zone.", + "type": "float", + "unit": "mm", + "enabled": "retraction_enable", + "default_value": 20, + "value": "machine_heat_zone_length", + "minimum_value_warning": "0", + "maximum_value_warning": "100", + "global_only": "True" + }, + "switch_extruder_retraction_speeds": + { + "label": "Nozzle Switch Retraction Speed", + "description": "The speed at which the filament is retracted. A higher retraction speed works better, but a very high retraction speed can lead to filament grinding.", + "type": "float", + "unit": "mm/s", + "enabled": "retraction_enable", + "default_value": 20, + "minimum_value": "0.1", + "maximum_value_warning": "300", + "global_only": "True", + "children": + { + "switch_extruder_retraction_speed": + { + "label": "Nozzle Switch Retract Speed", + "description": "The speed at which the filament is retracted during a nozzle switch retract.", + "type": "float", + "unit": "mm/s", + "enabled": "retraction_enable", + "default_value": 20, + "value": "switch_extruder_retraction_speeds", + "minimum_value": "0.1", + "maximum_value_warning": "300", + "global_only": "True" + }, + "switch_extruder_prime_speed": + { + "label": "Nozzle Switch Prime Speed", + "description": "The speed at which the filament is pushed back after a nozzle switch retraction.", + "type": "float", + "unit": "mm/s", + "enabled": "retraction_enable", + "default_value": 20, + "value": "switch_extruder_retraction_speeds", + "minimum_value": "0.1", + "maximum_value_warning": "300", + "global_only": "True" + } + } } } }, @@ -1018,6 +1183,19 @@ "global_only": true } } + }, + "speed_prime_tower": + { + "label": "Prime Tower Speed", + "description": "The speed at which the prime tower is printed. Printing the prime tower slower can make it more stable when the adhesion between the different filaments is suboptimal.", + "type": "float", + "unit": "mm/s", + "enabled": "prime_tower_enable", + "default_value": 60, + "value": "speed_print", + "minimum_value": "0.1", + "maximum_value_warning": "150", + "global_only": "True" } } }, @@ -1962,6 +2140,190 @@ } } }, + "dual": + { + "label": "Dual Extrusion", + "type": "category", + "icon": "category_dual", + "description": "Settings used for printing with multiple extruders.", + "children": + { + "extruder_nr": + { + "label": "Extruder", + "description": "The extruder train used for printing. This is used in multi-extrusion.", + "type": "int", + "default_value": 0, + "minimum_value": "0", + "maximum_value": "machine_extruder_count - 1" + }, + "adhesion_extruder_nr": + { + "label": "Platform Adhesion Extruder", + "description": "The extruder train to use for printing the skirt/brim/raft. This is used in multi-extrusion.", + "type": "int", + "default_value": 0, + "minimum_value": "0", + "maximum_value": "machine_extruder_count - 1", + "global_only": "True" + }, + "support_extruder_nr": + { + "label": "Support Extruder", + "description": "The extruder train to use for printing the support. This is used in multi-extrusion.", + "type": "int", + "default_value": 0, + "minimum_value": "0", + "maximum_value": "machine_extruder_count - 1", + "global_only": "True", + "children": { + "support_infill_extruder_nr": + { + "label": "Support Infill Extruder", + "description": "The extruder train to use for printing the infill of the support. This is used in multi-extrusion.", + "type": "int", + "default_value": 0, + "value": "support_extruder_nr", + "minimum_value": "0", + "maximum_value": "machine_extruder_count - 1", + "global_only": "True" + }, + "support_extruder_nr_layer_0": + { + "label": "First Layer Support Extruder", + "description": "The extruder train to use for printing the first layer of support infill. This is used in multi-extrusion.", + "type": "int", + "default_value": 0, + "value": "support_extruder_nr", + "minimum_value": "0", + "maximum_value": "machine_extruder_count - 1", + "global_only": "True" + }, + "support_roof_extruder_nr": + { + "label": "Support Roof Extruder", + "description": "The extruder train to use for printing the roof of the support. This is used in multi-extrusion.", + "type": "int", + "default_value": 0, + "value": "support_extruder_nr", + "minimum_value": "0", + "maximum_value": "machine_extruder_count - 1", + "global_only": "True" + } + } + }, + "prime_tower_enable": + { + "label": "Enable Prime Tower", + "description": "Print a tower next to the print which serves to prime the material after each nozzle switch.", + "type": "bool", + "default_value": false, + "global_only": "True" + }, + "prime_tower_size": + { + "label": "Prime Tower Size", + "description": "The width of the prime tower.", + "type": "float", + "unit": "mm", + "enabled": "prime_tower_enable", + "default_value": 15, + "value": "15 if prime_tower_enable else 0", + "minimum_value": "0", + "maximum_value_warning": "20", + "global_only": "True" + }, + "prime_tower_position_x": + { + "label": "Prime Tower X Position", + "description": "The x coordinate of the position of the prime tower.", + "type": "float", + "unit": "mm", + "enabled": "prime_tower_enable", + "default_value": 200, + "minimum_value_warning": "-1000", + "maximum_value_warning": "1000", + "global_only": "True" + }, + "prime_tower_position_y": + { + "label": "Prime Tower Y Position", + "description": "The y coordinate of the position of the prime tower.", + "type": "float", + "unit": "mm", + "enabled": "prime_tower_enable", + "default_value": 200, + "minimum_value_warning": "-1000", + "maximum_value_warning": "1000", + "global_only": "True" + }, + "prime_tower_flow": + { + "label": "Prime Tower Flow", + "description": "Flow compensation: the amount of material extruded is multiplied by this value.", + "type": "float", + "unit": "%", + "enabled": "prime_tower_enable", + "default_value": 100, + "minimum_value": "0.0001", + "minimum_value_warning": "50", + "maximum_value_warning": "150", + "global_only": "True" + }, + "prime_tower_wipe_enabled": + { + "label": "Wipe Nozzle on Prime Tower", + "description": "After printing the prime tower with one nozzle, wipe the oozed material from the other nozzle off on the prime tower.", + "type": "bool", + "enabled": "prime_tower_enable", + "default_value": false, + "global_only": "True" + }, + "multiple_mesh_overlap": + { + "label": "Dual Extrusion Overlap", + "description": "Make the objects printed with different extruder trains overlap a bit. This makes the different materials bond together better.", + "type": "float", + "unit": "mm", + "default_value": 0.15, + "minimum_value": "0", + "maximum_value_warning": "1.0", + "global_only": "True" + }, + "ooze_shield_enabled": + { + "label": "Enable Ooze Shield", + "description": "Enable exterior ooze shield. This will create a shell around the object which is likely to wipe a second nozzle if it's at the same height as the first nozzle.", + "type": "bool", + "default_value": false, + "global_only": "True" + }, + "ooze_shield_angle": + { + "label": "Ooze Shield Angle", + "description": "The maximum angle a part in the ooze shield will have. With 0 degrees being vertical, and 90 degrees being horizontal. A smaller angle leads to less failed ooze shields, but more material.", + "type": "float", + "unit": "°", + "enabled": "ooze_shield_enabled", + "default_value": 60, + "minimum_value": "0", + "maximum_value": "90", + "global_only": "True" + }, + "ooze_shield_dist": + { + "label": "Ooze Shield Distance", + "description": "Distance of the ooze shield from the print, in the X/Y directions.", + "type": "float", + "unit": "mm", + "enabled": "ooze_shield_enabled", + "default_value": 2, + "minimum_value": "0", + "maximum_value_warning": "30", + "global_only": "True" + } + } + }, "experimental": { "label": "Experimental Modes", diff --git a/resources/machines/dual_extrusion_printer.json b/resources/machines/dual_extrusion_printer.json deleted file mode 100644 index 57ad490cdd..0000000000 --- a/resources/machines/dual_extrusion_printer.json +++ /dev/null @@ -1,361 +0,0 @@ -{ - "version": 1, - "id": "dual_extrusion", - "name": "Dual Extrusion Base File", - "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g", - "inherits": "fdmprinter.json", - - "visible": false, - - "machine_extruder_trains": { - "0": { - "extruder_nr": { - "default": 0 - }, - "machine_nozzle_offset_x": { - "default": 0 - }, - "machine_nozzle_offset_y": { - "default": 0 - }, - "machine_nozzle_heat_up_speed": { - "default": 2 - }, - "machine_nozzle_cool_down_speed": { - "default": 2 - }, - "machine_nozzle_tip_outer_diameter": { - "default": 1 - }, - "machine_nozzle_head_distance": { - "default": 3 - }, - "machine_nozzle_expansion_angle": { - "default": 45 - }, - "machine_heat_zone_length": { - "default": 16 - } - }, - "1": { - "extruder_nr": { - "default": 1 - }, - "machine_nozzle_offset_x": { - "default": 0 - }, - "machine_nozzle_offset_y": { - "default": 0 - }, - "machine_nozzle_heat_up_speed": { - "default": 2 - }, - "machine_nozzle_cool_down_speed": { - "default": 2 - }, - "machine_nozzle_tip_outer_diameter": { - "default": 1 - }, - "machine_nozzle_head_distance": { - "default": 3 - }, - "machine_nozzle_expansion_angle": { - "default": 45 - }, - "machine_heat_zone_length": { - "default": 16 - } - } - }, - - "machine_settings": { - "machine_use_extruder_offset_to_offset_coords": { "default": false }, - - "machine_nozzle_offset_x": { "default": 0, "SEE_machine_extruder_trains": true }, - "machine_nozzle_offset_y": { "default": 0, "SEE_machine_extruder_trains": true }, - "machine_extruder_start_code": { "default": "", "SEE_machine_extruder_trains": true }, - "machine_extruder_start_pos_abs": { "default": false, "SEE_machine_extruder_trains": true }, - "machine_extruder_start_pos_x": { "default": 0, "SEE_machine_extruder_trains": true }, - "machine_extruder_start_pos_y": { "default": 0, "SEE_machine_extruder_trains": true }, - "machine_extruder_end_pos_abs": { "default": false, "SEE_machine_extruder_trains": true }, - "machine_extruder_end_pos_x": { "default": 0, "SEE_machine_extruder_trains": true }, - "machine_extruder_end_pos_y": { "default": 0, "SEE_machine_extruder_trains": true }, - "machine_extruder_end_code": { "default": "", "SEE_machine_extruder_trains": true } - }, - "overrides": { - "speed_print": { - "children": { - "speed_prime_tower": { - "label": "Prime Tower Speed", - "description": "The speed at which the prime tower is printed. Printing the prime tower slower can make it more stable when the adhesion between the different filaments is suboptimal.", - "unit": "mm/s", - "type": "float", - "min_value": "0.1", - "max_value_warning": "150", - "default": 60, - "visible": false, - "enabled": "prime_tower_enable", - "global_only": true - } - } - }, - "line_width": { - "children": { - "prime_tower_line_width": { - "label": "Prime Tower Line Width", - "description": "Width of a single prime tower line.", - "unit": "mm", - "min_value": "0.0001", - "min_value_warning": "0.2", - "max_value_warning": "5", - "default": 0.4, - "type": "float", - "visible": false, - "enabled": "prime_tower_enable", - "global_only": true - } - } - } - }, - "categories": { - "dual": { - "label": "Dual Extrusion", - "visible": true, - "icon": "category_dual", - "settings": { - "extruder_nr": { - "label": "Extruder", - "description": "The extruder train used for printing. This is used in multi-extrusion.", - "type": "int", - "default": 0, - "min_value": "0", - "max_value": "machine_extruder_count - 1", - "always_visible": true - }, - "adhesion_extruder_nr": { - "label": "Platform Adhesion Extruder", - "description": "The extruder train to use for printing the skirt/brim/raft. This is used in multi-extrusion.", - "type": "int", - "default": 0, - "min_value": "0", - "max_value": "machine_extruder_count - 1", - "global_only": true - }, - "support_extruder_nr": { - "label": "Support Extruder", - "description": "The extruder train to use for printing the support. This is used in multi-extrusion.", - "type": "int", - "default": 0, - "min_value": "0", - "max_value": "machine_extruder_count - 1", - "global_only": true, - "children": { - "support_infill_extruder_nr": { - "label": "Support Infill Extruder", - "description": "The extruder train to use for printing the infill of the support. This is used in multi-extrusion.", - "type": "int", - "default": 0, - "min_value": "0", - "max_value": "machine_extruder_count - 1", - "global_only": true - }, - "support_extruder_nr_layer_0": { - "label": "First Layer Support Extruder", - "description": "The extruder train to use for printing the first layer of support infill. This is used in multi-extrusion.", - "type": "int", - "default": 0, - "min_value": "0", - "max_value": "machine_extruder_count - 1", - "global_only": true - }, - "support_roof_extruder_nr": { - "label": "Support Roof Extruder", - "description": "The extruder train to use for printing the roof of the support. This is used in multi-extrusion.", - "type": "int", - "default": 0, - "min_value": "0", - "max_value": "machine_extruder_count - 1", - "enabled": "support_roof_enable", - "global_only": true - } - } - }, - "prime_tower_enable": { - "label": "Enable Prime Tower", - "description": "Print a tower next to the print which serves to prime the material after each nozzle switch.", - "type": "boolean", - "visible": true, - "default": false, - "global_only": true - }, - "prime_tower_size": { - "label": "Prime Tower Size", - "description": "The width of the prime tower.", - "visible": false, - "type": "float", - "unit": "mm", - "default": 15, - "min_value": "0", - "max_value_warning": "20", - "inherit_function": "15 if prime_tower_enable else 0", - "enabled": "prime_tower_enable", - "global_only": true - }, - "prime_tower_position_x": { - "label": "Prime Tower X Position", - "description": "The x position of the prime tower.", - "visible": false, - "type": "float", - "unit": "mm", - "default": 200, - "min_value_warning": "-1000", - "max_value_warning": "1000", - "enabled": "prime_tower_enable", - "global_only": true - }, - "prime_tower_position_y": { - "label": "Prime Tower Y Position", - "description": "The y position of the prime tower.", - "visible": false, - "type": "float", - "unit": "mm", - "default": 200, - "min_value_warning": "-1000", - "max_value_warning": "1000", - "enabled": "prime_tower_enable", - "global_only": true - }, - "prime_tower_flow": { - "label": "Prime Tower Flow", - "description": "Flow compensation: the amount of material extruded is multiplied by this value.", - "visible": false, - "unit": "%", - "default": 100, - "type": "float", - "min_value": "5", - "min_value_warning": "50", - "max_value_warning": "150", - "enabled": "prime_tower_enable", - "global_only": true - }, - "prime_tower_wipe_enabled": { - "label": "Wipe Nozzle on Prime tower", - "description": "After printing the prime tower with the one nozzle, wipe the oozed material from the other nozzle off on the prime tower.", - "type": "boolean", - "default": false, - "enabled": "prime_tower_enable", - "global_only": true - }, - "multiple_mesh_overlap": { - "label": "Dual Extrusion Overlap", - "description": "Make the objects printed with different extruder trains overlap a bit. This makes the different materials bond together better.", - "visible": false, - "type": "float", - "unit": "mm", - "default": 0.15, - "min_value": "0", - "max_value_warning": "1.0", - "global_only": true - }, - "ooze_shield_enabled": { - "label": "Enable Ooze Shield", - "description": "Enable exterior ooze shield. This will create a shell around the object which is likely to wipe a second nozzle if it's at the same height as the first nozzle.", - "type": "boolean", - "default": false, - "global_only": true - }, - "ooze_shield_angle": { - "label": "Ooze Shield Angle", - "description": "The maximum angle a part in the ooze shield will have. With 0 degrees being vertical, and 90 degrees being horizontal. A smaller angle leads to less failed ooze shields, but more material.", - "unit": "°", - "type": "float", - "min_value": "0", - "max_value": "90", - "default": 60, - "visible": false, - "enabled": "ooze_shield_enabled", - "global_only": true - }, - "ooze_shield_dist": { - "label": "Ooze Shields Distance", - "description": "Distance of the ooze shield from the print, in the X/Y directions.", - "unit": "mm", - "type": "float", - "min_value": "0", - "max_value_warning": "30", - "default": 2, - "visible": false, - "enabled": "ooze_shield_enabled", - "global_only": true - } - } - }, - "material": { - "settings": { - "material_standby_temperature": { - "label": "Standby Temperature", - "description": "The temperature of the nozzle when another nozzle is currently used for printing.", - "unit": "°C", - "type": "float", - "default": 150, - "min_value": "0", - "max_value_warning": "260", - "global_only": "True", - "visible": false - }, - "switch_extruder_retraction_amount": { - "label": "Nozzle Switch Retraction Distance", - "description": "The amount of retraction: Set at 0 for no retraction at all. This should generally be the same as the length of the heat zone.", - "unit": "mm", - "type": "float", - "default": 20, - "min_value_warning": "0", - "max_value_warning": "100", - "visible": false, - "inherit_function": "machine_heat_zone_length", - "enabled": "retraction_enable", - "global_only": true - }, - "switch_extruder_retraction_speeds": { - "label": "Nozzle Switch Retraction Speed", - "description": "The speed at which the filament is retracted. A higher retraction speed works better, but a very high retraction speed can lead to filament grinding.", - "unit": "mm/s", - "type": "float", - "default": 20, - "min_value": "0.1", - "max_value_warning": "300", - "visible": false, - "inherit": false, - "enabled": "retraction_enable", - "global_only": true, - "children": { - "switch_extruder_retraction_speed": { - "label": "Nozzle Switch Retract Speed", - "description": "The speed at which the filament is retracted during a nozzle switch retract. ", - "unit": "mm/s", - "type": "float", - "default": 20, - "min_value": "0.1", - "max_value_warning": "300", - "visible": false, - "enabled": "retraction_enable", - "global_only": true - }, - "switch_extruder_prime_speed": { - "label": "Nozzle Switch Prime Speed", - "description": "The speed at which the filament is pushed back after a nozzle switch retraction.", - "unit": "mm/s", - "type": "float", - "default": 20, - "min_value": "0.1", - "max_value_warning": "300", - "visible": false, - "enabled": "retraction_enable", - "global_only": true - } - } - } - } - } - } -} From 0e792e7a2257da9af263ab491980540f2431f7f7 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 19 May 2016 11:25:25 +0200 Subject: [PATCH 185/705] Added SettingOverrideDecorator stub CURA-1278 --- cura/SettingOverrideDecorator.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 cura/SettingOverrideDecorator.py diff --git a/cura/SettingOverrideDecorator.py b/cura/SettingOverrideDecorator.py new file mode 100644 index 0000000000..5574fb3182 --- /dev/null +++ b/cura/SettingOverrideDecorator.py @@ -0,0 +1,13 @@ +# Copyright (c) 2016 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. +from UM.Scene.SceneNodeDecorator import SceneNodeDecorator + + +## A decorator that adds a container stack to a Node. This stack should be queried for all settings regarding +# the linked node. The Stack in question will refer to the global stack (so that settings that are not defined by +# this stack still resolve. +class SettingOverrideDecorator(SceneNodeDecorator): + + def __init__(self): + super().__init__() + From e20691c4216483f5edf0a554c7b7873fcb55d05f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 19 May 2016 11:41:10 +0200 Subject: [PATCH 186/705] Fleshing out of SettingOverrideDecorator CURA-1278 --- cura/SettingOverrideDecorator.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/cura/SettingOverrideDecorator.py b/cura/SettingOverrideDecorator.py index 5574fb3182..826970c51f 100644 --- a/cura/SettingOverrideDecorator.py +++ b/cura/SettingOverrideDecorator.py @@ -2,12 +2,28 @@ # Cura is released under the terms of the AGPLv3 or higher. from UM.Scene.SceneNodeDecorator import SceneNodeDecorator +from UM.Settings.ContainerStack import ContainerStack +from UM.Settings.InstanceContainer import InstanceContainer +from UM.Settings.ContainerRegistry import ContainerRegistry + +from UM.Application import Application ## A decorator that adds a container stack to a Node. This stack should be queried for all settings regarding # the linked node. The Stack in question will refer to the global stack (so that settings that are not defined by # this stack still resolve. class SettingOverrideDecorator(SceneNodeDecorator): - def __init__(self): super().__init__() + self._stack = ContainerStack(id = "SettingOverrideStack") + self._instance = InstanceContainer(id = "SettingOverrideInstanceContainer") + self._stack.addContainer(self._instance) + Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged) + self._onGlobalContainerStackChanged() + + def _onGlobalContainerStackChanged(self): + ## Ensure that the next stack is always the global stack. + self._stack.setNextStack(Application.getInstance().getGlobalContainerStack()) + + def getStack(self): + return self._stack \ No newline at end of file From 4de0a208d15faa6474e733878b50ed3ce8803f1a Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 19 May 2016 14:48:34 +0200 Subject: [PATCH 187/705] Fix version number and remove beta tag in Changelog Fixes CURA-1575 --- plugins/ChangeLogPlugin/ChangeLog.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/ChangeLogPlugin/ChangeLog.txt b/plugins/ChangeLogPlugin/ChangeLog.txt index 8dc6a61dd8..6cf0b5a488 100644 --- a/plugins/ChangeLogPlugin/ChangeLog.txt +++ b/plugins/ChangeLogPlugin/ChangeLog.txt @@ -1,6 +1,5 @@ -[2.1.0] +[2.1.1] -*2.1 Beta release Cura has been completely reengineered from the ground up for an even more seamless integration between hardware, software and materials. Together with its intuitive new user interface, it’s now also ready for any future developments. For the beginner Cura makes 3D printing incredibly easy, and for more advanced users, there are over 140 new customisable settings. *Select Multiple Objects From 570910187fd7f2557955d19aba7549a8d79050ce Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 19 May 2016 16:27:51 +0200 Subject: [PATCH 188/705] Fix typo in method name CURA-1278 --- resources/qml/Settings/SettingCategory.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index 56a20aec3b..f4e3dbe5ae 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -62,7 +62,7 @@ Button { width: height; onClicked: { - base.showAllHidenInheritedSettings() + base.showAllHiddenInheritedSettings() } color: UM.Theme.getColor("setting_control_button") From 2696f883b026fe4ea49fc22d62770099ee5521c6 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 19 May 2016 16:31:29 +0200 Subject: [PATCH 189/705] Add a bit of documentation I was going further with this, but then it was decided that we need to do this later but I won't throw away this bit of documentation when I have it anyway. Contributes to issue CURA-1278. --- plugins/CuraEngineBackend/StartSliceJob.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index f51cff5d93..9fecb20646 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -38,20 +38,23 @@ class StartSliceJob(Job): self._profile = profile self._socket = socket + ## Runs the job that initiates the slicing. def run(self): self._scene.acquireLock() + # Remove old layer data. for node in DepthFirstIterator(self._scene.getRoot()): if node.callDecoration("getLayerData"): node.getParent().removeChild(node) break + # Get the objects in their groups to print. object_groups = [] if self._profile.getSettingValue("print_sequence") == "one_at_a_time": for node in OneAtATimeIterator(self._scene.getRoot()): temp_list = [] - ## Node can't be printed, so don't bother sending it. + # Node can't be printed, so don't bother sending it. if getattr(node, "_outside_buildarea", False): continue From 2fa24edc1fdac439ce23450ee85994039b146af3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 20 May 2016 11:29:48 +0200 Subject: [PATCH 190/705] Fixed type for global_only property CURA-1278 --- cura/CuraApplication.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index eee0807161..adce2f854e 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -24,7 +24,7 @@ from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation from UM.Operations.GroupedOperation import GroupedOperation from UM.Operations.SetTransformOperation import SetTransformOperation -from UM.Settings.SettingDefinition import SettingDefinition +from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyType from UM.Settings.ContainerRegistry import ContainerRegistry from UM.i18n import i18nCatalog @@ -119,7 +119,7 @@ class CuraApplication(QtApplication): Resources.addType(self.ResourceTypes.QmlFiles, "qml") Resources.addType(self.ResourceTypes.Firmware, "firmware") - SettingDefinition.addSupportedProperty("global_only", "bool") + SettingDefinition.addSupportedProperty("global_only", DefinitionPropertyType.Function, default = False) ## Add the 4 types of profiles to storage. Resources.addStorageType(self.ResourceTypes.QualityInstanceContainer, "quality") From 9dc70fba02b1c52d3724a5b66fa80926300a4814 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 20 May 2016 12:42:18 +0200 Subject: [PATCH 191/705] Add missing category-metadata Forgot to add this, apparently. Contributes to issue CURA-1278. --- resources/definitions/ultimaker2.def.json | 1 + resources/definitions/ultimaker_original.def.json | 1 + 2 files changed, 2 insertions(+) diff --git a/resources/definitions/ultimaker2.def.json b/resources/definitions/ultimaker2.def.json index 606d51c545..7b2222e5b3 100644 --- a/resources/definitions/ultimaker2.def.json +++ b/resources/definitions/ultimaker2.def.json @@ -7,6 +7,7 @@ "visible": true, "author": "Ultimaker", "manufacturer": "Ultimaker", + "category": "Ultimaker", "file_formats": "text/x-gcode", "icon": "icon_ultimaker2.png", "platform": "ultimaker2_platform.obj", diff --git a/resources/definitions/ultimaker_original.def.json b/resources/definitions/ultimaker_original.def.json index cd2fac4599..ae659174bd 100644 --- a/resources/definitions/ultimaker_original.def.json +++ b/resources/definitions/ultimaker_original.def.json @@ -6,6 +6,7 @@ "metadata": { "author": "Ultimaker", "manufacturer": "Ultimaker", + "category": "Ultimaker", "file_formats": "text/x-gcode", "icon": "icon_ultimaker.png", "platform": "ultimaker_platform.stl", From 6fe70fc7e9a4e9674c7375c129fe2e71fa1ec53b Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 20 May 2016 13:28:05 +0200 Subject: [PATCH 192/705] Add definition for machine_use_extruder_offset_to_offset_coords While this was only used by Ultimaker printers, it is not specific to Ultimaker's printers so I'm putting the definition in FDMPrinter. Contributes to issue CURA-1278. --- resources/definitions/fdmprinter.def.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index cd997c3f34..e22d10f2aa 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -327,6 +327,13 @@ "unit": "mm", "default_value": 0, "global_only": "True" + }, + "machine_use_extruder_offset_to_offset_coords": + { + "label": "Offset With Extruder", + "description": "Apply the extruder offset to the coordinate system.", + "type": "bool", + "default_value": true } } }, From 7656f5a19b45b8eec11b7617ff1d6f213161014d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 20 May 2016 13:30:19 +0200 Subject: [PATCH 193/705] Make definition of machine_extruder_drive_upgrade This setting is specific to UMO, so I'm defining it in the UMO definition. Contributes to issue CURA-1278. --- resources/definitions/ultimaker_original.def.json | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/resources/definitions/ultimaker_original.def.json b/resources/definitions/ultimaker_original.def.json index ae659174bd..76b6c8b4ff 100644 --- a/resources/definitions/ultimaker_original.def.json +++ b/resources/definitions/ultimaker_original.def.json @@ -18,6 +18,14 @@ ] }, + "settings": { + "machine_extruder_drive_upgrade": { + "label": "Extruder Drive Upgrade", + "description": "This machine has the extruder drive upgrade.", + "type": "bool", + "default_value": false + } + }, "overrides": { "machine_width": { "default_value": 205 @@ -63,9 +71,6 @@ }, "machine_end_gcode": { "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" - }, - "machine_extruder_drive_upgrade": { - "default_value": false } } } From 8e3d6cf2b549ace769387f4e157e27bdae79314a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 20 May 2016 13:34:47 +0200 Subject: [PATCH 194/705] Repair x and y nozzle offsets The setting name is different. This probably wasn't updated for a while. Contributes to issue CURA-1278. --- resources/definitions/innovo_inventor.def.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/definitions/innovo_inventor.def.json b/resources/definitions/innovo_inventor.def.json index 14619833a7..9ba8d0d44b 100644 --- a/resources/definitions/innovo_inventor.def.json +++ b/resources/definitions/innovo_inventor.def.json @@ -43,10 +43,10 @@ "gantry_height": { "default_value": 82.3 }, - "machine_nozzle_offset_x_1": { + "machine_nozzle_offset_x": { "default_value": 0 }, - "machine_nozzle_offset_y_1": { + "machine_nozzle_offset_y": { "default_value": 15 }, "machine_gcode_flavor": { From 305cb27ac0e6550f359c2e5f52031970f1a80d67 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 20 May 2016 13:35:38 +0200 Subject: [PATCH 195/705] Global_only is now a string, as the filtering does not work with settingFunctions CURA-1278 --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index adce2f854e..f328e83174 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -119,7 +119,7 @@ class CuraApplication(QtApplication): Resources.addType(self.ResourceTypes.QmlFiles, "qml") Resources.addType(self.ResourceTypes.Firmware, "firmware") - SettingDefinition.addSupportedProperty("global_only", DefinitionPropertyType.Function, default = False) + SettingDefinition.addSupportedProperty("global_only", DefinitionPropertyType.String, default = "False") ## Add the 4 types of profiles to storage. Resources.addStorageType(self.ResourceTypes.QualityInstanceContainer, "quality") From 295cea338cbfcfa141b485acec90a3b9fe78e2e1 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 20 May 2016 14:09:58 +0200 Subject: [PATCH 196/705] Translate tool is now no longer stopped by ton of errors CURA-1278 --- cura/ConvexHullDecorator.py | 6 +++--- cura/ConvexHullJob.py | 10 +++++----- .../CuraEngineBackend/CuraEngineBackend.py | 20 +++++++++---------- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/cura/ConvexHullDecorator.py b/cura/ConvexHullDecorator.py index b53737cc80..04a46ecaca 100644 --- a/cura/ConvexHullDecorator.py +++ b/cura/ConvexHullDecorator.py @@ -25,9 +25,9 @@ class ConvexHullDecorator(SceneNodeDecorator): self._convex_hull_job = None self._profile = None - Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onActiveProfileChanged) - Application.getInstance().getMachineManager().activeMachineInstanceChanged.connect(self._onActiveMachineInstanceChanged) - self._onActiveProfileChanged() + #Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onActiveProfileChanged) + #Application.getInstance().getMachineManager().activeMachineInstanceChanged.connect(self._onActiveMachineInstanceChanged) + #self._onActiveProfileChanged() ## Force that a new (empty) object is created upon copy. def __deepcopy__(self, memo): diff --git a/cura/ConvexHullJob.py b/cura/ConvexHullJob.py index 9fb18981d3..7e814af7d7 100644 --- a/cura/ConvexHullJob.py +++ b/cura/ConvexHullJob.py @@ -59,12 +59,12 @@ class ConvexHullJob(Job): # This is done because of rounding errors. hull = hull.getMinkowskiHull(Polygon(numpy.array([[-0.5, -0.5], [-0.5, 0.5], [0.5, 0.5], [0.5, -0.5]], numpy.float32))) - profile = Application.getInstance().getMachineManager().getWorkingProfile() - if profile: - if profile.getSettingValue("print_sequence") == "one_at_a_time" and not self._node.getParent().callDecoration("isGroup"): + global_stack = Application.getInstance().getGlobalContainerStack() + if global_stack: + if global_stack.getProperty("print_sequence", "value")== "one_at_a_time" and not self._node.getParent().callDecoration("isGroup"): # Printing one at a time and it's not an object in a group self._node.callDecoration("setConvexHullBoundary", copy.deepcopy(hull)) - head_and_fans = Polygon(numpy.array(profile.getSettingValue("machine_head_with_fans_polygon"), numpy.float32)) + head_and_fans = Polygon(numpy.array(global_stack.getProperty("machine_head_with_fans_polygon", "value"), numpy.float32)) # Full head hull is used to actually check the order. full_head_hull = hull.getMinkowskiHull(head_and_fans) @@ -77,7 +77,7 @@ class ConvexHullJob(Job): # Min head hull is used for the push free min_head_hull = hull.getMinkowskiHull(head_and_fans) self._node.callDecoration("setConvexHullHead", min_head_hull) - hull = hull.getMinkowskiHull(Polygon(numpy.array(profile.getSettingValue("machine_head_polygon"),numpy.float32))) + hull = hull.getMinkowskiHull(Polygon(numpy.array(global_stack.getProperty("machine_head_polygon","value"),numpy.float32))) else: self._node.callDecoration("setConvexHullHead", None) if self._node.getParent() is None: # Node was already deleted before job is done. diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 5102427823..a57aa01ba9 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -134,14 +134,15 @@ class CuraEngineBackend(Backend): self._process_layers_job.abort() self._process_layers_job = None - if self._profile.hasErrorValue(): - Logger.log("w", "Profile has error values. Aborting slicing") - if self._message: - self._message.hide() - self._message = None - self._message = Message(catalog.i18nc("@info:status", "Unable to slice. Please check your setting values for errors.")) - self._message.show() - return #No slicing if we have error values since those are by definition illegal values. + #TODO: Re-add don't slice with error stuff. + #if self._profile.hasErrorValue(): + # Logger.log("w", "Profile has error values. Aborting slicing") + # if self._message: + # self._message.hide() + # self._message = None + # self._message = Message(catalog.i18nc("@info:status", "Unable to slice. Please check your setting values for errors.")) + # self._message.show() + # return #No slicing if we have error values since those are by definition illegal values. self.processingProgress.emit(0.0) self.backendStateChange.emit(BackendState.NOT_STARTED) @@ -265,9 +266,6 @@ class CuraEngineBackend(Backend): self._change_timer.start() def _onChanged(self): - if not self._profile: - return - self._change_timer.start() def _onBackendConnected(self): From bcff683fb0cd2a415c561a0fcf02490979ecdb06 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 20 May 2016 14:15:06 +0200 Subject: [PATCH 197/705] Removed old perobject setting code, so plugin is actually loaded (instead of crashing) CURA-1278 --- .../PerObjectSettingsModel.py | 16 ++++++++-------- .../SettingOverrideModel.py | 13 +++++++------ plugins/PerObjectSettingsTool/__init__.py | 2 +- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsModel.py b/plugins/PerObjectSettingsTool/PerObjectSettingsModel.py index 7f7cef049b..cbe22d129e 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsModel.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsModel.py @@ -7,8 +7,8 @@ from UM.Application import Application from UM.Qt.ListModel import ListModel from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator from UM.Scene.SceneNode import SceneNode -from UM.Settings.SettingOverrideDecorator import SettingOverrideDecorator -from UM.Settings.ProfileOverrideDecorator import ProfileOverrideDecorator +#from UM.Settings.SettingOverrideDecorator import SettingOverrideDecorator +#from UM.Settings.ProfileOverrideDecorator import ProfileOverrideDecorator from . import SettingOverrideModel @@ -35,7 +35,7 @@ class PerObjectSettingsModel(ListModel): self.setProperty(self.find("id", object_id), "profile", profile_name) profile = None - if profile_name != "global": + '''if profile_name != "global": profile = Application.getInstance().getMachineManager().findProfile(profile_name) node = self._scene.findObject(object_id) @@ -45,7 +45,7 @@ class PerObjectSettingsModel(ListModel): node.callDecoration("setProfile", profile) else: if node.getDecorator(ProfileOverrideDecorator): - node.removeDecorator(ProfileOverrideDecorator) + node.removeDecorator(ProfileOverrideDecorator)''' @pyqtSlot("quint64", str) def addSettingOverride(self, object_id, key): @@ -54,8 +54,8 @@ class PerObjectSettingsModel(ListModel): return node = self._scene.findObject(object_id) - if not node.getDecorator(SettingOverrideDecorator): - node.addDecorator(SettingOverrideDecorator()) + #if not node.getDecorator(SettingOverrideDecorator): + # node.addDecorator(SettingOverrideDecorator()) node.callDecoration("addSetting", key) @@ -64,8 +64,8 @@ class PerObjectSettingsModel(ListModel): node = self._scene.findObject(object_id) node.callDecoration("removeSetting", key) - if len(node.callDecoration("getAllSettings")) == 0: - node.removeDecorator(SettingOverrideDecorator) + #if len(node.callDecoration("getAllSettings")) == 0: + # node.removeDecorator(SettingOverrideDecorator) def _updateModel(self): self.clear() diff --git a/plugins/PerObjectSettingsTool/SettingOverrideModel.py b/plugins/PerObjectSettingsTool/SettingOverrideModel.py index 860650015c..d4bebfdfee 100644 --- a/plugins/PerObjectSettingsTool/SettingOverrideModel.py +++ b/plugins/PerObjectSettingsTool/SettingOverrideModel.py @@ -5,7 +5,7 @@ from PyQt5.QtCore import Qt, pyqtSlot, QUrl from UM.Application import Application from UM.Qt.ListModel import ListModel -from UM.Settings.SettingOverrideDecorator import SettingOverrideDecorator +#from UM.Settings.SettingOverrideDecorator import SettingOverrideDecorator class SettingOverrideModel(ListModel): KeyRole = Qt.UserRole + 1 @@ -29,9 +29,9 @@ class SettingOverrideModel(ListModel): self._node.decoratorsChanged.connect(self._onDecoratorsChanged) self._onDecoratorsChanged(None) - self._activeProfile = Application.getInstance().getMachineManager().getWorkingProfile() #To be able to get notified when a setting changes. - self._activeProfile.settingValueChanged.connect(self._onProfileSettingValueChanged) - Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onProfileChanged) + #self._activeProfile = Application.getInstance().getMachineManager().getWorkingProfile() #To be able to get notified when a setting changes. + #self._activeProfile.settingValueChanged.connect(self._onProfileSettingValueChanged) + #Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onProfileChanged) self.addRoleName(self.KeyRole, "key") self.addRoleName(self.LabelRole, "label") @@ -53,7 +53,8 @@ class SettingOverrideModel(ListModel): self._decorator.setSettingValue(key, value) def _onDecoratorsChanged(self, node): - if not self._node.getDecorator(SettingOverrideDecorator): + return + '''if not self._node.getDecorator(SettingOverrideDecorator): self.clear() return @@ -61,7 +62,7 @@ class SettingOverrideModel(ListModel): self._decorator.settingAdded.connect(self._onSettingsChanged) self._decorator.settingRemoved.connect(self._onSettingsChanged) self._decorator.settingValueChanged.connect(self._onSettingValueChanged) - self._onSettingsChanged() + self._onSettingsChanged()''' def _createOptionsModel(self, options): if not options: diff --git a/plugins/PerObjectSettingsTool/__init__.py b/plugins/PerObjectSettingsTool/__init__.py index 0d49b2c892..d5d249b430 100644 --- a/plugins/PerObjectSettingsTool/__init__.py +++ b/plugins/PerObjectSettingsTool/__init__.py @@ -13,7 +13,7 @@ def getMetaData(): "author": "Ultimaker", "version": "1.0", "description": i18n_catalog.i18nc("@info:whatsthis", "Provides the Per Object Settings."), - "api": 2 + "api": 3 }, "tool": { "name": i18n_catalog.i18nc("@label", "Per Object Settings"), From e9380ba83d0a3b7c45b659547149914aff784cc8 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 20 May 2016 15:08:17 +0200 Subject: [PATCH 198/705] Added rudimentary display of settings again CURA-1278 --- .../PerObjectCategory.qml | 29 ++++ .../PerObjectSettingsTool/PerObjectItem.qml | 29 ++++ .../PerObjectSettingsPanel.qml | 147 +++++------------- 3 files changed, 97 insertions(+), 108 deletions(-) create mode 100644 plugins/PerObjectSettingsTool/PerObjectCategory.qml create mode 100644 plugins/PerObjectSettingsTool/PerObjectItem.qml diff --git a/plugins/PerObjectSettingsTool/PerObjectCategory.qml b/plugins/PerObjectSettingsTool/PerObjectCategory.qml new file mode 100644 index 0000000000..2113a623a0 --- /dev/null +++ b/plugins/PerObjectSettingsTool/PerObjectCategory.qml @@ -0,0 +1,29 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 +import QtQuick.Layouts 1.1 + +import UM 1.1 as UM + +import ".." + +Button { + id: base; + + style: UM.Theme.styles.sidebar_category; + + signal showTooltip(string text); + signal hideTooltip(); + signal contextMenuRequested() + + text: definition.label + iconSource: UM.Theme.getIcon(definition.icon) + + checkable: true + checked: definition.expanded + + onClicked: definition.expanded ? settingDefinitionsModel.collapse(definition.key) : settingDefinitionsModel.expandAll(definition.key) +} diff --git a/plugins/PerObjectSettingsTool/PerObjectItem.qml b/plugins/PerObjectSettingsTool/PerObjectItem.qml new file mode 100644 index 0000000000..d2243ab562 --- /dev/null +++ b/plugins/PerObjectSettingsTool/PerObjectItem.qml @@ -0,0 +1,29 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 + +import UM 1.2 as UM + +UM.TooltipArea +{ + x: model.depth * UM.Theme.getSize("default_margin").width; + text: model.description; + + width: childrenRect.width; + height: childrenRect.height; + + Button + { + id: check + + text: definition.label + + //onClicked: delegateItem.settingsModel.setSettingVisible(model.key, checked); + } +} + + diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index c664aeaeef..19dab6bc26 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -6,7 +6,10 @@ import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.2 import QtQuick.Window 2.2 -import UM 1.1 as UM +import UM 1.2 as UM +import Cura 1.0 as Cura +import ".." + Item { id: base; @@ -133,6 +136,7 @@ Item { id: settingPickDialog title: catalog.i18nc("@title:window", "Pick a Setting to Customize") + property string labelFilter: "" TextField { id: filter; @@ -145,123 +149,50 @@ Item { placeholderText: catalog.i18nc("@label:textbox", "Filter..."); - onTextChanged: settingCategoriesModel.filter(text); + onTextChanged: settingPickDialog.labelFilter = text; } - ScrollView { - id: view; - anchors { + ScrollView + { + id: scrollView + + anchors + { top: filter.bottom; left: parent.left; right: parent.right; bottom: parent.bottom; } + ListView + { + model: UM.SettingDefinitionsModel + { + id: definitionsModel; + containerId: Cura.MachineManager.activeDefinitionId + filter: + { + "global_only": "False" + } + } + delegate:Loader + { + id: loader - Column { - width: view.width - UM.Theme.getSize("default_margin").width * 2; - height: childrenRect.height; + width: parent.width + height: model.type != undefined ? UM.Theme.getSize("section").height : 0; - Repeater { - id: settingList; + property var definition: model + property var settingDefinitionsModel: definitionsModel - model: UM.SettingCategoriesModel { id: settingCategoriesModel; } - - delegate: Item { - id: delegateItem; - - width: parent.width; - height: childrenRect.height; - visible: model.visible && settingsColumn.childrenHeight != 0 //If all children are hidden, the height is 0, and then the category header must also be hidden. - - ToolButton { - id: categoryHeader; - text: model.name; - checkable: true; - width: parent.width; - onCheckedChanged: settingsColumn.state != "" ? settingsColumn.state = "" : settingsColumn.state = "collapsed"; - - style: ButtonStyle { - background: Rectangle - { - width: control.width; - height: control.height; - color: control.hovered ? palette.highlight : "transparent"; - } - label: Row - { - spacing: UM.Theme.getSize("default_margin").width; - Image - { - anchors.verticalCenter: parent.verticalCenter; - source: control.checked ? UM.Theme.getIcon("arrow_right") : UM.Theme.getIcon("arrow_bottom"); - } - Label - { - text: control.text; - font.bold: true; - color: control.hovered ? palette.highlightedText : palette.text; - } - } - } - } - - property variant settingsModel: model.settings; - - Column { - id: settingsColumn; - - anchors.top: categoryHeader.bottom; - - property real childrenHeight: - { - var h = 0.0; - for(var i in children) - { - var item = children[i]; - h += children[i].height; - if(item.settingVisible) - { - if(i > 0) - { - h += spacing; - } - } - } - return h; - } - - width: childrenRect.width; - height: childrenHeight; - Repeater { - model: delegateItem.settingsModel; - - delegate: ToolButton { - id: button; - x: model.visible_depth * UM.Theme.getSize("default_margin").width; - text: model.name; - tooltip: model.description; - visible: !model.global_only - height: model.global_only ? 0 : undefined - - onClicked: { - var object_id = UM.ActiveTool.properties.getValue("Model").getItem(base.currentIndex).id; - UM.ActiveTool.properties.getValue("Model").addSettingOverride(object_id, model.key); - settingPickDialog.visible = false; - } - - states: State { - name: "filtered" - when: model.filtered || !model.visible || !model.enabled - PropertyChanges { target: button; height: 0; opacity: 0; } - } - } - } - - states: State { - name: "collapsed"; - - PropertyChanges { target: settingsColumn; opacity: 0; height: 0; } - } + asynchronous: true + source: + { + switch(model.type) + { + case "category": + return "PerObjectCategory.qml" + default: + return "PerObjectItem.qml" } } } From 7cc62db81dea84e367586a925d5cff10937df2b8 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 20 May 2016 14:06:07 +0200 Subject: [PATCH 199/705] Increment XRayView API number This plug-in still works, so this can be incremented without trouble. Contributes to issue CURA-1278. --- plugins/XRayView/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/XRayView/__init__.py b/plugins/XRayView/__init__.py index 277dc69b92..34e4761863 100644 --- a/plugins/XRayView/__init__.py +++ b/plugins/XRayView/__init__.py @@ -13,7 +13,7 @@ def getMetaData(): "author": "Ultimaker", "version": "1.0", "description": catalog.i18nc("@info:whatsthis", "Provides the X-Ray view."), - "api": 2 + "api": 3 }, "view": { "name": catalog.i18nc("@item:inlistbox", "X-Ray"), From 85ce8a719ed0bbafae04cafe83af3a81fb8fbcf3 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 20 May 2016 16:16:25 +0200 Subject: [PATCH 200/705] Merge local with origin Contributes to issue CURA-1278. --- cura/CuraApplication.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index f328e83174..b95f6058b4 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -224,6 +224,7 @@ class CuraApplication(QtApplication): ## Handle loading of all plugin types (and the backend explicitly) # \sa PluginRegistery def _loadPlugins(self): + self._plugin_registry.addType("profile_reader", self._addProfileReader) self._plugin_registry.addPluginLocation(os.path.join(QtApplication.getInstallPrefix(), "lib", "cura")) if not hasattr(sys, "frozen"): self._plugin_registry.addPluginLocation(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "plugins")) @@ -711,3 +712,6 @@ class CuraApplication(QtApplication): job = ReadMeshJob(os.path.abspath(file)) job.finished.connect(self._onFileLoaded) job.start() + + def _addProfileReader(self, profile_reader): + pass \ No newline at end of file From 5a28eca2039bce9b6e8102c9330c3087ece9484a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 20 May 2016 16:16:55 +0200 Subject: [PATCH 201/705] Add profile reader plug-in type This type of plug-in will load a file as an instance container of the user profile type. Contributes to issue CURA-1278. --- cura/ProfileReader.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 cura/ProfileReader.py diff --git a/cura/ProfileReader.py b/cura/ProfileReader.py new file mode 100644 index 0000000000..36bb2c7177 --- /dev/null +++ b/cura/ProfileReader.py @@ -0,0 +1,17 @@ +# Copyright (c) 2016 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. + +from UM.PluginObject import PluginObject + +## A type of plug-ins that reads profiles from a file. +# +# The profile is then stored as instance container of the type user profile. +class ProfileReader(PluginObject): + def __init__(self): + super().__init__() + + ## Read profile data from a file and return a filled profile. + # + # \return \type{Profile} The profile that was obtained from the file. + def read(self, file_name): + raise NotImplementedError("Profile reader plug-in was not correctly implemented. The read function was not implemented.") \ No newline at end of file From 117973ee25ddd7e4f3a63fd425118d8be8734538 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 20 May 2016 16:20:58 +0200 Subject: [PATCH 202/705] Add todo message for adding profile readers This should be done when we have a working profile manager again. Contributes to issue CURA-1278. --- cura/CuraApplication.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index b95f6058b4..c46833f6e0 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -714,4 +714,5 @@ class CuraApplication(QtApplication): job.start() def _addProfileReader(self, profile_reader): + # TODO: Add the profile reader to the list of plug-ins that can be used when importing profiles. pass \ No newline at end of file From 754932f83ad10c9ac045c240e3c838548040884d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 20 May 2016 16:22:00 +0200 Subject: [PATCH 203/705] Move LegacyProfileReader to new setting structure Untested as the profile manager is not functional at the moment. Contributes to issue CURA-1278. --- .../LegacyProfileReader/LegacyProfileReader.py | 16 +++++++++------- plugins/LegacyProfileReader/__init__.py | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/plugins/LegacyProfileReader/LegacyProfileReader.py b/plugins/LegacyProfileReader/LegacyProfileReader.py index 3daf360ee6..19154c9c5a 100644 --- a/plugins/LegacyProfileReader/LegacyProfileReader.py +++ b/plugins/LegacyProfileReader/LegacyProfileReader.py @@ -9,8 +9,9 @@ import os.path #For concatenating the path to the plugin and the relative path t from UM.Application import Application #To get the machine manager to create the new profile in. from UM.Logger import Logger #Logging errors. from UM.PluginRegistry import PluginRegistry #For getting the path to this plugin's directory. -from UM.Settings.Profile import Profile -from UM.Settings.ProfileReader import ProfileReader +from UM.Settings.DefinitionContainer import DefinitionContainer #For getting the current machine's defaults. +from UM.Settings.InstanceContainer import InstanceContainer #The new profile to make. +from cura.ProfileReader import ProfileReader #The plug-in type to implement. ## A plugin that reads profile data from legacy Cura versions. # @@ -66,7 +67,7 @@ class LegacyProfileReader(ProfileReader): if file_name.split(".")[-1] != "ini": return None Logger.log("i", "Importing legacy profile from file " + file_name + ".") - profile = Profile(machine_manager = Application.getInstance().getMachineManager(), read_only = False) #Create an empty profile. + profile = InstanceContainer("Imported Legacy Profile") #Create an empty profile. parser = configparser.ConfigParser(interpolation = None) try: @@ -103,23 +104,24 @@ class LegacyProfileReader(ProfileReader): if "target_version" not in dict_of_doom: Logger.log("e", "Dictionary of Doom has no target version. Is it the correct JSON file?") return None - if Profile.ProfileVersion != dict_of_doom["target_version"]: - Logger.log("e", "Dictionary of Doom of legacy profile reader (version %s) is not in sync with the profile version (version %s)!", dict_of_doom["target_version"], str(Profile.ProfileVersion)) + if InstanceContainer.Version != dict_of_doom["target_version"]: + Logger.log("e", "Dictionary of Doom of legacy profile reader (version %s) is not in sync with the current instance container version (version %s)!", dict_of_doom["target_version"], str(InstanceContainer.Version)) return None if "translation" not in dict_of_doom: Logger.log("e", "Dictionary of Doom has no translation. Is it the correct JSON file?") return None + current_printer = Application.getInstance().getGlobalContainerStack().findContainer({ }, DefinitionContainer) for new_setting in dict_of_doom["translation"]: #Evaluate all new settings that would get a value from the translations. old_setting_expression = dict_of_doom["translation"][new_setting] compiled = compile(old_setting_expression, new_setting, "eval") try: new_value = eval(compiled, {"math": math}, legacy_settings) #Pass the legacy settings as local variables to allow access to in the evaluation. value_using_defaults = eval(compiled, {"math": math}, defaults) #Evaluate again using only the default values to try to see if they are default. - except Exception as e: #Probably some setting name that was missing or something else that went wrong in the ini file. + except Exception: #Probably some setting name that was missing or something else that went wrong in the ini file. Logger.log("w", "Setting " + new_setting + " could not be set because the evaluation failed. Something is probably missing from the imported legacy profile.") continue - if new_value != value_using_defaults and profile.getSettingValue(new_setting) != new_value: #Not equal to the default in the new Cura OR the default in the legacy Cura. + if new_value != value_using_defaults and current_printer.findDefinitions(key = new_setting).default_value != new_value: #Not equal to the default in the new Cura OR the default in the legacy Cura. profile.setSettingValue(new_setting, new_value) #Store the setting in the profile! if len(profile.getChangedSettings()) == 0: diff --git a/plugins/LegacyProfileReader/__init__.py b/plugins/LegacyProfileReader/__init__.py index e671f02571..f8b1f5c156 100644 --- a/plugins/LegacyProfileReader/__init__.py +++ b/plugins/LegacyProfileReader/__init__.py @@ -13,7 +13,7 @@ def getMetaData(): "author": "Ultimaker", "version": "1.0", "description": catalog.i18nc("@info:whatsthis", "Provides support for importing profiles from legacy Cura versions."), - "api": 2 + "api": 3 }, "profile_reader": [ { From fc7f3498017d4a35ebc21f9452fb6b4e43ceae34 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 20 May 2016 17:21:09 +0200 Subject: [PATCH 204/705] Added rudimentary filtering Current implementation looks for an exact mach, whereas we should look for text in property. CURA-1278 --- .../PerObjectSettingsPanel.qml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index 19dab6bc26..e53b5d338b 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -149,7 +149,17 @@ Item { placeholderText: catalog.i18nc("@label:textbox", "Filter..."); - onTextChanged: settingPickDialog.labelFilter = text; + onTextChanged: + { + if(text != "") + { + listview.model.filter.label = = {"global_only":"False", "label": text} + } + else + { + listview.model.filter = {"global_only":"False"} + } + } } ScrollView @@ -165,6 +175,7 @@ Item { } ListView { + id:listview model: UM.SettingDefinitionsModel { id: definitionsModel; From 63b623a6ef9b557924fb45b918f0cc699c93a80f Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 23 May 2016 02:18:20 +0200 Subject: [PATCH 205/705] Move global_only property declaration to before the super() call so containerregistry knows about it when loading Also, properly set its type to function and default to False --- cura/CuraApplication.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index c46833f6e0..bfe342d1e4 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -85,6 +85,9 @@ class CuraApplication(QtApplication): self._open_file_queue = [] # Files to open when plug-ins are loaded. + # Need to do this before ContainerRegistry tries to load the machines + SettingDefinition.addSupportedProperty("global_only", DefinitionPropertyType.Function, default = False) + super().__init__(name = "cura", version = CuraVersion) self.setWindowIcon(QIcon(Resources.getPath(Resources.Images, "cura-icon.png"))) @@ -119,8 +122,6 @@ class CuraApplication(QtApplication): Resources.addType(self.ResourceTypes.QmlFiles, "qml") Resources.addType(self.ResourceTypes.Firmware, "firmware") - SettingDefinition.addSupportedProperty("global_only", DefinitionPropertyType.String, default = "False") - ## Add the 4 types of profiles to storage. Resources.addStorageType(self.ResourceTypes.QualityInstanceContainer, "quality") Resources.addStorageType(self.ResourceTypes.VariantInstanceContainer, "variants") @@ -715,4 +716,4 @@ class CuraApplication(QtApplication): def _addProfileReader(self, profile_reader): # TODO: Add the profile reader to the list of plug-ins that can be used when importing profiles. - pass \ No newline at end of file + pass From b452cf7ba4b3ae0f2df84b01ce828d1ca4d55dae Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 23 May 2016 02:19:11 +0200 Subject: [PATCH 206/705] Add a materials management page Based off Aldo's work which is in a different branch --- resources/qml/Cura.qml | 2 + resources/qml/Preferences/MaterialsPage.qml | 183 ++++++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 resources/qml/Preferences/MaterialsPage.qml diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index ba42bdc051..b03c5ed06a 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -551,6 +551,8 @@ UM.MainWindow insertPage(2, catalog.i18nc("@title:tab", "Printers"), Qt.resolvedUrl("MachinesPage.qml")); + insertPage(3, catalog.i18nc("@title:tab", "Materials"), Qt.resolvedUrl("Preferences/MaterialsPage.qml")) + //Force refresh setPage(0); } diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml new file mode 100644 index 0000000000..f58b1876e3 --- /dev/null +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -0,0 +1,183 @@ +// Copyright (c) 2016 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Dialogs 1.2 + +import UM 1.2 as UM + +UM.ManagementPage +{ + id: base; + + title: catalog.i18nc("@title:tab", "Materials"); + + model: UM.InstanceContainersModel { filter: { "type": "material" } } +/* + onAddObject: { var selectedMaterial = UM.MaterialManager.createProfile(); base.selectMaterial(selectedMaterial); } + onRemoveObject: confirmDialog.open(); + onRenameObject: { renameDialog.open(); renameDialog.selectText(); } +*/ +// activateEnabled: false + addEnabled: false + removeEnabled: false + renameEnabled: false + + scrollviewCaption: " " + detailsVisible: true + + property string currency: UM.Preferences.getValue("general/currency") + + Item { + UM.I18nCatalog { id: catalog; name: "cura"; } + + visible: base.currentItem != null + anchors.fill: parent + + Label { id: profileName; text: base.currentItem ? base.currentItem.name : ""; font: UM.Theme.getFont("large"); width: parent.width; } + + TabView { + id: scrollView + anchors.left: parent.left + anchors.right: parent.right + anchors.top: profileName.bottom + anchors.topMargin: UM.Theme.getSize("default_margin").height + anchors.bottom: parent.bottom + + Tab { + title: "Information" + anchors.margins: UM.Theme.getSize("default_margin").height + + Column { + spacing: UM.Theme.getSize("default_margin").height + + Grid { + id: containerGrid + columns: 2 + spacing: UM.Theme.getSize("default_margin").width + + Label { text: catalog.i18nc("@label", "Profile Type") } + Label { text: base.currentItem ? base.currentItem.metadata.status : "Unknown"} + + Label { text: catalog.i18nc("@label", "Supplier") } + Label { text: base.currentItem ? base.currentItem.metadata.brand : "Unknown"} + + Label { text: catalog.i18nc("@label", "Material Type") } + Label { text: base.currentItem ? base.currentItem.metadata.material : "Unknown" } + + Label { text: catalog.i18nc("@label", "Color") } + Rectangle { color: base.currentItem ? base.currentItem.metadata.color_code : "yellow" } + + Label { text: "" + catalog.i18nc("@label", "Properties") + "" } + Label { text: " " } + + Label { text: catalog.i18nc("@label", "Density") } + Label { text: base.currentItem ? base.currentItem.metadata.properties.density + " " + "g/cm³" : "" } + + Label { text: catalog.i18nc("@label", "Diameter") } + Label { text: base.currentItem ? base.currentItem.metadata.properties.diameter + " " + "mm" : ""} + + Label { + text: catalog.i18nc("@label", "Filament cost") + height: spoolCostInput.height + verticalAlignment: Text.AlignVCenter + } + + Row { + Label { + text: base.currentItem && base.currentItem.spoolCost ? base.currency + " " : "" + anchors.verticalCenter: parent.verticalCenter + } + TextField { + id: spoolCostInput + text: base.currentItem.spoolCost + } + } + + Label { text: catalog.i18nc("@label", "Filament weight") } + Label { text: base.currentItem ? base.currentItem.metadata.properies.spool_weight + " " + "kg" : "" } + + Label { text: catalog.i18nc("@label", "Filament length") } + Label { text: base.currentItem ? catalog.i18nc("@label", "approx.") + " " + base.currentItem.metadata.properties.spool_length + " " + "m" : "" } + + Label { text: catalog.i18nc("@label", "Cost per meter") } + Label { text: base.currentItem && base.currentItem.lenghtCost ? catalog.i18nc("@label", "approx.") + " " + base.currency + " " + base.currentItem.lenghtCost + "/m" : "" } + +// Column { +// +// +// +// +// } +// Column { +// +// +// +// Column { +// Label { text: base.currentItem && base.currentItem.variant ? base.currentItem.variant : "" } +// Row { +// spacing: UM.Theme.getSize("default_margin").width/2 +// Rectangle { +// color: base.currentItem && base.currentItem.colorDisplay ? base.currentItem.colorDisplay : "yellow" +// width: colorLabel.height +// height: colorLabel.height +// border.width: UM.Theme.getSize("default_lining").height +// } +// Label { id: colorLabel; text: base.currentItem && base.currentItem.colorRAL ? base.currentItem.colorRAL : "" } +// } +// } +// } +// Column { +// +// } +// Column { +// +// +// +// +// +// +// +// } + } + Label { + text: base.currentItem && base.currentItem.infoGeneral ? "" + catalog.i18nc("@label", "Information") + "
" + base.currentItem.infoGeneral : "" + width: scrollView.width - 2 * UM.Theme.getSize("default_margin").width + wrapMode: Text.WordWrap + } + Label { + text: base.currentItem && base.currentItem.infoAdhesion ? "" + catalog.i18nc("@label", "Adhesion") + "
" + base.currentItem.infoAdhesion : "" + width: scrollView.width - 2 * UM.Theme.getSize("default_margin").width + wrapMode: Text.WordWrap + } + } + } + Tab { + title: catalog.i18nc("@label", "Print settings") + anchors.margins: UM.Theme.getSize("default_margin").height + + Grid { + columns: 2 + spacing: UM.Theme.getSize("default_margin").width + + Column { + Repeater { + model: base.currentItem ? base.currentItem.settings : null + Label { + text: modelData.name.toString(); + elide: Text.ElideMiddle; + } + } + } + Column { + Repeater { + model: base.currentItem ? base.currentItem.settings : null + Label { text: modelData.value.toString() + " " + modelData.unit.toString(); } + } + } + } + } + } + } +} From e0c7ed85617ba54759ae2c65179ccdedbeb40236 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 23 May 2016 02:19:39 +0200 Subject: [PATCH 207/705] Add a plugin that loads XML materials and an example material --- .../XmlMaterialProfile/XmlMaterialProfile.py | 84 +++++++++++++++++++ plugins/XmlMaterialProfile/__init__.py | 32 +++++++ .../materials/generic_pla.xml.fdm_material | 48 +++++++++++ 3 files changed, 164 insertions(+) create mode 100644 plugins/XmlMaterialProfile/XmlMaterialProfile.py create mode 100644 plugins/XmlMaterialProfile/__init__.py create mode 100644 resources/materials/generic_pla.xml.fdm_material diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py new file mode 100644 index 0000000000..5566301a09 --- /dev/null +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -0,0 +1,84 @@ +# Copyright (c) 2016 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. + +import math +import xml.etree.ElementTree as ET + +import UM.Settings + +def _tag_without_namespace(element): + return element.tag[element.tag.rfind("}") + 1:] + +class XmlMaterialProfile(UM.Settings.InstanceContainer): + def __init__(self, container_id, *args, **kwargs): + super().__init__(container_id, *args, **kwargs) + + def serialize(self): + raise NotImplementedError("Writing material profiles has not yet been implemented") + + def deserialize(self, serialized): + print("deserialize material profile") + data = ET.fromstring(serialized) + + self.addMetaDataEntry("type", "material") + + # TODO: Add material verfication + self.addMetaDataEntry("status", "Unknown") + + metadata = data.iterfind("./um:metadata/*", self.__namespaces) + for entry in metadata: + # The namespace is prepended to the tag name but between {}. + # We are only interested in the actual tag name. + tag_name = entry.tag[entry.tag.rfind("}") + 1:] + + if tag_name == "name": + brand = entry.find("./um:brand", self.__namespaces) + material = entry.find("./um:material", self.__namespaces) + color = entry.find("./um:color", self.__namespaces) + + self.setName("{0} {1} ({2})".format(brand.text, material.text, color.text)) + + self.addMetaDataEntry("brand", brand.text) + self.addMetaDataEntry("material", material.text) + self.addMetaDataEntry("color_name", color.text) + + self.addMetaDataEntry(tag_name, entry.text) + + property_values = {} + properties = data.iterfind("./um:properties/*", self.__namespaces) + for entry in properties: + tag_name = entry.tag[entry.tag.rfind("}") + 1:] + property_values[tag_name] = entry.text + + diameter = float(property_values.get("diameter", 2.85)) # In mm + density = float(property_values.get("density", 1.3)) # In g/cm3 + + weight_per_cm = (math.pi * (diameter / 20) ** 2 * 0.1) * density + + spool_weight = property_values.get("spool_weight") + spool_length = property_values.get("spool_length") + if spool_weight: + length = float(spool_weight) / weight_per_cm + property_values["spool_length"] = str(length / 100) + elif spool_length: + weight = (float(spool_length) * 100) * weight_per_cm + property_values["spool_weight"] = str(weight) + + self.addMetaDataEntry("properties", property_values) + + settings = data.iterfind("./um:settings/um:setting", self.__namespaces) + for entry in settings: + tag_name = _tag_without_namespace(entry) + + if tag_name in self.__material_property_setting_map: + self.setProperty(self.__material_property_setting_map[tag_name], "value", entry.text) + + __material_property_setting_map = { + "print temperature": "material_print_temperature", + "heated bed temperature": "material_bed_temperature", + "standby temperature": "material_standby_temperature", + } + + __namespaces = { + "um": "http://www.ultimaker.com/material" + } diff --git a/plugins/XmlMaterialProfile/__init__.py b/plugins/XmlMaterialProfile/__init__.py new file mode 100644 index 0000000000..041a3f6346 --- /dev/null +++ b/plugins/XmlMaterialProfile/__init__.py @@ -0,0 +1,32 @@ +# Copyright (c) 2016 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. + +from . import XmlMaterialProfile + +from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase +from UM.i18n import i18nCatalog +catalog = i18nCatalog("cura") + +def getMetaData(): + return { + "plugin": { + "name": catalog.i18nc("@label", "Material Profiles"), + "author": "Ultimaker", + "version": "1.0", + "description": catalog.i18nc("@info:whatsthis", "Provides capabilities to read and write XML-based material profiles."), + "api": 3 + }, + "settings_container": { + "mimetype": "application/x-ultimaker-material-profile" + } + } + +def register(app): + mime_type = MimeType( + name = "application/x-ultimaker-material-profile", + comment = "Ultimaker Material Profile", + suffixes = [ "xml.fdm_material" ] + ) + MimeTypeDatabase.addMimeType(mime_type) + return { "settings_container": XmlMaterialProfile.XmlMaterialProfile("default_xml_material_profile") } + diff --git a/resources/materials/generic_pla.xml.fdm_material b/resources/materials/generic_pla.xml.fdm_material new file mode 100644 index 0000000000..b64ecdc61b --- /dev/null +++ b/resources/materials/generic_pla.xml.fdm_material @@ -0,0 +1,48 @@ + + + + + + Generic + PLA + Generic + + 506c9f0d-e3aa-4bd4-b2d2-23e2425b1aa9 + 0 + #FFFFFF + + + 1.3 + 2.85 + 750 + + + 210 + 60 + 175 + + + + + + 150 + + + + + + + + + 150 + + 80 + + + 100 + + + + From f8c8de86bc47ccf69ae520a58a22e6f8aae07499 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 23 May 2016 11:35:01 +0200 Subject: [PATCH 208/705] Fix showing changelog when the first item in the changelog doesn't start with an "*" CURA-1583 --- plugins/ChangeLogPlugin/ChangeLog.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/plugins/ChangeLogPlugin/ChangeLog.py b/plugins/ChangeLogPlugin/ChangeLog.py index 7c8c81f2c6..d004104f91 100644 --- a/plugins/ChangeLogPlugin/ChangeLog.py +++ b/plugins/ChangeLogPlugin/ChangeLog.py @@ -48,7 +48,8 @@ class ChangeLog(Extension, QObject,): result += "

" + str(version) + "


" result += "" for change in logs[version]: - result += "" + str(change) + "
" + if str(change) != "": + result += "" + str(change) + "
" for line in logs[version][change]: result += str(line) + "
" result += "
" @@ -60,20 +61,21 @@ class ChangeLog(Extension, QObject,): self._change_logs = collections.OrderedDict() with open(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "ChangeLog.txt"), "r",-1, "utf-8") as f: open_version = None - open_header = None + open_header = "" # Initialise to an empty header in case there is no "*" in the first line of the changelog for line in f: line = line.replace("\n","") if "[" in line and "]" in line: line = line.replace("[","") line = line.replace("]","") open_version = Version(line) - self._change_logs[Version(line)] = collections.OrderedDict() + self._change_logs[open_version] = collections.OrderedDict() elif line.startswith("*"): open_header = line.replace("*","") self._change_logs[open_version][open_header] = [] - else: - if line != "": - self._change_logs[open_version][open_header].append(line) + elif line != "": + if open_header not in self._change_logs[open_version]: + self._change_logs[open_version][open_header] = [] + self._change_logs[open_version][open_header].append(line) def _onEngineCreated(self): if not self._version: @@ -105,4 +107,3 @@ class ChangeLog(Extension, QObject,): self._changelog_context = QQmlContext(Application.getInstance()._engine.rootContext()) self._changelog_context.setContextProperty("manager", self) self._changelog_window = component.create(self._changelog_context) - #print(self._changelog_window) From 740f3775fa5c2703a6ff43c347aee6d5e23bec6c Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 13 May 2016 13:05:58 +0200 Subject: [PATCH 209/705] Reset stored layer data as soon as a new slice operation starts This prevents layer view showing a combination of stale and fresh data Fixes CURA-1370 (and CURA-1519) --- plugins/CuraEngineBackend/CuraEngineBackend.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index e3f9a4542e..d3d3469fbc 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -119,6 +119,7 @@ class CuraEngineBackend(Backend): ## Perform a slice of the scene. def slice(self): + self._stored_layer_data = [] if not self._enabled: return From 4877c35f063687429fb9eb9a1e03d756bfab4c1e Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 23 May 2016 13:35:52 +0200 Subject: [PATCH 210/705] Fix layout of SettingTextField items CURA-1278 --- resources/qml/Settings/SettingTextField.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingTextField.qml b/resources/qml/Settings/SettingTextField.qml index 3cbd21387b..9972f83aa1 100644 --- a/resources/qml/Settings/SettingTextField.qml +++ b/resources/qml/Settings/SettingTextField.qml @@ -85,7 +85,7 @@ SettingItem anchors { left: parent.left - leftMargin: UM.Theme.unitRightMargin + leftMargin: UM.Theme.getSize("setting_unit_margin").width right: parent.right verticalCenter: parent.verticalCenter } From 0969356cb696e0de512e981395aad7ba2aa583fe Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 23 May 2016 14:22:21 +0200 Subject: [PATCH 211/705] Fix bq_hephestos_2 json definition --- resources/machines/bq_hephestos_2.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/machines/bq_hephestos_2.json b/resources/machines/bq_hephestos_2.json index 7fe4a43406..d3af415b7a 100644 --- a/resources/machines/bq_hephestos_2.json +++ b/resources/machines/bq_hephestos_2.json @@ -54,6 +54,6 @@ "skirt_line_count": { "default": 4 }, "skirt_minimal_length": { "default": 30.0, "visible": false }, "skirt_gap": { "default": 6.0 }, - "cool_fan_full_at_height": { "default": 0.4, "visible": false }, + "cool_fan_full_at_height": { "default": 0.4, "visible": false } } } From c23980437d05f4021cfc09a3e95ea61f360be149 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 23 May 2016 14:42:14 +0200 Subject: [PATCH 212/705] Fix naming of quality profiles --- resources/quality/high.inst.cfg | 2 +- resources/quality/normal.inst.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/quality/high.inst.cfg b/resources/quality/high.inst.cfg index 2e860cf380..89dcd4c9bc 100644 --- a/resources/quality/high.inst.cfg +++ b/resources/quality/high.inst.cfg @@ -1,6 +1,6 @@ [general] version = 2 -name = high +name = High Quality definition = fdmprinter [metadata] diff --git a/resources/quality/normal.inst.cfg b/resources/quality/normal.inst.cfg index 6bb23d841c..6d317cdf7a 100644 --- a/resources/quality/normal.inst.cfg +++ b/resources/quality/normal.inst.cfg @@ -1,6 +1,6 @@ [general] version = 2 -name = normal +name = Normal Quality definition = fdmprinter [metadata] From f68a9ae90fc4b22b2533929cb0366825a2d7837f Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 23 May 2016 14:42:40 +0200 Subject: [PATCH 213/705] Fix materials page so it displays the proper data Also, make sure the code is reasonably clean --- resources/qml/Preferences/MaterialsPage.qml | 211 +++++++++++--------- 1 file changed, 122 insertions(+), 89 deletions(-) diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index f58b1876e3..f1f3432a41 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -35,7 +35,7 @@ UM.ManagementPage visible: base.currentItem != null anchors.fill: parent - Label { id: profileName; text: base.currentItem ? base.currentItem.name : ""; font: UM.Theme.getFont("large"); width: parent.width; } + Label { id: profileName; text: materialProperties.name; font: UM.Theme.getFont("large"); width: parent.width; } TabView { id: scrollView @@ -49,106 +49,83 @@ UM.ManagementPage title: "Information" anchors.margins: UM.Theme.getSize("default_margin").height - Column { - spacing: UM.Theme.getSize("default_margin").height + Flow { + id: containerGrid - Grid { - id: containerGrid - columns: 2 - spacing: UM.Theme.getSize("default_margin").width + width: scrollView.width; + property real columnWidth: width / 2 - Label { text: catalog.i18nc("@label", "Profile Type") } - Label { text: base.currentItem ? base.currentItem.metadata.status : "Unknown"} + Label { width: parent.columnWidth; text: catalog.i18nc("@label", "Profile Type") } + Label { width: parent.columnWidth; text: materialProperties.profile_type } - Label { text: catalog.i18nc("@label", "Supplier") } - Label { text: base.currentItem ? base.currentItem.metadata.brand : "Unknown"} + Label { width: parent.columnWidth; text: catalog.i18nc("@label", "Supplier") } + Label { width: parent.columnWidth; text: materialProperties.supplier } - Label { text: catalog.i18nc("@label", "Material Type") } - Label { text: base.currentItem ? base.currentItem.metadata.material : "Unknown" } + Label { width: parent.columnWidth; text: catalog.i18nc("@label", "Material Type") } + Label { width: parent.columnWidth; text: materialProperties.material_type } - Label { text: catalog.i18nc("@label", "Color") } - Rectangle { color: base.currentItem ? base.currentItem.metadata.color_code : "yellow" } + Label { width: parent.columnWidth; text: catalog.i18nc("@label", "Color") } - Label { text: "" + catalog.i18nc("@label", "Properties") + "" } - Label { text: " " } - - Label { text: catalog.i18nc("@label", "Density") } - Label { text: base.currentItem ? base.currentItem.metadata.properties.density + " " + "g/cm³" : "" } - - Label { text: catalog.i18nc("@label", "Diameter") } - Label { text: base.currentItem ? base.currentItem.metadata.properties.diameter + " " + "mm" : ""} - - Label { - text: catalog.i18nc("@label", "Filament cost") - height: spoolCostInput.height - verticalAlignment: Text.AlignVCenter + Row { + width: parent.columnWidth; + spacing: UM.Theme.getSize("default_margin").width/2 + Rectangle { + color: materialProperties.color_code + width: colorLabel.height + height: colorLabel.height + border.width: UM.Theme.getSize("default_lining").height } - - Row { - Label { - text: base.currentItem && base.currentItem.spoolCost ? base.currency + " " : "" - anchors.verticalCenter: parent.verticalCenter - } - TextField { - id: spoolCostInput - text: base.currentItem.spoolCost - } - } - - Label { text: catalog.i18nc("@label", "Filament weight") } - Label { text: base.currentItem ? base.currentItem.metadata.properies.spool_weight + " " + "kg" : "" } - - Label { text: catalog.i18nc("@label", "Filament length") } - Label { text: base.currentItem ? catalog.i18nc("@label", "approx.") + " " + base.currentItem.metadata.properties.spool_length + " " + "m" : "" } - - Label { text: catalog.i18nc("@label", "Cost per meter") } - Label { text: base.currentItem && base.currentItem.lenghtCost ? catalog.i18nc("@label", "approx.") + " " + base.currency + " " + base.currentItem.lenghtCost + "/m" : "" } - -// Column { -// -// -// -// -// } -// Column { -// -// -// -// Column { -// Label { text: base.currentItem && base.currentItem.variant ? base.currentItem.variant : "" } -// Row { -// spacing: UM.Theme.getSize("default_margin").width/2 -// Rectangle { -// color: base.currentItem && base.currentItem.colorDisplay ? base.currentItem.colorDisplay : "yellow" -// width: colorLabel.height -// height: colorLabel.height -// border.width: UM.Theme.getSize("default_lining").height -// } -// Label { id: colorLabel; text: base.currentItem && base.currentItem.colorRAL ? base.currentItem.colorRAL : "" } -// } -// } -// } -// Column { -// -// } -// Column { -// -// -// -// -// -// -// -// } + Label { id: colorLabel; text: materialProperties.color_name } } + + Item { width: parent.width; height: UM.Theme.getSize("default_margin").height } + + Label { width: parent.width; text: "" + catalog.i18nc("@label", "Properties") + "" } + + Label { width: parent.columnWidth; text: catalog.i18nc("@label", "Density") } + Label { width: parent.columnWidth; text: materialProperties.density } + + Label { width: parent.columnWidth; text: catalog.i18nc("@label", "Diameter") } + Label { width: parent.columnWidth; text: materialProperties.diameter } + Label { - text: base.currentItem && base.currentItem.infoGeneral ? "" + catalog.i18nc("@label", "Information") + "
" + base.currentItem.infoGeneral : "" - width: scrollView.width - 2 * UM.Theme.getSize("default_margin").width + text: catalog.i18nc("@label", "Filament cost") + width: parent.columnWidth; + height: spoolCostInput.height + verticalAlignment: Text.AlignVCenter + } + + Row { + width: parent.columnWidth; + Label { + text: base.currency ? base.currency + " " : " " + anchors.verticalCenter: parent.verticalCenter + } + TextField { + id: spoolCostInput + text: materialProperties.spool_cost + } + } + + Label { width: parent.columnWidth; text: catalog.i18nc("@label", "Filament weight") } + Label { width: parent.columnWidth; text: materialProperties.spool_weight + " " + "g" } + + Label { width: parent.columnWidth; text: catalog.i18nc("@label", "Filament length") } + Label { width: parent.columnWidth; text: materialProperties.spool_length + " " + "m" } + + Label { width: parent.columnWidth; text: catalog.i18nc("@label", "Cost per meter") } + Label { width: parent.columnWidth; text: catalog.i18nc("@label", "approx. %1 %2/m").arg(materialProperties.cost_per_meter).arg(base.currency); } + + Item { width: parent.width; height: UM.Theme.getSize("default_margin").height } + + Label { + text: materialProperties.description ? "" + catalog.i18nc("@label", "Information") + "
" + materialProperties.description : ""; + width: parent.width wrapMode: Text.WordWrap } Label { - text: base.currentItem && base.currentItem.infoAdhesion ? "" + catalog.i18nc("@label", "Adhesion") + "
" + base.currentItem.infoAdhesion : "" - width: scrollView.width - 2 * UM.Theme.getSize("default_margin").width + text: materialProperties.adhesion_info ? "" + catalog.i18nc("@label", "Adhesion") + "
" + materialProperties.adhesion_info : ""; + width: parent.width wrapMode: Text.WordWrap } } @@ -179,5 +156,61 @@ UM.ManagementPage } } } + + QtObject + { + id: materialProperties + + property string name: "Unknown"; + property string profile_type: "Unknown"; + property string supplier: "Unknown"; + property string material_type: "Unknown"; + + property string color_name: "Yellow"; + property color color_code: "yellow"; + + property string density: "Unknown"; + property string diameter: "Unknown"; + + property string spool_cost: "Unknown"; + property string spool_weight: "Unknown"; + property string spool_length: "Unknown"; + property string cost_per_meter: "Unknown"; + + property string description: ""; + property string adhesion_info: ""; + } + } + + onCurrentItemChanged: + { + if(!currentItem == null) + { + return + } + + materialProperties.name = currentItem.name; + + if(currentItem.metadata != undefined && currentItem.metadata != null) + { + materialProperties.supplier = currentItem.metadata.brand ? currentItem.metadata.brand : "Unknown"; + materialProperties.material_type = currentItem.metadata.material ? currentItem.metadata.material : "Unknown"; + materialProperties.color_name = currentItem.metadata.color_name ? currentItem.metadata.color_name : "Yellow"; + materialProperties.color_code = currentItem.metadata.color_code ? currentItem.metadata.color_code : "yellow"; + + materialProperties.description = currentItem.metadata.description ? currentItem.metadata.description : ""; + materialProperties.adhesion_info = currentItem.metadata.adhesion_info ? currentItem.metadata.adhesion_info : ""; + + if(currentItem.metadata.properties != undefined && currentItem.metadata.properties != null) + { + materialProperties.density = currentItem.metadata.properties.density ? currentItem.metadata.properties.density : "Unknown"; + materialProperties.diameter = currentItem.metadata.properties.diameter ? currentItem.metadata.properties.diameter : "Unknown"; + } + else + { + materialProperties.density = "Unknown"; + materialProperties.diameter = "Unknown"; + } + } } } From bace52fccf80bc0153db3ba2f237b89d9eb01d92 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 13:02:46 +0200 Subject: [PATCH 214/705] Add documentation I need a bit of documentation for myself to understand this process. Contributes to issue CURA-1278. --- .../CuraEngineBackend/CuraEngineBackend.py | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index a57aa01ba9..0c569ce6f3 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -29,6 +29,10 @@ catalog = i18nCatalog("cura") class CuraEngineBackend(Backend): + ## Starts the back-end plug-in. + # + # This registers all the signal listeners and prepares for communication + # with the back-end in general. def __init__(self): super().__init__() @@ -50,19 +54,15 @@ class CuraEngineBackend(Backend): self._onActiveViewChanged() self._stored_layer_data = [] - # When there are current settings and machine instance is changed, there is no profile changed event. We should - # pretend there is though. - #Application.getInstance().getMachineManager().activeMachineInstanceChanged.connect(self._onActiveProfileChanged) - - #self._profile = None - #Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onActiveProfileChanged) - #self._onActiveProfileChanged() - + #When you update a setting and other settings get changed through inheritance, many propertyChanged signals are fired. + #This timer will group them up, and only slice for the last setting changed signal. + #TODO: Properly group propertyChanged signals by whether they are triggered by the same user interaction. self._change_timer = QTimer() self._change_timer.setInterval(500) self._change_timer.setSingleShot(True) self._change_timer.timeout.connect(self.slice) + #Listeners for receiving messages from the back-end. self._message_handlers["cura.proto.Layer"] = self._onLayerMessage self._message_handlers["cura.proto.Progress"] = self._onProgressMessage self._message_handlers["cura.proto.GCodeLayer"] = self._onGCodeLayerMessage @@ -70,29 +70,31 @@ class CuraEngineBackend(Backend): self._message_handlers["cura.proto.ObjectPrintTime"] = self._onObjectPrintTimeMessage self._message_handlers["cura.proto.SlicingFinished"] = self._onSlicingFinishedMessage - self._slicing = False - self._restart = False - self._enabled = True - self._always_restart = True + self._slicing = False #Are we currently slicing? + self._restart = False #Back-end is currently restarting? + self._enabled = True #Should we be slicing? Slicing might be paused when, for instance, the user is dragging the mesh around. + self._always_restart = True #Always restart the engine when starting a new slice. Don't keep the process running. TODO: Fix engine statelessness. self._process_layers_job = None #The currently active job to process layers, or None if it is not processing layers. - self._message = None + self._message = None #Pop-up message that shows the slicing progress bar (or an error message). self.backendQuit.connect(self._onBackendQuit) - self.backendConnected.connect(self._onBackendConnected) + + #When a tool operation is in progress, don't slice. So we need to listen for tool operations. Application.getInstance().getController().toolOperationStarted.connect(self._onToolOperationStarted) Application.getInstance().getController().toolOperationStopped.connect(self._onToolOperationStopped) - #Application.getInstance().getMachineManager().activeMachineInstanceChanged.connect(self._onInstanceChanged) - + ## Called when closing the application. + # + # This function should terminate the engine process. def close(self): # Terminate CuraEngine if it is still running at this point self._terminate() super().close() ## Get the command that is used to call the engine. - # This is usefull for debugging and used to actually start the engine + # This is useful for debugging and used to actually start the engine. # \return list of commands and args / parameters. def getEngineCommand(self): active_machine = Application.getInstance().getMachineManager().getActiveMachineInstance() @@ -112,7 +114,7 @@ class CuraEngineBackend(Backend): ## Emitted when the slicing process starts. slicingStarted = Signal() - ## Emitted whne the slicing process is aborted forcefully. + ## Emitted when the slicing process is aborted forcefully. slicingCancelled = Signal() ## Perform a slice of the scene. From e5df225b1e0e697640208b5d36d5099e8ffad33f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 13:04:36 +0200 Subject: [PATCH 215/705] Connect SettingChanged to new propertyChanged function The listener doesn't properly listen to the signal's parameters yet though. Contributes to issue CURA-1278. --- plugins/CuraEngineBackend/CuraEngineBackend.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 0c569ce6f3..7aaba3edce 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -54,6 +54,10 @@ class CuraEngineBackend(Backend): self._onActiveViewChanged() self._stored_layer_data = [] + #When any setting property changed, call the _onSettingChanged function. + #This function will then see if we need to start slicing. + Application.getInstance().getGlobalContainerStack().propertyChanged.connect(self._onSettingChanged) + #When you update a setting and other settings get changed through inheritance, many propertyChanged signals are fired. #This timer will group them up, and only slice for the last setting changed signal. #TODO: Properly group propertyChanged signals by whether they are triggered by the same user interaction. From ab2a6136d700167b5df7803fc8d46e0676a05728 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 13:20:42 +0200 Subject: [PATCH 216/705] Filter setting changed listener properly The parameters of the listener were out of date and it should only trigger a reslice if we're changing the value of a setting, not any other property. Contributes to issue CURA-1278. --- plugins/CuraEngineBackend/CuraEngineBackend.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 7aaba3edce..b101fae5fd 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -123,8 +123,7 @@ class CuraEngineBackend(Backend): ## Perform a slice of the scene. def slice(self): - - if not self._enabled: + if not self._enabled: #We shouldn't be slicing. return if self._slicing: @@ -225,8 +224,13 @@ class CuraEngineBackend(Backend): self._profile.settingValueChanged.connect(self._onSettingChanged) self._onChanged() - def _onSettingChanged(self, setting): - self._onChanged() + ## A setting has changed, so check if we must reslice. + # + # \param instance The setting instance that has changed. + # \param property The property of the setting instance that has changed. + def _onSettingChanged(self, instance, property): + if property == "value": #Only reslice if the value has changed. + self._onChanged() def _onLayerMessage(self, message): self._stored_layer_data.append(message) From 83c1ea2ccc600129c060473af98480c9e3147032 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 13:24:54 +0200 Subject: [PATCH 217/705] Move message hide into terminate function Always if we terminate we want to hide the old message. This fixes the message not hiding when using the tools. Contributes to issue CURA-1278. --- plugins/CuraEngineBackend/CuraEngineBackend.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index b101fae5fd..da4ba1a139 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -129,12 +129,6 @@ class CuraEngineBackend(Backend): if self._slicing: self._terminate() - if self._message: - self._message.hide() - self._message = None - - return - if self._process_layers_job: self._process_layers_job.abort() self._process_layers_job = None @@ -181,6 +175,9 @@ class CuraEngineBackend(Backend): #self._createSocket() # Re create the socket except Exception as e: # terminating a process that is already terminating causes an exception, silently ignore this. Logger.log("d", "Exception occured while trying to kill the engine %s", str(e)) + if self._message: + self._message.hide() + self._message = None def _onStartSliceCompleted(self, job): From ae6f4912e613ddea4e22729ab604c6b115b9439f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 13:28:04 +0200 Subject: [PATCH 218/705] Remove unnecessary variable initialisation This isn't C++ or anything. Variable scope isn't limited by if statements. Contributes to issue CURA-1278. --- plugins/CuraEngineBackend/CuraEngineBackend.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index da4ba1a139..6dc166129e 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -102,7 +102,6 @@ class CuraEngineBackend(Backend): # \return list of commands and args / parameters. def getEngineCommand(self): active_machine = Application.getInstance().getMachineManager().getActiveMachineInstance() - json_path = "" if not active_machine: json_path = Resources.getPath(Resources.MachineDefinitions, "fdmprinter.json") else: From a0645a44c8a51eecf587170b57adda754ebab04e Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 13:36:32 +0200 Subject: [PATCH 219/705] Re-enable slicing message Nothing appears right now, but this enables progress to show later on in the progress (if it would get there). Contributes to issue CURA-1278. --- plugins/CuraEngineBackend/CuraEngineBackend.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 6dc166129e..b3755602d1 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -125,10 +125,10 @@ class CuraEngineBackend(Backend): if not self._enabled: #We shouldn't be slicing. return - if self._slicing: + if self._slicing: #We were already slicing. Stop the old job. self._terminate() - if self._process_layers_job: + if self._process_layers_job: #We were processing layers. Stop that, the layers are going to change soon. self._process_layers_job.abort() self._process_layers_job = None @@ -146,9 +146,9 @@ class CuraEngineBackend(Backend): self.backendStateChange.emit(BackendState.NOT_STARTED) if self._message: self._message.setProgress(-1) - #else: - # self._message = Message(catalog.i18nc("@info:status", "Slicing..."), 0, False, -1) - # self._message.show() + else: + self._message = Message(catalog.i18nc("@info:status", "Slicing..."), 0, False, -1) + self._message.show() self._scene.gcode_list = [] self._slicing = True From 63bf5bec3d5fc109a4d59abbec17f3a27b58cf35 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 13:56:42 +0200 Subject: [PATCH 220/705] Remove _profile from start slice job parameters Instead, the start slice job searches for the container stack itself. Contributes to issue CURA-1278. --- plugins/CuraEngineBackend/CuraEngineBackend.py | 2 +- plugins/CuraEngineBackend/StartSliceJob.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index b3755602d1..a4c7e1c1ed 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -154,7 +154,7 @@ class CuraEngineBackend(Backend): self._slicing = True self.slicingStarted.emit() - job = StartSliceJob.StartSliceJob(self._profile, self._socket) + job = StartSliceJob.StartSliceJob(self._socket) job.start() job.finished.connect(self._onStartSliceCompleted) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 9fecb20646..480076b9cc 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -31,11 +31,11 @@ class GcodeStartEndFormatter(Formatter): ## Job that handles sending the current scene data to CuraEngine class StartSliceJob(Job): - def __init__(self, profile, socket): + def __init__(self, socket): super().__init__() self._scene = Application.getInstance().getController().getScene() - self._profile = profile + self._settings = Application.getInstance().getGlobalContainerStack() self._socket = socket ## Runs the job that initiates the slicing. From eb951ed07c4830f90eb1f771e36c8f04eb4d0392 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 13:58:36 +0200 Subject: [PATCH 221/705] Fix potential concurrency of finishing before connected to finishing This was a concurrency issue: If the slicing was very fast, it could finish slicing before the listener was connected to the message of being finished. Therefore, we should connect to being finished before we even start the start-slice job. Contributes to issue CURA-1278. --- plugins/CuraEngineBackend/CuraEngineBackend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index a4c7e1c1ed..a854f29bf1 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -155,8 +155,8 @@ class CuraEngineBackend(Backend): self.slicingStarted.emit() job = StartSliceJob.StartSliceJob(self._socket) - job.start() job.finished.connect(self._onStartSliceCompleted) + job.start() def _terminate(self): self._slicing = False From b03aa246a08fd029f8ab7016a018f0b23d5f922d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 14:47:02 +0200 Subject: [PATCH 222/705] Call new function to send global settings I'm going to rename this function to be able to send per-extruder and per-object settings with different functions later on. This updates the call to the function to use the new one. Contributes to issue CURA-1278. --- plugins/CuraEngineBackend/StartSliceJob.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 480076b9cc..e98658b717 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -35,7 +35,6 @@ class StartSliceJob(Job): super().__init__() self._scene = Application.getInstance().getController().getScene() - self._settings = Application.getInstance().getGlobalContainerStack() self._socket = socket ## Runs the job that initiates the slicing. @@ -85,7 +84,7 @@ class StartSliceJob(Job): if not object_groups: return - self._sendSettings(self._profile) + self._sendGlobalSettings() slice_message = self._socket.createMessage("cura.proto.Slice") @@ -123,6 +122,13 @@ class StartSliceJob(Job): Logger.log("w", "Unabled to do token replacement on start/end gcode %s", traceback.format_exc()) return str(value).encode("utf-8") + ## Sends all global settings to the engine. + # + # The settings are taken from the global stack. This does not include any + # per-extruder settings or per-object settings. + def _sendGlobalSettings(self): + pass #TODO: Implement this. + def _sendSettings(self, profile): msg = self._socket.createMessage("cura.proto.SettingList") settings = profile.getAllSettingValues(include_machine = True) From 8a21ac77edc1c59e8a7b2bbc1a903fd93e27614c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 15:53:40 +0200 Subject: [PATCH 223/705] Re-implement sending global settings It turns out to be mostly the same. Contributes to issue CURA-1278 and CURA-1588. --- plugins/CuraEngineBackend/StartSliceJob.py | 42 ++++++++++++++-------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index e98658b717..3d58c74b93 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -5,8 +5,9 @@ import numpy from string import Formatter import traceback -from UM.Job import Job from UM.Application import Application +from UM.Settings.DefinitionContainer import DefinitionContainer +from UM.Job import Job from UM.Logger import Logger from UM.Scene.SceneNode import SceneNode @@ -127,23 +128,20 @@ class StartSliceJob(Job): # The settings are taken from the global stack. This does not include any # per-extruder settings or per-object settings. def _sendGlobalSettings(self): - pass #TODO: Implement this. - - def _sendSettings(self, profile): - msg = self._socket.createMessage("cura.proto.SettingList") - settings = profile.getAllSettingValues(include_machine = True) + message = self._socket.createMessage("cura.proto.SettingList") + settings = self._getAllSettingValues() #Get all the settings to send. start_gcode = settings["machine_start_gcode"] - settings["material_bed_temp_prepend"] = "{material_bed_temperature}" not in start_gcode + settings["material_bed_temp_prepend"] = "{material_bed_temperature}" not in start_gcode #Pre-compute material_bed_temp_prepend and material_print_temp_prepend. settings["material_print_temp_prepend"] = "{material_print_temperature}" not in start_gcode - for key, value in settings.items(): - s = msg.addRepeatedMessage("settings") - s.name = key - if key == "machine_start_gcode" or key == "machine_end_gcode": - s.value = self._expandGcodeTokens(key, value, settings) + for key, value in settings.items(): #Add all submessages for each individual setting. + setting_message = message.addRepeatedMessage("settings") + setting_message.name = key + if key == "machine_start_gcode" or key == "machine_end_gcode": #If it's a g-code message, use special formatting. + setting_message.value = self._expandGcodeTokens(key, value, settings) else: - s.value = str(value).encode("utf-8") + setting_message.value = str(value).encode("utf-8") - self._socket.sendMessage(msg) + self._socket.sendMessage(message) def _handlePerObjectSettings(self, node, message): profile = node.callDecoration("getProfile") @@ -164,3 +162,19 @@ class StartSliceJob(Job): setting.value = str(value).encode() Job.yieldThread() + + ## Gets all setting values as a dictionary. + # + # \return A dictionary with the setting keys as keys and the setting + # values as values. + def _getAllSettingValues(self): + stack = Application.getInstance().getGlobalContainerStack() + setting_values = {} + + definition_containers = [container for container in stack.getContainers() if container.__class__ == DefinitionContainer] #To get all keys, get all definitions from all definition containers. + for definition_container in definition_containers: + for definition in definition_container.definitions: + if definition.key not in setting_values: #Prevent looking up the same key twice, for speed. + setting_values[definition.key] = stack.getProperty(definition.key, "value") + + return setting_values \ No newline at end of file From 8f1860413babff4770df12b439506f486f50169c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 16:00:39 +0200 Subject: [PATCH 224/705] Always send FDMPrinter definition via socket We don't save the file name any more. The engine doesn't need any machine-specific definitions at the moment, so we can always just send FDMPrinter.. This may later change, but later we will also send a serialised JSON rather than a file name so then we won't need the file name any more. Contributes to issues CURA-1278 and CURA-1588. --- plugins/CuraEngineBackend/CuraEngineBackend.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index a854f29bf1..38a78beda0 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -101,12 +101,7 @@ class CuraEngineBackend(Backend): # This is useful for debugging and used to actually start the engine. # \return list of commands and args / parameters. def getEngineCommand(self): - active_machine = Application.getInstance().getMachineManager().getActiveMachineInstance() - if not active_machine: - json_path = Resources.getPath(Resources.MachineDefinitions, "fdmprinter.json") - else: - json_path = active_machine.getMachineDefinition().getPath() - + json_path = Resources.getPath(Resources.DefinitionContainers, "fdmprinter.def.json") return [Preferences.getInstance().getValue("backend/location"), "connect", "127.0.0.1:{0}".format(self._port), "-j", json_path, "-vv"] ## Emitted when we get a message containing print duration and material amount. This also implies the slicing has finished. From c996bcb191e1a76b0999bb73b960fd0e66d30c75 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 16:01:57 +0200 Subject: [PATCH 225/705] Remove extruder drive upgrade option It was originally included with the thought that there would be different firmware for this, but there isn't. So this setting is not needed. Contributes to issue CURA-1278. --- resources/definitions/ultimaker_original.def.json | 8 -------- resources/qml/WizardPages/SelectUpgradedParts.qml | 9 --------- 2 files changed, 17 deletions(-) diff --git a/resources/definitions/ultimaker_original.def.json b/resources/definitions/ultimaker_original.def.json index 76b6c8b4ff..f445057860 100644 --- a/resources/definitions/ultimaker_original.def.json +++ b/resources/definitions/ultimaker_original.def.json @@ -18,14 +18,6 @@ ] }, - "settings": { - "machine_extruder_drive_upgrade": { - "label": "Extruder Drive Upgrade", - "description": "This machine has the extruder drive upgrade.", - "type": "bool", - "default_value": false - } - }, "overrides": { "machine_width": { "default_value": 205 diff --git a/resources/qml/WizardPages/SelectUpgradedParts.qml b/resources/qml/WizardPages/SelectUpgradedParts.qml index 4a327a6ed4..a49401ada9 100644 --- a/resources/qml/WizardPages/SelectUpgradedParts.qml +++ b/resources/qml/WizardPages/SelectUpgradedParts.qml @@ -17,9 +17,6 @@ Item Component.onDestruction: { - if (extruderCheckBox.checked == true){ - UM.MachineManager.setMachineSettingValue("machine_extruder_drive_upgrade", true) - } if (heatedBedCheckBox1.checked == true || heatedBedCheckBox2.checked == true){ UM.MachineManager.setMachineSettingValue("machine_heated_bed", true) } @@ -52,12 +49,6 @@ Item anchors.topMargin: UM.Theme.getSize("default_margin").height width: parent.width - UM.Theme.getSize("default_margin").width CheckBox - { - id: extruderCheckBox - text: catalog.i18nc("@option:check","Extruder driver ugrades") - checked: true - } - CheckBox { id: heatedBedCheckBox1 text: catalog.i18nc("@option:check","Heated printer bed") From 9dab21c4d0dd4e1097eae165f4a396e60f86e329 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 16:06:38 +0200 Subject: [PATCH 226/705] Fix getting print_sequence setting The setting is used to group items for one-at-a-time printing before they're sent to the engine. This properly gets the setting value under the new setting system. Contributes to issues CURA-1278 and CURA-1588. --- plugins/CuraEngineBackend/StartSliceJob.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 3d58c74b93..965ccc8b8a 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -50,7 +50,7 @@ class StartSliceJob(Job): # Get the objects in their groups to print. object_groups = [] - if self._profile.getSettingValue("print_sequence") == "one_at_a_time": + if Application.getInstance().getGlobalContainerStack().getProperty("print_sequence", "value") == "one_at_a_time": for node in OneAtATimeIterator(self._scene.getRoot()): temp_list = [] From 70b52f4b62755d48add1c7ae9269cb1613a5e3fd Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 16:34:14 +0200 Subject: [PATCH 227/705] Also get setting values of child definitions Otherwise we just get the setting categories, which is not very useful. Contributes to issues CURA-1278 and CURA-1588. --- plugins/CuraEngineBackend/StartSliceJob.py | 25 ++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 965ccc8b8a..5379e00156 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -37,6 +37,7 @@ class StartSliceJob(Job): self._scene = Application.getInstance().getController().getScene() self._socket = socket + self._stack = Application.getInstance().getGlobalContainerStack() ## Runs the job that initiates the slicing. def run(self): @@ -130,6 +131,7 @@ class StartSliceJob(Job): def _sendGlobalSettings(self): message = self._socket.createMessage("cura.proto.SettingList") settings = self._getAllSettingValues() #Get all the settings to send. + print(settings) start_gcode = settings["machine_start_gcode"] settings["material_bed_temp_prepend"] = "{material_bed_temperature}" not in start_gcode #Pre-compute material_bed_temp_prepend and material_print_temp_prepend. settings["material_print_temp_prepend"] = "{material_print_temperature}" not in start_gcode @@ -163,18 +165,33 @@ class StartSliceJob(Job): Job.yieldThread() + ## Gets the current values for all child definitions of a definition. + # + # To be clear, it looks up all child definitions, and returns the CURRENT + # VALUE of the keys of these definitions according to the global stack. It + # doesn't return the "value" property in the definition. + # + # \param definition The setting definition to get the child settings of. + def _getAllChildSettingValues(self, definition): + setting_values = { } + for child in definition.children: + setting_values[child.key] = self._stack.getProperty(child.key, "value") + for key, value in self._getAllChildSettingValues(child).items(): + setting_values[key] = value + return setting_values + ## Gets all setting values as a dictionary. # # \return A dictionary with the setting keys as keys and the setting # values as values. def _getAllSettingValues(self): - stack = Application.getInstance().getGlobalContainerStack() setting_values = {} - definition_containers = [container for container in stack.getContainers() if container.__class__ == DefinitionContainer] #To get all keys, get all definitions from all definition containers. + definition_containers = [container for container in self._stack.getContainers() if container.__class__ == DefinitionContainer] #To get all keys, get all definitions from all definition containers. for definition_container in definition_containers: for definition in definition_container.definitions: - if definition.key not in setting_values: #Prevent looking up the same key twice, for speed. - setting_values[definition.key] = stack.getProperty(definition.key, "value") + setting_values[definition.key] = self._stack.getProperty(definition.key, "value") + for key, value in self._getAllChildSettingValues(definition).items(): + setting_values[key] = value return setting_values \ No newline at end of file From 15333fa9407e2905b0a680a1e596672b18ede0a7 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 16:37:11 +0200 Subject: [PATCH 228/705] Codestyle: Spaces after commas Contributes to issues CURA-1278 and CURA-1588. --- plugins/CuraEngineBackend/StartSliceJob.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 5379e00156..0b01b11992 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -101,8 +101,8 @@ class StartSliceJob(Job): obj.id = id(current_object) verts = numpy.array(mesh_data.getVertices()) - verts[:,[1,2]] = verts[:,[2,1]] - verts[:,1] *= -1 + verts[:, [1, 2]] = verts[:, [2, 1]] + verts[:, 1] *= -1 obj.vertices = verts From 6fcba4cdde7d75ba73cd66f6b672447c44e5a5d7 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 16:38:08 +0200 Subject: [PATCH 229/705] Fix typo in error message Contributes to issues CURA-1278 and CURA-1588. --- plugins/CuraEngineBackend/CuraEngineBackend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 38a78beda0..dee6f43bd6 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -168,7 +168,7 @@ class CuraEngineBackend(Backend): self._process = None #self._createSocket() # Re create the socket except Exception as e: # terminating a process that is already terminating causes an exception, silently ignore this. - Logger.log("d", "Exception occured while trying to kill the engine %s", str(e)) + Logger.log("d", "Exception occurred while trying to kill the engine %s", str(e)) if self._message: self._message.hide() self._message = None From e94220f46d93a0be1cb384ce77e1e41815e7ac04 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 16:39:37 +0200 Subject: [PATCH 230/705] Remove commented code Contributes to issues CURA-1278 and CURA-1588. --- plugins/CuraEngineBackend/CuraEngineBackend.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index dee6f43bd6..1f7d34556e 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -166,7 +166,6 @@ class CuraEngineBackend(Backend): self._process.terminate() Logger.log("d", "Engine process is killed. Received return code %s", self._process.wait()) self._process = None - #self._createSocket() # Re create the socket except Exception as e: # terminating a process that is already terminating causes an exception, silently ignore this. Logger.log("d", "Exception occurred while trying to kill the engine %s", str(e)) if self._message: From c8de272ec445023c467767336be043284514e99f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 16:45:43 +0200 Subject: [PATCH 231/705] Document old functions I was reading through these to check if they'd still work. They should still work, but since I went through them I went ahead and documented them too. Contributes to issues CURA-1278 and CURA-1588. --- plugins/CuraEngineBackend/CuraEngineBackend.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 1f7d34556e..d7c4d6bd8b 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -153,6 +153,7 @@ class CuraEngineBackend(Backend): job.finished.connect(self._onStartSliceCompleted) job.start() + ## Terminate the engine process. def _terminate(self): self._slicing = False self._restart = True @@ -172,7 +173,14 @@ class CuraEngineBackend(Backend): self._message.hide() self._message = None - + ## Event handler to call when the job to initiate the slicing process is + # completed. + # + # When the start slice job is successfully completed, it will be happily + # slicing. This function handles any errors that may occur during the + # bootstrapping of a slice job. + # + # \param job The start slice job that was just finished. def _onStartSliceCompleted(self, job): if job.getError() or job.getResult() != True: if self._message: @@ -180,6 +188,11 @@ class CuraEngineBackend(Backend): self._message = None return + ## Listener for when the scene has changed. + # + # This should start a slice if the scene is now ready to slice. + # + # \param source The scene node that was changed. def _onSceneChanged(self, source): if type(source) is not SceneNode: return @@ -195,6 +208,9 @@ class CuraEngineBackend(Backend): self._onChanged() + ## Called when an error occurs in the socket connection towards the engine. + # + # \param error The exception that occurred. def _onSocketError(self, error): if Application.getInstance().isShuttingDown(): return From 9217dd3e1bfbb519c88d43d6123a2386d1478da9 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 16:47:22 +0200 Subject: [PATCH 232/705] Remove unused function No longer used due to fix for setting rework. Contributes to issues CURA-1278 and CURA-1288. --- plugins/CuraEngineBackend/CuraEngineBackend.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index d7c4d6bd8b..8414cd2cb6 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -221,15 +221,6 @@ class CuraEngineBackend(Backend): if error.getErrorCode() not in [Arcus.ErrorCode.BindFailedError, Arcus.ErrorCode.ConnectionResetError, Arcus.ErrorCode.Debug]: Logger.log("e", "A socket error caused the connection to be reset") - def _onActiveProfileChanged(self): - if self._profile: - self._profile.settingValueChanged.disconnect(self._onSettingChanged) - - self._profile = Application.getInstance().getMachineManager().getWorkingProfile() - if self._profile: - self._profile.settingValueChanged.connect(self._onSettingChanged) - self._onChanged() - ## A setting has changed, so check if we must reslice. # # \param instance The setting instance that has changed. From 90ce0f44c3045c4cf414e9c43a5172d96496e3d7 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 17:00:10 +0200 Subject: [PATCH 233/705] Document remaining functions of CuraEngineBackend They have all been checked for correctness now. While I was doing that, I documented their working as far as I could understand. Contributes to issues CURA-1278 and CURA-1588. --- .../CuraEngineBackend/CuraEngineBackend.py | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 8414cd2cb6..0410fc77fa 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -229,10 +229,15 @@ class CuraEngineBackend(Backend): if property == "value": #Only reslice if the value has changed. self._onChanged() + ## Called when a sliced layer data message is received from the engine. + # + # \param message The protobuf message containing sliced layer data. def _onLayerMessage(self, message): self._stored_layer_data.append(message) - + ## Called when a progress message is received from the engine. + # + # \param message The protobuf message containing the slicing progress. def _onProgressMessage(self, message): if self._message: self._message.setProgress(round(message.amount * 100)) @@ -240,6 +245,9 @@ class CuraEngineBackend(Backend): self.processingProgress.emit(message.amount) self.backendStateChange.emit(BackendState.PROCESSING) + ## Called when the engine sends a message that slicing is finished. + # + # \param message The protobuf message signalling that slicing is finished. def _onSlicingFinishedMessage(self, message): self.backendStateChange.emit(BackendState.DONE) self.processingProgress.emit(1.0) @@ -256,15 +264,27 @@ class CuraEngineBackend(Backend): self._process_layers_job.start() self._stored_layer_data = [] + ## Called when a g-code message is received from the engine. + # + # \param message The protobuf message containing g-code, encoded as UTF-8. def _onGCodeLayerMessage(self, message): self._scene.gcode_list.append(message.data.decode("utf-8", "replace")) + ## Called when a g-code prefix message is received from the engine. + # + # \param message The protobuf message containing the g-code prefix, + # encoded as UTF-8. def _onGCodePrefixMessage(self, message): self._scene.gcode_list.insert(0, message.data.decode("utf-8", "replace")) + ## Called when a print time message is received from the engine. + # + # \param message The protobuf message containing the print time and + # material amount. def _onObjectPrintTimeMessage(self, message): self.printDurationMessage.emit(message.time, message.material_amount) + ## Creates a new socket connection. def _createSocket(self): super()._createSocket(os.path.abspath(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "Cura.proto"))) @@ -272,25 +292,41 @@ class CuraEngineBackend(Backend): def forceSlice(self): self._change_timer.start() + ## Called when anything has changed to the stuff that needs to be sliced. + # + # This indicates that we should probably re-slice soon. def _onChanged(self): self._change_timer.start() + ## Called when the back-end connects to the front-end. def _onBackendConnected(self): if self._restart: self._onChanged() self._restart = False + ## Called when the user starts using some tool. + # + # When the user starts using a tool, we should pause slicing to prevent + # continuously slicing while the user is dragging some tool handle. + # + # \param tool The tool that the user is using. def _onToolOperationStarted(self, tool): self._terminate() # Do not continue slicing once a tool has started self._enabled = False # Do not reslice when a tool is doing it's 'thing' + ## Called when the user stops using some tool. + # + # This indicates that we can safely start slicing again. + # + # \param tool The tool that the user was using. def _onToolOperationStopped(self, tool): self._enabled = True # Tool stop, start listening for changes again. + ## Called when the user changes the active view mode. def _onActiveViewChanged(self): if Application.getInstance().getController().getActiveView(): view = Application.getInstance().getController().getActiveView() - if view.getPluginId() == "LayerView": + if view.getPluginId() == "LayerView": #If switching to layer view, we should process the layers if that hasn't been done yet. self._layer_view_active = True # There is data and we're not slicing at the moment # if we are slicing, there is no need to re-calculate the data as it will be invalid in a moment. @@ -304,6 +340,9 @@ class CuraEngineBackend(Backend): def _onInstanceChanged(self): self._terminate() + ## Called when the back-end self-terminates. + # + # We should reset our state and start listening for new connections. def _onBackendQuit(self): if not self._restart and self._process: Logger.log("d", "Backend quit with return code %s. Resetting process and socket.", self._process.wait()) From c6d3677d6f2f46ab159f750e655d24acf8cf46ff Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 17:00:58 +0200 Subject: [PATCH 234/705] Remove unused function There are no machine instances any more. We can just listen for setting value changes. Contributes to issues CURA-1278 and CURA-1588. --- plugins/CuraEngineBackend/CuraEngineBackend.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 0410fc77fa..df4d5f6dd2 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -337,9 +337,6 @@ class CuraEngineBackend(Backend): else: self._layer_view_active = False - def _onInstanceChanged(self): - self._terminate() - ## Called when the back-end self-terminates. # # We should reset our state and start listening for new connections. From d235b36692db5b7d48998b294da2ce812fedd09c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 17:03:25 +0200 Subject: [PATCH 235/705] Fix computation of material length from volume The setting value was obtained wrongly. Contributes to issue CURA-1278. --- cura/PrintInformation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index 994dac69d0..2663cab5a0 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -63,6 +63,6 @@ class PrintInformation(QObject): self.currentPrintTimeChanged.emit() # Material amount is sent as an amount of mm^3, so calculate length from that - r = Application.getInstance().getGlobalContainerStack().getValue("material_diameter") / 2 + r = Application.getInstance().getGlobalContainerStack().getProperty("material_diameter", "value") / 2 self._material_amount = round((amount / (math.pi * r ** 2)) / 1000, 2) self.materialAmountChanged.emit() From 6116f592b3de0aced9e12ead0804e35550c9b0a8 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 17:04:56 +0200 Subject: [PATCH 236/705] Remove print This was printing all settings that were being sent to the engine. Could've been useful, actually. Maybe I'll re-add it in the form of a log. Contributes to issues CURA-1278 and CURA-1588. --- plugins/CuraEngineBackend/StartSliceJob.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 0b01b11992..70c56dfcc5 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -131,7 +131,6 @@ class StartSliceJob(Job): def _sendGlobalSettings(self): message = self._socket.createMessage("cura.proto.SettingList") settings = self._getAllSettingValues() #Get all the settings to send. - print(settings) start_gcode = settings["machine_start_gcode"] settings["material_bed_temp_prepend"] = "{material_bed_temperature}" not in start_gcode #Pre-compute material_bed_temp_prepend and material_print_temp_prepend. settings["material_print_temp_prepend"] = "{material_print_temperature}" not in start_gcode From eb8b3e01e3b2ba39bbbad377dcd5aa6d0f354d40 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 23 May 2016 18:10:35 +0200 Subject: [PATCH 237/705] Properly catch exceptions when serializing containers and check for dirty state --- cura/CuraApplication.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index bfe342d1e4..dc3d777c2f 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -193,7 +193,17 @@ class CuraApplication(QtApplication): ## Cura has multiple locations where instance containers need to be saved, so we need to handle this differently. def _onExit(self): for instance in ContainerRegistry.getInstance().findInstanceContainers(): - data = instance.serialize() + if not instance.isDirty(): + continue + + try: + data = instance.serialize() + except NotImplementedError: + continue + except Exception: + Logger.logException("e", "An exception occurred when serializing container %s", instance.getId()) + continue + file_name = urllib.parse.quote_plus(instance.getId()) + ".inst.cfg" instance_type = instance.getMetaDataEntry("type") path = None @@ -211,7 +221,17 @@ class CuraApplication(QtApplication): f.write(data) for stack in ContainerRegistry.getInstance().findContainerStacks(): - data = stack.serialize() + if not stack.isDirty(): + continue + + try: + data = stack.serialize() + except NotImplementedError: + continue + except Exception: + Logger.logException("e", "An exception occurred when serializing container %s", instance.getId()) + continue + file_name = urllib.parse.quote_plus(stack.getId()) + ".stack.cfg" path = Resources.getStoragePath(self.ResourceTypes.MachineStack, file_name) with SaveFile(path, "wt", -1, "utf-8") as f: From ea5dc00080f4fcee2fc21c20c04bacc9c188638b Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 23 May 2016 18:11:03 +0200 Subject: [PATCH 238/705] Bump LayerView API version to 3 It does not use any setting API so it is safe --- plugins/LayerView/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/LayerView/__init__.py b/plugins/LayerView/__init__.py index 3d43532126..67750fb562 100644 --- a/plugins/LayerView/__init__.py +++ b/plugins/LayerView/__init__.py @@ -14,7 +14,7 @@ def getMetaData(): "author": "Ultimaker", "version": "1.0", "description": catalog.i18nc("@info:whatsthis", "Provides the Layer view."), - "api": 2 + "api": 3 }, "view": { "name": catalog.i18nc("@item:inlistbox", "Layers"), From 8284ab9de539828825c31f182f9a95ba4e2f8f69 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 23 May 2016 18:11:24 +0200 Subject: [PATCH 239/705] Insert printers and materials pages at the right location --- resources/qml/Cura.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index b03c5ed06a..b8ea7b1a72 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -549,9 +549,9 @@ UM.MainWindow //: View preferences page title insertPage(1, catalog.i18nc("@title:tab","View"), Qt.resolvedUrl("ViewPage.qml")); - insertPage(2, catalog.i18nc("@title:tab", "Printers"), Qt.resolvedUrl("MachinesPage.qml")); + insertPage(3, catalog.i18nc("@title:tab", "Printers"), Qt.resolvedUrl("MachinesPage.qml")); - insertPage(3, catalog.i18nc("@title:tab", "Materials"), Qt.resolvedUrl("Preferences/MaterialsPage.qml")) + insertPage(4, catalog.i18nc("@title:tab", "Materials"), Qt.resolvedUrl("Preferences/MaterialsPage.qml")); //Force refresh setPage(0); From f90be96bc66b5339d1e6e709450d13a670f93b8a Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 23 May 2016 18:12:25 +0200 Subject: [PATCH 240/705] Add back the Profiles page --- resources/qml/Cura.qml | 2 + resources/qml/Preferences/ProfilesPage.qml | 222 +++++++++++++++++++++ 2 files changed, 224 insertions(+) create mode 100644 resources/qml/Preferences/ProfilesPage.qml diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index b8ea7b1a72..733def1b81 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -553,6 +553,8 @@ UM.MainWindow insertPage(4, catalog.i18nc("@title:tab", "Materials"), Qt.resolvedUrl("Preferences/MaterialsPage.qml")); + insertPage(5, catalog.i18nc("@title:tab", "Profiles"), Qt.resolvedUrl("Preferences/ProfilesPage.qml")); + //Force refresh setPage(0); } diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml new file mode 100644 index 0000000000..6e5d39cb49 --- /dev/null +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -0,0 +1,222 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Dialogs 1.2 + +import UM 1.2 as UM + +UM.ManagementPage +{ + id: base; + + title: catalog.i18nc("@title:tab", "Profiles"); + addText: catalog.i18nc("@label", "Duplicate") + + model: UM.InstanceContainersModel { filter: { "type": "quality" } } + + onAddObject: { + var selectedProfile; + if (objectList.currentIndex == 0) { + // Current settings + selectedProfile = UM.MachineManager.createProfile(); + } else { + selectedProfile = UM.MachineManager.duplicateProfile(currentItem.name); + } + base.selectProfile(selectedProfile); + + renameDialog.removeWhenRejected = true; + renameDialog.open(); + renameDialog.selectText(); + } + onRemoveObject: confirmDialog.open(); + onRenameObject: { renameDialog.removeWhenRejected = false; renameDialog.open(); renameDialog.selectText(); } + + addEnabled: currentItem != null; + removeEnabled: currentItem != null ? !currentItem.readOnly : false; + renameEnabled: currentItem != null ? !currentItem.readOnly : false; + + scrollviewCaption: catalog.i18nc("@label %1 is printer name","Printer: %1").arg(UM.MachineManager.activeMachineInstance) + + signal selectProfile(string name) + onSelectProfile: { + objectList.currentIndex = objectList.model.find("name", name); + } + + Item { + visible: base.currentItem != null + anchors.fill: parent + + Label { + id: profileName + text: base.currentItem ? base.currentItem.name : "" + font: UM.Theme.getFont("large") + width: parent.width + elide: Text.ElideRight + } + + ScrollView { + anchors.left: parent.left + anchors.top: profileName.bottom + anchors.topMargin: UM.Theme.getSize("default_margin").height + anchors.right: parent.right + anchors.bottom: parent.bottom + + Column + { + spacing: UM.Theme.getSize("default_margin").height + + Row + { + visible: base.currentItem.id == -1 || base.currentItem.active + Button + { + text: { + var profileName = UM.MachineManager.activeProfile; + profileName = (profileName.length > 20) ? profileName.substring(0, 20) + '...' : profileName; + return catalog.i18nc("@action:button", "Update \"%1\"".arg(profileName)); + } + enabled: UM.ActiveProfile.hasCustomisedValues && !UM.ActiveProfile.readOnly + onClicked: UM.ActiveProfile.updateProfile() + } + + Button + { + text: catalog.i18nc("@action:button", "Discard changes"); + enabled: UM.ActiveProfile.hasCustomisedValues + onClicked: UM.ActiveProfile.discardChanges() + } + } + + Grid + { + id: containerGrid + columns: 2 + spacing: UM.Theme.getSize("default_margin").width + + Label { + text: base.currentItem == null ? "" : + base.currentItem.id == -1 ? catalog.i18nc("@label", "Based on") : catalog.i18nc("@label", "Profile type") + } + Label { + text: base.currentItem == null ? "" : + base.currentItem.id == -1 ? UM.MachineManager.activeProfile : + base.currentItem.readOnly ? catalog.i18nc("@label", "Protected profile") : catalog.i18nc("@label", "Custom profile") + } + + Column { + Repeater { + model: base.currentItem ? base.currentItem.settings : null + Label { + text: modelData.name.toString(); + elide: Text.ElideMiddle; + } + } + } + Column { + Repeater { + model: base.currentItem ? base.currentItem.settings : null + Label { text: modelData.value.toString(); } + } + } + } + } + } + } + + buttons: Row { + + Button + { + text: catalog.i18nc("@action:button", "Import"); + iconName: "document-import"; + onClicked: importDialog.open(); + } + + Button + { + text: catalog.i18nc("@action:button", "Export"); + iconName: "document-export"; + onClicked: exportDialog.open(); + } + } + + Item + { + UM.I18nCatalog { id: catalog; name: "uranium"; } + + UM.ConfirmRemoveDialog + { + id: confirmDialog; + object: base.currentItem != null ? base.currentItem.name : ""; + onYes: base.model.removeProfile(base.currentItem.name); + } + UM.RenameDialog + { + id: renameDialog; + object: base.currentItem != null ? base.currentItem.name : ""; + property bool removeWhenRejected: false; + onAccepted: base.model.renameProfile(base.currentItem.name, newName.trim()); + onRejected: { + if(removeWhenRejected) { + base.model.removeProfile(base.currentItem.name) + } + } + } + MessageDialog + { + id: messageDialog + title: catalog.i18nc("@window:title", "Import Profile"); + standardButtons: StandardButton.Ok + modality: Qt.ApplicationModal + } + + FileDialog + { + id: importDialog; + title: catalog.i18nc("@title:window", "Import Profile"); + selectExisting: true; + nameFilters: base.model.getFileNameFiltersRead() + folder: base.model.getDefaultPath() + onAccepted: + { + var result = base.model.importProfile(fileUrl) + messageDialog.text = result.message + if(result.status == "ok") + { + messageDialog.icon = StandardIcon.Information + } + else if(result.status == "duplicate") + { + messageDialog.icon = StandardIcon.Warning + } + else + { + messageDialog.icon = StandardIcon.Critical + } + messageDialog.open() + } + } + + FileDialog + { + id: exportDialog; + title: catalog.i18nc("@title:window", "Export Profile"); + selectExisting: false; + nameFilters: base.model.getFileNameFiltersWrite() + folder: base.model.getDefaultPath() + onAccepted: + { + var result = base.model.exportProfile(base.currentItem.id, base.currentItem.name, fileUrl, selectedNameFilter) + if(result && result.status == "error") + { + messageDialog.icon = StandardIcon.Critical + messageDialog.text = result.message + messageDialog.open() + } + // else pop-up Message thing from python code + } + } + } +} From a1115649cfa69a63dc6aa6d51546612daad8e64a Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 23 May 2016 18:13:22 +0200 Subject: [PATCH 241/705] Rename all variant profiles to .inst.cfg and correctly mark them as type variant Still some issues with formulas causing errors, but it is getting closer --- ...ed_plus_0.25.cfg => ultimaker2_extended_plus_0.25.inst.cfg} | 3 ++- ...nded_plus_0.4.cfg => ultimaker2_extended_plus_0.4.inst.cfg} | 3 ++- ...nded_plus_0.6.cfg => ultimaker2_extended_plus_0.6.inst.cfg} | 3 ++- ...nded_plus_0.8.cfg => ultimaker2_extended_plus_0.8.inst.cfg} | 3 ++- ...{ultimaker2_plus_0.25.cfg => ultimaker2_plus_0.25.inst.cfg} | 3 ++- .../{ultimaker2_plus_0.4.cfg => ultimaker2_plus_0.4.inst.cfg} | 3 ++- .../{ultimaker2_plus_0.6.cfg => ultimaker2_plus_0.6.inst.cfg} | 3 ++- .../{ultimaker2_plus_0.8.cfg => ultimaker2_plus_0.8.inst.cfg} | 3 ++- 8 files changed, 16 insertions(+), 8 deletions(-) rename resources/variants/{ultimaker2_extended_plus_0.25.cfg => ultimaker2_extended_plus_0.25.inst.cfg} (84%) rename resources/variants/{ultimaker2_extended_plus_0.4.cfg => ultimaker2_extended_plus_0.4.inst.cfg} (82%) rename resources/variants/{ultimaker2_extended_plus_0.6.cfg => ultimaker2_extended_plus_0.6.inst.cfg} (83%) rename resources/variants/{ultimaker2_extended_plus_0.8.cfg => ultimaker2_extended_plus_0.8.inst.cfg} (83%) rename resources/variants/{ultimaker2_plus_0.25.cfg => ultimaker2_plus_0.25.inst.cfg} (84%) rename resources/variants/{ultimaker2_plus_0.4.cfg => ultimaker2_plus_0.4.inst.cfg} (81%) rename resources/variants/{ultimaker2_plus_0.6.cfg => ultimaker2_plus_0.6.inst.cfg} (83%) rename resources/variants/{ultimaker2_plus_0.8.cfg => ultimaker2_plus_0.8.inst.cfg} (83%) diff --git a/resources/variants/ultimaker2_extended_plus_0.25.cfg b/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg similarity index 84% rename from resources/variants/ultimaker2_extended_plus_0.25.cfg rename to resources/variants/ultimaker2_extended_plus_0.25.inst.cfg index 2bc14d7588..0c0154c03b 100644 --- a/resources/variants/ultimaker2_extended_plus_0.25.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg @@ -5,6 +5,7 @@ definition = ultimaker2_extended_plus [metadata] author = Ultimaker +type = variant [values] machine_nozzle_size = 0.25 @@ -13,4 +14,4 @@ coasting_volume = 0.1 coasting_min_volume = 0.17 speed_wall = round(speed_print / 1.2, 1) speed_wall_0 = 1 if speed_wall < 5 else (speed_wall - 5) -speed_topbottom = round(speed_print / 1.5, 1) \ No newline at end of file +speed_topbottom = round(speed_print / 1.5, 1) diff --git a/resources/variants/ultimaker2_extended_plus_0.4.cfg b/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg similarity index 82% rename from resources/variants/ultimaker2_extended_plus_0.4.cfg rename to resources/variants/ultimaker2_extended_plus_0.4.inst.cfg index a0de0ad2d7..87b74b2572 100644 --- a/resources/variants/ultimaker2_extended_plus_0.4.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg @@ -5,10 +5,11 @@ definition = ultimaker2_extended_plus [metadata] author = Ultimaker +type = variant [values] machine_nozzle_size = 0.4 machine_nozzle_tip_outer_diameter = 1.05 speed_wall = round(speed_print / 1.25, 1) speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) -speed_topbottom = round(speed_print / 2.25, 1) \ No newline at end of file +speed_topbottom = round(speed_print / 2.25, 1) diff --git a/resources/variants/ultimaker2_extended_plus_0.6.cfg b/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg similarity index 83% rename from resources/variants/ultimaker2_extended_plus_0.6.cfg rename to resources/variants/ultimaker2_extended_plus_0.6.inst.cfg index 10fa9dd4de..343b2d85e5 100644 --- a/resources/variants/ultimaker2_extended_plus_0.6.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg @@ -5,6 +5,7 @@ definition = ultimaker2_extended_plus [metadata] author = Ultimaker +type = variant [values] machine_nozzle_size = 0.6 @@ -12,4 +13,4 @@ machine_nozzle_tip_outer_diameter = 1.25 coasting_volume = 1.36 speed_wall = round(speed_print * 4 / 3, 1) speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) -speed_topbottom = round(speed_print / 2, 1) \ No newline at end of file +speed_topbottom = round(speed_print / 2, 1) diff --git a/resources/variants/ultimaker2_extended_plus_0.8.cfg b/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg similarity index 83% rename from resources/variants/ultimaker2_extended_plus_0.8.cfg rename to resources/variants/ultimaker2_extended_plus_0.8.inst.cfg index 2980215ebd..c1bb4555c1 100644 --- a/resources/variants/ultimaker2_extended_plus_0.8.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg @@ -5,6 +5,7 @@ definition = ultimaker2_extended_plus [metadata] author = Ultimaker +type = variant [values] machine_nozzle_size = 0.8 @@ -12,4 +13,4 @@ machine_nozzle_tip_outer_diameter = 1.35 coasting_volume = 3.22 speed_wall = round(speed_print * 4 / 3, 1) speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) -speed_topbottom = round(speed_print / 2, 1) \ No newline at end of file +speed_topbottom = round(speed_print / 2, 1) diff --git a/resources/variants/ultimaker2_plus_0.25.cfg b/resources/variants/ultimaker2_plus_0.25.inst.cfg similarity index 84% rename from resources/variants/ultimaker2_plus_0.25.cfg rename to resources/variants/ultimaker2_plus_0.25.inst.cfg index 18839a8871..51a4b44a4a 100644 --- a/resources/variants/ultimaker2_plus_0.25.cfg +++ b/resources/variants/ultimaker2_plus_0.25.inst.cfg @@ -5,6 +5,7 @@ definition = ultimaker2_plus [metadata] author = Ultimaker +type = variant [values] machine_nozzle_size = 0.25 @@ -13,4 +14,4 @@ coasting_volume = 0.1 coasting_min_volume = 0.17 speed_wall = round(speed_print / 1.2, 1) speed_wall_0 = 1 if speed_wall < 5 else (speed_wall - 5) -speed_topbottom = round(speed_print / 1.5, 1) \ No newline at end of file +speed_topbottom = round(speed_print / 1.5, 1) diff --git a/resources/variants/ultimaker2_plus_0.4.cfg b/resources/variants/ultimaker2_plus_0.4.inst.cfg similarity index 81% rename from resources/variants/ultimaker2_plus_0.4.cfg rename to resources/variants/ultimaker2_plus_0.4.inst.cfg index b7dc47ea6e..aaea23a8df 100644 --- a/resources/variants/ultimaker2_plus_0.4.cfg +++ b/resources/variants/ultimaker2_plus_0.4.inst.cfg @@ -5,10 +5,11 @@ definition = ultimaker2_plus [metadata] author = Ultimaker +type = variant [values] machine_nozzle_size = 0.4 machine_nozzle_tip_outer_diameter = 1.05 speed_wall = round(speed_print / 1.25, 1) speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) -speed_topbottom = round(speed_print / 2.25, 1) \ No newline at end of file +speed_topbottom = round(speed_print / 2.25, 1) diff --git a/resources/variants/ultimaker2_plus_0.6.cfg b/resources/variants/ultimaker2_plus_0.6.inst.cfg similarity index 83% rename from resources/variants/ultimaker2_plus_0.6.cfg rename to resources/variants/ultimaker2_plus_0.6.inst.cfg index d6a7da7437..c416b2ec3c 100644 --- a/resources/variants/ultimaker2_plus_0.6.cfg +++ b/resources/variants/ultimaker2_plus_0.6.inst.cfg @@ -5,6 +5,7 @@ definition = ultimaker2_plus [metadata] author = Ultimaker +type = variant [values] machine_nozzle_size = 0.6 @@ -12,4 +13,4 @@ machine_nozzle_tip_outer_diameter = 1.25 coasting_volume = 1.36 speed_wall = round(speed_print * 4 / 3, 1) speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) -speed_topbottom = round(speed_print / 2, 1) \ No newline at end of file +speed_topbottom = round(speed_print / 2, 1) diff --git a/resources/variants/ultimaker2_plus_0.8.cfg b/resources/variants/ultimaker2_plus_0.8.inst.cfg similarity index 83% rename from resources/variants/ultimaker2_plus_0.8.cfg rename to resources/variants/ultimaker2_plus_0.8.inst.cfg index cb97151642..3b577384ec 100644 --- a/resources/variants/ultimaker2_plus_0.8.cfg +++ b/resources/variants/ultimaker2_plus_0.8.inst.cfg @@ -5,6 +5,7 @@ definition = ultimaker2_plus [metadata] author = Ultimaker +type = variant [values] machine_nozzle_size = 0.8 @@ -12,4 +13,4 @@ machine_nozzle_tip_outer_diameter = 1.35 coasting_volume = 3.22 speed_wall = round(speed_print * 4 / 3, 1) speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) -speed_topbottom = round(speed_print / 2, 1) \ No newline at end of file +speed_topbottom = round(speed_print / 2, 1) From b6aa78cc8d858ba851f571f910fdd5fc4bad9c0e Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 23:15:21 +0200 Subject: [PATCH 242/705] Use getAllKeys of ContainerStack to get all setting values Instead of traversing the setting definitions ourselves, let the stack do it. This code should be reusable for other places where we want to get certain properties of all settings, hopefully. Contributes to issues CURA-1278 and CURA-1588. --- plugins/CuraEngineBackend/StartSliceJob.py | 42 +++++----------------- 1 file changed, 9 insertions(+), 33 deletions(-) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 70c56dfcc5..c0019b4401 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -130,10 +130,17 @@ class StartSliceJob(Job): # per-extruder settings or per-object settings. def _sendGlobalSettings(self): message = self._socket.createMessage("cura.proto.SettingList") - settings = self._getAllSettingValues() #Get all the settings to send. + + #Get all the settings to send. + stack = Application.getInstance().getGlobalContainerStack() + keys = stack.getAllKeys() + settings = { } + for key in keys: + settings[key] = stack.getProperty(key, "value") start_gcode = settings["machine_start_gcode"] settings["material_bed_temp_prepend"] = "{material_bed_temperature}" not in start_gcode #Pre-compute material_bed_temp_prepend and material_print_temp_prepend. settings["material_print_temp_prepend"] = "{material_print_temperature}" not in start_gcode + for key, value in settings.items(): #Add all submessages for each individual setting. setting_message = message.addRepeatedMessage("settings") setting_message.name = key @@ -162,35 +169,4 @@ class StartSliceJob(Job): setting.name = key setting.value = str(value).encode() - Job.yieldThread() - - ## Gets the current values for all child definitions of a definition. - # - # To be clear, it looks up all child definitions, and returns the CURRENT - # VALUE of the keys of these definitions according to the global stack. It - # doesn't return the "value" property in the definition. - # - # \param definition The setting definition to get the child settings of. - def _getAllChildSettingValues(self, definition): - setting_values = { } - for child in definition.children: - setting_values[child.key] = self._stack.getProperty(child.key, "value") - for key, value in self._getAllChildSettingValues(child).items(): - setting_values[key] = value - return setting_values - - ## Gets all setting values as a dictionary. - # - # \return A dictionary with the setting keys as keys and the setting - # values as values. - def _getAllSettingValues(self): - setting_values = {} - - definition_containers = [container for container in self._stack.getContainers() if container.__class__ == DefinitionContainer] #To get all keys, get all definitions from all definition containers. - for definition_container in definition_containers: - for definition in definition_container.definitions: - setting_values[definition.key] = self._stack.getProperty(definition.key, "value") - for key, value in self._getAllChildSettingValues(definition).items(): - setting_values[key] = value - - return setting_values \ No newline at end of file + Job.yieldThread() \ No newline at end of file From 1cbb3a3f285b5093c00afb2be4ca27c839df365c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 23 May 2016 23:47:38 +0200 Subject: [PATCH 243/705] Prevent slicing if there is an invalid setting value E.g. higher than maximum_value. This seems to work okay but is largely untested because switching to advanced mode gives a segfault. Contributes to issues CURA-1278 and CURA-1588. --- .../CuraEngineBackend/CuraEngineBackend.py | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index df4d5f6dd2..cc0d1b1600 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -11,6 +11,7 @@ from UM.Qt.Bindings.BackendProxy import BackendState #To determine the state of from UM.Message import Message from UM.PluginRegistry import PluginRegistry from UM.Resources import Resources +from UM.Settings.Validator import ValidatorState #To find if a setting is in an error state. We can't slice then. from cura.OneAtATimeIterator import OneAtATimeIterator from . import ProcessSlicedLayersJob @@ -127,15 +128,26 @@ class CuraEngineBackend(Backend): self._process_layers_job.abort() self._process_layers_job = None - #TODO: Re-add don't slice with error stuff. - #if self._profile.hasErrorValue(): - # Logger.log("w", "Profile has error values. Aborting slicing") - # if self._message: - # self._message.hide() - # self._message = None - # self._message = Message(catalog.i18nc("@info:status", "Unable to slice. Please check your setting values for errors.")) - # self._message.show() - # return #No slicing if we have error values since those are by definition illegal values. + #Don't slice if there is a setting with an error value. + stack = Application.getInstance().getGlobalContainerStack() + for key in stack.getAllKeys(): + validation_state = stack.getProperty(key, "validationState") + #Only setting instances have a validation state, so settings which + #are not overwritten by any instance will have none. The property + #then, and only then, evaluates to None. We make the assumption that + #the definition defines the setting with a default value that is + #valid. Therefore we can allow both ValidatorState.Valid and None as + #allowable validation states. + #TODO: This assumption is wrong! If the definition defines an inheritance function that through inheritance evaluates to a disallowed value, a setting is still invalid even though it's default! + #TODO: Therefore we must also validate setting definitions. + if validation_state != None and validation_state != ValidatorState.Valid: + Logger.log("w", "Setting %s is not valid, but %s. Aborting slicing.", key, validation_state) + if self._message: #Hide any old message before creating a new one. + self._message.hide() + self._message = None + self._message = Message(catalog.i18nc("@info:status", "Unable to slice. Please check your setting values for errors.")) + self._message.show() + return self.processingProgress.emit(0.0) self.backendStateChange.emit(BackendState.NOT_STARTED) From fa1d262123387918414b74e69a33a57ee2e10910 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 24 May 2016 01:16:11 +0200 Subject: [PATCH 244/705] Fix getting platform centre With the new setting system. Contributes to issues CURA-1278 and CURA-1591. --- plugins/CuraEngineBackend/ProcessSlicedLayersJob.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py index 6a947866d3..59feec0fc2 100644 --- a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py +++ b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py @@ -62,8 +62,6 @@ class ProcessSlicedLayersJob(Job): self._progress.hide() return - settings = Application.getInstance().getMachineManager().getWorkingProfile() - mesh = MeshData() layer_data = LayerData.LayerData() layer_count = len(self._layers) @@ -132,8 +130,9 @@ class ProcessSlicedLayersJob(Job): new_node.setMeshData(mesh) new_node.setParent(self._scene.getRoot()) # Note: After this we can no longer abort! - if not settings.getSettingValue("machine_center_is_zero"): - new_node.setPosition(Vector(-settings.getSettingValue("machine_width") / 2, 0.0, settings.getSettingValue("machine_depth") / 2)) + settings = Application.getInstance().getGlobalContainerStack() + if not settings.getProperty("machine_center_is_zero", "value"): + new_node.setPosition(Vector(-settings.getProperty("machine_width", "value") / 2, 0.0, settings.getProperty("machine_depth", "value") / 2)) if self._progress: self._progress.setProgress(100) From 59b8d5c169bc762dfd80e847f1c6b23d10239217 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 24 May 2016 02:24:11 +0200 Subject: [PATCH 245/705] Fix saving g-code to file The settings that are serialised at the end of the g-code are now the serialised global container stack. That's fairly useless since the serialised version of a container stack just lists the IDs of the containers in the stack, not the settings themselves. One of these containers is likely a current_profile container and that's all the information you'll get from that serialisation. Contributes to issue CURA-1278. --- plugins/GCodeWriter/GCodeWriter.py | 23 ++++++++++++----------- plugins/GCodeWriter/__init__.py | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/plugins/GCodeWriter/GCodeWriter.py b/plugins/GCodeWriter/GCodeWriter.py index ee766ef221..5db25aeac2 100644 --- a/plugins/GCodeWriter/GCodeWriter.py +++ b/plugins/GCodeWriter/GCodeWriter.py @@ -32,7 +32,7 @@ class GCodeWriter(MeshWriter): def write(self, stream, node, mode = MeshWriter.OutputMode.TextMode): if mode != MeshWriter.OutputMode.TextMode: - Logger.log("e", "GCode Writer does not support non-text mode") + Logger.log("e", "GCode Writer does not support non-text mode.") return False scene = Application.getInstance().getController().getScene() @@ -40,26 +40,27 @@ class GCodeWriter(MeshWriter): if gcode_list: for gcode in gcode_list: stream.write(gcode) - # Serialise the profile and put them at the end of the file. - profile = self._serialiseProfile(Application.getInstance().getMachineManager().getWorkingProfile()) - stream.write(profile) + # Serialise the current container stack and put it at the end of the file. + settings = self._serialiseSettings(Application.getInstance().getGlobalContainerStack()) + stream.write(settings) return True return False - ## Serialises the profile to prepare it for saving in the g-code. + ## Serialises a container stack to prepare it for writing at the end of the + # g-code. # - # The profile are serialised, and special characters (including newline) + # The settings are serialised, and special characters (including newline) # are escaped. # - # \param profile The profile to serialise. - # \return A serialised string of the profile. - def _serialiseProfile(self, profile): + # \param settings A container stack to serialise. + # \return A serialised string of the settings. + def _serialiseSettings(self, settings): prefix = ";SETTING_" + str(GCodeWriter.version) + " " # The prefix to put before each line. prefix_length = len(prefix) - # Serialise a deepcopy to remove the defaults from the profile - serialised = copy.deepcopy(profile).serialise() + #TODO: This just serialises the container stack, which only indicates the IDs of the containers in that stack, not the settings themselves, making this about 9001x as useless as the fax functionality in Adobe Acrobat. + serialised = settings.serialize() # Escape characters that have a special meaning in g-code comments. pattern = re.compile("|".join(GCodeWriter.escape_characters.keys())) diff --git a/plugins/GCodeWriter/__init__.py b/plugins/GCodeWriter/__init__.py index cd8a5d3418..efe3368c61 100644 --- a/plugins/GCodeWriter/__init__.py +++ b/plugins/GCodeWriter/__init__.py @@ -13,7 +13,7 @@ def getMetaData(): "author": "Ultimaker", "version": "1.0", "description": catalog.i18nc("@info:whatsthis", "Writes GCode to a file."), - "api": 2 + "api": 3 }, "mesh_writer": { From 673f63cf51d9100d9a655e1a8a8a892125a8d738 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 24 May 2016 02:26:02 +0200 Subject: [PATCH 246/705] Remove unused import The deep copy is no longer needed. Also updated copyright year. Contributes to issue CURA-1278. --- plugins/GCodeWriter/GCodeWriter.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/GCodeWriter/GCodeWriter.py b/plugins/GCodeWriter/GCodeWriter.py index 5db25aeac2..3cbed77aab 100644 --- a/plugins/GCodeWriter/GCodeWriter.py +++ b/plugins/GCodeWriter/GCodeWriter.py @@ -1,11 +1,10 @@ -# Copyright (c) 2015 Ultimaker B.V. +# Copyright (c) 2016 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. from UM.Mesh.MeshWriter import MeshWriter from UM.Logger import Logger from UM.Application import Application import re #For escaping characters in the settings. -import copy class GCodeWriter(MeshWriter): From 8b5c4b0361bf1aa9d5ad6572452700ee7579adf0 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 24 May 2016 02:28:56 +0200 Subject: [PATCH 247/705] Document GCodeWriter class Contributes to issue CURA-1278. --- plugins/GCodeWriter/GCodeWriter.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/plugins/GCodeWriter/GCodeWriter.py b/plugins/GCodeWriter/GCodeWriter.py index 3cbed77aab..ec5d1ceaf8 100644 --- a/plugins/GCodeWriter/GCodeWriter.py +++ b/plugins/GCodeWriter/GCodeWriter.py @@ -6,7 +6,16 @@ from UM.Logger import Logger from UM.Application import Application import re #For escaping characters in the settings. - +## Writes g-code to a file. +# +# While this poses as a mesh writer, what this really does is take the g-code +# in the entire scene and write it to an output device. Since the g-code of a +# single mesh isn't separable from the rest what with rafts and travel moves +# and all, it doesn't make sense to write just a single mesh. +# +# So this plug-in takes the g-code that is stored in the root of the scene +# node tree, adds a bit of extra information about the profiles and writes +# that to the output device. class GCodeWriter(MeshWriter): ## The file format version of the serialised g-code. # From d602c0754fa0a89ed5b5545b75d6f7d582198e17 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 24 May 2016 03:00:16 +0200 Subject: [PATCH 248/705] Properly serialise all settings to g-code file This makes for ugly g-code files, true, but at least the functionality of saving settings is useful now: It's traceable. Could've implemented this somewhere else too, but this is fine for now. Contributes to issue CURA-1278. --- plugins/GCodeWriter/GCodeWriter.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plugins/GCodeWriter/GCodeWriter.py b/plugins/GCodeWriter/GCodeWriter.py index ec5d1ceaf8..d304f0d046 100644 --- a/plugins/GCodeWriter/GCodeWriter.py +++ b/plugins/GCodeWriter/GCodeWriter.py @@ -4,6 +4,7 @@ from UM.Mesh.MeshWriter import MeshWriter from UM.Logger import Logger from UM.Application import Application +from UM.Settings.InstanceContainer import InstanceContainer #To create a complete setting profile to store in the g-code. import re #For escaping characters in the settings. ## Writes g-code to a file. @@ -67,8 +68,11 @@ class GCodeWriter(MeshWriter): prefix = ";SETTING_" + str(GCodeWriter.version) + " " # The prefix to put before each line. prefix_length = len(prefix) - #TODO: This just serialises the container stack, which only indicates the IDs of the containers in that stack, not the settings themselves, making this about 9001x as useless as the fax functionality in Adobe Acrobat. - serialised = settings.serialize() + all_settings = InstanceContainer("G-code-imported-profile") #Create a new 'profile' with ALL settings so that the slice can be precisely reproduced. + all_settings.setDefinition(settings.getBottom()) + for key in settings.getAllKeys(): + all_settings.setProperty(key, "value", settings.getProperty(key, "value")) #Just copy everything over to the setting instance. + serialised = all_settings.serialize() # Escape characters that have a special meaning in g-code comments. pattern = re.compile("|".join(GCodeWriter.escape_characters.keys())) From b1d5cad89842c3474fe4508a51cc14000f0690fd Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 24 May 2016 11:43:57 +0200 Subject: [PATCH 249/705] Document QTbug Took a while to find! Contributes to issue CURA-1278. --- resources/qml/Settings/SettingView.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 6b09c8b9a3..65c7546d02 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -44,6 +44,7 @@ ScrollView property var settingDefinitionsModel: definitionsModel property var propertyProvider: provider + //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989 asynchronous: true source: From 332321b99119f7b0ebe96a11776bd6114c43d608 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 24 May 2016 11:50:39 +0200 Subject: [PATCH 250/705] Disable asynchronous loading of SettingItem when Qt Version < 5.5 --- resources/qml/Settings/SettingView.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 65c7546d02..0e99ecc4b7 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -45,7 +45,7 @@ ScrollView property var propertyProvider: provider //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989 - asynchronous: true + asynchronous: QT_VERSION_STR.split(".")[1] >= 5 source: { From c80455c6bca2d79a54b5a0225bb6e14afdc2f64d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 24 May 2016 15:04:08 +0200 Subject: [PATCH 251/705] Fix creating print job name Also fixed up the code style of that bit. Perhaps this should've been done in Python, but that is for later. Contributes to issue CURA-1278. --- resources/qml/Cura.qml | 2 +- resources/qml/JobSpecs.qml | 50 ++++++++++++++++++++++---------------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 733def1b81..52a8498f5e 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -813,7 +813,7 @@ UM.MainWindow base.visible = true; restart(); } - else if(UM.MachineManager.activeMachineInstance == "") + else if(Cura.MachineManager.activeMachineName == "") { addMachineDialog.firstRun = true; addMachineDialog.open(); diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml index fac4fd841d..60e2c6698e 100644 --- a/resources/qml/JobSpecs.qml +++ b/resources/qml/JobSpecs.qml @@ -7,15 +7,16 @@ import QtQuick.Controls.Styles 1.1 import QtQuick.Layouts 1.1 import UM 1.1 as UM +import Cura 1.0 as Cura Rectangle { id: base; property bool activity: Printer.getPlatformActivity; property string fileBaseName - property variant activeMachineInstance: UM.MachineManager.activeMachineInstance + property variant activeMachineName: Cura.MachineManager.activeMachineName - onActiveMachineInstanceChanged: + onActiveMachineNameChanged: { base.createFileName() } @@ -28,27 +29,34 @@ Rectangle { height: childrenRect.height color: "transparent" - function createFileName(){ - var splitMachineName = UM.MachineManager.activeMachineInstance.split(" ") - var abbrMachine = '' - for (var i = 0; i < splitMachineName.length; i++){ - if (splitMachineName[i].search(/ultimaker/i) != -1){ - abbrMachine += 'UM' - } - else{ - if (splitMachineName[i].charAt(0).search(/[0-9]/g) == -1) - abbrMachine += splitMachineName[i].charAt(0) - } - var regExpAdditives = /[0-9\+]/g; - var resultAdditives = splitMachineName[i].match(regExpAdditives); - if (resultAdditives != null){ - for (var j = 0; j < resultAdditives.length; j++){ - abbrMachine += resultAdditives[j] - - } + function createFileName() + { + var splitMachineName = Cura.MachineManager.activeMachineName.split(" "); + var abbrMachine = ''; + for (var i = 0; i < splitMachineName.length; i++) + { + if (splitMachineName[i].search(/ultimaker/i) != -1) + { + abbrMachine += 'UM'; + } + else + { + if (splitMachineName[i].charAt(0).search(/[0-9]/g) == -1) + { + abbrMachine += splitMachineName[i].charAt(0); } } - printJobTextfield.text = abbrMachine + '_' + base.fileBaseName + var regExpAdditives = /[0-9\+]/g; + var resultAdditives = splitMachineName[i].match(regExpAdditives); + if (resultAdditives != null) + { + for (var j = 0; j < resultAdditives.length; j++) + { + abbrMachine += resultAdditives[j]; + } + } + } + printJobTextfield.text = abbrMachine + '_' + base.fileBaseName; } Connections { From fd3788ba7c8f830daf5a71f071aef79e01e09c4f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 25 May 2016 11:06:48 +0200 Subject: [PATCH 252/705] Removed stray = sign. CURA-1278 CURA-1592 --- plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index e53b5d338b..67534222fb 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -153,7 +153,7 @@ Item { { if(text != "") { - listview.model.filter.label = = {"global_only":"False", "label": text} + listview.model.filter.label = {"global_only":"False", "label": text} } else { From 5f54d611cf3f9ab7de3bc485229f28bc2fb23513 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 25 May 2016 11:14:11 +0200 Subject: [PATCH 253/705] Per object settings filter now uses correct bool types (instead of strings) CURA-1278 --- plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index 67534222fb..48ed7caaa5 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -153,11 +153,11 @@ Item { { if(text != "") { - listview.model.filter.label = {"global_only":"False", "label": text} + listview.model.filter.label = {"global_only": false, "label": text} } else { - listview.model.filter = {"global_only":"False"} + listview.model.filter = {"global_only": false} } } } @@ -182,7 +182,7 @@ Item { containerId: Cura.MachineManager.activeDefinitionId filter: { - "global_only": "False" + "global_only": false } } delegate:Loader From 81cdb3fd8c5000b5fb8d3b1004476b7b55fcbf83 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 25 May 2016 11:28:58 +0200 Subject: [PATCH 254/705] Added wildcard to filtering CURA-1278 --- plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index 48ed7caaa5..9b78116d24 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -153,7 +153,7 @@ Item { { if(text != "") { - listview.model.filter.label = {"global_only": false, "label": text} + listview.model.filter = {"global_only": false, "label": "*" + text} } else { From 2e0205f174e3f778943f08978e051eaa752e283c Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 25 May 2016 11:21:33 +0200 Subject: [PATCH 255/705] Store the global container stack as an instance property This reduces the amount of function calls and makes it simpler to check for container existance --- cura/MachineManagerModel.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 0f45f0a7b1..b0fce98311 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -8,7 +8,10 @@ import UM.Settings class MachineManagerModel(QObject): def __init__(self, parent = None): super().__init__(parent) + + self._global_container_stack = None Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged) + self._onGlobalContainerChanged() ## When the global container is changed, active material probably needs to be updated. self.globalContainerChanged.connect(self.activeMaterialChanged) @@ -31,10 +34,16 @@ class MachineManagerModel(QObject): activeQualityChanged = pyqtSignal() def _onGlobalContainerChanged(self): - Preferences.getInstance().setValue("cura/active_machine", Application.getInstance().getGlobalContainerStack().getId()) - Application.getInstance().getGlobalContainerStack().containersChanged.connect(self._onInstanceContainersChanged) + if self._global_container_stack: + self._global_container_stack.containersChanged.disconnect(self._onInstanceContainersChanged) + + self._global_container_stack = Application.getInstance().getGlobalContainerStack() self.globalContainerChanged.emit() + if self._global_container_stack: + Preferences.getInstance().setValue("cura/active_machine", self._global_container_stack.getId()) + self._global_container_stack.containersChanged.connect(self._onInstanceContainersChanged) + def _onInstanceContainersChanged(self, container): container_type = container.getMetaDataEntry("type") if container_type == "material": From b1f887a70f846307ac9361a1dcd4b7bd4f613202 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 25 May 2016 11:22:59 +0200 Subject: [PATCH 256/705] Use the global stack instance variable and account for it potentially being None --- cura/MachineManagerModel.py | 117 +++++++++++++++++++++++------------- 1 file changed, 76 insertions(+), 41 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index b0fce98311..eb92aa422e 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -110,78 +110,111 @@ class MachineManagerModel(QObject): @pyqtProperty(str, notify = globalContainerChanged) def activeMachineName(self): - return Application.getInstance().getGlobalContainerStack().getName() + if self._global_container_stack: + return self._global_container_stack.getName() + + return "" @pyqtProperty(str, notify = globalContainerChanged) def activeMachineId(self): - return Application.getInstance().getGlobalContainerStack().getId() + if self._global_container_stack: + return self._global_container_stack.getId() + + return "" @pyqtProperty(str, notify = activeMaterialChanged) def activeMaterialName(self): - material = Application.getInstance().getGlobalContainerStack().findContainer({"type":"material"}) - if material: - return material.getName() + if self._global_container_stack: + material = self._global_container_stack.findContainer({"type":"material"}) + if material: + return material.getName() + + return "" @pyqtProperty(str, notify=activeMaterialChanged) def activeMaterialId(self): - material = Application.getInstance().getGlobalContainerStack().findContainer({"type": "material"}) - if material: - return material.getId() + if self._global_container_stack: + material = self._global_container_stack.findContainer({"type": "material"}) + if material: + return material.getId() + + return "" @pyqtProperty(str, notify=activeQualityChanged) def activeQualityName(self): - quality = Application.getInstance().getGlobalContainerStack().findContainer({"type": "quality"}) - if quality: - return quality.getName() + if self._global_container_stack: + quality = self._global_container_stack.findContainer({"type": "quality"}) + if quality: + return quality.getName() + return "" @pyqtProperty(str, notify=activeQualityChanged) def activeQualityId(self): - quality = Application.getInstance().getGlobalContainerStack().findContainer({"type": "quality"}) - if quality: - return quality.getId() + if self._global_container_stack: + quality = self._global_container_stack.findContainer({"type": "quality"}) + if quality: + return quality.getId() + return "" @pyqtSlot(str) def setActiveMaterial(self, material_id): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=material_id) - old_material = Application.getInstance().getGlobalContainerStack().findContainer({"type":"material"}) + if not containers or not self._global_container_stack: + return + + old_material = self._global_container_stack.findContainer({"type":"material"}) if old_material: - material_index = Application.getInstance().getGlobalContainerStack().getContainerIndex(old_material) - Application.getInstance().getGlobalContainerStack().replaceContainer(material_index, containers[0]) + material_index = self._global_container_stack.getContainerIndex(old_material) + self._global_container_stack.replaceContainer(material_index, containers[0]) @pyqtSlot(str) def setActiveVariant(self, variant_id): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=variant_id) - old_variant = Application.getInstance().getGlobalContainerStack().findContainer({"type": "variant"}) + if not containers or not self._global_container_stack: + return + + old_variant = self._global_container_stack.findContainer({"type": "variant"}) if old_variant: - variant_index = Application.getInstance().getGlobalContainerStack().getContainerIndex(old_variant) - Application.getInstance().getGlobalContainerStack().replaceContainer(variant_index, containers[0]) + variant_index = self._global_container_stack.getContainerIndex(old_variant) + self._global_container_stack.replaceContainer(variant_index, containers[0]) @pyqtSlot(str) def setActiveQuality(self, quality_id): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = quality_id) - old_quality = Application.getInstance().getGlobalContainerStack().findContainer({"type": "quality"}) + if not containers or not self._global_container_stack: + return + + old_quality = self._global_container_stack.findContainer({"type": "quality"}) if old_quality: - quality_index = Application.getInstance().getGlobalContainerStack().getContainerIndex(old_quality) - Application.getInstance().getGlobalContainerStack().replaceContainer(quality_index, containers[0]) + quality_index = self._global_container_stack.getContainerIndex(old_quality) + self._global_container_stack.replaceContainer(quality_index, containers[0]) @pyqtProperty(str, notify = activeVariantChanged) def activeVariantName(self): - variant = Application.getInstance().getGlobalContainerStack().findContainer({"type": "variant"}) - if variant: - return variant.getName() + if self._global_container_stack: + variant = self._global_container_stack.findContainer({"type": "variant"}) + if variant: + return variant.getName() + + return "" @pyqtProperty(str, notify = activeVariantChanged) def activeVariantId(self): - variant = Application.getInstance().getGlobalContainerStack().findContainer({"type": "variant"}) - if variant: - return variant.getId() + if self._global_container_stack: + variant = self._global_container_stack.findContainer({"type": "variant"}) + if variant: + return variant.getId() + + return "" @pyqtProperty(str, notify = globalContainerChanged) def activeDefinitionId(self): - definition = Application.getInstance().getGlobalContainerStack().getBottom() - if definition: - return definition.id - return None + if self._global_container_stack: + definition = self._global_container_stack.getBottom() + if definition: + return definition.id + + return "" @pyqtSlot(str, str) def renameMachine(self, machine_id, new_name): @@ -193,17 +226,19 @@ class MachineManagerModel(QObject): def removeMachine(self, machine_id): UM.Settings.ContainerRegistry.getInstance().removeContainer(machine_id) - @pyqtProperty(bool) + @pyqtProperty(bool, notify = globalContainerChanged) def hasMaterials(self): - # Todo: Still hardcoded. - # We should implement this properly when it's clear how a machine notifies us if it can handle materials - return True + if self._global_container_stack: + return self._global_container_stack.getMetaDataEntry("has_materials", False) - @pyqtProperty(bool) + return False + + @pyqtProperty(bool, notify = globalContainerChanged) def hasVariants(self): - # Todo: Still hardcoded. - # We should implement this properly when it's clear how a machine notifies us if it can handle variants - return True + if self._global_container_stack: + return self._global_container_stack.getMetaDataEntry("has_variants", False) + + return False def createMachineManagerModel(engine, script_engine): return MachineManagerModel() From 396f023bdf7bbde07b9f8e74b553a560d0076dfd Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 25 May 2016 11:23:23 +0200 Subject: [PATCH 257/705] Account for global container stack being None in the backend plugin --- plugins/CuraEngineBackend/CuraEngineBackend.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index cc0d1b1600..e7fb946bb6 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -57,7 +57,8 @@ class CuraEngineBackend(Backend): #When any setting property changed, call the _onSettingChanged function. #This function will then see if we need to start slicing. - Application.getInstance().getGlobalContainerStack().propertyChanged.connect(self._onSettingChanged) + if Application.getInstance().getGlobalContainerStack(): + Application.getInstance().getGlobalContainerStack().propertyChanged.connect(self._onSettingChanged) #When you update a setting and other settings get changed through inheritance, many propertyChanged signals are fired. #This timer will group them up, and only slice for the last setting changed signal. From 24210246eec01790fe668caf2a836d20460b766e Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 25 May 2016 11:23:49 +0200 Subject: [PATCH 258/705] Add preferred variant, material and quality to UM2+ definition --- resources/definitions/ultimaker2_plus.def.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/resources/definitions/ultimaker2_plus.def.json b/resources/definitions/ultimaker2_plus.def.json index 646b424c5c..9f68c2a16b 100644 --- a/resources/definitions/ultimaker2_plus.def.json +++ b/resources/definitions/ultimaker2_plus.def.json @@ -10,7 +10,10 @@ "category": "Ultimaker", "file_formats": "text/x-gcode", "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2Plusbackplate.png" + "platform_texture": "Ultimaker2Plusbackplate.png", + "preferred_variant": "ultimaker2_plus_0.4", + "preferred_material": "pla", + "preferred_quality": "high" }, "overrides": { From a1d48fd51151a28760476f2dbd1b041bedf98b02 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 25 May 2016 11:25:03 +0200 Subject: [PATCH 259/705] When creating a new container stack, add empty containers for things where we cannot find containers Additionally, record this information in the metadata of the stack --- cura/MachineManagerModel.py | 39 +++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index eb92aa422e..8354f3a140 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -63,34 +63,52 @@ class MachineManagerModel(QObject): def addMachine(self,name, definition_id): definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id=definition_id) if definitions: + definition = definitions[0] + new_global_stack = UM.Settings.ContainerStack(name) new_global_stack.addMetaDataEntry("type", "machine") UM.Settings.ContainerRegistry.getInstance().addContainer(new_global_stack) + empty_container = UM.Settings.ContainerRegistry.getInstance().getEmptyInstanceContainer() + + variants = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = definition.id) + if variants: + new_global_stack.addMetaDataEntry("has_variants", True) + + preferred_variant_id = definitions[0].getMetaDataEntry("preferred_variant") + variant_instance_container = empty_container + if preferred_variant_id: + preferred_variant_id = preferred_variant_id.lower() + container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = preferred_variant_id) + if container: + variant_instance_container = container[0] + + if variants and variant_instance_container == empty_container: + variant_instance_container = variants[0] + + materials = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "material", definition = definition.id) + if materials: + new_global_stack.addMetaDataEntry("has_materials", True) preferred_material_id = definitions[0].getMetaDataEntry("preferred_material") - material_instance_container = None + material_instance_container = empty_container if preferred_material_id: preferred_material_id = preferred_material_id.lower() container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = preferred_material_id) if container: material_instance_container = container[0] + if materials and material_instance_container == empty_container: + material_instance_container = materials[0] + preferred_quality_id = definitions[0].getMetaDataEntry("preferred_quality") - quality_instance_container = None + quality_instance_container = empty_container if preferred_quality_id: preferred_quality_id = preferred_quality_id.lower() container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = preferred_quality_id) if container: quality_instance_container = container[0] - ## DEBUG CODE - variant_instance_container = UM.Settings.InstanceContainer("test_variant") - variant_instance_container.addMetaDataEntry("type", "variant") - variant_instance_container.setDefinition(definitions[0]) - - UM.Settings.ContainerRegistry.getInstance().addContainer(variant_instance_container) - current_settings_instance_container = UM.Settings.InstanceContainer(name + "_current_settings") current_settings_instance_container.addMetaDataEntry("machine", name) current_settings_instance_container.addMetaDataEntry("type", "user") @@ -99,9 +117,10 @@ class MachineManagerModel(QObject): # If a definition is found, its a list. Should only have one item. new_global_stack.addContainer(definitions[0]) + if variant_instance_container: + new_global_stack.addContainer(variant_instance_container) if material_instance_container: new_global_stack.addContainer(material_instance_container) - new_global_stack.addContainer(variant_instance_container) if quality_instance_container: new_global_stack.addContainer(quality_instance_container) new_global_stack.addContainer(current_settings_instance_container) From e29cc5e699d70476936f652710964935d9d92025 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 25 May 2016 11:26:19 +0200 Subject: [PATCH 260/705] Create machine-specific material containers for machine specific overrides in XML material files --- .../XmlMaterialProfile/XmlMaterialProfile.py | 67 ++++++++++++++++--- 1 file changed, 59 insertions(+), 8 deletions(-) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 5566301a09..50c39238fd 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -2,10 +2,16 @@ # Cura is released under the terms of the AGPLv3 or higher. import math +import copy import xml.etree.ElementTree as ET +from UM.Logger import Logger + import UM.Settings +# The namespace is prepended to the tag name but between {}. +# We are only interested in the actual tag name, so discard everything +# before the last } def _tag_without_namespace(element): return element.tag[element.tag.rfind("}") + 1:] @@ -17,7 +23,6 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): raise NotImplementedError("Writing material profiles has not yet been implemented") def deserialize(self, serialized): - print("deserialize material profile") data = ET.fromstring(serialized) self.addMetaDataEntry("type", "material") @@ -27,9 +32,7 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): metadata = data.iterfind("./um:metadata/*", self.__namespaces) for entry in metadata: - # The namespace is prepended to the tag name but between {}. - # We are only interested in the actual tag name. - tag_name = entry.tag[entry.tag.rfind("}") + 1:] + tag_name = _tag_without_namespace(entry) if tag_name == "name": brand = entry.find("./um:brand", self.__namespaces) @@ -47,7 +50,7 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): property_values = {} properties = data.iterfind("./um:properties/*", self.__namespaces) for entry in properties: - tag_name = entry.tag[entry.tag.rfind("}") + 1:] + tag_name = _tag_without_namespace(entry) property_values[tag_name] = entry.text diameter = float(property_values.get("diameter", 2.85)) # In mm @@ -66,12 +69,50 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): self.addMetaDataEntry("properties", property_values) + global_setting_values = {} settings = data.iterfind("./um:settings/um:setting", self.__namespaces) for entry in settings: - tag_name = _tag_without_namespace(entry) + key = entry.get("key") + if key in self.__material_property_setting_map: + self.setProperty(self.__material_property_setting_map[key], "value", entry.text, self._definition) + global_setting_values[key] = entry.text + + machines = data.iterfind("./um:settings/um:machine", self.__namespaces) + for machine in machines: + machine_setting_values = {} + settings = machine.iterfind("./um:setting", self.__namespaces) + for entry in settings: + key = entry.get("key") + if key in self.__material_property_setting_map: + machine_setting_values[self.__material_property_setting_map[key]] = entry.text + + identifiers = machine.iterfind("./um:machine_identifier", self.__namespaces) + for identifier in identifiers: + machine_id = self.__product_id_map.get(identifier.get("product"), None) + if machine_id is None: + Logger.log("w", "Cannot create material for unknown machine %s", machine_id) + continue + + definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = machine_id) + if not definitions: + Logger.log("w", "No definition found for machine ID %s", machine_id) + continue + + new_material = XmlMaterialProfile(self.id + "_" + machine_id) + new_material.setName(self.getName()) + new_material.setMetaData(self.getMetaData()) + new_material.setDefinition(definitions[0]) + + for key, value in global_setting_values.items(): + new_material.setProperty(key, "value", value, definitions[0]) + + for key, value in machine_setting_values.items(): + new_material.setProperty(key, "value", value, definitions[0]) + + new_material._dirty = False + + UM.Settings.ContainerRegistry.getInstance().addContainer(new_material) - if tag_name in self.__material_property_setting_map: - self.setProperty(self.__material_property_setting_map[tag_name], "value", entry.text) __material_property_setting_map = { "print temperature": "material_print_temperature", @@ -79,6 +120,16 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): "standby temperature": "material_standby_temperature", } + __product_id_map = { + "Ultimaker2": "ultimaker2", + "Ultimaker2+": "ultimaker2_plus", + "Ultimaker2go": "ultimaker2_go", + "Ultimaker2extended": "ultimaker2_extended", + "Ultimaker2extended+": "ultimaker2_extended_plus", + "Ultimaker Original": "ultimaker_original", + "Ultimaker Original+": "ultimaker_original_plus" + } + __namespaces = { "um": "http://www.ultimaker.com/material" } From 2654033fae9847f5c321a8a93379433039085825 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 25 May 2016 11:26:51 +0200 Subject: [PATCH 261/705] Show the add machine dialog when we do not have an active machine --- resources/qml/Cura.qml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 52a8498f5e..42098e9883 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -813,9 +813,8 @@ UM.MainWindow base.visible = true; restart(); } - else if(Cura.MachineManager.activeMachineName == "") + else if(Cura.MachineManager.activeMachineId == null || Cura.MachineManager.activeMachineId == "") { - addMachineDialog.firstRun = true; addMachineDialog.open(); } } From b2a8810d04cc927c9fb7dab05b5b3f1abfd83945 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 25 May 2016 11:28:29 +0200 Subject: [PATCH 262/705] Filter available materials by the machine definition Since we now have some machine-specific materials --- resources/qml/Preferences/MaterialsPage.qml | 2 +- resources/qml/SidebarHeader.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index f1f3432a41..4ebe281c08 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -13,7 +13,7 @@ UM.ManagementPage title: catalog.i18nc("@title:tab", "Materials"); - model: UM.InstanceContainersModel { filter: { "type": "material" } } + model: UM.InstanceContainersModel { filter: { "type": "material", "definition": Cura.MachineManager.activeDefinitionId } } /* onAddObject: { var selectedMaterial = UM.MaterialManager.createProfile(); base.selectMaterial(selectedMaterial); } onRemoveObject: confirmDialog.open(); diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 5284178ba7..d8bc4291bb 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -197,7 +197,7 @@ Item id: materialSelectionInstantiator model: UM.InstanceContainersModel { - filter: {"type": "material"} + filter: { "type": "material", "definition": Cura.MachineManager.activeDefinitionId } } MenuItem { From 81d0b34f202e19adac3dd23586a8abe15e851a20 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 25 May 2016 11:28:53 +0200 Subject: [PATCH 263/705] Update example XML material to use the right product names --- resources/materials/generic_pla.xml.fdm_material | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/resources/materials/generic_pla.xml.fdm_material b/resources/materials/generic_pla.xml.fdm_material index b64ecdc61b..a4fe02c195 100644 --- a/resources/materials/generic_pla.xml.fdm_material +++ b/resources/materials/generic_pla.xml.fdm_material @@ -16,7 +16,6 @@ Generic PLA profile. Serves as an example file, data in this file is not correct 1.3 2.85 - 750 210 @@ -24,9 +23,8 @@ Generic PLA profile. Serves as an example file, data in this file is not correct 175 - - - + + 150 @@ -36,6 +34,7 @@ Generic PLA profile. Serves as an example file, data in this file is not correct + 150 80 From ab0d34d9acd4de2673a76327fa849d6a9ec2df3b Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 25 May 2016 11:29:15 +0200 Subject: [PATCH 264/705] Add layer height to high quality profile so we have something that changes --- resources/quality/high.inst.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/quality/high.inst.cfg b/resources/quality/high.inst.cfg index 89dcd4c9bc..0329e9ffe1 100644 --- a/resources/quality/high.inst.cfg +++ b/resources/quality/high.inst.cfg @@ -7,3 +7,4 @@ definition = fdmprinter type = quality [values] +layer_height = 0.06 From 9bb4917ae74b3d6d129e7e215976964dffa6f749 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 25 May 2016 11:30:47 +0200 Subject: [PATCH 265/705] Import Cura in materials preferences page so we can use the active definition id --- resources/qml/Preferences/MaterialsPage.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index 4ebe281c08..03ede39a5c 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -6,6 +6,7 @@ import QtQuick.Controls 1.1 import QtQuick.Dialogs 1.2 import UM 1.2 as UM +import Cura 1.0 as Cura UM.ManagementPage { From 6522aae915cccb2c2b4c82635dd99377783e326c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 25 May 2016 11:50:58 +0200 Subject: [PATCH 266/705] Improve slice trigger documentation Contributes to issue CURA-1278. --- plugins/CuraEngineBackend/CuraEngineBackend.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index e7fb946bb6..aa42a08393 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -55,10 +55,9 @@ class CuraEngineBackend(Backend): self._onActiveViewChanged() self._stored_layer_data = [] - #When any setting property changed, call the _onSettingChanged function. - #This function will then see if we need to start slicing. + #Triggers for when to (re)start slicing: if Application.getInstance().getGlobalContainerStack(): - Application.getInstance().getGlobalContainerStack().propertyChanged.connect(self._onSettingChanged) + Application.getInstance().getGlobalContainerStack().propertyChanged.connect(self._onSettingChanged) #Note: Only starts slicing when the value changed. #When you update a setting and other settings get changed through inheritance, many propertyChanged signals are fired. #This timer will group them up, and only slice for the last setting changed signal. From 2683907121eb7384016dfb04603388cb0dfb12e4 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 25 May 2016 13:57:16 +0200 Subject: [PATCH 267/705] Show Ultimaker Original and Ultimaker Original + in Add Machine wizard CURA-1278 --- resources/definitions/ultimaker_original.def.json | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/definitions/ultimaker_original.def.json b/resources/definitions/ultimaker_original.def.json index f445057860..1dbdb95d8c 100644 --- a/resources/definitions/ultimaker_original.def.json +++ b/resources/definitions/ultimaker_original.def.json @@ -4,6 +4,7 @@ "name": "Ultimaker Original", "inherits": "ultimaker", "metadata": { + "visible": true, "author": "Ultimaker", "manufacturer": "Ultimaker", "category": "Ultimaker", From f349221fa6ffa48045ddee4b69fef19cffb24cd2 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 25 May 2016 14:56:05 +0200 Subject: [PATCH 268/705] Make simple mode extruder selection work with settings_rework CURA-1278 & CURA-790 --- resources/qml/SidebarSimple.qml | 67 ++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 21 deletions(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 9c68c2ef81..56ceb39b18 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -268,15 +268,13 @@ Item function populateExtruderModel() { -// extruderModel.clear() -// var extruder_count = UM.MachineManager.getSettingValue("machine_extruder_count"); -// for(var extruder = 0; extruder < extruder_count ; extruder++) { -// extruderModel.append({ -// name: catalog.i18nc("@label", "Extruder %1").arg(extruder), -// text: catalog.i18nc("@label", "Extruder %1").arg(extruder), -// value: extruder -// }) -// } + extruderModel.clear(); + for(var extruder = 0; extruder < machineExtruderCount.properties.value ; extruder++) { + print(catalog.i18nc("@label", "Extruder %1").arg(extruder)); + extruderModel.append({ + text: catalog.i18nc("@label", "Extruder %1").arg(extruder) + }) + } } Rectangle { @@ -286,8 +284,7 @@ Item anchors.left: parent.left width: parent.width height: childrenRect.height - // Use both UM.ActiveProfile and UM.MachineManager to force UM.MachineManager.getSettingValue() to be reevaluated -// visible: UM.ActiveProfile.settingValues.getValue("machine_extruder_count") || (UM.MachineManager.getSettingValue("machine_extruder_count") > 1) + visible: machineExtruderCount.properties.value > 1 Label { id: mainExtruderLabel @@ -305,9 +302,9 @@ Item anchors.top: parent.top anchors.left: supportExtruderLabel.right style: UM.Theme.styles.combobox -// currentIndex: UM.ActiveProfile.valid ? UM.ActiveProfile.settingValues.getValue("extruder_nr") : 0 + currentIndex: mainExtruderNr.properties.value onActivated: { -// UM.MachineManager.setSettingValue("extruder_nr", index) + mainExtruderNr.setPropertyValue("value", index) } } @@ -328,9 +325,9 @@ Item anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.left: supportExtruderLabel.right style: UM.Theme.styles.combobox -// currentIndex: UM.ActiveProfile.valid ? UM.ActiveProfile.settingValues.getValue("support_extruder_nr") : 0 + currentIndex: supportExtruderNr.properties.value onActivated: { - UM.MachineManager.setSettingValue("support_extruder_nr", index) + supportExtruderNr.setPropertyValue("value", index) } } @@ -338,12 +335,12 @@ Item id: extruderModel Component.onCompleted: populateExtruderModel() } -// Connections -// { -// id: machineChange -// target: UM.MachineManager -// onActiveMachineInstanceChanged: populateExtruderModel() -// } + Connections + { + id: machineChange + target: Cura.MachineManager + onGlobalContainerChanged: populateExtruderModel() + } } Rectangle { @@ -400,4 +397,32 @@ Item watchedProperties: [ "value" ] storeIndex: 0 } + + UM.SettingPropertyProvider + { + id: machineExtruderCount + + containerStackId: Cura.MachineManager.activeMachineId + key: "machine_extruder_count" + watchedProperties: [ "value" ] + storeIndex: 0 + } + UM.SettingPropertyProvider + { + id: supportExtruderNr + + containerStackId: Cura.MachineManager.activeMachineId + key: "support_extruder_nr" + watchedProperties: [ "value" ] + storeIndex: 0 + } + UM.SettingPropertyProvider + { + id: mainExtruderNr + + containerStackId: Cura.MachineManager.activeMachineId + key: "extruder_nr" + watchedProperties: [ "value" ] + storeIndex: 0 + } } From 6305c70820f19dc3aa29cadc314655cdb78b3635 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 25 May 2016 15:12:56 +0200 Subject: [PATCH 269/705] Remove old version of FDM printer base file --- resources/machines/fdmprinter.json | 2403 ---------------------------- 1 file changed, 2403 deletions(-) delete mode 100644 resources/machines/fdmprinter.json diff --git a/resources/machines/fdmprinter.json b/resources/machines/fdmprinter.json deleted file mode 100644 index c85c46f786..0000000000 --- a/resources/machines/fdmprinter.json +++ /dev/null @@ -1,2403 +0,0 @@ -{ - "id": "fdmprinter", - "visible": false, - "version": 1, - "name": "FDM Printer Base Description", - "author": "Ultimaker B.V.", - "manufacturer": "Ultimaker", - "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g", - - "add_pages": [], - - "machine_settings": { - "machine_show_variants": { - "description": "Wether to show the different variants of this machine, which are described in separate json files.", - "default": false - }, - "machine_start_gcode": { - "description": "Gcode commands to be executed at the very start - separated by \\n.", - "default": "G28 ; Home\nG1 Z15.0 F6000 ;move the platform down 15mm\n;Prime the extruder\nG92 E0\nG1 F200 E3\nG92 E0", - "global_only": true - }, - "machine_end_gcode": { - "description": "Gcode commands to be executed at the very end - separated by \\n.", - "default": "M104 S0\nM140 S0\n;Retract the filament\nG92 E1\nG1 E-1 F300\nG28 X0 Y0\nM84", - "global_only": true - }, - "material_bed_temp_wait": { - "description": "Whether to insert a command to wait until the bed temperature is reached at the start.", - "default": true, - "global_only": true - }, - "material_print_temp_wait": { - "description": "Whether to insert a command to wait until the nozzle temperatures are reached at the start.", - "default": true, - "global_only": true - }, - "material_print_temp_prepend": { - "description": "Whether to include nozzle temperature commands at the start of the gcode. When the start_gcode already contains nozzle temperature commands Cura frontend will automatically disable this setting.", - "default": true, - "global_only": true - }, - "material_bed_temp_prepend": { - "description": "Whether to include bed temperature commands at the start of the gcode. When the start_gcode already contains bed temperature commands Cura frontend will automatically disable this setting.", - "default": true, - "global_only": true - }, - "machine_width": { - "description": "The width (X-direction) of the printable area.", - "default": 100, - "global_only": true - }, - "machine_depth": { - "description": "The depth (Y-direction) of the printable area.", - "default": 100, - "global_only": true - }, - "machine_height": { - "description": "The height (Z-direction) of the printable area.", - "default": 100, - "global_only": true - }, - "machine_heated_bed": { - "description": "Whether the machine has a heated bed present.", - "default": false, - "global_only": true - }, - "machine_center_is_zero": { - "description": "Whether the X/Y coordinates of the zero position of the printer is at the center of the printable area.", - "default": false, - "global_only": true - }, - "machine_extruder_count": { - "description": "Number of extruder trains. An extruder train is the combination of a feeder, bowden tube, and nozzle.", - "default": 1, - "global_only": true - }, - "machine_nozzle_tip_outer_diameter": { - "description": "The outer diameter of the tip of the nozzle.", - "default": 1, - "SEE_machine_extruder_trains": true, - "global_only": true - }, - "machine_nozzle_head_distance": { - "description": "The height difference between the tip of the nozzle and the lowest part of the print head.", - "default": 3, - "SEE_machine_extruder_trains": true, - "global_only": true - }, - "machine_nozzle_expansion_angle": { - "description": "The angle between the horizontal plane and the conical part right above the tip of the nozzle.", - "default": 45, - "SEE_machine_extruder_trains": true, - "global_only": true - }, - "machine_heat_zone_length": { - "description": "The distance from the tip of the nozzle in which heat from the nozzle is transfered to the filament.", - "default": 16, - "SEE_machine_extruder_trains": true, - "global_only": true - }, - "machine_nozzle_heat_up_speed": { - "description": "The speed (°C/s) by which the nozzle heats up averaged over the window of normal printing temperatures and the standby temperature.", - "default": 2.0, - "SEE_machine_extruder_trains": true, - "global_only": true - }, - "machine_nozzle_cool_down_speed": { - "description": "The speed (°C/s) by which the nozzle cools down averaged over the window of normal printing temperatures and the standby temperature.", - "default": 2.0, - "SEE_machine_extruder_trains": true, - "global_only": true - }, - "machine_gcode_flavor": { - "description": "The type of gcode to be generated.", - "default": "RepRap", - "global_only": true - }, - "machine_disallowed_areas": { - "description": "A list of polygons with areas the print head is not allowed to enter.", - "type": "polygons", - "default": [], - "global_only": true - }, - "machine_head_polygon": { - "description": "A 2D silhouette of the print head (fan caps excluded).", - "type": "polygon", - "default": [ - [ - -1, - 1 - ], - [ - -1, - -1 - ], - [ - 1, - -1 - ], - [ - 1, - 1 - ] - ], - "global_only": true - }, - "machine_head_with_fans_polygon": { - "description": "A 2D silhouette of the print head (fan caps included).", - "type": "polygon", - "default": [ - [ - -20, - 10 - ], - [ - 10, - 10 - ], - [ - 10, - -10 - ], - [ - -20, - -10 - ] - ], - "global_only": true - }, - "gantry_height": { - "description": "The height difference between the tip of the nozzle and the gantry system (X and Y axes).", - "default": 99999999999, - "global_only": true - } - }, - "categories": { - "machine": { - "label": "Machine", - "visible": true, - "icon": "category_machine", - "settings": { - "machine_nozzle_size": { - "label": "Nozzle Diameter", - "description": "The inner diameter of the nozzle. Change this setting when using a non-standard nozzle size.", - "unit": "mm", - "type": "float", - "default": 0.4, - "min_value": "0.001", - "max_value_warning": "10", - "visible": false - } - }, - "global_only": true - }, - "resolution": { - "label": "Quality", - "visible": true, - "icon": "category_layer_height", - "settings": { - "layer_height": { - "label": "Layer Height", - "description": "The height of each layer in mm. Higher values produce faster prints in lower resolution, lower values produce slower prints in higher resolution.", - "unit": "mm", - "type": "float", - "default": 0.1, - "min_value": "0.001", - "min_value_warning": "0.04", - "max_value_warning": "0.8 * machine_nozzle_size", - "global_only": "True" - }, - "layer_height_0": { - "label": "Initial Layer Height", - "description": "The height of the initial layer in mm. A thicker initial layer makes adhesion to the build plate easier.", - "unit": "mm", - "type": "float", - "default": 0.3, - "min_value": "0.001", - "min_value_warning": "0.04", - "max_value_warning": "0.8 * machine_nozzle_size", - "visible": false, - "global_only": "True" - }, - "line_width": { - "label": "Line Width", - "description": "Width of a single line. Generally, the width of each line should correspond to the width of the nozzle. However, slightly reducing this value could produce better prints.", - "unit": "mm", - "min_value": "0.0001", - "min_value_warning": "0.2", - "max_value_warning": "2 * machine_nozzle_size", - "default": 0.4, - "type": "float", - "visible": false, - "inherit_function": "machine_nozzle_size", - "children": { - "wall_line_width": { - "label": "Wall Line Width", - "description": "Width of a single wall line.", - "unit": "mm", - "min_value": "0.0001", - "min_value_warning": "0.2", - "max_value_warning": "5", - "default": 0.4, - "type": "float", - "visible": false, - "children": { - "wall_line_width_0": { - "label": "Outer Wall Line Width", - "description": "Width of the outermost wall line. By lowering this value, higher levels of detail can be printed.", - "unit": "mm", - "min_value": "0.0001", - "min_value_warning": "0.2", - "max_value_warning": "5", - "default": 0.4, - "type": "float", - "visible": false - }, - "wall_line_width_x": { - "label": "Inner Wall(s) Line Width", - "description": "Width of a single wall line for all wall lines except the outermost one.", - "unit": "mm", - "min_value": "0.0001", - "min_value_warning": "0.2", - "max_value_warning": "5", - "default": 0.4, - "type": "float", - "visible": false - } - } - }, - "skin_line_width": { - "label": "Top/bottom Line Width", - "description": "Width of a single top/bottom line.", - "unit": "mm", - "min_value": "0.0001", - "min_value_warning": "0.2", - "max_value_warning": "5", - "default": 0.4, - "type": "float", - "visible": false - }, - "infill_line_width": { - "label": "Infill Line Width", - "description": "Width of a single infill line.", - "unit": "mm", - "min_value": "0.0001", - "min_value_warning": "0.2", - "max_value_warning": "5", - "default": 0.4, - "type": "float", - "visible": false - }, - "skirt_line_width": { - "label": "Skirt Line Width", - "description": "Width of a single skirt line.", - "unit": "mm", - "min_value": "0.0001", - "min_value_warning": "0.2", - "max_value_warning": "5", - "default": 0.4, - "type": "float", - "visible": false, - "global_only": true - }, - "support_line_width": { - "label": "Support Line Width", - "description": "Width of a single support structure line.", - "unit": "mm", - "min_value": "0.0001", - "min_value_warning": "0.2", - "max_value_warning": "5", - "default": 0.4, - "type": "float", - "visible": false, - "enabled": "support_enable", - "global_only": true - }, - "support_roof_line_width": { - "label": "Support Roof Line Width", - "description": "Width of a single support roof line.", - "unit": "mm", - "default": 0.4, - "min_value": "0.0001", - "max_value_warning": "machine_nozzle_size * 2", - "type": "float", - "visible": false, - "enabled": "support_roof_enable", - "global_only": true - } - } - } - } - }, - "shell": { - "label": "Shell", - "visible": true, - "icon": "category_shell", - "settings": { - "wall_thickness": { - "label": "Wall Thickness", - "description": "The thickness of the outside walls in the horizontal direction. This value divided by the wall line width defines the number of walls.", - "unit": "mm", - "default": 0.8, - "min_value": "0", - "min_value_warning": "line_width", - "max_value_warning": "5 * line_width", - "type": "float", - "visible": true, - "children": { - "wall_line_count": { - "label": "Wall Line Count", - "description": "The number of walls. When calculated by the wall thickness, this value is rounded to a whole number.", - "default": 2, - "min_value": "0", - "type": "int", - "visible": false, - "inherit_function": "1 if magic_spiralize else max(1, round((wall_thickness - wall_line_width_0) / wall_line_width_x) + 1)" - } - } - }, - "top_bottom_thickness": { - "label": "Top/Bottom Thickness", - "description": "The thickness of the top/bottom layers in the print. This value divided by the layer height defines the number of top/bottom layers.", - "unit": "mm", - "default": 0.8, - "min_value": "0", - "max_value": "5", - "min_value_warning": "0.6", - "type": "float", - "visible": true, - "children": { - "top_thickness": { - "label": "Top Thickness", - "description": "The thickness of the top layers in the print. This value divided by the layer height defines the number of top layers.", - "unit": "mm", - "default": 0.8, - "min_value": "0", - "max_value_warning": "100", - "type": "float", - "visible": false, - "children": { - "top_layers": { - "label": "Top Layers", - "description": "The number of top layers. When calculated by the top thickness, this value is rounded to a whole number.", - "default": 8, - "min_value": "0", - "max_value_warning": "100", - "type": "int", - "visible": false, - "inherit_function": "0 if infill_sparse_density == 100 else math.ceil(round(parent_value / layer_height, 4))" - } - } - }, - "bottom_thickness": { - "label": "Bottom Thickness", - "description": "The thickness of the bottom layers in the print. This value divided by the layer height defines the number of bottom layers.", - "unit": "mm", - "default": 0.6, - "min_value": "0", - "type": "float", - "visible": false, - "children": { - "bottom_layers": { - "label": "Bottom Layers", - "description": "The number of bottom layers. When calculated by the bottom thickness, this value is rounded to a whole number.", - "min_value": "0", - "default": 6, - "type": "int", - "visible": false, - "inherit_function": "999999 if infill_sparse_density == 100 else math.ceil(round(parent_value / layer_height, 4))" - } - } - } - } - }, - "top_bottom_pattern": { - "label": "Top/Bottom Pattern", - "description": "The pattern of the top/bottom layers.", - "type": "enum", - "options": { - "lines": "Lines", - "concentric": "Concentric", - "zigzag": "Zig Zag" - }, - "default": "lines", - "visible": false - }, - "wall_0_inset": { - "label": "Outer Wall Inset", - "description": "Inset applied to the path of the outer wall. If the outer wall is smaller than the nozzle, and printed after the inner walls, use this offset to get the hole in the nozzle to overlap with the inner walls instead of the outside of the object.", - "unit": "mm", - "type": "float", - "default": 0.0, - "inherit_function": "(machine_nozzle_size - wall_line_width_0) / 2 if wall_line_width_0 < machine_nozzle_size else 0", - "min_value_warning": "0", - "max_value_warning": "machine_nozzle_size", - "visible": false - }, - "alternate_extra_perimeter": { - "label": "Alternate Extra Wall", - "description": "Prints an extra wall at every other layer. This way infill gets caught between these extra walls, resulting in stronger prints.", - "type": "boolean", - "default": false, - "visible": false, - "inherit": false - }, - "travel_compensate_overlapping_walls_enabled": { - "label": "Compensate Wall Overlaps", - "description": "Compensate the flow for parts of a wall being printed where there is already a wall in place.", - "type": "boolean", - "default": true, - "visible": false, - "children": { - "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": "boolean", - "default": true, - "visible": false, - "inherit_function": "parent_value" - }, - "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": "boolean", - "default": true, - "visible": false, - "inherit_function": "parent_value" - } - } - }, - "xy_offset": { - "label": "Horizontal Expansion", - "description": "Amount of offset applied to all polygons in each layer. Positive values can compensate for too big holes; negative values can compensate for too small holes.", - "unit": "mm", - "type": "float", - "min_value_warning": "-10", - "max_value_warning": "10", - "default": 0, - "visible": false - }, - "z_seam_type": { - "label": "Z Seam Alignment", - "description": "Starting point of each path in a layer. When paths in consecutive layers start at the same point a vertical seam may show on the print. When aligning these at the back, the seam is easiest to remove. When placed randomly the inaccuracies at the paths' start will be less noticeable. When taking the shortest path the print will be quicker.", - "type": "enum", - "options": { - "back": "Back", - "shortest": "Shortest", - "random": "Random" - }, - "default": "shortest", - "visible": false - }, - "skin_no_small_gaps_heuristic": { - "label": "Ignore Small Z Gaps", - "description": "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such case, disable the setting.", - "type": "boolean", - "default": true, - "visible": false - } - } - }, - "infill": { - "label": "Infill", - "visible": true, - "icon": "category_infill", - "settings": { - "infill_sparse_density": { - "label": "Infill Density", - "description": "Adjusts the density of infill of the print.", - "unit": "%", - "type": "float", - "default": 20, - "min_value": "0", - "max_value_warning": "100", - "children": { - "infill_line_distance": { - "label": "Infill Line Distance", - "description": "Distance between the printed infill lines. This setting is calculated by the infill density and the infill line width.", - "unit": "mm", - "type": "float", - "default": 2, - "min_value": "0", - "visible": false, - "inherit_function": "0 if infill_sparse_density == 0 else (infill_line_width * 100) / infill_sparse_density * (2 if infill_pattern == \"grid\" else (3 if infill_pattern == \"triangles\" else 1))" - } - } - }, - "infill_pattern": { - "label": "Infill Pattern", - "description": "The pattern of the infill material of the print. The line and zig zag infill swap direction on alternate layers, reducing material cost. The grid, triangle and concentric patterns are fully printed every layer.", - "type": "enum", - "visible": false, - "options": { - "grid": "Grid", - "lines": "Lines", - "triangles": "Triangles", - "concentric": "Concentric", - "zigzag": "Zig Zag" - }, - "default": "grid", - "inherit_function": "'lines' if infill_sparse_density > 25 else 'grid'" - }, - "infill_overlap": { - "label": "Infill Overlap Percentage", - "description": "The amount of overlap between the infill and the walls. A slight overlap allows the walls to connect firmly to the infill.", - "unit": "%", - "type": "float", - "default": 10, - "inherit_function": "10 if infill_sparse_density < 95 and infill_pattern != \"concentric\" else 0", - "min_value_warning": "-50", - "max_value_warning": "100", - "visible": false, - "enabled": "infill_pattern != \"concentric\"", - "children": { - "infill_overlap_mm": { - "label": "Infill Overlap", - "description": "The amount of overlap between the infill and the walls. A slight overlap allows the walls to connect firmly to the infill.", - "unit": "mm", - "type": "float", - "default": 0.04, - "min_value_warning": "-0.5 * machine_nozzle_size", - "max_value_warning": "machine_nozzle_size", - "inherit_function": "infill_line_width * parent_value / 100 if infill_sparse_density < 95 and infill_pattern != \"concentric\" else 0", - "visible": false, - "enabled": "infill_pattern != \"concentric\"" - } - } - }, - "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": "%", - "type": "float", - "default": 5, - "min_value_warning": "-50", - "max_value_warning": "100", - "inherit_function": "5 if top_bottom_pattern != \"concentric\" else 0", - "visible": false, - "enabled": "top_bottom_pattern != \"concentric\"", - "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", - "type": "float", - "default": 0.02, - "min_value_warning": "-0.5 * machine_nozzle_size", - "max_value_warning": "machine_nozzle_size", - "inherit_function": "skin_line_width * parent_value / 100 if top_bottom_pattern != \"concentric\" else 0", - "visible": false, - "enabled": "top_bottom_pattern != \"concentric\"" - } - } - }, - "infill_wipe_dist": { - "label": "Infill Wipe Distance", - "description": "Distance of a travel move inserted after every infill line, to make the infill stick to the walls better. This option is similar to infill overlap, but without extrusion and only on one end of the infill line.", - "unit": "mm", - "type": "float", - "default": 0.04, - "inherit_function": "wall_line_width_0 / 4 if wall_line_count == 1 else wall_line_width_x / 4", - "min_value_warning": "0", - "max_value_warning": "machine_nozzle_size", - "visible": false - }, - "infill_sparse_thickness": { - "label": "Infill Layer Thickness", - "description": "The thickness per layer of infill material. This value should always be a multiple of the layer height and is otherwise rounded.", - "unit": "mm", - "type": "float", - "default": 0.1, - "min_value": "0.0001", - "max_value_warning": "0.32", - "max_value": "layer_height * 8", - "visible": false, - "inherit_function": "layer_height" - }, - "infill_before_walls": { - "label": "Infill Before Walls", - "description": "Print the infill before printing the walls. Printing the walls first may lead to more accurate walls, but overhangs print worse. Printing the infill first leads to sturdier walls, but the infill pattern might sometimes show through the surface.", - "type": "boolean", - "default": true, - "visible": false - } - } - }, - "material": { - "label": "Material", - "visible": true, - "icon": "category_material", - "settings": { - "material_flow_dependent_temperature": { - "label": "Auto Temperature", - "description": "Change the temperature for each layer automatically with the average flow speed of that layer.", - "type": "boolean", - "default": false, - "visible": false, - "enabled": "False", - "global_only": true - }, - "material_print_temperature": { - "label": "Printing Temperature", - "description": "The temperature used for printing. Set at 0 to pre-heat the printer manually.", - "unit": "°C", - "type": "float", - "default": 210, - "min_value": "0", - "max_value_warning": "260", - "enabled": "not (material_flow_dependent_temperature)" - }, - "material_flow_temp_graph": { - "label": "Flow Temperature Graph", - "description": "Data linking material flow (in mm3 per second) to temperature (degrees Celsius).", - "unit": "", - "type": "string", - "default": "[[3.5,200],[7.0,240]]", - "enabled": "False", - "enabled_before_removal": "material_flow_dependent_temperature", - "global_only": true - }, - "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", - "type": "float", - "default": 0.5, - "min_value": "0", - "max_value_warning": "10.0", - "global_only": "True", - "enabled": "False", - "enabled_before_removal": "material_flow_dependent_temperature or machine_extruder_count > 1", - "visible": false - }, - "material_bed_temperature": { - "label": "Bed Temperature", - "description": "The temperature used for the heated bed. Set at 0 to pre-heat the printer manually.", - "unit": "°C", - "type": "float", - "default": 60, - "min_value": "0", - "max_value_warning": "260", - "enabled": "machine_heated_bed", - "global_only": "True" - }, - "material_diameter": { - "label": "Diameter", - "description": "Adjusts the diameter of the filament used. Match this value with the diameter of the used filament.", - "unit": "mm", - "type": "float", - "default": 2.85, - "min_value": "0.0001", - "min_value_warning": "0.4", - "max_value_warning": "3.5", - "global_only": "True" - }, - "material_flow": { - "label": "Flow", - "description": "Flow compensation: the amount of material extruded is multiplied by this value.", - "unit": "%", - "default": 100, - "type": "float", - "min_value": "5", - "min_value_warning": "50", - "max_value_warning": "150" - }, - "retraction_enable": { - "label": "Enable Retraction", - "description": "Retract the filament when the nozzle is moving over a non-printed area. ", - "type": "boolean", - "default": true, - "visible": true - }, - "retraction_amount": { - "label": "Retraction Distance", - "description": "The length of material retracted during a retraction move.", - "unit": "mm", - "type": "float", - "default": 6.5, - "min_value_warning": "-0.0001", - "max_value_warning": "10.0", - "visible": false, - "inherit": false, - "enabled": "retraction_enable" - }, - "retraction_speed": { - "label": "Retraction Speed", - "description": "The speed at which the filament is retracted and primed during a retraction move.", - "unit": "mm/s", - "type": "float", - "default": 25, - "min_value": "0", - "max_value": "299792458000", - "max_value_warning": "100", - "visible": false, - "inherit": false, - "enabled": "retraction_enable", - "children": { - "retraction_retract_speed": { - "label": "Retraction Retract Speed", - "description": "The speed at which the filament is retracted during a retraction move.", - "unit": "mm/s", - "type": "float", - "default": 25, - "min_value": "0", - "max_value": "299792458000", - "max_value_warning": "100", - "visible": false, - "enabled": "retraction_enable" - }, - "retraction_prime_speed": { - "label": "Retraction Prime Speed", - "description": "The speed at which the filament is primed during a retraction move.", - "unit": "mm/s", - "type": "float", - "default": 25, - "min_value": "0", - "max_value": "299792458000", - "max_value_warning": "100", - "visible": false, - "enabled": "retraction_enable" - } - } - }, - "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³", - "type": "float", - "default": 0, - "min_value_warning": "-0.0001", - "max_value_warning": "5.0", - "visible": false, - "inherit": false, - "enabled": "retraction_enable" - }, - "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", - "type": "float", - "default": 1.5, - "inherit_function": "line_width * 2", - "min_value": "0", - "max_value_warning": "10", - "visible": false, - "inherit": false, - "enabled": "retraction_enable" - }, - "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": 45, - "min_value": "0", - "max_value_warning": "100", - "type": "int", - "visible": false, - "inherit": false, - "enabled": "retraction_enable" - }, - "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", - "type": "float", - "default": 4.5, - "min_value": "0", - "max_value_warning": "retraction_amount * 2", - "visible": false, - "inherit_function": "retraction_amount", - "enabled": "retraction_enable" - }, - "retraction_hop": { - "label": "Z Hop when Retracting", - "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.", - "unit": "mm", - "type": "float", - "default": 0, - "min_value_warning": "-0.0001", - "max_value_warning": "10", - "visible": false, - "inherit": false, - "enabled": "retraction_enable" - } - } - }, - "speed": { - "label": "Speed", - "visible": true, - "icon": "category_speed", - "settings": { - "speed_print": { - "label": "Print Speed", - "description": "The speed at which printing happens.", - "unit": "mm/s", - "type": "float", - "min_value": "0.1", - "max_value_warning": "150", - "max_value": "299792458000", - "default": 60, - "children": { - "speed_infill": { - "label": "Infill Speed", - "description": "The speed at which infill is printed.", - "unit": "mm/s", - "type": "float", - "min_value": "0.1", - "max_value": "299792458000", - "max_value_warning": "150", - "default": 60, - "visible": false - }, - "speed_wall": { - "label": "Wall Speed", - "description": "The speed at which the walls are printed.", - "unit": "mm/s", - "type": "float", - "min_value": "0.1", - "max_value": "299792458000", - "max_value_warning": "150", - "default": 30, - "visible": false, - "inherit_function": "parent_value / 2", - "children": { - "speed_wall_0": { - "label": "Outer Wall Speed", - "description": "The speed at which the outermost walls are printed. Printing the outer wall at a lower speed improves the final skin quality. However, having a large difference between the inner wall speed and the outer wall speed will effect quality in a negative way.", - "unit": "mm/s", - "type": "float", - "min_value": "0.1", - "max_value": "299792458000", - "max_value_warning": "150", - "default": 30, - "visible": false - }, - "speed_wall_x": { - "label": "Inner Wall Speed", - "description": "The speed at which all inner walls are printed Printing the inner wall faster than the outer wall will reduce printing time. It works well to set this in between the outer wall speed and the infill speed.", - "unit": "mm/s", - "type": "float", - "min_value": "0.1", - "max_value": "299792458000", - "max_value_warning": "150", - "default": 60, - "visible": false, - "inherit_function": "parent_value * 2" - } - } - }, - "speed_topbottom": { - "label": "Top/Bottom Speed", - "description": "The speed at which top/bottom layers are printed.", - "unit": "mm/s", - "type": "float", - "min_value": "0.1", - "max_value": "299792458000", - "max_value_warning": "150", - "default": 30, - "visible": false, - "inherit_function": "parent_value / 2" - }, - "speed_support": { - "label": "Support Speed", - "description": "The speed at which the support structure is printed. Printing support at higher speeds can greatly reduce printing time. The surface quality of the support structure is not important since it is removed after printing.", - "unit": "mm/s", - "type": "float", - "min_value": "0.1", - "max_value": "299792458000", - "max_value_warning": "150", - "default": 60, - "visible": false, - "inherit_function": "speed_print", - "enabled": "support_roof_enable", - "children": { - "speed_support_infill": { - "label": "Support Infill Speed", - "description": "The speed at which the infill of support is printed. Printing the infill at lower speeds improves stability.", - "unit": "mm/s", - "type": "float", - "default": 60, - "min_value": "0.1", - "max_value": "299792458000", - "max_value_warning": "150", - "visible": false, - "inherit": true, - "enabled": "support_enable", - "global_only": true - }, - "speed_support_roof": { - "label": "Support Roof Speed", - "description": "The speed at which the roofs of support are printed. Printing the support roof at lower speeds can improve overhang quality.", - "unit": "mm/s", - "type": "float", - "default": 40, - "min_value": "0.1", - "max_value": "299792458000", - "max_value_warning": "150", - "visible": false, - "enabled": "support_roof_enable", - "inherit_function": "parent_value / 1.5", - "global_only": true - } - } - } - } - }, - "speed_travel": { - "label": "Travel Speed", - "description": "The speed at which travel moves are made.", - "unit": "mm/s", - "type": "float", - "default": 120, - "min_value": "0.1", - "max_value": "299792458000", - "max_value_warning": "300", - "inherit_function": "speed_print if magic_spiralize else 120", - "global_only": true - }, - "speed_layer_0": { - "label": "Initial Layer Speed", - "description": "The print speed for the initial layer. A lower value is advised to improve adhesion to the build plate.", - "unit": "mm/s", - "type": "float", - "default": 30, - "min_value": "0.1", - "max_value": "299792458000", - "max_value_warning": "300", - "visible": false - }, - "skirt_speed": { - "label": "Skirt 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 at a different speed.", - "unit": "mm/s", - "type": "float", - "default": 30, - "min_value": "0.1", - "max_value": "299792458000", - "max_value_warning": "300", - "visible": false, - "inherit_function": "speed_layer_0", - "global_only": true - }, - "speed_slowdown_layers": { - "label": "Number of Slower Layers", - "description": "The first few layers are printed slower than the rest of the object, to get better adhesion to the build plate and improve the overall success rate of prints. The speed is gradually increased over these layers.", - "type": "int", - "default": 2, - "min_value": "0", - "max_value": "299792458000", - "max_value_warning": "300", - "visible": false, - "global_only": true - } - } - }, - "travel": { - "label": "Travel", - "visible": true, - "icon": "category_travel", - "settings": { - "retraction_combing": { - "label": "Combing Mode", - "description": "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas by combing within the infill only. It is also possible to avoid combing over top/bottom skin areas by combing within the infill only.", - "type": "enum", - "options": { - "off": "Off", - "all": "All", - "noskin": "No Skin" - }, - "default": "all", - "visible": false, - "global_only": true - }, - "travel_avoid_other_parts": { - "label": "Avoid Printed Parts when Traveling", - "description": "The nozzle avoids already printed parts when traveling. This option is only available when combing is enabled.", - "type": "boolean", - "default": true, - "visible": false, - "enabled": "retraction_combing != \"off\"", - "global_only": "True" - }, - "travel_avoid_distance": { - "label": "Travel Avoid Distance", - "description": "The distance between the nozzle and already printed parts when avoiding during travel moves.", - "unit": "mm", - "type": "float", - "default": 1.5, - "inherit_function": "machine_nozzle_tip_outer_diameter / 2 * 1.25", - "min_value": "0", - "max_value_warning": "machine_nozzle_tip_outer_diameter * 5", - "visible": false, - "inherit": false, - "enabled": "retraction_combing != \"off\" and travel_avoid_other_parts", - "global_only": "True" - } - } - }, - "cooling": { - "label": "Cooling", - "visible": true, - "icon": "category_cool", - "settings": { - "cool_fan_enabled": { - "label": "Enable Cooling Fans", - "description": "Enables the cooling fans while printing. The fans improve print quality on layers with short layer times and bridging / overhangs.", - "type": "boolean", - "default": true, - "global_only": "True" - }, - "cool_fan_speed": { - "label": "Fan Speed", - "description": "The speed at which the cooling fans spin.", - "unit": "%", - "type": "float", - "min_value": "0", - "max_value": "100", - "default": 100, - "visible": false, - "inherit_function": "100.0 if cool_fan_enabled else 0.0", - "enabled": "cool_fan_enabled", - "global_only": "True", - "children": { - "cool_fan_speed_min": { - "label": "Regular Fan Speed", - "description": "The speed at which the fans spin before hitting the threshold. When a layer prints faster than the threshold, the fan speed gradually inclines towards the maximum fan speed.", - "unit": "%", - "type": "float", - "min_value": "0", - "max_value": "100", - "inherit_function": "parent_value", - "default": 100, - "visible": false, - "enabled": "cool_fan_enabled", - "global_only": "True" - }, - "cool_fan_speed_max": { - "label": "Maximum Fan Speed", - "description": "The speed at which the fans spin on the minimum layer time. The fan speed gradually increases between the regular fan speed and maximum fan speed when the threshold is hit.", - "unit": "%", - "type": "float", - "min_value": "max(0, cool_fan_speed_min)", - "max_value": "100", - "default": 100, - "visible": false, - "enabled": "cool_fan_enabled", - "global_only": "True" - } - } - }, - "cool_min_layer_time_fan_speed_max": { - "label": "Regular/Maximum Fan Speed Threshold", - "description": "The layer time which sets the threshold between regular fan speed and maximum fan speed. Layers that print slower than this time use regular fan speed. For faster layers the fan speed gradually increases towards the maximum fan speed.", - "unit": "sec", - "type": "float", - "default": 10, - "min_value": "cool_min_layer_time", - "max_value_warning": "600", - "visible": false, - "global_only": "True" - }, - "cool_fan_full_at_height": { - "label": "Regular Fan Speed at Height", - "description": "The height at which the fans spin on regular fan speed. At the layers below the fan speed gradually increases from zero to regular fan speed.", - "unit": "mm", - "type": "float", - "default": 0.5, - "inherit_function": "layer_height_0", - "min_value": "0", - "max_value_warning": "10.0", - "visible": false, - "global_only": "True", - "children": { - "cool_fan_full_layer": { - "label": "Regular Fan Speed at Layer", - "description": "The layer at which the fans spin on regular fan speed. If regular fan speed at height is set, this value is calculated and rounded to a whole number.", - "type": "int", - "default": 1, - "min_value": "0", - "max_value_warning": "100", - "visible": false, - "inherit_function": "max(0, int(round((parent_value - layer_height_0) / layer_height, 0)))", - "global_only": "True" - } - } - }, - "cool_min_layer_time": { - "label": "Minimum Layer Time", - "description": "The minimum time spent in a layer. This forces the printer to slow down, to at least spend the time set here in one layer. This allows the printed material to cool down properly before printing the next layer.", - "unit": "sec", - "type": "float", - "default": 5, - "min_value": "0", - "max_value_warning": "600", - "visible": false, - "global_only": "True" - }, - "cool_min_speed": { - "label": "Minimum Speed", - "description": "The minimum print speed, despite slowing down due to the minimum layer time. When the printer would slow down too much, the pressure in the nozzle would be too low and result in bad print quality.", - "unit": "mm/s", - "type": "float", - "default": 10, - "min_value": "0", - "max_value_warning": "100", - "visible": false, - "global_only": "True" - }, - "cool_lift_head": { - "label": "Lift Head", - "description": "When the minimum speed is hit because of minimum layer time, lift the head away from the print and wait the extra time until the minimum layer time is reached.", - "type": "boolean", - "default": false, - "visible": false, - "global_only": "True" - } - } - }, - "support": { - "label": "Support", - "visible": true, - "icon": "category_support", - "settings": { - "support_enable": { - "label": "Enable Support", - "description": "Enable support structures. These structures support parts of the model with severe overhangs.", - "type": "boolean", - "default": false - }, - "support_type": { - "label": "Support Placement", - "description": "Adjusts the placement of the support structures. The placement can be set to touching build plate or everywhere. When set to everywhere the support structures will also be printed on the model.", - "type": "enum", - "options": { - "buildplate": "Touching Buildplate", - "everywhere": "Everywhere" - }, - "default": "everywhere", - "enabled": "support_enable" - }, - "support_angle": { - "label": "Support Overhang Angle", - "description": "The minimum angle of overhangs for which support is added. At a value of 0° all overhangs are supported, 90° will not provide any support.", - "unit": "°", - "type": "float", - "min_value": "0", - "max_value": "90", - "default": 50, - "visible": false, - "enabled": "support_enable" - }, - "support_pattern": { - "label": "Support Pattern", - "description": "The pattern of the support structures of the print. The different options available result in sturdy or easy to remove support.", - "type": "enum", - "options": { - "lines": "Lines", - "grid": "Grid", - "triangles": "Triangles", - "concentric": "Concentric", - "zigzag": "Zig Zag" - }, - "default": "zigzag", - "visible": false, - "enabled": "support_enable", - "global_only": true - }, - "support_connect_zigzags": { - "label": "Connect Support ZigZags", - "description": "Connect the ZigZags. This will increase the strength of the zig zag support structure.", - "type": "boolean", - "default": true, - "visible": false, - "enabled": "support_enable and (support_pattern == \"zigzag\")", - "global_only": true - }, - "support_infill_rate": { - "label": "Support Density", - "description": "Adjusts the density of the support structure. A higher value results in better overhangs, but the supports are harder to remove.", - "unit": "%", - "type": "float", - "min_value": "0", - "max_value_warning": "100", - "default": 15, - "visible": false, - "enabled": "support_enable", - "global_only": true, - "children": { - "support_line_distance": { - "label": "Support Line Distance", - "description": "Distance between the printed support structure lines. This setting is calculated by the support density.", - "unit": "mm", - "type": "float", - "min_value": "0", - "default": 2.66, - "visible": false, - "enabled": "support_enable", - "inherit_function": "(support_line_width * 100) / parent_value * (2 if support_pattern == \"grid\" else (3 if support_pattern == \"triangles\" else 1))", - "global_only": true - } - } - }, - "support_z_distance": { - "label": "Support Z Distance", - "description": "Distance from the top/bottom of the support structure to the print. This gap provides clearance to remove the supports after the model is printed. This value is rounded down to a multiple of the layer height.", - "unit": "mm", - "type": "float", - "min_value": "0", - "max_value_warning": "10", - "default": 0.15, - "visible": false, - "enabled": "support_enable", - - "children": { - "support_top_distance": { - "label": "Support Top Distance", - "description": "Distance from the top of the support to the print.", - "unit": "mm", - "min_value": "0", - "max_value_warning": "10", - "default": 0.15, - "type": "float", - "visible": false, - "enabled": "support_enable" - }, - "support_bottom_distance": { - "label": "Support Bottom Distance", - "description": "Distance from the print to the bottom of the support.", - "unit": "mm", - "min_value": "0", - "max_value_warning": "10", - "default": 0.1, - "inherit_function": "0.1 if support_type == 'everywhere' else 0", - "type": "float", - "visible": false, - "enabled": "support_enable and support_type == 'everywhere'" - } - } - }, - "support_xy_distance": { - "label": "Support X/Y Distance", - "description": "Distance of the support structure from the print in the X/Y directions.", - "unit": "mm", - "type": "float", - "min_value": "0", - "max_value_warning": "10", - "default": 0.7, - "visible": false, - "enabled": "support_enable" - }, - "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": { - "xy_overrides_z": "X/Y overrides Z", - "z_overrides_xy": "Z overrides X/Y" - }, - "default": "z_overrides_xy", - "visible": false, - "enabled": "support_enable" - }, - "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", - "type": "float", - "min_value": "0", - "max_value_warning": "10", - "default": 0.2, - "visible": false, - "inherit_function": "machine_nozzle_size / 2", - "enabled": "support_enable and support_xy_overrides_z==\"z_overrides_xy\"" - }, - "support_bottom_stair_step_height": { - "label": "Support Stair Step Height", - "description": "The height of the steps of the stair-like bottom of support resting on the model. A low value makes the support harder to remove, but too high values can lead to unstable support structures.", - "unit": "mm", - "type": "float", - "default": 0.3, - "min_value": "0", - "max_value_warning": "1.0", - "visible": false, - "enabled": "support_enable" - }, - "support_join_distance": { - "label": "Support Join Distance", - "description": "The maximum distance between support structures in the X/Y directions. When seperate structures are closer together than this value, the structures merge into one.", - "unit": "mm", - "type": "float", - "default": 2.0, - "min_value_warning": "0", - "max_value_warning": "10", - "visible": false, - "enabled": "support_enable" - }, - "support_offset": { - "label": "Support Horizontal Expansion", - "description": "Amount of offset applied to all support polygons in each layer. Positive values can smooth out the support areas and result in more sturdy support.", - "unit": "mm", - "type": "float", - "default": 0.2, - "min_value_warning": "-0.5", - "max_value_warning": "5.0", - "visible": false, - "enabled": "support_enable" - }, - "support_area_smoothing": { - "label": "Support Area Smoothing", - "description": "Maximum distance in the X/Y directions of a line segment which is to be smoothed out. Ragged lines are introduced by the join distance and support bridge, which cause the machine to resonate. Smoothing the support areas won't cause them to break with the constraints, except it might change the overhang.", - "unit": "mm", - "type": "float", - "default": 0.6, - "min_value": "0", - "max_value_warning": "1.0", - "visible": false, - "enabled": "support_enable" - }, - "support_roof_enable": { - "label": "Enable Support Roof", - "description": "Generate a dense top skin at the top of the support on which the model is printed.", - "type": "boolean", - "default": false, - "visible": true, - "enabled": "support_enable" - }, - "support_roof_height": { - "label": "Support Roof Thickness", - "description": "The thickness of the support roofs.", - "unit": "mm", - "type": "float", - "default": 1, - "min_value": "0", - "max_value_warning": "10", - "visible": false, - "enabled": "support_roof_enable" - }, - "support_roof_density": { - "label": "Support Roof Density", - "description": "Adjusts the density of the roof of the support structure. A higher value results in better overhangs, but the supports are harder to remove.", - "unit": "%", - "type": "float", - "default": 100, - "min_value": "0", - "max_value_warning": "100", - "enabled":"support_roof_enable", - "global_only": true, - "children": { - "support_roof_line_distance": { - "label": "Support Roof Line Distance", - "description": "Distance between the printed support roof lines. This setting is calculated by the support roof Density, but can be adjusted separately.", - "unit": "mm", - "type": "float", - "default": 0.4, - "min_value": "0", - "visible": false, - "inherit_function": "0 if parent_value == 0 else (support_roof_line_width * 100) / parent_value * (2 if support_roof_pattern == \"grid\" else (3 if support_roof_pattern == \"triangles\" else 1))", - "enabled": "support_roof_enable", - "global_only": true - } - } - }, - "support_roof_pattern": { - "label": "Support Roof Pattern", - "description": "The pattern with which the top of the support is printed.", - "type": "enum", - "visible": false, - "options": { - "lines": "Lines", - "grid": "Grid", - "triangles": "Triangles", - "concentric": "Concentric", - "zigzag": "Zig Zag" - }, - "default": "concentric", - "enabled": "support_roof_enable", - "global_only": true - }, - "support_use_towers": { - "label": "Use Towers", - "description": "Use specialized towers to support tiny overhang areas. These towers have a larger diameter than the region they support. Near the overhang the towers' diameter decreases, forming a roof.", - "type": "boolean", - "default": true, - "visible": false, - "enabled": "support_enable" - }, - "support_tower_diameter": { - "label": "Tower Diameter", - "description": "The diameter of a special tower.", - "unit": "mm", - "type": "float", - "default": 3.0, - "min_value": "0", - "max_value_warning": "10", - "visible": false, - "enabled": "support_enable and support_use_towers" - }, - "support_minimal_diameter": { - "label": "Minimum Diameter", - "description": "Minimum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower.", - "unit": "mm", - "type": "float", - "default": 3.0, - "min_value": "0", - "max_value_warning": "10", - "max_value": "support_tower_diameter", - "inherit": true, - "visible": false, - "enabled": "support_enable and support_use_towers" - }, - "support_tower_roof_angle": { - "label": "Tower Roof Angle", - "description": "The angle of a rooftop of a tower. A higher value results in pointed tower roofs, a lower value results in flattened tower roofs.", - "unit": "°", - "type": "int", - "min_value": "0", - "max_value": "90", - "default": 65, - "visible": false, - "enabled": "support_enable and support_use_towers" - } - } - }, - "platform_adhesion": { - "label": "Platform Adhesion", - "visible": true, - "icon": "category_adhesion", - "settings": { - "adhesion_type": { - "label": "Platform Adhesion Type", - "description": "Different options that help to improve both priming your extrusion and adhesion to the build plate. Brim adds a single layer flat area around the base of your object to prevent warping. Raft adds a thick grid with a roof below the object. Skirt is a line printed around the object, but not connected to the model.", - "type": "enum", - "options": { - "skirt": "Skirt", - "brim": "Brim", - "raft": "Raft" - }, - "default": "brim", - "global_only": "True" - }, - "skirt_line_count": { - "label": "Skirt Line Count", - "description": "Multiple skirt lines help to prime your extrusion better for small objects. Setting this to 0 will disable the skirt.", - "type": "int", - "default": 1, - "min_value": "0", - "max_value_warning": "10", - "enabled": "adhesion_type == \"skirt\"", - "global_only": "True", - "visible": false - }, - "skirt_gap": { - "label": "Skirt Distance", - "description": "The horizontal distance between the skirt and the first layer of the print.\nThis is the minimum distance, multiple skirt lines will extend outwards from this distance.", - "unit": "mm", - "type": "float", - "default": 3, - "min_value_warning": "0", - "max_value_warning": "100", - "enabled": "adhesion_type == \"skirt\"", - "global_only": "True", - "visible": false - }, - "skirt_minimal_length": { - "label": "Skirt Minimum Length", - "description": "The minimum length of the skirt. If this length is not reached by the skirt line count, more skirt lines will be added until the minimum length is reached. Note: If the line count is set to 0 this is ignored.", - "unit": "mm", - "type": "float", - "default": 250, - "min_value": "0", - "min_value_warning": "25", - "max_value_warning": "2500", - "enabled": "adhesion_type == \"skirt\"", - "global_only": "True", - "visible": false - }, - "brim_width": { - "label": "Brim Width", - "description": "The distance from the model to the outermost brim line. A larger brim enhances adhesion to the build plate, but also reduces the effective print area.", - "type": "float", - "unit": "mm", - "default": 8.0, - "min_value": "0.0", - "max_value_warning": "100.0", - "enabled": "adhesion_type == \"brim\"", - "global_only": "True", - "visible": true, - "children": { - "brim_line_count": { - "label": "Brim Line Count", - "description": "The number of lines used for a brim. More brim lines enhance adhesion to the build plate, but also reduces the effective print area.", - "type": "int", - "default": 20, - "min_value": "0", - "max_value_warning": "300", - "inherit_function": "math.ceil(parent_value / skirt_line_width)", - "enabled": "adhesion_type == \"brim\"", - "global_only": "True", - "visible": false - } - } - }, - "raft_margin": { - "label": "Raft Extra Margin", - "description": "If the raft is enabled, this is the extra raft area around the object which is also given a raft. Increasing this margin will create a stronger raft while using more material and leaving less area for your print.", - "unit": "mm", - "type": "float", - "default": 5, - "min_value_warning": "0", - "max_value_warning": "10", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True", - "visible": false - }, - "raft_airgap": { - "label": "Raft Air Gap", - "description": "The gap between the final raft layer and the first layer of the object. Only the first layer is raised by this amount to lower the bonding between the raft layer and the object. Makes it easier to peel off the raft.", - "unit": "mm", - "type": "float", - "default": 0.3, - "min_value": "0", - "max_value_warning": "1.0", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True", - "visible": true - }, - "layer_0_z_overlap": { - "label": "Initial Layer Z Overlap", - "description": "Make the first and second layer of the object 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", - "type": "float", - "default": 0.22, - "inherit_function": "raft_airgap / 2", - "min_value": "0", - "max_value_warning": "layer_height", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True", - "visible": true - }, - "raft_surface_layers": { - "label": "Raft Top Layers", - "description": "The number of top layers on top of the 2nd raft layer. These are fully filled layers that the object sits on. 2 layers result in a smoother top surface than 1.", - "type": "int", - "default": 2, - "min_value": "0", - "max_value_warning": "20", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True", - "visible": true - }, - "raft_surface_thickness": { - "label": "Raft Top Layer Thickness", - "description": "Layer thickness of the top raft layers.", - "unit": "mm", - "type": "float", - "default": 0.1, - "min_value": "0", - "max_value_warning": "2.0", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True", - "visible": false - }, - "raft_surface_line_width": { - "label": "Raft Top Line Width", - "description": "Width of the lines in the top surface of the raft. These can be thin lines so that the top of the raft becomes smooth.", - "unit": "mm", - "type": "float", - "default": 0.3, - "min_value": "0.0001", - "max_value_warning": "machine_nozzle_size * 2", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True", - "visible": false - }, - "raft_surface_line_spacing": { - "label": "Raft Top Spacing", - "description": "The distance between the raft lines for the top raft layers. The spacing should be equal to the line width, so that the surface is solid.", - "unit": "mm", - "type": "float", - "default": 0.3, - "min_value": "0.0001", - "max_value_warning": "5.0", - "enabled": "adhesion_type == \"raft\"", - "inherit_function": "raft_surface_line_width", - "global_only": "True", - "visible": false - }, - "raft_interface_thickness": { - "label": "Raft Middle Thickness", - "description": "Layer thickness of the middle raft layer.", - "unit": "mm", - "type": "float", - "default": 0.27, - "min_value": "0", - "max_value_warning": "5.0", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True", - "visible": false - }, - "raft_interface_line_width": { - "label": "Raft Middle Line Width", - "description": "Width of the lines in the middle raft layer. Making the second layer extrude more causes the lines to stick to the bed.", - "unit": "mm", - "type": "float", - "default": 1, - "inherit_function": "line_width", - "min_value": "0.0001", - "max_value_warning": "machine_nozzle_size * 2", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True", - "visible": false - }, - "raft_interface_line_spacing": { - "label": "Raft Middle Spacing", - "description": "The distance between the raft lines for the middle raft layer. The spacing of the middle should be quite wide, while being dense enough to support the top raft layers.", - "unit": "mm", - "type": "float", - "default": 1.0, - "min_value": "0", - "max_value_warning": "15.0", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True", - "visible": false - }, - "raft_base_thickness": { - "label": "Raft Base Thickness", - "description": "Layer thickness of the base raft layer. This should be a thick layer which sticks firmly to the printer bed.", - "unit": "mm", - "type": "float", - "default": 0.3, - "min_value": "0", - "max_value_warning": "5.0", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True", - "visible": false - }, - "raft_base_line_width": { - "label": "Raft Base Line Width", - "description": "Width of the lines in the base raft layer. These should be thick lines to assist in bed adhesion.", - "unit": "mm", - "type": "float", - "default": 1, - "min_value": "0.0001", - "inherit_function": "line_width", - "max_value_warning": "machine_nozzle_size * 2", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True", - "visible": false - }, - "raft_base_line_spacing": { - "label": "Raft Line Spacing", - "description": "The distance between the raft lines for the base raft layer. Wide spacing makes for easy removal of the raft from the build plate.", - "unit": "mm", - "type": "float", - "default": 3.0, - "min_value": "0.0001", - "max_value_warning": "100", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True", - "visible": false - }, - "raft_speed": { - "label": "Raft Print Speed", - "description": "The speed at which the raft is printed.", - "unit": "mm/s", - "type": "float", - "default": 30, - "min_value": "0.1", - "max_value": "299792458000", - "max_value_warning": "200", - "enabled": "adhesion_type == \"raft\"", - "inherit_function": "speed_print / 60 * 30", - "global_only": "True", - "visible": false, - "children": { - "raft_surface_speed": { - "label": "Raft Surface Print Speed", - "description": "The speed at which the surface raft layers are printed. These should be printed a bit slower, so that the nozzle can slowly smooth out adjacent surface lines.", - "unit": "mm/s", - "type": "float", - "default": 30, - "min_value": "0.1", - "max_value": "299792458000", - "max_value_warning": "100", - "enabled": "adhesion_type == \"raft\"", - "inherit_function": "parent_value", - "global_only": "True", - "visible": false - }, - "raft_interface_speed": { - "label": "Raft Interface Print Speed", - "description": "The speed at which the interface raft layer is printed. This should be printed quite slowly, as the volume of material coming out of the nozzle is quite high.", - "unit": "mm/s", - "type": "float", - "default": 15, - "min_value": "0.1", - "max_value": "299792458000", - "max_value_warning": "150", - "enabled": "adhesion_type == \"raft\"", - "inherit_function": "0.5 * parent_value", - "global_only": "True", - "visible": false - }, - "raft_base_speed": { - "label": "Raft Base Print Speed", - "description": "The speed at which the base raft layer is printed. This should be printed quite slowly, as the volume of material coming out of the nozzle is quite high.", - "unit": "mm/s", - "type": "float", - "default": 15, - "min_value": "0.1", - "max_value": "299792458000", - "max_value_warning": "200", - "enabled": "adhesion_type == \"raft\"", - "inherit_function": "0.5 * parent_value", - "global_only": "True", - "visible": false - } - } - }, - "raft_fan_speed": { - "label": "Raft Fan Speed", - "description": "The fan speed for the raft.", - "unit": "%", - "type": "float", - "min_value": "0", - "max_value": "100", - "default": 0, - "global_only": "True", - "visible": false, - "enabled": "adhesion_type == \"raft\"", - "children": { - "raft_surface_fan_speed": { - "label": "Raft Surface Fan Speed", - "description": "The fan speed for the surface raft layers.", - "unit": "%", - "type": "float", - "min_value": "0", - "max_value": "100", - "default": 0, - "global_only": "True", - "visible": false, - "inherit": true, - "enabled": "adhesion_type == \"raft\"" - }, - "raft_interface_fan_speed": { - "label": "Raft Interface Fan Speed", - "description": "The fan speed for the interface raft layer.", - "unit": "%", - "type": "float", - "min_value": "0", - "max_value": "100", - "default": 0, - "global_only": "True", - "visible": false, - "inherit": true, - "enabled": "adhesion_type == \"raft\"" - }, - "raft_base_fan_speed": { - "label": "Raft Base Fan Speed", - "description": "The fan speed for the base raft layer.", - "unit": "%", - "type": "float", - "min_value": "0", - "max_value": "100", - "default": 0, - "global_only": "True", - "visible": false, - "inherit": true, - "enabled": "adhesion_type == \"raft\"" - } - } - } - } - }, - "meshfix": { - "label": "Mesh Fixes", - "visible": true, - "icon": "category_fixes", - "settings": { - "meshfix_union_all": { - "label": "Union Overlapping Volumes", - "description": "Ignore the internal geometry arising from overlapping volumes and print the volumes as one. This may cause internal cavities to disappear.", - "type": "boolean", - "default": true, - "visible": false - }, - "meshfix_union_all_remove_holes": { - "label": "Remove All Holes", - "description": "Remove the holes in each layer and keep only the outside shape. This will ignore any invisible internal geometry. However, it also ignores layer holes which can be viewed from above or below.", - "type": "boolean", - "default": false, - "visible": false - }, - "meshfix_extensive_stitching": { - "label": "Extensive Stitching", - "description": "Extensive stitching tries to stitch up open holes in the mesh by closing the hole with touching polygons. This option can introduce a lot of processing time.", - "type": "boolean", - "default": false, - "visible": false - }, - "meshfix_keep_open_polygons": { - "label": "Keep Disconnected Faces", - "description": "Normally Cura tries to stitch up small holes in the mesh and remove parts of a layer with big holes. Enabling this option keeps those parts which cannot be stitched. This option should be used as a last resort option when everything else fails to produce proper GCode.", - "type": "boolean", - "default": false, - "visible": false - } - } - }, - "blackmagic": { - "label": "Special Modes", - "visible": true, - "icon": "category_blackmagic", - "settings": { - "print_sequence": { - "label": "Print Sequence", - "description": "Whether to print all objects one layer at a time or to wait for one object to finish, before moving on to the next. One at a time mode is only possible if all models are separated in such a way that the whole print head can move in between and all models are lower than the distance between the nozzle and the X/Y axes.", - "type": "enum", - "options": { - "all_at_once": "All at Once", - "one_at_a_time": "One at a Time" - }, - "default": "all_at_once", - "visible": true, - "global_only": true - }, - "magic_mesh_surface_mode": { - "label": "Surface Mode", - "description": "Treat the model as a surface only, a volume, or volumes with loose surfaces. The normal print mode only prints enclosed volumes. \"Surface\" prints a single wall tracing the mesh surface with no infill and no top/bottom skin. \"Both\" prints enclosed volumes like normal and any remaining polygons as surfaces.", - "type": "enum", - "options": { - "normal": "Normal", - "surface": "Surface", - "both": "Both" - }, - "default": "normal", - "visible": false - }, - "magic_spiralize": { - "label": "Spiralize Outer Contour", - "description": "Spiralize smooths out the Z move of the outer edge. This will create a steady Z increase over the whole print. This feature turns a solid object into a single walled print with a solid bottom. This feature used to be called Joris in older versions.", - "type": "boolean", - "default": false, - "visible": false, - "global_only": "True" - } - } - }, - "experimental": - { - "label": "Experimental", - "visible": true, - "icon": "category_blackmagic", - "settings": { - "draft_shield_enabled": { - "label": "Enable Draft Shield", - "description": "This will create a wall around the object, which traps (hot) air and shields against exterior airflow. Especially useful for materials which warp easily.", - "type": "boolean", - "default": false, - "global_only": true - }, - "draft_shield_dist": { - "label": "Draft Shield X/Y Distance", - "description": "Distance of the draft shield from the print, in the X/Y directions.", - "unit": "mm", - "type": "float", - "min_value": "0", - "max_value_warning": "100", - "default": 10, - "visible": false, - "enabled": "draft_shield_enabled", - "global_only": true - }, - "draft_shield_height_limitation": { - "label": "Draft Shield Limitation", - "description": "Set the height of the draft shield. Choose to print the draft shield at the full height of the object or at a limited height.", - "type": "enum", - "options": { - "full": "Full", - "limited": "Limited" - }, - "default": "full", - "visible": false, - "enabled": "draft_shield_enabled", - "global_only": true - }, - "draft_shield_height": { - "label": "Draft Shield Height", - "description": "Height limitation of the draft shield. Above this height no draft shield will be printed.", - "unit": "mm", - "type": "float", - "min_value": "0", - "max_value_warning": "9999", - "default": 0, - "inherit_function": "9999 if draft_shield_height_limitation == 'full' and draft_shield_enabled else 0.0", - "visible": false, - "enabled": "draft_shield_height_limitation == \"limited\"", - "global_only": true - }, - "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": "boolean", - "default": false, - "visible": false - }, - "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": "°", - "type": "float", - "min_value": "0", - "max_value": "89", - "default": 50, - "visible": true, - "enabled": "conical_overhang_enabled" - }, - "coasting_enable": { - "label": "Enable Coasting", - "description": "Coasting replaces the last part of an extrusion path with a travel path. The oozed material is used to print the last piece of the extrusion path in order to reduce stringing.", - "type": "boolean", - "default": false, - "visible": false, - "global_only": true - }, - "coasting_volume": { - "label": "Coasting Volume", - "description": "The volume otherwise oozed. This value should generally be close to the nozzle diameter cubed.", - "unit": "mm³", - "type": "float", - "default": 0.064, - "min_value": "0", - "max_value_warning": "2.0", - "visible": false, - "inherit": false, - "enabled": "coasting_enable", - "global_only": true - }, - "coasting_min_volume": { - "label": "Minimum Volume Before Coasting", - "description": "The smallest volume an extrusion path should have before allowing coasting. For smaller extrusion paths, less pressure has been built up in the bowden tube and so the coasted volume is scaled linearly. This value should always be larger than the Coasting Volume.", - "unit": "mm³", - "type": "float", - "default": 0.8, - "min_value": "0", - "max_value_warning": "10.0", - "visible": false, - "enabled": "coasting_enable", - "global_only": true - }, - "coasting_speed": { - "label": "Coasting Speed", - "description": "The speed by which to move during coasting, relative to the speed of the extrusion path. A value slightly under 100% is advised, since during the coasting move the pressure in the bowden tube drops.", - "unit": "%", - "type": "float", - "default": 90, - "min_value": "0.0001", - "max_value_warning": "100", - "visible": false, - "inherit": false, - "enabled": "coasting_enable", - "global_only": true - }, - "skin_outline_count": { - "label": "Extra Skin Wall Count", - "description": "Replaces the outermost part of the top/bottom pattern with a number of concentric lines. Using one or two lines improves roofs that start on infill material.", - "default": 0, - "min_value": "0", - "max_value_warning": "10", - "type": "int", - "visible": false - }, - "skin_alternate_rotation": { - "label": "Alternate Skin Rotation", - "description": "Alternate the direction in which the top/bottom layers are printed. Normally they are printed diagonally only. This setting adds the X-only and Y-only directions.", - "type": "boolean", - "default": false, - "visible": false, - "enabled": "top_bottom_pattern != \"concentric\"" - }, - "support_conical_enabled": { - "label": "Enable Conical Support", - "description": "Experimental feature: Make support areas smaller at the bottom than at the overhang.", - "type": "boolean", - "default": false, - "visible": true, - "enabled": "support_enable" - }, - "support_conical_angle": { - "label": "Conical Support Angle", - "description": "The angle of the tilt of conical support. With 0 degrees being vertical, and 90 degrees being horizontal. Smaller angles cause the support to be more sturdy, but consist of more material. Negative angles cause the base of the support to be wider than the top.", - "unit": "°", - "type": "float", - "min_value": "-90", - "min_value_warning": "-45", - "max_value_warning": "45", - "max_value": "90", - "default": 30, - "visible": false, - "enabled": "support_conical_enabled and support_enable" - }, - "support_conical_min_width": { - "label": "Conical Support Minimum Width", - "description": "Minimum width to which the base of the conical support area is reduced. Small widths can lead to unstable support structures.", - "unit": "mm", - "default": 5.0, - "min_value": "0", - "min_value_warning": "machine_nozzle_size * 3", - "max_value_warning": "100.0", - "type": "float", - "visible": false, - "enabled": "support_conical_enabled and support_enable" - }, - "magic_fuzzy_skin_enabled": { - "label": "Fuzzy Skin", - "description": "Randomly jitter while printing the outer wall, so that the surface has a rough and fuzzy look.", - "type": "boolean", - "default": false, - "visible": false - }, - "magic_fuzzy_skin_thickness": { - "label": "Fuzzy Skin Thickness", - "description": "The width within which to jitter. It's advised to keep this below the outer wall width, since the inner walls are unaltered.", - "type": "float", - "unit": "mm", - "default": 0.3, - "min_value": "0.001", - "max_value_warning": "wall_line_width_0", - "visible": false, - "enabled": "magic_fuzzy_skin_enabled" - }, - "magic_fuzzy_skin_point_density": { - "label": "Fuzzy Skin Density", - "description": "The average density of points introduced on each polygon in a layer. Note that the original points of the polygon are discarded, so a low density results in a reduction of the resolution.", - "type": "float", - "unit": "1/mm", - "default": 1.25, - "min_value": "0.008", - "min_value_warning": "0.1", - "max_value_warning": "10", - "max_value": "2 / magic_fuzzy_skin_thickness", - "visible": false, - "enabled": "magic_fuzzy_skin_enabled", - "children": { - "magic_fuzzy_skin_point_dist": { - "label": "Fuzzy Skin Point Distance", - "description": "The average distance between the random points introduced on each line segment. Note that the original points of the polygon are discarded, so a high smoothness results in a reduction of the resolution. This value must be higher than half the Fuzzy Skin Thickness.", - "type": "float", - "unit": "mm", - "default": 0.8, - "min_value": "magic_fuzzy_skin_thickness / 2", - "min_value_warning": "0.1", - "max_value_warning": "10", - "inherit_function": "10000 if parent_value == 0 else 1 / parent_value", - "visible": false, - "enabled": "magic_fuzzy_skin_enabled" - } - } - }, - "wireframe_enabled": { - "label": "Wire Printing", - "description": "Print only the outside surface with a sparse webbed structure, printing 'in thin air'. This is realized by horizontally printing the contours of the model at given Z intervals which are connected via upward and diagonally downward lines.", - "type": "boolean", - "default": false, - "visible": false, - "global_only": "True" - }, - "wireframe_height": { - "label": "WP Connection Height", - "description": "The height of the upward and diagonally downward lines between two horizontal parts. This determines the overall density of the net structure. Only applies to Wire Printing.", - "type": "float", - "unit": "mm", - "default": 3, - "min_value": "0.0001", - "max_value_warning": "20", - "visible": false, - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_roof_inset": { - "label": "WP Roof Inset Distance", - "description": "The distance covered when making a connection from a roof outline inward. Only applies to Wire Printing.", - "type": "float", - "unit": "mm", - "default": 3, - "min_value": "0", - "min_value_warning": "machine_nozzle_size", - "max_value_warning": "20", - "visible": false, - "enabled": "wireframe_enabled", - "inherit_function": "wireframe_height", - "global_only": "True" - }, - "wireframe_printspeed": { - "label": "WP Speed", - "description": "Speed at which the nozzle moves when extruding material. Only applies to Wire Printing.", - "unit": "mm/s", - "type": "float", - "default": 5, - "min_value": "0.1", - "max_value": "299792458000", - "max_value_warning": "50", - "visible": false, - "enabled": "wireframe_enabled", - "global_only": "True", - "children": { - "wireframe_printspeed_bottom": { - "label": "WP Bottom Printing Speed", - "description": "Speed of printing the first layer, which is the only layer touching the build platform. Only applies to Wire Printing.", - "unit": "mm/s", - "type": "float", - "default": 5, - "min_value": "0.1", - "max_value": "299792458000", - "max_value_warning": "50", - "visible": false, - "inherit": true, - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_printspeed_up": { - "label": "WP Upward Printing Speed", - "description": "Speed of printing a line upward 'in thin air'. Only applies to Wire Printing.", - "unit": "mm/s", - "type": "float", - "default": 5, - "min_value": "0.1", - "max_value": "299792458000", - "max_value_warning": "50", - "visible": false, - "inherit": true, - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_printspeed_down": { - "label": "WP Downward Printing Speed", - "description": "Speed of printing a line diagonally downward. Only applies to Wire Printing.", - "unit": "mm/s", - "type": "float", - "default": 5, - "min_value": "0.1", - "max_value": "299792458000", - "max_value_warning": "50", - "visible": false, - "inherit": true, - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_printspeed_flat": { - "label": "WP Horizontal Printing Speed", - "description": "Speed of printing the horizontal contours of the object. Only applies to Wire Printing.", - "unit": "mm/s", - "type": "float", - "default": 5, - "min_value": "0.1", - "max_value": "299792458000", - "max_value_warning": "100", - "visible": false, - "inherit": true, - "enabled": "wireframe_enabled", - "global_only": "True" - } - } - }, - "wireframe_flow": { - "label": "WP Flow", - "description": "Flow compensation: the amount of material extruded is multiplied by this value. Only applies to Wire Printing.", - "unit": "%", - "default": 100, - "min_value": "0", - "max_value_warning": "100", - "type": "float", - "visible": false, - "enabled": "wireframe_enabled", - "global_only": "True", - "children": { - "wireframe_flow_connection": { - "label": "WP Connection Flow", - "description": "Flow compensation when going up or down. Only applies to Wire Printing.", - "unit": "%", - "default": 100, - "min_value": "0", - "max_value_warning": "100", - "type": "float", - "visible": false, - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_flow_flat": { - "label": "WP Flat Flow", - "description": "Flow compensation when printing flat lines. Only applies to Wire Printing.", - "unit": "%", - "default": 100, - "min_value": "0", - "max_value_warning": "100", - "type": "float", - "visible": false, - "enabled": "wireframe_enabled", - "global_only": "True" - } - } - }, - "wireframe_top_delay": { - "label": "WP Top Delay", - "description": "Delay time after an upward move, so that the upward line can harden. Only applies to Wire Printing.", - "unit": "sec", - "type": "float", - "default": 0, - "min_value": "0", - "max_value_warning": "1", - "visible": false, - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_bottom_delay": { - "label": "WP Bottom Delay", - "description": "Delay time after a downward move. Only applies to Wire Printing.", - "unit": "sec", - "type": "float", - "default": 0, - "min_value": "0", - "max_value_warning": "1", - "visible": false, - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_flat_delay": { - "label": "WP Flat Delay", - "description": "Delay time between two horizontal segments. Introducing such a delay can cause better adhesion to previous layers at the connection points, while too long delays cause sagging. Only applies to Wire Printing.", - "unit": "sec", - "type": "float", - "default": 0.1, - "min_value": "0", - "max_value_warning": "0.5", - "visible": false, - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_up_half_speed": { - "label": "WP Ease Upward", - "description": "Distance of an upward move which is extruded with half speed.\nThis can cause better adhesion to previous layers, while not heating the material in those layers too much. Only applies to Wire Printing.", - "type": "float", - "unit": "mm", - "default": 0.3, - "min_value": "0", - "max_value_warning": "5.0", - "visible": false, - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_top_jump": { - "label": "WP Knot Size", - "description": "Creates a small knot at the top of an upward line, so that the consecutive horizontal layer has a better chance to connect to it. Only applies to Wire Printing.", - "type": "float", - "unit": "mm", - "default": 0.6, - "min_value": "0", - "max_value_warning": "2.0", - "visible": false, - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_fall_down": { - "label": "WP Fall Down", - "description": "Distance with which the material falls down after an upward extrusion. This distance is compensated for. Only applies to Wire Printing.", - "type": "float", - "unit": "mm", - "default": 0.5, - "min_value": "0", - "max_value_warning": "wireframe_height", - "visible": false, - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_drag_along": { - "label": "WP Drag Along", - "description": "Distance with which the material of an upward extrusion is dragged along with the diagonally downward extrusion. This distance is compensated for. Only applies to Wire Printing.", - "type": "float", - "unit": "mm", - "default": 0.6, - "min_value": "0", - "max_value_warning": "wireframe_height", - "visible": false, - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_strategy": { - "label": "WP Strategy", - "description": "Strategy for making sure two consecutive layers connect at each connection point. Retraction lets the upward lines harden in the right position, but may cause filament grinding. A knot can be made at the end of an upward line to heighten the chance of connecting to it and to let the line cool; however, it may require slow printing speeds. Another strategy is to compensate for the sagging of the top of an upward line; however, the lines won't always fall down as predicted.", - "type": "enum", - "options": { - "compensate": "Compensate", - "knot": "Knot", - "retract": "Retract" - }, - "default": "compensate", - "visible": false, - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_straight_before_down": { - "label": "WP Straighten Downward Lines", - "description": "Percentage of a diagonally downward line which is covered by a horizontal line piece. This can prevent sagging of the top most point of upward lines. Only applies to Wire Printing.", - "type": "float", - "unit": "%", - "default": 20, - "min_value": "0", - "max_value": "100", - "visible": false, - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_roof_fall_down": { - "label": "WP Roof Fall Down", - "description": "The distance which horizontal roof lines printed 'in thin air' fall down when being printed. This distance is compensated for. Only applies to Wire Printing.", - "type": "float", - "unit": "mm", - "default": 2, - "min_value_warning": "0", - "max_value_warning": "wireframe_roof_inset", - "visible": false, - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_roof_drag_along": { - "label": "WP Roof Drag Along", - "description": "The distance of the end piece of an inward line which gets dragged along when going back to the outer outline of the roof. This distance is compensated for. Only applies to Wire Printing.", - "type": "float", - "unit": "mm", - "default": 0.8, - "min_value": "0", - "max_value_warning": "10", - "visible": false, - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_roof_outer_delay": { - "label": "WP Roof Outer Delay", - "description": "Time spent at the outer perimeters of hole which is to become a roof. Longer times can ensure a better connection. Only applies to Wire Printing.", - "type": "float", - "unit": "sec", - "default": 0.2, - "min_value": "0", - "max_value_warning": "2.0", - "visible": false, - "enabled": "wireframe_enabled", - "global_only": "True" - }, - "wireframe_nozzle_clearance": { - "label": "WP Nozzle Clearance", - "description": "Distance between the nozzle and horizontally downward lines. Larger clearance results in diagonally downward lines with a less steep angle, which in turn results in less upward connections with the next layer. Only applies to Wire Printing.", - "type": "float", - "unit": "mm", - "default": 1, - "min_value_warning": "0", - "max_value_warning": "10.0", - "visible": false, - "enabled": "wireframe_enabled", - "global_only": "True" - } - } - } - } -} From fe53a4381932a231753d01a32751d508d2842172 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 26 May 2016 09:41:25 +0200 Subject: [PATCH 270/705] Combine support checkbox & support extruder selection & remove main extruder selection CURA-790 --- resources/qml/SidebarSimple.qml | 141 +++++++++++++------------------- 1 file changed, 55 insertions(+), 86 deletions(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index d303952a8d..36d92b6e78 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -175,38 +175,35 @@ Item } Rectangle { - id: helpersCellLeft + id: helpersCell anchors.top: infillCellRight.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.left: parent.left - width: parent.width/100*35 - UM.Theme.getSize("default_margin").width + anchors.right: parent.right height: childrenRect.height Label{ + id: adhesionHelperLabel anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width - //: Helpers selection label - text: catalog.i18nc("@label:listbox","Helpers:"); + anchors.verticalCenter: brimCheckBox.verticalCenter + width: parent.width/100*35 - 3 * UM.Theme.getSize("default_margin").width + //: Bed adhesion label + text: catalog.i18nc("@label:listbox","Bed Adhesion:"); font: UM.Theme.getFont("default"); color: UM.Theme.getColor("text"); } - } - Rectangle { - id: helpersCellRight - anchors.top: helpersCellLeft.top - anchors.left: helpersCellLeft.right - width: parent.width/100*65 - UM.Theme.getSize("default_margin").width - height: childrenRect.height CheckBox{ id: brimCheckBox property bool hovered_ex: false anchors.top: parent.top - anchors.left: parent.left + anchors.left: adhesionHelperLabel.right + anchors.leftMargin: UM.Theme.getSize("default_margin").width //: Setting enable skirt adhesion checkbox - text: catalog.i18nc("@option:check","Generate Brim"); + text: catalog.i18nc("@option:check","Print Brim"); style: UM.Theme.styles.checkbox; checked: platformAdhesionType.properties.value == "brim" @@ -231,16 +228,31 @@ Item } } } + + Label{ + id: supportHelperLabel + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_margin").width + anchors.verticalCenter: supportCheckBox.verticalCenter + width: parent.width/100*35 - 3 * UM.Theme.getSize("default_margin").width + //: Support label + text: catalog.i18nc("@label:listbox","Support:"); + font: UM.Theme.getFont("default"); + color: UM.Theme.getColor("text"); + } + CheckBox{ id: supportCheckBox + visible: machineExtruderCount.properties.value <= 1 property bool hovered_ex: false anchors.top: brimCheckBox.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height - anchors.left: parent.left + anchors.left: supportHelperLabel.right + anchors.leftMargin: UM.Theme.getSize("default_margin").width //: Setting enable support checkbox - text: catalog.i18nc("@option:check","Generate Support Structure"); + text: catalog.i18nc("@option:check","Print Support Structure"); style: UM.Theme.styles.checkbox; checked: supportEnabled.properties.value == "True" @@ -264,74 +276,27 @@ Item } } } - } - function populateExtruderModel() - { - extruderModel.clear(); - for(var extruder = 0; extruder < machineExtruderCount.properties.value ; extruder++) { - print(catalog.i18nc("@label", "Extruder %1").arg(extruder)); - extruderModel.append({ - text: catalog.i18nc("@label", "Extruder %1").arg(extruder) - }) - } - } - - Rectangle { - id: multiExtrusionCell - anchors.top: helpersCellRight.bottom - anchors.topMargin: UM.Theme.getSize("default_margin").height - anchors.left: parent.left - width: parent.width - height: childrenRect.height - visible: machineExtruderCount.properties.value > 1 - - Label { - id: mainExtruderLabel - text: catalog.i18nc("@label:listbox","Print object with:") - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - width: base.width/100* 35 - 2*UM.Theme.getSize("default_margin").width - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width - anchors.verticalCenter: mainExtruderCombobox.verticalCenter - } - ComboBox { - id: mainExtruderCombobox - model: extruderModel - anchors.top: parent.top - anchors.left: supportExtruderLabel.right - style: UM.Theme.styles.combobox - currentIndex: mainExtruderNr.properties.value - onActivated: { - mainExtruderNr.setPropertyValue("value", index) - } - } - - Label { - id: supportExtruderLabel - visible: supportCheckBox.checked - text: catalog.i18nc("@label:listbox","Print support with:") - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - width: base.width/100* 35 - 2*UM.Theme.getSize("default_margin").width - height: visible ? mainExtruderLabel.height : 0 - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width - anchors.verticalCenter: supportExtruderCombobox.verticalCenter - } ComboBox { id: supportExtruderCombobox - visible: supportCheckBox.checked + visible: machineExtruderCount.properties.value > 1 model: extruderModel - height: visible ? mainExtruderCombobox.height : 0 - anchors.top: mainExtruderCombobox.bottom + + anchors.top: brimCheckBox.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height - anchors.left: supportExtruderLabel.right + anchors.left: supportHelperLabel.right + anchors.leftMargin: UM.Theme.getSize("default_margin").width + width: parent.width/100*45 + style: UM.Theme.styles.combobox - currentIndex: supportExtruderNr.properties.value + currentIndex: supportEnabled.properties.value == "True" ? parseFloat(supportExtruderNr.properties.value) + 1 : 0 onActivated: { - supportExtruderNr.setPropertyValue("value", index) + if(index==0) { + supportEnabled.setPropertyValue("value", false); + } else { + supportEnabled.setPropertyValue("value", true); + supportExtruderNr.setPropertyValue("value", index - 1); + } } } @@ -347,9 +312,22 @@ Item } } + function populateExtruderModel() + { + extruderModel.clear(); + extruderModel.append({ + text: catalog.i18nc("@label", "Don't print support") + }) + for(var extruder = 0; extruder < machineExtruderCount.properties.value ; extruder++) { + extruderModel.append({ + text: catalog.i18nc("@label", "Print using Extruder %1").arg(extruder + 1) + }) + } + } + Rectangle { id: tipsCell - anchors.top: multiExtrusionCell.visible? multiExtrusionCell.bottom : helpersCellRight.bottom + anchors.top: helpersCell.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.left: parent.left width: parent.width @@ -420,13 +398,4 @@ Item watchedProperties: [ "value" ] storeIndex: 0 } - UM.SettingPropertyProvider - { - id: mainExtruderNr - - containerStackId: Cura.MachineManager.activeMachineId - key: "extruder_nr" - watchedProperties: [ "value" ] - storeIndex: 0 - } } From 098cf515df2b233d3704db052d45ede72bb768ca Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 25 May 2016 19:02:55 +0200 Subject: [PATCH 271/705] Fix tooltips for simple mode helpers CURA-790 --- resources/qml/SidebarSimple.qml | 22 ++++++++++++++++++++-- resources/themes/cura/styles.qml | 4 ++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 36d92b6e78..30190c32b2 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -218,7 +218,7 @@ Item onEntered: { parent.hovered_ex = true - base.showTooltip(brimCheckBox, Qt.point(-helpersCellRight.x, 0), + base.showTooltip(brimCheckBox, Qt.point(-brimCheckBox.x, 0), catalog.i18nc("@label", "Enable printing a brim. This will add a single-layer-thick flat area around your object which is easy to cut off afterwards.")); } onExited: @@ -266,7 +266,7 @@ Item onEntered: { parent.hovered_ex = true - base.showTooltip(supportCheckBox, Qt.point(-helpersCellRight.x, 0), + base.showTooltip(supportCheckBox, Qt.point(-supportCheckBox.x, 0), catalog.i18nc("@label", "Enable printing support structures. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air.")); } onExited: @@ -289,6 +289,8 @@ Item width: parent.width/100*45 style: UM.Theme.styles.combobox + property bool hovered_ex: false + currentIndex: supportEnabled.properties.value == "True" ? parseFloat(supportExtruderNr.properties.value) + 1 : 0 onActivated: { if(index==0) { @@ -298,6 +300,22 @@ Item supportExtruderNr.setPropertyValue("value", index - 1); } } + MouseArea { + anchors.fill: parent + hoverEnabled: true + acceptedButtons: Qt.NoButton + onEntered: + { + parent.hovered_ex = true + base.showTooltip(supportExtruderCombobox, Qt.point(-supportExtruderCombobox.x, 0), + catalog.i18nc("@label", "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air.")); + } + onExited: + { + parent.hovered_ex = false + base.hideTooltip(); + } + } } ListModel { diff --git a/resources/themes/cura/styles.qml b/resources/themes/cura/styles.qml index cb85abf0c1..b2c2329169 100644 --- a/resources/themes/cura/styles.qml +++ b/resources/themes/cura/styles.qml @@ -286,11 +286,11 @@ QtObject { implicitHeight: UM.Theme.getSize("setting_control").height; implicitWidth: UM.Theme.getSize("setting_control").width; - color: control.hovered ? Theme.getColor("setting_control_highlight") : Theme.getColor("setting_control"); + color: (control.hovered || control.hovered_ex) ? Theme.getColor("setting_control_highlight") : Theme.getColor("setting_control"); Behavior on color { ColorAnimation { duration: 50; } } border.width: Theme.getSize("default_lining").width; - border.color: control.hovered ? Theme.getColor("setting_control_border_highlight") : Theme.getColor("setting_control_border"); + border.color: (control.hovered || control.hovered_ex) ? Theme.getColor("setting_control_border_highlight") : Theme.getColor("setting_control_border"); } label: Item { Label { From 6a77f67c34bd4e10996f1f9f28ce36aecd7e0d03 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 25 May 2016 23:27:46 +0200 Subject: [PATCH 272/705] Rearrange sidebar top CURA-340 --- resources/qml/Sidebar.qml | 22 +++++++++++----------- resources/qml/SidebarHeader.qml | 14 +------------- 2 files changed, 12 insertions(+), 24 deletions(-) diff --git a/resources/qml/Sidebar.qml b/resources/qml/Sidebar.qml index 81823f039d..4109fd1586 100644 --- a/resources/qml/Sidebar.qml +++ b/resources/qml/Sidebar.qml @@ -56,22 +56,13 @@ Rectangle configureMachinesAction: base.configureMachinesAction; } - Rectangle { - id: headerSeparator - width: parent.width - height: UM.Theme.getSize("sidebar_lining").height - color: UM.Theme.getColor("sidebar_lining") - anchors.top: header.bottom - anchors.topMargin: UM.Theme.getSize("default_margin").height - } - ProfileSetup { id: profileItem addProfileAction: base.addProfileAction updateProfileAction: base.updateProfileAction resetProfileAction: base.resetProfileAction manageProfilesAction: base.manageProfilesAction - anchors.top: settingsModeSelection.bottom + anchors.top: header.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height width: parent.width height: totalHeightProfileSetup @@ -80,6 +71,15 @@ Rectangle onHideTooltip: base.hideTooltip() } + Rectangle { + id: headerSeparator + width: parent.width + height: UM.Theme.getSize("sidebar_lining").height + color: UM.Theme.getColor("sidebar_lining") + anchors.top: profileItem.bottom + anchors.topMargin: UM.Theme.getSize("default_margin").height + } + currentModeIndex: { var index = parseInt(UM.Preferences.getValue("cura/active_mode")) @@ -172,7 +172,7 @@ Rectangle id: sidebarContents anchors.bottom: footerSeparator.top - anchors.top: profileItem.bottom + anchors.top: settingsModeSelection.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.left: base.left anchors.right: base.right diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index d8bc4291bb..f880485fc5 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -25,23 +25,11 @@ Item color: UM.Theme.getColor("sidebar_header_bar") } - Label{ - id: printjobTabLabel - text: catalog.i18nc("@label:listbox","Print Job"); - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width; - anchors.top: sidebarTabRow.bottom - anchors.topMargin: UM.Theme.getSize("default_margin").height - width: parent.width/100*45 - font: UM.Theme.getFont("large"); - color: UM.Theme.getColor("text") - } - Rectangle { id: machineSelectionRow width: base.width height: UM.Theme.getSize("sidebar_setup").height - anchors.top: printjobTabLabel.bottom + anchors.top: sidebarTabRow.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.horizontalCenter: parent.horizontalCenter From 85370dad8743b96b5ea5fcf3e99703b81f180cec Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 26 May 2016 08:15:53 +0200 Subject: [PATCH 273/705] Fix indent CURA-340 --- resources/qml/SidebarSimple.qml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 30190c32b2..c828b5d3db 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -322,12 +322,12 @@ Item id: extruderModel Component.onCompleted: populateExtruderModel() } - Connections - { - id: machineChange - target: Cura.MachineManager - onGlobalContainerChanged: populateExtruderModel() - } + Connections + { + id: machineChange + target: Cura.MachineManager + onGlobalContainerChanged: populateExtruderModel() + } } function populateExtruderModel() From f0b956c3c66fcfaf53a6a5e32c59968c72678d1c Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 26 May 2016 08:21:19 +0200 Subject: [PATCH 274/705] Add selection "tab" for active extruder Only visible for multi-extrusion printers. Doesn't do anything but setting a qml property, but is to be used to change the variant/material per extruder, and to apply a filter to the advanced mode settings. CURA-340 --- resources/qml/SidebarHeader.qml | 93 ++++++++++++++++++++++++++++++++- 1 file changed, 92 insertions(+), 1 deletion(-) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index f880485fc5..282fa8af25 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -16,6 +16,7 @@ Item property Action configureMachinesAction; UM.I18nCatalog { id: catalog; name:"cura"} property int totalHeightHeader: childrenRect.height + property int currentExtruderIndex; Rectangle { id: sidebarTabRow @@ -87,9 +88,89 @@ Item } Rectangle { - id: variantRow + id: extruderSelection + width: parent.width/100*55 + visible: machineExtruderCount.properties.value > 1 + height: visible ? UM.Theme.getSize("sidebar_header_mode_toggle").height : 0 + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("default_margin").width anchors.top: machineSelectionRow.bottom anchors.topMargin: visible ? UM.Theme.getSize("default_margin").height : 0 + Component{ + id: wizardDelegate + Button { + height: extruderSelection.height + anchors.left: parent.left + anchors.leftMargin: model.index * (extruderSelection.width / machineExtruderCount.properties.value) + anchors.verticalCenter: parent.verticalCenter + width: parent.width / machineExtruderCount.properties.value + text: model.text + exclusiveGroup: extruderMenuGroup; + checkable: true; + checked: base.currentExtruderIndex == index + onClicked: base.currentExtruderIndex = index + + style: ButtonStyle { + background: Rectangle { + border.width: UM.Theme.getSize("default_lining").width + border.color: control.checked ? UM.Theme.getColor("toggle_checked_border") : + control.pressed ? UM.Theme.getColor("toggle_active_border") : + control.hovered ? UM.Theme.getColor("toggle_hovered_border") : UM.Theme.getColor("toggle_unchecked_border") + color: control.checked ? UM.Theme.getColor("toggle_checked") : + control.pressed ? UM.Theme.getColor("toggle_active") : + control.hovered ? UM.Theme.getColor("toggle_hovered") : UM.Theme.getColor("toggle_unchecked") + Behavior on color { ColorAnimation { duration: 50; } } + Label { + anchors.centerIn: parent + color: control.checked ? UM.Theme.getColor("toggle_checked_text") : + control.pressed ? UM.Theme.getColor("toggle_active_text") : + control.hovered ? UM.Theme.getColor("toggle_hovered_text") : UM.Theme.getColor("toggle_unchecked_text") + font: UM.Theme.getFont("default") + text: control.text; + } + } + label: Item { } + } + } + } + ExclusiveGroup { id: extruderMenuGroup; } + ListView{ + id: extrudersList + property var index: 0 + model: extrudersListModel + delegate: wizardDelegate + anchors.top: parent.top + anchors.left: parent.left + width: parent.width + } + } + + ListModel + { + id: extrudersListModel + Component.onCompleted: populateExtruderModel() + } + Connections + { + id: machineChange + target: Cura.MachineManager + onGlobalContainerChanged: populateExtruderModel() + } + + function populateExtruderModel() + { + extrudersListModel.clear(); + for(var extruder = 0; extruder < machineExtruderCount.properties.value ; extruder++) { + extrudersListModel.append({ + text: catalog.i18nc("@label", "Extruder %1").arg(extruder + 1) + }) + } + } + + Rectangle { + id: variantRow + anchors.top: extruderSelection.visible ? extruderSelection.bottom : machineSelectionRow.bottom + anchors.topMargin: visible ? UM.Theme.getSize("default_margin").height : 0 width: base.width height: visible ? UM.Theme.getSize("sidebar_setup").height : 0 visible: Cura.MachineManager.hasVariants || Cura.MachineManager.hasMaterials @@ -214,4 +295,14 @@ Item } } } + + UM.SettingPropertyProvider + { + id: machineExtruderCount + + containerStackId: Cura.MachineManager.activeMachineId + key: "machine_extruder_count" + watchedProperties: [ "value" ] + storeIndex: 0 + } } From f7f9dc036e1a7a51f3cc98819f48ded47bfb22e0 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 26 May 2016 08:52:41 +0200 Subject: [PATCH 275/705] Show correct page when opening profile manager CURA-1278 --- resources/qml/Cura.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 6ea69c428b..04ca44369c 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -582,7 +582,7 @@ UM.MainWindow onTriggered: { UM.MachineManager.createProfile(); - preferences.setPage(4); + preferences.setPage(5); preferences.show(); // Show the renameDialog after a very short delay so the preference page has time to initiate @@ -606,7 +606,7 @@ UM.MainWindow onTriggered: { preferences.visible = true; - preferences.setPage(4); + preferences.setPage(5); } } From 5975fa1b0dd2ec35e82f351bdaa18d5015dea608 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 26 May 2016 13:29:56 +0200 Subject: [PATCH 276/705] Fix enabled state of setting items Contributes to CURA-1278 --- resources/qml/Settings/SettingView.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 0e99ecc4b7..51f854b519 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -34,11 +34,11 @@ ScrollView id: delegate width: UM.Theme.getSize("sidebar").width; - height: provider.properties.enabled ? UM.Theme.getSize("section").height : 0 + height: provider.properties.enabled == "True" ? UM.Theme.getSize("section").height : 0 Behavior on height { NumberAnimation { duration: 100 } } - opacity: provider.properties.enabled ? 1 : 0 + opacity: provider.properties.enabled == "True" ? 1 : 0 Behavior on opacity { NumberAnimation { duration: 100 } } - enabled: provider.properties.enabled + enabled: provider.properties.enabled == "True" property var definition: model property var settingDefinitionsModel: definitionsModel From d5fa6d884f4cc8d2ed8aed462000c4e3ccb34270 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 26 May 2016 13:32:14 +0200 Subject: [PATCH 277/705] Fix XML material profiles so the global properties are properly set Contributes to CURA-339 --- plugins/XmlMaterialProfile/XmlMaterialProfile.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 50c39238fd..d73beec193 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -69,13 +69,15 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): self.addMetaDataEntry("properties", property_values) + self.setDefinition(UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = "fdmprinter")[0]) + global_setting_values = {} settings = data.iterfind("./um:settings/um:setting", self.__namespaces) for entry in settings: key = entry.get("key") if key in self.__material_property_setting_map: self.setProperty(self.__material_property_setting_map[key], "value", entry.text, self._definition) - global_setting_values[key] = entry.text + global_setting_values[self.__material_property_setting_map[key]] = entry.text machines = data.iterfind("./um:settings/um:machine", self.__namespaces) for machine in machines: From 8804c2837f67664b0585fb14f044f202f3a80d46 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 26 May 2016 15:28:57 +0200 Subject: [PATCH 278/705] Make reset and restore default buttons work properly again Contributes to CURA-1278 --- resources/qml/Settings/SettingItem.qml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index ebbf93af84..013dcd1680 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -89,7 +89,7 @@ Item { { id: revertButton; - visible: propertyProvider.properties.state == "InstanceState.User" + visible: propertyProvider.stackLevel == 0 height: parent.height; width: height; @@ -102,8 +102,8 @@ Item { iconSource: UM.Theme.getIcon("reset") onClicked: { - base.resetRequested() - controlContainer.notifyReset(); + revertButton.focus = true + propertyProvider.removeFromContainer(0) } onEntered: base.showTooltip(catalog.i18nc("@label", "This setting has a value that is different from the profile.\n\nClick to restore the value of the profile.")) @@ -116,14 +116,14 @@ Item { id: inheritButton; //visible: has_profile_value && base.has_inherit_function && base.is_enabled - visible: propertyProvider.properties.state == "InstanceState.User" + visible: propertyProvider.properties.state == "InstanceState.User" && propertyProvider.stackLevel > 0 height: parent.height; width: height; onClicked: { - base.resetToDefaultRequested(); - controlContainer.notifyReset(); + focus = true; + propertyProvider.removeFromContainer(propertyProvider.stackLevel) } backgroundColor: UM.Theme.getColor("setting_control"); From 43ec037c554142b4cf72ef4b49850347cb9ad9f6 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 26 May 2016 15:29:56 +0200 Subject: [PATCH 279/705] Do not load ComboBox items asynchronously Since there is a bug with Qt 5.5 that will do strange reordering. Contributes to CURA-1278 --- resources/qml/Settings/SettingView.qml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 51f854b519..34b07ce780 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -45,7 +45,9 @@ ScrollView property var propertyProvider: provider //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989 - asynchronous: QT_VERSION_STR.split(".")[1] >= 5 + //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes, + //causing nasty issues when selecting differnt options. So disable asynchronous loading of enum type completely. + asynchronous: model.type != "enum" source: { From 4fc1407c00b3fb709ca59a074565532388520ffd Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 26 May 2016 15:32:08 +0200 Subject: [PATCH 280/705] Update variant profiles to use the right syntax for formulas Contributes to CURA-1278 --- resources/variants/ultimaker2_extended_plus_0.25.inst.cfg | 6 +++--- resources/variants/ultimaker2_extended_plus_0.4.inst.cfg | 6 +++--- resources/variants/ultimaker2_extended_plus_0.6.inst.cfg | 6 +++--- resources/variants/ultimaker2_extended_plus_0.8.inst.cfg | 6 +++--- resources/variants/ultimaker2_plus_0.25.inst.cfg | 6 +++--- resources/variants/ultimaker2_plus_0.4.inst.cfg | 6 +++--- resources/variants/ultimaker2_plus_0.6.inst.cfg | 6 +++--- resources/variants/ultimaker2_plus_0.8.inst.cfg | 6 +++--- 8 files changed, 24 insertions(+), 24 deletions(-) diff --git a/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg index 0c0154c03b..b499db6163 100644 --- a/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg @@ -12,6 +12,6 @@ machine_nozzle_size = 0.25 machine_nozzle_tip_outer_diameter = 0.8 coasting_volume = 0.1 coasting_min_volume = 0.17 -speed_wall = round(speed_print / 1.2, 1) -speed_wall_0 = 1 if speed_wall < 5 else (speed_wall - 5) -speed_topbottom = round(speed_print / 1.5, 1) +speed_wall = =round(speed_print / 1.2, 1) +speed_wall_0 = =1 if speed_wall < 5 else (speed_wall - 5) +speed_topbottom = =round(speed_print / 1.5, 1) diff --git a/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg index 87b74b2572..d2fb6f76b1 100644 --- a/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg @@ -10,6 +10,6 @@ type = variant [values] machine_nozzle_size = 0.4 machine_nozzle_tip_outer_diameter = 1.05 -speed_wall = round(speed_print / 1.25, 1) -speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) -speed_topbottom = round(speed_print / 2.25, 1) +speed_wall = =round(speed_print / 1.25, 1) +speed_wall_0 = =1 if speed_wall < 10 else (speed_wall - 10) +speed_topbottom = =round(speed_print / 2.25, 1) diff --git a/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg index 343b2d85e5..e4f9f0ce45 100644 --- a/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg @@ -11,6 +11,6 @@ type = variant machine_nozzle_size = 0.6 machine_nozzle_tip_outer_diameter = 1.25 coasting_volume = 1.36 -speed_wall = round(speed_print * 4 / 3, 1) -speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) -speed_topbottom = round(speed_print / 2, 1) +speed_wall = =round(speed_print * 4 / 3, 1) +speed_wall_0 = =1 if speed_wall < 10 else (speed_wall - 10) +speed_topbottom = =round(speed_print / 2, 1) diff --git a/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg index c1bb4555c1..18570ea75d 100644 --- a/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg @@ -11,6 +11,6 @@ type = variant machine_nozzle_size = 0.8 machine_nozzle_tip_outer_diameter = 1.35 coasting_volume = 3.22 -speed_wall = round(speed_print * 4 / 3, 1) -speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) -speed_topbottom = round(speed_print / 2, 1) +speed_wall = =round(speed_print * 4 / 3, 1) +speed_wall_0 = =1 if speed_wall < 10 else (speed_wall - 10) +speed_topbottom = =round(speed_print / 2, 1) diff --git a/resources/variants/ultimaker2_plus_0.25.inst.cfg b/resources/variants/ultimaker2_plus_0.25.inst.cfg index 51a4b44a4a..7cab771101 100644 --- a/resources/variants/ultimaker2_plus_0.25.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.25.inst.cfg @@ -12,6 +12,6 @@ machine_nozzle_size = 0.25 machine_nozzle_tip_outer_diameter = 0.8 coasting_volume = 0.1 coasting_min_volume = 0.17 -speed_wall = round(speed_print / 1.2, 1) -speed_wall_0 = 1 if speed_wall < 5 else (speed_wall - 5) -speed_topbottom = round(speed_print / 1.5, 1) +speed_wall = =round(speed_print / 1.2, 1) +speed_wall_0 = =1 if speed_wall < 5 else (speed_wall - 5) +speed_topbottom = =round(speed_print / 1.5, 1) diff --git a/resources/variants/ultimaker2_plus_0.4.inst.cfg b/resources/variants/ultimaker2_plus_0.4.inst.cfg index aaea23a8df..748f367250 100644 --- a/resources/variants/ultimaker2_plus_0.4.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.4.inst.cfg @@ -10,6 +10,6 @@ type = variant [values] machine_nozzle_size = 0.4 machine_nozzle_tip_outer_diameter = 1.05 -speed_wall = round(speed_print / 1.25, 1) -speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) -speed_topbottom = round(speed_print / 2.25, 1) +speed_wall = =round(speed_print / 1.25, 1) +speed_wall_0 = =1 if speed_wall < 10 else (speed_wall - 10) +speed_topbottom = =round(speed_print / 2.25, 1) diff --git a/resources/variants/ultimaker2_plus_0.6.inst.cfg b/resources/variants/ultimaker2_plus_0.6.inst.cfg index c416b2ec3c..34d0f7a5cf 100644 --- a/resources/variants/ultimaker2_plus_0.6.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.6.inst.cfg @@ -11,6 +11,6 @@ type = variant machine_nozzle_size = 0.6 machine_nozzle_tip_outer_diameter = 1.25 coasting_volume = 1.36 -speed_wall = round(speed_print * 4 / 3, 1) -speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) -speed_topbottom = round(speed_print / 2, 1) +speed_wall = =round(speed_print * 4 / 3, 1) +speed_wall_0 = =1 if speed_wall < 10 else (speed_wall - 10) +speed_topbottom = =round(speed_print / 2, 1) diff --git a/resources/variants/ultimaker2_plus_0.8.inst.cfg b/resources/variants/ultimaker2_plus_0.8.inst.cfg index 3b577384ec..e719409060 100644 --- a/resources/variants/ultimaker2_plus_0.8.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.8.inst.cfg @@ -11,6 +11,6 @@ type = variant machine_nozzle_size = 0.8 machine_nozzle_tip_outer_diameter = 1.35 coasting_volume = 3.22 -speed_wall = round(speed_print * 4 / 3, 1) -speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) -speed_topbottom = round(speed_print / 2, 1) +speed_wall = =round(speed_print * 4 / 3, 1) +speed_wall_0 = =1 if speed_wall < 10 else (speed_wall - 10) +speed_topbottom = =round(speed_print / 2, 1) From c814e47b0e1b61b6a8237bb5847067dca325f13a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 26 May 2016 15:35:28 +0200 Subject: [PATCH 281/705] SettingView now works with PreferenceVisibility handler CURA-1278 --- resources/qml/Settings/SettingView.qml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 0e99ecc4b7..1069774563 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -27,7 +27,11 @@ ScrollView id: contents spacing: UM.Theme.getSize("default_lining").height; - model: UM.SettingDefinitionsModel { id: definitionsModel; containerId: Cura.MachineManager.activeDefinitionId } + model: UM.SettingDefinitionsModel { + id: definitionsModel; + containerId: Cura.MachineManager.activeDefinitionId + visibilityHandler: UM.SettingPreferenceVisibilityHandler {} + } delegate: Loader { From 7ce4e236772380b306c04067b72c0476b3951638 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 26 May 2016 15:52:36 +0200 Subject: [PATCH 282/705] Add all categories to default visible list Since otherwise none of the children will be visible Contributes to CURA-1278 Fixes CURA-1614 --- cura/CuraApplication.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 9691b638a1..23e40e66b3 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -149,6 +149,7 @@ class CuraApplication(QtApplication): Preferences.getInstance().setDefault("local_file/last_used_type", "text/x-gcode") Preferences.getInstance().setDefault("general/visible_settings", """ + machine_settings resolution layer_height shell @@ -165,6 +166,7 @@ class CuraApplication(QtApplication): speed speed_print speed_travel + travel cooling cool_fan_enabled support @@ -177,8 +179,11 @@ class CuraApplication(QtApplication): raft_airgap layer_0_z_overlap raft_surface_layers + meshfix blackmagic print_sequence + dual + experimental """) JobQueue.getInstance().jobFinished.connect(self._onJobFinished) From e02e2bde8d242a3b788d9e53d9428927239fa03c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 26 May 2016 16:35:34 +0200 Subject: [PATCH 283/705] Remove semicolon at the end of the line --- .../CuraEngineBackend/CuraEngineBackend.py | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index d088288391..c9a0efbbcb 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -134,26 +134,26 @@ class CuraEngineBackend(Backend): self._process_layers_job.abort() self._process_layers_job = None - #Don't slice if there is a setting with an error value. - stack = Application.getInstance().getGlobalContainerStack() - for key in stack.getAllKeys(): - validation_state = stack.getProperty(key, "validationState") - #Only setting instances have a validation state, so settings which - #are not overwritten by any instance will have none. The property - #then, and only then, evaluates to None. We make the assumption that - #the definition defines the setting with a default value that is - #valid. Therefore we can allow both ValidatorState.Valid and None as - #allowable validation states. - #TODO: This assumption is wrong! If the definition defines an inheritance function that through inheritance evaluates to a disallowed value, a setting is still invalid even though it's default! - #TODO: Therefore we must also validate setting definitions. - if validation_state != None and validation_state != ValidatorState.Valid: - Logger.log("w", "Setting %s is not valid, but %s. Aborting slicing.", key, validation_state) - if self._message: #Hide any old message before creating a new one. - self._message.hide() - self._message = None - self._message = Message(catalog.i18nc("@info:status", "Unable to slice. Please check your setting values for errors.")) - self._message.show() - return + # #Don't slice if there is a setting with an error value. + # stack = Application.getInstance().getGlobalContainerStack() + # for key in stack.getAllKeys(): + # validation_state = stack.getProperty(key, "validationState") + # #Only setting instances have a validation state, so settings which + # #are not overwritten by any instance will have none. The property + # #then, and only then, evaluates to None. We make the assumption that + # #the definition defines the setting with a default value that is + # #valid. Therefore we can allow both ValidatorState.Valid and None as + # #allowable validation states. + # #TODO: This assumption is wrong! If the definition defines an inheritance function that through inheritance evaluates to a disallowed value, a setting is still invalid even though it's default! + # #TODO: Therefore we must also validate setting definitions. + # if validation_state != None and validation_state != ValidatorState.Valid: + # Logger.log("w", "Setting %s is not valid, but %s. Aborting slicing.", key, validation_state) + # if self._message: #Hide any old message before creating a new one. + # self._message.hide() + # self._message = None + # self._message = Message(catalog.i18nc("@info:status", "Unable to slice. Please check your setting values for errors.")) + # self._message.show() + # return self.processingProgress.emit(0.0) self.backendStateChange.emit(BackendState.NOT_STARTED) @@ -168,7 +168,7 @@ class CuraEngineBackend(Backend): self.slicingStarted.emit() slice_message = self._socket.createMessage("cura.proto.Slice") - settings_message = self._socket.createMessage("cura.proto.SettingList"); + settings_message = self._socket.createMessage("cura.proto.SettingList") self._start_slice_job = StartSliceJob.StartSliceJob(slice_message, settings_message) self._start_slice_job.start() self._start_slice_job.finished.connect(self._onStartSliceCompleted) From 214d385dae06952d5e6af212f453effe70636c58 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 26 May 2016 17:11:41 +0200 Subject: [PATCH 284/705] fix: moved extruder definition settings to a new file fdmextruder.def.json (CURA-1616) --- resources/definitions/fdmextruder.def.json | 119 +++++++++++++++++++++ resources/definitions/fdmprinter.def.json | 100 +---------------- 2 files changed, 124 insertions(+), 95 deletions(-) create mode 100644 resources/definitions/fdmextruder.def.json diff --git a/resources/definitions/fdmextruder.def.json b/resources/definitions/fdmextruder.def.json new file mode 100644 index 0000000000..6533d211c5 --- /dev/null +++ b/resources/definitions/fdmextruder.def.json @@ -0,0 +1,119 @@ +{ + "id": "fdmextruder", + "name": "Extruder", + "version": 2, + "metadata": + { + "type": "extruder", + "author": "Ultimaker B.V.", + "manufacturer": "Ultimaker", + "visible": false + }, + "settings": + { + "machine_settings": + { + "label": "Machine", + "type": "category", + "description": "Machine specific settings", + "children": + { + "extruder_nr": + { + "label": "Extruder", + "description": "The extruder train used for printing. This is used in multi-extrusion.", + "type": "int", + "default_value": 0, + "minimum_value": "0", + "maximum_value": "machine_extruder_count - 1" + }, + "machine_nozzle_offset_x": + { + "label": "Nozzle X Offset", + "description": "The x-coordinate of the offset of the nozzle.", + "type": "float", + "unit": "mm", + "default_value": 0, + "global_only": "True" + }, + "machine_nozzle_offset_y": + { + "label": "Nozzle Y Offset", + "description": "The y-coordinate of the offset of the nozzle.", + "type": "float", + "unit": "mm", + "default_value": 0, + "global_only": "True" + }, + "machine_extruder_start_code": + { + "label": "Extruder Start G-Code", + "description": "Start g-code to execute whenever turning the extruder on.", + "type": "str", + "default_value": "", + "global_only": "True" + }, + "machine_extruder_start_pos_abs": + { + "label": "Extruder Start Position Absolute", + "description": "Make the extruder starting position absolute rather than relative to the last-known location of the head.", + "type": "bool", + "default_value": false, + "global_only": "True" + }, + "machine_extruder_start_pos_x": + { + "label": "Extruder Start Position X", + "description": "The x-coordinate of the starting position when turning the extruder on.", + "type": "float", + "unit": "mm", + "default_value": 0, + "global_only": "True" + }, + "machine_extruder_start_pos_y": + { + "label": "Extruder Start Position Y", + "description": "The y-coordinate of the starting position when turning the extruder on.", + "type": "float", + "unit": "mm", + "default_value": 0, + "global_only": "True" + }, + "machine_extruder_end_code": + { + "label": "Extruder End G-Code", + "description": "End g-code to execute whenever turning the extruder off.", + "type": "str", + "default_value": "", + "global_only": "True" + }, + "machine_extruder_end_pos_abs": + { + "label": "Extruder End Position Absolute", + "description": "Make the extruder ending position absolute rather than relative to the last-known location of the head.", + "type": "bool", + "default_value": false, + "global_only": "True" + }, + "machine_extruder_end_pos_x": + { + "label": "Extruder End Position X", + "description": "The x-coordinate of the ending position when turning the extruder off.", + "type": "float", + "unit": "mm", + "default_value": 0, + "global_only": "True" + }, + "machine_extruder_end_pos_y": + { + "label": "Extruder End Position Y", + "description": "The y-coordinate of the ending position when turning the extruder off.", + "type": "float", + "unit": "mm", + "default_value": 0, + "global_only": "True" + }, + } + } + } +} diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 150fbbdffc..f8400d6d62 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -4,6 +4,7 @@ "version": 2, "metadata": { + "type": "machine", "author": "Ultimaker B.V.", "category": "Ultimaker", "manufacturer": "Ultimaker", @@ -12,6 +13,10 @@ "preferred_material": "pla", "preferred_quality": "normal" }, + "machine_extruder_trains": + { + "0": "fdmextruder" + }, "settings": { "machine_settings": @@ -242,92 +247,6 @@ "minimum_value": "0.001", "maximum_value_warning": "10" }, - "machine_nozzle_offset_x": - { - "label": "Nozzle X Offset", - "description": "The x-coordinate of the offset of the nozzle.", - "type": "float", - "unit": "mm", - "default_value": 0, - "global_only": "True" - }, - "machine_nozzle_offset_y": - { - "label": "Nozzle Y Offset", - "description": "The y-coordinate of the offset of the nozzle.", - "type": "float", - "unit": "mm", - "default_value": 0, - "global_only": "True" - }, - "machine_extruder_start_code": - { - "label": "Extruder Start G-Code", - "description": "Start g-code to execute whenever turning the extruder on.", - "type": "str", - "default_value": "", - "global_only": "True" - }, - "machine_extruder_start_pos_abs": - { - "label": "Extruder Start Position Absolute", - "description": "Make the extruder starting position absolute rather than relative to the last-known location of the head.", - "type": "bool", - "default_value": false, - "global_only": "True" - }, - "machine_extruder_start_pos_x": - { - "label": "Extruder Start Position X", - "description": "The x-coordinate of the starting position when turning the extruder on.", - "type": "float", - "unit": "mm", - "default_value": 0, - "global_only": "True" - }, - "machine_extruder_start_pos_y": - { - "label": "Extruder Start Position Y", - "description": "The y-coordinate of the starting position when turning the extruder on.", - "type": "float", - "unit": "mm", - "default_value": 0, - "global_only": "True" - }, - "machine_extruder_end_code": - { - "label": "Extruder End G-Code", - "description": "End g-code to execute whenever turning the extruder off.", - "type": "str", - "default_value": "", - "global_only": "True" - }, - "machine_extruder_end_pos_abs": - { - "label": "Extruder End Position Absolute", - "description": "Make the extruder ending position absolute rather than relative to the last-known location of the head.", - "type": "bool", - "default_value": false, - "global_only": "True" - }, - "machine_extruder_end_pos_x": - { - "label": "Extruder End Position X", - "description": "The x-coordinate of the ending position when turning the extruder off.", - "type": "float", - "unit": "mm", - "default_value": 0, - "global_only": "True" - }, - "machine_extruder_end_pos_y": - { - "label": "Extruder End Position Y", - "description": "The y-coordinate of the ending position when turning the extruder off.", - "type": "float", - "unit": "mm", - "default_value": 0, - "global_only": "True" - }, "machine_use_extruder_offset_to_offset_coords": { "label": "Offset With Extruder", @@ -2201,15 +2120,6 @@ "description": "Settings used for printing with multiple extruders.", "children": { - "extruder_nr": - { - "label": "Extruder", - "description": "The extruder train used for printing. This is used in multi-extrusion.", - "type": "int", - "default_value": 0, - "minimum_value": "0", - "maximum_value": "machine_extruder_count - 1" - }, "adhesion_extruder_nr": { "label": "Platform Adhesion Extruder", From c01e7144d16511148db002a0316ae077e176ca0a Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 26 May 2016 18:06:40 +0200 Subject: [PATCH 285/705] Consistently change the spelling of bounding box bounding box, bounding_box, boundingBox --- cura/CuraApplication.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 9691b638a1..48f283f7f1 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -111,7 +111,7 @@ class CuraApplication(QtApplication): self._i18n_catalog = None self._previous_active_tool = None self._platform_activity = False - self._scene_boundingbox = AxisAlignedBox() + self._scene_bounding_box = AxisAlignedBox() self._job_name = None self._center_after_select = False self._camera_animation = None @@ -384,26 +384,26 @@ class CuraApplication(QtApplication): @pyqtProperty(str, notify = sceneBoundingBoxChanged) def getSceneBoundingBoxString(self): - return self._i18n_catalog.i18nc("@info", "%(width).1f x %(depth).1f x %(height).1f mm") % {'width' : self._scene_boundingbox.width.item(), 'depth': self._scene_boundingbox.depth.item(), 'height' : self._scene_boundingbox.height.item()} + return self._i18n_catalog.i18nc("@info", "%(width).1f x %(depth).1f x %(height).1f mm") % {'width' : self._scene_bounding_box.width.item(), 'depth': self._scene_bounding_box.depth.item(), 'height' : self._scene_bounding_box.height.item()} def updatePlatformActivity(self, node = None): count = 0 - scene_boundingbox = None + scene_bounding_box = None for node in DepthFirstIterator(self.getController().getScene().getRoot()): if type(node) is not SceneNode or not node.getMeshData(): continue count += 1 - if not scene_boundingbox: - scene_boundingbox = copy.deepcopy(node.getBoundingBox()) + if not scene_bounding_box: + scene_bounding_box = copy.deepcopy(node.getBoundingBox()) else: - scene_boundingbox += node.getBoundingBox() + scene_bounding_box += node.getBoundingBox() - if not scene_boundingbox: - scene_boundingbox = AxisAlignedBox() + if not scene_bounding_box: + scene_bounding_box = AxisAlignedBox() - if repr(self._scene_boundingbox) != repr(scene_boundingbox): - self._scene_boundingbox = scene_boundingbox + if repr(self._scene_bounding_box) != repr(scene_bounding_box): + self._scene_bounding_box = scene_bounding_box self.sceneBoundingBoxChanged.emit() self._platform_activity = True if count > 0 else False From 53661b27393395183aa69889485baab40c385e32 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 26 May 2016 22:18:34 +0200 Subject: [PATCH 286/705] Ensure a machine gets a unique names when adding or renaming a machine CURA-1606 --- cura/MachineManagerModel.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 8354f3a140..64990f9ab7 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -5,6 +5,8 @@ from UM.Preferences import Preferences import UM.Settings +import re + class MachineManagerModel(QObject): def __init__(self, parent = None): super().__init__(parent) @@ -64,6 +66,7 @@ class MachineManagerModel(QObject): definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id=definition_id) if definitions: definition = definitions[0] + name = self._uniqueMachineName(name, definition.getName()) new_global_stack = UM.Settings.ContainerStack(name) new_global_stack.addMetaDataEntry("type", "machine") @@ -127,6 +130,25 @@ class MachineManagerModel(QObject): Application.getInstance().setGlobalContainerStack(new_global_stack) + # Create a name that is not empty and unique + def _uniqueMachineName(self, name, fallback_name): + name = name.strip() + num_check = re.compile("(.*?)\s*#\d$").match(name) + if(num_check): + name = num_check.group(1) + if name == "": + name = fallback_name + unique_name = name + i = 1 + + #Check both the id and the name, because they may not be the same and it is better if they are both unique + while UM.Settings.ContainerRegistry.getInstance().findContainers(None, id = unique_name) or + UM.Settings.ContainerRegistry.getInstance().findContainers(None, name = unique_name): + i = i + 1 + unique_name = "%s #%d" % (name, i) + + return unique_name + @pyqtProperty(str, notify = globalContainerChanged) def activeMachineName(self): if self._global_container_stack: @@ -239,6 +261,7 @@ class MachineManagerModel(QObject): def renameMachine(self, machine_id, new_name): containers = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = machine_id) if containers: + new_name = self._uniqueMachineName(new_name, containers[0].getBottom().getName()) containers[0].setName(new_name) @pyqtSlot(str) From b60e704aa6cfa86cb8c7b088ca8b94943affae06 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 26 May 2016 22:29:21 +0200 Subject: [PATCH 287/705] Fix typo CURA-1606 --- cura/MachineManagerModel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 64990f9ab7..11cb55d2b4 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -142,8 +142,8 @@ class MachineManagerModel(QObject): i = 1 #Check both the id and the name, because they may not be the same and it is better if they are both unique - while UM.Settings.ContainerRegistry.getInstance().findContainers(None, id = unique_name) or - UM.Settings.ContainerRegistry.getInstance().findContainers(None, name = unique_name): + while UM.Settings.ContainerRegistry.getInstance().findContainers(None, id = unique_name) or \ + UM.Settings.ContainerRegistry.getInstance().findContainers(None, name = unique_name): i = i + 1 unique_name = "%s #%d" % (name, i) From 3311fa8033f8cf8832e972fc6b78f1c2ab0f462c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 27 May 2016 10:23:28 +0200 Subject: [PATCH 288/705] Add resource type for extruder definitions The definition is derived with inheritance, just like the printers. Therefore I decided to call this 'ExtruderStack' in line with how the resource type for the printer is named. Contributes to issue CURA-1278. --- cura/CuraApplication.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 0e7f3b4b42..403cda19e8 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -75,7 +75,7 @@ class CuraApplication(QtApplication): VariantInstanceContainer = Resources.UserType + 5 UserInstanceContainer = Resources.UserType + 6 MachineStack = Resources.UserType + 7 - ExtruderInstanceContainer = Resources.UserType + 8 + ExtruderStack = Resources.UserType + 8 Q_ENUMS(ResourceTypes) @@ -127,13 +127,14 @@ class CuraApplication(QtApplication): Resources.addStorageType(self.ResourceTypes.QualityInstanceContainer, "quality") Resources.addStorageType(self.ResourceTypes.VariantInstanceContainer, "variants") Resources.addStorageType(self.ResourceTypes.MaterialInstanceContainer, "materials") - Resources.addStorageType(self.ResourceTypes.ExtruderInstanceContainer, "extruders") + Resources.addStorageType(self.ResourceTypes.ExtruderStack, "extruders") Resources.addStorageType(self.ResourceTypes.UserInstanceContainer, "user") Resources.addStorageType(self.ResourceTypes.MachineStack, "machine_instances") ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.QualityInstanceContainer) ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.VariantInstanceContainer) ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MaterialInstanceContainer) + ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.ExtruderStack) ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.UserInstanceContainer) ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MachineStack) From c9144460608e4b37ce850c51ac71439b54b14930 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 27 May 2016 11:26:41 +0200 Subject: [PATCH 289/705] Initial changes for perobject stuff CURA-1278 --- cura/SettingOverrideDecorator.py | 4 +- .../PerObjectSettingsTool/PerObjectItem.qml | 4 +- .../PerObjectSettingVisibilityHandler.py | 76 +++++++++++++++++ .../PerObjectSettingsModel.py | 33 +++----- .../PerObjectSettingsPanel.qml | 82 ++++++------------- plugins/PerObjectSettingsTool/__init__.py | 4 + 6 files changed, 119 insertions(+), 84 deletions(-) create mode 100644 plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py diff --git a/cura/SettingOverrideDecorator.py b/cura/SettingOverrideDecorator.py index 826970c51f..ae06be8512 100644 --- a/cura/SettingOverrideDecorator.py +++ b/cura/SettingOverrideDecorator.py @@ -14,8 +14,8 @@ from UM.Application import Application class SettingOverrideDecorator(SceneNodeDecorator): def __init__(self): super().__init__() - self._stack = ContainerStack(id = "SettingOverrideStack") - self._instance = InstanceContainer(id = "SettingOverrideInstanceContainer") + self._stack = ContainerStack(stack_id = "SettingOverrideStack") + self._instance = InstanceContainer(container_id = "SettingOverrideInstanceContainer") self._stack.addContainer(self._instance) Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged) diff --git a/plugins/PerObjectSettingsTool/PerObjectItem.qml b/plugins/PerObjectSettingsTool/PerObjectItem.qml index d2243ab562..e0d389443f 100644 --- a/plugins/PerObjectSettingsTool/PerObjectItem.qml +++ b/plugins/PerObjectSettingsTool/PerObjectItem.qml @@ -16,13 +16,13 @@ UM.TooltipArea width: childrenRect.width; height: childrenRect.height; - Button + CheckBox { id: check text: definition.label - //onClicked: delegateItem.settingsModel.setSettingVisible(model.key, checked); + onClicked: addedSettingsModel.setVisible(model.key, checked); } } diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py b/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py new file mode 100644 index 0000000000..e56ad520c6 --- /dev/null +++ b/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py @@ -0,0 +1,76 @@ +from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal +from UM.Application import Application +from UM.Settings.SettingInstance import SettingInstance +from UM.Logger import Logger + +from cura.SettingOverrideDecorator import SettingOverrideDecorator + + +class PerObjectSettingVisibilityHandler(QObject): + def __init__(self, parent = None, *args, **kwargs): + super().__init__(parent = parent, *args, **kwargs) + self._selected_object_id = None + + visibilityChanged = pyqtSignal() + + def setSelectedObjectId(self, id): + self._selected_object_id = id + self.visibilityChanged.emit() + + @pyqtProperty("quint64", fset = setSelectedObjectId) + def selectedObjectId(self): + pass + + def setVisible(self, visible): + node = Application.getInstance().getController().getScene().findObject(self._selected_object_id) + if not node: + return + stack = node.callDecoration("getStack") + if not stack: + node.addDecorator(SettingOverrideDecorator()) + stack = node.callDecoration("getStack") + + settings = stack.getTop() + all_instances = settings.findInstances(**{}) + visibility_changed = False # Flag to check if at the end the signal needs to be emitted + + # Remove all instances that are not in visibility list + for instance in all_instances: + if instance.definition.key not in visible: + settings.removeInstance(instance.definition.key) + visibility_changed = True + + # Add all instances that are not added, but are in visiblity list + for item in visible: + if not settings.getInstance(item): + definition_container = Application.getInstance().getGlobalContainerStack().getBottom() + definitions = definition_container.findDefinitions(key = item) + if definitions: + settings.addInstance(SettingInstance(definitions[0], settings)) + visibility_changed = True + else: + Logger.log("w", "Unable to add instance (%s) to perobject visibility because we couldn't find the matching definition", item) + + if visibility_changed: + self.visibilityChanged.emit() + #settings.addInstance(SettingInstance()) + + def getVisible(self): + visible_settings = set() + node = Application.getInstance().getController().getScene().findObject(self._selected_object_id) + if not node: + return visible_settings + + stack = node.callDecoration("getStack") + if not stack: + return visible_settings + + settings = stack.getTop() + if not settings: + return visible_settings + + all_instances = settings.findInstances(**{}) + for instance in all_instances: + visible_settings.add(instance.definition.key) + return visible_settings + diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsModel.py b/plugins/PerObjectSettingsTool/PerObjectSettingsModel.py index cbe22d129e..74a1fbed9a 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsModel.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsModel.py @@ -13,21 +13,14 @@ from UM.Scene.SceneNode import SceneNode from . import SettingOverrideModel class PerObjectSettingsModel(ListModel): - IdRole = Qt.UserRole + 1 - XRole = Qt.UserRole + 2 - YRole = Qt.UserRole + 3 - MaterialRole = Qt.UserRole + 4 - ProfileRole = Qt.UserRole + 5 - SettingsRole = Qt.UserRole + 6 + IdRole = Qt.UserRole + 1 # ID of the node def __init__(self, parent = None): super().__init__(parent) self._scene = Application.getInstance().getController().getScene() self._root = self._scene.getRoot() self.addRoleName(self.IdRole,"id") - self.addRoleName(self.MaterialRole, "material") - self.addRoleName(self.ProfileRole, "profile") - self.addRoleName(self.SettingsRole, "settings") + self._updateModel() @pyqtSlot("quint64", str) @@ -48,7 +41,7 @@ class PerObjectSettingsModel(ListModel): node.removeDecorator(ProfileOverrideDecorator)''' @pyqtSlot("quint64", str) - def addSettingOverride(self, object_id, key): + def addOverride(self, object_id, key): machine = Application.getInstance().getMachineManager().getActiveMachineInstance() if not machine: return @@ -60,7 +53,7 @@ class PerObjectSettingsModel(ListModel): node.callDecoration("addSetting", key) @pyqtSlot("quint64", str) - def removeSettingOverride(self, object_id, key): + def removerOverride(self, object_id, key): node = self._scene.findObject(object_id) node.callDecoration("removeSetting", key) @@ -69,18 +62,14 @@ class PerObjectSettingsModel(ListModel): def _updateModel(self): self.clear() + for node in BreadthFirstIterator(self._root): if type(node) is not SceneNode or not node.isSelectable(): continue - node_profile = node.callDecoration("getProfile") - if not node_profile: - node_profile = "global" - else: - node_profile = node_profile.getName() - self.appendItem({ - "id": id(node), - "material": "", - "profile": node_profile, - "settings": SettingOverrideModel.SettingOverrideModel(node) - }) + node_stack = node.callDecoration("getStack") + + if not node_stack: + self.appendItem({ + "id": id(node) + }) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index 9b78116d24..5213c7ee58 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -20,73 +20,38 @@ Item { width: childrenRect.width; height: childrenRect.height; - Column { + Column + { id: items anchors.top: parent.top; anchors.left: parent.left; spacing: UM.Theme.getSize("default_margin").height; - - Column { - id: customisedSettings + height: childrenRect.height; + ListView + { + id: contents spacing: UM.Theme.getSize("default_lining").height; - width: UM.Theme.getSize("setting").width + UM.Theme.getSize("setting").height/2; + height: childrenRect.height; - Repeater { - id: settings; - - model: UM.ActiveTool.properties.getValue("Model").getItem(base.currentIndex).settings - - UM.SettingItem { - width: UM.Theme.getSize("setting").width; - height: UM.Theme.getSize("setting").height; - - name: model.label; - type: model.type; - value: model.value; - description: model.description; - unit: model.unit; - valid: model.valid; - visible: !model.global_only - options: model.options - indent: false - - style: UM.Theme.styles.setting_item; - - onItemValueChanged: { - settings.model.setSettingValue(model.key, value) - } - - Button - { - anchors.left: parent.right; - - width: UM.Theme.getSize("setting").height; - height: UM.Theme.getSize("setting").height; - - onClicked: UM.ActiveTool.properties.getValue("Model").removeSettingOverride(UM.ActiveTool.properties.getValue("Model").getItem(base.currentIndex).id, model.key) - - style: ButtonStyle - { - background: Rectangle - { - color: control.hovered ? control.parent.style.controlHighlightColor : control.parent.style.controlColor; - UM.RecolorImage - { - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - width: parent.width/2 - height: parent.height/2 - sourceSize.width: width - sourceSize.height: width - color: control.hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button") - source: UM.Theme.getIcon("cross1") - } - } - } - } + model: UM.SettingDefinitionsModel { + id: addedSettingsModel; + containerId: Cura.MachineManager.activeDefinitionId + visibilityHandler: Cura.PerObjectSettingVisibilityHandler { + selectedObjectId: UM.ActiveTool.properties.getValue("Model").getItem(base.currentIndex).id } } + + delegate:Button + { + anchors.left: parent.right; + + width: 150 + height:50 + + text: model.label + } + } Button @@ -184,6 +149,7 @@ Item { { "global_only": false } + visibilityHandler: UM.SettingPreferenceVisibilityHandler {} } delegate:Loader { diff --git a/plugins/PerObjectSettingsTool/__init__.py b/plugins/PerObjectSettingsTool/__init__.py index d5d249b430..1779556ade 100644 --- a/plugins/PerObjectSettingsTool/__init__.py +++ b/plugins/PerObjectSettingsTool/__init__.py @@ -2,6 +2,8 @@ # Uranium is released under the terms of the AGPLv3 or higher. from . import PerObjectSettingsTool +from . import PerObjectSettingVisibilityHandler +from PyQt5.QtQml import qmlRegisterType from UM.i18n import i18nCatalog i18n_catalog = i18nCatalog("cura") @@ -25,4 +27,6 @@ def getMetaData(): } def register(app): + qmlRegisterType(PerObjectSettingVisibilityHandler.PerObjectSettingVisibilityHandler, "Cura", 1, 0, + "PerObjectSettingVisibilityHandler") return { "tool": PerObjectSettingsTool.PerObjectSettingsTool() } From 64a613f407ad4065d5c30a96dbad82eae59c63d9 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 27 May 2016 11:47:50 +0200 Subject: [PATCH 290/705] Fix "Activate" button on the Manage Printers page CURA-1278 --- resources/qml/MachinesPage.qml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/qml/MachinesPage.qml b/resources/qml/MachinesPage.qml index 14425acc05..8c7a2c521d 100644 --- a/resources/qml/MachinesPage.qml +++ b/resources/qml/MachinesPage.qml @@ -22,9 +22,11 @@ UM.ManagementPage onAddObject: Printer.requestAddPrinter() onRemoveObject: confirmDialog.open(); onRenameObject: renameDialog.open(); + onActivateObject: Cura.MachineManager.setActiveMachine(base.currentItem.id) - removeEnabled: numInstances > 1 - renameEnabled: numInstances > 0 + removeEnabled: base.currentItem != null && numInstances > 1 + renameEnabled: base.currentItem != null && numInstances > 0 + activateEnabled: base.currentItem != null Flow { From 63556318425f595129aaee1aa8b6e98f1c9d1e39 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 27 May 2016 11:53:53 +0200 Subject: [PATCH 291/705] Activate another machine when we remove the currently active MachineManagerModel CURA-1278 --- cura/MachineManagerModel.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 11cb55d2b4..7b42483fca 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -266,6 +266,11 @@ class MachineManagerModel(QObject): @pyqtSlot(str) def removeMachine(self, machine_id): + # If the machine that is being removed is the currently active machine, set another machine as the active machine + if self._global_container_stack and self._global_container_stack.getId() == machine_id: + containers = UM.Settings.ContainerRegistry.getInstance().findContainerStacks() + if containers: + Application.getInstance().setGlobalContainerStack(containers[0]) UM.Settings.ContainerRegistry.getInstance().removeContainer(machine_id) @pyqtProperty(bool, notify = globalContainerChanged) From aa2d09aa0863b42284b001bbe99171ae26bbc2a0 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Fri, 27 May 2016 12:44:49 +0200 Subject: [PATCH 292/705] JSON lil fix: superflious comma (CURA-1616) --- resources/definitions/fdmextruder.def.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/definitions/fdmextruder.def.json b/resources/definitions/fdmextruder.def.json index 6533d211c5..e9be929e72 100644 --- a/resources/definitions/fdmextruder.def.json +++ b/resources/definitions/fdmextruder.def.json @@ -112,7 +112,7 @@ "unit": "mm", "default_value": 0, "global_only": "True" - }, + } } } } From 990d05815be06e3929978f67c61465b611898e5d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 27 May 2016 14:00:38 +0200 Subject: [PATCH 293/705] Added qml files to import path --- cura/CuraApplication.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 0e7f3b4b42..29e2fe4667 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -320,6 +320,7 @@ class CuraApplication(QtApplication): MachineManagerModel.createMachineManagerModel) self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml")) + self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles)) self.initializeEngine() if self._engine.rootObjects: From 41425fd36e35bfb74a8bc53e06106c55a7d2b10f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 27 May 2016 14:39:53 +0200 Subject: [PATCH 294/705] Replace symbols in default visible settings before usage These characters are just for visualisation in the code. They should never be used during the normal operation of the program, nor should they be saved to the file. So just replace them immediately. Contributes to issue CURA-1278. --- cura/CuraApplication.py | 72 ++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 2b0feb2b23..f0610a3538 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -150,42 +150,42 @@ class CuraApplication(QtApplication): Preferences.getInstance().setDefault("local_file/last_used_type", "text/x-gcode") Preferences.getInstance().setDefault("general/visible_settings", """ - machine_settings - resolution - layer_height - shell - wall_thickness - top_bottom_thickness - infill - infill_sparse_density - material - material_print_temperature - material_bed_temperature - material_diameter - material_flow - retraction_enable - speed - speed_print - speed_travel - travel - cooling - cool_fan_enabled - support - support_enable - support_type - support_roof_density - platform_adhesion - adhesion_type - brim_width - raft_airgap - layer_0_z_overlap - raft_surface_layers - meshfix - blackmagic - print_sequence - dual - experimental - """) + machine_settings + resolution + layer_height + shell + wall_thickness + top_bottom_thickness + infill + infill_sparse_density + material + material_print_temperature + material_bed_temperature + material_diameter + material_flow + retraction_enable + speed + speed_print + speed_travel + travel + cooling + cool_fan_enabled + support + support_enable + support_type + support_roof_density + platform_adhesion + adhesion_type + brim_width + raft_airgap + layer_0_z_overlap + raft_surface_layers + meshfix + blackmagic + print_sequence + dual + experimental + """.replace("\n", ";").replace(" ", "")) JobQueue.getInstance().jobFinished.connect(self._onJobFinished) From 89c1136d7fccd6f8370a10bc3ede18baba6b6a81 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 27 May 2016 15:28:54 +0200 Subject: [PATCH 295/705] Per object settings can now be added & changed CURA-1278 --- cura/SettingOverrideDecorator.py | 4 +- .../PerObjectSettingsTool/PerObjectItem.qml | 9 ++- .../PerObjectSettingVisibilityHandler.py | 1 - .../PerObjectSettingsPanel.qml | 68 +++++++++++++++---- .../PerObjectSettingsTool.py | 33 +++++---- 5 files changed, 85 insertions(+), 30 deletions(-) diff --git a/cura/SettingOverrideDecorator.py b/cura/SettingOverrideDecorator.py index ae06be8512..3e8815ec67 100644 --- a/cura/SettingOverrideDecorator.py +++ b/cura/SettingOverrideDecorator.py @@ -14,10 +14,12 @@ from UM.Application import Application class SettingOverrideDecorator(SceneNodeDecorator): def __init__(self): super().__init__() - self._stack = ContainerStack(stack_id = "SettingOverrideStack") + self._stack = ContainerStack(stack_id = id(self)) self._instance = InstanceContainer(container_id = "SettingOverrideInstanceContainer") self._stack.addContainer(self._instance) + ContainerRegistry.getInstance().addContainer(self._stack) + Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged) self._onGlobalContainerStackChanged() diff --git a/plugins/PerObjectSettingsTool/PerObjectItem.qml b/plugins/PerObjectSettingsTool/PerObjectItem.qml index e0d389443f..2dddf0b444 100644 --- a/plugins/PerObjectSettingsTool/PerObjectItem.qml +++ b/plugins/PerObjectSettingsTool/PerObjectItem.qml @@ -16,13 +16,18 @@ UM.TooltipArea width: childrenRect.width; height: childrenRect.height; - CheckBox + Button { id: check text: definition.label - onClicked: addedSettingsModel.setVisible(model.key, checked); + onClicked: + { + addedSettingsModel.setVisible(model.key, true); + settingPickDialog.visible = false + UM.ActiveTool.forceUpdate() + } } } diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py b/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py index e56ad520c6..9ef2515bed 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py @@ -53,7 +53,6 @@ class PerObjectSettingVisibilityHandler(QObject): if visibility_changed: self.visibilityChanged.emit() - #settings.addInstance(SettingInstance()) def getVisible(self): visible_settings = set() diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index 5213c7ee58..8c9b63ac1b 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -10,16 +10,20 @@ import UM 1.2 as UM import Cura 1.0 as Cura import ".." - Item { id: base; - property int currentIndex: UM.ActiveTool.properties.getValue("SelectedIndex") UM.I18nCatalog { id: catalog; name: "cura"; } width: childrenRect.width; height: childrenRect.height; + + function updateContainerID() + { + console.log("containerid",UM.ActiveTool.properties.getValue("ContainerID")) + } + Column { id: items @@ -27,33 +31,69 @@ Item { anchors.left: parent.left; spacing: UM.Theme.getSize("default_margin").height; - height: childrenRect.height; - ListView + + Repeater { id: contents - spacing: UM.Theme.getSize("default_lining").height; height: childrenRect.height; - model: UM.SettingDefinitionsModel { + model: UM.SettingDefinitionsModel + { id: addedSettingsModel; containerId: Cura.MachineManager.activeDefinitionId - visibilityHandler: Cura.PerObjectSettingVisibilityHandler { - selectedObjectId: UM.ActiveTool.properties.getValue("Model").getItem(base.currentIndex).id + visibilityHandler: Cura.PerObjectSettingVisibilityHandler + { + selectedObjectId: UM.ActiveTool.properties.getValue("SelectedObjectId") } } - delegate:Button + delegate: Loader { - anchors.left: parent.right; + width: UM.Theme.getSize("setting").width; + height: UM.Theme.getSize("setting").height; - width: 150 - height:50 + property var definition: model + property var settingDefinitionsModel: addedSettingsModel + property var propertyProvider: provider - text: model.label + //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989 + //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes, + //causing nasty issues when selecting differnt options. So disable asynchronous loading of enum type completely. + asynchronous: model.type != "enum" + + source: + { + switch(model.type) // TODO: This needs to be fixed properly. Got frustrated with it not working, so this is the patch job! + { + case "int": + return "../../resources/qml/Settings/SettingTextField.qml" + case "float": + return "../../resources/qml/Settings/SettingTextField.qml" + case "enum": + return "../../resources/qml/Settings/SettingComboBox.qml" + case "bool": + return "../../resources/qml/Settings/SettingCheckBox.qml" + case "str": + return "../../resources/qml/Settings/SettingTextField.qml" + case "category": + return "../../resources/qml/Settings/SettingCategory.qml" + default: + return "../../resources/qml/Settings/SettingUnknown.qml" + } + } + + UM.SettingPropertyProvider + { + id: provider + + containerStackId: UM.ActiveTool.properties.getValue("ContainerID") + key: model.key + watchedProperties: [ "value", "enabled", "state", "validationState" ] + storeIndex: 0 + } } } - Button { id: customise_settings_button; diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py index dc65725839..c74800e83d 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py @@ -13,23 +13,16 @@ class PerObjectSettingsTool(Tool): super().__init__() self._model = None - self.setExposedProperties("Model", "SelectedIndex") + self.setExposedProperties("SelectedObjectId","ContainerID") Preferences.getInstance().preferenceChanged.connect(self._onPreferenceChanged) + Selection.selectionChanged.connect(self.propertyChanged) self._onPreferenceChanged("cura/active_mode") def event(self, event): return False - def getModel(self): - if not self._model: - self._model = PerObjectSettingsModel.PerObjectSettingsModel() - - #For some reason, casting this model to itself causes the model to properly be cast to a QVariant, even though it ultimately inherits from QVariant. - #Yeah, we have no idea either... - return PerObjectSettingsModel.PerObjectSettingsModel(self._model) - - def getSelectedIndex(self): + def getSelectedObjectId(self): try: selected_object = Selection.getSelectedObject(0) if selected_object.getParent().callDecoration("isGroup"): @@ -37,8 +30,24 @@ class PerObjectSettingsTool(Tool): except: selected_object = None selected_object_id = id(selected_object) - index = self.getModel().find("id", selected_object_id) - return index + return selected_object_id + + def getContainerID(self): + try: + selected_object = Selection.getSelectedObject(0) + if selected_object.getParent().callDecoration("isGroup"): + selected_object = selected_object.getParent() + try: + return selected_object.callDecoration("getStack").getId() + except: + print(":(") + return + except: + print(":((") + return + + def setContainerID(self, value): + pass def _onPreferenceChanged(self, preference): if preference == "cura/active_mode": From f5fce512380209c1a05687ef83c4d2bf0f8b0bec Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 27 May 2016 17:11:54 +0200 Subject: [PATCH 296/705] Fix "Defaults" button on General page CURA-1278 --- resources/qml/GeneralPage.qml | 37 +++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/resources/qml/GeneralPage.qml b/resources/qml/GeneralPage.qml index 4f597ff32b..56782ea70a 100644 --- a/resources/qml/GeneralPage.qml +++ b/resources/qml/GeneralPage.qml @@ -5,6 +5,7 @@ import QtQuick 2.1 import QtQuick.Controls 1.1 import QtQuick.Layouts 1.1 import QtQuick.Controls.Styles 1.1 +import QtQml.Models 2.2 import UM 1.1 as UM @@ -28,18 +29,23 @@ UM.PreferencesPage function reset() { UM.Preferences.resetPreference("general/language") - UM.Preferences.resetPreference("physics/automatic_push_free") - UM.Preferences.resetPreference("mesh/scale_to_fit") - UM.Preferences.resetPreference("info/send_slice_info") - UM.Preferences.resetPreference("cura/jobname_prefix") - pushFreeCheckbox.checked = boolCheck(UM.Preferences.getValue("physics/automatic_push_free")) - sendDataCheckbox.checked = boolCheck(UM.Preferences.getValue("info/send_slice_info")) - scaleToFitCheckbox.checked = boolCheck(UM.Preferences.getValue("mesh/scale_to_fit")) - prefixJobNameCheckbox.checked = boolCheck(UM.Preferences.getValue("cura/jobname_prefix")) var defaultLanguage = UM.Preferences.getValue("general/language") setDefaultLanguage(defaultLanguage) - if (UM.Models.pluginsModel.find("id", "UpdateChecker") > -1) { + UM.Preferences.resetPreference("physics/automatic_push_free") + pushFreeCheckbox.checked = boolCheck(UM.Preferences.getValue("physics/automatic_push_free")) + UM.Preferences.resetPreference("mesh/scale_to_fit") + scaleToFitCheckbox.checked = boolCheck(UM.Preferences.getValue("mesh/scale_to_fit")) + UM.Preferences.resetPreference("mesh/scale_tiny_meshes") + scaleTinyCheckbox.checked = boolCheck(UM.Preferences.getValue("mesh/scale_tiny_meshes")) + UM.Preferences.resetPreference("cura/jobname_prefix") + prefixJobNameCheckbox.checked = boolCheck(UM.Preferences.getValue("cura/jobname_prefix")) + + if (plugins.model.find("id", "SliceInfoPlugin") > -1) { + UM.Preferences.resetPreference("info/send_slice_info") + sendDataCheckbox.checked = boolCheck(UM.Preferences.getValue("info/send_slice_info")) + } + if (plugins.model.find("id", "UpdateChecker") > -1) { UM.Preferences.resetPreference("info/automatic_update_check") checkUpdatesCheckbox.checked = boolCheck(UM.Preferences.getValue("info/automatic_update_check")) } @@ -158,9 +164,9 @@ UM.PreferencesPage } UM.TooltipArea { - visible: UM.Models.pluginsModel.find("id", "UpdateChecker") > -1 + visible: plugins.model.find("id", "UpdateChecker") > -1 width: childrenRect.width - height: childrenRect.height + height: visible ? childrenRect.height : 0 text: catalog.i18nc("@info:tooltip","Should Cura check for updates when the program is started?") CheckBox @@ -173,8 +179,9 @@ UM.PreferencesPage } UM.TooltipArea { + visible: plugins.model.find("id", "SliceInfoPlugin-1") > -1 width: childrenRect.width - height: childrenRect.height + height: visible ? childrenRect.height : 0 text: catalog.i18nc("@info:tooltip","Should anonymous data about your print be sent to Ultimaker? Note, no models, IP addresses or other personally identifiable information is sent or stored.") CheckBox @@ -199,5 +206,11 @@ UM.PreferencesPage onCheckedChanged: UM.Preferences.setValue("cura/jobname_prefix", checked) } } + + DelegateModel + { + id: plugins + model: UM.PluginsModel { } + } } } From 525f608b242a70d553e18ed724f4b40694950936 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 27 May 2016 17:17:26 +0200 Subject: [PATCH 297/705] Remove reference to machine_extruder_count This setting is not defined in this definition so it can't find the value of it here. I've re-introduced the maximum_value statically in the Jedi implementations of this setting. Contributes to issue CURA-1278 and CURA-351. --- resources/definitions/fdmextruder.def.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/definitions/fdmextruder.def.json b/resources/definitions/fdmextruder.def.json index e9be929e72..f755d72c4a 100644 --- a/resources/definitions/fdmextruder.def.json +++ b/resources/definitions/fdmextruder.def.json @@ -24,8 +24,7 @@ "description": "The extruder train used for printing. This is used in multi-extrusion.", "type": "int", "default_value": 0, - "minimum_value": "0", - "maximum_value": "machine_extruder_count - 1" + "minimum_value": "0" }, "machine_nozzle_offset_x": { From 6aa00a951f95d2e91158a6cb359205829c5e3ade Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 27 May 2016 17:21:14 +0200 Subject: [PATCH 298/705] Fix triggering actions from the extensions menu Contributes to CURA-1540, CURA-1278 --- resources/qml/Cura.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 04ca44369c..a7f4a43c22 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -305,6 +305,7 @@ UM.MainWindow Instantiator { + id: extenions model: UM.ExtensionModel { } Menu @@ -319,7 +320,7 @@ UM.MainWindow MenuItem { text: model.text - onTriggered: UM.Models.extensionModel.subMenuTriggered(name, model.text) + onTriggered: extenions.model.subMenuTriggered(name, model.text) } onObjectAdded: sub_menu.insertItem(index, object) onObjectRemoved: sub_menu.removeItem(object) From 472012a5b9451fc338d012de34e44deae8cca5c5 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 27 May 2016 17:46:53 +0200 Subject: [PATCH 299/705] Fix debug code introduced in f5fce512380209c1a05687ef83c4d2bf0f8b0bec --- resources/qml/GeneralPage.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/GeneralPage.qml b/resources/qml/GeneralPage.qml index 56782ea70a..dcd5c66d73 100644 --- a/resources/qml/GeneralPage.qml +++ b/resources/qml/GeneralPage.qml @@ -179,7 +179,7 @@ UM.PreferencesPage } UM.TooltipArea { - visible: plugins.model.find("id", "SliceInfoPlugin-1") > -1 + visible: plugins.model.find("id", "SliceInfoPlugin") > -1 width: childrenRect.width height: visible ? childrenRect.height : 0 text: catalog.i18nc("@info:tooltip","Should anonymous data about your print be sent to Ultimaker? Note, no models, IP addresses or other personally identifiable information is sent or stored.") From c63eb3871c3c60a1d1b153221a0c93078347ec10 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 30 May 2016 12:22:12 +0200 Subject: [PATCH 300/705] Account for the changes to BackendState in Uranium Contributes to CURA-1278 --- .../CuraEngineBackend/CuraEngineBackend.py | 9 ++--- resources/qml/SaveButton.qml | 40 +++++++++++++------ 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index c9a0efbbcb..989e3a0c50 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -1,13 +1,12 @@ # Copyright (c) 2015 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. -from UM.Backend.Backend import Backend +from UM.Backend.Backend import Backend, BackendState from UM.Application import Application from UM.Scene.SceneNode import SceneNode from UM.Preferences import Preferences from UM.Signal import Signal from UM.Logger import Logger -from UM.Qt.Bindings.BackendProxy import BackendState #To determine the state of the slicing job. from UM.Message import Message from UM.PluginRegistry import PluginRegistry from UM.Resources import Resources @@ -156,12 +155,12 @@ class CuraEngineBackend(Backend): # return self.processingProgress.emit(0.0) - self.backendStateChange.emit(BackendState.NOT_STARTED) if self._message: self._message.setProgress(-1) else: self._message = Message(catalog.i18nc("@info:status", "Slicing..."), 0, False, -1) self._message.show() + self.backendStateChange.emit(BackendState.NotStarted) self._scene.gcode_list = [] self._slicing = True @@ -274,13 +273,13 @@ class CuraEngineBackend(Backend): self._message.setProgress(round(message.amount * 100)) self.processingProgress.emit(message.amount) - self.backendStateChange.emit(BackendState.PROCESSING) + self.backendStateChange.emit(BackendState.Processing) ## Called when the engine sends a message that slicing is finished. # # \param message The protobuf message signalling that slicing is finished. def _onSlicingFinishedMessage(self, message): - self.backendStateChange.emit(BackendState.DONE) + self.backendStateChange.emit(BackendState.Done) self.processingProgress.emit(1.0) self._slicing = False diff --git a/resources/qml/SaveButton.qml b/resources/qml/SaveButton.qml index 64bdcdf540..db147b3e69 100644 --- a/resources/qml/SaveButton.qml +++ b/resources/qml/SaveButton.qml @@ -14,21 +14,35 @@ Rectangle { property real progress: UM.Backend.progress; property int backendState: UM.Backend.state; + property bool activity: Printer.getPlatformActivity; //Behavior on progress { NumberAnimation { duration: 250; } } property int totalHeight: childrenRect.height + UM.Theme.getSize("default_margin").height property string fileBaseName - property string statusText: { - if(base.backendState == 0) { - if(!activity) { - return catalog.i18nc("@label:PrintjobStatus","Please load a 3d model"); - } else { - return catalog.i18nc("@label:PrintjobStatus","Preparing to slice..."); + property string statusText: + { + if(base.backendState == 1) + { + if(!activity) + { + return catalog.i18nc("@label:PrintjobStatus", "Please load a 3d model"); } - } else if(base.backendState == 1) { - return catalog.i18nc("@label:PrintjobStatus","Slicing..."); - } else { - return catalog.i18nc("@label:PrintjobStatus","Ready to ") + UM.OutputDeviceManager.activeDeviceShortDescription; + else + { + return catalog.i18nc("@label:PrintjobStatus", "Preparing to slice..."); + } + } + else if(base.backendState == 2) + { + return catalog.i18nc("@label:PrintjobStatus", "Slicing..."); + } + else if(base.backendState == 3) + { + return catalog.i18nc("@label:PrintjobStatus %1 is target operation","Ready to %1").arg(UM.OutputDeviceManager.activeDeviceShortDescription); + } + else if(base.backendState == 4) + { + return catalog.i18nc("@label:PrintjobStatus", "Unable to slice due to errors") } } @@ -60,7 +74,7 @@ Rectangle { height: parent.height color: UM.Theme.getColor("progressbar_control") radius: UM.Theme.getSize("progressbar_radius").width - visible: base.backendState == 1 ? true : false + visible: base.backendState == 2 ? true : false } } @@ -76,7 +90,7 @@ Rectangle { id: saveToButton tooltip: UM.OutputDeviceManager.activeDeviceDescription; - enabled: base.backendState == 2 && base.activity == true + enabled: base.backendState == 3 && base.activity == true height: UM.Theme.getSize("save_button_save_to_button").height anchors.top: parent.top @@ -127,7 +141,7 @@ Rectangle { anchors.rightMargin: UM.Theme.getSize("default_margin").width width: UM.Theme.getSize("save_button_save_to_button").height height: UM.Theme.getSize("save_button_save_to_button").height - enabled: base.backendState == 2 && base.activity == true + enabled: base.backendState == 3 && base.activity == true visible: devicesModel.deviceCount > 1 From 0b3b718e8719f03a4c33a67636d506dc7dc91b7b Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 30 May 2016 12:23:05 +0200 Subject: [PATCH 301/705] Make CuraEngineBackend respond to changes to the global container stack This way we can properly connect to propertyChanged signals and trigger a reslice. Contributes to CURA-1278 --- plugins/CuraEngineBackend/CuraEngineBackend.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 989e3a0c50..4bc37f1215 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -55,8 +55,9 @@ class CuraEngineBackend(Backend): self._stored_layer_data = [] #Triggers for when to (re)start slicing: - if Application.getInstance().getGlobalContainerStack(): - Application.getInstance().getGlobalContainerStack().propertyChanged.connect(self._onSettingChanged) #Note: Only starts slicing when the value changed. + self._global_container_stack = None + Application.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged) + self._onGlobalStackChanged() #When you update a setting and other settings get changed through inheritance, many propertyChanged signals are fired. #This timer will group them up, and only slice for the last setting changed signal. @@ -123,7 +124,7 @@ class CuraEngineBackend(Backend): def slice(self): self._stored_layer_data = [] - if not self._enabled: #We shouldn't be slicing. + if not self._enabled or not self._global_container_stack: #We shouldn't be slicing. return if self._slicing: #We were already slicing. Stop the old job. @@ -375,3 +376,14 @@ class CuraEngineBackend(Backend): Logger.log("d", "Backend quit with return code %s. Resetting process and socket.", self._process.wait()) self._process = None self._createSocket() + + ## Called when the global container stack changes + def _onGlobalStackChanged(self): + if self._global_container_stack: + self._global_container_stack.propertyChanged.disconnect(self._onSettingChanged) + + self._global_container_stack = Application.getInstance().getGlobalContainerStack() + + if self._global_container_stack: + self._global_container_stack.propertyChanged.connect(self._onSettingChanged) #Note: Only starts slicing when the value changed. + self._onChanged() From cd2b853fff64ec026f90d66d8379a4f5df2124a7 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 30 May 2016 13:01:25 +0200 Subject: [PATCH 302/705] Remove "slicing" message since it is now displayed in the sidebar Now removed for good Contributes to CURA-1278 --- .../CuraEngineBackend/CuraEngineBackend.py | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 4bc37f1215..f90b27bf5d 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -156,11 +156,6 @@ class CuraEngineBackend(Backend): # return self.processingProgress.emit(0.0) - if self._message: - self._message.setProgress(-1) - else: - self._message = Message(catalog.i18nc("@info:status", "Slicing..."), 0, False, -1) - self._message.show() self.backendStateChange.emit(BackendState.NotStarted) self._scene.gcode_list = [] @@ -193,10 +188,6 @@ class CuraEngineBackend(Backend): except Exception as e: # terminating a process that is already terminating causes an exception, silently ignore this. Logger.log("d", "Exception occurred while trying to kill the engine %s", str(e)) - if self._message: - self._message.hide() - self._message = None - ## Event handler to call when the job to initiate the slicing process is # completed. # @@ -210,9 +201,6 @@ class CuraEngineBackend(Backend): if self._start_slice_job is job: self._start_slice_job = None if job.isCancelled() or job.getError() or job.getResult() != True: - if self._message: - self._message.hide() - self._message = None return else: # Preparation completed, send it to the backend. @@ -270,9 +258,6 @@ class CuraEngineBackend(Backend): # # \param message The protobuf message containing the slicing progress. def _onProgressMessage(self, message): - if self._message: - self._message.setProgress(round(message.amount * 100)) - self.processingProgress.emit(message.amount) self.backendStateChange.emit(BackendState.Processing) @@ -285,11 +270,6 @@ class CuraEngineBackend(Backend): self._slicing = False - if self._message: - self._message.setProgress(100) - self._message.hide() - self._message = None - if self._layer_view_active and (self._process_layers_job is None or not self._process_layers_job.isRunning()): self._process_layers_job = ProcessSlicedLayersJob.ProcessSlicedLayersJob(self._stored_layer_data) self._process_layers_job.start() From 8039184c18580b8909435bf0dee0a5c10302bac7 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 30 May 2016 13:03:06 +0200 Subject: [PATCH 303/705] Move setting error checking to StartSliceJob and allow the job to return a proper response Now the job can determine if we can continue with slicing or not and if not, why not. This also means we can now show a message when we cannot find any slicable objects. Contributes to CURA-1278 --- .../CuraEngineBackend/CuraEngineBackend.py | 53 ++++++++++--------- plugins/CuraEngineBackend/StartSliceJob.py | 25 +++++++-- resources/qml/SaveButton.qml | 16 +++--- 3 files changed, 56 insertions(+), 38 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index f90b27bf5d..c5804f920f 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -82,7 +82,7 @@ class CuraEngineBackend(Backend): self._always_restart = True #Always restart the engine when starting a new slice. Don't keep the process running. TODO: Fix engine statelessness. self._process_layers_job = None #The currently active job to process layers, or None if it is not processing layers. - self._message = None #Pop-up message that shows the slicing progress bar (or an error message). + self._error_message = None #Pop-up message that shows errors. self.backendQuit.connect(self._onBackendQuit) self.backendConnected.connect(self._onBackendConnected) @@ -134,26 +134,8 @@ class CuraEngineBackend(Backend): self._process_layers_job.abort() self._process_layers_job = None - # #Don't slice if there is a setting with an error value. - # stack = Application.getInstance().getGlobalContainerStack() - # for key in stack.getAllKeys(): - # validation_state = stack.getProperty(key, "validationState") - # #Only setting instances have a validation state, so settings which - # #are not overwritten by any instance will have none. The property - # #then, and only then, evaluates to None. We make the assumption that - # #the definition defines the setting with a default value that is - # #valid. Therefore we can allow both ValidatorState.Valid and None as - # #allowable validation states. - # #TODO: This assumption is wrong! If the definition defines an inheritance function that through inheritance evaluates to a disallowed value, a setting is still invalid even though it's default! - # #TODO: Therefore we must also validate setting definitions. - # if validation_state != None and validation_state != ValidatorState.Valid: - # Logger.log("w", "Setting %s is not valid, but %s. Aborting slicing.", key, validation_state) - # if self._message: #Hide any old message before creating a new one. - # self._message.hide() - # self._message = None - # self._message = Message(catalog.i18nc("@info:status", "Unable to slice. Please check your setting values for errors.")) - # self._message.show() - # return + if self._error_message: + self._error_message.hide() self.processingProgress.emit(0.0) self.backendStateChange.emit(BackendState.NotStarted) @@ -200,12 +182,31 @@ class CuraEngineBackend(Backend): # Note that cancelled slice jobs can still call this method. if self._start_slice_job is job: self._start_slice_job = None - if job.isCancelled() or job.getError() or job.getResult() != True: + + if job.isCancelled() or job.getError() or job.getResult() == StartSliceJob.StartJobResult.Error: return - else: - # Preparation completed, send it to the backend. - self._socket.sendMessage(job.getSettingsMessage()) - self._socket.sendMessage(job.getSliceMessage()) + + if job.getResult() == StartSliceJob.StartJobResult.SettingError: + if Application.getInstance().getPlatformActivity: + self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice. Please check your setting values for errors."), lifetime = 10) + self._error_message.show() + self.backendStateChange.emit(BackendState.Error) + else: + self.backendStateChange.emit(BackendState.NotStarted) + return + + if job.getResult() == StartSliceJob.StartJobResult.NothingToSlice: + if Application.getInstance().getPlatformActivity: + self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice. No suitable objects found."), lifetime = 10) + self._error_message.show() + self.backendStateChange.emit(BackendState.Error) + else: + self.backendStateChange.emit(BackendState.NotStarted) + return + + # Preparation completed, send it to the backend. + self._socket.sendMessage(job.getSettingsMessage()) + self._socket.sendMessage(job.getSliceMessage()) ## Listener for when the scene has changed. # diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 6e0da0cb34..cf008e7b6f 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -4,6 +4,7 @@ import numpy from string import Formatter import traceback +from enum import IntEnum from UM.Job import Job from UM.Application import Application @@ -12,8 +13,15 @@ from UM.Logger import Logger from UM.Scene.SceneNode import SceneNode from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator +from UM.Settings.Validator import ValidatorState + from cura.OneAtATimeIterator import OneAtATimeIterator +class StartJobResult(IntEnum): + Finished = 1 + Error = 2 + SettingError = 3 + NothingToSlice = 4 ## Formatter class that handles token expansion in start/end gcod class GcodeStartEndFormatter(Formatter): @@ -48,9 +56,19 @@ class StartSliceJob(Job): def run(self): stack = Application.getInstance().getGlobalContainerStack() if not stack: - self.setResult(False) + self.setResult(StartJobResult.Error) return + #Don't slice if there is a setting with an error value. + for key in stack.getAllKeys(): + validation_state = stack.getProperty(key, "validationState") + if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError): + Logger.log("w", "Setting %s is not valid, but %s. Aborting slicing.", key, validation_state) + self.setResult(StartJobResult.SettingError) + return + + Job.yieldThread() + with self._scene.getSceneLock(): # Remove old layer data. for node in DepthFirstIterator(self._scene.getRoot()): @@ -91,6 +109,7 @@ class StartSliceJob(Job): object_groups.append(temp_list) if not object_groups: + self.setResult(StartJobResult.NothingToSlice) return self._buildGlobalSettingsMessage(stack) @@ -116,7 +135,7 @@ class StartSliceJob(Job): Job.yieldThread() - self.setResult(True) + self.setResult(StartJobResult.Finished) def cancel(self): super().cancel() @@ -131,7 +150,7 @@ class StartSliceJob(Job): fmt = GcodeStartEndFormatter() return str(fmt.format(value, **settings)).encode("utf-8") except: - Logger.log("w", "Unabled to do token replacement on start/end gcode %s", traceback.format_exc()) + Logger.logException("w", "Unable to do token replacement on start/end gcode") return str(value).encode("utf-8") ## Sends all global settings to the engine. diff --git a/resources/qml/SaveButton.qml b/resources/qml/SaveButton.qml index db147b3e69..1307e8f820 100644 --- a/resources/qml/SaveButton.qml +++ b/resources/qml/SaveButton.qml @@ -21,16 +21,14 @@ Rectangle { property string fileBaseName property string statusText: { + if(!activity) + { + return catalog.i18nc("@label:PrintjobStatus", "Please load a 3d model"); + } + if(base.backendState == 1) { - if(!activity) - { - return catalog.i18nc("@label:PrintjobStatus", "Please load a 3d model"); - } - else - { - return catalog.i18nc("@label:PrintjobStatus", "Preparing to slice..."); - } + return catalog.i18nc("@label:PrintjobStatus", "Preparing to slice..."); } else if(base.backendState == 2) { @@ -42,7 +40,7 @@ Rectangle { } else if(base.backendState == 4) { - return catalog.i18nc("@label:PrintjobStatus", "Unable to slice due to errors") + return catalog.i18nc("@label:PrintjobStatus", "Unable to Slice") } } From 93873a2ce83edb24e33db751a7f25d8b8b340459 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 30 May 2016 14:02:51 +0200 Subject: [PATCH 304/705] Also trigger a reslice when the containerstack's containers change Contributes to CURA-1278 --- plugins/CuraEngineBackend/CuraEngineBackend.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index c5804f920f..9607ba407b 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -307,7 +307,7 @@ class CuraEngineBackend(Backend): ## Called when anything has changed to the stuff that needs to be sliced. # # This indicates that we should probably re-slice soon. - def _onChanged(self): + def _onChanged(self, *args, **kwargs): self._change_timer.start() ## Called when the back-end connects to the front-end. @@ -362,9 +362,11 @@ class CuraEngineBackend(Backend): def _onGlobalStackChanged(self): if self._global_container_stack: self._global_container_stack.propertyChanged.disconnect(self._onSettingChanged) + self._global_container_stack.containersChanged.disconnect(self._onChanged) self._global_container_stack = Application.getInstance().getGlobalContainerStack() if self._global_container_stack: self._global_container_stack.propertyChanged.connect(self._onSettingChanged) #Note: Only starts slicing when the value changed. + self._global_container_stack.containersChanged.connect(self._onChanged) self._onChanged() From 19695a93b55caae708b30bd39bb15a5de899aef9 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 30 May 2016 14:27:04 +0200 Subject: [PATCH 305/705] Move extruder trains to metadata Uranium doesn't know about extruder trains so it can't load that. Cura doesn't have access to anything outside of metadata or settings. So I'm putting it into metadata. Contributes to issues CURA-1278 and CURA-351. --- resources/definitions/fdmprinter.def.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index f8400d6d62..ab16f49a8d 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -11,11 +11,11 @@ "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g", "visible": false, "preferred_material": "pla", - "preferred_quality": "normal" - }, - "machine_extruder_trains": - { - "0": "fdmextruder" + "preferred_quality": "normal", + "machine_extruder_trains": + { + "0": "fdmextruder" + } }, "settings": { From 871d4087b0d043330c0dee8e745b2335316be732 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 30 May 2016 14:32:58 +0200 Subject: [PATCH 306/705] JSON refactor: moved dual extrusion acceleration and jerk settings to new .def.json (CURA-1443) --- resources/definitions/fdmprinter.def.json | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 1870036408..c98b0771b6 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1306,6 +1306,19 @@ "global_only": true } } + }, + "acceleration_prime_tower": { + "label": "Prime Tower Acceleration", + "description": "The acceleration with which the prime tower is printed.", + "unit": "mm/s²", + "type": "float", + "min_value": "0.1", + "min_value_warning": "100", + "max_value_warning": "10000", + "default": 3000, + "visible": false, + "enabled": "prime_tower_enable and acceleration_enabled", + "global_only": true } } }, @@ -1473,6 +1486,19 @@ "global_only": true } } + }, + "jerk_prime_tower": { + "label": "Prime Tower Jerk", + "description": "The jerk with which the prime tower is printed.", + "unit": "mm/s³", + "type": "float", + "min_value": "0.1", + "min_value_warning": "5", + "max_value_warning": "50", + "default": 20, + "visible": false, + "enabled": "prime_tower_enable and jerk_enabled", + "global_only": true } } }, From 7742073818b4367863ac64901d8eef9fc0ce544b Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 30 May 2016 14:34:32 +0200 Subject: [PATCH 307/705] Removed old dual_extrusion_printer.json which wass reintroduced due to faulty merge. (CURA-1443) --- .../machines/dual_extrusion_printer.json | 345 ------------------ 1 file changed, 345 deletions(-) delete mode 100644 resources/machines/dual_extrusion_printer.json diff --git a/resources/machines/dual_extrusion_printer.json b/resources/machines/dual_extrusion_printer.json deleted file mode 100644 index ccb1d4e96c..0000000000 --- a/resources/machines/dual_extrusion_printer.json +++ /dev/null @@ -1,345 +0,0 @@ -{ - "version": 1, - "id": "dual_extrusion", - "name": "Dual Extrusion Base File", - "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g", - "inherits": "fdmprinter.json", - - "visible": false, - - "machine_extruder_trains": { - "0": { - "extruder_nr": { "default": 0 }, - "machine_nozzle_offset_x": { "default": 0.0 }, - "machine_nozzle_offset_y": { "default": 0.0 } - }, - "1": { - "extruder_nr": { "default": 1 } - } - }, - - "machine_settings": { - "machine_use_extruder_offset_to_offset_coords": { "default": false }, - - "machine_nozzle_offset_x": { "default": 0, "SEE_machine_extruder_trains": true }, - "machine_nozzle_offset_y": { "default": 0, "SEE_machine_extruder_trains": true }, - "machine_extruder_start_code": { "default": "", "SEE_machine_extruder_trains": true }, - "machine_extruder_start_pos_abs": { "default": false, "SEE_machine_extruder_trains": true }, - "machine_extruder_start_pos_x": { "default": 0, "SEE_machine_extruder_trains": true }, - "machine_extruder_start_pos_y": { "default": 0, "SEE_machine_extruder_trains": true }, - "machine_extruder_end_pos_abs": { "default": false, "SEE_machine_extruder_trains": true }, - "machine_extruder_end_pos_x": { "default": 0, "SEE_machine_extruder_trains": true }, - "machine_extruder_end_pos_y": { "default": 0, "SEE_machine_extruder_trains": true }, - "machine_extruder_end_code": { "default": "", "SEE_machine_extruder_trains": true } - }, - "overrides": { - "speed_print": { - "children": { - "speed_prime_tower": { - "label": "Prime Tower Speed", - "description": "The speed at which the prime tower is printed. Printing the prime tower slower can make it more stable when the adhesion between the different filaments is suboptimal.", - "unit": "mm/s", - "type": "float", - "min_value": "0.1", - "max_value_warning": "150", - "default": 60, - "visible": false, - "enabled": "prime_tower_enable", - "global_only": true - } - } - }, - "acceleration_print": { - "children": { - "acceleration_prime_tower": { - "label": "Prime Tower Acceleration", - "description": "The acceleration with which the prime tower is printed.", - "unit": "mm/s²", - "type": "float", - "min_value": "0.1", - "min_value_warning": "100", - "max_value_warning": "10000", - "default": 3000, - "visible": false, - "enabled": "prime_tower_enable and acceleration_enabled", - "global_only": true - } - } - }, - "jerk_print": { - "children": { - "jerk_prime_tower": { - "label": "Prime Tower Jerk", - "description": "The jerk with which the prime tower is printed.", - "unit": "mm/s³", - "type": "float", - "min_value": "0.1", - "min_value_warning": "5", - "max_value_warning": "50", - "default": 20, - "visible": false, - "enabled": "prime_tower_enable and jerk_enabled", - "global_only": true - } - } - }, - "line_width": { - "children": { - "prime_tower_line_width": { - "label": "Prime Tower Line Width", - "description": "Width of a single prime tower line.", - "unit": "mm", - "min_value": "0.0001", - "min_value_warning": "0.2", - "max_value_warning": "5", - "default": 0.4, - "type": "float", - "visible": false, - "enabled": "prime_tower_enable", - "global_only": true - } - } - } - }, - "categories": { - "dual": { - "label": "Dual Extrusion", - "visible": true, - "icon": "category_dual", - "settings": { - "extruder_nr": { - "label": "Extruder", - "description": "The extruder train used for printing. This is used in multi-extrusion.", - "type": "int", - "default": 0, - "min_value": "0", - "max_value": "machine_extruder_count - 1", - "always_visible": true - }, - "adhesion_extruder_nr": { - "label": "Platform Adhesion Extruder", - "description": "The extruder train to use for printing the skirt/brim/raft. This is used in multi-extrusion.", - "type": "int", - "default": 0, - "min_value": "0", - "max_value": "machine_extruder_count - 1", - "global_only": true - }, - "support_extruder_nr": { - "label": "Support Extruder", - "description": "The extruder train to use for printing the support. This is used in multi-extrusion.", - "type": "int", - "default": 0, - "min_value": "0", - "max_value": "machine_extruder_count - 1", - "global_only": true, - "children": { - "support_infill_extruder_nr": { - "label": "Support Infill Extruder", - "description": "The extruder train to use for printing the infill of the support. This is used in multi-extrusion.", - "type": "int", - "default": 0, - "min_value": "0", - "max_value": "machine_extruder_count - 1", - "global_only": true - }, - "support_extruder_nr_layer_0": { - "label": "First Layer Support Extruder", - "description": "The extruder train to use for printing the first layer of support infill. This is used in multi-extrusion.", - "type": "int", - "default": 0, - "min_value": "0", - "max_value": "machine_extruder_count - 1", - "global_only": true - }, - "support_roof_extruder_nr": { - "label": "Support Roof Extruder", - "description": "The extruder train to use for printing the roof of the support. This is used in multi-extrusion.", - "type": "int", - "default": 0, - "min_value": "0", - "max_value": "machine_extruder_count - 1", - "enabled": "support_roof_enable", - "global_only": true - } - } - }, - "prime_tower_enable": { - "label": "Enable Prime Tower", - "description": "Print a tower next to the print which serves to prime the material after each nozzle switch.", - "type": "boolean", - "visible": true, - "default": false, - "global_only": true - }, - "prime_tower_size": { - "label": "Prime Tower Size", - "description": "The width of the prime tower.", - "visible": false, - "type": "float", - "unit": "mm", - "default": 15, - "min_value": "0", - "max_value_warning": "20", - "inherit_function": "15 if prime_tower_enable else 0", - "enabled": "prime_tower_enable", - "global_only": true - }, - "prime_tower_position_x": { - "label": "Prime Tower X Position", - "description": "The x position of the prime tower.", - "visible": false, - "type": "float", - "unit": "mm", - "default": 200, - "min_value_warning": "-1000", - "max_value_warning": "1000", - "enabled": "prime_tower_enable", - "global_only": true - }, - "prime_tower_position_y": { - "label": "Prime Tower Y Position", - "description": "The y position of the prime tower.", - "visible": false, - "type": "float", - "unit": "mm", - "default": 200, - "min_value_warning": "-1000", - "max_value_warning": "1000", - "enabled": "prime_tower_enable", - "global_only": true - }, - "prime_tower_flow": { - "label": "Prime Tower Flow", - "description": "Flow compensation: the amount of material extruded is multiplied by this value.", - "visible": false, - "unit": "%", - "default": 100, - "type": "float", - "min_value": "5", - "min_value_warning": "50", - "max_value_warning": "150", - "enabled": "prime_tower_enable", - "global_only": true - }, - "prime_tower_wipe_enabled": { - "label": "Wipe Nozzle on Prime tower", - "description": "After printing the prime tower with the one nozzle, wipe the oozed material from the other nozzle off on the prime tower.", - "type": "boolean", - "default": false, - "enabled": "prime_tower_enable", - "global_only": true - }, - "multiple_mesh_overlap": { - "label": "Dual Extrusion Overlap", - "description": "Make the objects printed with different extruder trains overlap a bit. This makes the different materials bond together better.", - "visible": false, - "type": "float", - "unit": "mm", - "default": 0.15, - "min_value": "0", - "max_value_warning": "1.0", - "global_only": true - }, - "ooze_shield_enabled": { - "label": "Enable Ooze Shield", - "description": "Enable exterior ooze shield. This will create a shell around the object which is likely to wipe a second nozzle if it's at the same height as the first nozzle.", - "type": "boolean", - "default": false, - "global_only": true - }, - "ooze_shield_angle": { - "label": "Ooze Shield Angle", - "description": "The maximum angle a part in the ooze shield will have. With 0 degrees being vertical, and 90 degrees being horizontal. A smaller angle leads to less failed ooze shields, but more material.", - "unit": "°", - "type": "float", - "min_value": "0", - "max_value": "90", - "default": 60, - "visible": false, - "enabled": "ooze_shield_enabled", - "global_only": true - }, - "ooze_shield_dist": { - "label": "Ooze Shields Distance", - "description": "Distance of the ooze shield from the print, in the X/Y directions.", - "unit": "mm", - "type": "float", - "min_value": "0", - "max_value_warning": "30", - "default": 2, - "visible": false, - "enabled": "ooze_shield_enabled", - "global_only": true - } - } - }, - "material": { - "settings": { - "material_standby_temperature": { - "label": "Standby Temperature", - "description": "The temperature of the nozzle when another nozzle is currently used for printing.", - "unit": "°C", - "type": "float", - "default": 150, - "min_value": "0", - "max_value_warning": "260", - "global_only": "True", - "visible": false - }, - "switch_extruder_retraction_amount": { - "label": "Nozzle Switch Retraction Distance", - "description": "The amount of retraction: Set at 0 for no retraction at all. This should generally be the same as the length of the heat zone.", - "unit": "mm", - "type": "float", - "default": 20, - "min_value_warning": "0", - "max_value_warning": "100", - "visible": false, - "inherit_function": "machine_heat_zone_length", - "enabled": "retraction_enable", - "global_only": true - }, - "switch_extruder_retraction_speeds": { - "label": "Nozzle Switch Retraction Speed", - "description": "The speed at which the filament is retracted. A higher retraction speed works better, but a very high retraction speed can lead to filament grinding.", - "unit": "mm/s", - "type": "float", - "default": 20, - "min_value": "0.1", - "max_value_warning": "300", - "visible": false, - "inherit": false, - "enabled": "retraction_enable", - "global_only": true, - "children": { - "switch_extruder_retraction_speed": { - "label": "Nozzle Switch Retract Speed", - "description": "The speed at which the filament is retracted during a nozzle switch retract. ", - "unit": "mm/s", - "type": "float", - "default": 20, - "min_value": "0.1", - "max_value_warning": "300", - "visible": false, - "enabled": "retraction_enable", - "global_only": true - }, - "switch_extruder_prime_speed": { - "label": "Nozzle Switch Prime Speed", - "description": "The speed at which the filament is pushed back after a nozzle switch retraction.", - "unit": "mm/s", - "type": "float", - "default": 20, - "min_value": "0.1", - "max_value_warning": "300", - "visible": false, - "enabled": "retraction_enable", - "global_only": true - } - } - } - } - } - } -} From c80e3fa62a1e4938646dfc6a6c9b61de6dc05728 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 30 May 2016 14:37:57 +0200 Subject: [PATCH 308/705] JSON fix: min_value ==> minimum_value (and for max) for acceleration and jerk settings (CURA-1443) --- resources/definitions/fdmprinter.def.json | 204 +++++++++++----------- 1 file changed, 102 insertions(+), 102 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index c98b0771b6..19d159084d 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1198,9 +1198,9 @@ "description": "The acceleration with which printing happens.", "unit": "mm/s²", "type": "float", - "min_value": "0.1", - "min_value_warning": "100", - "max_value_warning": "10000", + "minimum_value": "0.1", + "minimum_value_warning": "100", + "maximum_value_warning": "10000", "default": 3000, "visible": true, "enabled": "acceleration_enabled", @@ -1210,9 +1210,9 @@ "description": "The acceleration with which infill is printed.", "unit": "mm/s²", "type": "float", - "min_value": "0.1", - "min_value_warning": "100", - "max_value_warning": "10000", + "minimum_value": "0.1", + "minimum_value_warning": "100", + "maximum_value_warning": "10000", "default": 3000, "visible": false, "enabled": "acceleration_enabled" @@ -1222,9 +1222,9 @@ "description": "The acceleration with which the walls are printed.", "unit": "mm/s²", "type": "float", - "min_value": "0.1", - "min_value_warning": "100", - "max_value_warning": "10000", + "minimum_value": "0.1", + "minimum_value_warning": "100", + "maximum_value_warning": "10000", "default": 3000, "visible": false, "enabled": "acceleration_enabled", @@ -1234,9 +1234,9 @@ "description": "The acceleration with which the outermost walls are printed.", "unit": "mm/s²", "type": "float", - "min_value": "0.1", - "min_value_warning": "100", - "max_value_warning": "10000", + "minimum_value": "0.1", + "minimum_value_warning": "100", + "maximum_value_warning": "10000", "default": 3000, "visible": false, "enabled": "acceleration_enabled" @@ -1246,9 +1246,9 @@ "description": "The acceleration with which all inner walls are printed.", "unit": "mm/s²", "type": "float", - "min_value": "0.1", - "min_value_warning": "100", - "max_value_warning": "10000", + "minimum_value": "0.1", + "minimum_value_warning": "100", + "maximum_value_warning": "10000", "default": 3000, "visible": false, "enabled": "acceleration_enabled" @@ -1260,9 +1260,9 @@ "description": "The acceleration with which top/bottom layers are printed.", "unit": "mm/s²", "type": "float", - "min_value": "0.1", - "min_value_warning": "100", - "max_value_warning": "10000", + "minimum_value": "0.1", + "minimum_value_warning": "100", + "maximum_value_warning": "10000", "default": 3000, "visible": false, "enabled": "acceleration_enabled" @@ -1272,9 +1272,9 @@ "description": "The acceleration with which the support structure is printed.", "unit": "mm/s²", "type": "float", - "min_value": "0.1", - "min_value_warning": "100", - "max_value_warning": "10000", + "minimum_value": "0.1", + "minimum_value_warning": "100", + "maximum_value_warning": "10000", "default": 3000, "visible": false, "enabled": "acceleration_enabled and support_roof_enable", @@ -1285,9 +1285,9 @@ "unit": "mm/s²", "type": "float", "default": 3000, - "min_value": "0.1", - "min_value_warning": "100", - "max_value_warning": "10000", + "minimum_value": "0.1", + "minimum_value_warning": "100", + "maximum_value_warning": "10000", "visible": false, "enabled": "acceleration_enabled and support_enable", "global_only": true @@ -1298,9 +1298,9 @@ "unit": "mm/s²", "type": "float", "default": 3000, - "min_value": "0.1", - "min_value_warning": "100", - "max_value_warning": "10000", + "minimum_value": "0.1", + "minimum_value_warning": "100", + "maximum_value_warning": "10000", "visible": false, "enabled": "acceleration_enabled and support_roof_enable", "global_only": true @@ -1312,9 +1312,9 @@ "description": "The acceleration with which the prime tower is printed.", "unit": "mm/s²", "type": "float", - "min_value": "0.1", - "min_value_warning": "100", - "max_value_warning": "10000", + "minimum_value": "0.1", + "minimum_value_warning": "100", + "maximum_value_warning": "10000", "default": 3000, "visible": false, "enabled": "prime_tower_enable and acceleration_enabled", @@ -1328,9 +1328,9 @@ "unit": "mm/s²", "type": "float", "default": 5000, - "min_value": "0.1", - "min_value_warning": "100", - "max_value_warning": "10000", + "minimum_value": "0.1", + "minimum_value_warning": "100", + "maximum_value_warning": "10000", "inherit_function": "acceleration_print if magic_spiralize else 5000", "global_only": true, "visible": true, @@ -1342,9 +1342,9 @@ "unit": "mm/s²", "type": "float", "default": 3000, - "min_value": "0.1", - "min_value_warning": "100", - "max_value_warning": "10000", + "minimum_value": "0.1", + "minimum_value_warning": "100", + "maximum_value_warning": "10000", "visible": false, "enabled": "acceleration_enabled" }, @@ -1354,9 +1354,9 @@ "unit": "mm/s²", "type": "float", "default": 3000, - "min_value": "0.1", - "min_value_warning": "100", - "max_value_warning": "10000", + "minimum_value": "0.1", + "minimum_value_warning": "100", + "maximum_value_warning": "10000", "visible": false, "inherit_function": "acceleration_layer_0", "global_only": true, @@ -1378,9 +1378,9 @@ "description": "The maximal allowed jerk of the print head when starting to move or when changing direction.", "unit": "mm/s³", "type": "float", - "min_value": "0.1", - "min_value_warning": "5", - "max_value_warning": "50", + "minimum_value": "0.1", + "minimum_value_warning": "5", + "maximum_value_warning": "50", "default": 20, "visible": true, "enabled": "jerk_enabled", @@ -1390,9 +1390,9 @@ "description": "The jerk with which infill is printed.", "unit": "mm/s³", "type": "float", - "min_value": "0.1", - "min_value_warning": "5", - "max_value_warning": "50", + "minimum_value": "0.1", + "minimum_value_warning": "5", + "maximum_value_warning": "50", "default": 20, "visible": false, "enabled": "jerk_enabled" @@ -1402,9 +1402,9 @@ "description": "The jerk with which the walls are printed.", "unit": "mm/s³", "type": "float", - "min_value": "0.1", - "min_value_warning": "5", - "max_value_warning": "50", + "minimum_value": "0.1", + "minimum_value_warning": "5", + "maximum_value_warning": "50", "default": 20, "visible": false, "enabled": "jerk_enabled", @@ -1414,9 +1414,9 @@ "description": "The jerk with which the outermost walls are printed. Printing the outer wall at a lower jerk improves the final skin quality. However, having a large difference between the inner wall jerk and the outer wall jerk will effect quality in a negative way.", "unit": "mm/s³", "type": "float", - "min_value": "0.1", - "min_value_warning": "5", - "max_value_warning": "50", + "minimum_value": "0.1", + "minimum_value_warning": "5", + "maximum_value_warning": "50", "default": 20, "visible": false, "enabled": "jerk_enabled" @@ -1426,9 +1426,9 @@ "description": "The jerk with which all inner walls are printed Printing the inner wall faster than the outer wall will reduce printing time. It works well to set this in between the outer wall jerk and the infill jerk.", "unit": "mm/s³", "type": "float", - "min_value": "0.1", - "min_value_warning": "5", - "max_value_warning": "50", + "minimum_value": "0.1", + "minimum_value_warning": "5", + "maximum_value_warning": "50", "default": 20, "visible": false, "enabled": "jerk_enabled" @@ -1440,9 +1440,9 @@ "description": "The jerk with which top/bottom layers are printed.", "unit": "mm/s³", "type": "float", - "min_value": "0.1", - "min_value_warning": "5", - "max_value_warning": "50", + "minimum_value": "0.1", + "minimum_value_warning": "5", + "maximum_value_warning": "50", "default": 20, "visible": false, "enabled": "jerk_enabled" @@ -1452,9 +1452,9 @@ "description": "The jerk with which the support structure is printed. Printing support at higher jerks can greatly reduce printing time. The surface quality of the support structure is not important since it is removed after printing.", "unit": "mm/s³", "type": "float", - "min_value": "0.1", - "min_value_warning": "5", - "max_value_warning": "50", + "minimum_value": "0.1", + "minimum_value_warning": "5", + "maximum_value_warning": "50", "default": 20, "visible": false, "enabled": "jerk_enabled and support_roof_enable", @@ -1465,9 +1465,9 @@ "unit": "mm/s³", "type": "float", "default": 20, - "min_value": "0.1", - "min_value_warning": "5", - "max_value_warning": "50", + "minimum_value": "0.1", + "minimum_value_warning": "5", + "maximum_value_warning": "50", "visible": false, "enabled": "jerk_enabled and support_enable", "global_only": true @@ -1478,9 +1478,9 @@ "unit": "mm/s³", "type": "float", "default": 20, - "min_value": "0.1", - "min_value_warning": "5", - "max_value_warning": "50", + "minimum_value": "0.1", + "minimum_value_warning": "5", + "maximum_value_warning": "50", "visible": false, "enabled": "jerk_enabled and support_roof_enable", "global_only": true @@ -1492,9 +1492,9 @@ "description": "The jerk with which the prime tower is printed.", "unit": "mm/s³", "type": "float", - "min_value": "0.1", - "min_value_warning": "5", - "max_value_warning": "50", + "minimum_value": "0.1", + "minimum_value_warning": "5", + "maximum_value_warning": "50", "default": 20, "visible": false, "enabled": "prime_tower_enable and jerk_enabled", @@ -1508,9 +1508,9 @@ "unit": "mm/s³", "type": "float", "default": 30, - "min_value": "0.1", - "min_value_warning": "5", - "max_value_warning": "50", + "minimum_value": "0.1", + "minimum_value_warning": "5", + "maximum_value_warning": "50", "inherit_function": "jerk_print if magic_spiralize else 30", "global_only": true, "visible": true, @@ -1522,9 +1522,9 @@ "unit": "mm/s³", "type": "float", "default": 20, - "min_value": "0.1", - "min_value_warning": "5", - "max_value_warning": "50", + "minimum_value": "0.1", + "minimum_value_warning": "5", + "maximum_value_warning": "50", "visible": false, "enabled": "jerk_enabled" }, @@ -1534,9 +1534,9 @@ "unit": "mm/s³", "type": "float", "default": 20, - "min_value": "0.1", - "min_value_warning": "5", - "max_value_warning": "50", + "minimum_value": "0.1", + "minimum_value_warning": "5", + "maximum_value_warning": "50", "visible": false, "inherit_function": "jerk_layer_0", "global_only": true, @@ -2342,9 +2342,9 @@ "unit": "mm/s²", "type": "float", "default": 3000, - "min_value": "0.1", - "min_value_warning": "100", - "max_value_warning": "10000", + "minimum_value": "0.1", + "minimum_value_warning": "100", + "maximum_value_warning": "10000", "inherit_function": "acceleration_print", "global_only": "True", "visible": false, @@ -2356,9 +2356,9 @@ "unit": "mm/s²", "type": "float", "default": 3000, - "min_value": "0.1", - "min_value_warning": "100", - "max_value_warning": "10000", + "minimum_value": "0.1", + "minimum_value_warning": "100", + "maximum_value_warning": "10000", "global_only": "True", "visible": false, "enabled": "adhesion_type == \"raft\" and acceleration_enabled" @@ -2369,9 +2369,9 @@ "unit": "mm/s²", "type": "float", "default": 3000, - "min_value": "0.1", - "min_value_warning": "100", - "max_value_warning": "10000", + "minimum_value": "0.1", + "minimum_value_warning": "100", + "maximum_value_warning": "10000", "global_only": "True", "visible": false, "enabled": "adhesion_type == \"raft\" and acceleration_enabled" @@ -2382,9 +2382,9 @@ "unit": "mm/s²", "type": "float", "default": 3000, - "min_value": "0.1", - "min_value_warning": "100", - "max_value_warning": "10000", + "minimum_value": "0.1", + "minimum_value_warning": "100", + "maximum_value_warning": "10000", "global_only": "True", "visible": false, "enabled": "adhesion_type == \"raft\" and acceleration_enabled" @@ -2400,9 +2400,9 @@ "unit": "mm/s³", "type": "float", "default": 20, - "min_value": "0.1", - "min_value_warning": "5", - "max_value_warning": "50", + "minimum_value": "0.1", + "minimum_value_warning": "5", + "maximum_value_warning": "50", "inherit_function": "jerk_print", "global_only": "True", "visible": false, @@ -2414,9 +2414,9 @@ "unit": "mm/s³", "type": "float", "default": 20, - "min_value": "0.1", - "min_value_warning": "5", - "max_value_warning": "100", + "minimum_value": "0.1", + "minimum_value_warning": "5", + "maximum_value_warning": "100", "global_only": "True", "visible": false, "enabled": "adhesion_type == \"raft\" and jerk_enabled" @@ -2427,9 +2427,9 @@ "unit": "mm/s³", "type": "float", "default": 20, - "min_value": "0.1", - "min_value_warning": "5", - "max_value_warning": "50", + "minimum_value": "0.1", + "minimum_value_warning": "5", + "maximum_value_warning": "50", "global_only": "True", "visible": false, "enabled": "adhesion_type == \"raft\" and jerk_enabled" @@ -2440,9 +2440,9 @@ "unit": "mm/s³", "type": "float", "default": 20, - "min_value": "0.1", - "min_value_warning": "5", - "max_value_warning": "50", + "minimum_value": "0.1", + "minimum_value_warning": "5", + "maximum_value_warning": "50", "global_only": "True", "visible": false, "enabled": "adhesion_type == \"raft\" and jerk_enabled" From 4f793d2fc5ed694bd451abd079bd1b928ee305db Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 30 May 2016 14:41:04 +0200 Subject: [PATCH 309/705] JSON fix: default ==> default_value for acceleration and jerk (CURA-1443) --- resources/definitions/fdmprinter.def.json | 72 +++++++++++------------ 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 19d159084d..2e11f20b48 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1189,7 +1189,7 @@ "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": "boolean", - "default": false, + "default_value": false, "visible": false, "global_only": "True" }, @@ -1201,7 +1201,7 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "default": 3000, + "default_value": 3000, "visible": true, "enabled": "acceleration_enabled", "children": { @@ -1213,7 +1213,7 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "default": 3000, + "default_value": 3000, "visible": false, "enabled": "acceleration_enabled" }, @@ -1225,7 +1225,7 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "default": 3000, + "default_value": 3000, "visible": false, "enabled": "acceleration_enabled", "children": { @@ -1237,7 +1237,7 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "default": 3000, + "default_value": 3000, "visible": false, "enabled": "acceleration_enabled" }, @@ -1249,7 +1249,7 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "default": 3000, + "default_value": 3000, "visible": false, "enabled": "acceleration_enabled" } @@ -1263,7 +1263,7 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "default": 3000, + "default_value": 3000, "visible": false, "enabled": "acceleration_enabled" }, @@ -1275,7 +1275,7 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "default": 3000, + "default_value": 3000, "visible": false, "enabled": "acceleration_enabled and support_roof_enable", "children": { @@ -1284,7 +1284,7 @@ "description": "The acceleration with which the infill of support is printed.", "unit": "mm/s²", "type": "float", - "default": 3000, + "default_value": 3000, "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", @@ -1297,7 +1297,7 @@ "description": "The acceleration with which the roofs of support are printed. Printing the support roof at lower accelerations can improve overhang quality.", "unit": "mm/s²", "type": "float", - "default": 3000, + "default_value": 3000, "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", @@ -1315,7 +1315,7 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "default": 3000, + "default_value": 3000, "visible": false, "enabled": "prime_tower_enable and acceleration_enabled", "global_only": true @@ -1327,7 +1327,7 @@ "description": "The acceleration with which travel moves are made.", "unit": "mm/s²", "type": "float", - "default": 5000, + "default_value": 5000, "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", @@ -1341,7 +1341,7 @@ "description": "The acceleration for the initial layer.", "unit": "mm/s²", "type": "float", - "default": 3000, + "default_value": 3000, "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", @@ -1353,7 +1353,7 @@ "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 at a different acceleration.", "unit": "mm/s²", "type": "float", - "default": 3000, + "default_value": 3000, "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", @@ -1369,7 +1369,7 @@ "label": "Enable Jerk Control", "description": "Enables adjusting the jerk of print head when the X ar Y axis halts or starts to move. Increasing the jerk can reduce printing time at the cost of print quality.", "type": "boolean", - "default": false, + "default_value": false, "visible": false, "global_only": "True" }, @@ -1381,7 +1381,7 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "default": 20, + "default_value": 20, "visible": true, "enabled": "jerk_enabled", "children": { @@ -1393,7 +1393,7 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "default": 20, + "default_value": 20, "visible": false, "enabled": "jerk_enabled" }, @@ -1405,7 +1405,7 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "default": 20, + "default_value": 20, "visible": false, "enabled": "jerk_enabled", "children": { @@ -1417,7 +1417,7 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "default": 20, + "default_value": 20, "visible": false, "enabled": "jerk_enabled" }, @@ -1429,7 +1429,7 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "default": 20, + "default_value": 20, "visible": false, "enabled": "jerk_enabled" } @@ -1443,7 +1443,7 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "default": 20, + "default_value": 20, "visible": false, "enabled": "jerk_enabled" }, @@ -1455,7 +1455,7 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "default": 20, + "default_value": 20, "visible": false, "enabled": "jerk_enabled and support_roof_enable", "children": { @@ -1464,7 +1464,7 @@ "description": "The jerk with which the infill of support is printed. Printing the infill at lower jerks improves stability.", "unit": "mm/s³", "type": "float", - "default": 20, + "default_value": 20, "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", @@ -1477,7 +1477,7 @@ "description": "The jerk with which the roofs of support are printed. Printing the support roof at lower jerks can improve overhang quality.", "unit": "mm/s³", "type": "float", - "default": 20, + "default_value": 20, "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", @@ -1495,7 +1495,7 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "default": 20, + "default_value": 20, "visible": false, "enabled": "prime_tower_enable and jerk_enabled", "global_only": true @@ -1507,7 +1507,7 @@ "description": "The jerk with which travel moves are made.", "unit": "mm/s³", "type": "float", - "default": 30, + "default_value": 30, "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", @@ -1521,7 +1521,7 @@ "description": "The print jerk for the initial layer. A lower value is advised to improve adhesion to the build plate.", "unit": "mm/s³", "type": "float", - "default": 20, + "default_value": 20, "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", @@ -1533,7 +1533,7 @@ "description": "The jerk with which the skirt and brim are printed. Normally this is done at the initial layer jerk, but sometimes you might want to print the skirt with a different jerk.", "unit": "mm/s³", "type": "float", - "default": 20, + "default_value": 20, "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", @@ -2341,7 +2341,7 @@ "description": "The acceleration with which the raft is printed.", "unit": "mm/s²", "type": "float", - "default": 3000, + "default_value": 3000, "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", @@ -2355,7 +2355,7 @@ "description": "The acceleration with which the surface raft layers are printed.", "unit": "mm/s²", "type": "float", - "default": 3000, + "default_value": 3000, "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", @@ -2368,7 +2368,7 @@ "description": "The acceleration with which the interface raft layer is printed.", "unit": "mm/s²", "type": "float", - "default": 3000, + "default_value": 3000, "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", @@ -2381,7 +2381,7 @@ "description": "The acceleration with which the base raft layer is printed.", "unit": "mm/s²", "type": "float", - "default": 3000, + "default_value": 3000, "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", @@ -2399,7 +2399,7 @@ "description": "The jerk with which the raft is printed.", "unit": "mm/s³", "type": "float", - "default": 20, + "default_value": 20, "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", @@ -2413,7 +2413,7 @@ "description": "The jerk with which the surface raft layers are printed.", "unit": "mm/s³", "type": "float", - "default": 20, + "default_value": 20, "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "100", @@ -2426,7 +2426,7 @@ "description": "The jerk with which the interface raft layer is printed.", "unit": "mm/s³", "type": "float", - "default": 20, + "default_value": 20, "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", @@ -2439,7 +2439,7 @@ "description": "The jerk with which the base raft layer is printed.", "unit": "mm/s³", "type": "float", - "default": 20, + "default_value": 20, "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", From 6b5e72de72e33b7c1c259a4d19061682ea3a1dbc Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 30 May 2016 14:42:01 +0200 Subject: [PATCH 310/705] JSON refactor: inherit_function ==> default for acceleration and jerk (CURA-1443) --- resources/definitions/fdmprinter.def.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 2e11f20b48..06c9c50e20 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1331,7 +1331,7 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "inherit_function": "acceleration_print if magic_spiralize else 5000", + "default": "acceleration_print if magic_spiralize else 5000", "global_only": true, "visible": true, "enabled": "acceleration_enabled" @@ -1358,7 +1358,7 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "visible": false, - "inherit_function": "acceleration_layer_0", + "default": "acceleration_layer_0", "global_only": true, "enabled": "acceleration_enabled" }, @@ -1511,7 +1511,7 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "inherit_function": "jerk_print if magic_spiralize else 30", + "default": "jerk_print if magic_spiralize else 30", "global_only": true, "visible": true, "enabled": "jerk_enabled" @@ -1538,7 +1538,7 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "visible": false, - "inherit_function": "jerk_layer_0", + "default": "jerk_layer_0", "global_only": true, "enabled": "jerk_enabled" } @@ -2345,7 +2345,7 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "inherit_function": "acceleration_print", + "default": "acceleration_print", "global_only": "True", "visible": false, "enabled": "adhesion_type == \"raft\" and acceleration_enabled", @@ -2403,7 +2403,7 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "inherit_function": "jerk_print", + "default": "jerk_print", "global_only": "True", "visible": false, "enabled": "adhesion_type == \"raft\" and jerk_enabled", From d67bd1015ee69b78dc7ab83d537fe772f3be61c2 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 30 May 2016 14:50:09 +0200 Subject: [PATCH 311/705] JSON fix: visible wasn't inside metadata (CURA-1443) --- resources/definitions/ultimaker.def.json | 2 +- resources/definitions/ultimaker2_extended_plus.def.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/definitions/ultimaker.def.json b/resources/definitions/ultimaker.def.json index 60e4dbbf40..3ed8c3f42c 100644 --- a/resources/definitions/ultimaker.def.json +++ b/resources/definitions/ultimaker.def.json @@ -1,12 +1,12 @@ { "id": "ultimaker_base", "version": 2, - "visible": false, "name": "Ultimaker", "inherits": "fdmprinter", "metadata": { "author": "Ultimaker", "manufacturer": "Ultimaker", + "visible": false, "preferred_profile": "Normal Quality", "preferred_nozzle": "0.4 mm", "preferred_material": "PLA" diff --git a/resources/definitions/ultimaker2_extended_plus.def.json b/resources/definitions/ultimaker2_extended_plus.def.json index eae48773b6..96239fa804 100644 --- a/resources/definitions/ultimaker2_extended_plus.def.json +++ b/resources/definitions/ultimaker2_extended_plus.def.json @@ -3,14 +3,14 @@ "version": 2, "name": "Ultimaker 2 Extended+", "inherits": "ultimaker2_plus", - "visible": false, "metadata": { "author": "Ultimaker", "manufacturer": "Ultimaker", "category": "Ultimaker", "file_formats": "text/x-gcode", "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2ExtendedPlusbackplate.png" + "platform_texture": "Ultimaker2ExtendedPlusbackplate.png", + "visible": false }, "overrides": { From b8df3825f6f2ef1d22e033c47cd104da8582b33b Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 30 May 2016 14:54:33 +0200 Subject: [PATCH 312/705] JSON fix: remove visible property (and add visibility defaults (CURA-1443) for acceleration and jerk settings --- cura/CuraApplication.py | 3 ++ resources/definitions/fdmprinter.def.json | 35 ----------------------- 2 files changed, 3 insertions(+), 35 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index f0610a3538..de716fe25f 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -167,6 +167,9 @@ class CuraApplication(QtApplication): speed speed_print speed_travel + acceleration_print + acceleration_travel + jerk_print travel cooling cool_fan_enabled diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 06c9c50e20..716f7aa55f 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1190,7 +1190,6 @@ "description": "Enables adjusting the print head acceleration. Increasing the accelerations can reduce printing time at the cost of print quality.", "type": "boolean", "default_value": false, - "visible": false, "global_only": "True" }, "acceleration_print": { @@ -1202,7 +1201,6 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default_value": 3000, - "visible": true, "enabled": "acceleration_enabled", "children": { "acceleration_infill": { @@ -1214,7 +1212,6 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default_value": 3000, - "visible": false, "enabled": "acceleration_enabled" }, "acceleration_wall": { @@ -1226,7 +1223,6 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default_value": 3000, - "visible": false, "enabled": "acceleration_enabled", "children": { "acceleration_wall_0": { @@ -1238,7 +1234,6 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default_value": 3000, - "visible": false, "enabled": "acceleration_enabled" }, "acceleration_wall_x": { @@ -1250,7 +1245,6 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default_value": 3000, - "visible": false, "enabled": "acceleration_enabled" } } @@ -1264,7 +1258,6 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default_value": 3000, - "visible": false, "enabled": "acceleration_enabled" }, "acceleration_support": { @@ -1276,7 +1269,6 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default_value": 3000, - "visible": false, "enabled": "acceleration_enabled and support_roof_enable", "children": { "acceleration_support_infill": { @@ -1288,7 +1280,6 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "visible": false, "enabled": "acceleration_enabled and support_enable", "global_only": true }, @@ -1301,7 +1292,6 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "visible": false, "enabled": "acceleration_enabled and support_roof_enable", "global_only": true } @@ -1316,7 +1306,6 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default_value": 3000, - "visible": false, "enabled": "prime_tower_enable and acceleration_enabled", "global_only": true } @@ -1333,7 +1322,6 @@ "maximum_value_warning": "10000", "default": "acceleration_print if magic_spiralize else 5000", "global_only": true, - "visible": true, "enabled": "acceleration_enabled" }, "acceleration_layer_0": { @@ -1345,7 +1333,6 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "visible": false, "enabled": "acceleration_enabled" }, "acceleration_skirt": { @@ -1357,7 +1344,6 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "visible": false, "default": "acceleration_layer_0", "global_only": true, "enabled": "acceleration_enabled" @@ -1370,7 +1356,6 @@ "description": "Enables adjusting the jerk of print head when the X ar Y axis halts or starts to move. Increasing the jerk can reduce printing time at the cost of print quality.", "type": "boolean", "default_value": false, - "visible": false, "global_only": "True" }, "jerk_print": { @@ -1382,7 +1367,6 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default_value": 20, - "visible": true, "enabled": "jerk_enabled", "children": { "jerk_infill": { @@ -1394,7 +1378,6 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default_value": 20, - "visible": false, "enabled": "jerk_enabled" }, "jerk_wall": { @@ -1406,7 +1389,6 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default_value": 20, - "visible": false, "enabled": "jerk_enabled", "children": { "jerk_wall_0": { @@ -1418,7 +1400,6 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default_value": 20, - "visible": false, "enabled": "jerk_enabled" }, "jerk_wall_x": { @@ -1430,7 +1411,6 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default_value": 20, - "visible": false, "enabled": "jerk_enabled" } } @@ -1444,7 +1424,6 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default_value": 20, - "visible": false, "enabled": "jerk_enabled" }, "jerk_support": { @@ -1456,7 +1435,6 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default_value": 20, - "visible": false, "enabled": "jerk_enabled and support_roof_enable", "children": { "jerk_support_infill": { @@ -1468,7 +1446,6 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "visible": false, "enabled": "jerk_enabled and support_enable", "global_only": true }, @@ -1481,7 +1458,6 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "visible": false, "enabled": "jerk_enabled and support_roof_enable", "global_only": true } @@ -1496,7 +1472,6 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default_value": 20, - "visible": false, "enabled": "prime_tower_enable and jerk_enabled", "global_only": true } @@ -1525,7 +1500,6 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "visible": false, "enabled": "jerk_enabled" }, "jerk_skirt": { @@ -1537,7 +1511,6 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "visible": false, "default": "jerk_layer_0", "global_only": true, "enabled": "jerk_enabled" @@ -2347,7 +2320,6 @@ "maximum_value_warning": "10000", "default": "acceleration_print", "global_only": "True", - "visible": false, "enabled": "adhesion_type == \"raft\" and acceleration_enabled", "children": { "raft_surface_acceleration": { @@ -2360,7 +2332,6 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "global_only": "True", - "visible": false, "enabled": "adhesion_type == \"raft\" and acceleration_enabled" }, "raft_interface_acceleration": { @@ -2373,7 +2344,6 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "global_only": "True", - "visible": false, "enabled": "adhesion_type == \"raft\" and acceleration_enabled" }, "raft_base_acceleration": { @@ -2386,7 +2356,6 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "global_only": "True", - "visible": false, "enabled": "adhesion_type == \"raft\" and acceleration_enabled" } } @@ -2405,7 +2374,6 @@ "maximum_value_warning": "50", "default": "jerk_print", "global_only": "True", - "visible": false, "enabled": "adhesion_type == \"raft\" and jerk_enabled", "children": { "raft_surface_jerk": { @@ -2418,7 +2386,6 @@ "minimum_value_warning": "5", "maximum_value_warning": "100", "global_only": "True", - "visible": false, "enabled": "adhesion_type == \"raft\" and jerk_enabled" }, "raft_interface_jerk": { @@ -2431,7 +2398,6 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "global_only": "True", - "visible": false, "enabled": "adhesion_type == \"raft\" and jerk_enabled" }, "raft_base_jerk": { @@ -2444,7 +2410,6 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "global_only": "True", - "visible": false, "enabled": "adhesion_type == \"raft\" and jerk_enabled" } } From 79892daa5e493c85ae8d8da95e30bdcffbf9ce65 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 30 May 2016 15:26:21 +0200 Subject: [PATCH 313/705] Bump API version of plugins that do not need extra porting Contributes to CURA-1615 --- plugins/3MFReader/__init__.py | 2 +- plugins/ChangeLogPlugin/__init__.py | 4 ++-- plugins/ImageReader/__init__.py | 2 +- plugins/RemovableDriveOutputDevice/__init__.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/3MFReader/__init__.py b/plugins/3MFReader/__init__.py index 610165f7a0..42b1794160 100644 --- a/plugins/3MFReader/__init__.py +++ b/plugins/3MFReader/__init__.py @@ -13,7 +13,7 @@ def getMetaData(): "author": "Ultimaker", "version": "1.0", "description": catalog.i18nc("@info:whatsthis", "Provides support for reading 3MF files."), - "api": 2 + "api": 3 }, "mesh_reader": [ { diff --git a/plugins/ChangeLogPlugin/__init__.py b/plugins/ChangeLogPlugin/__init__.py index 88ac4e08a6..8466bfaa1b 100644 --- a/plugins/ChangeLogPlugin/__init__.py +++ b/plugins/ChangeLogPlugin/__init__.py @@ -13,9 +13,9 @@ def getMetaData(): "author": "Ultimaker", "version": "1.0", "description": catalog.i18nc("@info:whatsthis", "Shows changes since latest checked version."), - "api": 2 + "api": 3 } } def register(app): - return {"extension": ChangeLog.ChangeLog()} \ No newline at end of file + return {"extension": ChangeLog.ChangeLog()} diff --git a/plugins/ImageReader/__init__.py b/plugins/ImageReader/__init__.py index 69fc1ddcc3..7ebdc31e57 100644 --- a/plugins/ImageReader/__init__.py +++ b/plugins/ImageReader/__init__.py @@ -13,7 +13,7 @@ def getMetaData(): "author": "Ultimaker", "version": "1.0", "description": i18n_catalog.i18nc("@info:whatsthis", "Enables ability to generate printable geometry from 2D image files."), - "api": 2 + "api": 3 }, "mesh_reader": [ { diff --git a/plugins/RemovableDriveOutputDevice/__init__.py b/plugins/RemovableDriveOutputDevice/__init__.py index 635bdde008..16adcbfd7c 100644 --- a/plugins/RemovableDriveOutputDevice/__init__.py +++ b/plugins/RemovableDriveOutputDevice/__init__.py @@ -13,7 +13,7 @@ def getMetaData(): "author": "Ultimaker B.V.", "description": catalog.i18nc("@info:whatsthis", "Provides removable drive hotplugging and writing support."), "version": "1.0", - "api": 2 + "api": 3 } } From bdc8fdf508fdcbe13836de26d350f5f5cba0d909 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 30 May 2016 15:27:13 +0200 Subject: [PATCH 314/705] Turn CuraApplication::_onExit into public api as saveSettings Since we need it for the autosave plugin Contributes to CURA-1615 --- cura/CuraApplication.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index f0610a3538..eccb3e4525 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -116,6 +116,7 @@ class CuraApplication(QtApplication): self._center_after_select = False self._camera_animation = None self._cura_actions = None + self._started = False self.getController().getScene().sceneChanged.connect(self.updatePlatformActivity) self.getController().toolOperationStopped.connect(self._onToolOperationStopped) @@ -189,7 +190,7 @@ class CuraApplication(QtApplication): JobQueue.getInstance().jobFinished.connect(self._onJobFinished) - self.applicationShuttingDown.connect(self._onExit) + self.applicationShuttingDown.connect(self.saveSettings) self._recent_files = [] files = Preferences.getInstance().getValue("cura/recent_files").split(";") @@ -199,8 +200,13 @@ class CuraApplication(QtApplication): self._recent_files.append(QUrl.fromLocalFile(f)) - ## Cura has multiple locations where instance containers need to be saved, so we need to handle this differently. - def _onExit(self): + ## Cura has multiple locations where instance containers need to be saved, so we need to handle this differently. + # + # Note that the AutoSave plugin also calls this method. + def saveSettings(self): + if not self._started: # Do not do saving during application start + return + for instance in ContainerRegistry.getInstance().findInstanceContainers(): if not instance.isDirty(): continue @@ -332,6 +338,8 @@ class CuraApplication(QtApplication): for file_name in self._open_file_queue: #Open all the files that were queued up while plug-ins were loading. self._openFile(file_name) + self._started = True + self.exec_() ## Handle Qt events From 581b9ce11ff25d787c5dd0babd3b05cca1bde318 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 30 May 2016 15:28:14 +0200 Subject: [PATCH 315/705] Update AutoSave plugin to work with the new settings API Contributes to CURA-1615 --- plugins/AutoSave/AutoSave.py | 31 ++++++++++++------------------- plugins/AutoSave/__init__.py | 2 +- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/plugins/AutoSave/AutoSave.py b/plugins/AutoSave/AutoSave.py index e621ccdc4b..2aa49e3da1 100644 --- a/plugins/AutoSave/AutoSave.py +++ b/plugins/AutoSave/AutoSave.py @@ -15,15 +15,9 @@ class AutoSave(Extension): Preferences.getInstance().preferenceChanged.connect(self._triggerTimer) - machine_manager = Application.getInstance().getMachineManager() - - self._profile = None - machine_manager.activeProfileChanged.connect(self._onActiveProfileChanged) - machine_manager.profileNameChanged.connect(self._triggerTimer) - machine_manager.profilesChanged.connect(self._triggerTimer) - machine_manager.machineInstanceNameChanged.connect(self._triggerTimer) - machine_manager.machineInstancesChanged.connect(self._triggerTimer) - self._onActiveProfileChanged() + self._global_stack = None + Application.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged) + self._onGlobalStackChanged() Preferences.getInstance().addPreference("cura/autosave_delay", 1000 * 10) @@ -38,24 +32,23 @@ class AutoSave(Extension): if not self._saving: self._change_timer.start() - def _onActiveProfileChanged(self): - if self._profile: - self._profile.settingValueChanged.disconnect(self._triggerTimer) + def _onGlobalStackChanged(self): + if self._global_stack: + self._global_stack.propertyChanged.disconnect(self._triggerTimer) + self._global_stack.containersChanged.disconnect(self._triggerTimer) - self._profile = Application.getInstance().getMachineManager().getWorkingProfile() + self._global_stack = Application.getInstance().getGlobalContainerStack() - if self._profile: - self._profile.settingValueChanged.connect(self._triggerTimer) + if self._global_stack: + self._global_stack.propertyChanged.connect(self._triggerTimer) + self._global_stack.containersChanged.connect(self._triggerTimer) def _onTimeout(self): self._saving = True # To prevent the save process from triggering another autosave. Logger.log("d", "Autosaving preferences, instances and profiles") - machine_manager = Application.getInstance().getMachineManager() + Application.getInstance().saveSettings() - machine_manager.saveVisibility() - machine_manager.saveMachineInstances() - machine_manager.saveProfiles() Preferences.getInstance().writeToFile(Resources.getStoragePath(Resources.Preferences, Application.getInstance().getApplicationName() + ".cfg")) self._saving = False diff --git a/plugins/AutoSave/__init__.py b/plugins/AutoSave/__init__.py index 0caa02a748..7e70ebe0a2 100644 --- a/plugins/AutoSave/__init__.py +++ b/plugins/AutoSave/__init__.py @@ -13,7 +13,7 @@ def getMetaData(): "author": "Ultimaker", "version": "1.0", "description": catalog.i18nc("@info:whatsthis", "Automatically saves Preferences, Machines and Profiles after changes."), - "api": 2 + "api": 3 }, } From 7e33b76fe2b744db682b5a0bf4277906178647fb Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 30 May 2016 16:18:54 +0200 Subject: [PATCH 316/705] Increment version number Contributes to issue CURA-1583. --- plugins/ChangeLogPlugin/ChangeLog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/ChangeLogPlugin/ChangeLog.txt b/plugins/ChangeLogPlugin/ChangeLog.txt index 6cf0b5a488..48e96ce4b6 100644 --- a/plugins/ChangeLogPlugin/ChangeLog.txt +++ b/plugins/ChangeLogPlugin/ChangeLog.txt @@ -1,4 +1,4 @@ -[2.1.1] +[2.1.2] Cura has been completely reengineered from the ground up for an even more seamless integration between hardware, software and materials. Together with its intuitive new user interface, it’s now also ready for any future developments. For the beginner Cura makes 3D printing incredibly easy, and for more advanced users, there are over 140 new customisable settings. From d616a72bb12897807176a67e35c2642adb2df8cc Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 30 May 2016 16:25:20 +0200 Subject: [PATCH 317/705] Display affects/affected by in the tooltip again Contributes to CURA-1278 --- resources/qml/Settings/SettingItem.qml | 32 +++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index 013dcd1680..c1666a8157 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -50,7 +50,37 @@ Item { interval: 500; repeat: false; - onTriggered: base.showTooltip(definition.description); + onTriggered: + { + var affects = settingDefinitionsModel.getRequiredBy(definition.key, "value") + var affected_by = settingDefinitionsModel.getRequires(definition.key, "value") + + var affected_by_list = "" + for(var i in affected_by) + { + affected_by_list += "
  • %1
  • \n".arg(affected_by[i].label) + } + + var affects_list = "" + for(var i in affects) + { + affects_list += "
  • %1
  • \n".arg(affects[i].label) + } + + var tooltip = "%1
    \n

    %2

    ".arg(definition.label).arg(definition.description) + + if(affects_list != "") + { + tooltip += "
    %1
    \n
      \n%2
    ".arg(catalog.i18nc("@label", "Affects")).arg(affects_list) + } + + if(affected_by_list != "") + { + tooltip += "
    %1
    \n
      \n%2
    ".arg(catalog.i18nc("@label", "Affected By")).arg(affected_by_list) + } + + base.showTooltip(tooltip); + } } Label From b1419d802861952f8f1d2dab8cb9df751f15d5d4 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 30 May 2016 16:45:36 +0200 Subject: [PATCH 318/705] Fix activating (quality)profiles on the profiles page CURA-1278 --- resources/qml/Preferences/ProfilesPage.qml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 6e5d39cb49..10acc8beef 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -6,6 +6,7 @@ import QtQuick.Controls 1.1 import QtQuick.Dialogs 1.2 import UM 1.2 as UM +import Cura 1.0 as Cura UM.ManagementPage { @@ -16,6 +17,7 @@ UM.ManagementPage model: UM.InstanceContainersModel { filter: { "type": "quality" } } + onActivateObject: Cura.MachineManager.setActiveQuality(currentItem.id) onAddObject: { var selectedProfile; if (objectList.currentIndex == 0) { @@ -33,6 +35,7 @@ UM.ManagementPage onRemoveObject: confirmDialog.open(); onRenameObject: { renameDialog.removeWhenRejected = false; renameDialog.open(); renameDialog.selectText(); } + activateEnabled: currentItem != null ? currentItem.id != Cura.MachineManager.activeQualityId : false; addEnabled: currentItem != null; removeEnabled: currentItem != null ? !currentItem.readOnly : false; renameEnabled: currentItem != null ? !currentItem.readOnly : false; @@ -69,7 +72,7 @@ UM.ManagementPage Row { - visible: base.currentItem.id == -1 || base.currentItem.active + visible: base.currentItem.id == -1 || currentItem.id == Cura.MachineManager.activeQualityId Button { text: { From 932eefeb0e60cb0486f4927e7923b3e126d77a0e Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 30 May 2016 16:31:00 +0200 Subject: [PATCH 319/705] Correct data type for extruder number setting This caused a crash. Stupid mistake. --- 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 ab16f49a8d..6dca68a6c9 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -110,7 +110,7 @@ "description": "Number of extruder trains. An extruder train is the combination of a feeder, bowden tube, and nozzle.", "default_value": 1, "global_only": true, - "type": "bool", + "type": "int", "label": "Number extruders" }, "machine_nozzle_tip_outer_diameter": From d7eda39cb0e23351033e284656332bdd91afd563 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 30 May 2016 17:05:06 +0200 Subject: [PATCH 320/705] Basic extruder manager model implementation This implementation is currently not used, and also still leaves its container stacks empty. But still... Contributes to issues CURA-1278 and CURA-351. --- cura/ExtruderManagerModel.py | 102 +++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 cura/ExtruderManagerModel.py diff --git a/cura/ExtruderManagerModel.py b/cura/ExtruderManagerModel.py new file mode 100644 index 0000000000..7f0baa7aa8 --- /dev/null +++ b/cura/ExtruderManagerModel.py @@ -0,0 +1,102 @@ +# Copyright (c) 2016 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. + +from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal +import re + +from UM.Application import Application #To get the global container stack to find the current machine. +from UM.Logger import Logger +from UM.Settings.ContainerStack import ContainerStack #To create container stacks for each extruder. +from UM.Settings.ContainerRegistry import ContainerRegistry #Finding containers by ID. + + +## Class that handles the current extruder stack. +# +# This finds the extruders that are available for the currently active machine +# and makes sure that whenever the machine is swapped, this list is kept up to +# date. It also contains and updates the setting stacks for the extruders. +class ExtruderManagerModel(QObject): + ## Registers listeners and such to listen to changes to the extruders. + # + # \param parent Parent QObject of this model. + def __init__(self, parent = None): + super().__init__(parent) + + self._extruderDefinitions = [] #Extruder definitions for the current machine. + self._nozzles = {} #Nozzle instances for each extruder. + self._extruderTrains = [] #Container stacks for each of the extruder trains. + + Application.getInstance().getGlobalContainerStack().containersChanged.connect(self._reloadExtruders) #When the current machine changes, we need to reload all extruders belonging to the new machine. + + ## (Re)loads all extruders of the currently active machine. + # + # This looks at the global container stack to see which machine is active. + # Then it loads the extruder definitions for that machine and the variants + # of those definitions. Then it puts the new extruder definitions in the + # appropriate place in the container stacks. + def _reloadExtruders(self): + self._extruderDefinitions = [] + self._nozzles = {} + self._extruderTrains = [] + global_container_stack = Application.getInstance().getGlobalContainerStack() + if not global_container_stack: #No machine has been added yet. + return #Then leave them empty! + + #Fill the list of extruder trains. + machine = global_container_stack.getBottom() + extruder_train_ids = machine.getMetaData("machine_extruder_trains") + for extruder_train_id in extruder_train_ids: + extruders = ContainerRegistry.getInstance().findDefinitionContainers(id = extruder_train_id) #Should be only 1 definition if IDs are unique, but add the whole list anyway. + if not extruders: #Empty list or error. + Logger.log("w", "Machine definition %s refers to an extruder train \"%s\", but no such extruder was found.", machine.getId(), extruder_train_id) + continue + self._extruderDefinitions += extruders + + #Fill the nozzles for each of the extruder trains. + for extruder in self._extruderDefinitions: + self._nozzles[extruder.id] = [] + all_nozzles = ContainerRegistry.getInstance().findInstanceContainers(type="nozzle") + for nozzle in all_nozzles: + extruders = nozzle.getMetaDataEntry("definitions").split(",").strip() + for extruder_id in extruders: + self._nozzles[extruder_id] = nozzle + + #Create the extruder train container stacks. + for extruder in self._extruderDefinitions: + self._extruderTrains.append(self._createContainerStack(extruder)) + + ## Creates a container stack for the specified extruder. + # + # This fills in the specified extruder as base definition, then a nozzle + # that fits in that extruder train, then a material that fits through that + # nozzle, then a quality profile that can be used with that material, and + # finally an empty user profile. + # + # \param extruder The extruder to create the container stack for. + # \return A container stack with the specified extruder as base. + def _createContainerStack(self, extruder): + container_stack = ContainerStack(self._uniqueName(extruder)) + #TODO: Fill the container stack. + return container_stack + + ## Finds a unique name for an extruder stack. + # + # \param extruder Extruder to design a name for. + # \return A name for an extruder stack that is unique and reasonably + # human-readable. + def _uniqueName(self, extruder): + container_registry = ContainerRegistry.getInstance() + + name = extruder.getName().strip() + num_check = re.compile("(.*?)\s*#\d$").match(name) + if(num_check): #There is a number in the name. + name = num_check.group(1) #Filter out the number. + if name == "": #Wait, that deleted everything! + name = "Extruder" + unique_name = name + + i = 1 + while(container_registry.findContainers(id = unique_name) or container_registry.findContainers(name = unique_name)): #A container already has this name. + i += 1 #Try next numbering. + unique_name = "%s #%d" % (name, i) #Fill name like this: "Extruder #2". + return unique_name \ No newline at end of file From 5289d5b4ac29e66e759edb6478b7b731456b2b3e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 31 May 2016 11:02:22 +0200 Subject: [PATCH 321/705] Codestyle CURA-1278 --- plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index 8c9b63ac1b..8c39919b13 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -18,12 +18,6 @@ Item { width: childrenRect.width; height: childrenRect.height; - - function updateContainerID() - { - console.log("containerid",UM.ActiveTool.properties.getValue("ContainerID")) - } - Column { id: items @@ -58,7 +52,7 @@ Item { //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989 //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes, - //causing nasty issues when selecting differnt options. So disable asynchronous loading of enum type completely. + //causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely. asynchronous: model.type != "enum" source: From 72d7bd57697696540a88287c98c529cec3c6488d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 31 May 2016 11:06:26 +0200 Subject: [PATCH 322/705] Added hide button to per object settings CURA-1278 --- .../PerObjectSettingsPanel.qml | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index 8c39919b13..c68cd88dea 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -75,7 +75,32 @@ Item { return "../../resources/qml/Settings/SettingUnknown.qml" } } + Button + { + width: UM.Theme.getSize("setting").height; + height: UM.Theme.getSize("setting").height; + onClicked: addedSettingsModel.setVisible(model.key, false); + + style: ButtonStyle + { + background: Rectangle + { + color: control.hovered ? control.parent.style.controlHighlightColor : control.parent.style.controlColor; + UM.RecolorImage + { + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width/2 + height: parent.height/2 + sourceSize.width: width + sourceSize.height: width + color: control.hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button") + source: UM.Theme.getIcon("cross1") + } + } + } + } UM.SettingPropertyProvider { id: provider From 152f36256284bcb1e22e8b83024f681e85a43767 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 31 May 2016 11:12:22 +0200 Subject: [PATCH 323/705] Hide button is now in correct location CURA-1278 --- .../PerObjectSettingsPanel.qml | 64 ++++++++++--------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index c68cd88dea..e5149ccb79 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -41,40 +41,44 @@ Item { } } - delegate: Loader + delegate: Row { - width: UM.Theme.getSize("setting").width; - height: UM.Theme.getSize("setting").height; - - property var definition: model - property var settingDefinitionsModel: addedSettingsModel - property var propertyProvider: provider - - //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989 - //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes, - //causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely. - asynchronous: model.type != "enum" - - source: + Loader { - switch(model.type) // TODO: This needs to be fixed properly. Got frustrated with it not working, so this is the patch job! + width: UM.Theme.getSize("setting").width; + height: UM.Theme.getSize("setting").height; + + property var definition: model + property var settingDefinitionsModel: addedSettingsModel + property var propertyProvider: provider + + //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989 + //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes, + //causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely. + asynchronous: model.type != "enum" + + source: { - case "int": - return "../../resources/qml/Settings/SettingTextField.qml" - case "float": - return "../../resources/qml/Settings/SettingTextField.qml" - case "enum": - return "../../resources/qml/Settings/SettingComboBox.qml" - case "bool": - return "../../resources/qml/Settings/SettingCheckBox.qml" - case "str": - return "../../resources/qml/Settings/SettingTextField.qml" - case "category": - return "../../resources/qml/Settings/SettingCategory.qml" - default: - return "../../resources/qml/Settings/SettingUnknown.qml" + switch(model.type) // TODO: This needs to be fixed properly. Got frustrated with it not working, so this is the patch job! + { + case "int": + return "../../resources/qml/Settings/SettingTextField.qml" + case "float": + return "../../resources/qml/Settings/SettingTextField.qml" + case "enum": + return "../../resources/qml/Settings/SettingComboBox.qml" + case "bool": + return "../../resources/qml/Settings/SettingCheckBox.qml" + case "str": + return "../../resources/qml/Settings/SettingTextField.qml" + case "category": + return "../../resources/qml/Settings/SettingCategory.qml" + default: + return "../../resources/qml/Settings/SettingUnknown.qml" + } } } + Button { width: UM.Theme.getSize("setting").height; @@ -111,8 +115,8 @@ Item { storeIndex: 0 } } - } + Button { id: customise_settings_button; From 29ed8c2f5be2f87c7b44cf441f14f1baa190f396 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 31 May 2016 11:33:02 +0200 Subject: [PATCH 324/705] Increased width of per-object settings panel CURA-1278 --- plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml | 2 +- resources/themes/cura/theme.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index e5149ccb79..f873ec9a79 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -46,7 +46,7 @@ Item { Loader { width: UM.Theme.getSize("setting").width; - height: UM.Theme.getSize("setting").height; + height: UM.Theme.getSize("section").height; property var definition: model property var settingDefinitionsModel: addedSettingsModel diff --git a/resources/themes/cura/theme.json b/resources/themes/cura/theme.json index 67df41ef7c..acd60e2646 100644 --- a/resources/themes/cura/theme.json +++ b/resources/themes/cura/theme.json @@ -176,7 +176,7 @@ "section_icon": [1.6, 1.6], "section_icon_column": [2.8, 0.0], - "setting": [19.0, 1.8], + "setting": [25.0, 1.8], "setting_control": [10.0, 2.0], "setting_control_depth_margin": [1.4, 0.0], "setting_preferences_button_margin": [3.3, 0.0], From 3638890138d1fed247bfd01bb5abbb55fa650003 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 31 May 2016 15:26:38 +0200 Subject: [PATCH 325/705] Renaming a printer in the Manage Printers dialog is now reflected in the sidebar again Contributes to CURA-1632 --- cura/MachineManagerModel.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 7b42483fca..deef72529b 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -263,6 +263,7 @@ class MachineManagerModel(QObject): if containers: new_name = self._uniqueMachineName(new_name, containers[0].getBottom().getName()) containers[0].setName(new_name) + self.globalContainerChanged.emit() @pyqtSlot(str) def removeMachine(self, machine_id): From 21e8dd151ef26801ce006f326ff664eb1cb2a616 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 31 May 2016 15:48:08 +0200 Subject: [PATCH 326/705] Prevent removing the last printer, disable Activate button for current active printer Fixes CURA-1631 --- resources/qml/MachinesPage.qml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/resources/qml/MachinesPage.qml b/resources/qml/MachinesPage.qml index 8c7a2c521d..00ebcfc0af 100644 --- a/resources/qml/MachinesPage.qml +++ b/resources/qml/MachinesPage.qml @@ -12,11 +12,9 @@ UM.ManagementPage id: base; title: catalog.i18nc("@title:tab", "Printers"); - property int numInstances: model.rowCount(); model: UM.ContainerStacksModel { filter: {"type": "machine"} - onDataChanged: numInstances = model.rowCount() } onAddObject: Printer.requestAddPrinter() @@ -24,9 +22,9 @@ UM.ManagementPage onRenameObject: renameDialog.open(); onActivateObject: Cura.MachineManager.setActiveMachine(base.currentItem.id) - removeEnabled: base.currentItem != null && numInstances > 1 - renameEnabled: base.currentItem != null && numInstances > 0 - activateEnabled: base.currentItem != null + removeEnabled: base.currentItem != null && model.rowCount() > 1 + renameEnabled: base.currentItem != null + activateEnabled: base.currentItem != null && base.currentItem.id != Cura.MachineManager.activeMachineId Flow { From 23cb386b7c99f4070900a32ebfe0c9406f57e950 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Tue, 31 May 2016 17:41:36 +0200 Subject: [PATCH 327/705] Set default version to 2.1.2 While discussing on #718 I noticed that the splash screen still shows "master" when built from [2.1]. This sets the version to 2.1.2. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dc9f37c76e..6a23ffe94f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ include(GNUInstallDirs) set(URANIUM_SCRIPTS_DIR "${CMAKE_SOURCE_DIR}/../uranium/scripts" CACHE DIRECTORY "The location of the scripts directory of the Uranium repository") -set(CURA_VERSION "master" CACHE STRING "Version name of Cura") +set(CURA_VERSION "2.1.2" CACHE STRING "Version name of Cura") configure_file(cura/CuraVersion.py.in CuraVersion.py @ONLY) # Macro needed to list all sub-directory of a directory. From 4dffc414fb0ee775ef6d5fc21e2a8cc85ee98858 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 31 May 2016 17:59:03 +0200 Subject: [PATCH 328/705] Make convex hull decorator respond properly to property change events Fixes CURA-1460 --- cura/ConvexHullDecorator.py | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/cura/ConvexHullDecorator.py b/cura/ConvexHullDecorator.py index 8fb26858a5..6639d12dc7 100644 --- a/cura/ConvexHullDecorator.py +++ b/cura/ConvexHullDecorator.py @@ -27,7 +27,9 @@ class ConvexHullDecorator(SceneNodeDecorator): # Keep track of the previous parent so we can clear its convex hull when the object is reparented self._parent_node = None - self._profile = None + self._global_stack = None + Application.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged) + self._onGlobalStackChanged() #Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onActiveProfileChanged) #Application.getInstance().getMachineManager().activeMachineInstanceChanged.connect(self._onActiveMachineInstanceChanged) #self._onActiveProfileChanged() @@ -95,28 +97,30 @@ class ConvexHullDecorator(SceneNodeDecorator): def setConvexHullNode(self, node): self._convex_hull_node = node - def _onActiveProfileChanged(self): - if self._profile: - self._profile.settingValueChanged.disconnect(self._onSettingValueChanged) + def _onSettingValueChanged(self, key, property_name): + if key == "print_sequence" and property_name == "value": + self._onChanged() - self._profile = Application.getInstance().getMachineManager().getWorkingProfile() - - if self._profile: - self._profile.settingValueChanged.connect(self._onSettingValueChanged) - - def _onActiveMachineInstanceChanged(self): + def _onChanged(self): if self._convex_hull_job: self._convex_hull_job.cancel() self.setConvexHull(None) - def _onSettingValueChanged(self, setting): - if setting == "print_sequence": - if self._convex_hull_job: - self._convex_hull_job.cancel() - self.setConvexHull(None) - def _onParentChanged(self, node): # Force updating the convex hull of the parent group if the object is in a group if self._parent_node and self._parent_node.callDecoration("isGroup"): self._parent_node.callDecoration("setConvexHull", None) self._parent_node = self.getNode().getParent() + + def _onGlobalStackChanged(self): + if self._global_stack: + self._global_stack.propertyChanged.disconnect(self._onSettingValueChanged) + self._global_stack.containersChanged.disconnect(self._onChanged) + + self._global_stack = Application.getInstance().getGlobalContainerStack() + + if self._global_stack: + self._global_stack.propertyChanged.connect(self._onSettingValueChanged) + self._global_stack.containersChanged.connect(self._onChanged) + + self._onChanged() From f21e48adbbebb11630b90ac339d34f1a5e8bda9c Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 31 May 2016 18:00:26 +0200 Subject: [PATCH 329/705] Register all QML files in Cura's QML directory as part of the Cura module Jaime asked for it. --- cura/CuraApplication.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index eccb3e4525..d7e5768116 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -42,7 +42,7 @@ from . import MachineManagerModel from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty, QEvent, Q_ENUMS from PyQt5.QtGui import QColor, QIcon -from PyQt5.QtQml import qmlRegisterUncreatableType, qmlRegisterSingletonType +from PyQt5.QtQml import qmlRegisterUncreatableType, qmlRegisterSingletonType, qmlRegisterType import platform import sys @@ -365,6 +365,15 @@ class CuraApplication(QtApplication): qmlRegisterUncreatableType(CuraApplication, "Cura", 1, 0, "ResourceTypes", "Just an Enum type") + qmlRegisterSingletonType(QUrl.fromLocalFile(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")), "Cura", 1, 0, "Actions") + + for path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.QmlFiles): + type_name = os.path.splitext(os.path.basename(path))[0] + if type_name in ("Cura", "Actions"): + continue + + qmlRegisterType(QUrl.fromLocalFile(path), "Cura", 1, 0, type_name) + def onSelectionChanged(self): if Selection.hasSelection(): if not self.getController().getActiveTool(): From 3b51c3d339a07effb593339b9fa7202e3f36c358 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 31 May 2016 18:06:20 +0200 Subject: [PATCH 330/705] Remove qmldir from qml resources and use proper Cura namespace for everything Since we now properly expose all the qml files in the Cura namespace we should also use it from there. --- resources/qml/Cura.qml | 124 ++++++++++----------- resources/qml/Settings/SettingCategory.qml | 5 +- resources/qml/Settings/SettingView.qml | 4 +- resources/qml/qmldir | 3 - 4 files changed, 64 insertions(+), 72 deletions(-) delete mode 100644 resources/qml/qmldir diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index a7f4a43c22..a043567c0f 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -10,8 +10,6 @@ import QtQuick.Dialogs 1.1 import UM 1.2 as UM import Cura 1.0 as Cura -import "." - UM.MainWindow { id: base @@ -56,7 +54,7 @@ UM.MainWindow title: catalog.i18nc("@title:menu menubar:toplevel","&File"); MenuItem { - action: Actions.open; + action: Cura.Actions.open; } Menu @@ -118,11 +116,11 @@ UM.MainWindow } } - MenuItem { action: Actions.reloadAll; } + MenuItem { action: Cura.Actions.reloadAll; } MenuSeparator { } - MenuItem { action: Actions.quit; } + MenuItem { action: Cura.Actions.quit; } } Menu @@ -130,17 +128,17 @@ UM.MainWindow //: Edit menu title: catalog.i18nc("@title:menu menubar:toplevel","&Edit"); - MenuItem { action: Actions.undo; } - MenuItem { action: Actions.redo; } + MenuItem { action: Cura.Actions.undo; } + MenuItem { action: Cura.Actions.redo; } MenuSeparator { } - MenuItem { action: Actions.deleteSelection; } - MenuItem { action: Actions.deleteAll; } - MenuItem { action: Actions.resetAllTranslation; } - MenuItem { action: Actions.resetAll; } + MenuItem { action: Cura.Actions.deleteSelection; } + MenuItem { action: Cura.Actions.deleteAll; } + MenuItem { action: Cura.Actions.resetAllTranslation; } + MenuItem { action: Cura.Actions.resetAll; } MenuSeparator { } - MenuItem { action: Actions.groupObjects;} - MenuItem { action: Actions.mergeObjects;} - MenuItem { action: Actions.unGroupObjects;} + MenuItem { action: Cura.Actions.groupObjects;} + MenuItem { action: Cura.Actions.mergeObjects;} + MenuItem { action: Cura.Actions.unGroupObjects;} } Menu @@ -216,8 +214,8 @@ UM.MainWindow MenuSeparator { visible: Cura.MachineManager.hasVariants; } - MenuItem { action: Actions.addMachine; } - MenuItem { action: Actions.configureMachines; } + MenuItem { action: Cura.Actions.addMachine; } + MenuItem { action: Cura.Actions.configureMachines; } } Menu @@ -290,11 +288,11 @@ UM.MainWindow MenuSeparator { id: profileMenuSeparator } - MenuItem { action: Actions.updateProfile; } - MenuItem { action: Actions.resetProfile; } - MenuItem { action: Actions.addProfile; } + MenuItem { action: Cura.Actions.updateProfile; } + MenuItem { action: Cura.Actions.resetProfile; } + MenuItem { action: Cura.Actions.addProfile; } MenuSeparator { } - MenuItem { action: Actions.manageProfiles; } + MenuItem { action: Cura.Actions.manageProfiles; } } Menu @@ -337,7 +335,7 @@ UM.MainWindow //: Settings menu title: catalog.i18nc("@title:menu menubar:toplevel","&Settings"); - MenuItem { action: Actions.preferences; } + MenuItem { action: Cura.Actions.preferences; } } Menu @@ -345,11 +343,11 @@ UM.MainWindow //: Help menu title: catalog.i18nc("@title:menu menubar:toplevel","&Help"); - MenuItem { action: Actions.showEngineLog; } - MenuItem { action: Actions.documentation; } - MenuItem { action: Actions.reportBug; } + MenuItem { action: Cura.Actions.showEngineLog; } + MenuItem { action: Cura.Actions.documentation; } + MenuItem { action: Cura.Actions.reportBug; } MenuSeparator { } - MenuItem { action: Actions.about; } + MenuItem { action: Cura.Actions.about; } } } @@ -439,7 +437,7 @@ UM.MainWindow left: parent.left; //leftMargin: UM.Theme.getSize("loadfile_margin").width } - action: Actions.open; + action: Cura.Actions.open; } Image @@ -527,12 +525,12 @@ UM.MainWindow width: UM.Theme.getSize("sidebar").width; - addMachineAction: Actions.addMachine; - configureMachinesAction: Actions.configureMachines; - addProfileAction: Actions.addProfile; - updateProfileAction: Actions.updateProfile; - resetProfileAction: Actions.resetProfile; - manageProfilesAction: Actions.manageProfiles; + addMachineAction: Cura.Actions.addMachine; + configureMachinesAction: Cura.Actions.configureMachines; + addProfileAction: Cura.Actions.addProfile; + updateProfileAction: Cura.Actions.updateProfile; + resetProfileAction: Cura.Actions.resetProfile; + manageProfilesAction: Cura.Actions.manageProfiles; } } } @@ -573,13 +571,13 @@ UM.MainWindow Connections { - target: Actions.preferences + target: Cura.Actions.preferences onTriggered: preferences.visible = true } Connections { - target: Actions.addProfile + target: Cura.Actions.addProfile onTriggered: { UM.MachineManager.createProfile(); @@ -593,7 +591,7 @@ UM.MainWindow Connections { - target: Actions.configureMachines + target: Cura.Actions.configureMachines onTriggered: { preferences.visible = true; @@ -603,7 +601,7 @@ UM.MainWindow Connections { - target: Actions.manageProfiles + target: Cura.Actions.manageProfiles onTriggered: { preferences.visible = true; @@ -613,7 +611,7 @@ UM.MainWindow Connections { - target: Actions.configureSettingVisibility + target: Cura.Actions.configureSettingVisibility onTriggered: { preferences.visible = true; @@ -636,22 +634,22 @@ UM.MainWindow id: objectContextMenu; property variant objectId: -1; - MenuItem { action: Actions.centerObject; } - MenuItem { action: Actions.deleteObject; } - MenuItem { action: Actions.multiplyObject; } + MenuItem { action: Cura.Actions.centerObject; } + MenuItem { action: Cura.Actions.deleteObject; } + MenuItem { action: Cura.Actions.multiplyObject; } MenuSeparator { } - MenuItem { action: Actions.deleteAll; } - MenuItem { action: Actions.reloadAll; } - MenuItem { action: Actions.resetAllTranslation; } - MenuItem { action: Actions.resetAll; } + MenuItem { action: Cura.Actions.deleteAll; } + MenuItem { action: Cura.Actions.reloadAll; } + MenuItem { action: Cura.Actions.resetAllTranslation; } + MenuItem { action: Cura.Actions.resetAll; } MenuSeparator { } - MenuItem { action: Actions.groupObjects; } - MenuItem { action: Actions.mergeObjects; } - MenuItem { action: Actions.unGroupObjects; } + MenuItem { action: Cura.Actions.groupObjects; } + MenuItem { action: Cura.Actions.mergeObjects; } + MenuItem { action: Cura.Actions.unGroupObjects; } Connections { - target: Actions.deleteObject + target: Cura.Actions.deleteObject onTriggered: { if(objectContextMenu.objectId != 0) @@ -664,7 +662,7 @@ UM.MainWindow Connections { - target: Actions.multiplyObject + target: Cura.Actions.multiplyObject onTriggered: { if(objectContextMenu.objectId != 0) @@ -677,7 +675,7 @@ UM.MainWindow Connections { - target: Actions.centerObject + target: Cura.Actions.centerObject onTriggered: { if(objectContextMenu.objectId != 0) @@ -692,14 +690,14 @@ UM.MainWindow Menu { id: contextMenu; - MenuItem { action: Actions.deleteAll; } - MenuItem { action: Actions.reloadAll; } - MenuItem { action: Actions.resetAllTranslation; } - MenuItem { action: Actions.resetAll; } + MenuItem { action: Cura.Actions.deleteAll; } + MenuItem { action: Cura.Actions.reloadAll; } + MenuItem { action: Cura.Actions.resetAllTranslation; } + MenuItem { action: Cura.Actions.resetAll; } MenuSeparator { } - MenuItem { action: Actions.groupObjects; } - MenuItem { action: Actions.mergeObjects; } - MenuItem { action: Actions.unGroupObjects; } + MenuItem { action: Cura.Actions.groupObjects; } + MenuItem { action: Cura.Actions.mergeObjects; } + MenuItem { action: Cura.Actions.unGroupObjects; } } Connections @@ -720,13 +718,13 @@ UM.MainWindow Connections { - target: Actions.quit + target: Cura.Actions.quit onTriggered: base.visible = false; } Connections { - target: Actions.toggleFullScreen + target: Cura.Actions.toggleFullScreen onTriggered: base.toggleFullscreen(); } @@ -756,7 +754,7 @@ UM.MainWindow Connections { - target: Actions.open + target: Cura.Actions.open onTriggered: openDialog.open() } @@ -767,7 +765,7 @@ UM.MainWindow Connections { - target: Actions.showEngineLog + target: Cura.Actions.showEngineLog onTriggered: engineLog.visible = true; } @@ -778,7 +776,7 @@ UM.MainWindow Connections { - target: Actions.addMachine + target: Cura.Actions.addMachine onTriggered: addMachineDialog.visible = true; } @@ -789,7 +787,7 @@ UM.MainWindow Connections { - target: Actions.about + target: Cura.Actions.about onTriggered: aboutDialog.visible = true; } diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index f4e3dbe5ae..f4c35f876e 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -7,8 +7,7 @@ import QtQuick.Controls.Styles 1.1 import QtQuick.Layouts 1.1 import UM 1.1 as UM - -import ".." +import Cura 1.0 as Cura Button { id: base; @@ -45,7 +44,7 @@ Button { iconSource: UM.Theme.getIcon("settings"); onClicked: { - Actions.configureSettingVisibility.trigger(definition) + Cura.Actions.configureSettingVisibility.trigger(definition) } } diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 560e7b0803..48380e9a95 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -9,8 +9,6 @@ import QtQuick.Layouts 1.1 import UM 1.2 as UM import Cura 1.0 as Cura -import ".." - ScrollView { id: base; @@ -134,7 +132,7 @@ ScrollView //: Settings context menu action text: catalog.i18nc("@action:menu", "Configure setting visiblity..."); - onTriggered: Actions.configureSettingVisibility.trigger(contextMenu); + onTriggered: Cura.Actions.configureSettingVisibility.trigger(contextMenu); } } } diff --git a/resources/qml/qmldir b/resources/qml/qmldir deleted file mode 100644 index 096561aca5..0000000000 --- a/resources/qml/qmldir +++ /dev/null @@ -1,3 +0,0 @@ -module Cura - -singleton Actions 1.0 Actions.qml From 3953da7a509886f002e305b8f62587504af5a37d Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Tue, 31 May 2016 18:13:47 +0200 Subject: [PATCH 331/705] JSON fix: support roof speed was visible when roof enabled but support not (CURA-1498) --- 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 6dca68a6c9..ce7c17c41c 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1116,7 +1116,7 @@ "minimum_value": "0.1", "maximum_value": "299792458000", "maximum_value_warning": "150", - "enabled": "support_roof_enable", + "enabled": "support_roof_enable and support_enable", "value": "speed_support / 1.5", "global_only": true } From 38c9d9e4a12e65ccead5f784feaf9abfd7dab2b0 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 1 Jun 2016 10:47:04 +0200 Subject: [PATCH 332/705] Fix highlighting the currently active (printer|quality|material) on their management pages CURA-1278 --- resources/qml/MachinesPage.qml | 10 ++++++++++ resources/qml/Preferences/MaterialsPage.qml | 10 ++++++++++ resources/qml/Preferences/ProfilesPage.qml | 10 ++++++++++ 3 files changed, 30 insertions(+) diff --git a/resources/qml/MachinesPage.qml b/resources/qml/MachinesPage.qml index 00ebcfc0af..faef019deb 100644 --- a/resources/qml/MachinesPage.qml +++ b/resources/qml/MachinesPage.qml @@ -17,6 +17,16 @@ UM.ManagementPage filter: {"type": "machine"} } + activeId: Cura.MachineManager.activeMachineId + activeIndex: { + for(var i = 0; i < model.rowCount(); i++) { + if (model.getItem(i).id == Cura.MachineManager.activeMachineId) { + return i; + } + } + return -1; + } + onAddObject: Printer.requestAddPrinter() onRemoveObject: confirmDialog.open(); onRenameObject: renameDialog.open(); diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index 03ede39a5c..0b606ced77 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -15,6 +15,16 @@ UM.ManagementPage title: catalog.i18nc("@title:tab", "Materials"); model: UM.InstanceContainersModel { filter: { "type": "material", "definition": Cura.MachineManager.activeDefinitionId } } + + activeId: Cura.MachineManager.activeMaterialId + activeIndex: { + for(var i = 0; i < model.rowCount(); i++) { + if (model.getItem(i).id == Cura.MachineManager.activeMaterialId) { + return i; + } + } + return -1; + } /* onAddObject: { var selectedMaterial = UM.MaterialManager.createProfile(); base.selectMaterial(selectedMaterial); } onRemoveObject: confirmDialog.open(); diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 10acc8beef..9561bba521 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -17,6 +17,16 @@ UM.ManagementPage model: UM.InstanceContainersModel { filter: { "type": "quality" } } + activeId: Cura.MachineManager.activeQualityId + activeIndex: { + for(var i = 0; i < model.rowCount(); i++) { + if (model.getItem(i).id == Cura.MachineManager.activeQualityId) { + return i; + } + } + return -1; + } + onActivateObject: Cura.MachineManager.setActiveQuality(currentItem.id) onAddObject: { var selectedProfile; From 2a288cd7a2107f43239143623fe4184264eb3b9b Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 1 Jun 2016 11:51:42 +0200 Subject: [PATCH 333/705] Fix typo causing a minor error when opening MaterialsPage.qml CURA-339 --- resources/qml/Preferences/MaterialsPage.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index 0b606ced77..ed35a32fdf 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -195,7 +195,7 @@ UM.ManagementPage onCurrentItemChanged: { - if(!currentItem == null) + if(currentItem == null) { return } From a08e71774d2386d57e52aaa8e353bda0a8202d77 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 31 May 2016 10:59:32 +0200 Subject: [PATCH 334/705] Make ExtruderManagerModel no longer a PyQt model It is still a model according to the MVC paradigm but not according to Qt. To be consistent with the rest, don't call it a model any more. Contributes to issues CURA-1278 and CURA-351. --- cura/{ExtruderManagerModel.py => ExtruderManager.py} | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) rename cura/{ExtruderManagerModel.py => ExtruderManager.py} (94%) diff --git a/cura/ExtruderManagerModel.py b/cura/ExtruderManager.py similarity index 94% rename from cura/ExtruderManagerModel.py rename to cura/ExtruderManager.py index 7f0baa7aa8..c99ac4be00 100644 --- a/cura/ExtruderManagerModel.py +++ b/cura/ExtruderManager.py @@ -1,7 +1,6 @@ # Copyright (c) 2016 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. -from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal import re from UM.Application import Application #To get the global container stack to find the current machine. @@ -15,13 +14,9 @@ from UM.Settings.ContainerRegistry import ContainerRegistry #Finding containers # This finds the extruders that are available for the currently active machine # and makes sure that whenever the machine is swapped, this list is kept up to # date. It also contains and updates the setting stacks for the extruders. -class ExtruderManagerModel(QObject): +class ExtruderManager: ## Registers listeners and such to listen to changes to the extruders. - # - # \param parent Parent QObject of this model. - def __init__(self, parent = None): - super().__init__(parent) - + def __init__(self): self._extruderDefinitions = [] #Extruder definitions for the current machine. self._nozzles = {} #Nozzle instances for each extruder. self._extruderTrains = [] #Container stacks for each of the extruder trains. From 6164112bf2d8f78c30b6fe39cda29b5223686da4 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 1 Jun 2016 13:35:09 +0200 Subject: [PATCH 335/705] Setting textfield now updates correctly, even when mouse is hovering another text field. CURA-1278 --- resources/qml/Settings/SettingTextField.qml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/resources/qml/Settings/SettingTextField.qml b/resources/qml/Settings/SettingTextField.qml index 9972f83aa1..2a1fb96330 100644 --- a/resources/qml/Settings/SettingTextField.qml +++ b/resources/qml/Settings/SettingTextField.qml @@ -16,8 +16,6 @@ SettingItem anchors.fill: parent - property alias hovered: mouseArea.containsMouse; - border.width: UM.Theme.getSize("default_lining").width border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : hovered ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border") @@ -74,7 +72,7 @@ SettingItem { id: mouseArea anchors.fill: parent; - hoverEnabled: true; + //hoverEnabled: true; cursorShape: Qt.IBeamCursor } From 48eb8de9a10b870aa3d0f26386a67c9d8f5e47c1 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 1 Jun 2016 13:35:30 +0200 Subject: [PATCH 336/705] Add basic extruder implementation This implementation can load an extruder from a definition container, but doesn't expose anything (yet). It is intended to function in much the same way as a definition model, so it must expose its relevant properties to QML. Contributes to issues CURA-1278 and CURA-351. --- cura/Extruder.py | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 cura/Extruder.py diff --git a/cura/Extruder.py b/cura/Extruder.py new file mode 100644 index 0000000000..f9f957dfe3 --- /dev/null +++ b/cura/Extruder.py @@ -0,0 +1,85 @@ +# Copyright (c) 2016 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. + +import re #To parse container registry names to increment the duplicates-resolving number. + +import UM.Settings.ContainerRegistry #To search for nozzles, materials, etc. +import UM.Settings.ContainerStack #To create a container stack for this extruder. + +class Extruder: + ## Creates a new extruder from the specified definition container. + # + # \param definition The definition container defining this extruder. + def __init__(self, definition): + self._definition = definition + + container_registry = UM.Settings.ContainerRegistry.getInstance() + + #Find the nozzles that fit on this extruder. + self._nozzles = container_registry.findInstanceContainers(type = "nozzle", definitions = "*," + definition.getId() + ",*") + self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = "*," + definition.getId()) + self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = definition.getId() + ",*") + self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = definition.getId()) + + #Create a container stack for this extruder. + self._container_stack = UM.Settings.ContainerStack(self._uniqueName(self._definition.getId())) + self._container_stack.addMetaDataEntry("type", "extruder_train") + self._container_stack.addContainer(self._definition) + + #Find the nozzle to use for this extruder. + self._nozzle = container_registry.getEmptyInstanceContainer() + if len(self._nozzles) >= 1: #First add any extruder. Later, overwrite with preference if the preference is valid. + self._nozzle = self._nozzles[0] + preferred_nozzle_id = self._definition.getMetaDataEntry("preferred_nozzle") + if preferred_nozzle_id: + for nozzle in self._nozzles: + if nozzle.getId() == preferred_nozzle_id: + self._nozzle = nozzle + break + self._container_stack.addContainer(self._nozzle) + + #Find a material to use for this nozzle. + self._material = container_registry.getEmptyInstanceContainer() + all_materials = container_registry.findInstanceContainers(type = "material") + if len(all_materials) >= 1: + self._material = all_materials[0] + preferred_material_id = self._definition.getMetaDataEntry("preferred_material") + if preferred_material_id: + preferred_material = container_registry.findInstanceContainers(type = "material", id = preferred_material_id.lower()) + if len(preferred_material) >= 1: + self._material = preferred_material[0] + self._container_stack.addContainer(self._material) + + #Find a quality to use for this extruder. + self._quality = container_registry.getEmptyInstanceContainer() + all_qualities = container_registry.findInstanceContainers(type = "quality") + if len(all_qualities) >= 1: + self._quality = all_qualities[0] + preferred_quality_id = self._definition.getMetaDataEntry("preferred_quality") + if preferred_quality_id: + preferred_quality = container_registry.findInstanceContainers(type = "quality", id = preferred_quality_id.lower()) + if len(preferred_quality) >= 1: + self._quality = preferred_quality[0] + self._container_stack.addContainer(self._quality) + + ## Finds a unique name for an extruder stack. + # + # \param extruder An extruder definition to design a name for. + # \return A name for an extruder stack that is unique and reasonably + # human-readable. + def _uniqueName(self, extruder): + container_registry = UM.Settings.ContainerRegistry.getInstance() + + name = extruder.getName().strip() + num_check = re.compile("(.*?)\s*#\d$").match(name) + if num_check: #There is a number in the name. + name = num_check.group(1) #Filter out the number. + if name == "": #Wait, that deleted everything! + name = "Extruder" + unique_name = name + + i = 1 + while container_registry.findContainers(id = unique_name) or container_registry.findContainers(name = unique_name): #A container already has this name. + i += 1 #Try next numbering. + unique_name = "%s #%d" % (name, i) #Fill name like this: "Extruder #2". + return unique_name \ No newline at end of file From 377fed206c0d581c74b72d534fe8bf988ca3b5ef Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 1 Jun 2016 13:41:25 +0200 Subject: [PATCH 337/705] Remove extruder creation logic from manager This logic is now in cura/Extruder.py. Contributes to issues CURA-1278 and CURA-351. --- cura/ExtruderManager.py | 68 ++++++----------------------------------- 1 file changed, 9 insertions(+), 59 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index c99ac4be00..924c6a1e21 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -3,6 +3,7 @@ import re +from cura.Extruder import Extruder #The individual extruders managed by this manager. from UM.Application import Application #To get the global container stack to find the current machine. from UM.Logger import Logger from UM.Settings.ContainerStack import ContainerStack #To create container stacks for each extruder. @@ -26,72 +27,21 @@ class ExtruderManager: ## (Re)loads all extruders of the currently active machine. # # This looks at the global container stack to see which machine is active. - # Then it loads the extruder definitions for that machine and the variants - # of those definitions. Then it puts the new extruder definitions in the - # appropriate place in the container stacks. + # Then it loads the extruders for that machine and loads each of them in a + # list of extruders. def _reloadExtruders(self): - self._extruderDefinitions = [] - self._nozzles = {} - self._extruderTrains = [] + self._extruders = [] global_container_stack = Application.getInstance().getGlobalContainerStack() if not global_container_stack: #No machine has been added yet. return #Then leave them empty! - #Fill the list of extruder trains. + #Get the extruder definitions belonging to the current machine. machine = global_container_stack.getBottom() extruder_train_ids = machine.getMetaData("machine_extruder_trains") for extruder_train_id in extruder_train_ids: - extruders = ContainerRegistry.getInstance().findDefinitionContainers(id = extruder_train_id) #Should be only 1 definition if IDs are unique, but add the whole list anyway. - if not extruders: #Empty list or error. + extruder_definitions = ContainerRegistry.getInstance().findDefinitionContainers(id = extruder_train_id) #Should be only 1 definition if IDs are unique, but add the whole list anyway. + if not extruder_definitions: #Empty list or error. Logger.log("w", "Machine definition %s refers to an extruder train \"%s\", but no such extruder was found.", machine.getId(), extruder_train_id) continue - self._extruderDefinitions += extruders - - #Fill the nozzles for each of the extruder trains. - for extruder in self._extruderDefinitions: - self._nozzles[extruder.id] = [] - all_nozzles = ContainerRegistry.getInstance().findInstanceContainers(type="nozzle") - for nozzle in all_nozzles: - extruders = nozzle.getMetaDataEntry("definitions").split(",").strip() - for extruder_id in extruders: - self._nozzles[extruder_id] = nozzle - - #Create the extruder train container stacks. - for extruder in self._extruderDefinitions: - self._extruderTrains.append(self._createContainerStack(extruder)) - - ## Creates a container stack for the specified extruder. - # - # This fills in the specified extruder as base definition, then a nozzle - # that fits in that extruder train, then a material that fits through that - # nozzle, then a quality profile that can be used with that material, and - # finally an empty user profile. - # - # \param extruder The extruder to create the container stack for. - # \return A container stack with the specified extruder as base. - def _createContainerStack(self, extruder): - container_stack = ContainerStack(self._uniqueName(extruder)) - #TODO: Fill the container stack. - return container_stack - - ## Finds a unique name for an extruder stack. - # - # \param extruder Extruder to design a name for. - # \return A name for an extruder stack that is unique and reasonably - # human-readable. - def _uniqueName(self, extruder): - container_registry = ContainerRegistry.getInstance() - - name = extruder.getName().strip() - num_check = re.compile("(.*?)\s*#\d$").match(name) - if(num_check): #There is a number in the name. - name = num_check.group(1) #Filter out the number. - if name == "": #Wait, that deleted everything! - name = "Extruder" - unique_name = name - - i = 1 - while(container_registry.findContainers(id = unique_name) or container_registry.findContainers(name = unique_name)): #A container already has this name. - i += 1 #Try next numbering. - unique_name = "%s #%d" % (name, i) #Fill name like this: "Extruder #2". - return unique_name \ No newline at end of file + for extruder_definition in extruder_definitions: + self._extruders.append(Extruder(extruder_definition)) \ No newline at end of file From 60a71fcc332da5f7b20939e7458609b7c2be845c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 1 Jun 2016 14:54:30 +0200 Subject: [PATCH 338/705] Only list extruders in extruder manager Let the extruders themselves take care of which profiles are attached to each. Contributes to issues CURA-1278 and CURA-351. --- cura/ExtruderManager.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 924c6a1e21..d0dea31206 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -18,9 +18,7 @@ from UM.Settings.ContainerRegistry import ContainerRegistry #Finding containers class ExtruderManager: ## Registers listeners and such to listen to changes to the extruders. def __init__(self): - self._extruderDefinitions = [] #Extruder definitions for the current machine. - self._nozzles = {} #Nozzle instances for each extruder. - self._extruderTrains = [] #Container stacks for each of the extruder trains. + self._extruders = [] #Extruders for the current machine. Application.getInstance().getGlobalContainerStack().containersChanged.connect(self._reloadExtruders) #When the current machine changes, we need to reload all extruders belonging to the new machine. From d1566ef637a5c244c0e7a20611f4998a0fd104f3 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 1 Jun 2016 14:55:15 +0200 Subject: [PATCH 339/705] Also reload extruders at init Not a reload really, just a load. Contributes to issues CURA-1278 and CURA-351. --- cura/ExtruderManager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index d0dea31206..4d95a9008d 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -21,6 +21,7 @@ class ExtruderManager: self._extruders = [] #Extruders for the current machine. Application.getInstance().getGlobalContainerStack().containersChanged.connect(self._reloadExtruders) #When the current machine changes, we need to reload all extruders belonging to the new machine. + self._reloadExtruders() ## (Re)loads all extruders of the currently active machine. # From 91fc90a42323ef64258555c36b3e805881713e22 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 1 Jun 2016 15:05:14 +0200 Subject: [PATCH 340/705] Link extruder stack to global container stack Each extruder stack is linked to the same global container stack. Contributes to issues CURA-1278 and CURA-351. --- cura/Extruder.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cura/Extruder.py b/cura/Extruder.py index f9f957dfe3..8fa1b71ab1 100644 --- a/cura/Extruder.py +++ b/cura/Extruder.py @@ -3,6 +3,7 @@ import re #To parse container registry names to increment the duplicates-resolving number. +import UM.Application #To link the stack to the global container stack. import UM.Settings.ContainerRegistry #To search for nozzles, materials, etc. import UM.Settings.ContainerStack #To create a container stack for this extruder. @@ -62,6 +63,8 @@ class Extruder: self._quality = preferred_quality[0] self._container_stack.addContainer(self._quality) + self._container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack()) + ## Finds a unique name for an extruder stack. # # \param extruder An extruder definition to design a name for. From 0e108f0c04b8be53f51ee7ef18ad23946b3d7e5c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 1 Jun 2016 15:12:20 +0200 Subject: [PATCH 341/705] Document filtering nozzles by extruder better Contributes to issues CURA-1278 and CURA-351. --- cura/Extruder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Extruder.py b/cura/Extruder.py index 8fa1b71ab1..5f74bd036f 100644 --- a/cura/Extruder.py +++ b/cura/Extruder.py @@ -17,7 +17,7 @@ class Extruder: container_registry = UM.Settings.ContainerRegistry.getInstance() #Find the nozzles that fit on this extruder. - self._nozzles = container_registry.findInstanceContainers(type = "nozzle", definitions = "*," + definition.getId() + ",*") + self._nozzles = container_registry.findInstanceContainers(type = "nozzle", definitions = "*," + definition.getId() + ",*") #Extruder needs to be delimited by either a comma or the end of string. self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = "*," + definition.getId()) self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = definition.getId() + ",*") self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = definition.getId()) From faf647dca05bb39f988637d56f7e2fbdaf5ad769 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 1 Jun 2016 15:14:03 +0200 Subject: [PATCH 342/705] Git ignore resources/firmware It is also compiled and will only be included by including the cura-binary-data repository. However it is also useful to have this in your testing environment. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 72ba4bf565..f60e268711 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ docs/html *.log resources/i18n/en resources/i18n/x-test +resources/firmware # Editors and IDEs. *kdev* From 49e5b1938a8a367d4d47ca04dc877e065982a940 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 1 Jun 2016 15:45:54 +0200 Subject: [PATCH 343/705] Reduce number of top layer to increase processing speed --- plugins/LayerView/LayerView.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/LayerView/LayerView.py b/plugins/LayerView/LayerView.py index 9f65a8e783..27bb7f022c 100644 --- a/plugins/LayerView/LayerView.py +++ b/plugins/LayerView/LayerView.py @@ -44,7 +44,7 @@ class LayerView(View): self._top_layers_job = None self._activity = False - self._solid_layers = 5 + self._solid_layers = 1 self._top_layer_timer = QTimer() self._top_layer_timer.setInterval(50) From ffa6a0376d44d7189cdaea9ff7fafd2d5eefaf49 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 1 Jun 2016 21:44:56 +0200 Subject: [PATCH 344/705] Fix typo Contributes to CURA-1540, CURA-1278 --- resources/qml/Cura.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index a043567c0f..32e1e79029 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -303,7 +303,7 @@ UM.MainWindow Instantiator { - id: extenions + id: extensions model: UM.ExtensionModel { } Menu @@ -318,7 +318,7 @@ UM.MainWindow MenuItem { text: model.text - onTriggered: extenions.model.subMenuTriggered(name, model.text) + onTriggered: extensions.model.subMenuTriggered(name, model.text) } onObjectAdded: sub_menu.insertItem(index, object) onObjectRemoved: sub_menu.removeItem(object) From c6dd9d2c8c8028b3798080ad0192bfd165707226 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 1 Jun 2016 22:21:12 +0200 Subject: [PATCH 345/705] Fix codestyle and change faux-"hovered" property mechanism hovered_ex was a bool property that was set in onEntered and onExited, and has been replaced with an alias to the mouseArea.containsMouse that necessitated the clutch. CURA-790 --- resources/qml/SidebarSimple.qml | 39 +++++++++++++++----------------- resources/themes/cura/styles.qml | 20 ++++++++-------- 2 files changed, 28 insertions(+), 31 deletions(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index c828b5d3db..c95cb54b1f 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -28,13 +28,13 @@ Item id: infillCellLeft anchors.top: parent.top anchors.left: parent.left - width: base.width/100* 35 - UM.Theme.getSize("default_margin").width + width: base.width / 100 * 35 - UM.Theme.getSize("default_margin").width height: childrenRect.height Label{ id: infillLabel //: Infill selection label - text: catalog.i18nc("@label","Infill:"); + text: catalog.i18nc("@label", "Infill:"); font: UM.Theme.getFont("default"); color: UM.Theme.getColor("text"); anchors.top: parent.top @@ -85,7 +85,7 @@ Item { return UM.Theme.getColor("setting_control_selected") } - else if(mousearea.containsMouse) + else if(infillMouseArea.containsMouse) { return UM.Theme.getColor("setting_control_border_highlight") } @@ -106,7 +106,7 @@ Item } MouseArea { - id: mousearea + id: infillMouseArea anchors.fill: parent hoverEnabled: true onClicked: { @@ -187,28 +187,29 @@ Item anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width anchors.verticalCenter: brimCheckBox.verticalCenter - width: parent.width/100*35 - 3 * UM.Theme.getSize("default_margin").width + width: parent.width / 100 * 35 - 3 * UM.Theme.getSize("default_margin").width //: Bed adhesion label - text: catalog.i18nc("@label:listbox","Bed Adhesion:"); + text: catalog.i18nc("@label:listbox", "Bed Adhesion:"); font: UM.Theme.getFont("default"); color: UM.Theme.getColor("text"); } CheckBox{ id: brimCheckBox - property bool hovered_ex: false + property alias _hovered: brimMouseArea.containsMouse anchors.top: parent.top anchors.left: adhesionHelperLabel.right anchors.leftMargin: UM.Theme.getSize("default_margin").width //: Setting enable skirt adhesion checkbox - text: catalog.i18nc("@option:check","Print Brim"); + text: catalog.i18nc("@option:check", "Print Brim"); style: UM.Theme.styles.checkbox; checked: platformAdhesionType.properties.value == "brim" MouseArea { + id: brimMouseArea anchors.fill: parent hoverEnabled: true onClicked: @@ -217,13 +218,11 @@ Item } onEntered: { - parent.hovered_ex = true base.showTooltip(brimCheckBox, Qt.point(-brimCheckBox.x, 0), catalog.i18nc("@label", "Enable printing a brim. This will add a single-layer-thick flat area around your object which is easy to cut off afterwards.")); } onExited: { - parent.hovered_ex = false base.hideTooltip(); } } @@ -234,9 +233,9 @@ Item anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width anchors.verticalCenter: supportCheckBox.verticalCenter - width: parent.width/100*35 - 3 * UM.Theme.getSize("default_margin").width + width: parent.width / 100 * 35 - 3 * UM.Theme.getSize("default_margin").width //: Support label - text: catalog.i18nc("@label:listbox","Support:"); + text: catalog.i18nc("@label:listbox", "Support:"); font: UM.Theme.getFont("default"); color: UM.Theme.getColor("text"); } @@ -244,7 +243,7 @@ Item CheckBox{ id: supportCheckBox visible: machineExtruderCount.properties.value <= 1 - property bool hovered_ex: false + property alias _hovered: supportMouseArea.containsMouse anchors.top: brimCheckBox.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height @@ -252,11 +251,12 @@ Item anchors.leftMargin: UM.Theme.getSize("default_margin").width //: Setting enable support checkbox - text: catalog.i18nc("@option:check","Print Support Structure"); + text: catalog.i18nc("@option:check", "Print Support Structure"); style: UM.Theme.styles.checkbox; checked: supportEnabled.properties.value == "True" MouseArea { + id: supportMouseArea anchors.fill: parent hoverEnabled: true onClicked: @@ -265,13 +265,11 @@ Item } onEntered: { - parent.hovered_ex = true base.showTooltip(supportCheckBox, Qt.point(-supportCheckBox.x, 0), catalog.i18nc("@label", "Enable printing support structures. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air.")); } onExited: { - parent.hovered_ex = false base.hideTooltip(); } } @@ -286,10 +284,10 @@ Item anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.left: supportHelperLabel.right anchors.leftMargin: UM.Theme.getSize("default_margin").width - width: parent.width/100*45 + width: parent.width / 100 * 45 style: UM.Theme.styles.combobox - property bool hovered_ex: false + property alias _hovered: supportExtruderMouseArea.containsMouse currentIndex: supportEnabled.properties.value == "True" ? parseFloat(supportExtruderNr.properties.value) + 1 : 0 onActivated: { @@ -301,18 +299,17 @@ Item } } MouseArea { + id: supportExtruderMouseArea anchors.fill: parent hoverEnabled: true acceptedButtons: Qt.NoButton onEntered: { - parent.hovered_ex = true base.showTooltip(supportExtruderCombobox, Qt.point(-supportExtruderCombobox.x, 0), catalog.i18nc("@label", "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air.")); } onExited: { - parent.hovered_ex = false base.hideTooltip(); } } @@ -358,7 +355,7 @@ Item anchors.rightMargin: UM.Theme.getSize("default_margin").width wrapMode: Text.WordWrap //: Tips label - text: catalog.i18nc("@label","Need help improving your prints? Read the Ultimaker Troubleshooting Guides").arg("https://ultimaker.com/en/troubleshooting"); + text: catalog.i18nc("@label", "Need help improving your prints? Read the Ultimaker Troubleshooting Guides").arg("https://ultimaker.com/en/troubleshooting"); font: UM.Theme.getFont("default"); color: UM.Theme.getColor("text"); linkColor: UM.Theme.getColor("text_link") diff --git a/resources/themes/cura/styles.qml b/resources/themes/cura/styles.qml index b2c2329169..1428c3d40a 100644 --- a/resources/themes/cura/styles.qml +++ b/resources/themes/cura/styles.qml @@ -283,14 +283,14 @@ QtObject { property Component combobox: Component { ComboBoxStyle { background: Rectangle { - implicitHeight: UM.Theme.getSize("setting_control").height; - implicitWidth: UM.Theme.getSize("setting_control").width; + implicitHeight: Theme.getSize("setting_control").height; + implicitWidth: Theme.getSize("setting_control").width; - color: (control.hovered || control.hovered_ex) ? Theme.getColor("setting_control_highlight") : Theme.getColor("setting_control"); + color: (control.hovered || control._hovered) ? Theme.getColor("setting_control_highlight") : Theme.getColor("setting_control"); Behavior on color { ColorAnimation { duration: 50; } } border.width: Theme.getSize("default_lining").width; - border.color: (control.hovered || control.hovered_ex) ? Theme.getColor("setting_control_border_highlight") : Theme.getColor("setting_control_border"); + border.color: (control.hovered || control._hovered) ? Theme.getColor("setting_control_border_highlight") : Theme.getColor("setting_control_border"); } label: Item { Label { @@ -301,7 +301,7 @@ QtObject { anchors.verticalCenter: parent.verticalCenter; text: control.currentText; - font: UM.Theme.getFont("default"); + font: Theme.getFont("default"); color: !enabled ? Theme.getColor("setting_control_disabled_text") : Theme.getColor("setting_control_text"); elide: Text.ElideRight; @@ -314,9 +314,9 @@ QtObject { anchors.rightMargin: Theme.getSize("default_lining").width * 2; anchors.verticalCenter: parent.verticalCenter; - source: UM.Theme.getIcon("arrow_bottom") - width: UM.Theme.getSize("standard_arrow").width - height: UM.Theme.getSize("standard_arrow").height + source: Theme.getIcon("arrow_bottom") + width: Theme.getSize("standard_arrow").width + height: Theme.getSize("standard_arrow").height sourceSize.width: width + 5 sourceSize.height: width + 5 @@ -333,13 +333,13 @@ QtObject { implicitWidth: Theme.getSize("checkbox").width; implicitHeight: Theme.getSize("checkbox").height; - color: (control.hovered || control.hovered_ex) ? Theme.getColor("checkbox_hover") : Theme.getColor("checkbox"); + color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_hover") : Theme.getColor("checkbox"); Behavior on color { ColorAnimation { duration: 50; } } radius: control.exclusiveGroup ? Theme.getSize("checkbox").width / 2 : 0 border.width: Theme.getSize("default_lining").width; - border.color: (control.hovered || control.hovered_ex) ? Theme.getColor("checkbox_border_hover") : Theme.getColor("checkbox_border"); + border.color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_border_hover") : Theme.getColor("checkbox_border"); UM.RecolorImage { anchors.verticalCenter: parent.verticalCenter From 7d65475bf99d88b6ed8d66154b733147b4112669 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 1 Jun 2016 23:59:09 +0200 Subject: [PATCH 346/705] Fix mouseover highlight of checkbox settings CURA-1278 --- resources/qml/Settings/SettingCheckBox.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/Settings/SettingCheckBox.qml b/resources/qml/Settings/SettingCheckBox.qml index 6f0314160e..1d66e509d0 100644 --- a/resources/qml/Settings/SettingCheckBox.qml +++ b/resources/qml/Settings/SettingCheckBox.qml @@ -16,6 +16,7 @@ SettingItem { id: control anchors.fill: parent + hoverEnabled: true property bool checked: { From 907de8b586192f51909a7233b85ffeea80e7b51b Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 2 Jun 2016 00:01:08 +0200 Subject: [PATCH 347/705] Improve performance of advanced sidebar Prevent a delegate being loaded when the item is "filtered out" by the model. CURA-1278 --- resources/qml/Settings/SettingView.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 48380e9a95..9dabbaee98 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -50,6 +50,7 @@ ScrollView //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes, //causing nasty issues when selecting differnt options. So disable asynchronous loading of enum type completely. asynchronous: model.type != "enum" + active: model.type != undefined source: { From ed3d01ed7b53d6a83e3ce274fe35455214382504 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 2 Jun 2016 06:38:57 +0200 Subject: [PATCH 348/705] Add icon to Machine category to squelch some warnings CURA-1278 --- resources/definitions/fdmprinter.def.json | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index ce7c17c41c..48952c2c99 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -24,6 +24,7 @@ "label": "Machine", "type": "category", "description": "Machine specific settings", + "icon": "category_machine", "children": { "machine_show_variants": From d5aa75f2cf7beba2f6f2ba5243dc7d7cc8d18c46 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 31 May 2016 01:47:44 +0200 Subject: [PATCH 349/705] Remove obsolete file --- .../Settings/SettingsConfigurationPage.qml | 119 ------------------ 1 file changed, 119 deletions(-) delete mode 100644 resources/qml/Settings/SettingsConfigurationPage.qml diff --git a/resources/qml/Settings/SettingsConfigurationPage.qml b/resources/qml/Settings/SettingsConfigurationPage.qml deleted file mode 100644 index a2889d410a..0000000000 --- a/resources/qml/Settings/SettingsConfigurationPage.qml +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) 2015 Ultimaker B.V. -// Uranium is released under the terms of the AGPLv3 or higher. - -import QtQuick 2.1 -import QtQuick.Controls 1.1 -import QtQuick.Layouts 1.1 -import QtQuick.Dialogs 1.1 -import QtQuick.Controls.Styles 1.1 -import QtQml 2.2 - -import UM 1.1 as UM - -import "../Preferences" - -PreferencesPage -{ - //: Machine configuration page title. - title: catalog.i18nc("@title:tab","Machine"); - id: base - - contents: ColumnLayout - { - z: base.z - anchors.fill: parent; - UM.I18nCatalog { id: catalog; name:"uranium"} - RowLayout - { - //: Active machine combo box label - Label { text: catalog.i18nc("@label:listbox","Active Machine:"); } - ComboBox - { - id: machineCombo; - Layout.fillWidth: true; - model: UM.Models.machinesModel; - textRole: "name"; - onActivated: - { - if(index != -1) - UM.Models.machinesModel.setActive(index); - } - - Connections - { - id: machineChange - target: UM.Application - onMachineChanged: machineCombo.currentIndex = machineCombo.find(UM.Application.machineName); - } - - Component.onCompleted: machineCombo.currentIndex = machineCombo.find(UM.Application.machineName); - } - //: Remove active machine button - Button { text: catalog.i18nc("@action:button","Remove"); onClicked: confirmRemoveDialog.open(); } - } - ScrollView - { - id: settingsScrollView - Layout.fillWidth: true; - Layout.fillHeight: true; - - ListView - { - id: settingsListView - delegate: settingDelegate - model: UM.Models.settingsModel - x: 0 - - section.property: "category" - section.delegate: Label { text: section } - } - } - } - - Component - { - id: settingDelegate - CheckBox - { - z:0 - id: settingCheckBox - text: model.name; - x: depth * 25 - checked: model.visibility - onClicked: ListView.view.model.setVisibility(model.key, checked) - //enabled: !model.disabled - - onHoveredChanged: - { - if(hovered) - { - var xPos = parent.x + settingCheckBox.width; - var yPos = parent.y; - toolTip.show(model.description, 1000, 200, undefined, undefined) //tooltip-text, hover-delay in msec, animation-length in msec, position X, position Y (both y en x == undefined: gives the tooltip a standard placement in the right corner) - } else - { - toolTip.hide(0, 0)//hover-delay in msec, animation-length in msec - } - } - } - } - - PreferencesToolTip - { - id: toolTip; - } - - MessageDialog - { - id: confirmRemoveDialog; - - icon: StandardIcon.Question; - //: Remove machine confirmation dialog title - title: catalog.i18nc("@title:window","Confirm Machine Deletion"); - //: Remove machine confirmation dialog text - text: catalog.i18nc("@label","Are you sure you wish to remove the machine?"); - standardButtons: StandardButton.Yes | StandardButton.No; - - onYes: UM.Models.machinesModel.removeMachine(machineCombo.currentIndex); - } -} From 803dcdcec703c69896dafc5263476c00c1ee9643 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 31 May 2016 01:48:21 +0200 Subject: [PATCH 350/705] Stop the Item's hover timer when showing a different tooltip --- resources/qml/Settings/SettingItem.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index c1666a8157..4c14ee4039 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -136,7 +136,7 @@ Item { propertyProvider.removeFromContainer(0) } - onEntered: base.showTooltip(catalog.i18nc("@label", "This setting has a value that is different from the profile.\n\nClick to restore the value of the profile.")) + onEntered: { hoverTimer.stop(); base.showTooltip(catalog.i18nc("@label", "This setting has a value that is different from the profile.\n\nClick to restore the value of the profile.")) } onExited: base.showTooltip(definition.description); } @@ -163,7 +163,7 @@ Item { iconSource: UM.Theme.getIcon("notice"); - onEntered: base.showTooltip(catalog.i18nc("@label", "This setting is normally calculated, but it currently has an absolute value set.\n\nClick to restore the calculated value.")) + onEntered: { hoverTimer.stop(); base.showTooltip(catalog.i18nc("@label", "This setting is normally calculated, but it currently has an absolute value set.\n\nClick to restore the calculated value.")) } onExited: base.showTooltip(definition.description); } From e0fab7aa11532b9243a42d8b7c1f9eb0093c9591 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 2 Jun 2016 08:03:24 +0200 Subject: [PATCH 351/705] Add some logging and documentation to XmlMaterialProfile Contributes to CURA-339 --- plugins/XmlMaterialProfile/XmlMaterialProfile.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index d73beec193..9cfca1c535 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -45,6 +45,8 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): self.addMetaDataEntry("material", material.text) self.addMetaDataEntry("color_name", color.text) + continue + self.addMetaDataEntry(tag_name, entry.text) property_values = {} @@ -78,6 +80,8 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): if key in self.__material_property_setting_map: self.setProperty(self.__material_property_setting_map[key], "value", entry.text, self._definition) global_setting_values[self.__material_property_setting_map[key]] = entry.text + else: + Logger.log("d", "Unsupported material setting %s", key) machines = data.iterfind("./um:settings/um:machine", self.__namespaces) for machine in machines: @@ -87,6 +91,8 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): key = entry.get("key") if key in self.__material_property_setting_map: machine_setting_values[self.__material_property_setting_map[key]] = entry.text + else: + Logger.log("d", "Unsupported material setting %s", key) identifiers = machine.iterfind("./um:machine_identifier", self.__namespaces) for identifier in identifiers: @@ -116,12 +122,15 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): UM.Settings.ContainerRegistry.getInstance().addContainer(new_material) + + # Map XML file setting names to internal names __material_property_setting_map = { "print temperature": "material_print_temperature", "heated bed temperature": "material_bed_temperature", "standby temperature": "material_standby_temperature", } + # Map XML file product names to internal ids __product_id_map = { "Ultimaker2": "ultimaker2", "Ultimaker2+": "ultimaker2_plus", From f491405eb19f6504969a4f031aa630c5ba8b2526 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 2 Jun 2016 08:04:06 +0200 Subject: [PATCH 352/705] Use a copy of the metadata for Xml materials Contributes to CURA-339 --- plugins/XmlMaterialProfile/XmlMaterialProfile.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 9cfca1c535..bdffc3d60f 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -106,16 +106,18 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): Logger.log("w", "No definition found for machine ID %s", machine_id) continue + definition = definitions[0] + new_material = XmlMaterialProfile(self.id + "_" + machine_id) new_material.setName(self.getName()) - new_material.setMetaData(self.getMetaData()) - new_material.setDefinition(definitions[0]) + new_material.setMetaData(copy.deepcopy(self.getMetaData())) + new_material.setDefinition(definition) for key, value in global_setting_values.items(): - new_material.setProperty(key, "value", value, definitions[0]) + new_material.setProperty(key, "value", value, definition) for key, value in machine_setting_values.items(): - new_material.setProperty(key, "value", value, definitions[0]) + new_material.setProperty(key, "value", value, definition) new_material._dirty = False From 90ac1c1380cb904ee07b33317954fdf65aa0d2d2 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 2 Jun 2016 08:04:43 +0200 Subject: [PATCH 353/705] Add support for hotend-specfic overrides to XmlMaterialProfile Contributes to CURA-339 --- .../XmlMaterialProfile/XmlMaterialProfile.py | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index bdffc3d60f..c97dbe85ed 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -123,6 +123,44 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): UM.Settings.ContainerRegistry.getInstance().addContainer(new_material) + hotends = machine.iterfind("./um:hotend", self.__namespaces) + for hotend in hotends: + hotend_id = hotend.get("id") + if hotend_id is None: + continue + + variant_containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = hotend_id) + if not variant_containers: + # It is not really properly defined what "ID" is so also search for variants by name. + variant_containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(definition = definition.id, name = hotend_id) + + if not variant_containers: + Logger.log("d", "No variants found with ID or name %s for machine %s", hotend_id, definition.id) + continue + + new_hotend_material = XmlMaterialProfile(self.id + "_" + machine_id + "_" + hotend_id.replace(" ", "_")) + new_hotend_material.setName(self.getName()) + new_hotend_material.setMetaData(copy.deepcopy(self.getMetaData())) + new_hotend_material.setDefinition(definition) + + new_hotend_material.addMetaDataEntry("variant", variant_containers[0].id) + + for key, value in global_setting_values.items(): + new_hotend_material.setProperty(key, "value", value, definition) + + for key, value in machine_setting_values.items(): + new_hotend_material.setProperty(key, "value", value, definition) + + settings = hotend.iterfind("./um:setting", self.__namespaces) + for entry in settings: + key = entry.get("key") + if key in self.__material_property_setting_map: + new_hotend_material.setProperty(self.__material_property_setting_map[key], "value", entry.text, definition) + else: + Logger.log("d", "Unsupported material setting %s", key) + + new_hotend_material._dirty = False + UM.Settings.ContainerRegistry.getInstance().addContainer(new_hotend_material) # Map XML file setting names to internal names From eaea940aa2a9a4cbccdc23459088fb12064bdaf0 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 2 Jun 2016 08:05:11 +0200 Subject: [PATCH 354/705] Add support for some additional properties to XmlMaterialProfile Contributes to CURA-339 --- plugins/XmlMaterialProfile/XmlMaterialProfile.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index c97dbe85ed..89c7d76e9f 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -168,6 +168,9 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): "print temperature": "material_print_temperature", "heated bed temperature": "material_bed_temperature", "standby temperature": "material_standby_temperature", + "print cooling": "cool_fan_speed", + "retraction amount": "retraction_amount", + "retraction speed": "retraction_speed", } # Map XML file product names to internal ids From 123af4e3e46e0f5ca0c5e6e801a27008b0dd956a Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 2 Jun 2016 08:07:04 +0200 Subject: [PATCH 355/705] Use metadata to determine what materials/qualities to use when adding a machine Contributes to CURA-1612 --- cura/MachineManagerModel.py | 97 ++++++++++++++++++++++++------------- 1 file changed, 64 insertions(+), 33 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index deef72529b..83b8e87859 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -1,11 +1,13 @@ +import re + from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal from UM.Application import Application from UM.Preferences import Preferences +from UM.Logger import Logger import UM.Settings -import re class MachineManagerModel(QObject): def __init__(self, parent = None): @@ -74,43 +76,48 @@ class MachineManagerModel(QObject): empty_container = UM.Settings.ContainerRegistry.getInstance().getEmptyInstanceContainer() - variants = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = definition.id) - if variants: - new_global_stack.addMetaDataEntry("has_variants", True) - - preferred_variant_id = definitions[0].getMetaDataEntry("preferred_variant") variant_instance_container = empty_container - if preferred_variant_id: - preferred_variant_id = preferred_variant_id.lower() - container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = preferred_variant_id) - if container: - variant_instance_container = container[0] + if definition.getMetaDataEntry("has_variants"): + variant_instance_container = self._getPreferredContainer(definition, "preferred_variant", empty_container) - if variants and variant_instance_container == empty_container: - variant_instance_container = variants[0] + if variant_instance_container == empty_container: + variants = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = definition.id) + if variants: + variant_instance_container = variants[0] - materials = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "material", definition = definition.id) - if materials: - new_global_stack.addMetaDataEntry("has_materials", True) + if variant_instance_container == empty_container: + Logger.log("w", "Machine %s defines it has variants but no variants found", definition.id) - preferred_material_id = definitions[0].getMetaDataEntry("preferred_material") material_instance_container = empty_container - if preferred_material_id: - preferred_material_id = preferred_material_id.lower() - container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = preferred_material_id) - if container: - material_instance_container = container[0] + if definition.getMetaDataEntry("has_materials"): + material_instance_container = self._getPreferredContainer(definition, "preferred_material", empty_container) - if materials and material_instance_container == empty_container: - material_instance_container = materials[0] + if material_instance_container == empty_container: + materials = None + if definition.getMetaDataEntry("has_machine_materials"): + if variant_instance_container != empty_container: + materials = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "material", definition = definition.id, variant = variant_instance_container.id) + else: + materials = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "material", definition = definition.id) + else: + materials = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "material", definition = "fdmprinter") - preferred_quality_id = definitions[0].getMetaDataEntry("preferred_quality") - quality_instance_container = empty_container - if preferred_quality_id: - preferred_quality_id = preferred_quality_id.lower() - container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = preferred_quality_id) - if container: - quality_instance_container = container[0] + if materials: + material_instance_container = materials[0] + + quality_instance_container = self._getPreferredContainer(definition, "preferred_quality", empty_container) + + if quality_instance_container == empty_container: + if definition.getMetaDataEntry("has_machine_quality"): + if material_instance_container: + qualities = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "quality", definition = definition.id, material = material_instance_container.id) + else: + qualities = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "quality", definition = definition.id) + else: + qualities = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "quality", definition = "fdmprinter") + + if qualities: + quality_instance_container = qualities[0] current_settings_instance_container = UM.Settings.InstanceContainer(name + "_current_settings") current_settings_instance_container.addMetaDataEntry("machine", name) @@ -277,16 +284,40 @@ class MachineManagerModel(QObject): @pyqtProperty(bool, notify = globalContainerChanged) def hasMaterials(self): if self._global_container_stack: - return self._global_container_stack.getMetaDataEntry("has_materials", False) + return bool(self._global_container_stack.getMetaDataEntry("has_materials", False)) return False @pyqtProperty(bool, notify = globalContainerChanged) def hasVariants(self): if self._global_container_stack: - return self._global_container_stack.getMetaDataEntry("has_variants", False) + return bool(self._global_container_stack.getMetaDataEntry("has_variants", False)) return False + @pyqtProperty(bool, notify = globalContainerChanged) + def filterMaterialsByMachine(self): + if self._global_container_stack: + return bool(self._global_container_stack.getMetaDataEntry("has_machine_materials", False)) + + return False + + @pyqtProperty(bool, notify = globalContainerChanged) + def filterQualityByMachine(self): + if self._global_container_stack: + return bool(self._global_container_stack.getMetaDataEntry("has_machine_quality", False)) + + return False + + def _getPreferredContainer(self, definition, property_name, default_container): + preferred_id = definition.getMetaDataEntry(property_name) + if preferred_id: + preferred_variant_id = preferred_variant_id.lower() + container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = preferred_variant_id) + if container: + return container[0] + + return default_container + def createMachineManagerModel(engine, script_engine): return MachineManagerModel() From ceb21ce89b6f7e8cbc89fcc17a4546f57f72f3ed Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 2 Jun 2016 08:07:51 +0200 Subject: [PATCH 356/705] Filter material/quality by machine only when we should filter Contributes to CURA-1612 --- resources/qml/ProfileSetup.qml | 18 +++++++++++++++++- resources/qml/SidebarHeader.qml | 18 +++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/resources/qml/ProfileSetup.qml b/resources/qml/ProfileSetup.qml index 95aed3685c..3175a4e2b3 100644 --- a/resources/qml/ProfileSetup.qml +++ b/resources/qml/ProfileSetup.qml @@ -59,7 +59,23 @@ Item{ id: profileSelectionInstantiator model: UM.InstanceContainersModel { - filter: {"type": "quality"} + filter: + { + var result = { "type": "quality" }; + if(Cura.MachineManager.filterQualityByMachine) + { + result.definition = Cura.MachineManager.activeDefinitionId; + if(Cura.MachineManager.hasMaterials) + { + result.material = Cura.MachineManager.activeMaterialId; + } + } + else + { + result.definition = "fdmprinter" + } + return result + } } property int separatorIndex: -1 diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 282fa8af25..4b48584174 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -266,7 +266,23 @@ Item id: materialSelectionInstantiator model: UM.InstanceContainersModel { - filter: { "type": "material", "definition": Cura.MachineManager.activeDefinitionId } + filter: + { + var result = { "type": "material" } + if(Cura.MachineManager.filterMaterialsByMachine) + { +// result.definition = Cura.MachineManager.activeDefinitionId + if(Cura.MachineManager.hasVariants) + { + result.variant = Cura.MachineManager.activeVariantId + } + } + else + { + result.definition = "fdmprinter" + } + return result + } } MenuItem { From 2b91e3639ed6e28985ee3b3f82345f0be2c57808 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 2 Jun 2016 08:08:21 +0200 Subject: [PATCH 357/705] Add basic ABS and CPE material profiles Contributes to CURA-1612 --- .../materials/generic_abs.xml.fdm_material | 34 +++++++++++++++++++ .../materials/generic_cpe.xml.fdm_material | 34 +++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 resources/materials/generic_abs.xml.fdm_material create mode 100644 resources/materials/generic_cpe.xml.fdm_material diff --git a/resources/materials/generic_abs.xml.fdm_material b/resources/materials/generic_abs.xml.fdm_material new file mode 100644 index 0000000000..654b06d221 --- /dev/null +++ b/resources/materials/generic_abs.xml.fdm_material @@ -0,0 +1,34 @@ + + + + + + Generic + ABS + Generic + + 506c9f0d-e3aa-4bd4-b2d2-23e2425b1aa9 + 0 + #FF0000 + + + 1.07 + 2.85 + + + 250 + 80 + + + + + + + + + + + + diff --git a/resources/materials/generic_cpe.xml.fdm_material b/resources/materials/generic_cpe.xml.fdm_material new file mode 100644 index 0000000000..bbe6e328d2 --- /dev/null +++ b/resources/materials/generic_cpe.xml.fdm_material @@ -0,0 +1,34 @@ + + + + + + Generic + CPE + Generic + + 506c9f0d-e3aa-4bd4-b2d2-23e2425b1aa9 + 0 + #0000FF + + + 0.94 + 2.85 + + + 250 + 70 + + + + + + + + + + + + From 6847365e097420c12e2824923ef85bbd70972933 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 2 Jun 2016 08:08:56 +0200 Subject: [PATCH 358/705] Indicate the UM2+ should use machine specific materials and qualities Contributes to CURA-1612 --- resources/definitions/ultimaker.def.json | 5 +---- resources/definitions/ultimaker2_plus.def.json | 8 ++++++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/resources/definitions/ultimaker.def.json b/resources/definitions/ultimaker.def.json index 60e4dbbf40..b33f820198 100644 --- a/resources/definitions/ultimaker.def.json +++ b/resources/definitions/ultimaker.def.json @@ -6,9 +6,6 @@ "inherits": "fdmprinter", "metadata": { "author": "Ultimaker", - "manufacturer": "Ultimaker", - "preferred_profile": "Normal Quality", - "preferred_nozzle": "0.4 mm", - "preferred_material": "PLA" + "manufacturer": "Ultimaker" } } diff --git a/resources/definitions/ultimaker2_plus.def.json b/resources/definitions/ultimaker2_plus.def.json index 9f68c2a16b..75501fb158 100644 --- a/resources/definitions/ultimaker2_plus.def.json +++ b/resources/definitions/ultimaker2_plus.def.json @@ -12,8 +12,12 @@ "platform": "ultimaker2_platform.obj", "platform_texture": "Ultimaker2Plusbackplate.png", "preferred_variant": "ultimaker2_plus_0.4", - "preferred_material": "pla", - "preferred_quality": "high" + "preferred_material": "generic_pla_ultimaker2_plus_0.4mm", + "preferred_quality": "pla_0.4_normal", + "has_variants": true, + "has_materials": true, + "has_machine_materials": true, + "has_machine_quality": true }, "overrides": { From 48c8e7a1897961cd504edd510931e19cd4fc3478 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 2 Jun 2016 08:09:14 +0200 Subject: [PATCH 359/705] Update generic PLA profile Contributes to CURA-1612 --- .../materials/generic_pla.xml.fdm_material | 23 ++++--------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/resources/materials/generic_pla.xml.fdm_material b/resources/materials/generic_pla.xml.fdm_material index a4fe02c195..40432d5849 100644 --- a/resources/materials/generic_pla.xml.fdm_material +++ b/resources/materials/generic_pla.xml.fdm_material @@ -11,7 +11,7 @@ Generic PLA profile. Serves as an example file, data in this file is not correct 506c9f0d-e3aa-4bd4-b2d2-23e2425b1aa9 0 - #FFFFFF + #00FF00 1.3 @@ -20,28 +20,15 @@ Generic PLA profile. Serves as an example file, data in this file is not correct 210 60 - 175 - 150 - - - - - - - - - 150 - - 80 - - - 100 - + + + + From 5ce9bc64f4ec9145d53d481a3f0f1f8638f79032 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 2 Jun 2016 08:09:38 +0200 Subject: [PATCH 360/705] Remove non-xml material profiles Contributes to CURA-1612 --- resources/materials/abs.inst.cfg | 12 ------------ resources/materials/cpe.inst.cfg | 11 ----------- resources/materials/pla.inst.cfg | 10 ---------- 3 files changed, 33 deletions(-) delete mode 100644 resources/materials/abs.inst.cfg delete mode 100644 resources/materials/cpe.inst.cfg delete mode 100644 resources/materials/pla.inst.cfg diff --git a/resources/materials/abs.inst.cfg b/resources/materials/abs.inst.cfg deleted file mode 100644 index 0d64e81437..0000000000 --- a/resources/materials/abs.inst.cfg +++ /dev/null @@ -1,12 +0,0 @@ -[general] -version = 2 -name = ABS -definition = fdmprinter - -[metadata] -type = material - -[values] -material_print_temperature = 250 -material_bed_temperature = 80 -material_flow = 107 diff --git a/resources/materials/cpe.inst.cfg b/resources/materials/cpe.inst.cfg deleted file mode 100644 index ca30cba046..0000000000 --- a/resources/materials/cpe.inst.cfg +++ /dev/null @@ -1,11 +0,0 @@ -[general] -version = 2 -name = CPE -definition = fdmprinter - -[metadata] -type = material - -[values] -material_print_temperature = 250 -material_bed_temperature = 70 \ No newline at end of file diff --git a/resources/materials/pla.inst.cfg b/resources/materials/pla.inst.cfg deleted file mode 100644 index dfa9c62469..0000000000 --- a/resources/materials/pla.inst.cfg +++ /dev/null @@ -1,10 +0,0 @@ -[general] -version = 2 -name = PLA -definition = fdmprinter - -[metadata] -type = material - -[values] -material_bed_temperature = 60 From 7f7b56ff08988058ea1ba28b4496f5c2310fef0a Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 2 Jun 2016 08:10:32 +0200 Subject: [PATCH 361/705] Add additional quality profiles Low quality and machine-specific qualities for UM2+ Contributes to CURA-1612 --- resources/quality/low.inst.cfg | 10 +++++++++ .../ultimaker2_plus/pla_0.25_normal.inst.cfg | 18 ++++++++++++++++ .../ultimaker2_plus/pla_0.4_fast.inst.cfg | 20 ++++++++++++++++++ .../ultimaker2_plus/pla_0.4_high.inst.cfg | 18 ++++++++++++++++ .../ultimaker2_plus/pla_0.4_normal.inst.cfg | 18 ++++++++++++++++ .../ultimaker2_plus/pla_0.4_ulti.inst.cfg | 21 +++++++++++++++++++ .../ultimaker2_plus/pla_0.6_normal.inst.cfg | 18 ++++++++++++++++ .../ultimaker2_plus/pla_0.8_normal.inst.cfg | 18 ++++++++++++++++ 8 files changed, 141 insertions(+) create mode 100644 resources/quality/low.inst.cfg create mode 100644 resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg create mode 100644 resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg create mode 100644 resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg create mode 100644 resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg create mode 100644 resources/quality/ultimaker2_plus/pla_0.4_ulti.inst.cfg create mode 100644 resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg create mode 100644 resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg diff --git a/resources/quality/low.inst.cfg b/resources/quality/low.inst.cfg new file mode 100644 index 0000000000..d684bd81b9 --- /dev/null +++ b/resources/quality/low.inst.cfg @@ -0,0 +1,10 @@ +[general] +version = 2 +name = Low Quality +definition = fdmprinter + +[metadata] +type = quality + +[values] +layer_height = 0.15 diff --git a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg new file mode 100644 index 0000000000..9a44582610 --- /dev/null +++ b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg @@ -0,0 +1,18 @@ +[general] +version = 2 +name = High Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_pla_ultimaker2_plus_0.25_mm +weight = -2 + +[values] +layer_height = 0.06 +wall_thickness = 0.88 +top_bottom_thickness = 0.72 +infill_sparse_density = 22 +speed_print = 30 +cool_min_layer_time = 5 +cool_min_speed = 10 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg new file mode 100644 index 0000000000..be1e1ce992 --- /dev/null +++ b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg @@ -0,0 +1,20 @@ +[general] +version = 2 +name = Fast Print +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_pla_ultimaker2_plus_0.4_mm +weight = -1 + +[values] +layer_height = 0.15 +wall_thickness = 0.7 +top_bottom_thickness = 0.75 +infill_sparse_density = 18 +speed_print = 60 +speed_travel = 150 +speed_layer_0 = 30 +cool_min_layer_time = 5 +cool_min_speed = 10 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg new file mode 100644 index 0000000000..b058d17fbd --- /dev/null +++ b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg @@ -0,0 +1,18 @@ +[general] +version = 2 +name = High Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_pla_ultimaker2_plus_0.4_mm +weight = -3 + +[values] +layer_height = 0.06 +wall_thickness = 1.05 +top_bottom_thickness = 0.72 +infill_sparse_density = 22 +speed_print = 50 +cool_min_layer_time = 5 +cool_min_speed = 10 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg new file mode 100644 index 0000000000..78ee8cf566 --- /dev/null +++ b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg @@ -0,0 +1,18 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_pla_ultimaker2_plus_0.4_mm +weight = -2 + +[values] +layer_height = 0.1 +wall_thickness = 1.05 +top_bottom_thickness = 0.8 +infill_sparse_density = 20 +speed_print = 50 +cool_min_layer_time = 5 +cool_min_speed = 10 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_ulti.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_ulti.inst.cfg new file mode 100644 index 0000000000..db091d8e8d --- /dev/null +++ b/resources/quality/ultimaker2_plus/pla_0.4_ulti.inst.cfg @@ -0,0 +1,21 @@ +[general] +version = 1 +name = Ulti Quality +machine_type = ultimaker2plus +machine_variant = 0.4 mm +material = PLA +weight = -4 + +[settings] +line_width = 0.35 +layer_height = 0.04 +layer_height_0 = 0.26 +wall_thickness = 1.4 +top_bottom_thickness = 1.12 +infill_sparse_density = 25 +speed_print = 30 +speed_infill = 50 +speed_wall_x = 40 +speed_topbottom = 20 +speed_layer_0 = 25 +cool_min_layer_time_fan_speed_max = 15 diff --git a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg new file mode 100644 index 0000000000..f8f966e25a --- /dev/null +++ b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg @@ -0,0 +1,18 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_plus + +[metadata] +material = generic_pla_ultimaker2_plus_0.6_mm +type = quality +weight = -2 + +[values] +layer_height = 0.15 +wall_thickness = 1.59 +top_bottom_thickness = 1.2 +infill_sparse_density = 20 +speed_print = 55 +cool_min_layer_time = 5 +cool_min_speed = 10 diff --git a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg new file mode 100644 index 0000000000..ec53d15867 --- /dev/null +++ b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg @@ -0,0 +1,18 @@ +[general] +version = 2 +name = Fast Print +definition = ultimaker2_plus + +[metadata] +material = generic_pla_ultimaker2_plus_0.8_mm +type = quality +weight = -2 + +[values] +layer_height = 0.2 +wall_thickness = 2.1 +top_bottom_thickness = 1.2 +infill_sparse_density = 20 +speed_print = 40 +cool_min_layer_time = 5 +cool_min_speed = 10 From 72bc68f38ac8209170d1d60693fe8fab7c2f74a1 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 1 Jun 2016 15:16:39 +0200 Subject: [PATCH 362/705] Use self._definition instead of local definition parameter This is supposedly more defensive coding. Contributes to issues CURA-1278 and CURA-351. --- cura/Extruder.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cura/Extruder.py b/cura/Extruder.py index 5f74bd036f..b8783026f1 100644 --- a/cura/Extruder.py +++ b/cura/Extruder.py @@ -17,10 +17,10 @@ class Extruder: container_registry = UM.Settings.ContainerRegistry.getInstance() #Find the nozzles that fit on this extruder. - self._nozzles = container_registry.findInstanceContainers(type = "nozzle", definitions = "*," + definition.getId() + ",*") #Extruder needs to be delimited by either a comma or the end of string. - self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = "*," + definition.getId()) - self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = definition.getId() + ",*") - self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = definition.getId()) + self._nozzles = container_registry.findInstanceContainers(type = "nozzle", definitions = "*," + self._definition.getId() + ",*") #Extruder needs to be delimited by either a comma or the end of string. + self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = "*," + self._definition.getId()) + self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = self._definition.getId() + ",*") + self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = self._definition.getId()) #Create a container stack for this extruder. self._container_stack = UM.Settings.ContainerStack(self._uniqueName(self._definition.getId())) From 7993775feb6887874dd5947160760101955883d7 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 1 Jun 2016 16:33:24 +0200 Subject: [PATCH 363/705] Make profiles only load if the extruder says it has them For instance, only load materials if has_materials is True. Contributes to issues CURA-351 and CURA-1278. --- cura/Extruder.py | 60 ++++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/cura/Extruder.py b/cura/Extruder.py index b8783026f1..d0c5478270 100644 --- a/cura/Extruder.py +++ b/cura/Extruder.py @@ -29,39 +29,45 @@ class Extruder: #Find the nozzle to use for this extruder. self._nozzle = container_registry.getEmptyInstanceContainer() - if len(self._nozzles) >= 1: #First add any extruder. Later, overwrite with preference if the preference is valid. - self._nozzle = self._nozzles[0] - preferred_nozzle_id = self._definition.getMetaDataEntry("preferred_nozzle") - if preferred_nozzle_id: - for nozzle in self._nozzles: - if nozzle.getId() == preferred_nozzle_id: - self._nozzle = nozzle - break - self._container_stack.addContainer(self._nozzle) + if self._definition.getMetaDataEntry("has_nozzles", default = "False") == "True": + if len(self._nozzles) >= 1: #First add any extruder. Later, overwrite with preference if the preference is valid. + self._nozzle = self._nozzles[0] + preferred_nozzle_id = self._definition.getMetaDataEntry("preferred_nozzle") + if preferred_nozzle_id: + for nozzle in self._nozzles: + if nozzle.getId() == preferred_nozzle_id: + self._nozzle = nozzle + break + self._container_stack.addContainer(self._nozzle) #Find a material to use for this nozzle. self._material = container_registry.getEmptyInstanceContainer() - all_materials = container_registry.findInstanceContainers(type = "material") - if len(all_materials) >= 1: - self._material = all_materials[0] - preferred_material_id = self._definition.getMetaDataEntry("preferred_material") - if preferred_material_id: - preferred_material = container_registry.findInstanceContainers(type = "material", id = preferred_material_id.lower()) - if len(preferred_material) >= 1: - self._material = preferred_material[0] - self._container_stack.addContainer(self._material) + if self._definition.getMetaDataEntry("has_materials", default = "False") == "True": + if self._definition.getMetaDataEntry("has_nozzle_materials", default = "False") == "True": + all_materials = container_registry.findInstanceContainers(type = "material", nozzle = self._nozzle.getId()) + else: + all_materials = container_registry.findInstanceContainers(type = "material") + if len(all_materials) >= 1: + self._material = all_materials[0] + preferred_material_id = self._definition.getMetaDataEntry("preferred_material") + if preferred_material_id: + preferred_material = container_registry.findInstanceContainers(type = "material", id = preferred_material_id.lower()) + if len(preferred_material) >= 1: + self._material = preferred_material[0] + self._container_stack.addContainer(self._material) #Find a quality to use for this extruder. self._quality = container_registry.getEmptyInstanceContainer() - all_qualities = container_registry.findInstanceContainers(type = "quality") - if len(all_qualities) >= 1: - self._quality = all_qualities[0] - preferred_quality_id = self._definition.getMetaDataEntry("preferred_quality") - if preferred_quality_id: - preferred_quality = container_registry.findInstanceContainers(type = "quality", id = preferred_quality_id.lower()) - if len(preferred_quality) >= 1: - self._quality = preferred_quality[0] - self._container_stack.addContainer(self._quality) + if self._definition.getMetaDataEntry("has_machine_quality"): + all_qualities = container_registry.findInstanceContainers(type = "quality") + if len(all_qualities) >= 1: + self._quality = all_qualities[0] + preferred_quality_id = self._definition.getMetaDataEntry("preferred_quality") + if preferred_quality_id: + preferred_quality = container_registry.findInstanceContainers(type = "quality", id = preferred_quality_id.lower()) + if len(preferred_quality) >= 1: + self._quality = preferred_quality[0] + self._container_stack.addContainer(self._quality) self._container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack()) From 9772d95984e4d52261de5dd6df18488abe363521 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 1 Jun 2016 16:47:52 +0200 Subject: [PATCH 364/705] Add user profile to extruder stack This profile is empty to start with. The user can fill it. Contributes to issues CURA-351 and CURA-1278. --- cura/Extruder.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cura/Extruder.py b/cura/Extruder.py index d0c5478270..c51f3106a2 100644 --- a/cura/Extruder.py +++ b/cura/Extruder.py @@ -23,7 +23,8 @@ class Extruder: self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = self._definition.getId()) #Create a container stack for this extruder. - self._container_stack = UM.Settings.ContainerStack(self._uniqueName(self._definition.getId())) + name = self._uniqueName(self._definition.getId()) + self._container_stack = UM.Settings.ContainerStack(name) self._container_stack.addMetaDataEntry("type", "extruder_train") self._container_stack.addContainer(self._definition) @@ -69,6 +70,11 @@ class Extruder: self._quality = preferred_quality[0] self._container_stack.addContainer(self._quality) + #Add an empty user profile. + self._user_profile = UM.Settings.InstanceContainer(name + "_current_settings") + self._user_profile.addMetaDataEntry("type", "user") + self._container_stack.addContainer(self._user_profile) + self._container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack()) ## Finds a unique name for an extruder stack. From 1603bb3075d0bd90d3f11cef1587709d8fa0a46f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 10:55:03 +0200 Subject: [PATCH 365/705] Give access to nozzle, material and quality profiles You can now swap them out in the extruder model. Contributes to issues CURA-1278 and CURA-351. --- cura/Extruder.py | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/cura/Extruder.py b/cura/Extruder.py index c51f3106a2..5be05c713c 100644 --- a/cura/Extruder.py +++ b/cura/Extruder.py @@ -4,8 +4,10 @@ import re #To parse container registry names to increment the duplicates-resolving number. import UM.Application #To link the stack to the global container stack. +import UM.Logger import UM.Settings.ContainerRegistry #To search for nozzles, materials, etc. import UM.Settings.ContainerStack #To create a container stack for this extruder. +import UM.Signal #To notify people of changing extruder stacks. class Extruder: ## Creates a new extruder from the specified definition container. @@ -77,6 +79,73 @@ class Extruder: self._container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack()) + nozzle_changed = UM.Signal.Signal() + material_changed = UM.Signal.Signal() + quality_changed = UM.Signal.Signal() + + ## Gets the currently active material on this extruder. + # + # \return The currently active material on this extruder. + @property + def material(self): + return self._material + + ## Changes the currently active material in this extruder. + # + # \param value The new material to extrude through this extruder. + @material.setter + def material(self, value): + try: + position = self._container_stack.index(self._material) + except ValueError: #Material is not in the list. + UM.Logger.log("e", "I've lost my old material, so I can't find where to insert the new material.") + return + self._container_stack.replaceContainer(position, value) + self._material = value + self.material_changed.emit() + + ## Gets the currently active nozzle on this extruder. + # + # \return The currently active nozzle on this extruder. + @property + def nozzle(self): + return self._nozzle + + ## Changes the currently active nozzle on this extruder. + # + # \param value The new nozzle to use with this extruder. + @nozzle.setter + def nozzle(self, value): + try: + position = self._container_stack.index(self._nozzle) + except ValueError: #Nozzle is not in the list. + UM.Logger.log("e", "I've lost my old nozzle, so I can't find where to insert the new nozzle.") + return + self._container_stack.replaceContainer(position, value) + self._nozzle = value + self.nozzle_changed.emit() + + ## Gets the currently active quality on this extruder. + # + # \return The currently active quality on this extruder. + @property + def quality(self): + return self._quality + + ## Changes the currently active quality to use with this extruder. + # + # \param value The new quality to use with this extruder. + @quality.setter + def quality(self, value): + try: + position = self._container_stack.index(self._quality) + except ValueError: #Quality is not in the list. + UM.Logger.log("e", "I've lost my old quality, so I can't find where to insert the new quality.") + return + self._container_stack.replaceContainer(position, value) + self._quality = value + self.quality_changed.emit() + ## Finds a unique name for an extruder stack. # # \param extruder An extruder definition to design a name for. From e03f65c47158474d48e1d5643433baf4e3828524 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 2 Jun 2016 11:12:37 +0200 Subject: [PATCH 366/705] Remove stray debug print CURA-1278 --- resources/qml/SidebarSimple.qml | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index c95cb54b1f..80870ac29f 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -371,8 +371,6 @@ Item key: "infill_sparse_density" watchedProperties: [ "value" ] storeIndex: 0 - - onPropertiesChanged: console.log(properties.value) } UM.SettingPropertyProvider From c369202957e4e5c10fe7b1a889a5e704ffbab337 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 11:08:22 +0200 Subject: [PATCH 367/705] Fix unknown variable Was probably a copy-paste mistake here. Fixed it for him. Contributes to issue CURA-1278. --- cura/MachineManagerModel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 83b8e87859..c3b57ca8d0 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -312,8 +312,8 @@ class MachineManagerModel(QObject): def _getPreferredContainer(self, definition, property_name, default_container): preferred_id = definition.getMetaDataEntry(property_name) if preferred_id: - preferred_variant_id = preferred_variant_id.lower() - container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = preferred_variant_id) + preferred_id = preferred_id.lower() + container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = preferred_id) if container: return container[0] From 73f12ffd99e0b4c7fba37dd845f36928d2d884e4 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 11:15:52 +0200 Subject: [PATCH 368/705] Incorporate switching of global extruder stack When the global extruder stack switches, we need to re-connect the reloading of extruders to the new containersChanged signal of the new global container stack. This now also bootstraps the listening for the first time, when the global container stack changes from None to the first stack. Contributes to issues CURA-1278 and CURA-351. --- cura/ExtruderManager.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 4d95a9008d..71b636ad6f 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -19,9 +19,17 @@ class ExtruderManager: ## Registers listeners and such to listen to changes to the extruders. def __init__(self): self._extruders = [] #Extruders for the current machine. + self._global_container_stack = None - Application.getInstance().getGlobalContainerStack().containersChanged.connect(self._reloadExtruders) #When the current machine changes, we need to reload all extruders belonging to the new machine. - self._reloadExtruders() + Application.getInstance().globalContainerStackChanged.connect(self._reconnectExtruderReload) #When the current machine changes, we need to reload all extruders belonging to the new machine. + + ## When the global container stack changes, this reconnects to the new + # signal for containers changing. + def _reconnectExtruderReload(self): + if self._global_container_stack: + self._global_container_stack.containersChanged.disconnect(self._reloadExtruders) #Disconnect from the old global container stack. + self._global_container_stack = Application.getInstance().getGlobalContainerStack() + self._global_container_stack.containersChanged.connect(self._reloadExtruders) #When the current machine changes, we need to reload all extruders belonging to the new machine. ## (Re)loads all extruders of the currently active machine. # @@ -30,12 +38,11 @@ class ExtruderManager: # list of extruders. def _reloadExtruders(self): self._extruders = [] - global_container_stack = Application.getInstance().getGlobalContainerStack() - if not global_container_stack: #No machine has been added yet. + if not self._global_container_stack: #No machine has been added yet. return #Then leave them empty! #Get the extruder definitions belonging to the current machine. - machine = global_container_stack.getBottom() + machine = self._global_container_stack.getBottom() extruder_train_ids = machine.getMetaData("machine_extruder_trains") for extruder_train_id in extruder_train_ids: extruder_definitions = ContainerRegistry.getInstance().findDefinitionContainers(id = extruder_train_id) #Should be only 1 definition if IDs are unique, but add the whole list anyway. From 95e633f16cf1746b97405d63ae86e63959ac241f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 11:17:39 +0200 Subject: [PATCH 369/705] Load extruder manager on start-up This will consequently also load all extruder stacks of the current machine whenever the current machine changes. Contributes to issues CURA-1278 and CURA-351. --- cura/CuraApplication.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index d7e5768116..49fcbbf405 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -30,6 +30,7 @@ from UM.Settings.ContainerRegistry import ContainerRegistry from UM.i18n import i18nCatalog +from . import ExtruderManager from . import PlatformPhysics from . import BuildVolume from . import CameraAnimation @@ -326,6 +327,8 @@ class CuraApplication(QtApplication): qmlRegisterSingletonType(MachineManagerModel.MachineManagerModel, "Cura", 1, 0, "MachineManager", MachineManagerModel.createMachineManagerModel) + self._extruder_manager = ExtruderManager.ExtruderManager() + self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml")) self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles)) self.initializeEngine() From 5873f1d4d09206261f27bb12c6527a7fa9aeb123 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 2 Jun 2016 11:22:39 +0200 Subject: [PATCH 370/705] Limit layer processing to 99% to indicate more stuff needs to happen Fixes CURA-1644 --- plugins/CuraEngineBackend/ProcessSlicedLayersJob.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py index d3053f9175..77a42f6b3e 100644 --- a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py +++ b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py @@ -96,7 +96,7 @@ class ProcessSlicedLayersJob(Job): Job.yieldThread() Job.yieldThread() current_layer += 1 - progress = (current_layer / layer_count) * 100 + progress = (current_layer / layer_count) * 99 # TODO: Rebuild the layer data mesh once the layer has been processed. # This needs some work in LayerData so we can add the new layers instead of recreating the entire mesh. From 070e791b94dcc9197e7a865d4e055b0dd26b1635 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 2 Jun 2016 11:23:18 +0200 Subject: [PATCH 371/705] Add a preference to change LayerView top layers between 1 and 5 Fixes CURA-1643 --- plugins/LayerView/LayerView.py | 16 +++++++++++++++- resources/qml/ViewPage.qml | 27 +++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/plugins/LayerView/LayerView.py b/plugins/LayerView/LayerView.py index 27bb7f022c..b5f152e825 100644 --- a/plugins/LayerView/LayerView.py +++ b/plugins/LayerView/LayerView.py @@ -12,6 +12,7 @@ from UM.Math.Color import Color from UM.Mesh.MeshData import MeshData from UM.Job import Job from UM.Message import Message +from UM.Preferences import Preferences from UM.View.RenderBatch import RenderBatch from UM.View.GL.OpenGL import OpenGL @@ -44,7 +45,10 @@ class LayerView(View): self._top_layers_job = None self._activity = False - self._solid_layers = 1 + Preferences.getInstance().addPreference("view/top_layer_count", 1) + Preferences.getInstance().preferenceChanged.connect(self._onPreferencesChanged) + + self._solid_layers = int(Preferences.getInstance().getValue("view/top_layer_count")) self._top_layer_timer = QTimer() self._top_layer_timer.setInterval(50) @@ -212,6 +216,16 @@ class LayerView(View): self._top_layers_job = None + def _onPreferencesChanged(self, preference): + if preference != "view/top_layer_count": + return + + self._solid_layers = int(Preferences.getInstance().getValue("view/top_layer_count")) + + self._current_layer_mesh = None + self._current_layer_jumps = None + self._top_layer_timer.start() + class _CreateTopLayersJob(Job): def __init__(self, scene, layer_number, solid_layers): super().__init__() diff --git a/resources/qml/ViewPage.qml b/resources/qml/ViewPage.qml index ee0c74904a..3860f8f304 100644 --- a/resources/qml/ViewPage.qml +++ b/resources/qml/ViewPage.qml @@ -19,6 +19,7 @@ UM.PreferencesPage { UM.Preferences.resetPreference("view/show_overhang"); UM.Preferences.resetPreference("view/center_on_select"); + UM.Preferences.resetPreference("view/top_layer_count"); } Column @@ -57,12 +58,38 @@ UM.PreferencesPage } } + UM.TooltipArea { + width: childrenRect.width; + height: childrenRect.height; + text: catalog.i18nc("@info:tooltip","Displays") + + CheckBox + { + id: topLayerCheckbox + text: catalog.i18nc("@action:button","Display five top layers in layer view."); + checked: UM.Preferences.getValue("view/top_layer_count") == 5 + onClicked: + { + if(UM.Preferences.getValue("view/top_layer_count") == 5) + { + UM.Preferences.setValue("view/top_layer_count", 1) + } + else + { + UM.Preferences.setValue("view/top_layer_count", 5) + } + } + } + } + Connections { target: UM.Preferences onPreferenceChanged: { overhangCheckbox.checked = boolCheck(UM.Preferences.getValue("view/show_overhang")) centerCheckbox.checked = boolCheck(UM.Preferences.getValue("view/center_on_select")) + topLayerCheckbox = UM.Preferences.getValue("view/top_layer_count") == 5 + } } } From 02b8fa90437d5aac8875ce52145344affa8d7dec Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 2 Jun 2016 12:46:01 +0200 Subject: [PATCH 372/705] Add missing tooltip CURA-1643 --- resources/qml/ViewPage.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/ViewPage.qml b/resources/qml/ViewPage.qml index 3860f8f304..1763325e18 100644 --- a/resources/qml/ViewPage.qml +++ b/resources/qml/ViewPage.qml @@ -61,7 +61,7 @@ UM.PreferencesPage UM.TooltipArea { width: childrenRect.width; height: childrenRect.height; - text: catalog.i18nc("@info:tooltip","Displays") + text: catalog.i18nc("@info:tooltip","Display 5 top layers in layer view or only the top-most layer. Rendering 5 layers takes longer, but may show more information.") CheckBox { From 14a8b8a1a40ea3e889fb2a1715f4637eb3e10fa1 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 2 Jun 2016 13:30:26 +0200 Subject: [PATCH 373/705] Fix showing formatted tooltip when exiting reset-value-icon CURA-1278 --- resources/qml/Settings/SettingItem.qml | 65 ++++++++++++++------------ 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index 4c14ee4039..aa4ef5be85 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -22,6 +22,38 @@ Item { signal showTooltip(string text); signal hideTooltip(); + property string tooltipText: + { + var affects = settingDefinitionsModel.getRequiredBy(definition.key, "value") + var affected_by = settingDefinitionsModel.getRequires(definition.key, "value") + + var affected_by_list = "" + for(var i in affected_by) + { + affected_by_list += "
  • %1
  • \n".arg(affected_by[i].label) + } + + var affects_list = "" + for(var i in affects) + { + affects_list += "
  • %1
  • \n".arg(affects[i].label) + } + + var tooltip = "%1\n

    %2

    ".arg(definition.label).arg(definition.description) + + if(affects_list != "") + { + tooltip += "
    %1\n
      \n%2
    ".arg(catalog.i18nc("@label", "Affects")).arg(affects_list) + } + + if(affected_by_list != "") + { + tooltip += "
    %1\n
      \n%2
    ".arg(catalog.i18nc("@label", "Affected By")).arg(affected_by_list) + } + + return tooltip + } + MouseArea { id: mouse; @@ -52,34 +84,7 @@ Item { onTriggered: { - var affects = settingDefinitionsModel.getRequiredBy(definition.key, "value") - var affected_by = settingDefinitionsModel.getRequires(definition.key, "value") - - var affected_by_list = "" - for(var i in affected_by) - { - affected_by_list += "
  • %1
  • \n".arg(affected_by[i].label) - } - - var affects_list = "" - for(var i in affects) - { - affects_list += "
  • %1
  • \n".arg(affects[i].label) - } - - var tooltip = "%1
    \n

    %2

    ".arg(definition.label).arg(definition.description) - - if(affects_list != "") - { - tooltip += "
    %1
    \n
      \n%2
    ".arg(catalog.i18nc("@label", "Affects")).arg(affects_list) - } - - if(affected_by_list != "") - { - tooltip += "
    %1
    \n
      \n%2
    ".arg(catalog.i18nc("@label", "Affected By")).arg(affected_by_list) - } - - base.showTooltip(tooltip); + base.showTooltip(base.tooltipText); } } @@ -137,7 +142,7 @@ Item { } onEntered: { hoverTimer.stop(); base.showTooltip(catalog.i18nc("@label", "This setting has a value that is different from the profile.\n\nClick to restore the value of the profile.")) } - onExited: base.showTooltip(definition.description); + onExited: base.showTooltip(base.tooltipText); } UM.SimpleButton @@ -164,7 +169,7 @@ Item { iconSource: UM.Theme.getIcon("notice"); onEntered: { hoverTimer.stop(); base.showTooltip(catalog.i18nc("@label", "This setting is normally calculated, but it currently has an absolute value set.\n\nClick to restore the calculated value.")) } - onExited: base.showTooltip(definition.description); + onExited: base.showTooltip(base.tooltipText); } } From 1af6e63b35f8483bac5674ae7315bed1dcf867e2 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 2 Jun 2016 13:41:46 +0200 Subject: [PATCH 374/705] Removed unused model --- .../PerObjectSettingsModel.py | 75 ------------------- .../PerObjectSettingsTool.py | 1 - 2 files changed, 76 deletions(-) delete mode 100644 plugins/PerObjectSettingsTool/PerObjectSettingsModel.py diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsModel.py b/plugins/PerObjectSettingsTool/PerObjectSettingsModel.py deleted file mode 100644 index 74a1fbed9a..0000000000 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsModel.py +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright (c) 2015 Ultimaker B.V. -# Uranium is released under the terms of the AGPLv3 or higher. - -from PyQt5.QtCore import Qt, pyqtSlot, QUrl - -from UM.Application import Application -from UM.Qt.ListModel import ListModel -from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator -from UM.Scene.SceneNode import SceneNode -#from UM.Settings.SettingOverrideDecorator import SettingOverrideDecorator -#from UM.Settings.ProfileOverrideDecorator import ProfileOverrideDecorator - -from . import SettingOverrideModel - -class PerObjectSettingsModel(ListModel): - IdRole = Qt.UserRole + 1 # ID of the node - - def __init__(self, parent = None): - super().__init__(parent) - self._scene = Application.getInstance().getController().getScene() - self._root = self._scene.getRoot() - self.addRoleName(self.IdRole,"id") - - self._updateModel() - - @pyqtSlot("quint64", str) - def setObjectProfile(self, object_id, profile_name): - self.setProperty(self.find("id", object_id), "profile", profile_name) - - profile = None - '''if profile_name != "global": - profile = Application.getInstance().getMachineManager().findProfile(profile_name) - - node = self._scene.findObject(object_id) - if profile: - if not node.getDecorator(ProfileOverrideDecorator): - node.addDecorator(ProfileOverrideDecorator()) - node.callDecoration("setProfile", profile) - else: - if node.getDecorator(ProfileOverrideDecorator): - node.removeDecorator(ProfileOverrideDecorator)''' - - @pyqtSlot("quint64", str) - def addOverride(self, object_id, key): - machine = Application.getInstance().getMachineManager().getActiveMachineInstance() - if not machine: - return - - node = self._scene.findObject(object_id) - #if not node.getDecorator(SettingOverrideDecorator): - # node.addDecorator(SettingOverrideDecorator()) - - node.callDecoration("addSetting", key) - - @pyqtSlot("quint64", str) - def removerOverride(self, object_id, key): - node = self._scene.findObject(object_id) - node.callDecoration("removeSetting", key) - - #if len(node.callDecoration("getAllSettings")) == 0: - # node.removeDecorator(SettingOverrideDecorator) - - def _updateModel(self): - self.clear() - - for node in BreadthFirstIterator(self._root): - if type(node) is not SceneNode or not node.isSelectable(): - continue - - node_stack = node.callDecoration("getStack") - - if not node_stack: - self.appendItem({ - "id": id(node) - }) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py index c74800e83d..f702d0b939 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py @@ -6,7 +6,6 @@ from UM.Scene.Selection import Selection from UM.Application import Application from UM.Preferences import Preferences -from . import PerObjectSettingsModel class PerObjectSettingsTool(Tool): def __init__(self): From ca218d7a1fb6e46a4092ab072062458c56e44273 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 2 Jun 2016 13:52:11 +0200 Subject: [PATCH 375/705] Removed too generic exception handling CURA-1278 --- .../PerObjectSettingsTool.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py index f702d0b939..a06ecd297f 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py @@ -32,18 +32,14 @@ class PerObjectSettingsTool(Tool): return selected_object_id def getContainerID(self): + + selected_object = Selection.getSelectedObject(0) + if selected_object.getParent().callDecoration("isGroup"): + selected_object = selected_object.getParent() try: - selected_object = Selection.getSelectedObject(0) - if selected_object.getParent().callDecoration("isGroup"): - selected_object = selected_object.getParent() - try: - return selected_object.callDecoration("getStack").getId() - except: - print(":(") - return - except: - print(":((") - return + return selected_object.callDecoration("getStack").getId() + except AttributeError: + return "" def setContainerID(self, value): pass From b9f2d498b4ddfc0d02f36b8d109180abf90a42a7 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 11:25:38 +0200 Subject: [PATCH 376/705] Fix typo in documentation --- resources/qml/Settings/SettingView.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 9dabbaee98..6a11136966 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -48,7 +48,7 @@ ScrollView //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989 //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes, - //causing nasty issues when selecting differnt options. So disable asynchronous loading of enum type completely. + //causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely. asynchronous: model.type != "enum" active: model.type != undefined From 1f9805a73c0b7cdfba3b57405062703e0e6b9d97 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 11:43:02 +0200 Subject: [PATCH 377/705] Remove unused imports These are unused because the code was moved to Extruder.py Contributes to issues CURA-1278 and CURA-351. --- cura/ExtruderManager.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 71b636ad6f..60d452ae73 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -1,12 +1,9 @@ # Copyright (c) 2016 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. -import re - from cura.Extruder import Extruder #The individual extruders managed by this manager. from UM.Application import Application #To get the global container stack to find the current machine. from UM.Logger import Logger -from UM.Settings.ContainerStack import ContainerStack #To create container stacks for each extruder. from UM.Settings.ContainerRegistry import ContainerRegistry #Finding containers by ID. From 06f7f90bb08c5a5dea6e216a670cf05d112125a9 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 12:04:19 +0200 Subject: [PATCH 378/705] Make ExtruderManager into a singleton This way we don't need to load it in CuraApplication but we can just load it whenever it is first needed. ExtruderManager should be robust against initialising it at any point in Cura's runtime. Contributes to issues CURA-1278 and CURA-351. --- cura/CuraApplication.py | 2 -- cura/ExtruderManager.py | 13 +++++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 49fcbbf405..b8cef52d0c 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -327,8 +327,6 @@ class CuraApplication(QtApplication): qmlRegisterSingletonType(MachineManagerModel.MachineManagerModel, "Cura", 1, 0, "MachineManager", MachineManagerModel.createMachineManagerModel) - self._extruder_manager = ExtruderManager.ExtruderManager() - self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml")) self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles)) self.initializeEngine() diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 60d452ae73..34dbfd7c0c 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -13,6 +13,9 @@ from UM.Settings.ContainerRegistry import ContainerRegistry #Finding containers # and makes sure that whenever the machine is swapped, this list is kept up to # date. It also contains and updates the setting stacks for the extruders. class ExtruderManager: + ## The singleton instance of this manager. + __instance = None + ## Registers listeners and such to listen to changes to the extruders. def __init__(self): self._extruders = [] #Extruders for the current machine. @@ -20,6 +23,16 @@ class ExtruderManager: Application.getInstance().globalContainerStackChanged.connect(self._reconnectExtruderReload) #When the current machine changes, we need to reload all extruders belonging to the new machine. + ## Gets an instance of this extruder manager. + # + # If an instance was already created, the old instance is returned. This + # implements the singleton pattern. + @classmethod + def getInstance(cls): + if not cls.__instance: + cls.__instance = ExtruderManager() + return cls.__instance + ## When the global container stack changes, this reconnects to the new # signal for containers changing. def _reconnectExtruderReload(self): From 8a8b0016ba314fbf7167710f24cf139beb0ce8ce Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 12:55:01 +0200 Subject: [PATCH 379/705] Add signal for when extruder list changes The ExtrudersModel will need to listen to this. Contributes to issues CURA-1278 and CURA-351. --- cura/ExtruderManager.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 34dbfd7c0c..3477a3175f 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -5,6 +5,7 @@ from cura.Extruder import Extruder #The individual extruders managed by this man from UM.Application import Application #To get the global container stack to find the current machine. from UM.Logger import Logger from UM.Settings.ContainerRegistry import ContainerRegistry #Finding containers by ID. +import UM.Signal #To notify other components of changes in the extruders. ## Class that handles the current extruder stack. @@ -16,6 +17,9 @@ class ExtruderManager: ## The singleton instance of this manager. __instance = None + ## Signal to notify other components when the list of extruders changes. + extrudersChanged = UM.Signal() + ## Registers listeners and such to listen to changes to the extruders. def __init__(self): self._extruders = [] #Extruders for the current machine. @@ -49,6 +53,7 @@ class ExtruderManager: def _reloadExtruders(self): self._extruders = [] if not self._global_container_stack: #No machine has been added yet. + self.extrudersChanged.emit() #Yes, we just cleared the _extruders list! return #Then leave them empty! #Get the extruder definitions belonging to the current machine. @@ -60,4 +65,5 @@ class ExtruderManager: Logger.log("w", "Machine definition %s refers to an extruder train \"%s\", but no such extruder was found.", machine.getId(), extruder_train_id) continue for extruder_definition in extruder_definitions: - self._extruders.append(Extruder(extruder_definition)) \ No newline at end of file + self._extruders.append(Extruder(extruder_definition)) + self.extrudersChanged.emit() \ No newline at end of file From 83693162369851aff7f287de64095066205edcd3 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 12:56:55 +0200 Subject: [PATCH 380/705] Use modern import method This is more robust to cyclic dependencies, and also the intended way of importing these classes in Python in general. Contributes to issues CURA-1278 and CURA-351. --- cura/ExtruderManager.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 3477a3175f..51faa0a5e2 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -2,9 +2,9 @@ # Cura is released under the terms of the AGPLv3 or higher. from cura.Extruder import Extruder #The individual extruders managed by this manager. -from UM.Application import Application #To get the global container stack to find the current machine. -from UM.Logger import Logger -from UM.Settings.ContainerRegistry import ContainerRegistry #Finding containers by ID. +import UM.Application #To get the global container stack to find the current machine. +import UM.Logger +import UM.Settings.ContainerRegistry #Finding containers by ID. import UM.Signal #To notify other components of changes in the extruders. @@ -25,7 +25,7 @@ class ExtruderManager: self._extruders = [] #Extruders for the current machine. self._global_container_stack = None - Application.getInstance().globalContainerStackChanged.connect(self._reconnectExtruderReload) #When the current machine changes, we need to reload all extruders belonging to the new machine. + UM.Application.getInstance().globalContainerStackChanged.connect(self._reconnectExtruderReload) #When the current machine changes, we need to reload all extruders belonging to the new machine. ## Gets an instance of this extruder manager. # @@ -42,7 +42,7 @@ class ExtruderManager: def _reconnectExtruderReload(self): if self._global_container_stack: self._global_container_stack.containersChanged.disconnect(self._reloadExtruders) #Disconnect from the old global container stack. - self._global_container_stack = Application.getInstance().getGlobalContainerStack() + self._global_container_stack = UM.Application.getInstance().getGlobalContainerStack() self._global_container_stack.containersChanged.connect(self._reloadExtruders) #When the current machine changes, we need to reload all extruders belonging to the new machine. ## (Re)loads all extruders of the currently active machine. @@ -60,9 +60,9 @@ class ExtruderManager: machine = self._global_container_stack.getBottom() extruder_train_ids = machine.getMetaData("machine_extruder_trains") for extruder_train_id in extruder_train_ids: - extruder_definitions = ContainerRegistry.getInstance().findDefinitionContainers(id = extruder_train_id) #Should be only 1 definition if IDs are unique, but add the whole list anyway. + extruder_definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = extruder_train_id) #Should be only 1 definition if IDs are unique, but add the whole list anyway. if not extruder_definitions: #Empty list or error. - Logger.log("w", "Machine definition %s refers to an extruder train \"%s\", but no such extruder was found.", machine.getId(), extruder_train_id) + UM.Logger.log("w", "Machine definition %s refers to an extruder train \"%s\", but no such extruder was found.", machine.getId(), extruder_train_id) continue for extruder_definition in extruder_definitions: self._extruders.append(Extruder(extruder_definition)) From 8a8de959692e4ea65135166de3ad4c2bba84d585 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 13:11:02 +0200 Subject: [PATCH 381/705] Add iteration over extruder manager This iteration iterates over the extruders. Contributes to issues CURA-1278 and CURA-351. --- cura/ExtruderManager.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 51faa0a5e2..3c1e50d9bd 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -24,6 +24,7 @@ class ExtruderManager: def __init__(self): self._extruders = [] #Extruders for the current machine. self._global_container_stack = None + self._next_item = 0 #For when you use this class as iterator. UM.Application.getInstance().globalContainerStackChanged.connect(self._reconnectExtruderReload) #When the current machine changes, we need to reload all extruders belonging to the new machine. @@ -37,6 +38,12 @@ class ExtruderManager: cls.__instance = ExtruderManager() return cls.__instance + ## Creates an iterator over the extruders in this manager. + # + # \return An iterator over the extruders in this manager. + def __iter__(self): + return iter(self._extruders) + ## When the global container stack changes, this reconnects to the new # signal for containers changing. def _reconnectExtruderReload(self): From 25a6a992869e7f84511e838211f951e17df2ab61 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 13:15:33 +0200 Subject: [PATCH 382/705] Make name of extruder a property This stores the name for later use, for instance when displaying the extruder. Contributes to issues CURA-1278 and CURA-351. --- cura/Extruder.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/cura/Extruder.py b/cura/Extruder.py index 5be05c713c..cff5f3e6d0 100644 --- a/cura/Extruder.py +++ b/cura/Extruder.py @@ -25,8 +25,8 @@ class Extruder: self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = self._definition.getId()) #Create a container stack for this extruder. - name = self._uniqueName(self._definition.getId()) - self._container_stack = UM.Settings.ContainerStack(name) + self._name = self._uniqueName(self._definition.getId()) + self._container_stack = UM.Settings.ContainerStack(self._name) self._container_stack.addMetaDataEntry("type", "extruder_train") self._container_stack.addContainer(self._definition) @@ -73,15 +73,16 @@ class Extruder: self._container_stack.addContainer(self._quality) #Add an empty user profile. - self._user_profile = UM.Settings.InstanceContainer(name + "_current_settings") + self._user_profile = UM.Settings.InstanceContainer(self._name + "_current_settings") self._user_profile.addMetaDataEntry("type", "user") self._container_stack.addContainer(self._user_profile) self._container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack()) - nozzle_changed = UM.Signal.Signal() - material_changed = UM.Signal.Signal() - quality_changed = UM.Signal.Signal() + material_changed = UM.Signal() + name_changed = UM.Signal() + nozzle_changed = UM.Signal() + quality_changed = UM.Signal() ## Gets the currently active material on this extruder. # @@ -104,6 +105,19 @@ class Extruder: self._material = value self.material_changed.emit() + ## Gets the name of this extruder. + # + # \return The name of this extruder. + @property + def name(self): + return self._name + + ## Changes the name of this extruder. + @name.setter + def name(self, value): + self._name = value + self.name_changed.emit() + ## Gets the currently active nozzle on this extruder. # # \return The currently active nozzle on this extruder. From df363a024a7a9e3c31ee9dfbc629da180e71b40d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 13:24:53 +0200 Subject: [PATCH 383/705] Expose definition container of extruders This contains important metadata which we'll need. It's also more consistent with the rest. Contributes to issues CURA-1278 and CURA-351. --- cura/Extruder.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/cura/Extruder.py b/cura/Extruder.py index cff5f3e6d0..9f2a8ab493 100644 --- a/cura/Extruder.py +++ b/cura/Extruder.py @@ -79,11 +79,33 @@ class Extruder: self._container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack()) + definition_changed = UM.Signal() material_changed = UM.Signal() name_changed = UM.Signal() nozzle_changed = UM.Signal() quality_changed = UM.Signal() + ## Gets the definition container of this extruder. + # + # \return The definition container of this extruder. + @property + def definition(self): + return self._definition + + ## Changes the definition container of this extruder. + # + # \param value The new definition for this extruder. + @definition.setter + def definition(self, value): + try: + position = self._container_stack.index(self._definition) + except ValueError: #Definition is not in the list. Big trouble! + UM.Logger.log("e", "I've lost my old extruder definition, so I can't find where to insert the new definition.") + return + self._container_stack.replaceContainer(position, value) + self._definition = value + self.definition_changed.emit() + ## Gets the currently active material on this extruder. # # \return The currently active material on this extruder. From e16fedf2d8640146fa4059b28a1a0fea51b2e68e Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 13:27:11 +0200 Subject: [PATCH 384/705] Changing name of extruder also changes name in container stack This name may be used to get a unique human-readable name. Just for consistency really. Contributes to issues CURA-1278 and CURA-351. --- cura/Extruder.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cura/Extruder.py b/cura/Extruder.py index 9f2a8ab493..4bbe24183d 100644 --- a/cura/Extruder.py +++ b/cura/Extruder.py @@ -135,9 +135,12 @@ class Extruder: return self._name ## Changes the name of this extruder. + # + # \param value The new name for this extruder. @name.setter def name(self, value): self._name = value + self._container_stack.setName(value) #Also update in container stack, being defensive. self.name_changed.emit() ## Gets the currently active nozzle on this extruder. From c24f4be8ae3403223141d991d29fe4ca085c8d3f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 13:42:02 +0200 Subject: [PATCH 385/705] Add extruders model Hasn't been tested much because there is no display for this in the front-end yet. It needs a setting data type to go with in order to display it. This model is for the drop-down boxes to select an extruder to print, for instance, the support with. Contributes to issues CURA-1278 and CURA-351. --- cura/ExtrudersModel.py | 55 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 cura/ExtrudersModel.py diff --git a/cura/ExtrudersModel.py b/cura/ExtrudersModel.py new file mode 100644 index 0000000000..08f349c1ff --- /dev/null +++ b/cura/ExtrudersModel.py @@ -0,0 +1,55 @@ +# Copyright (c) 2016 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. + +from PyQt5.QtCore import Qt + +import cura.ExtruderManager +import UM.Qt.ListModel + +## Model that holds extruders. +# +# This model is designed for use by any list of extruders, but specifically +# intended for drop-down lists of extruders in place of settings. +class ExtrudersModel(UM.Qt.ListModel): + ## Human-readable name of the extruder. + NameRole = Qt.UserRole + 1 + + ## Colour of the material loaded in the extruder. + ColourRole = Qt.UserRole + 2 + + ## Index of the extruder, which is also the value of the setting itself. + # + # An index of 0 indicates the first extruder, an index of 1 the second + # one, and so on. This is the value that will be saved in instance + # containers. + IndexRole = Qt.UserRole + 3 + + ## Initialises the extruders model, defining the roles and listening for + # changes in the data. + # + # \param parent Parent QtObject of this list. + def __init__(self, parent = None): + super().__init__(parent) + + self.addRoleName(self.NameRole, "name") + self.addRoleName(self.ColourRole, "colour") + self.addRoleName(self.IndexRole, "index") + + #Listen to changes. + manager = cura.ExtruderManager.ExtruderManager.getInstance() + manager.extrudersChanged.connect(self._updateExtruders()) + + ## Update the list of extruders. + # + # This should be called whenever the list of extruders changes. + def _updateExtruders(self): + self.clear() + manager = cura.ExtruderManager.ExtruderManager.getInstance() + for index, extruder in enumerate(manager): + item = { #Construct an item with only the relevant information. + "name": extruder.name, + "colour": extruder.material.getMetaDataEntry("color_code", default = "#FFFF00"), + "index": index + } + self.appendItem(item) + self.sort(lambda item: item["index"]) \ No newline at end of file From f18eeba793e148088f9d34fad2455fbb126fa374 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 14:02:44 +0200 Subject: [PATCH 386/705] Add extruder setting type This is a new data type. It behaves and saves just like an integer, but it's actually just an index of the extruder to use. Contributes to issues CURA-1278 and CURA-351. --- cura/CuraApplication.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index b8cef52d0c..a5357b10d7 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -18,6 +18,7 @@ from UM.JobQueue import JobQueue from UM.SaveFile import SaveFile from UM.Scene.Selection import Selection from UM.Scene.GroupDecorator import GroupDecorator +import UM.Settings.Validator from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation @@ -89,6 +90,7 @@ class CuraApplication(QtApplication): # Need to do this before ContainerRegistry tries to load the machines SettingDefinition.addSupportedProperty("global_only", DefinitionPropertyType.Function, default = False) + SettingDefinition.addSettingType("extruder", int, str, UM.Settings.Validator) super().__init__(name = "cura", version = CuraVersion) From 45d01bf37186c065f73eb16ce793cfb2c43cb619 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 14:03:33 +0200 Subject: [PATCH 387/705] Remove unused import This was no longer needed since ExtruderManager is now a singleton. It's no longer in CuraApplication. Contributes to issues CURA-1278 and CURA-351. --- cura/CuraApplication.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index a5357b10d7..3c3415aefe 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -31,7 +31,6 @@ from UM.Settings.ContainerRegistry import ContainerRegistry from UM.i18n import i18nCatalog -from . import ExtruderManager from . import PlatformPhysics from . import BuildVolume from . import CameraAnimation From c994cb6bef743e96edad69c9c740bf0048c163fe Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 2 Jun 2016 14:19:39 +0200 Subject: [PATCH 388/705] Slicing no longer occurs when a perObject setting is in error state CURA-1288 --- plugins/CuraEngineBackend/StartSliceJob.py | 19 +++++++++++++++++-- .../PerObjectSettingsTool.py | 1 - 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index cf008e7b6f..0851261877 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -3,7 +3,6 @@ import numpy from string import Formatter -import traceback from enum import IntEnum from UM.Job import Job @@ -59,7 +58,7 @@ class StartSliceJob(Job): self.setResult(StartJobResult.Error) return - #Don't slice if there is a setting with an error value. + # Don't slice if there is a setting with an error value. for key in stack.getAllKeys(): validation_state = stack.getProperty(key, "validationState") if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError): @@ -69,6 +68,22 @@ class StartSliceJob(Job): Job.yieldThread() + # Don't slice if there is a per object setting with an error value. + for node in DepthFirstIterator(self._scene.getRoot()): + if type(node) is not SceneNode or not node.isSelectable(): + continue + + node_stack = node.callDecoration("getStack") + if node_stack: + for key in node_stack.getAllKeys(): + validation_state = node_stack.getProperty(key, "validationState") + if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError): + Logger.log("w", "Per object setting %s is not valid, but %s. Aborting slicing.", key, validation_state) + self.setResult(StartJobResult.SettingError) + return + + Job.yieldThread() + with self._scene.getSceneLock(): # Remove old layer data. for node in DepthFirstIterator(self._scene.getRoot()): diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py index a06ecd297f..ee653ae339 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py @@ -32,7 +32,6 @@ class PerObjectSettingsTool(Tool): return selected_object_id def getContainerID(self): - selected_object = Selection.getSelectedObject(0) if selected_object.getParent().callDecoration("isGroup"): selected_object = selected_object.getParent() From 388a345140ace9f11af6b22451acfb3377a52f98 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 2 Jun 2016 14:42:48 +0200 Subject: [PATCH 389/705] Changing a per-object setting now forces a re-slice CURA-1278 --- cura/SettingOverrideDecorator.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cura/SettingOverrideDecorator.py b/cura/SettingOverrideDecorator.py index 3e8815ec67..e212d93dac 100644 --- a/cura/SettingOverrideDecorator.py +++ b/cura/SettingOverrideDecorator.py @@ -18,11 +18,17 @@ class SettingOverrideDecorator(SceneNodeDecorator): self._instance = InstanceContainer(container_id = "SettingOverrideInstanceContainer") self._stack.addContainer(self._instance) + self._stack.propertyChanged.connect(self._onSettingChanged) + ContainerRegistry.getInstance().addContainer(self._stack) Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged) self._onGlobalContainerStackChanged() + def _onSettingChanged(self, instance, property): + if property == "value": # Only reslice if the value has changed. + Application.getInstance().getBackend().forceSlice() + def _onGlobalContainerStackChanged(self): ## Ensure that the next stack is always the global stack. self._stack.setNextStack(Application.getInstance().getGlobalContainerStack()) From 6257fe41d531d46476c207689b2a1375bf5fb192 Mon Sep 17 00:00:00 2001 From: Aldo Hoeben Date: Thu, 2 Jun 2016 14:50:02 +0200 Subject: [PATCH 390/705] Remove unsanctioned PLA profile --- .../ultimaker2+/pla_0.4_ulti.curaprofile | 23 ------------------- 1 file changed, 23 deletions(-) delete mode 100644 resources/profiles/ultimaker2+/pla_0.4_ulti.curaprofile diff --git a/resources/profiles/ultimaker2+/pla_0.4_ulti.curaprofile b/resources/profiles/ultimaker2+/pla_0.4_ulti.curaprofile deleted file mode 100644 index 5cb807de01..0000000000 --- a/resources/profiles/ultimaker2+/pla_0.4_ulti.curaprofile +++ /dev/null @@ -1,23 +0,0 @@ -[general] -version = 1 -name = Ulti Quality -machine_type = ultimaker2plus -machine_variant = 0.4 mm -material = PLA -weight = -4 - -[settings] -line_width = 0.35 -layer_height = 0.04 -layer_height_0 = 0.26 -wall_thickness = 1.4 -top_bottom_thickness = 1.12 -infill_sparse_density = 25 -retraction_amount = 5.5 -retraction_extrusion_window = 6 -speed_print = 30 -speed_infill = 50 -speed_wall_x = 40 -speed_topbottom = 20 -speed_layer_0 = 25 -cool_min_layer_time_fan_speed_max = 15 From 64e4cd0041127f1c31eb28d356dd98f8a348264d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 2 Jun 2016 15:52:25 +0200 Subject: [PATCH 391/705] Added properties to make setting items more customisable CURA-1278 --- resources/qml/Settings/SettingItem.qml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index aa4ef5be85..f476349c42 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -18,6 +18,10 @@ Item { property alias contents: controlContainer.children; property alias hovered: mouse.containsMouse + property var showRevertButton: true + property var showInheritButton: true + property var doDepthIdentation: true + signal contextMenuRequested() signal showTooltip(string text); signal hideTooltip(); @@ -93,7 +97,7 @@ Item { id: label; anchors.left: parent.left; - anchors.leftMargin: (UM.Theme.getSize("section_icon_column").width + 5) + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width) + anchors.leftMargin: doDepthIdentation ? (UM.Theme.getSize("section_icon_column").width + 5) + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width) : 0 anchors.right: settingControls.left; anchors.verticalCenter: parent.verticalCenter @@ -124,7 +128,7 @@ Item { { id: revertButton; - visible: propertyProvider.stackLevel == 0 + visible: propertyProvider.stackLevel == 0 && base.showRevertButton height: parent.height; width: height; @@ -151,7 +155,7 @@ Item { id: inheritButton; //visible: has_profile_value && base.has_inherit_function && base.is_enabled - visible: propertyProvider.properties.state == "InstanceState.User" && propertyProvider.stackLevel > 0 + visible: propertyProvider.properties.state == "InstanceState.User" && propertyProvider.stackLevel > 0 && base.showInheritButton height: parent.height; width: height; From edd5eecc3dacf626ff5aadb0c343ced12e7e7a72 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 2 Jun 2016 15:53:00 +0200 Subject: [PATCH 392/705] Per object settings no longer show depth identation, revert/inherit buttons CURA-1278 --- plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index f873ec9a79..d707fe9810 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -45,6 +45,7 @@ Item { { Loader { + id: settingLoader width: UM.Theme.getSize("setting").width; height: UM.Theme.getSize("section").height; @@ -57,6 +58,12 @@ Item { //causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely. asynchronous: model.type != "enum" + onLoaded: { + settingLoader.item.showRevertButton = false + settingLoader.item.showInheritButton = false + settingLoader.item.doDepthIdentation = false + } + source: { switch(model.type) // TODO: This needs to be fixed properly. Got frustrated with it not working, so this is the patch job! From 2ed518c47edfb8853abf998876dfa6db5f08f39a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 2 Jun 2016 16:02:47 +0200 Subject: [PATCH 393/705] Removed no longer used code CURA-1278 --- .../SettingOverrideModel.py | 138 ------------------ 1 file changed, 138 deletions(-) delete mode 100644 plugins/PerObjectSettingsTool/SettingOverrideModel.py diff --git a/plugins/PerObjectSettingsTool/SettingOverrideModel.py b/plugins/PerObjectSettingsTool/SettingOverrideModel.py deleted file mode 100644 index d4bebfdfee..0000000000 --- a/plugins/PerObjectSettingsTool/SettingOverrideModel.py +++ /dev/null @@ -1,138 +0,0 @@ -# Copyright (c) 2015 Ultimaker B.V. -# Uranium is released under the terms of the AGPLv3 or higher. - -from PyQt5.QtCore import Qt, pyqtSlot, QUrl - -from UM.Application import Application -from UM.Qt.ListModel import ListModel -#from UM.Settings.SettingOverrideDecorator import SettingOverrideDecorator - -class SettingOverrideModel(ListModel): - KeyRole = Qt.UserRole + 1 - LabelRole = Qt.UserRole + 2 - DescriptionRole = Qt.UserRole + 3 - ValueRole = Qt.UserRole + 4 - TypeRole = Qt.UserRole + 5 - UnitRole = Qt.UserRole + 6 - ValidRole = Qt.UserRole + 7 - OptionsRole = Qt.UserRole + 8 - WarningDescriptionRole = Qt.UserRole + 9 - ErrorDescriptionRole = Qt.UserRole + 10 - GlobalOnlyRole = Qt.UserRole + 11 - - def __init__(self, node, parent = None): - super().__init__(parent) - - self._ignore_setting_change = None - - self._node = node - self._node.decoratorsChanged.connect(self._onDecoratorsChanged) - self._onDecoratorsChanged(None) - - #self._activeProfile = Application.getInstance().getMachineManager().getWorkingProfile() #To be able to get notified when a setting changes. - #self._activeProfile.settingValueChanged.connect(self._onProfileSettingValueChanged) - #Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onProfileChanged) - - self.addRoleName(self.KeyRole, "key") - self.addRoleName(self.LabelRole, "label") - self.addRoleName(self.DescriptionRole, "description") - self.addRoleName(self.ValueRole,"value") - self.addRoleName(self.TypeRole, "type") - self.addRoleName(self.UnitRole, "unit") - self.addRoleName(self.ValidRole, "valid") - self.addRoleName(self.OptionsRole, "options") - self.addRoleName(self.WarningDescriptionRole, "warning_description") - self.addRoleName(self.ErrorDescriptionRole, "error_description") - self.addRoleName(self.GlobalOnlyRole, "global_only") - - @pyqtSlot(str, "QVariant") - def setSettingValue(self, key, value): - if not self._decorator: - return - - self._decorator.setSettingValue(key, value) - - def _onDecoratorsChanged(self, node): - return - '''if not self._node.getDecorator(SettingOverrideDecorator): - self.clear() - return - - self._decorator = self._node.getDecorator(SettingOverrideDecorator) - self._decorator.settingAdded.connect(self._onSettingsChanged) - self._decorator.settingRemoved.connect(self._onSettingsChanged) - self._decorator.settingValueChanged.connect(self._onSettingValueChanged) - self._onSettingsChanged()''' - - def _createOptionsModel(self, options): - if not options: - return None - - model = ListModel() - model.addRoleName(Qt.UserRole + 1, "value") - model.addRoleName(Qt.UserRole + 2, "name") - for value, name in options.items(): - model.appendItem({"value": str(value), "name": str(name)}) - return model - - ## Updates the active profile in this model if the active profile is - # changed. - # - # This links the settingValueChanged of the new profile to this model's - # _onSettingValueChanged function, so that it properly listens to those - # events again. - def _onProfileChanged(self): - if self._activeProfile: #Unlink from the old profile. - self._activeProfile.settingValueChanged.disconnect(self._onProfileSettingValueChanged) - old_profile = self._activeProfile - self._activeProfile = Application.getInstance().getMachineManager().getWorkingProfile() - self._activeProfile.settingValueChanged.connect(self._onProfileSettingValueChanged) #Re-link to the new profile. - for setting_name in old_profile.getChangedSettings().keys(): #Update all changed settings in the old and new profiles. - self._onProfileSettingValueChanged(setting_name) - for setting_name in self._activeProfile.getChangedSettings().keys(): - self._onProfileSettingValueChanged(setting_name) - - ## Updates the global_only property of a setting once a setting value - # changes. - # - # This method should only get called on settings that are dependent on the - # changed setting. - # - # \param setting_name The setting that needs to be updated. - def _onProfileSettingValueChanged(self, setting_name): - index = self.find("key", setting_name) - if index != -1: - self.setProperty(index, "global_only", Application.getInstance().getMachineManager().getActiveMachineInstance().getMachineDefinition().getSetting(setting_name).getGlobalOnly()) - - def _onSettingsChanged(self): - self.clear() - - items = [] - for key, setting in self._decorator.getAllSettings().items(): - value = self._decorator.getSettingValue(key) - items.append({ - "key": key, - "label": setting.getLabel(), - "description": setting.getDescription(), - "value": str(value), - "type": setting.getType(), - "unit": setting.getUnit(), - "valid": setting.validate(value), - "options": self._createOptionsModel(setting.getOptions()), - "warning_description": setting.getWarningDescription(), - "error_description": setting.getErrorDescription(), - "global_only": setting.getGlobalOnly() - }) - - items.sort(key = lambda i: i["key"]) - - for item in items: - self.appendItem(item) - - def _onSettingValueChanged(self, setting): - index = self.find("key", setting.getKey()) - value = self._decorator.getSettingValue(setting.getKey()) - if index != -1: - self.setProperty(index, "value", str(value)) - self.setProperty(index, "valid", setting.validate(value)) - self.setProperty(index, "global_only", setting.getGlobalOnly()) \ No newline at end of file From 1ae69b25fad24303e132830c8c576c77081d11d6 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 2 Jun 2016 16:07:09 +0200 Subject: [PATCH 394/705] Added documentation --- .../PerObjectSettingVisibilityHandler.py | 3 ++- plugins/PerObjectSettingsTool/PerObjectSettingsTool.py | 7 +++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py b/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py index 9ef2515bed..381d45b1c2 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py @@ -5,7 +5,8 @@ from UM.Logger import Logger from cura.SettingOverrideDecorator import SettingOverrideDecorator - +## The per object setting visibility handler ensures that only setting defintions that have a matching instance Container +# are returned as visible. class PerObjectSettingVisibilityHandler(QObject): def __init__(self, parent = None, *args, **kwargs): super().__init__(parent = parent, *args, **kwargs) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py index ee653ae339..6ae44c2671 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py @@ -7,12 +7,14 @@ from UM.Application import Application from UM.Preferences import Preferences +## This tool allows the user to add & change settings per node in the scene. +# The settings per object are kept in a ContainerStack, which is linked to a node by decorator. class PerObjectSettingsTool(Tool): def __init__(self): super().__init__() self._model = None - self.setExposedProperties("SelectedObjectId","ContainerID") + self.setExposedProperties("SelectedObjectId", "ContainerID") Preferences.getInstance().preferenceChanged.connect(self._onPreferenceChanged) Selection.selectionChanged.connect(self.propertyChanged) @@ -40,9 +42,6 @@ class PerObjectSettingsTool(Tool): except AttributeError: return "" - def setContainerID(self, value): - pass - def _onPreferenceChanged(self, preference): if preference == "cura/active_mode": enabled = Preferences.getInstance().getValue(preference)==1 From 64ef5ab3a404aca828c9ecffb2ea9ab5707c994f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 14:58:11 +0200 Subject: [PATCH 395/705] Inherit from class, not module This is an import fail on my part, sorry. Contributes to issues CURA-1278 and CURA-351. --- cura/ExtrudersModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/ExtrudersModel.py b/cura/ExtrudersModel.py index 08f349c1ff..3eac9ce17b 100644 --- a/cura/ExtrudersModel.py +++ b/cura/ExtrudersModel.py @@ -10,7 +10,7 @@ import UM.Qt.ListModel # # This model is designed for use by any list of extruders, but specifically # intended for drop-down lists of extruders in place of settings. -class ExtrudersModel(UM.Qt.ListModel): +class ExtrudersModel(UM.Qt.ListModel.ListModel): ## Human-readable name of the extruder. NameRole = Qt.UserRole + 1 From 05243a4fcab2ae763bcc4dc448beb7993166bd5b Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 14:59:01 +0200 Subject: [PATCH 396/705] Connect to function, not result of function The result of the function was None, but I don't need None to be called whenever extruders changed. I need the function itself to be called. Contributes to issues CURA-1278 and CURA-351. --- cura/ExtrudersModel.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/ExtrudersModel.py b/cura/ExtrudersModel.py index 3eac9ce17b..eb63bc4257 100644 --- a/cura/ExtrudersModel.py +++ b/cura/ExtrudersModel.py @@ -37,7 +37,8 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): #Listen to changes. manager = cura.ExtruderManager.ExtruderManager.getInstance() - manager.extrudersChanged.connect(self._updateExtruders()) + manager.extrudersChanged.connect(self._updateExtruders) + self._updateExtruders() ## Update the list of extruders. # From 84fc7948ce7831dd26315dc58041b08f88a5230c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 15:00:40 +0200 Subject: [PATCH 397/705] Expose ExtrudersModel to QML It is required by the drop-down for extruder settings. Contributes to issues CURA-1278 and CURA-351. --- cura/CuraApplication.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 3c3415aefe..323d0b349a 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -31,6 +31,7 @@ from UM.Settings.ContainerRegistry import ContainerRegistry from UM.i18n import i18nCatalog +from . import ExtrudersModel from . import PlatformPhysics from . import BuildVolume from . import CameraAnimation @@ -367,6 +368,8 @@ class CuraApplication(QtApplication): qmlRegisterUncreatableType(CuraApplication, "Cura", 1, 0, "ResourceTypes", "Just an Enum type") + qmlRegisterType(ExtrudersModel.ExtrudersModel, "Cura", 1, 0, "ExtrudersModel") + qmlRegisterSingletonType(QUrl.fromLocalFile(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")), "Cura", 1, 0, "Actions") for path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.QmlFiles): From 7146c9ab7d537390dc5b254b396c6ba685772548 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 15:27:21 +0200 Subject: [PATCH 398/705] Make a drop-down box for selecting an extruder For use by settings such as infill_extruder_nr. Contributes to issues CURA-351 and CURA-1278. --- resources/qml/Settings/SettingExtruder.qml | 112 +++++++++++++++++++++ resources/qml/Settings/SettingView.qml | 2 + 2 files changed, 114 insertions(+) create mode 100644 resources/qml/Settings/SettingExtruder.qml diff --git a/resources/qml/Settings/SettingExtruder.qml b/resources/qml/Settings/SettingExtruder.qml new file mode 100644 index 0000000000..86ab728fc1 --- /dev/null +++ b/resources/qml/Settings/SettingExtruder.qml @@ -0,0 +1,112 @@ +// Copyright (c) 2016 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 + +import UM 1.1 as UM +import Cura 1.0 as Cura + +SettingItem +{ + id: base + + contents: ComboBox + { + id: control + + model: Cura.ExtrudersModel { + id: extruders_model + } + textRole: "name"; + + anchors.fill: parent + + MouseArea + { + anchors.fill: parent; + acceptedButtons: Qt.NoButton; + onWheel: wheel.accepted = true; + } + + style: ComboBoxStyle + { + background: Rectangle + { + color: + { + if (!enabled) + { + return UM.Theme.getColor("setting_control_disabled") + } + if(control.hovered || base.activeFocus) + { + return UM.Theme.getColor("setting_control_highlight") + } + else + { + return UM.Theme.getColor("setting_control") + } + } + border.width: UM.Theme.getSize("default_lining").width; + border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : control.hovered ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border"); + } + label: Item + { + Label + { + anchors.left: parent.left; + anchors.leftMargin: UM.Theme.getSize("default_lining").width + anchors.right: downArrow.left; + anchors.rightMargin: UM.Theme.getSize("default_lining").width; + anchors.verticalCenter: parent.verticalCenter; + + text: control.currentText; + font: UM.Theme.getFont("default"); + color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text"); + + elide: Text.ElideRight; + verticalAlignment: Text.AlignVCenter; + } + + UM.RecolorImage + { + id: downArrow + anchors.right: parent.right; + anchors.rightMargin: UM.Theme.getSize("default_lining").width * 2; + anchors.verticalCenter: parent.verticalCenter; + + source: UM.Theme.getIcon("arrow_bottom") + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width + 5 + sourceSize.height: width + 5 + + color: UM.Theme.getColor("setting_control_text"); + + } + } + } + + onActivated: provider.setPropertyValue("value", extruders_model.getItem(index).index) + onModelChanged: updateCurrentIndex(); + + Connections + { + target: provider + onPropertiesChanged: control.updateCurrentIndex() + } + + function updateCurrentIndex() { + for(var i = 0; i < extruders_model.rowCount(); ++i) { + if(extruders_model.getItem(i).index == provider.properties.value) { + currentIndex = i; + return; + } + } + + currentIndex = -1; + } + } +} diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 6a11136966..1555149d22 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -62,6 +62,8 @@ ScrollView return "SettingTextField.qml" case "enum": return "SettingComboBox.qml" + case "extruder": + return "SettingExtruder.qml" case "bool": return "SettingCheckBox.qml" case "str": From 1a30dd96b1acbb3f8e5af545bac49e6bd57ed837 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 15:30:39 +0200 Subject: [PATCH 399/705] Change setting type for extruder_nr settings This way it can determine the difference between an integer and an index in the extruder list. Contributes to issues CURA-1278. --- resources/definitions/fdmextruder.def.json | 2 +- resources/definitions/fdmprinter.def.json | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/resources/definitions/fdmextruder.def.json b/resources/definitions/fdmextruder.def.json index f755d72c4a..69797385a1 100644 --- a/resources/definitions/fdmextruder.def.json +++ b/resources/definitions/fdmextruder.def.json @@ -22,7 +22,7 @@ { "label": "Extruder", "description": "The extruder train used for printing. This is used in multi-extrusion.", - "type": "int", + "type": "extruder", "default_value": 0, "minimum_value": "0" }, diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 48952c2c99..ec27abd9f5 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -2125,7 +2125,7 @@ { "label": "Platform Adhesion Extruder", "description": "The extruder train to use for printing the skirt/brim/raft. This is used in multi-extrusion.", - "type": "int", + "type": "extruder", "default_value": 0, "minimum_value": "0", "maximum_value": "machine_extruder_count - 1", @@ -2135,7 +2135,7 @@ { "label": "Support Extruder", "description": "The extruder train to use for printing the support. This is used in multi-extrusion.", - "type": "int", + "type": "extruder", "default_value": 0, "minimum_value": "0", "maximum_value": "machine_extruder_count - 1", @@ -2145,7 +2145,7 @@ { "label": "Support Infill Extruder", "description": "The extruder train to use for printing the infill of the support. This is used in multi-extrusion.", - "type": "int", + "type": "extruder", "default_value": 0, "value": "support_extruder_nr", "minimum_value": "0", @@ -2156,7 +2156,7 @@ { "label": "First Layer Support Extruder", "description": "The extruder train to use for printing the first layer of support infill. This is used in multi-extrusion.", - "type": "int", + "type": "extruder", "default_value": 0, "value": "support_extruder_nr", "minimum_value": "0", @@ -2167,7 +2167,7 @@ { "label": "Support Roof Extruder", "description": "The extruder train to use for printing the roof of the support. This is used in multi-extrusion.", - "type": "int", + "type": "extruder", "default_value": 0, "value": "support_extruder_nr", "minimum_value": "0", From 186eca160b507a6d417e4c9cb7759eea0a80b99f Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 2 Jun 2016 12:01:19 +0200 Subject: [PATCH 400/705] Fix containersChanged signal handlers Fixes CURA-1642 --- cura/ConvexHullDecorator.py | 2 +- cura/ExtruderManager.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/ConvexHullDecorator.py b/cura/ConvexHullDecorator.py index 6639d12dc7..39cdc36232 100644 --- a/cura/ConvexHullDecorator.py +++ b/cura/ConvexHullDecorator.py @@ -101,7 +101,7 @@ class ConvexHullDecorator(SceneNodeDecorator): if key == "print_sequence" and property_name == "value": self._onChanged() - def _onChanged(self): + def _onChanged(self, *args): if self._convex_hull_job: self._convex_hull_job.cancel() self.setConvexHull(None) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 3c1e50d9bd..bfce380a70 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -57,7 +57,7 @@ class ExtruderManager: # This looks at the global container stack to see which machine is active. # Then it loads the extruders for that machine and loads each of them in a # list of extruders. - def _reloadExtruders(self): + def _reloadExtruders(self, *args): self._extruders = [] if not self._global_container_stack: #No machine has been added yet. self.extrudersChanged.emit() #Yes, we just cleared the _extruders list! @@ -65,7 +65,7 @@ class ExtruderManager: #Get the extruder definitions belonging to the current machine. machine = self._global_container_stack.getBottom() - extruder_train_ids = machine.getMetaData("machine_extruder_trains") + extruder_train_ids = machine.getMetaDataEntry("machine_extruder_trains") for extruder_train_id in extruder_train_ids: extruder_definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = extruder_train_id) #Should be only 1 definition if IDs are unique, but add the whole list anyway. if not extruder_definitions: #Empty list or error. From bb18bf6a30914e7127d7e40a4dbf3baa5baf1d3e Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 2 Jun 2016 16:38:06 +0200 Subject: [PATCH 401/705] Fix creating a jobname after loading a file Moves jobname creation out of qml and into python. CURA-1619 --- cura/CuraApplication.py | 15 ------- cura/PrintInformation.py | 56 ++++++++++++++++++++++-- resources/qml/Cura.qml | 4 +- resources/qml/JobSpecs.qml | 85 ++++++++++-------------------------- resources/qml/SaveButton.qml | 2 +- 5 files changed, 79 insertions(+), 83 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 49fcbbf405..3e3ab28010 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -436,21 +436,6 @@ class CuraApplication(QtApplication): self._platform_activity = True if count > 0 else False self.activityChanged.emit() - @pyqtSlot(str) - def setJobName(self, name): - # when a file is opened using the terminal; the filename comes from _onFileLoaded and still contains its - # extension. This cuts the extension off if necessary. - name = os.path.splitext(name)[0] - if self._job_name != name: - self._job_name = name - self.jobNameChanged.emit() - - jobNameChanged = pyqtSignal() - - @pyqtProperty(str, notify = jobNameChanged) - def jobName(self): - return self._job_name - # Remove all selected objects from the scene. @pyqtSlot() def deleteSelection(self): diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index 2663cab5a0..dd15d7a264 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -1,14 +1,17 @@ # Copyright (c) 2015 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. -from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty +from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty, pyqtSlot from UM.Application import Application from UM.Qt.Duration import Duration +from UM.Preferences import Preferences import math +import os.path +import unicodedata -## A class for processing and calculating minimum, current and maximum print time. +## A class for processing and calculating minimum, current and maximum print time as well as managing the job name # # This class contains all the logic relating to calculation and slicing for the # time/quality slider concept. It is a rather tricky combination of event handling @@ -22,6 +25,8 @@ import math # - When that is done, we update the minimum print time and start the final slice pass, the "high quality settings pass". # - When the high quality pass is done, we update the maximum print time. # +# This class also mangles the current machine name and the filename of the first loaded mesh into a job name. +# This job name is requested by the JobSpecs qml file. class PrintInformation(QObject): class SlicePass: CurrentSettings = 1 @@ -45,14 +50,17 @@ class PrintInformation(QObject): if self._backend: self._backend.printDurationMessage.connect(self._onPrintDurationMessage) + self._job_name = "" + Application.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged) + currentPrintTimeChanged = pyqtSignal() - + @pyqtProperty(Duration, notify = currentPrintTimeChanged) def currentPrintTime(self): return self._current_print_time materialAmountChanged = pyqtSignal() - + @pyqtProperty(float, notify = materialAmountChanged) def materialAmount(self): return self._material_amount @@ -66,3 +74,43 @@ class PrintInformation(QObject): r = Application.getInstance().getGlobalContainerStack().getProperty("material_diameter", "value") / 2 self._material_amount = round((amount / (math.pi * r ** 2)) / 1000, 2) self.materialAmountChanged.emit() + + @pyqtSlot(str) + def setJobName(self, name): + # when a file is opened using the terminal; the filename comes from _onFileLoaded and still contains its + # extension. This cuts the extension off if necessary. + name = os.path.splitext(name)[0] + if self._job_name != name: + self._job_name = name + self.jobNameChanged.emit() + + jobNameChanged = pyqtSignal() + + @pyqtProperty(str, notify = jobNameChanged) + def jobName(self): + return self._job_name + + @pyqtSlot(str, result = str) + def createJobName(self, base_name): + base_name = self._stripAccents(base_name) + if Preferences.getInstance().getValue("cura/jobname_prefix"): + return self._abbr_machine + "_" + base_name + else: + return base_name + + def _onGlobalStackChanged(self): + global_stack_name = Application.getInstance().getGlobalContainerStack().getName() + split_name = global_stack_name.split(" ") + abbr_machine = "" + for word in split_name: + if(word.lower() == "ultimaker"): + abbr_machine += "UM" + elif word.isdigit(): + abbr_machine += word + else: + abbr_machine += self._stripAccents(word.strip("()[]{}#").upper())[0] + + self._abbr_machine = abbr_machine + + def _stripAccents(self, str): + return ''.join(char for char in unicodedata.normalize('NFD', str) if unicodedata.category(char) != 'Mn') \ No newline at end of file diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 32e1e79029..cf99b39864 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -93,7 +93,7 @@ UM.MainWindow text: catalog.i18nc("@action:inmenu menubar:file", "&Save Selection to File"); enabled: UM.Selection.hasSelection; iconName: "document-save-as"; - onTriggered: UM.OutputDeviceManager.requestWriteSelectionToDevice("local_file", Printer.jobName, { "filter_by_machine": false }); + onTriggered: UM.OutputDeviceManager.requestWriteSelectionToDevice("local_file", PrintInformation.jobName, { "filter_by_machine": false }); } Menu { @@ -109,7 +109,7 @@ UM.MainWindow MenuItem { text: model.description; - onTriggered: UM.OutputDeviceManager.requestWriteToDevice(model.id, Printer.jobName, { "filter_by_machine": false }); + onTriggered: UM.OutputDeviceManager.requestWriteToDevice(model.id, PrintInformation.jobName, { "filter_by_machine": false }); } onObjectAdded: saveAllMenu.insertItem(index, object) onObjectRemoved: saveAllMenu.removeItem(object) diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml index 9551e3bcf5..e73bf145de 100644 --- a/resources/qml/JobSpecs.qml +++ b/resources/qml/JobSpecs.qml @@ -10,62 +10,25 @@ import UM 1.1 as UM import Cura 1.0 as Cura Rectangle { - id: base; + id: base - property bool activity: Printer.getPlatformActivity; + property bool activity: Printer.getPlatformActivity property string fileBaseName property variant activeMachineName: Cura.MachineManager.activeMachineName onActiveMachineNameChanged: { - base.createFileName() + printJobTextfield.text = PrintInformation.createJobName(base.fileBaseName); } UM.I18nCatalog { id: catalog; name:"cura"} - property variant printDuration: PrintInformation.currentPrintTime; - property real printMaterialAmount: PrintInformation.materialAmount; + property variant printDuration: PrintInformation.currentPrintTime + property real printMaterialAmount: PrintInformation.materialAmount height: childrenRect.height color: "transparent" - function createFileName() - { - var splitMachineName = Cura.MachineManager.activeMachineName.split(" ") - var abbrMachine = ""; - if ((UM.Preferences.getValue("cura/jobname_prefix"))) - { - for (var i = 0; i < splitMachineName.length; i++) - { - if (splitMachineName[i].search(/ultimaker/i) != -1) - { - abbrMachine += "UM"; - } - else - { - if (splitMachineName[i].charAt(0).search(/[0-9]/g) == -1) - { - abbrMachine += splitMachineName[i].charAt(0); - } - } - } - var regExpAdditives = /[0-9\+]/g; - var resultAdditives = splitMachineName[i].match(regExpAdditives); - if (resultAdditives != null) - { - for (var j = 0; j < resultAdditives.length; j++) - { - abbrMachine += resultAdditives[j]; - } - } - printJobTextfield.text = abbrMachine + "_" + base.fileBaseName; - } - else - { - printJobTextfield.text = base.fileBaseName; - } - } - Connections { target: backgroundItem @@ -78,20 +41,20 @@ Rectangle { onActivityChanged: { if (activity == true && base.fileBaseName == ''){ //this only runs when you open a file from the terminal (or something that works the same way; for example when you drag a file on the icon in MacOS or use 'open with' on Windows) - base.fileBaseName = Printer.jobName //it gets the fileBaseName from CuraApplication.py because this saves the filebase when the file is opened using the terminal (or something alike) - base.createFileName() + base.fileBaseName = PrintInformation.jobName; //get the fileBaseName from PrintInformation.py because this saves the filebase when the file is opened using the terminal (or something alike) + printJobTextfield.text = PrintInformation.createJobName(base.fileBaseName); } if (activity == true && base.fileBaseName != ''){ //this runs in all other cases where there is a mesh on the buildplate (activity == true). It uses the fileBaseName from the hasMesh signal - base.createFileName() + printJobTextfield.text = PrintInformation.createJobName(base.fileBaseName); } if (activity == false){ //When there is no mesh in the buildplate; the printJobTextField is set to an empty string so it doesn't set an empty string as a jobName (which is later used for saving the file) - printJobTextfield.text = '' + printJobTextfield.text = ''; } } - Rectangle + Rectangle { id: jobNameRow anchors.top: parent.top @@ -112,22 +75,22 @@ Rectangle { width: UM.Theme.getSize("save_button_specs_icons").width height: UM.Theme.getSize("save_button_specs_icons").height - onClicked: + onClicked: { - printJobTextfield.selectAll() - printJobTextfield.focus = true + printJobTextfield.selectAll(); + printJobTextfield.focus = true; } style: ButtonStyle { background: Rectangle { color: "transparent" - UM.RecolorImage + UM.RecolorImage { - width: UM.Theme.getSize("save_button_specs_icons").width - height: UM.Theme.getSize("save_button_specs_icons").height - sourceSize.width: width - sourceSize.height: width + width: UM.Theme.getSize("save_button_specs_icons").width; + height: UM.Theme.getSize("save_button_specs_icons").height; + sourceSize.width: width; + sourceSize.height: width; color: control.hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("text"); source: UM.Theme.getIcon("pencil"); } @@ -147,15 +110,15 @@ Rectangle { text: '' horizontalAlignment: TextInput.AlignRight onTextChanged: { - Printer.setJobName(text) + PrintInformation.setJobName(text); } onEditingFinished: { if (printJobTextfield.text != ''){ - printJobTextfield.focus = false + printJobTextfield.focus = false; } } validator: RegExpValidator { - regExp: /^[^\\ \/ \.]*$/ + regExp: /^[^\\ \/ \*\?\|\[\]]*$/ } style: TextFieldStyle{ textColor: UM.Theme.getColor("setting_control_text"); @@ -200,7 +163,7 @@ Rectangle { sourceSize.width: width sourceSize.height: width color: UM.Theme.getColor("text_subtext") - source: UM.Theme.getIcon("print_time"); + source: UM.Theme.getIcon("print_time") } Label{ id: timeSpec @@ -221,7 +184,7 @@ Rectangle { sourceSize.width: width sourceSize.height: width color: UM.Theme.getColor("text_subtext") - source: UM.Theme.getIcon("category_material"); + source: UM.Theme.getIcon("category_material") } Label{ id: lengthSpec @@ -229,7 +192,7 @@ Rectangle { anchors.verticalCenter: parent.verticalCenter font: UM.Theme.getFont("small") color: UM.Theme.getColor("text_subtext") - text: base.printMaterialAmount <= 0 ? catalog.i18nc("@label", "0.0 m") : catalog.i18nc("@label", "%1 m").arg(base.printMaterialAmount) + text: catalog.i18nc("@label", "%1 m").arg(base.printMaterialAmount > 0 ? base.printMaterialAmount : 0) } } } diff --git a/resources/qml/SaveButton.qml b/resources/qml/SaveButton.qml index 1307e8f820..8b95de15ee 100644 --- a/resources/qml/SaveButton.qml +++ b/resources/qml/SaveButton.qml @@ -98,7 +98,7 @@ Rectangle { text: UM.OutputDeviceManager.activeDeviceShortDescription onClicked: { - UM.OutputDeviceManager.requestWriteToDevice(UM.OutputDeviceManager.activeDevice, Printer.jobName, { "filter_by_machine": true }) + UM.OutputDeviceManager.requestWriteToDevice(UM.OutputDeviceManager.activeDevice, PrintInformation.jobName, { "filter_by_machine": true }) } style: ButtonStyle { From 4cd224aeb2ea6f5fbf7523fc16e1c8bbf4ec1927 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 2 Jun 2016 17:19:47 +0200 Subject: [PATCH 402/705] Add empty variant, material and quality containers Since we need these for making container switching work. Contributes to CURA-1612 --- cura/CuraApplication.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 39c3ed924f..dc5eb70394 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -142,6 +142,23 @@ class CuraApplication(QtApplication): ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.UserInstanceContainer) ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MachineStack) + # Add empty variant, material and quality containers. + # Since they are empty, they should never be serialized and instead just programmatically created. + # We need them to simplify the switching between materials. + empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer() + empty_variant_container = copy.deepcopy(empty_container) + empty_variant_container._id = "empty_variant" + empty_variant_container.addMetaDataEntry("type", "variant") + ContainerRegistry.getInstance().addContainer(empty_variant_container) + empty_material_container = copy.deepcopy(empty_container) + empty_material_container._id = "empty_material" + empty_material_container.addMetaDataEntry("type", "material") + ContainerRegistry.getInstance().addContainer(empty_material_container) + empty_quality_container = copy.deepcopy(empty_container) + empty_quality_container._id = "empty_quality" + empty_quality_container.addMetaDataEntry("type", "quality") + ContainerRegistry.getInstance().addContainer(empty_quality_container) + ContainerRegistry.getInstance().load() Preferences.getInstance().addPreference("cura/active_mode", "simple") From e36397fa29bd5999655502d599b1904512eaa202 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 2 Jun 2016 17:21:18 +0200 Subject: [PATCH 403/705] Use the new empty type-specific containers when adding a new machine Contributes to CURA-1612 --- cura/MachineManagerModel.py | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index c3b57ca8d0..77dfa39d3b 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -22,6 +22,10 @@ class MachineManagerModel(QObject): self.globalContainerChanged.connect(self.activeVariantChanged) self.globalContainerChanged.connect(self.activeQualityChanged) + self._empty_variant_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_variant")[0] + self._empty_material_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_material")[0] + self._empty_quality_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_quality")[0] + Preferences.getInstance().addPreference("cura/active_machine", "") active_machine_id = Preferences.getInstance().getValue("cura/active_machine") @@ -74,28 +78,26 @@ class MachineManagerModel(QObject): new_global_stack.addMetaDataEntry("type", "machine") UM.Settings.ContainerRegistry.getInstance().addContainer(new_global_stack) - empty_container = UM.Settings.ContainerRegistry.getInstance().getEmptyInstanceContainer() - - variant_instance_container = empty_container + variant_instance_container = self._empty_variant_container if definition.getMetaDataEntry("has_variants"): - variant_instance_container = self._getPreferredContainer(definition, "preferred_variant", empty_container) + variant_instance_container = self._getPreferredContainer(definition, "preferred_variant", self._empty_variant_container) - if variant_instance_container == empty_container: + if variant_instance_container == self._empty_variant_container: variants = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = definition.id) if variants: variant_instance_container = variants[0] - if variant_instance_container == empty_container: + if variant_instance_container == self._empty_variant_container: Logger.log("w", "Machine %s defines it has variants but no variants found", definition.id) - material_instance_container = empty_container + material_instance_container = self._empty_material_container if definition.getMetaDataEntry("has_materials"): - material_instance_container = self._getPreferredContainer(definition, "preferred_material", empty_container) + material_instance_container = self._getPreferredContainer(definition, "preferred_material", self._empty_material_container) - if material_instance_container == empty_container: + if material_instance_container == self._empty_material_container: materials = None if definition.getMetaDataEntry("has_machine_materials"): - if variant_instance_container != empty_container: + if variant_instance_container != self._empty_material_container: materials = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "material", definition = definition.id, variant = variant_instance_container.id) else: materials = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "material", definition = definition.id) @@ -105,9 +107,11 @@ class MachineManagerModel(QObject): if materials: material_instance_container = materials[0] - quality_instance_container = self._getPreferredContainer(definition, "preferred_quality", empty_container) + if material_instance_container == self._empty_materials_container: + Logger.log("w", "Machine %s defines it has materials but no matererials found", definition.id) - if quality_instance_container == empty_container: + quality_instance_container = self._getPreferredContainer(definition, "preferred_quality", self._empty_quality_container) + if quality_instance_container == self._empty_quality_container: if definition.getMetaDataEntry("has_machine_quality"): if material_instance_container: qualities = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "quality", definition = definition.id, material = material_instance_container.id) From 95a0c69662ec6ac7bd68bd2bd16055831297c7ae Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 2 Jun 2016 17:25:34 +0200 Subject: [PATCH 404/705] Bit of code refactoring to prevent duplication CURA-1288 --- plugins/CuraEngineBackend/StartSliceJob.py | 38 ++++++++++++---------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 0851261877..dee6f2b64c 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -51,6 +51,20 @@ class StartSliceJob(Job): def getSliceMessage(self): return self._slice_message + ## Check if a stack has any errors. + ## returns true if it has errors, false otherwise. + def _checkStackForErrors(self, stack): + if stack is None: + return False + + for key in stack.getAllKeys(): + validation_state = stack.getProperty(key, "validationState") + if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError): + Logger.log("w", "Setting %s is not valid, but %s. Aborting slicing.", key, validation_state) + return True + Job.yieldThread() + return False + ## Runs the job that initiates the slicing. def run(self): stack = Application.getInstance().getGlobalContainerStack() @@ -59,30 +73,18 @@ class StartSliceJob(Job): return # Don't slice if there is a setting with an error value. - for key in stack.getAllKeys(): - validation_state = stack.getProperty(key, "validationState") - if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError): - Logger.log("w", "Setting %s is not valid, but %s. Aborting slicing.", key, validation_state) - self.setResult(StartJobResult.SettingError) - return - - Job.yieldThread() + if self._checkStackForErrors(stack): + self.setResult(StartJobResult.SettingError) + return # Don't slice if there is a per object setting with an error value. for node in DepthFirstIterator(self._scene.getRoot()): if type(node) is not SceneNode or not node.isSelectable(): continue - node_stack = node.callDecoration("getStack") - if node_stack: - for key in node_stack.getAllKeys(): - validation_state = node_stack.getProperty(key, "validationState") - if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError): - Logger.log("w", "Per object setting %s is not valid, but %s. Aborting slicing.", key, validation_state) - self.setResult(StartJobResult.SettingError) - return - - Job.yieldThread() + if self._checkStackForErrors(node.callDecoration("getStack")): + self.setResult(StartJobResult.SettingError) + return with self._scene.getSceneLock(): # Remove old layer data. From 11cb9af97f819b362a719ff66ba8e6c7f8ac0464 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 2 Jun 2016 17:32:26 +0200 Subject: [PATCH 405/705] fixed typo --- cura/MachineManagerModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 77dfa39d3b..4bd42c9c9d 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -107,7 +107,7 @@ class MachineManagerModel(QObject): if materials: material_instance_container = materials[0] - if material_instance_container == self._empty_materials_container: + if material_instance_container == self._empty_material_container: Logger.log("w", "Machine %s defines it has materials but no matererials found", definition.id) quality_instance_container = self._getPreferredContainer(definition, "preferred_quality", self._empty_quality_container) From 0dec0aafcfbff6091d1e3a92908d9699b5ff11b7 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 2 Jun 2016 17:44:06 +0200 Subject: [PATCH 406/705] Fix exception when loading an object CURA-1619 --- cura/CuraApplication.py | 6 ++++-- cura/PrintInformation.py | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 39c3ed924f..3c4d776df8 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -706,16 +706,18 @@ class CuraApplication(QtApplication): def _onActiveMachineChanged(self): pass + fileLoaded = pyqtSignal() + def _onFileLoaded(self, job): node = job.getResult() if node != None: - self.setJobName(os.path.basename(job.getFileName())) + self.fileLoaded.emit(job.getFileName()) node.setSelectable(True) node.setName(os.path.basename(job.getFileName())) op = AddSceneNodeOperation(node, self.getController().getScene().getRoot()) op.push() - self.getController().getScene().sceneChanged.emit(node) #F orce scene change. + self.getController().getScene().sceneChanged.emit(node) #Force scene change. def _onJobFinished(self, job): if type(job) is not ReadMeshJob or not job.getResult(): diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index dd15d7a264..22bc562502 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -52,6 +52,7 @@ class PrintInformation(QObject): self._job_name = "" Application.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged) + Application.getInstance().fileLoaded.connect(self.setJobName) currentPrintTimeChanged = pyqtSignal() From ad35c9f070a6321f5328c92390fd7baef93fe566 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 3 Jun 2016 10:06:08 +0200 Subject: [PATCH 407/705] Added reload profile (simply clears user instance container) CURA-1278 --- cura/MachineManagerModel.py | 22 ++++++++++++++++++++++ resources/qml/Actions.qml | 5 +++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 4bd42c9c9d..d34e392720 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -41,9 +41,15 @@ class MachineManagerModel(QObject): activeVariantChanged = pyqtSignal() activeQualityChanged = pyqtSignal() + globalPropertyChanged = pyqtSignal() # Emitted whenever a property inside global container is changed. + + def _onGlobalPropertyChanged(self, key, property_name): + self.globalPropertyChanged.emit() + def _onGlobalContainerChanged(self): if self._global_container_stack: self._global_container_stack.containersChanged.disconnect(self._onInstanceContainersChanged) + self._global_container_stack.propertyChanged.disconnect(self._onGlobalPropertyChanged) self._global_container_stack = Application.getInstance().getGlobalContainerStack() self.globalContainerChanged.emit() @@ -51,6 +57,7 @@ class MachineManagerModel(QObject): if self._global_container_stack: Preferences.getInstance().setValue("cura/active_machine", self._global_container_stack.getId()) self._global_container_stack.containersChanged.connect(self._onInstanceContainersChanged) + self._global_container_stack.propertyChanged.connect(self._onGlobalPropertyChanged) def _onInstanceContainersChanged(self, container): container_type = container.getMetaDataEntry("type") @@ -160,6 +167,21 @@ class MachineManagerModel(QObject): return unique_name + @pyqtSlot() + def clearUserSettings(self): + if not self._global_container_stack: + return + user_settings = self._global_container_stack.getTop() + user_settings.clear() + + @pyqtProperty(bool, notify = globalPropertyChanged) + def hasUserSettings(self): + if not self._global_container_stack: + return + + user_settings = self._global_container_stack.getTop().findInstances(**{}) + return len(user_settings) != 0 + @pyqtProperty(str, notify = globalContainerChanged) def activeMachineName(self): if self._global_container_stack: diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index f3bce7b993..6dd851c3d5 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -6,6 +6,7 @@ pragma Singleton import QtQuick 2.2 import QtQuick.Controls 1.1 import UM 1.1 as UM +import Cura 1.0 as Cura Item { @@ -117,9 +118,9 @@ Item Action { id: resetProfileAction; - enabled: UM.ActiveProfile.valid && UM.ActiveProfile.hasCustomisedValues + enabled: Cura.MachineManager.hasUserSettings text: catalog.i18nc("@action:inmenu menubar:profile","&Reload Current Profile"); - onTriggered: UM.ActiveProfile.discardChanges(); + onTriggered: Cura.MachineManager.clearUserSettings(); } Action From 171adde6be95a11d751c892f565a732da42152b5 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 3 Jun 2016 10:15:01 +0200 Subject: [PATCH 408/705] Fixed broken signal when file was loaded --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 41dec309d9..d22fed73ce 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -723,7 +723,7 @@ class CuraApplication(QtApplication): def _onActiveMachineChanged(self): pass - fileLoaded = pyqtSignal() + fileLoaded = pyqtSignal(str) def _onFileLoaded(self, job): node = job.getResult() From 113da81db527773f32746bd84fd29e6103e8f7d3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 3 Jun 2016 10:29:19 +0200 Subject: [PATCH 409/705] Added isValidGlobalStack property to MachineManager CURA-1585 --- cura/MachineManagerModel.py | 16 ++++++++++++++++ resources/qml/Actions.qml | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index d34e392720..e9b8ba7d55 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -7,6 +7,7 @@ from UM.Preferences import Preferences from UM.Logger import Logger import UM.Settings +from UM.Settings.Validator import ValidatorState class MachineManagerModel(QObject): @@ -167,6 +168,17 @@ class MachineManagerModel(QObject): return unique_name + ## Convenience function to check if a stack has errors. + def _checkStackForErrors(self, stack): + if stack is None: + return False + + for key in stack.getAllKeys(): + validation_state = stack.getProperty(key, "validationState") + if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError): + return True + return False + @pyqtSlot() def clearUserSettings(self): if not self._global_container_stack: @@ -182,6 +194,10 @@ class MachineManagerModel(QObject): user_settings = self._global_container_stack.getTop().findInstances(**{}) return len(user_settings) != 0 + @pyqtProperty(bool, notify = globalPropertyChanged) + def isGlobalStackValid(self): + return not self._checkStackForErrors(self._global_container_stack) + @pyqtProperty(str, notify = globalContainerChanged) def activeMachineName(self): if self._global_container_stack: diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index 6dd851c3d5..4769b53b05 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -110,7 +110,7 @@ Item Action { id: updateProfileAction; - enabled: UM.ActiveProfile.valid && !UM.ActiveProfile.readOnly && UM.ActiveProfile.hasCustomisedValues + enabled: Cura.MachineManager.isGlobalStackValid && !UM.ActiveProfile.readOnly && Cura.MachineManager.hasUserSettings text: catalog.i18nc("@action:inmenu menubar:profile","&Update Current Profile"); onTriggered: UM.ActiveProfile.updateProfile(); } @@ -126,7 +126,7 @@ Item Action { id: addProfileAction; - enabled: UM.ActiveProfile.valid + enabled: Cura.MachineManager.isGlobalStackValid text: catalog.i18nc("@action:inmenu menubar:profile","&Create New Profile..."); } From 4fc565711d3675fef2c860c38531c8013fe9f39d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 3 Jun 2016 11:19:33 +0200 Subject: [PATCH 410/705] Added read-only property to profiles CURA-1585 --- cura/MachineManagerModel.py | 9 +++++++++ resources/qml/Actions.qml | 2 +- resources/quality/high.inst.cfg | 1 + resources/quality/low.inst.cfg | 1 + resources/quality/normal.inst.cfg | 1 + .../quality/ultimaker2_plus/pla_0.25_normal.inst.cfg | 1 + resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg | 1 + resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg | 1 + .../quality/ultimaker2_plus/pla_0.4_normal.inst.cfg | 1 + .../quality/ultimaker2_plus/pla_0.6_normal.inst.cfg | 1 + .../quality/ultimaker2_plus/pla_0.8_normal.inst.cfg | 1 + 11 files changed, 19 insertions(+), 1 deletion(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index e9b8ba7d55..5a43f8cbf1 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -246,6 +246,15 @@ class MachineManagerModel(QObject): return quality.getId() return "" + ## Check if a container is read_only + @pyqtSlot(str, result = bool) + def isReadOnly(self, container_id): + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=container_id) + if not containers or not self._global_container_stack: + return True + return containers[0].getMetaDataEntry("read_only", False) == "True" + + @pyqtSlot(str) def setActiveMaterial(self, material_id): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=material_id) diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index 4769b53b05..2e89ce043a 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -110,7 +110,7 @@ Item Action { id: updateProfileAction; - enabled: Cura.MachineManager.isGlobalStackValid && !UM.ActiveProfile.readOnly && Cura.MachineManager.hasUserSettings + enabled: Cura.MachineManager.isGlobalStackValid && Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) text: catalog.i18nc("@action:inmenu menubar:profile","&Update Current Profile"); onTriggered: UM.ActiveProfile.updateProfile(); } diff --git a/resources/quality/high.inst.cfg b/resources/quality/high.inst.cfg index 0329e9ffe1..546d11326b 100644 --- a/resources/quality/high.inst.cfg +++ b/resources/quality/high.inst.cfg @@ -5,6 +5,7 @@ definition = fdmprinter [metadata] type = quality +read_only = True [values] layer_height = 0.06 diff --git a/resources/quality/low.inst.cfg b/resources/quality/low.inst.cfg index d684bd81b9..11a0094aca 100644 --- a/resources/quality/low.inst.cfg +++ b/resources/quality/low.inst.cfg @@ -5,6 +5,7 @@ definition = fdmprinter [metadata] type = quality +read_only = True [values] layer_height = 0.15 diff --git a/resources/quality/normal.inst.cfg b/resources/quality/normal.inst.cfg index 6d317cdf7a..b12603f921 100644 --- a/resources/quality/normal.inst.cfg +++ b/resources/quality/normal.inst.cfg @@ -5,5 +5,6 @@ definition = fdmprinter [metadata] type = quality +read_only = True [values] diff --git a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg index 9a44582610..7a1da403ff 100644 --- a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_pla_ultimaker2_plus_0.25_mm weight = -2 +read_only = True [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg index be1e1ce992..54f180379d 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_pla_ultimaker2_plus_0.4_mm weight = -1 +read_only = True [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg index b058d17fbd..926bcdcae7 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_pla_ultimaker2_plus_0.4_mm weight = -3 +read_only = True [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg index 78ee8cf566..f65544307e 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_pla_ultimaker2_plus_0.4_mm weight = -2 +read_only = True [values] layer_height = 0.1 diff --git a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg index f8f966e25a..906613dc23 100644 --- a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus material = generic_pla_ultimaker2_plus_0.6_mm type = quality weight = -2 +read_only = True [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg index ec53d15867..5cad44ec9c 100644 --- a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus material = generic_pla_ultimaker2_plus_0.8_mm type = quality weight = -2 +read_only = True [values] layer_height = 0.2 From d29cc37d6bcbca9306a8ecffc73566a90af28ff1 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 3 Jun 2016 11:58:59 +0200 Subject: [PATCH 411/705] Adds way to convert user settings into quality settings CURA-1585 --- cura/MachineManagerModel.py | 32 +++++++++++++++++++++++++++----- resources/qml/Cura.qml | 2 +- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 5a43f8cbf1..130b492ff4 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -8,6 +8,7 @@ from UM.Logger import Logger import UM.Settings from UM.Settings.Validator import ValidatorState +from UM.Settings.InstanceContainer import InstanceContainer class MachineManagerModel(QObject): @@ -80,7 +81,7 @@ class MachineManagerModel(QObject): definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id=definition_id) if definitions: definition = definitions[0] - name = self._uniqueMachineName(name, definition.getName()) + name = self._createUniqueStackName(name, definition.getName()) new_global_stack = UM.Settings.ContainerStack(name) new_global_stack.addMetaDataEntry("type", "machine") @@ -150,7 +151,7 @@ class MachineManagerModel(QObject): Application.getInstance().setGlobalContainerStack(new_global_stack) # Create a name that is not empty and unique - def _uniqueMachineName(self, name, fallback_name): + def _createUniqueStackName(self, name, fallback_name): name = name.strip() num_check = re.compile("(.*?)\s*#\d$").match(name) if(num_check): @@ -160,10 +161,10 @@ class MachineManagerModel(QObject): unique_name = name i = 1 - #Check both the id and the name, because they may not be the same and it is better if they are both unique + # Check both the id and the name, because they may not be the same and it is better if they are both unique while UM.Settings.ContainerRegistry.getInstance().findContainers(None, id = unique_name) or \ UM.Settings.ContainerRegistry.getInstance().findContainers(None, name = unique_name): - i = i + 1 + i += 1 unique_name = "%s #%d" % (name, i) return unique_name @@ -254,6 +255,27 @@ class MachineManagerModel(QObject): return True return containers[0].getMetaDataEntry("read_only", False) == "True" + @pyqtSlot() + def convertUserContainerToQuality(self): + if not self._global_container_stack: + return + + name = self._createUniqueStackName("Custom profile", "") + user_settings = self._global_container_stack.getTop() + new_quality_container = InstanceContainer("") + + ## Copy all values + new_quality_container.deserialize(user_settings.serialize()) + + ## Change type / id / name + new_quality_container.setMetaDataEntry("type","quality") + new_quality_container.setName(name) + new_quality_container._id = name + + UM.Settings.ContainerRegistry.getInstance().addContainer(new_quality_container) + self.clearUserSettings() # As all users settings are noq a quality, remove them. + self.setActiveQuality(name) + @pyqtSlot(str) def setActiveMaterial(self, material_id): @@ -319,7 +341,7 @@ class MachineManagerModel(QObject): def renameMachine(self, machine_id, new_name): containers = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = machine_id) if containers: - new_name = self._uniqueMachineName(new_name, containers[0].getBottom().getName()) + new_name = self._createUniqueStackName(new_name, containers[0].getBottom().getName()) containers[0].setName(new_name) self.globalContainerChanged.emit() diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index cf99b39864..2b7a4ccea7 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -580,7 +580,7 @@ UM.MainWindow target: Cura.Actions.addProfile onTriggered: { - UM.MachineManager.createProfile(); + Cura.MachineManager.convertUserContainerToQuality(); preferences.setPage(5); preferences.show(); From 0dece95f0f0b9c25026f0c00dcf5a03f53e250ed Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 3 Jun 2016 13:03:56 +0200 Subject: [PATCH 412/705] Updating non-readonly profiles is now possible again CURA-1585 --- cura/MachineManagerModel.py | 10 ++++++++++ resources/qml/Actions.qml | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 130b492ff4..b9d6a9d37c 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -276,6 +276,16 @@ class MachineManagerModel(QObject): self.clearUserSettings() # As all users settings are noq a quality, remove them. self.setActiveQuality(name) + @pyqtSlot() + def updateUserContainerToQuality(self): + if not self._global_container_stack: + return + user_settings = self._global_container_stack.getTop() + quality = self._global_container_stack.findContainer({"type": "quality"}) + for key in user_settings.getAllKeys(): + quality.setProperty(key, "value", user_settings.getProperty(key, "value")) + self.clearUserSettings() # As all users settings are noq a quality, remove them. + @pyqtSlot(str) def setActiveMaterial(self, material_id): diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index 2e89ce043a..e09b6b5424 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -112,7 +112,7 @@ Item id: updateProfileAction; enabled: Cura.MachineManager.isGlobalStackValid && Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) text: catalog.i18nc("@action:inmenu menubar:profile","&Update Current Profile"); - onTriggered: UM.ActiveProfile.updateProfile(); + onTriggered: Cura.MachineManager.updateUserContainerToQuality() } Action From 7b87143e65f4b14c0a9859e415db185b7ef0b39e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 3 Jun 2016 13:07:35 +0200 Subject: [PATCH 413/705] Only value property events are now used This speeds the num events up a bit, but it's still a tad to slow CURA-1585 --- cura/MachineManagerModel.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index b9d6a9d37c..c03c8074f5 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -43,10 +43,11 @@ class MachineManagerModel(QObject): activeVariantChanged = pyqtSignal() activeQualityChanged = pyqtSignal() - globalPropertyChanged = pyqtSignal() # Emitted whenever a property inside global container is changed. + globalValueChanged = pyqtSignal() # Emitted whenever a property inside global container is changed. def _onGlobalPropertyChanged(self, key, property_name): - self.globalPropertyChanged.emit() + if property_name == "value": + self.globalValueChanged.emit() def _onGlobalContainerChanged(self): if self._global_container_stack: @@ -187,7 +188,7 @@ class MachineManagerModel(QObject): user_settings = self._global_container_stack.getTop() user_settings.clear() - @pyqtProperty(bool, notify = globalPropertyChanged) + @pyqtProperty(bool, notify = globalValueChanged) def hasUserSettings(self): if not self._global_container_stack: return @@ -195,7 +196,7 @@ class MachineManagerModel(QObject): user_settings = self._global_container_stack.getTop().findInstances(**{}) return len(user_settings) != 0 - @pyqtProperty(bool, notify = globalPropertyChanged) + @pyqtProperty(bool, notify = globalValueChanged) def isGlobalStackValid(self): return not self._checkStackForErrors(self._global_container_stack) From 5faf2f024fb9118df7c146b40905fb14be3389cc Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 3 Jun 2016 13:14:49 +0200 Subject: [PATCH 414/705] Added signal for validation state This improves the runtime speed somewhat CURA-1585 --- cura/MachineManagerModel.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index c03c8074f5..3496252bb5 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -43,11 +43,14 @@ class MachineManagerModel(QObject): activeVariantChanged = pyqtSignal() activeQualityChanged = pyqtSignal() - globalValueChanged = pyqtSignal() # Emitted whenever a property inside global container is changed. + globalValueChanged = pyqtSignal() # Emitted whenever a value inside global container is changed. + globalValidationChanged = pyqtSignal() # Emitted whenever a validation inside global container is changed. def _onGlobalPropertyChanged(self, key, property_name): if property_name == "value": self.globalValueChanged.emit() + if property_name == "validationState": + self.globalValidationChanged.emit() def _onGlobalContainerChanged(self): if self._global_container_stack: @@ -196,7 +199,7 @@ class MachineManagerModel(QObject): user_settings = self._global_container_stack.getTop().findInstances(**{}) return len(user_settings) != 0 - @pyqtProperty(bool, notify = globalValueChanged) + @pyqtProperty(bool, notify = globalValidationChanged) def isGlobalStackValid(self): return not self._checkStackForErrors(self._global_container_stack) From 2b91b81f2d85eb3d5b3e1bfe1165c91a990c01e8 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 3 Jun 2016 13:24:23 +0200 Subject: [PATCH 415/705] Added documentation CURA-1585 --- cura/MachineManagerModel.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 3496252bb5..ef0de37774 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -174,6 +174,7 @@ class MachineManagerModel(QObject): return unique_name ## Convenience function to check if a stack has errors. + # TODO; This is a rather expensive check, which we run way to often. def _checkStackForErrors(self, stack): if stack is None: return False @@ -184,6 +185,7 @@ class MachineManagerModel(QObject): return True return False + ## Remove all instances from the top instanceContainer (effectively removing all user-changed settings) @pyqtSlot() def clearUserSettings(self): if not self._global_container_stack: @@ -191,6 +193,7 @@ class MachineManagerModel(QObject): user_settings = self._global_container_stack.getTop() user_settings.clear() + ## Check if the global_container has instances in the user container @pyqtProperty(bool, notify = globalValueChanged) def hasUserSettings(self): if not self._global_container_stack: @@ -199,6 +202,8 @@ class MachineManagerModel(QObject): user_settings = self._global_container_stack.getTop().findInstances(**{}) return len(user_settings) != 0 + ## Check if the global profile does not contain error states + # TODO; Way to expensive step. We should probably cache this. @pyqtProperty(bool, notify = globalValidationChanged) def isGlobalStackValid(self): return not self._checkStackForErrors(self._global_container_stack) From b6b154e153e92dab90a59ab10e1d062453662e2e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 3 Jun 2016 13:34:06 +0200 Subject: [PATCH 416/705] Fixed slowdown caused by validation check CURA-1585 --- cura/MachineManagerModel.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index ef0de37774..d9d62ecc1d 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -17,6 +17,7 @@ class MachineManagerModel(QObject): self._global_container_stack = None Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged) + self._global_stack_valid = None self._onGlobalContainerChanged() ## When the global container is changed, active material probably needs to be updated. @@ -32,6 +33,8 @@ class MachineManagerModel(QObject): active_machine_id = Preferences.getInstance().getValue("cura/active_machine") + + if active_machine_id != "": # An active machine was saved, so restore it. self.setActiveMachine(active_machine_id) @@ -50,7 +53,16 @@ class MachineManagerModel(QObject): if property_name == "value": self.globalValueChanged.emit() if property_name == "validationState": - self.globalValidationChanged.emit() + if self._global_stack_valid: + changed_validation_state = self._global_container_stack.getProperty(key, property_name) + if changed_validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError): + self._global_stack_valid = False + self.globalValidationChanged.emit() + else: + new_validation_state = self._checkStackForErrors(self._global_container_stack) + if new_validation_state: + self._global_stack_valid = True + self.globalValidationChanged.emit() def _onGlobalContainerChanged(self): if self._global_container_stack: @@ -64,6 +76,7 @@ class MachineManagerModel(QObject): Preferences.getInstance().setValue("cura/active_machine", self._global_container_stack.getId()) self._global_container_stack.containersChanged.connect(self._onInstanceContainersChanged) self._global_container_stack.propertyChanged.connect(self._onGlobalPropertyChanged) + self._global_stack_valid = self._checkStackForErrors(self._global_container_stack) def _onInstanceContainersChanged(self, container): container_type = container.getMetaDataEntry("type") @@ -174,7 +187,6 @@ class MachineManagerModel(QObject): return unique_name ## Convenience function to check if a stack has errors. - # TODO; This is a rather expensive check, which we run way to often. def _checkStackForErrors(self, stack): if stack is None: return False @@ -203,10 +215,11 @@ class MachineManagerModel(QObject): return len(user_settings) != 0 ## Check if the global profile does not contain error states - # TODO; Way to expensive step. We should probably cache this. + # Note that the _global_stack_valid is cached due to performance issues + # Calling _checkStackForErrors on every change is simply too expensive @pyqtProperty(bool, notify = globalValidationChanged) def isGlobalStackValid(self): - return not self._checkStackForErrors(self._global_container_stack) + return self._global_stack_valid @pyqtProperty(str, notify = globalContainerChanged) def activeMachineName(self): From ea73f00aacc9dc024f544b385dec7f285dd5c18a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 3 Jun 2016 14:39:36 +0200 Subject: [PATCH 417/705] Fixed case where validation state was set incorrectly CURA-1585 --- cura/MachineManagerModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index d9d62ecc1d..f89920e407 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -76,7 +76,7 @@ class MachineManagerModel(QObject): Preferences.getInstance().setValue("cura/active_machine", self._global_container_stack.getId()) self._global_container_stack.containersChanged.connect(self._onInstanceContainersChanged) self._global_container_stack.propertyChanged.connect(self._onGlobalPropertyChanged) - self._global_stack_valid = self._checkStackForErrors(self._global_container_stack) + self._global_stack_valid = not self._checkStackForErrors(self._global_container_stack) def _onInstanceContainersChanged(self, container): container_type = container.getMetaDataEntry("type") From cd8df448127449136323cebc45b5c61d43aa8f94 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 3 Jun 2016 14:40:28 +0200 Subject: [PATCH 418/705] Changed multiple properties in profile page to new API CURA-1285 --- resources/qml/Preferences/ProfilesPage.qml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 9561bba521..982f612943 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -90,15 +90,15 @@ UM.ManagementPage profileName = (profileName.length > 20) ? profileName.substring(0, 20) + '...' : profileName; return catalog.i18nc("@action:button", "Update \"%1\"".arg(profileName)); } - enabled: UM.ActiveProfile.hasCustomisedValues && !UM.ActiveProfile.readOnly + enabled: Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) onClicked: UM.ActiveProfile.updateProfile() } Button { text: catalog.i18nc("@action:button", "Discard changes"); - enabled: UM.ActiveProfile.hasCustomisedValues - onClicked: UM.ActiveProfile.discardChanges() + enabled: Cura.MachineManager.hasUserSettings + onClicked: Cura.MachineManager.clearUserSettings(); } } @@ -114,7 +114,7 @@ UM.ManagementPage } Label { text: base.currentItem == null ? "" : - base.currentItem.id == -1 ? UM.MachineManager.activeProfile : + base.currentItem.id == -1 ? Cura.MachineManager.activeQualityName: base.currentItem.readOnly ? catalog.i18nc("@label", "Protected profile") : catalog.i18nc("@label", "Custom profile") } From 80f24b6c5420b80d0d90823fd3352cfc588995fd Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 3 Jun 2016 14:56:42 +0200 Subject: [PATCH 419/705] Removed ulti quality, as that got in 2.1 by mistake As it got in there by mistake, it has no place here either! --- .../ultimaker2_plus/pla_0.4_ulti.inst.cfg | 21 ------------------- 1 file changed, 21 deletions(-) delete mode 100644 resources/quality/ultimaker2_plus/pla_0.4_ulti.inst.cfg diff --git a/resources/quality/ultimaker2_plus/pla_0.4_ulti.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_ulti.inst.cfg deleted file mode 100644 index db091d8e8d..0000000000 --- a/resources/quality/ultimaker2_plus/pla_0.4_ulti.inst.cfg +++ /dev/null @@ -1,21 +0,0 @@ -[general] -version = 1 -name = Ulti Quality -machine_type = ultimaker2plus -machine_variant = 0.4 mm -material = PLA -weight = -4 - -[settings] -line_width = 0.35 -layer_height = 0.04 -layer_height_0 = 0.26 -wall_thickness = 1.4 -top_bottom_thickness = 1.12 -infill_sparse_density = 25 -speed_print = 30 -speed_infill = 50 -speed_wall_x = 40 -speed_topbottom = 20 -speed_layer_0 = 25 -cool_min_layer_time_fan_speed_max = 15 From 01999f7ddd6b101ab128141ef7c17525823f64f5 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 3 Jun 2016 15:00:09 +0200 Subject: [PATCH 420/705] Custom profiles can now be renamed --- 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 982f612943..fb133a08ec 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -170,7 +170,7 @@ UM.ManagementPage id: renameDialog; object: base.currentItem != null ? base.currentItem.name : ""; property bool removeWhenRejected: false; - onAccepted: base.model.renameProfile(base.currentItem.name, newName.trim()); + onAccepted: base.model.rename(base.currentItem.id, newName.trim()); onRejected: { if(removeWhenRejected) { base.model.removeProfile(base.currentItem.name) From d1d60e27cc2719431aece5cea292bfcc8d17be48 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 3 Jun 2016 15:25:08 +0200 Subject: [PATCH 421/705] Added function to duplicate container CURA-1427 --- cura/MachineManagerModel.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index f89920e407..355fc188d3 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -277,8 +277,9 @@ class MachineManagerModel(QObject): return True return containers[0].getMetaDataEntry("read_only", False) == "True" - @pyqtSlot() + @pyqtSlot(result = str) def convertUserContainerToQuality(self): + print("convertUserContainerToQuality") if not self._global_container_stack: return @@ -297,6 +298,23 @@ class MachineManagerModel(QObject): UM.Settings.ContainerRegistry.getInstance().addContainer(new_quality_container) self.clearUserSettings() # As all users settings are noq a quality, remove them. self.setActiveQuality(name) + return name + + @pyqtSlot(str, result=str) + def duplicateContainer(self, container_id): + print("convertUserContainerToQuality") + if not self._global_container_stack: + return + container_to_duplicate = self._global_container_stack.findContainer({"id": container_id}) + if container_to_duplicate: + new_name = self._createUniqueStackName(container_to_duplicate.getName(), "") + new_container = InstanceContainer("") + new_container.setName(new_name) + new_container._id = new_name + UM.Settings.ContainerRegistry.getInstance().addContainer(new_container) + return new_name + + return "" @pyqtSlot() def updateUserContainerToQuality(self): From fdbd6d7c5f3114760a8d11dd4bdc6264041b203c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 3 Jun 2016 15:29:41 +0200 Subject: [PATCH 422/705] Updating profile now also works in profile page CURA-1585 --- resources/qml/Preferences/ProfilesPage.qml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index fb133a08ec..594b15e066 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -29,14 +29,14 @@ UM.ManagementPage onActivateObject: Cura.MachineManager.setActiveQuality(currentItem.id) onAddObject: { - var selectedProfile; + var selectedContainer; if (objectList.currentIndex == 0) { // Current settings - selectedProfile = UM.MachineManager.createProfile(); + selectedContainer = Cura.MachineManager.convertUserContainerToQuality(); } else { - selectedProfile = UM.MachineManager.duplicateProfile(currentItem.name); + selectedContainer = Cura.MachineManager.duplicateContainer(currentItem.id); } - base.selectProfile(selectedProfile); + base.selectContainer(selectedContainer); renameDialog.removeWhenRejected = true; renameDialog.open(); @@ -50,11 +50,11 @@ UM.ManagementPage removeEnabled: currentItem != null ? !currentItem.readOnly : false; renameEnabled: currentItem != null ? !currentItem.readOnly : false; - scrollviewCaption: catalog.i18nc("@label %1 is printer name","Printer: %1").arg(UM.MachineManager.activeMachineInstance) + scrollviewCaption: catalog.i18nc("@label %1 is printer name","Printer: %1").arg(Cura.MachineManager.activeMachineName) - signal selectProfile(string name) - onSelectProfile: { - objectList.currentIndex = objectList.model.find("name", name); + signal selectContainer(string id) + onSelectContainer: { + objectList.currentIndex = objectList.model.find("id", id); } Item { @@ -86,12 +86,12 @@ UM.ManagementPage Button { text: { - var profileName = UM.MachineManager.activeProfile; + var profileName = Cura.MachineManager.activeQualityName; profileName = (profileName.length > 20) ? profileName.substring(0, 20) + '...' : profileName; return catalog.i18nc("@action:button", "Update \"%1\"".arg(profileName)); } enabled: Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) - onClicked: UM.ActiveProfile.updateProfile() + onClicked: Cura.MachineManager.updateUserContainerToQuality() } Button From 490a8724e589365f0136b11f2851a906f9c9d8dd Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 3 Jun 2016 16:29:46 +0200 Subject: [PATCH 423/705] Fixed duplication of profiles CURA-1427 --- cura/MachineManagerModel.py | 13 ++++++++----- resources/qml/Preferences/ProfilesPage.qml | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 355fc188d3..609d2a77f8 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -279,7 +279,6 @@ class MachineManagerModel(QObject): @pyqtSlot(result = str) def convertUserContainerToQuality(self): - print("convertUserContainerToQuality") if not self._global_container_stack: return @@ -302,13 +301,17 @@ class MachineManagerModel(QObject): @pyqtSlot(str, result=str) def duplicateContainer(self, container_id): - print("convertUserContainerToQuality") if not self._global_container_stack: return - container_to_duplicate = self._global_container_stack.findContainer({"id": container_id}) - if container_to_duplicate: - new_name = self._createUniqueStackName(container_to_duplicate.getName(), "") + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=container_id) + if containers: + new_name = self._createUniqueStackName(containers[0].getName(), "") + new_container = InstanceContainer("") + + ## Copy all values + new_container.deserialize(containers[0].serialize()) + new_container.setName(new_name) new_container._id = new_name UM.Settings.ContainerRegistry.getInstance().addContainer(new_container) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 594b15e066..8182eb1bb6 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -34,7 +34,7 @@ UM.ManagementPage // Current settings selectedContainer = Cura.MachineManager.convertUserContainerToQuality(); } else { - selectedContainer = Cura.MachineManager.duplicateContainer(currentItem.id); + selectedContainer = Cura.MachineManager.duplicateContainer(base.currentItem.id); } base.selectContainer(selectedContainer); From c62ab6e937460e7fe81ca0765fbb3393f9e6e69d Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Sat, 4 Jun 2016 13:55:35 +0200 Subject: [PATCH 424/705] Adding a field of the build type to the spashscreen. For example, if the community distributes Cura in a different way, they can set CURA_BUILDTYPE via 'cmake -DCURA_BUILDTYPE=' and whenever Cura is launched " (PPA)" will be appended. Of course, this could be done by appending " (PPA)" to CURA_VERSION, but in case of my Ubuntu/Debian packaging it will only need one modification in debian/changelog to change the version. During build (debian/rules) this version will be read from debian/changelog. Changing the version number across different files, is a waste of time. Finally, we can use that field in the future to indicate debug or other other special builds. --- CMakeLists.txt | 1 + cura/CuraApplication.py | 5 +++-- cura/CuraSplashScreen.py | 3 +++ cura/CuraVersion.py.in | 1 + 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dc9f37c76e..98dca222b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,7 @@ include(GNUInstallDirs) set(URANIUM_SCRIPTS_DIR "${CMAKE_SOURCE_DIR}/../uranium/scripts" CACHE DIRECTORY "The location of the scripts directory of the Uranium repository") set(CURA_VERSION "master" CACHE STRING "Version name of Cura") +set(CURA_BUILDTYPE "" CACHE STRING "Build type of Cura, eg. 'PPA'") configure_file(cura/CuraVersion.py.in CuraVersion.py @ONLY) # Macro needed to list all sub-directory of a directory. diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index eccb3e4525..ac95529a5d 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -61,9 +61,10 @@ if platform.system() == "Linux": # Needed for platform.linux_distribution, which ctypes.CDLL(find_library('GL'), ctypes.RTLD_GLOBAL) try: - from cura.CuraVersion import CuraVersion + from cura.CuraVersion import CuraVersion, CuraBuildType except ImportError: CuraVersion = "master" # [CodeStyle: Reflecting imported value] + CuraBuildType = "" class CuraApplication(QtApplication): @@ -89,7 +90,7 @@ class CuraApplication(QtApplication): # Need to do this before ContainerRegistry tries to load the machines SettingDefinition.addSupportedProperty("global_only", DefinitionPropertyType.Function, default = False) - super().__init__(name = "cura", version = CuraVersion) + super().__init__(name = "cura", version = CuraVersion, build_type = CuraBuildType) self.setWindowIcon(QIcon(Resources.getPath(Resources.Images, "cura-icon.png"))) diff --git a/cura/CuraSplashScreen.py b/cura/CuraSplashScreen.py index d27c9c0240..8f677986df 100644 --- a/cura/CuraSplashScreen.py +++ b/cura/CuraSplashScreen.py @@ -21,6 +21,9 @@ class CuraSplashScreen(QSplashScreen): painter.setPen(QColor(0, 0, 0, 255)) version = Application.getInstance().getVersion().split("-") + buildtype = Application.getInstance().getBuildType() + if buildtype: + version += " (%s)" %(buildtype) painter.setFont(QFont("Proxima Nova Rg", 20 )) painter.drawText(0, 0, 330 * self._scale, 230 * self._scale, Qt.AlignHCenter | Qt.AlignBottom, version[0]) diff --git a/cura/CuraVersion.py.in b/cura/CuraVersion.py.in index bb69319ee6..5ad819b1fc 100644 --- a/cura/CuraVersion.py.in +++ b/cura/CuraVersion.py.in @@ -2,3 +2,4 @@ # Cura is released under the terms of the AGPLv3 or higher. CuraVersion = "@CURA_VERSION@" +CuraBuildType = "@CURA_BUILDTYPE@" \ No newline at end of file From b33ce573c1522e8b1864882e2429709de80ab4a0 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Sat, 4 Jun 2016 19:22:42 +0200 Subject: [PATCH 425/705] Also filter materials and profiles preference pages by machine etc. when desired Contriubtes to CURA-1612 --- resources/qml/Preferences/MaterialsPage.qml | 28 +++++++++++++++------ resources/qml/Preferences/ProfilesPage.qml | 21 +++++++++++++++- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index ed35a32fdf..af0f0c1bd2 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -14,7 +14,26 @@ UM.ManagementPage title: catalog.i18nc("@title:tab", "Materials"); - model: UM.InstanceContainersModel { filter: { "type": "material", "definition": Cura.MachineManager.activeDefinitionId } } + model: UM.InstanceContainersModel + { + filter: + { + var result = { "type": "material" } + if(Cura.MachineManager.filterMaterialsByMachine) + { + result.definition = Cura.MachineManager.activeDefinitionId + if(Cura.MachineManager.hasVariants) + { + result.variant = Cura.MachineManager.activeVariantId + } + } + else + { + result.definition = "fdmprinter" + } + return result + } + } activeId: Cura.MachineManager.activeMaterialId activeIndex: { @@ -25,12 +44,7 @@ UM.ManagementPage } return -1; } -/* - onAddObject: { var selectedMaterial = UM.MaterialManager.createProfile(); base.selectMaterial(selectedMaterial); } - onRemoveObject: confirmDialog.open(); - onRenameObject: { renameDialog.open(); renameDialog.selectText(); } -*/ -// activateEnabled: false + addEnabled: false removeEnabled: false renameEnabled: false diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 8182eb1bb6..b7261afcec 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -15,7 +15,26 @@ UM.ManagementPage title: catalog.i18nc("@title:tab", "Profiles"); addText: catalog.i18nc("@label", "Duplicate") - model: UM.InstanceContainersModel { filter: { "type": "quality" } } + model: UM.InstanceContainersModel + { + filter: + { + var result = { "type": "quality" }; + if(Cura.MachineManager.filterQualityByMachine) + { + result.definition = Cura.MachineManager.activeDefinitionId; + if(Cura.MachineManager.hasMaterials) + { + result.material = Cura.MachineManager.activeMaterialId; + } + } + else + { + result.definition = "fdmprinter" + } + return result + } + } activeId: Cura.MachineManager.activeQualityId activeIndex: { From 6a3b321e5a597e92b1257fd838569bdd1a6b190b Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Sat, 4 Jun 2016 19:23:46 +0200 Subject: [PATCH 426/705] Re-enable commented code --- resources/qml/SidebarHeader.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 4b48584174..bb7aeebae7 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -271,7 +271,7 @@ Item var result = { "type": "material" } if(Cura.MachineManager.filterMaterialsByMachine) { -// result.definition = Cura.MachineManager.activeDefinitionId + result.definition = Cura.MachineManager.activeDefinitionId if(Cura.MachineManager.hasVariants) { result.variant = Cura.MachineManager.activeVariantId From 8f21ec39807f3aeec50954f74f0bc4147194728d Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Sat, 4 Jun 2016 20:51:53 +0200 Subject: [PATCH 427/705] Add PLA profiles for UM2Extended+ Contributes to CURA-1612 --- .../um2ep_pla_0.25_normal.inst.cfg | 19 +++++++++++++++++ .../um2ep_pla_0.4_fast.inst.cfg | 21 +++++++++++++++++++ .../um2ep_pla_0.4_high.inst.cfg | 19 +++++++++++++++++ .../um2ep_pla_0.4_normal.inst.cfg | 19 +++++++++++++++++ .../um2ep_pla_0.6_normal.inst.cfg | 19 +++++++++++++++++ .../um2ep_pla_0.8_normal.inst.cfg | 19 +++++++++++++++++ 6 files changed, 116 insertions(+) create mode 100644 resources/quality/ultimaker2_extended_plus/um2ep_pla_0.25_normal.inst.cfg create mode 100644 resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_fast.inst.cfg create mode 100644 resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_high.inst.cfg create mode 100644 resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_normal.inst.cfg create mode 100644 resources/quality/ultimaker2_extended_plus/um2ep_pla_0.6_normal.inst.cfg create mode 100644 resources/quality/ultimaker2_extended_plus/um2ep_pla_0.8_normal.inst.cfg diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.25_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.25_normal.inst.cfg new file mode 100644 index 0000000000..142ee42b71 --- /dev/null +++ b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.25_normal.inst.cfg @@ -0,0 +1,19 @@ +[general] +version = 2 +name = High Quality +definition = ultimaker2_extended_plus + +[metadata] +type = quality +material = generic_pla_ultimaker2_extended_plus_0.25_mm +weight = -2 +read_only = True + +[values] +layer_height = 0.06 +wall_thickness = 0.88 +top_bottom_thickness = 0.72 +infill_sparse_density = 22 +speed_print = 30 +cool_min_layer_time = 5 +cool_min_speed = 10 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_fast.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_fast.inst.cfg new file mode 100644 index 0000000000..8fd8fedf4c --- /dev/null +++ b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_fast.inst.cfg @@ -0,0 +1,21 @@ +[general] +version = 2 +name = Fast Print +definition = ultimaker2_extended_plus + +[metadata] +type = quality +material = generic_pla_ultimaker2_extended_plus_0.4_mm +weight = -1 +read_only = True + +[values] +layer_height = 0.15 +wall_thickness = 0.7 +top_bottom_thickness = 0.75 +infill_sparse_density = 18 +speed_print = 60 +speed_travel = 150 +speed_layer_0 = 30 +cool_min_layer_time = 5 +cool_min_speed = 10 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_high.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_high.inst.cfg new file mode 100644 index 0000000000..3fc5cb39a0 --- /dev/null +++ b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_high.inst.cfg @@ -0,0 +1,19 @@ +[general] +version = 2 +name = High Quality +definition = ultimaker2_extended_plus + +[metadata] +type = quality +material = generic_pla_ultimaker2_extended_plus_0.4_mm +weight = -3 +read_only = True + +[values] +layer_height = 0.06 +wall_thickness = 1.05 +top_bottom_thickness = 0.72 +infill_sparse_density = 22 +speed_print = 50 +cool_min_layer_time = 5 +cool_min_speed = 10 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_normal.inst.cfg new file mode 100644 index 0000000000..94816b233c --- /dev/null +++ b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_normal.inst.cfg @@ -0,0 +1,19 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_extended_plus + +[metadata] +type = quality +material = generic_pla_ultimaker2_extended_plus_0.4_mm +weight = -2 +read_only = True + +[values] +layer_height = 0.1 +wall_thickness = 1.05 +top_bottom_thickness = 0.8 +infill_sparse_density = 20 +speed_print = 50 +cool_min_layer_time = 5 +cool_min_speed = 10 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.6_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.6_normal.inst.cfg new file mode 100644 index 0000000000..2de9b6a482 --- /dev/null +++ b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.6_normal.inst.cfg @@ -0,0 +1,19 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_extended_plus + +[metadata] +material = generic_pla_ultimaker2_extended_plus_0.6_mm +type = quality +weight = -2 +read_only = True + +[values] +layer_height = 0.15 +wall_thickness = 1.59 +top_bottom_thickness = 1.2 +infill_sparse_density = 20 +speed_print = 55 +cool_min_layer_time = 5 +cool_min_speed = 10 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.8_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.8_normal.inst.cfg new file mode 100644 index 0000000000..f3a1a14f73 --- /dev/null +++ b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.8_normal.inst.cfg @@ -0,0 +1,19 @@ +[general] +version = 2 +name = Fast Print +definition = ultimaker2_extended_plus + +[metadata] +material = generic_pla_ultimaker2_extended_plus_0.8_mm +type = quality +weight = -2 +read_only = True + +[values] +layer_height = 0.2 +wall_thickness = 2.1 +top_bottom_thickness = 1.2 +infill_sparse_density = 20 +speed_print = 40 +cool_min_layer_time = 5 +cool_min_speed = 10 From 3a3314aad1e6c14d0eb8c2af7efb2e53edee525e Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Sat, 4 Jun 2016 21:16:39 +0200 Subject: [PATCH 428/705] Remove all old profiles Contributes to CURA-1612 --- resources/instances/high_quality.inst.cfg | 9 -------- resources/instances/normal_quality.inst.cfg | 9 -------- resources/profiles/general/High+Quality.cfg | 10 --------- resources/profiles/general/Low+Quality.cfg | 15 ------------- resources/profiles/general/Normal+Quality.cfg | 8 ------- resources/profiles/general/Ulti+Quality.cfg | 9 -------- resources/profiles/materials/abs.cfg | 9 -------- resources/profiles/materials/cpe.cfg | 8 ------- resources/profiles/materials/pla.cfg | 7 ------ .../ultimaker2+/abs_0.25_normal.curaprofile | 20 ----------------- .../ultimaker2+/abs_0.4_fast.curaprofile | 21 ------------------ .../ultimaker2+/abs_0.4_high.curaprofile | 19 ---------------- .../ultimaker2+/abs_0.4_normal.curaprofile | 18 --------------- .../ultimaker2+/abs_0.6_normal.curaprofile | 20 ----------------- .../ultimaker2+/abs_0.8_normal.curaprofile | 19 ---------------- .../ultimaker2+/cpe_0.25_normal.curaprofile | 19 ---------------- .../ultimaker2+/cpe_0.4_fast.curaprofile | 22 ------------------- .../ultimaker2+/cpe_0.4_high.curaprofile | 18 --------------- .../ultimaker2+/cpe_0.4_normal.curaprofile | 19 ---------------- .../ultimaker2+/cpe_0.6_normal.curaprofile | 18 --------------- .../ultimaker2+/cpe_0.8_normal.curaprofile | 18 --------------- .../ultimaker2+/pla_0.25_normal.curaprofile | 16 -------------- .../ultimaker2+/pla_0.4_fast.curaprofile | 18 --------------- .../ultimaker2+/pla_0.4_high.curaprofile | 16 -------------- .../ultimaker2+/pla_0.4_normal.curaprofile | 16 -------------- .../ultimaker2+/pla_0.4_ulti.curaprofile | 21 ------------------ .../ultimaker2+/pla_0.6_normal.curaprofile | 16 -------------- .../ultimaker2+/pla_0.8_normal.curaprofile | 16 -------------- 28 files changed, 434 deletions(-) delete mode 100644 resources/instances/high_quality.inst.cfg delete mode 100644 resources/instances/normal_quality.inst.cfg delete mode 100644 resources/profiles/general/High+Quality.cfg delete mode 100644 resources/profiles/general/Low+Quality.cfg delete mode 100644 resources/profiles/general/Normal+Quality.cfg delete mode 100644 resources/profiles/general/Ulti+Quality.cfg delete mode 100644 resources/profiles/materials/abs.cfg delete mode 100644 resources/profiles/materials/cpe.cfg delete mode 100644 resources/profiles/materials/pla.cfg delete mode 100644 resources/profiles/ultimaker2+/abs_0.25_normal.curaprofile delete mode 100644 resources/profiles/ultimaker2+/abs_0.4_fast.curaprofile delete mode 100644 resources/profiles/ultimaker2+/abs_0.4_high.curaprofile delete mode 100644 resources/profiles/ultimaker2+/abs_0.4_normal.curaprofile delete mode 100644 resources/profiles/ultimaker2+/abs_0.6_normal.curaprofile delete mode 100644 resources/profiles/ultimaker2+/abs_0.8_normal.curaprofile delete mode 100644 resources/profiles/ultimaker2+/cpe_0.25_normal.curaprofile delete mode 100644 resources/profiles/ultimaker2+/cpe_0.4_fast.curaprofile delete mode 100644 resources/profiles/ultimaker2+/cpe_0.4_high.curaprofile delete mode 100644 resources/profiles/ultimaker2+/cpe_0.4_normal.curaprofile delete mode 100644 resources/profiles/ultimaker2+/cpe_0.6_normal.curaprofile delete mode 100644 resources/profiles/ultimaker2+/cpe_0.8_normal.curaprofile delete mode 100644 resources/profiles/ultimaker2+/pla_0.25_normal.curaprofile delete mode 100644 resources/profiles/ultimaker2+/pla_0.4_fast.curaprofile delete mode 100644 resources/profiles/ultimaker2+/pla_0.4_high.curaprofile delete mode 100644 resources/profiles/ultimaker2+/pla_0.4_normal.curaprofile delete mode 100644 resources/profiles/ultimaker2+/pla_0.4_ulti.curaprofile delete mode 100644 resources/profiles/ultimaker2+/pla_0.6_normal.curaprofile delete mode 100644 resources/profiles/ultimaker2+/pla_0.8_normal.curaprofile diff --git a/resources/instances/high_quality.inst.cfg b/resources/instances/high_quality.inst.cfg deleted file mode 100644 index 2e860cf380..0000000000 --- a/resources/instances/high_quality.inst.cfg +++ /dev/null @@ -1,9 +0,0 @@ -[general] -version = 2 -name = high -definition = fdmprinter - -[metadata] -type = quality - -[values] diff --git a/resources/instances/normal_quality.inst.cfg b/resources/instances/normal_quality.inst.cfg deleted file mode 100644 index 6bb23d841c..0000000000 --- a/resources/instances/normal_quality.inst.cfg +++ /dev/null @@ -1,9 +0,0 @@ -[general] -version = 2 -name = normal -definition = fdmprinter - -[metadata] -type = quality - -[values] diff --git a/resources/profiles/general/High+Quality.cfg b/resources/profiles/general/High+Quality.cfg deleted file mode 100644 index a006c7a995..0000000000 --- a/resources/profiles/general/High+Quality.cfg +++ /dev/null @@ -1,10 +0,0 @@ -[general] -version = 1 -name = High Quality -weight = -3 - -[settings] -layer_height = 0.06 -speed_topbottom = 15 -speed_infill = 80 - diff --git a/resources/profiles/general/Low+Quality.cfg b/resources/profiles/general/Low+Quality.cfg deleted file mode 100644 index f7f4e5d6b7..0000000000 --- a/resources/profiles/general/Low+Quality.cfg +++ /dev/null @@ -1,15 +0,0 @@ -[general] -version = 1 -name = Low Quality -weight = -1 - -[settings] -infill_sparse_density = 10 -layer_height = 0.15 -cool_min_layer_time = 3 -speed_wall_0 = 40 -speed_wall_x = 80 -speed_infill = 100 -wall_thickness = 1 -speed_topbottom = 30 - diff --git a/resources/profiles/general/Normal+Quality.cfg b/resources/profiles/general/Normal+Quality.cfg deleted file mode 100644 index 575c3343e2..0000000000 --- a/resources/profiles/general/Normal+Quality.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 1 -name = Normal Quality -weight = -2 - -[settings] -speed_topbottom = 15 -speed_infill = 80 \ No newline at end of file diff --git a/resources/profiles/general/Ulti+Quality.cfg b/resources/profiles/general/Ulti+Quality.cfg deleted file mode 100644 index 1fa9b6085c..0000000000 --- a/resources/profiles/general/Ulti+Quality.cfg +++ /dev/null @@ -1,9 +0,0 @@ -[general] -version = 1 -name = Ulti Quality -weight = -4 - -[settings] -layer_height = 0.04 -speed_topbottom = 15 -speed_infill = 80 \ No newline at end of file diff --git a/resources/profiles/materials/abs.cfg b/resources/profiles/materials/abs.cfg deleted file mode 100644 index 67abc32810..0000000000 --- a/resources/profiles/materials/abs.cfg +++ /dev/null @@ -1,9 +0,0 @@ -[general] -version = 1 -type = material -name = ABS - -[settings] -material_print_temperature = 250 -material_bed_temperature = 80 -material_flow = 107 diff --git a/resources/profiles/materials/cpe.cfg b/resources/profiles/materials/cpe.cfg deleted file mode 100644 index 0621260745..0000000000 --- a/resources/profiles/materials/cpe.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 1 -type = material -name = CPE - -[settings] -material_print_temperature = 250 -material_bed_temperature = 70 \ No newline at end of file diff --git a/resources/profiles/materials/pla.cfg b/resources/profiles/materials/pla.cfg deleted file mode 100644 index b5af61b9b6..0000000000 --- a/resources/profiles/materials/pla.cfg +++ /dev/null @@ -1,7 +0,0 @@ -[general] -version = 1 -type = material -name = PLA - -[settings] -material_bed_temperature = 60 \ No newline at end of file diff --git a/resources/profiles/ultimaker2+/abs_0.25_normal.curaprofile b/resources/profiles/ultimaker2+/abs_0.25_normal.curaprofile deleted file mode 100644 index 9f45e9d01a..0000000000 --- a/resources/profiles/ultimaker2+/abs_0.25_normal.curaprofile +++ /dev/null @@ -1,20 +0,0 @@ -[general] -version = 1 -name = High Quality -machine_type = ultimaker2plus -machine_variant = 0.25 mm -material = ABS -weight = -2 - -[settings] -layer_height = 0.06 -wall_thickness = 0.88 -top_bottom_thickness = 0.72 -infill_sparse_density = 22 -speed_print = 30 -cool_min_layer_time = 3 -cool_fan_speed_min = 20 -cool_min_speed = 10 -cool_min_layer_time_fan_speed_max = 15 - - diff --git a/resources/profiles/ultimaker2+/abs_0.4_fast.curaprofile b/resources/profiles/ultimaker2+/abs_0.4_fast.curaprofile deleted file mode 100644 index 50018372b5..0000000000 --- a/resources/profiles/ultimaker2+/abs_0.4_fast.curaprofile +++ /dev/null @@ -1,21 +0,0 @@ -[general] -version = 1 -name = Fast Print -machine_type = ultimaker2plus -machine_variant = 0.4 mm -material = ABS -weight = -1 - -[settings] -layer_height = 0.15 -wall_thickness = 0.7 -top_bottom_thickness = 0.75 -infill_sparse_density = 18 -speed_print = 55 -speed_travel = 150 -speed_layer_0 = 30 -cool_min_layer_time = 3 -cool_fan_speed_min = 20 -cool_min_speed = 10 -cool_min_layer_time_fan_speed_max = 15 - diff --git a/resources/profiles/ultimaker2+/abs_0.4_high.curaprofile b/resources/profiles/ultimaker2+/abs_0.4_high.curaprofile deleted file mode 100644 index 341c9cc34f..0000000000 --- a/resources/profiles/ultimaker2+/abs_0.4_high.curaprofile +++ /dev/null @@ -1,19 +0,0 @@ -[general] -version = 1 -name = High Quality -machine_type = ultimaker2plus -machine_variant = 0.4 mm -material = ABS -weight = -3 - -[settings] -layer_height = 0.06 -wall_thickness = 1.05 -top_bottom_thickness = 0.72 -infill_sparse_density = 22 -speed_print = 45 -cool_min_layer_time = 3 -cool_fan_speed_min = 20 -cool_min_speed = 10 -cool_min_layer_time_fan_speed_max = 15 - diff --git a/resources/profiles/ultimaker2+/abs_0.4_normal.curaprofile b/resources/profiles/ultimaker2+/abs_0.4_normal.curaprofile deleted file mode 100644 index d8fce8a4dd..0000000000 --- a/resources/profiles/ultimaker2+/abs_0.4_normal.curaprofile +++ /dev/null @@ -1,18 +0,0 @@ -[general] -version = 1 -name = Normal Quality -machine_type = ultimaker2plus -machine_variant = 0.4 mm -material = ABS -weight = -2 - -[settings] -layer_height = 0.1 -wall_thickness = 1.05 -top_bottom_thickness = 0.8 -infill_sparse_density = 20 -speed_print = 45 -cool_min_layer_time = 3 -cool_fan_speed_min = 20 -cool_min_speed = 10 -cool_min_layer_time_fan_speed_max = 15 diff --git a/resources/profiles/ultimaker2+/abs_0.6_normal.curaprofile b/resources/profiles/ultimaker2+/abs_0.6_normal.curaprofile deleted file mode 100644 index 5512450471..0000000000 --- a/resources/profiles/ultimaker2+/abs_0.6_normal.curaprofile +++ /dev/null @@ -1,20 +0,0 @@ -[general] -version = 1 -name = Normal Quality -machine_type = ultimaker2plus -machine_variant = 0.6 mm -material = ABS -weight = -2 - -[settings] -layer_height = 0.15 -wall_thickness = 1.59 -top_bottom_thickness = 1.2 -infill_sparse_density = 20 -speed_print = 40 -cool_min_layer_time = 3 -cool_fan_speed_min = 50 -cool_min_speed = 20 -cool_min_layer_time_fan_speed_max = 20 - - diff --git a/resources/profiles/ultimaker2+/abs_0.8_normal.curaprofile b/resources/profiles/ultimaker2+/abs_0.8_normal.curaprofile deleted file mode 100644 index e5f27c51a2..0000000000 --- a/resources/profiles/ultimaker2+/abs_0.8_normal.curaprofile +++ /dev/null @@ -1,19 +0,0 @@ -[general] -version = 1 -name = Fast Print -machine_type = ultimaker2plus -machine_variant = 0.8 mm -material = ABS -weight = -2 - -[settings] -layer_height = 0.2 -wall_thickness = 2.1 -top_bottom_thickness = 1.2 -infill_sparse_density = 20 -speed_print = 40 -cool_min_layer_time = 3 -cool_fan_speed_min = 50 -cool_min_speed = 15 -cool_min_layer_time_fan_speed_max = 25 - diff --git a/resources/profiles/ultimaker2+/cpe_0.25_normal.curaprofile b/resources/profiles/ultimaker2+/cpe_0.25_normal.curaprofile deleted file mode 100644 index c4c09932d8..0000000000 --- a/resources/profiles/ultimaker2+/cpe_0.25_normal.curaprofile +++ /dev/null @@ -1,19 +0,0 @@ -[general] -version = 1 -name = High Quality -machine_type = ultimaker2plus -machine_variant = 0.25 mm -material = CPE -weight = -2 - -[settings] -layer_height = 0.06 -wall_thickness = 0.88 -top_bottom_thickness = 0.72 -infill_sparse_density = 22 -speed_print = 30 -cool_min_layer_time = 2 -cool_fan_speed_min = 20 -cool_min_speed = 15 -cool_min_layer_time_fan_speed_max = 15 - diff --git a/resources/profiles/ultimaker2+/cpe_0.4_fast.curaprofile b/resources/profiles/ultimaker2+/cpe_0.4_fast.curaprofile deleted file mode 100644 index f9050e5ce5..0000000000 --- a/resources/profiles/ultimaker2+/cpe_0.4_fast.curaprofile +++ /dev/null @@ -1,22 +0,0 @@ -[general] -version = 1 -name = Fast Print -machine_type = ultimaker2plus -machine_variant = 0.4 mm -material = CPE -weight = -1 - -[settings] -layer_height = 0.15 -wall_thickness = 0.7 -top_bottom_thickness = 0.75 -infill_sparse_density = 18 -speed_print = 45 -speed_travel = 150 -speed_layer_0 = 30 -cool_min_layer_time = 3 -cool_fan_speed_min = 80 -cool_min_speed = 10 -cool_min_layer_time_fan_speed_max = 15 - - diff --git a/resources/profiles/ultimaker2+/cpe_0.4_high.curaprofile b/resources/profiles/ultimaker2+/cpe_0.4_high.curaprofile deleted file mode 100644 index 377ab5b257..0000000000 --- a/resources/profiles/ultimaker2+/cpe_0.4_high.curaprofile +++ /dev/null @@ -1,18 +0,0 @@ -[general] -version = 1 -name = High Quality -machine_type = ultimaker2plus -machine_variant = 0.4 mm -material = CPE -weight = -3 - -[settings] -layer_height = 0.06 -wall_thickness = 1.05 -top_bottom_thickness = 0.72 -infill_sparse_density = 22 -speed_print = 45 -cool_min_layer_time = 2 -cool_fan_speed_min = 80 -cool_min_speed = 15 -cool_min_layer_time_fan_speed_max = 15 diff --git a/resources/profiles/ultimaker2+/cpe_0.4_normal.curaprofile b/resources/profiles/ultimaker2+/cpe_0.4_normal.curaprofile deleted file mode 100644 index e8142405ff..0000000000 --- a/resources/profiles/ultimaker2+/cpe_0.4_normal.curaprofile +++ /dev/null @@ -1,19 +0,0 @@ -[general] -version = 1 -name = Normal Quality -machine_type = ultimaker2plus -machine_variant = 0.4 mm -material = CPE -weight = -2 - -[settings] -layer_height = 0.1 -wall_thickness = 1.05 -top_bottom_thickness = 0.8 -infill_sparse_density = 20 -speed_print = 45 -cool_min_layer_time = 3 -cool_fan_speed_min = 80 -cool_min_speed = 10 -cool_min_layer_time_fan_speed_max = 15 - diff --git a/resources/profiles/ultimaker2+/cpe_0.6_normal.curaprofile b/resources/profiles/ultimaker2+/cpe_0.6_normal.curaprofile deleted file mode 100644 index 034fa17e1b..0000000000 --- a/resources/profiles/ultimaker2+/cpe_0.6_normal.curaprofile +++ /dev/null @@ -1,18 +0,0 @@ -[general] -version = 1 -name = Normal Quality -machine_type = ultimaker2plus -machine_variant = 0.6 mm -material = CPE -weight = -2 - -[settings] -layer_height = 0.15 -wall_thickness = 1.59 -top_bottom_thickness = 1.2 -infill_sparse_density = 20 -speed_print = 40 -cool_min_layer_time = 5 -cool_fan_speed_min = 80 -cool_min_speed = 8 -cool_min_layer_time_fan_speed_max = 20 diff --git a/resources/profiles/ultimaker2+/cpe_0.8_normal.curaprofile b/resources/profiles/ultimaker2+/cpe_0.8_normal.curaprofile deleted file mode 100644 index 523a5d3243..0000000000 --- a/resources/profiles/ultimaker2+/cpe_0.8_normal.curaprofile +++ /dev/null @@ -1,18 +0,0 @@ -[general] -version = 1 -name = Fast Print -machine_type = ultimaker2plus -machine_variant = 0.8 mm -material = CPE -weight = -2 - -[settings] -layer_height = 0.2 -wall_thickness = 2.1 -top_bottom_thickness = 1.2 -infill_sparse_density = 20 -speed_print = 40 -cool_min_layer_time = 3 -cool_fan_speed_min = 80 -cool_min_speed = 8 -cool_min_layer_time_fan_speed_max = 25 diff --git a/resources/profiles/ultimaker2+/pla_0.25_normal.curaprofile b/resources/profiles/ultimaker2+/pla_0.25_normal.curaprofile deleted file mode 100644 index 63c1fc9fdd..0000000000 --- a/resources/profiles/ultimaker2+/pla_0.25_normal.curaprofile +++ /dev/null @@ -1,16 +0,0 @@ -[general] -version = 1 -name = High Quality -machine_type = ultimaker2plus -machine_variant = 0.25 mm -material = PLA -weight = -2 - -[settings] -layer_height = 0.06 -wall_thickness = 0.88 -top_bottom_thickness = 0.72 -infill_sparse_density = 22 -speed_print = 30 -cool_min_layer_time = 5 -cool_min_speed = 10 diff --git a/resources/profiles/ultimaker2+/pla_0.4_fast.curaprofile b/resources/profiles/ultimaker2+/pla_0.4_fast.curaprofile deleted file mode 100644 index 06e401c139..0000000000 --- a/resources/profiles/ultimaker2+/pla_0.4_fast.curaprofile +++ /dev/null @@ -1,18 +0,0 @@ -[general] -version = 1 -name = Fast Print -machine_type = ultimaker2plus -machine_variant = 0.4 mm -material = PLA -weight = -1 - -[settings] -layer_height = 0.15 -wall_thickness = 0.7 -top_bottom_thickness = 0.75 -infill_sparse_density = 18 -speed_print = 60 -speed_travel = 150 -speed_layer_0 = 30 -cool_min_layer_time = 5 -cool_min_speed = 10 diff --git a/resources/profiles/ultimaker2+/pla_0.4_high.curaprofile b/resources/profiles/ultimaker2+/pla_0.4_high.curaprofile deleted file mode 100644 index 5e2f762354..0000000000 --- a/resources/profiles/ultimaker2+/pla_0.4_high.curaprofile +++ /dev/null @@ -1,16 +0,0 @@ -[general] -version = 1 -name = High Quality -machine_type = ultimaker2plus -machine_variant = 0.4 mm -material = PLA -weight = -3 - -[settings] -layer_height = 0.06 -wall_thickness = 1.05 -top_bottom_thickness = 0.72 -infill_sparse_density = 22 -speed_print = 50 -cool_min_layer_time = 5 -cool_min_speed = 10 diff --git a/resources/profiles/ultimaker2+/pla_0.4_normal.curaprofile b/resources/profiles/ultimaker2+/pla_0.4_normal.curaprofile deleted file mode 100644 index 689a3251b2..0000000000 --- a/resources/profiles/ultimaker2+/pla_0.4_normal.curaprofile +++ /dev/null @@ -1,16 +0,0 @@ -[general] -version = 1 -name = Normal Quality -machine_type = ultimaker2plus -machine_variant = 0.4 mm -material = PLA -weight = -2 - -[settings] -layer_height = 0.1 -wall_thickness = 1.05 -top_bottom_thickness = 0.8 -infill_sparse_density = 20 -speed_print = 50 -cool_min_layer_time = 5 -cool_min_speed = 10 diff --git a/resources/profiles/ultimaker2+/pla_0.4_ulti.curaprofile b/resources/profiles/ultimaker2+/pla_0.4_ulti.curaprofile deleted file mode 100644 index db091d8e8d..0000000000 --- a/resources/profiles/ultimaker2+/pla_0.4_ulti.curaprofile +++ /dev/null @@ -1,21 +0,0 @@ -[general] -version = 1 -name = Ulti Quality -machine_type = ultimaker2plus -machine_variant = 0.4 mm -material = PLA -weight = -4 - -[settings] -line_width = 0.35 -layer_height = 0.04 -layer_height_0 = 0.26 -wall_thickness = 1.4 -top_bottom_thickness = 1.12 -infill_sparse_density = 25 -speed_print = 30 -speed_infill = 50 -speed_wall_x = 40 -speed_topbottom = 20 -speed_layer_0 = 25 -cool_min_layer_time_fan_speed_max = 15 diff --git a/resources/profiles/ultimaker2+/pla_0.6_normal.curaprofile b/resources/profiles/ultimaker2+/pla_0.6_normal.curaprofile deleted file mode 100644 index 188ed42a95..0000000000 --- a/resources/profiles/ultimaker2+/pla_0.6_normal.curaprofile +++ /dev/null @@ -1,16 +0,0 @@ -[general] -version = 1 -name = Normal Quality -machine_type = ultimaker2plus -machine_variant = 0.6 mm -material = PLA -weight = -2 - -[settings] -layer_height = 0.15 -wall_thickness = 1.59 -top_bottom_thickness = 1.2 -infill_sparse_density = 20 -speed_print = 55 -cool_min_layer_time = 5 -cool_min_speed = 10 diff --git a/resources/profiles/ultimaker2+/pla_0.8_normal.curaprofile b/resources/profiles/ultimaker2+/pla_0.8_normal.curaprofile deleted file mode 100644 index 92cb4a6054..0000000000 --- a/resources/profiles/ultimaker2+/pla_0.8_normal.curaprofile +++ /dev/null @@ -1,16 +0,0 @@ -[general] -version = 1 -name = Fast Print -machine_type = ultimaker2plus -machine_variant = 0.8 mm -material = PLA -weight = -2 - -[settings] -layer_height = 0.2 -wall_thickness = 2.1 -top_bottom_thickness = 1.2 -infill_sparse_density = 20 -speed_print = 40 -cool_min_layer_time = 5 -cool_min_speed = 10 From 3413334c6d0b8409307c5d234fbaf65f79c9eb66 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Sat, 4 Jun 2016 21:17:27 +0200 Subject: [PATCH 429/705] Update active material/quality when changing one of the lower levels Contributes to CURA-1612 --- cura/MachineManagerModel.py | 119 ++++++++++++++++++++---------------- 1 file changed, 67 insertions(+), 52 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 609d2a77f8..24020f50a4 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -104,50 +104,9 @@ class MachineManagerModel(QObject): new_global_stack.addMetaDataEntry("type", "machine") UM.Settings.ContainerRegistry.getInstance().addContainer(new_global_stack) - variant_instance_container = self._empty_variant_container - if definition.getMetaDataEntry("has_variants"): - variant_instance_container = self._getPreferredContainer(definition, "preferred_variant", self._empty_variant_container) - - if variant_instance_container == self._empty_variant_container: - variants = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = definition.id) - if variants: - variant_instance_container = variants[0] - - if variant_instance_container == self._empty_variant_container: - Logger.log("w", "Machine %s defines it has variants but no variants found", definition.id) - - material_instance_container = self._empty_material_container - if definition.getMetaDataEntry("has_materials"): - material_instance_container = self._getPreferredContainer(definition, "preferred_material", self._empty_material_container) - - if material_instance_container == self._empty_material_container: - materials = None - if definition.getMetaDataEntry("has_machine_materials"): - if variant_instance_container != self._empty_material_container: - materials = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "material", definition = definition.id, variant = variant_instance_container.id) - else: - materials = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "material", definition = definition.id) - else: - materials = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "material", definition = "fdmprinter") - - if materials: - material_instance_container = materials[0] - - if material_instance_container == self._empty_material_container: - Logger.log("w", "Machine %s defines it has materials but no matererials found", definition.id) - - quality_instance_container = self._getPreferredContainer(definition, "preferred_quality", self._empty_quality_container) - if quality_instance_container == self._empty_quality_container: - if definition.getMetaDataEntry("has_machine_quality"): - if material_instance_container: - qualities = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "quality", definition = definition.id, material = material_instance_container.id) - else: - qualities = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "quality", definition = definition.id) - else: - qualities = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "quality", definition = "fdmprinter") - - if qualities: - quality_instance_container = qualities[0] + variant_instance_container = self._updateVariantContainer(definition) + material_instance_container = self._updateMaterialContainer(definition) + quality_instance_container = self._updateQualityContainer(definition) current_settings_instance_container = UM.Settings.InstanceContainer(name + "_current_settings") current_settings_instance_container.addMetaDataEntry("machine", name) @@ -341,6 +300,8 @@ class MachineManagerModel(QObject): material_index = self._global_container_stack.getContainerIndex(old_material) self._global_container_stack.replaceContainer(material_index, containers[0]) + self.setActiveQuality(self._updateQualityContainer(self._global_container_stack.getBottom(), containers[0]).id) + @pyqtSlot(str) def setActiveVariant(self, variant_id): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=variant_id) @@ -352,6 +313,8 @@ class MachineManagerModel(QObject): variant_index = self._global_container_stack.getContainerIndex(old_variant) self._global_container_stack.replaceContainer(variant_index, containers[0]) + self.setActiveMaterial(self._updateMaterialContainer(self._global_container_stack.getBottom(), containers[0]).id) + @pyqtSlot(str) def setActiveQuality(self, quality_id): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = quality_id) @@ -435,15 +398,67 @@ class MachineManagerModel(QObject): return False - def _getPreferredContainer(self, definition, property_name, default_container): - preferred_id = definition.getMetaDataEntry(property_name) - if preferred_id: - preferred_id = preferred_id.lower() - container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = preferred_id) - if container: - return container[0] + def _updateVariantContainer(self, definition): + if not definition.getMetaDataEntry("has_variants"): + return self._empty_variant_container - return default_container + containers = [] + preferred_variant = definition.getMetaDataEntry("preferred_variant") + if preferred_variant: + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = definition.id, id = preferred_variant) + + if not containers: + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = definition.id) + + if containers: + return containers[0] + + return self._empty_variant_container + + def _updateMaterialContainer(self, definition, variant_container): + if not definition.getMetaDataEntry("has_materials"): + return self._empty_material_container + + search_criteria = { "type": "material" } + + if definition.getMetaDataEntry("has_machine_materials"): + search_criteria["definition"] = definition.id + + if definition.getMetaDataEntry("has_variants") and variant_container: + search_criteria["variant"] = variant_container.id + else: + search_criteria["definition"] = "fdmprinter" + + preferred_material = definition.getMetaDataEntry("preferred_material") + if preferred_material: + search_criteria["id"] = preferred_material + + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**search_criteria) + if containers: + return containers[0] + + return self._empty_material_container + + def _updateQualityContainer(self, definition, material_container): + search_criteria = { "type": "quality" } + + if definition.getMetaDataEntry("has_machine_quality"): + search_criteria["definition"] = definition.id + + if definition.getMetaDataEntry("has_materials") and material_container: + search_criteria["material"] = material_container.id + else: + search_criteria["definition"] = "fdmprinter" + + preferred_quality = definition.getMetaDataEntry("preferred_quality") + if preferred_quality: + search_criteria["id"] = preferred_quality + + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**search_criteria) + if containers: + return containers[0] + + return self._empty_quality_container def createMachineManagerModel(engine, script_engine): return MachineManagerModel() From 65a563027de5b8dad9c5b4edba766a2ee33c7ba8 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Sat, 4 Jun 2016 21:19:05 +0200 Subject: [PATCH 430/705] Specify preferred material/quality as wildcards This way it becomes a lot simpler to match them Contributes to CURA-1612 --- resources/definitions/ultimaker2_plus.def.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/definitions/ultimaker2_plus.def.json b/resources/definitions/ultimaker2_plus.def.json index 75501fb158..b29f904095 100644 --- a/resources/definitions/ultimaker2_plus.def.json +++ b/resources/definitions/ultimaker2_plus.def.json @@ -12,8 +12,8 @@ "platform": "ultimaker2_platform.obj", "platform_texture": "Ultimaker2Plusbackplate.png", "preferred_variant": "ultimaker2_plus_0.4", - "preferred_material": "generic_pla_ultimaker2_plus_0.4mm", - "preferred_quality": "pla_0.4_normal", + "preferred_material": "*pla*", + "preferred_quality": "*normal*", "has_variants": true, "has_materials": true, "has_machine_materials": true, From e0ebe960acc9e0d8d9eea9448d3df82909c8ff03 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Sat, 4 Jun 2016 21:19:29 +0200 Subject: [PATCH 431/705] Update standard quality profiles Contributes to CURA-1612 --- resources/quality/high.inst.cfg | 2 ++ resources/quality/low.inst.cfg | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/resources/quality/high.inst.cfg b/resources/quality/high.inst.cfg index 546d11326b..86df9dab92 100644 --- a/resources/quality/high.inst.cfg +++ b/resources/quality/high.inst.cfg @@ -9,3 +9,5 @@ read_only = True [values] layer_height = 0.06 +speed_topbottom = 15 +speed_infill = 80 diff --git a/resources/quality/low.inst.cfg b/resources/quality/low.inst.cfg index 11a0094aca..6cebc46dd5 100644 --- a/resources/quality/low.inst.cfg +++ b/resources/quality/low.inst.cfg @@ -8,4 +8,11 @@ type = quality read_only = True [values] +infill_sparse_density = 10 layer_height = 0.15 +cool_min_layer_time = 3 +speed_wall_0 = 40 +speed_wall_x = 80 +speed_infill = 100 +wall_thickness = 1 +speed_topbottom = 30 From 312097c523fe81ea51913698517b9c319ba792b5 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Sat, 4 Jun 2016 21:21:24 +0200 Subject: [PATCH 432/705] Specify UMO as having materials Contributes to CURA-1612 --- resources/definitions/ultimaker_original.def.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/resources/definitions/ultimaker_original.def.json b/resources/definitions/ultimaker_original.def.json index 1dbdb95d8c..55668946a0 100644 --- a/resources/definitions/ultimaker_original.def.json +++ b/resources/definitions/ultimaker_original.def.json @@ -11,6 +11,9 @@ "file_formats": "text/x-gcode", "icon": "icon_ultimaker.png", "platform": "ultimaker_platform.stl", + "has_materials": true, + "preferred_material": "*pla*", + "preferred_quality": "*normal*", "pages": [ "SelectUpgradedParts", "UpgradeFirmware", From 2d77ddada41915cc410f731230e229e8d518a434 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Sat, 4 Jun 2016 21:21:57 +0200 Subject: [PATCH 433/705] Add ABS/CPE quality profiles for UM2(E)+ Contributes to CURA-1612 --- .../um2ep_abs_0.25_normal.inst.cfg | 23 +++++++++++++++++ .../um2ep_abs_0.4_fast.inst.cfg | 24 ++++++++++++++++++ .../um2ep_abs_0.4_high.inst.cfg | 22 ++++++++++++++++ .../um2ep_abs_0.4_normal.inst.cfg | 21 ++++++++++++++++ .../um2ep_abs_0.6_normal.inst.cfg | 23 +++++++++++++++++ .../um2ep_abs_0.8_normal.inst.cfg | 22 ++++++++++++++++ .../um2ep_cpe_0.25_normal.inst.cfg | 22 ++++++++++++++++ .../um2ep_cpe_0.4_fast.inst.cfg | 25 +++++++++++++++++++ .../um2ep_cpe_0.4_high.inst.cfg | 21 ++++++++++++++++ .../um2ep_cpe_0.4_normal.inst.cfg | 22 ++++++++++++++++ .../um2ep_cpe_0.6_normal.inst.cfg | 21 ++++++++++++++++ .../um2ep_cpe_0.8_normal.inst.cfg | 21 ++++++++++++++++ .../um2p_abs_0.25_normal.inst.cfg | 23 +++++++++++++++++ .../um2p_abs_0.4_fast.inst.cfg | 24 ++++++++++++++++++ .../um2p_abs_0.4_high.inst.cfg | 22 ++++++++++++++++ .../um2p_abs_0.4_normal.inst.cfg | 21 ++++++++++++++++ .../um2p_abs_0.6_normal.inst.cfg | 23 +++++++++++++++++ .../um2p_abs_0.8_normal.inst.cfg | 22 ++++++++++++++++ .../um2p_cpe_0.25_normal.inst.cfg | 22 ++++++++++++++++ .../um2p_cpe_0.4_fast.inst.cfg | 25 +++++++++++++++++++ .../um2p_cpe_0.4_high.inst.cfg | 21 ++++++++++++++++ .../um2p_cpe_0.4_normal.inst.cfg | 22 ++++++++++++++++ .../um2p_cpe_0.6_normal.inst.cfg | 21 ++++++++++++++++ .../um2p_cpe_0.8_normal.inst.cfg | 21 ++++++++++++++++ 24 files changed, 534 insertions(+) create mode 100644 resources/quality/ultimaker2_extended_plus/um2ep_abs_0.25_normal.inst.cfg create mode 100644 resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg create mode 100644 resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg create mode 100644 resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg create mode 100644 resources/quality/ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg create mode 100644 resources/quality/ultimaker2_extended_plus/um2ep_abs_0.8_normal.inst.cfg create mode 100644 resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.25_normal.inst.cfg create mode 100644 resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg create mode 100644 resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg create mode 100644 resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg create mode 100644 resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.6_normal.inst.cfg create mode 100644 resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.8_normal.inst.cfg create mode 100644 resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg create mode 100644 resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg create mode 100644 resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg create mode 100644 resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg create mode 100644 resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg create mode 100644 resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg create mode 100644 resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg create mode 100644 resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg create mode 100644 resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg create mode 100644 resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg create mode 100644 resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg create mode 100644 resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.25_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.25_normal.inst.cfg new file mode 100644 index 0000000000..07d3fae601 --- /dev/null +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.25_normal.inst.cfg @@ -0,0 +1,23 @@ +[general] +version = 2 +name = High Quality +definition = ultimaker2_extended_plus + +[metadata] +type = quality +material = generic_abs_ultimaker2_extended_plus_0.25_mm +weight = -2 +read_only = True + +[values] +layer_height = 0.06 +wall_thickness = 0.88 +top_bottom_thickness = 0.72 +infill_sparse_density = 22 +speed_print = 30 +cool_min_layer_time = 3 +cool_fan_speed_min = 20 +cool_min_speed = 10 +cool_min_layer_time_fan_speed_max = 15 + + diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg new file mode 100644 index 0000000000..f554c7f058 --- /dev/null +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg @@ -0,0 +1,24 @@ +[general] +version = 2 +name = Fast Print +definition = ultimaker2_extended_plus + +[metadata] +type = quality +material = generic_abs_ultimaker2_extended_plus_0.4_mm +weight = -1 +read_only = True + +[values] +layer_height = 0.15 +wall_thickness = 0.7 +top_bottom_thickness = 0.75 +infill_sparse_density = 18 +speed_print = 55 +speed_travel = 150 +speed_layer_0 = 30 +cool_min_layer_time = 3 +cool_fan_speed_min = 20 +cool_min_speed = 10 +cool_min_layer_time_fan_speed_max = 15 + diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg new file mode 100644 index 0000000000..c1a8136cf5 --- /dev/null +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg @@ -0,0 +1,22 @@ +[general] +version = 2 +name = High Quality +definition = ultimaker2_extended_plus + +[metadata] +type = quality +material = generic_abs_ultimaker2_extended_plus_0.4_mm +weight = -3 +read_only = True + +[values] +layer_height = 0.06 +wall_thickness = 1.05 +top_bottom_thickness = 0.72 +infill_sparse_density = 22 +speed_print = 45 +cool_min_layer_time = 3 +cool_fan_speed_min = 20 +cool_min_speed = 10 +cool_min_layer_time_fan_speed_max = 15 + diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg new file mode 100644 index 0000000000..eabc9827a1 --- /dev/null +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg @@ -0,0 +1,21 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_extended_plus + +[metadata] +type = quality +material = generic_abs_ultimaker2_extended_plus_0.4_mm +weight = -2 +read_only = True + +[values] +layer_height = 0.1 +wall_thickness = 1.05 +top_bottom_thickness = 0.8 +infill_sparse_density = 20 +speed_print = 45 +cool_min_layer_time = 3 +cool_fan_speed_min = 20 +cool_min_speed = 10 +cool_min_layer_time_fan_speed_max = 15 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg new file mode 100644 index 0000000000..64e0ec72fb --- /dev/null +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg @@ -0,0 +1,23 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_extended_plus + +[metadata] +type = quality +material = generic_abs_ultimaker2_extended_plus_0.6_mm +weight = -2 +read_only = True + +[values] +layer_height = 0.15 +wall_thickness = 1.59 +top_bottom_thickness = 1.2 +infill_sparse_density = 20 +speed_print = 40 +cool_min_layer_time = 3 +cool_fan_speed_min = 50 +cool_min_speed = 20 +cool_min_layer_time_fan_speed_max = 20 + + diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.8_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.8_normal.inst.cfg new file mode 100644 index 0000000000..8857db6cc1 --- /dev/null +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.8_normal.inst.cfg @@ -0,0 +1,22 @@ +[general] +version = 2 +name = Fast Print +definition = ultimaker2_extended_plus + +[metadata] +type = quality +material = generic_abs_ultimaker2_extended_plus_0.8_mm +weight = -2 +read_only = True + +[values] +layer_height = 0.2 +wall_thickness = 2.1 +top_bottom_thickness = 1.2 +infill_sparse_density = 20 +speed_print = 40 +cool_min_layer_time = 3 +cool_fan_speed_min = 50 +cool_min_speed = 15 +cool_min_layer_time_fan_speed_max = 25 + diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.25_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.25_normal.inst.cfg new file mode 100644 index 0000000000..d34ea88798 --- /dev/null +++ b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.25_normal.inst.cfg @@ -0,0 +1,22 @@ +[general] +version = 2 +name = High Quality +definition = ultimaker2_extended_plus + +[metadata] +type = quality +material = generic_cpe_ultimaker2_extended_plus_0.25_mm +weight = -2 +read_only = True + +[values] +layer_height = 0.06 +wall_thickness = 0.88 +top_bottom_thickness = 0.72 +infill_sparse_density = 22 +speed_print = 30 +cool_min_layer_time = 2 +cool_fan_speed_min = 20 +cool_min_speed = 15 +cool_min_layer_time_fan_speed_max = 15 + diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg new file mode 100644 index 0000000000..ae9b437010 --- /dev/null +++ b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg @@ -0,0 +1,25 @@ +[general] +version = 2 +name = Fast Print +definition = ultimaker2_extended_plus + +[metadata] +type = quality +material = generic_cpe_ultimaker2_extended_plus_0.4_mm +weight = -1 +read_only = True + +[values] +layer_height = 0.15 +wall_thickness = 0.7 +top_bottom_thickness = 0.75 +infill_sparse_density = 18 +speed_print = 45 +speed_travel = 150 +speed_layer_0 = 30 +cool_min_layer_time = 3 +cool_fan_speed_min = 80 +cool_min_speed = 10 +cool_min_layer_time_fan_speed_max = 15 + + diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg new file mode 100644 index 0000000000..e3fa254a74 --- /dev/null +++ b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg @@ -0,0 +1,21 @@ +[general] +version = 2 +name = High Quality +definition = ultimaker2_extended_plus + +[metadata] +type = quality +material = generic_cpe_ultimaker2_extended_plus_0.4_mm +weight = -3 +read_only = True + +[values] +layer_height = 0.06 +wall_thickness = 1.05 +top_bottom_thickness = 0.72 +infill_sparse_density = 22 +speed_print = 45 +cool_min_layer_time = 2 +cool_fan_speed_min = 80 +cool_min_speed = 15 +cool_min_layer_time_fan_speed_max = 15 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg new file mode 100644 index 0000000000..48e767e1cb --- /dev/null +++ b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg @@ -0,0 +1,22 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_extended_plus + +[metadata] +type = quality +material = generic_cpe_ultimaker2_extended_plus_0.4_mm +weight = -2 +read_only = True + +[values] +layer_height = 0.1 +wall_thickness = 1.05 +top_bottom_thickness = 0.8 +infill_sparse_density = 20 +speed_print = 45 +cool_min_layer_time = 3 +cool_fan_speed_min = 80 +cool_min_speed = 10 +cool_min_layer_time_fan_speed_max = 15 + diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.6_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.6_normal.inst.cfg new file mode 100644 index 0000000000..675c949364 --- /dev/null +++ b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.6_normal.inst.cfg @@ -0,0 +1,21 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_extended_plus + +[metadata] +type = quality +material = generic_cpe_ultimaker2_extended_plus_0.6_mm +weight = -2 +read_only = True + +[values] +layer_height = 0.15 +wall_thickness = 1.59 +top_bottom_thickness = 1.2 +infill_sparse_density = 20 +speed_print = 40 +cool_min_layer_time = 5 +cool_fan_speed_min = 80 +cool_min_speed = 8 +cool_min_layer_time_fan_speed_max = 20 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.8_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.8_normal.inst.cfg new file mode 100644 index 0000000000..b631baea42 --- /dev/null +++ b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.8_normal.inst.cfg @@ -0,0 +1,21 @@ +[general] +version = 2 +name = Fast Print +definition = ultimaker2_extended_plus + +[metadata] +type = quality +material = generic_cpe_ultimaker2_extended_plus_0.8_mm +weight = -2 +read_only = True + +[values] +layer_height = 0.2 +wall_thickness = 2.1 +top_bottom_thickness = 1.2 +infill_sparse_density = 20 +speed_print = 40 +cool_min_layer_time = 3 +cool_fan_speed_min = 80 +cool_min_speed = 8 +cool_min_layer_time_fan_speed_max = 25 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg new file mode 100644 index 0000000000..0b7a371ff1 --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg @@ -0,0 +1,23 @@ +[general] +version = 2 +name = High Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_abs_ultimaker2_plus_0.25_mm +weight = -2 +read_only = True + +[values] +layer_height = 0.06 +wall_thickness = 0.88 +top_bottom_thickness = 0.72 +infill_sparse_density = 22 +speed_print = 30 +cool_min_layer_time = 3 +cool_fan_speed_min = 20 +cool_min_speed = 10 +cool_min_layer_time_fan_speed_max = 15 + + diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg new file mode 100644 index 0000000000..e9593b10a7 --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg @@ -0,0 +1,24 @@ +[general] +version = 2 +name = Fast Print +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_abs_ultimaker2_plus_0.4_mm +weight = -1 +read_only = True + +[values] +layer_height = 0.15 +wall_thickness = 0.7 +top_bottom_thickness = 0.75 +infill_sparse_density = 18 +speed_print = 55 +speed_travel = 150 +speed_layer_0 = 30 +cool_min_layer_time = 3 +cool_fan_speed_min = 20 +cool_min_speed = 10 +cool_min_layer_time_fan_speed_max = 15 + diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg new file mode 100644 index 0000000000..2bd3b4fa1a --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg @@ -0,0 +1,22 @@ +[general] +version = 2 +name = High Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_abs_ultimaker2_plus_0.4_mm +weight = -3 +read_only = True + +[values] +layer_height = 0.06 +wall_thickness = 1.05 +top_bottom_thickness = 0.72 +infill_sparse_density = 22 +speed_print = 45 +cool_min_layer_time = 3 +cool_fan_speed_min = 20 +cool_min_speed = 10 +cool_min_layer_time_fan_speed_max = 15 + diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg new file mode 100644 index 0000000000..34bb28d20a --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg @@ -0,0 +1,21 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_abs_ultimaker2_plus_0.4_mm +weight = -2 +read_only = True + +[values] +layer_height = 0.1 +wall_thickness = 1.05 +top_bottom_thickness = 0.8 +infill_sparse_density = 20 +speed_print = 45 +cool_min_layer_time = 3 +cool_fan_speed_min = 20 +cool_min_speed = 10 +cool_min_layer_time_fan_speed_max = 15 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg new file mode 100644 index 0000000000..2c4656a4d9 --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg @@ -0,0 +1,23 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_abs_ultimaker2_plus_0.6_mm +weight = -2 +read_only = True + +[values] +layer_height = 0.15 +wall_thickness = 1.59 +top_bottom_thickness = 1.2 +infill_sparse_density = 20 +speed_print = 40 +cool_min_layer_time = 3 +cool_fan_speed_min = 50 +cool_min_speed = 20 +cool_min_layer_time_fan_speed_max = 20 + + diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg new file mode 100644 index 0000000000..d5b9557ebb --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg @@ -0,0 +1,22 @@ +[general] +version = 2 +name = Fast Print +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_abs_ultimaker2_plus_0.8_mm +weight = -2 +read_only = True + +[values] +layer_height = 0.2 +wall_thickness = 2.1 +top_bottom_thickness = 1.2 +infill_sparse_density = 20 +speed_print = 40 +cool_min_layer_time = 3 +cool_fan_speed_min = 50 +cool_min_speed = 15 +cool_min_layer_time_fan_speed_max = 25 + diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg new file mode 100644 index 0000000000..eaab2ff2b6 --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg @@ -0,0 +1,22 @@ +[general] +version = 2 +name = High Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_cpe_ultimaker2_plus_0.25_mm +weight = -2 +read_only = True + +[values] +layer_height = 0.06 +wall_thickness = 0.88 +top_bottom_thickness = 0.72 +infill_sparse_density = 22 +speed_print = 30 +cool_min_layer_time = 2 +cool_fan_speed_min = 20 +cool_min_speed = 15 +cool_min_layer_time_fan_speed_max = 15 + diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg new file mode 100644 index 0000000000..e20f5ec96b --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg @@ -0,0 +1,25 @@ +[general] +version = 2 +name = Fast Print +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_cpe_ultimaker2_plus_0.4_mm +weight = -1 +read_only = True + +[values] +layer_height = 0.15 +wall_thickness = 0.7 +top_bottom_thickness = 0.75 +infill_sparse_density = 18 +speed_print = 45 +speed_travel = 150 +speed_layer_0 = 30 +cool_min_layer_time = 3 +cool_fan_speed_min = 80 +cool_min_speed = 10 +cool_min_layer_time_fan_speed_max = 15 + + diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg new file mode 100644 index 0000000000..9b64b5580c --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg @@ -0,0 +1,21 @@ +[general] +version = 2 +name = High Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_cpe_ultimaker2_plus_0.4_mm +weight = -3 +read_only = True + +[values] +layer_height = 0.06 +wall_thickness = 1.05 +top_bottom_thickness = 0.72 +infill_sparse_density = 22 +speed_print = 45 +cool_min_layer_time = 2 +cool_fan_speed_min = 80 +cool_min_speed = 15 +cool_min_layer_time_fan_speed_max = 15 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg new file mode 100644 index 0000000000..6ec06e1fb9 --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg @@ -0,0 +1,22 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_cpe_ultimaker2_plus_0.4_mm +weight = -2 +read_only = True + +[values] +layer_height = 0.1 +wall_thickness = 1.05 +top_bottom_thickness = 0.8 +infill_sparse_density = 20 +speed_print = 45 +cool_min_layer_time = 3 +cool_fan_speed_min = 80 +cool_min_speed = 10 +cool_min_layer_time_fan_speed_max = 15 + diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg new file mode 100644 index 0000000000..f19032a95e --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg @@ -0,0 +1,21 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_cpe_ultimaker2_plus_0.6_mm +weight = -2 +read_only = True + +[values] +layer_height = 0.15 +wall_thickness = 1.59 +top_bottom_thickness = 1.2 +infill_sparse_density = 20 +speed_print = 40 +cool_min_layer_time = 5 +cool_fan_speed_min = 80 +cool_min_speed = 8 +cool_min_layer_time_fan_speed_max = 20 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg new file mode 100644 index 0000000000..45372fdf39 --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg @@ -0,0 +1,21 @@ +[general] +version = 2 +name = Fast Print +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_cpe_ultimaker2_plus_0.8_mm +weight = -2 +read_only = True + +[values] +layer_height = 0.2 +wall_thickness = 2.1 +top_bottom_thickness = 1.2 +infill_sparse_density = 20 +speed_print = 40 +cool_min_layer_time = 3 +cool_fan_speed_min = 80 +cool_min_speed = 8 +cool_min_layer_time_fan_speed_max = 25 From 0a9382aa114d1315c8b701f4448278ac61f309af Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Sat, 4 Jun 2016 21:22:21 +0200 Subject: [PATCH 434/705] Fix exclusiveGroup for machine selection in the menu Contributes to CURA-1278 --- resources/qml/Cura.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 2b7a4ccea7..851e7c984f 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -178,7 +178,7 @@ UM.MainWindow text: model.name; checkable: true; checked: Cura.MachineManager.activeMachineId == model.id - exclusiveGroup: machineSelectionMenuGroup; + exclusiveGroup: machineMenuGroup; onTriggered: Cura.MachineManager.setActiveMachine(model.id); } onObjectAdded: machineMenu.insertItem(index, object) From 2f3352bfa0cc38675230f05a0b2cece1d5759b5a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Sun, 5 Jun 2016 10:45:47 +0200 Subject: [PATCH 435/705] Added default values when adding variant & materials CURA-1612 --- cura/MachineManagerModel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 24020f50a4..3e4c7a0411 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -415,7 +415,7 @@ class MachineManagerModel(QObject): return self._empty_variant_container - def _updateMaterialContainer(self, definition, variant_container): + def _updateMaterialContainer(self, definition, variant_container = None): if not definition.getMetaDataEntry("has_materials"): return self._empty_material_container @@ -439,7 +439,7 @@ class MachineManagerModel(QObject): return self._empty_material_container - def _updateQualityContainer(self, definition, material_container): + def _updateQualityContainer(self, definition, material_container = None): search_criteria = { "type": "quality" } if definition.getMetaDataEntry("has_machine_quality"): From d6acb78bd4c310b5ded6180e6cc17394872672a6 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Sun, 5 Jun 2016 09:59:57 +0100 Subject: [PATCH 436/705] Fixing a typo Had that change locally here, but for a reason I forgot to commit that fix. Oops.. --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index ac95529a5d..8668a746fb 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -90,7 +90,7 @@ class CuraApplication(QtApplication): # Need to do this before ContainerRegistry tries to load the machines SettingDefinition.addSupportedProperty("global_only", DefinitionPropertyType.Function, default = False) - super().__init__(name = "cura", version = CuraVersion, build_type = CuraBuildType) + super().__init__(name = "cura", version = CuraVersion, buildtype = CuraBuildType) self.setWindowIcon(QIcon(Resources.getPath(Resources.Images, "cura-icon.png"))) From c79b7bdd7ad2ed7df481f718c87346a489ba5da9 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Sun, 5 Jun 2016 11:34:29 +0200 Subject: [PATCH 437/705] Machine manager now creates ExtruderTrainStacks CURA-340 --- cura/CuraApplication.py | 12 +++++++++--- cura/MachineManagerModel.py | 27 ++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index df72a4208d..729264767e 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -269,9 +269,15 @@ class CuraApplication(QtApplication): continue file_name = urllib.parse.quote_plus(stack.getId()) + ".stack.cfg" - path = Resources.getStoragePath(self.ResourceTypes.MachineStack, file_name) - with SaveFile(path, "wt", -1, "utf-8") as f: - f.write(data) + stack_type = stack.getMetaDataEntry("type", None) + path = None + if not stack_type: + path = Resources.getStoragePath(self.ResourceTypes.MachineStack, file_name) + elif stack_type == "extruder": + path = Resources.getStoragePath(self.ResourceTypes.ExtruderStack, file_name) + if path: + with SaveFile(path, "wt", -1, "utf-8") as f: + f.write(data) @pyqtSlot(result = QUrl) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 3e4c7a0411..c69ddbc3c2 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -33,8 +33,6 @@ class MachineManagerModel(QObject): active_machine_id = Preferences.getInstance().getValue("cura/active_machine") - - if active_machine_id != "": # An active machine was saved, so restore it. self.setActiveMachine(active_machine_id) @@ -46,9 +44,15 @@ class MachineManagerModel(QObject): activeVariantChanged = pyqtSignal() activeQualityChanged = pyqtSignal() + activeExtrudersChanged = pyqtSignal() + globalValueChanged = pyqtSignal() # Emitted whenever a value inside global container is changed. globalValidationChanged = pyqtSignal() # Emitted whenever a validation inside global container is changed. + @pyqtProperty("QVariantMap", notify = activeExtrudersChanged) + def activeExtruders(self): + return {} + def _onGlobalPropertyChanged(self, key, property_name): if property_name == "value": self.globalValueChanged.emit() @@ -115,7 +119,7 @@ class MachineManagerModel(QObject): UM.Settings.ContainerRegistry.getInstance().addContainer(current_settings_instance_container) # If a definition is found, its a list. Should only have one item. - new_global_stack.addContainer(definitions[0]) + new_global_stack.addContainer(definition) if variant_instance_container: new_global_stack.addContainer(variant_instance_container) if material_instance_container: @@ -124,6 +128,23 @@ class MachineManagerModel(QObject): new_global_stack.addContainer(quality_instance_container) new_global_stack.addContainer(current_settings_instance_container) + ## Check if the machine has extruder trains + extruder_trains = definition.getMetaDataEntry("machine_extruder_trains", {}) + for extruder in extruder_trains: + extruder_train_stack = UM.Settings.ContainerStack(name + "_extruder_" + extruder) + extruder_train_stack.addMetaDataEntry("type", "extruder") + extruder_definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id=extruder_trains[extruder]) + if extruder_definitions: + extruder_train_stack.addContainer(extruder_definitions[0]) + current_settings_container_extruder = UM.Settings.InstanceContainer(extruder_train_stack.getName() + "_current_settings") + current_settings_container_extruder.addMetaDataEntry("machine", name) + current_settings_container_extruder.addMetaDataEntry("type", "user") + extruder_train_stack.addContainer(current_settings_container_extruder) + extruder_train_stack.setNextStack(new_global_stack) + UM.Settings.ContainerRegistry.getInstance().addContainer(extruder_train_stack) + else: + Logger.log("W", "Unable to find definition for extruder") + Application.getInstance().setGlobalContainerStack(new_global_stack) # Create a name that is not empty and unique From 1e44abb9bea42cb1374127be7df46127d954d3cd Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Sun, 5 Jun 2016 12:01:46 +0200 Subject: [PATCH 438/705] Added activeExtruder stack to machineManager model CURA-340 --- cura/MachineManagerModel.py | 26 ++++++++++++++++++++++---- resources/qml/SidebarHeader.qml | 6 +++++- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index c69ddbc3c2..1134e36a38 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -33,6 +33,8 @@ class MachineManagerModel(QObject): active_machine_id = Preferences.getInstance().getValue("cura/active_machine") + self._active_extruder_index = 0 + if active_machine_id != "": # An active machine was saved, so restore it. self.setActiveMachine(active_machine_id) @@ -44,14 +46,28 @@ class MachineManagerModel(QObject): activeVariantChanged = pyqtSignal() activeQualityChanged = pyqtSignal() - activeExtrudersChanged = pyqtSignal() + activeExtruderChanged = pyqtSignal() globalValueChanged = pyqtSignal() # Emitted whenever a value inside global container is changed. globalValidationChanged = pyqtSignal() # Emitted whenever a validation inside global container is changed. - @pyqtProperty("QVariantMap", notify = activeExtrudersChanged) - def activeExtruders(self): - return {} + @pyqtProperty(str, notify=activeExtruderChanged) + def activeExtruderStackId(self): + return self.extrudersIds[str(self._active_extruder_index)] + + @pyqtSlot(int) + def setActiveExtruderIndex(self, index): + self._active_extruder_index = index + self.activeExtruderChanged.emit() + + @pyqtProperty("QVariantMap", notify = globalContainerChanged) + def extrudersIds(self): + ## Find all extruders that reference the new stack + extruders = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(**{"machine": self._global_container_stack.getId()}) + result = {} + for extruder in extruders: + result[extruder.getMetaDataEntry("position")] = extruder.getId() + return result def _onGlobalPropertyChanged(self, key, property_name): if property_name == "value": @@ -133,6 +149,8 @@ class MachineManagerModel(QObject): for extruder in extruder_trains: extruder_train_stack = UM.Settings.ContainerStack(name + "_extruder_" + extruder) extruder_train_stack.addMetaDataEntry("type", "extruder") + extruder_train_stack.addMetaDataEntry("machine", name) # What global stack is this extruder linked with? + extruder_train_stack.addMetaDataEntry("position", extruder) # What is the position of the extruder (as defined by machine definition) extruder_definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id=extruder_trains[extruder]) if extruder_definitions: extruder_train_stack.addContainer(extruder_definitions[0]) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index bb7aeebae7..61ccbb998d 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -108,7 +108,11 @@ Item exclusiveGroup: extruderMenuGroup; checkable: true; checked: base.currentExtruderIndex == index - onClicked: base.currentExtruderIndex = index + onClicked: + { + base.currentExtruderIndex = index + Cura.MachineManager.setActiveExtruderIndex(index) + } style: ButtonStyle { background: Rectangle { From 783134031bd43b6125fe3c5bd8236a99e2e00121 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Sun, 5 Jun 2016 12:17:35 +0200 Subject: [PATCH 439/705] Settings can now be set by extruder CURA-340 --- cura/MachineManagerModel.py | 1 + resources/qml/Settings/SettingView.qml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 1134e36a38..1423744263 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -157,6 +157,7 @@ class MachineManagerModel(QObject): current_settings_container_extruder = UM.Settings.InstanceContainer(extruder_train_stack.getName() + "_current_settings") current_settings_container_extruder.addMetaDataEntry("machine", name) current_settings_container_extruder.addMetaDataEntry("type", "user") + current_settings_container_extruder.setDefinition(definition) extruder_train_stack.addContainer(current_settings_container_extruder) extruder_train_stack.setNextStack(new_global_stack) UM.Settings.ContainerRegistry.getInstance().addContainer(extruder_train_stack) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 1555149d22..7430932b65 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -79,7 +79,7 @@ ScrollView { id: provider - containerStackId: Cura.MachineManager.activeMachineId + containerStackId: Cura.MachineManager.activeExtruderStackId key: model.key watchedProperties: [ "value", "enabled", "state", "validationState" ] storeIndex: 0 From d13b5adda6549064ec9eca0e0f19aa35f73cef79 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sun, 5 Jun 2016 12:22:23 +0200 Subject: [PATCH 440/705] Codestyle & comments CURA-1619 --- cura/PrintInformation.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index 22bc562502..47d3989b55 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -51,7 +51,7 @@ class PrintInformation(QObject): self._backend.printDurationMessage.connect(self._onPrintDurationMessage) self._job_name = "" - Application.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged) + Application.getInstance().globalContainerStackChanged.connect(self._setAbbreviatedMachineName) Application.getInstance().fileLoaded.connect(self.setJobName) currentPrintTimeChanged = pyqtSignal() @@ -99,12 +99,14 @@ class PrintInformation(QObject): else: return base_name - def _onGlobalStackChanged(self): + ## Created an acronymn-like abbreviated machine name from the currently active machine name + # Called each time the global stack is switched + def _setAbbreviatedMachineName(self): global_stack_name = Application.getInstance().getGlobalContainerStack().getName() split_name = global_stack_name.split(" ") abbr_machine = "" for word in split_name: - if(word.lower() == "ultimaker"): + if word.lower() == "ultimaker": abbr_machine += "UM" elif word.isdigit(): abbr_machine += word @@ -113,5 +115,6 @@ class PrintInformation(QObject): self._abbr_machine = abbr_machine + ## Utility method that strips accents from characters (eg: â -> a) def _stripAccents(self, str): return ''.join(char for char in unicodedata.normalize('NFD', str) if unicodedata.category(char) != 'Mn') \ No newline at end of file From b63c3086940dfa208ceabb3742d830c1f125b1df Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Sun, 5 Jun 2016 12:45:02 +0200 Subject: [PATCH 441/705] Changed order of loading containers so extruder stacks don't fail anymore CURA-340 --- cura/CuraApplication.py | 4 ++-- cura/MachineManagerModel.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 22ae244286..1198f4523d 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -132,15 +132,15 @@ class CuraApplication(QtApplication): Resources.addStorageType(self.ResourceTypes.QualityInstanceContainer, "quality") Resources.addStorageType(self.ResourceTypes.VariantInstanceContainer, "variants") Resources.addStorageType(self.ResourceTypes.MaterialInstanceContainer, "materials") - Resources.addStorageType(self.ResourceTypes.ExtruderStack, "extruders") Resources.addStorageType(self.ResourceTypes.UserInstanceContainer, "user") + Resources.addStorageType(self.ResourceTypes.ExtruderStack, "extruders") Resources.addStorageType(self.ResourceTypes.MachineStack, "machine_instances") ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.QualityInstanceContainer) ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.VariantInstanceContainer) ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MaterialInstanceContainer) - ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.ExtruderStack) ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.UserInstanceContainer) + ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.ExtruderStack) ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MachineStack) # Add empty variant, material and quality containers. diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 1423744263..50098dfa1b 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -158,6 +158,7 @@ class MachineManagerModel(QObject): current_settings_container_extruder.addMetaDataEntry("machine", name) current_settings_container_extruder.addMetaDataEntry("type", "user") current_settings_container_extruder.setDefinition(definition) + UM.Settings.ContainerRegistry.getInstance().addContainer(current_settings_container_extruder) extruder_train_stack.addContainer(current_settings_container_extruder) extruder_train_stack.setNextStack(new_global_stack) UM.Settings.ContainerRegistry.getInstance().addContainer(extruder_train_stack) From cb742cf7ce749c5f4111f07ab43f4e3160e0ce9d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Sun, 5 Jun 2016 12:53:41 +0200 Subject: [PATCH 442/705] Fixed saving of machines again --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 1198f4523d..a067ae659b 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -271,7 +271,7 @@ class CuraApplication(QtApplication): file_name = urllib.parse.quote_plus(stack.getId()) + ".stack.cfg" stack_type = stack.getMetaDataEntry("type", None) path = None - if not stack_type: + if stack_type == "machine": path = Resources.getStoragePath(self.ResourceTypes.MachineStack, file_name) elif stack_type == "extruder": path = Resources.getStoragePath(self.ResourceTypes.ExtruderStack, file_name) From ead91db06291dcfa08c2b9ece9275d0a65ba1b95 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sun, 5 Jun 2016 13:54:55 +0200 Subject: [PATCH 443/705] Fix activating another container stack when the currently active stack is removed CURA-1632 --- cura/MachineManagerModel.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 50098dfa1b..a0af119636 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -405,11 +405,13 @@ class MachineManagerModel(QObject): @pyqtSlot(str) def removeMachine(self, machine_id): # If the machine that is being removed is the currently active machine, set another machine as the active machine - if self._global_container_stack and self._global_container_stack.getId() == machine_id: - containers = UM.Settings.ContainerRegistry.getInstance().findContainerStacks() - if containers: - Application.getInstance().setGlobalContainerStack(containers[0]) + activate_new_machine = (self._global_container_stack and self._global_container_stack.getId() == machine_id) UM.Settings.ContainerRegistry.getInstance().removeContainer(machine_id) + if activate_new_machine: + stacks = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(type = "machine") + if stacks: + Application.getInstance().setGlobalContainerStack(stacks[0]) + @pyqtProperty(bool, notify = globalContainerChanged) def hasMaterials(self): From c21475abd78a103bfc394e098cd92194a461dd8a Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sun, 5 Jun 2016 14:05:56 +0200 Subject: [PATCH 444/705] Prevent multiple machines having the same custom name Caused by container vs containerstack confusion Fixes CURA-1606 and CURA-1649 --- cura/MachineManagerModel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index a0af119636..75b273e1f5 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -179,8 +179,8 @@ class MachineManagerModel(QObject): i = 1 # Check both the id and the name, because they may not be the same and it is better if they are both unique - while UM.Settings.ContainerRegistry.getInstance().findContainers(None, id = unique_name) or \ - UM.Settings.ContainerRegistry.getInstance().findContainers(None, name = unique_name): + while UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = unique_name, type = "machine") or \ + UM.Settings.ContainerRegistry.getInstance().findContainerStacks(name = unique_name, type = "machine"): i += 1 unique_name = "%s #%d" % (name, i) From 9aa8ca329221f8e8b8b0ec78830eaa34dc97d287 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sun, 5 Jun 2016 16:03:31 +0200 Subject: [PATCH 445/705] Fix uninitialised variable CURA-1619 --- cura/PrintInformation.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index 47d3989b55..f1eb93de0e 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -51,6 +51,8 @@ class PrintInformation(QObject): self._backend.printDurationMessage.connect(self._onPrintDurationMessage) self._job_name = "" + self._abbr_machine = "" + Application.getInstance().globalContainerStackChanged.connect(self._setAbbreviatedMachineName) Application.getInstance().fileLoaded.connect(self.setJobName) From d810c7ddbb9d9594ec622b2be9ac372cba4225dc Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 17:00:38 +0200 Subject: [PATCH 446/705] Properly reload extruders at the start The extruder manager was too late to catch the initial global stack switch and machine switch. Now it just always reloads the extruders at the beginning. Contributes to issues CURA-1278 and CURA-351. --- cura/ExtruderManager.py | 4 +++- cura/ExtrudersModel.py | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index bfce380a70..46cdeabc91 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -27,6 +27,7 @@ class ExtruderManager: self._next_item = 0 #For when you use this class as iterator. UM.Application.getInstance().globalContainerStackChanged.connect(self._reconnectExtruderReload) #When the current machine changes, we need to reload all extruders belonging to the new machine. + self._reconnectExtruderReload() ## Gets an instance of this extruder manager. # @@ -51,6 +52,7 @@ class ExtruderManager: self._global_container_stack.containersChanged.disconnect(self._reloadExtruders) #Disconnect from the old global container stack. self._global_container_stack = UM.Application.getInstance().getGlobalContainerStack() self._global_container_stack.containersChanged.connect(self._reloadExtruders) #When the current machine changes, we need to reload all extruders belonging to the new machine. + self._reloadExtruders() ## (Re)loads all extruders of the currently active machine. # @@ -66,7 +68,7 @@ class ExtruderManager: #Get the extruder definitions belonging to the current machine. machine = self._global_container_stack.getBottom() extruder_train_ids = machine.getMetaDataEntry("machine_extruder_trains") - for extruder_train_id in extruder_train_ids: + for _,extruder_train_id in extruder_train_ids.items(): extruder_definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = extruder_train_id) #Should be only 1 definition if IDs are unique, but add the whole list anyway. if not extruder_definitions: #Empty list or error. UM.Logger.log("w", "Machine definition %s refers to an extruder train \"%s\", but no such extruder was found.", machine.getId(), extruder_train_id) diff --git a/cura/ExtrudersModel.py b/cura/ExtrudersModel.py index eb63bc4257..60514e8708 100644 --- a/cura/ExtrudersModel.py +++ b/cura/ExtrudersModel.py @@ -53,4 +53,5 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): "index": index } self.appendItem(item) + print("Appending extruder " + extruder.name + " to presenter.") self.sort(lambda item: item["index"]) \ No newline at end of file From 9b2acf03174410b09bc6f0e35c3975a5cf507723 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 17:12:22 +0200 Subject: [PATCH 447/705] Remove print statement Contributes to issues CURA-1278 and CURA-351. --- cura/ExtrudersModel.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cura/ExtrudersModel.py b/cura/ExtrudersModel.py index 60514e8708..eb63bc4257 100644 --- a/cura/ExtrudersModel.py +++ b/cura/ExtrudersModel.py @@ -53,5 +53,4 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): "index": index } self.appendItem(item) - print("Appending extruder " + extruder.name + " to presenter.") self.sort(lambda item: item["index"]) \ No newline at end of file From b4782e9b122ff4b5eaff134d2e4c7cef25540abb Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 17:13:30 +0200 Subject: [PATCH 448/705] Pass definition to _uniqueName instead of name This function expects the entire definition. Contributes to issueS CURA-1278 and CURA-351. --- cura/Extruder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Extruder.py b/cura/Extruder.py index 4bbe24183d..f27cd061bd 100644 --- a/cura/Extruder.py +++ b/cura/Extruder.py @@ -25,7 +25,7 @@ class Extruder: self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = self._definition.getId()) #Create a container stack for this extruder. - self._name = self._uniqueName(self._definition.getId()) + self._name = self._uniqueName(self._definition) self._container_stack = UM.Settings.ContainerStack(self._name) self._container_stack.addMetaDataEntry("type", "extruder_train") self._container_stack.addContainer(self._definition) From c50d0a97dab3b23042bdd90da889450864f1556e Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 17:18:09 +0200 Subject: [PATCH 449/705] Load extruder combobox synchronously Asynchronously causes Qt 5.4 to give a segfault. Contributes to issues CURA-351 and CURA-1278. --- plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml | 2 +- resources/qml/Settings/SettingView.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index d707fe9810..8ab05e90c1 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -56,7 +56,7 @@ Item { //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989 //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes, //causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely. - asynchronous: model.type != "enum" + asynchronous: model.type != "enum" && model.type != "extruder" onLoaded: { settingLoader.item.showRevertButton = false diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 7430932b65..1ffc2f939f 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -49,7 +49,7 @@ ScrollView //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989 //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes, //causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely. - asynchronous: model.type != "enum" + asynchronous: model.type != "enum" && model.type != "extruder" active: model.type != undefined source: From a948c7bcc67fafbc3e32c593a127eac51cd5b6b2 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 2 Jun 2016 17:29:26 +0200 Subject: [PATCH 450/705] Set colours of extruder selection to material colour Ubuntu Unity doesn't seem to listen to these colours at all though. Contributes to issues CURA-1278 and CURA-351. --- resources/qml/Settings/SettingExtruder.qml | 60 +++++++++++----------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/resources/qml/Settings/SettingExtruder.qml b/resources/qml/Settings/SettingExtruder.qml index 86ab728fc1..0160dab7fa 100644 --- a/resources/qml/Settings/SettingExtruder.qml +++ b/resources/qml/Settings/SettingExtruder.qml @@ -16,17 +16,18 @@ SettingItem { id: control - model: Cura.ExtrudersModel { + model: Cura.ExtrudersModel + { id: extruders_model } - textRole: "name"; + textRole: "name" anchors.fill: parent MouseArea { - anchors.fill: parent; - acceptedButtons: Qt.NoButton; + anchors.fill: parent + acceptedButtons: Qt.NoButton onWheel: wheel.accepted = true; } @@ -38,44 +39,44 @@ SettingItem { if (!enabled) { - return UM.Theme.getColor("setting_control_disabled") + return UM.Theme.getColor("setting_control_disabled"); } if(control.hovered || base.activeFocus) { - return UM.Theme.getColor("setting_control_highlight") + return UM.Theme.getColor("setting_control_highlight"); } else { - return UM.Theme.getColor("setting_control") + return extruders_model.getItem(index).colour; } } - border.width: UM.Theme.getSize("default_lining").width; - border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : control.hovered ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border"); + border.width: UM.Theme.getSize("default_lining").width + border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : control.hovered ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border") } label: Item { Label { - anchors.left: parent.left; + anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_lining").width - anchors.right: downArrow.left; - anchors.rightMargin: UM.Theme.getSize("default_lining").width; - anchors.verticalCenter: parent.verticalCenter; + anchors.right: downArrow.left + anchors.rightMargin: UM.Theme.getSize("default_lining").width + anchors.verticalCenter: parent.verticalCenter - text: control.currentText; - font: UM.Theme.getFont("default"); - color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text"); + text: control.currentText + font: UM.Theme.getFont("default") + color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : extruders_model.getItem(index).colour - elide: Text.ElideRight; - verticalAlignment: Text.AlignVCenter; + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter } UM.RecolorImage { id: downArrow - anchors.right: parent.right; - anchors.rightMargin: UM.Theme.getSize("default_lining").width * 2; - anchors.verticalCenter: parent.verticalCenter; + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("default_lining").width * 2 + anchors.verticalCenter: parent.verticalCenter source: UM.Theme.getIcon("arrow_bottom") width: UM.Theme.getSize("standard_arrow").width @@ -83,29 +84,30 @@ SettingItem sourceSize.width: width + 5 sourceSize.height: width + 5 - color: UM.Theme.getColor("setting_control_text"); - + color: UM.Theme.getColor("setting_control_text") } } } - onActivated: provider.setPropertyValue("value", extruders_model.getItem(index).index) + onActivated: provider.setPropertyValue("value", extruders_model.getItem(index).index); onModelChanged: updateCurrentIndex(); Connections { target: provider - onPropertiesChanged: control.updateCurrentIndex() + onPropertiesChanged: control.updateCurrentIndex(); } - function updateCurrentIndex() { - for(var i = 0; i < extruders_model.rowCount(); ++i) { - if(extruders_model.getItem(i).index == provider.properties.value) { + function updateCurrentIndex() + { + for(var i = 0; i < extruders_model.rowCount(); ++i) + { + if(extruders_model.getItem(i).index == provider.properties.value) + { currentIndex = i; return; } } - currentIndex = -1; } } From e03c3b95c527347c92939257b44d8d450b41c929 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Mon, 6 Jun 2016 06:36:30 +0100 Subject: [PATCH 451/705] Splashscreen: Another (and last) correction Now all the needed changes should be done. --- cura/CuraSplashScreen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraSplashScreen.py b/cura/CuraSplashScreen.py index 8f677986df..f2810d359b 100644 --- a/cura/CuraSplashScreen.py +++ b/cura/CuraSplashScreen.py @@ -23,7 +23,7 @@ class CuraSplashScreen(QSplashScreen): version = Application.getInstance().getVersion().split("-") buildtype = Application.getInstance().getBuildType() if buildtype: - version += " (%s)" %(buildtype) + version[0] += " (%s)" %(buildtype) painter.setFont(QFont("Proxima Nova Rg", 20 )) painter.drawText(0, 0, 330 * self._scale, 230 * self._scale, Qt.AlignHCenter | Qt.AlignBottom, version[0]) From 1171bf112c79f3f3586fb0d030d9dea20db9b961 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Mon, 6 Jun 2016 06:43:07 +0100 Subject: [PATCH 452/705] Ignoring Eclipse+PyDev project files --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 72ba4bf565..925de00391 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ resources/i18n/x-test *~ *.qm .idea +.project +.pydevproject From b88f2847ef58cf27b4aab96398ef160a483b9c63 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 6 Jun 2016 08:39:38 +0200 Subject: [PATCH 453/705] Fix saving machine instances to the cura profile CURA-340, see https://github.com/Ultimaker/Cura/commit/c79b7bdd7ad2ed7df481f718c87346a489ba5da9 --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 1198f4523d..4f02d2dab5 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -271,7 +271,7 @@ class CuraApplication(QtApplication): file_name = urllib.parse.quote_plus(stack.getId()) + ".stack.cfg" stack_type = stack.getMetaDataEntry("type", None) path = None - if not stack_type: + if not stack_type or stack_type == "machine": path = Resources.getStoragePath(self.ResourceTypes.MachineStack, file_name) elif stack_type == "extruder": path = Resources.getStoragePath(self.ResourceTypes.ExtruderStack, file_name) From a3e5c065727270d5175c6f76d557115ebb17d97b Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Mon, 6 Jun 2016 06:40:34 +0100 Subject: [PATCH 454/705] Adding debian to gitignore Got a link here my packaging files. As Cura does not come with packaging files itself, we can add this ignore here. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 76f470544f..cc21d3092c 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,6 @@ resources/firmware .idea .project .pydevproject + +# Debian packaging +debian/ From c7340c3b21fbf10c36d6ddf9ec96c95e75703eeb Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 6 Jun 2016 10:18:19 +0200 Subject: [PATCH 455/705] Temporary removed multi extruder stack so slicing works again --- resources/qml/Settings/SettingView.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 7430932b65..1555149d22 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -79,7 +79,7 @@ ScrollView { id: provider - containerStackId: Cura.MachineManager.activeExtruderStackId + containerStackId: Cura.MachineManager.activeMachineId key: model.key watchedProperties: [ "value", "enabled", "state", "validationState" ] storeIndex: 0 From 22857bf3e1599367ac82e0b30e1334658005e7b0 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 6 Jun 2016 12:14:10 +0200 Subject: [PATCH 456/705] Disable export profile button when no profile is selected CURA-1585 --- resources/qml/Preferences/ProfilesPage.qml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index b7261afcec..3f7c696d9d 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -168,9 +168,10 @@ UM.ManagementPage Button { - text: catalog.i18nc("@action:button", "Export"); - iconName: "document-export"; - onClicked: exportDialog.open(); + text: catalog.i18nc("@action:button", "Export") + iconName: "document-export" + onClicked: exportDialog.open() + enabled: currentItem != null } } From 3752a6bbef2f534efc92d7666dc5397f7d0f62f8 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 6 Jun 2016 13:02:20 +0200 Subject: [PATCH 457/705] Show rename profile dialog after creating a profile from the profiles dropdown CURA-1585 --- resources/qml/Preferences/ProfilesPage.qml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 3f7c696d9d..0b57405b56 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -71,6 +71,9 @@ UM.ManagementPage scrollviewCaption: catalog.i18nc("@label %1 is printer name","Printer: %1").arg(Cura.MachineManager.activeMachineName) + signal showProfileNameDialog() + onShowProfileNameDialog: { renameDialog.removeWhenRejected = true; renameDialog.open(); renameDialog.selectText(); } + signal selectContainer(string id) onSelectContainer: { objectList.currentIndex = objectList.model.find("id", id); From a139809b75d956773f4a3164f7623a3acdd5ebd0 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 6 Jun 2016 13:39:11 +0200 Subject: [PATCH 458/705] Fix showing profiles created using the dropdown menu in the dropdown and on the profiles manager CURA-1585 --- cura/MachineManagerModel.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 75b273e1f5..3a584a2797 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -289,6 +289,12 @@ class MachineManagerModel(QObject): ## Copy all values new_quality_container.deserialize(user_settings.serialize()) + ## If the currently active machine does not have quality profiles of its own, + # make the new quality profile available for all machines that don't have + # unique quality profiles (including the current machine) + if not self.filterQualityByMachine: + new_quality_container.setDefinition(UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = "fdmprinter")[0]) + ## Change type / id / name new_quality_container.setMetaDataEntry("type","quality") new_quality_container.setName(name) From a2db4740b9654fde55f0f811cb33797dc9e63320 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 6 Jun 2016 15:09:21 +0200 Subject: [PATCH 459/705] Fix removing custom (quality) profiles CURA-1585 --- cura/MachineManagerModel.py | 22 +++++++++++++++++++++- resources/qml/Preferences/ProfilesPage.qml | 8 ++++---- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 3a584a2797..6e1a6185e7 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -301,7 +301,7 @@ class MachineManagerModel(QObject): new_quality_container._id = name UM.Settings.ContainerRegistry.getInstance().addContainer(new_quality_container) - self.clearUserSettings() # As all users settings are noq a quality, remove them. + self.clearUserSettings() # As all users settings are now transfered to the new quality profile, remove them. self.setActiveQuality(name) return name @@ -325,6 +325,26 @@ class MachineManagerModel(QObject): return "" + + @pyqtSlot(str) + def removeQualityContainer(self, container_id): + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id) + if not containers or not self._global_container_stack: + return + + # If the container that is being removed is the currently active container, set another machine as the active container + activate_new_container = container_id == self.activeQualityId + + UM.Settings.ContainerRegistry.getInstance().removeContainer(container_id) + + if activate_new_container: + old_container = self._global_container_stack.findInstanceContainers({"type": "quality"}) + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = container_type) + if containers and old_container: + container_index = self._global_container_stack.getContainerIndex(old_container) + self._global_container_stack.replaceContainer(container_index, containers[0]) + + @pyqtSlot() def updateUserContainerToQuality(self): if not self._global_container_stack: diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 0b57405b56..f5d3169508 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -66,8 +66,8 @@ UM.ManagementPage activateEnabled: currentItem != null ? currentItem.id != Cura.MachineManager.activeQualityId : false; addEnabled: currentItem != null; - removeEnabled: currentItem != null ? !currentItem.readOnly : false; - renameEnabled: currentItem != null ? !currentItem.readOnly : false; + removeEnabled: currentItem != null ? !currentItem.metadata.read_only : false; + renameEnabled: currentItem != null ? !currentItem.metadata.read_only : false; scrollviewCaption: catalog.i18nc("@label %1 is printer name","Printer: %1").arg(Cura.MachineManager.activeMachineName) @@ -137,7 +137,7 @@ UM.ManagementPage Label { text: base.currentItem == null ? "" : base.currentItem.id == -1 ? Cura.MachineManager.activeQualityName: - base.currentItem.readOnly ? catalog.i18nc("@label", "Protected profile") : catalog.i18nc("@label", "Custom profile") + base.currentItem.metadata.read_only ? catalog.i18nc("@label", "Protected profile") : catalog.i18nc("@label", "Custom profile") } Column { @@ -186,7 +186,7 @@ UM.ManagementPage { id: confirmDialog; object: base.currentItem != null ? base.currentItem.name : ""; - onYes: base.model.removeProfile(base.currentItem.name); + onYes: Cura.MachineManager.removeQualityContainer(base.currentItem.id); } UM.RenameDialog { From 2660b2a68f892dad154fdcbd034d90a402515ec7 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 6 Jun 2016 09:37:25 +0200 Subject: [PATCH 460/705] Give default empty machine_extruder_ids Works also if the machine has no machine_extruder_ids metadata. Contributes to issues CURA-1278 and CURA-351. --- cura/ExtruderManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 46cdeabc91..7222a1c0f8 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -67,7 +67,7 @@ class ExtruderManager: #Get the extruder definitions belonging to the current machine. machine = self._global_container_stack.getBottom() - extruder_train_ids = machine.getMetaDataEntry("machine_extruder_trains") + extruder_train_ids = machine.getMetaDataEntry("machine_extruder_trains", { }) for _,extruder_train_id in extruder_train_ids.items(): extruder_definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = extruder_train_id) #Should be only 1 definition if IDs are unique, but add the whole list anyway. if not extruder_definitions: #Empty list or error. From 357997c984793edcb06881c29047854154c30823 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 6 Jun 2016 09:40:20 +0200 Subject: [PATCH 461/705] Add user profile to container registry This will allow it to be saved when restarting Cura and such. Contributes to issues CURA-1278 and CURA-351. --- cura/Extruder.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/Extruder.py b/cura/Extruder.py index f27cd061bd..1e701f9eaa 100644 --- a/cura/Extruder.py +++ b/cura/Extruder.py @@ -76,6 +76,7 @@ class Extruder: self._user_profile = UM.Settings.InstanceContainer(self._name + "_current_settings") self._user_profile.addMetaDataEntry("type", "user") self._container_stack.addContainer(self._user_profile) + container_registry.addContainer(self._user_profile) self._container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack()) From bfc880b61a42026e78b4afbca2e3937b00d8dbd6 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 6 Jun 2016 10:20:59 +0200 Subject: [PATCH 462/705] Add extruder container stack to registry Contributes to issues CURA-1278 and CURA-351. --- cura/Extruder.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/Extruder.py b/cura/Extruder.py index 1e701f9eaa..bfda6db27a 100644 --- a/cura/Extruder.py +++ b/cura/Extruder.py @@ -27,6 +27,7 @@ class Extruder: #Create a container stack for this extruder. self._name = self._uniqueName(self._definition) self._container_stack = UM.Settings.ContainerStack(self._name) + container_registry.addContainer(self._container_stack) self._container_stack.addMetaDataEntry("type", "extruder_train") self._container_stack.addContainer(self._definition) From 79c37d667e50d3dd730ade079dfb245a3c614079 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 6 Jun 2016 10:22:47 +0200 Subject: [PATCH 463/705] Add extruder stack only when it's completely built Probably better for concurrency reasons, though that is not a problem yet at this moment. Contributes to issues CURA-1278 and CURA-351. --- cura/Extruder.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/Extruder.py b/cura/Extruder.py index bfda6db27a..6418f008c4 100644 --- a/cura/Extruder.py +++ b/cura/Extruder.py @@ -27,7 +27,6 @@ class Extruder: #Create a container stack for this extruder. self._name = self._uniqueName(self._definition) self._container_stack = UM.Settings.ContainerStack(self._name) - container_registry.addContainer(self._container_stack) self._container_stack.addMetaDataEntry("type", "extruder_train") self._container_stack.addContainer(self._definition) @@ -81,6 +80,8 @@ class Extruder: self._container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack()) + container_registry.addContainer(self._container_stack) + definition_changed = UM.Signal() material_changed = UM.Signal() name_changed = UM.Signal() From 927d33145f227d04fbfce393213e0878bae87cd5 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 6 Jun 2016 13:41:49 +0200 Subject: [PATCH 464/705] Move creating extruder manager logic to ExtruderManager This logic was both in Extruder.py and in MachineManagerModel.py due to a planning mishap. Contributes to issues CURA-1278 and CURA-340. --- cura/CuraApplication.py | 3 + cura/Extruder.py | 211 ------------------------- cura/ExtruderManager.py | 139 ++++++++++++---- cura/MachineManagerModel.py | 31 ---- resources/qml/Settings/SettingView.qml | 2 +- resources/qml/SidebarHeader.qml | 2 +- 6 files changed, 109 insertions(+), 279 deletions(-) delete mode 100644 cura/Extruder.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 4f02d2dab5..126d8b2864 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -31,6 +31,7 @@ from UM.Settings.ContainerRegistry import ContainerRegistry from UM.i18n import i18nCatalog +from . import ExtruderManager from . import ExtrudersModel from . import PlatformPhysics from . import BuildVolume @@ -352,6 +353,8 @@ class CuraApplication(QtApplication): qmlRegisterSingletonType(MachineManagerModel.MachineManagerModel, "Cura", 1, 0, "MachineManager", MachineManagerModel.createMachineManagerModel) + qmlRegisterSingletonType(ExtruderManager.ExtruderManager, "Cura", 1, 0, "ExtruderManager", + ExtruderManager.createExtruderManager) self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml")) self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles)) diff --git a/cura/Extruder.py b/cura/Extruder.py deleted file mode 100644 index 6418f008c4..0000000000 --- a/cura/Extruder.py +++ /dev/null @@ -1,211 +0,0 @@ -# Copyright (c) 2016 Ultimaker B.V. -# Cura is released under the terms of the AGPLv3 or higher. - -import re #To parse container registry names to increment the duplicates-resolving number. - -import UM.Application #To link the stack to the global container stack. -import UM.Logger -import UM.Settings.ContainerRegistry #To search for nozzles, materials, etc. -import UM.Settings.ContainerStack #To create a container stack for this extruder. -import UM.Signal #To notify people of changing extruder stacks. - -class Extruder: - ## Creates a new extruder from the specified definition container. - # - # \param definition The definition container defining this extruder. - def __init__(self, definition): - self._definition = definition - - container_registry = UM.Settings.ContainerRegistry.getInstance() - - #Find the nozzles that fit on this extruder. - self._nozzles = container_registry.findInstanceContainers(type = "nozzle", definitions = "*," + self._definition.getId() + ",*") #Extruder needs to be delimited by either a comma or the end of string. - self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = "*," + self._definition.getId()) - self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = self._definition.getId() + ",*") - self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = self._definition.getId()) - - #Create a container stack for this extruder. - self._name = self._uniqueName(self._definition) - self._container_stack = UM.Settings.ContainerStack(self._name) - self._container_stack.addMetaDataEntry("type", "extruder_train") - self._container_stack.addContainer(self._definition) - - #Find the nozzle to use for this extruder. - self._nozzle = container_registry.getEmptyInstanceContainer() - if self._definition.getMetaDataEntry("has_nozzles", default = "False") == "True": - if len(self._nozzles) >= 1: #First add any extruder. Later, overwrite with preference if the preference is valid. - self._nozzle = self._nozzles[0] - preferred_nozzle_id = self._definition.getMetaDataEntry("preferred_nozzle") - if preferred_nozzle_id: - for nozzle in self._nozzles: - if nozzle.getId() == preferred_nozzle_id: - self._nozzle = nozzle - break - self._container_stack.addContainer(self._nozzle) - - #Find a material to use for this nozzle. - self._material = container_registry.getEmptyInstanceContainer() - if self._definition.getMetaDataEntry("has_materials", default = "False") == "True": - if self._definition.getMetaDataEntry("has_nozzle_materials", default = "False") == "True": - all_materials = container_registry.findInstanceContainers(type = "material", nozzle = self._nozzle.getId()) - else: - all_materials = container_registry.findInstanceContainers(type = "material") - if len(all_materials) >= 1: - self._material = all_materials[0] - preferred_material_id = self._definition.getMetaDataEntry("preferred_material") - if preferred_material_id: - preferred_material = container_registry.findInstanceContainers(type = "material", id = preferred_material_id.lower()) - if len(preferred_material) >= 1: - self._material = preferred_material[0] - self._container_stack.addContainer(self._material) - - #Find a quality to use for this extruder. - self._quality = container_registry.getEmptyInstanceContainer() - if self._definition.getMetaDataEntry("has_machine_quality"): - all_qualities = container_registry.findInstanceContainers(type = "quality") - if len(all_qualities) >= 1: - self._quality = all_qualities[0] - preferred_quality_id = self._definition.getMetaDataEntry("preferred_quality") - if preferred_quality_id: - preferred_quality = container_registry.findInstanceContainers(type = "quality", id = preferred_quality_id.lower()) - if len(preferred_quality) >= 1: - self._quality = preferred_quality[0] - self._container_stack.addContainer(self._quality) - - #Add an empty user profile. - self._user_profile = UM.Settings.InstanceContainer(self._name + "_current_settings") - self._user_profile.addMetaDataEntry("type", "user") - self._container_stack.addContainer(self._user_profile) - container_registry.addContainer(self._user_profile) - - self._container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack()) - - container_registry.addContainer(self._container_stack) - - definition_changed = UM.Signal() - material_changed = UM.Signal() - name_changed = UM.Signal() - nozzle_changed = UM.Signal() - quality_changed = UM.Signal() - - ## Gets the definition container of this extruder. - # - # \return The definition container of this extruder. - @property - def definition(self): - return self._definition - - ## Changes the definition container of this extruder. - # - # \param value The new definition for this extruder. - @definition.setter - def definition(self, value): - try: - position = self._container_stack.index(self._definition) - except ValueError: #Definition is not in the list. Big trouble! - UM.Logger.log("e", "I've lost my old extruder definition, so I can't find where to insert the new definition.") - return - self._container_stack.replaceContainer(position, value) - self._definition = value - self.definition_changed.emit() - - ## Gets the currently active material on this extruder. - # - # \return The currently active material on this extruder. - @property - def material(self): - return self._material - - ## Changes the currently active material in this extruder. - # - # \param value The new material to extrude through this extruder. - @material.setter - def material(self, value): - try: - position = self._container_stack.index(self._material) - except ValueError: #Material is not in the list. - UM.Logger.log("e", "I've lost my old material, so I can't find where to insert the new material.") - return - self._container_stack.replaceContainer(position, value) - self._material = value - self.material_changed.emit() - - ## Gets the name of this extruder. - # - # \return The name of this extruder. - @property - def name(self): - return self._name - - ## Changes the name of this extruder. - # - # \param value The new name for this extruder. - @name.setter - def name(self, value): - self._name = value - self._container_stack.setName(value) #Also update in container stack, being defensive. - self.name_changed.emit() - - ## Gets the currently active nozzle on this extruder. - # - # \return The currently active nozzle on this extruder. - @property - def nozzle(self): - return self._nozzle - - ## Changes the currently active nozzle on this extruder. - # - # \param value The new nozzle to use with this extruder. - @nozzle.setter - def nozzle(self, value): - try: - position = self._container_stack.index(self._nozzle) - except ValueError: #Nozzle is not in the list. - UM.Logger.log("e", "I've lost my old nozzle, so I can't find where to insert the new nozzle.") - return - self._container_stack.replaceContainer(position, value) - self._nozzle = value - self.nozzle_changed.emit() - - ## Gets the currently active quality on this extruder. - # - # \return The currently active quality on this extruder. - @property - def quality(self): - return self._quality - - ## Changes the currently active quality to use with this extruder. - # - # \param value The new quality to use with this extruder. - @quality.setter - def quality(self, value): - try: - position = self._container_stack.index(self._quality) - except ValueError: #Quality is not in the list. - UM.Logger.log("e", "I've lost my old quality, so I can't find where to insert the new quality.") - return - self._container_stack.replaceContainer(position, value) - self._quality = value - self.quality_changed.emit() - - ## Finds a unique name for an extruder stack. - # - # \param extruder An extruder definition to design a name for. - # \return A name for an extruder stack that is unique and reasonably - # human-readable. - def _uniqueName(self, extruder): - container_registry = UM.Settings.ContainerRegistry.getInstance() - - name = extruder.getName().strip() - num_check = re.compile("(.*?)\s*#\d$").match(name) - if num_check: #There is a number in the name. - name = num_check.group(1) #Filter out the number. - if name == "": #Wait, that deleted everything! - name = "Extruder" - unique_name = name - - i = 1 - while container_registry.findContainers(id = unique_name) or container_registry.findContainers(name = unique_name): #A container already has this name. - i += 1 #Try next numbering. - unique_name = "%s #%d" % (name, i) #Fill name like this: "Extruder #2". - return unique_name \ No newline at end of file diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 7222a1c0f8..4f23a01808 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -1,7 +1,8 @@ # Copyright (c) 2016 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. -from cura.Extruder import Extruder #The individual extruders managed by this manager. +from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject + import UM.Application #To get the global container stack to find the current machine. import UM.Logger import UM.Settings.ContainerRegistry #Finding containers by ID. @@ -13,21 +14,24 @@ import UM.Signal #To notify other components of changes in the extruders. # This finds the extruders that are available for the currently active machine # and makes sure that whenever the machine is swapped, this list is kept up to # date. It also contains and updates the setting stacks for the extruders. -class ExtruderManager: +class ExtruderManager(QObject): ## The singleton instance of this manager. __instance = None ## Signal to notify other components when the list of extruders changes. extrudersChanged = UM.Signal() - ## Registers listeners and such to listen to changes to the extruders. - def __init__(self): - self._extruders = [] #Extruders for the current machine. - self._global_container_stack = None - self._next_item = 0 #For when you use this class as iterator. + ## Notify when the user switches the currently active extruder. + activeExtruderChanged = pyqtSignal() - UM.Application.getInstance().globalContainerStackChanged.connect(self._reconnectExtruderReload) #When the current machine changes, we need to reload all extruders belonging to the new machine. - self._reconnectExtruderReload() + ## Registers listeners and such to listen to changes to the extruders. + def __init__(self, parent = None): + super().__init__(parent) + self._extruder_trains = { } #Extruders for the current machine. + self._next_item = 0 #For when you use this class as iterator. + self._active_extruder_index = 0 + + self._repopulate() ## Gets an instance of this extruder manager. # @@ -45,34 +49,99 @@ class ExtruderManager: def __iter__(self): return iter(self._extruders) - ## When the global container stack changes, this reconnects to the new - # signal for containers changing. - def _reconnectExtruderReload(self): - if self._global_container_stack: - self._global_container_stack.containersChanged.disconnect(self._reloadExtruders) #Disconnect from the old global container stack. - self._global_container_stack = UM.Application.getInstance().getGlobalContainerStack() - self._global_container_stack.containersChanged.connect(self._reloadExtruders) #When the current machine changes, we need to reload all extruders belonging to the new machine. - self._reloadExtruders() + @pyqtProperty(str, notify = activeExtruderChanged) + def activeExtruderStackId(self): + if UM.Application.getInstance().getGlobalContainerStack(): + try: + return self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getId()][str(self._active_extruder_index)] + except KeyError: + pass - ## (Re)loads all extruders of the currently active machine. - # - # This looks at the global container stack to see which machine is active. - # Then it loads the extruders for that machine and loads each of them in a - # list of extruders. - def _reloadExtruders(self, *args): - self._extruders = [] - if not self._global_container_stack: #No machine has been added yet. + @pyqtSlot(int) + def setActiveExtruderIndex(self, index): + self._active_extruder_index = index + self.activeExtruderChanged.emit() + + ## (Re)populates the collections of extruders by machine. + def _repopulate(self): + self._extruder_trains = { } + if not UM.Application.getInstance().getGlobalContainerStack(): #No machine has been added yet. self.extrudersChanged.emit() #Yes, we just cleared the _extruders list! return #Then leave them empty! - #Get the extruder definitions belonging to the current machine. - machine = self._global_container_stack.getBottom() - extruder_train_ids = machine.getMetaDataEntry("machine_extruder_trains", { }) - for _,extruder_train_id in extruder_train_ids.items(): - extruder_definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = extruder_train_id) #Should be only 1 definition if IDs are unique, but add the whole list anyway. - if not extruder_definitions: #Empty list or error. - UM.Logger.log("w", "Machine definition %s refers to an extruder train \"%s\", but no such extruder was found.", machine.getId(), extruder_train_id) + extruder_trains = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(type = "extruder_train") + for extruder_train in extruder_trains: + machine_id = extruder_train.getMetaDataEntry("machine") + if not machine_id: continue - for extruder_definition in extruder_definitions: - self._extruders.append(Extruder(extruder_definition)) - self.extrudersChanged.emit() \ No newline at end of file + if machine_id not in self._extruder_trains: + self._extruder_trains[machine_id] = { } + self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train.getId() + self.extrudersChanged.emit() + + def createExtruderTrain(self, definition, extruder_id): + container_registry = UM.Settings.ContainerRegistry.getInstance() + + #Create a container stack for this extruder. + name = self._uniqueName(extruder_id) + container_stack = UM.Settings.ContainerStack(name) + container_stack.addMetaDataEntry("type", "extruder_train") + container_stack.addContainer(definition) + + """ + Yes, I'm committing this code which needs to be transformed to work later. + #Find the nozzle to use for this extruder. + nozzle = container_registry.getEmptyInstanceContainer() + if definition.getMetaDataEntry("has_nozzles", default = "False") == "True": + if len(self._nozzles) >= 1: #First add any extruder. Later, overwrite with preference if the preference is valid. + self._nozzle = self._nozzles[0] + preferred_nozzle_id = definition.getMetaDataEntry("preferred_nozzle") + if preferred_nozzle_id: + for nozzle in self._nozzles: + if nozzle.getId() == preferred_nozzle_id: + self._nozzle = nozzle + break + self._container_stack.addContainer(self._nozzle) + + #Find a material to use for this nozzle. + self._material = container_registry.getEmptyInstanceContainer() + if self._definition.getMetaDataEntry("has_materials", default = "False") == "True": + if self._definition.getMetaDataEntry("has_nozzle_materials", default = "False") == "True": + all_materials = container_registry.findInstanceContainers(type = "material", nozzle = self._nozzle.getId()) + else: + all_materials = container_registry.findInstanceContainers(type = "material") + if len(all_materials) >= 1: + self._material = all_materials[0] + preferred_material_id = self._definition.getMetaDataEntry("preferred_material") + if preferred_material_id: + preferred_material = container_registry.findInstanceContainers(type = "material", id = preferred_material_id.lower()) + if len(preferred_material) >= 1: + self._material = preferred_material[0] + self._container_stack.addContainer(self._material) + + #Find a quality to use for this extruder. + self._quality = container_registry.getEmptyInstanceContainer() + if self._definition.getMetaDataEntry("has_machine_quality"): + all_qualities = container_registry.findInstanceContainers(type = "quality") + if len(all_qualities) >= 1: + self._quality = all_qualities[0] + preferred_quality_id = self._definition.getMetaDataEntry("preferred_quality") + if preferred_quality_id: + preferred_quality = container_registry.findInstanceContainers(type = "quality", id = preferred_quality_id.lower()) + if len(preferred_quality) >= 1: + self._quality = preferred_quality[0] + self._container_stack.addContainer(self._quality) + """ + + #Add an empty user profile. + user_profile = UM.Settings.InstanceContainer(name + "_current_settings") + user_profile.addMetaDataEntry("type", "user") + container_stack.addContainer(user_profile) + container_registry.addContainer(user_profile) + + container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack()) + + container_registry.addContainer(container_stack) + +def createExtruderManager(engine, script_engine): + return ExtruderManager() \ No newline at end of file diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 3a584a2797..3515d613bd 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -46,20 +46,9 @@ class MachineManagerModel(QObject): activeVariantChanged = pyqtSignal() activeQualityChanged = pyqtSignal() - activeExtruderChanged = pyqtSignal() - globalValueChanged = pyqtSignal() # Emitted whenever a value inside global container is changed. globalValidationChanged = pyqtSignal() # Emitted whenever a validation inside global container is changed. - @pyqtProperty(str, notify=activeExtruderChanged) - def activeExtruderStackId(self): - return self.extrudersIds[str(self._active_extruder_index)] - - @pyqtSlot(int) - def setActiveExtruderIndex(self, index): - self._active_extruder_index = index - self.activeExtruderChanged.emit() - @pyqtProperty("QVariantMap", notify = globalContainerChanged) def extrudersIds(self): ## Find all extruders that reference the new stack @@ -145,26 +134,6 @@ class MachineManagerModel(QObject): new_global_stack.addContainer(current_settings_instance_container) ## Check if the machine has extruder trains - extruder_trains = definition.getMetaDataEntry("machine_extruder_trains", {}) - for extruder in extruder_trains: - extruder_train_stack = UM.Settings.ContainerStack(name + "_extruder_" + extruder) - extruder_train_stack.addMetaDataEntry("type", "extruder") - extruder_train_stack.addMetaDataEntry("machine", name) # What global stack is this extruder linked with? - extruder_train_stack.addMetaDataEntry("position", extruder) # What is the position of the extruder (as defined by machine definition) - extruder_definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id=extruder_trains[extruder]) - if extruder_definitions: - extruder_train_stack.addContainer(extruder_definitions[0]) - current_settings_container_extruder = UM.Settings.InstanceContainer(extruder_train_stack.getName() + "_current_settings") - current_settings_container_extruder.addMetaDataEntry("machine", name) - current_settings_container_extruder.addMetaDataEntry("type", "user") - current_settings_container_extruder.setDefinition(definition) - UM.Settings.ContainerRegistry.getInstance().addContainer(current_settings_container_extruder) - extruder_train_stack.addContainer(current_settings_container_extruder) - extruder_train_stack.setNextStack(new_global_stack) - UM.Settings.ContainerRegistry.getInstance().addContainer(extruder_train_stack) - else: - Logger.log("W", "Unable to find definition for extruder") - Application.getInstance().setGlobalContainerStack(new_global_stack) # Create a name that is not empty and unique diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 0eb13d668c..2e62280865 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -79,7 +79,7 @@ ScrollView { id: provider - containerStackId: Cura.MachineManager.activeMachineId + containerStackId: Cura.ExtruderManager.activeExtruderStackId ? Cura.ExtruderManager.activeExtruderStackId : Cura.MachineManager.activeMachineId key: model.key watchedProperties: [ "value", "enabled", "state", "validationState" ] storeIndex: 0 diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 61ccbb998d..b38f65772d 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -111,7 +111,7 @@ Item onClicked: { base.currentExtruderIndex = index - Cura.MachineManager.setActiveExtruderIndex(index) + Cura.ExtruderManager.setActiveExtruderIndex(index) } style: ButtonStyle { From d1be5b6c029d5764436226b53461b1ef600cda46 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 6 Jun 2016 14:17:00 +0200 Subject: [PATCH 465/705] Create extruder train for each train in a machine We had the functionality, but this function was not yet called! Contributes to issues CURA-1278 and CURA-340. --- cura/ExtruderManager.py | 5 +++-- cura/MachineManagerModel.py | 12 ++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 4f23a01808..ccf8a3ad40 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -79,14 +79,14 @@ class ExtruderManager(QObject): self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train.getId() self.extrudersChanged.emit() - def createExtruderTrain(self, definition, extruder_id): + def createExtruderTrain(self, extruder_definition, machine_definition, extruder_id): container_registry = UM.Settings.ContainerRegistry.getInstance() #Create a container stack for this extruder. name = self._uniqueName(extruder_id) container_stack = UM.Settings.ContainerStack(name) container_stack.addMetaDataEntry("type", "extruder_train") - container_stack.addContainer(definition) + container_stack.addContainer(extruder_definition) """ Yes, I'm committing this code which needs to be transformed to work later. @@ -136,6 +136,7 @@ class ExtruderManager(QObject): #Add an empty user profile. user_profile = UM.Settings.InstanceContainer(name + "_current_settings") user_profile.addMetaDataEntry("type", "user") + user_profile.setDefinition(machine_definition) container_stack.addContainer(user_profile) container_registry.addContainer(user_profile) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 3515d613bd..5e811e603d 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -9,7 +9,7 @@ from UM.Logger import Logger import UM.Settings from UM.Settings.Validator import ValidatorState from UM.Settings.InstanceContainer import InstanceContainer - +from . import ExtruderManager class MachineManagerModel(QObject): def __init__(self, parent = None): @@ -133,7 +133,15 @@ class MachineManagerModel(QObject): new_global_stack.addContainer(quality_instance_container) new_global_stack.addContainer(current_settings_instance_container) - ## Check if the machine has extruder trains + for position, extruder_train_id in definitions.getMetaDataEntry("machine_extruder_trains", default = {}).items(): + extruder_definition = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = extruder_train_id) + if extruder_definition: + extruder_definition = extruder_definition[0] + else: + Logger.log("w", "Machine %s references an extruder with ID %s, which doesn't exist.", definition.getName(), extruder_train_id) + continue + ExtruderManager.getInstance().createExtruderTrain(extruder_definition, definition, extruder_train_id) + Application.getInstance().setGlobalContainerStack(new_global_stack) # Create a name that is not empty and unique From 70e6c8093ed56db8bcb50b40a140d7ffe5e4d0da Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 6 Jun 2016 14:19:18 +0200 Subject: [PATCH 466/705] Explicitly return None if no global container stack That's what it does. This is more clear than doing 'pass' or something. Contributes to issues CURA-340 and CURA-1278. --- cura/ExtruderManager.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index ccf8a3ad40..ff29165df5 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -51,11 +51,12 @@ class ExtruderManager(QObject): @pyqtProperty(str, notify = activeExtruderChanged) def activeExtruderStackId(self): - if UM.Application.getInstance().getGlobalContainerStack(): - try: - return self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getId()][str(self._active_extruder_index)] - except KeyError: - pass + if not UM.Application.getInstance().getGlobalContainerStack(): + return None #Whatta ya gonna do? + try: + return self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getId()][str(self._active_extruder_index)] + except KeyError: + return None @pyqtSlot(int) def setActiveExtruderIndex(self, index): From 7950dfaa072bf9208b5c25551e46bac7bb29e011 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 6 Jun 2016 14:31:02 +0200 Subject: [PATCH 467/705] Document activeExtruderStackId Contributes to issues CURA-340, CURA-351 and CURA-1278. --- cura/ExtruderManager.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index ff29165df5..369eb33d51 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -49,13 +49,19 @@ class ExtruderManager(QObject): def __iter__(self): return iter(self._extruders) + ## Gets the unique identifier of the currently active extruder stack. + # + # The currently active extruder stack is the stack that is currently being + # edited. + # + # \return The unique ID of the currently active extruder stack. @pyqtProperty(str, notify = activeExtruderChanged) def activeExtruderStackId(self): if not UM.Application.getInstance().getGlobalContainerStack(): - return None #Whatta ya gonna do? + return None #No active machine, so no active extruder. try: return self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getId()][str(self._active_extruder_index)] - except KeyError: + except KeyError: #Extruder index could be -1 if the global tab is selected, or the entry doesn't exist if the machine definition is wrong. return None @pyqtSlot(int) From 77c918a0a7c92a98e499fb0dba22a4e193fac16f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 6 Jun 2016 14:32:20 +0200 Subject: [PATCH 468/705] Remove superfluous singleton pattern The qmlRegisterSingletonType function already makes sure it is a singleton. Contributes to issues CURA-340 and CURA-1278. --- cura/ExtruderManager.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 369eb33d51..9785c51c2c 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -15,9 +15,6 @@ import UM.Signal #To notify other components of changes in the extruders. # and makes sure that whenever the machine is swapped, this list is kept up to # date. It also contains and updates the setting stacks for the extruders. class ExtruderManager(QObject): - ## The singleton instance of this manager. - __instance = None - ## Signal to notify other components when the list of extruders changes. extrudersChanged = UM.Signal() @@ -33,16 +30,6 @@ class ExtruderManager(QObject): self._repopulate() - ## Gets an instance of this extruder manager. - # - # If an instance was already created, the old instance is returned. This - # implements the singleton pattern. - @classmethod - def getInstance(cls): - if not cls.__instance: - cls.__instance = ExtruderManager() - return cls.__instance - ## Creates an iterator over the extruders in this manager. # # \return An iterator over the extruders in this manager. From 64c92caa58b410ab39c9306747d004568ad5ed5f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 6 Jun 2016 14:48:55 +0200 Subject: [PATCH 469/705] Update documentation of ExtruderManager class Contributes to issues CURA-1278 and CURA-340. --- cura/ExtruderManager.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 9785c51c2c..11cd6d70cc 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -9,11 +9,9 @@ import UM.Settings.ContainerRegistry #Finding containers by ID. import UM.Signal #To notify other components of changes in the extruders. -## Class that handles the current extruder stack. +## Manages all existing extruder stacks. # -# This finds the extruders that are available for the currently active machine -# and makes sure that whenever the machine is swapped, this list is kept up to -# date. It also contains and updates the setting stacks for the extruders. +# This keeps a list of extruder stacks for each machine. class ExtruderManager(QObject): ## Signal to notify other components when the list of extruders changes. extrudersChanged = UM.Signal() From 84a91662417dfb38323d878f5cfc4b15cfed1b28 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 6 Jun 2016 15:06:36 +0200 Subject: [PATCH 470/705] Make extrudersChanged into a pyqtSignal This way we can listen for it on the cute side. Contributes to issues CURA-340 and CURA-1278. --- cura/ExtruderManager.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 11cd6d70cc..b35243df05 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -1,12 +1,11 @@ # Copyright (c) 2016 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. -from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject +from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject #For communicating data and events to Qt. import UM.Application #To get the global container stack to find the current machine. import UM.Logger import UM.Settings.ContainerRegistry #Finding containers by ID. -import UM.Signal #To notify other components of changes in the extruders. ## Manages all existing extruder stacks. @@ -14,7 +13,7 @@ import UM.Signal #To notify other components of changes in the extruders. # This keeps a list of extruder stacks for each machine. class ExtruderManager(QObject): ## Signal to notify other components when the list of extruders changes. - extrudersChanged = UM.Signal() + extrudersChanged = pyqtSignal() ## Notify when the user switches the currently active extruder. activeExtruderChanged = pyqtSignal() From 0b57728d9d7042fff3b5d694732b09a697564779 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 6 Jun 2016 15:55:14 +0200 Subject: [PATCH 471/705] Fix creating a unique name for profiles CURA-1585 --- cura/MachineManagerModel.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 6e1a6185e7..4deea99afc 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -9,7 +9,8 @@ from UM.Logger import Logger import UM.Settings from UM.Settings.Validator import ValidatorState from UM.Settings.InstanceContainer import InstanceContainer - +from UM.i18n import i18nCatalog +catalog = i18nCatalog("cura") class MachineManagerModel(QObject): def __init__(self, parent = None): @@ -118,7 +119,7 @@ class MachineManagerModel(QObject): definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id=definition_id) if definitions: definition = definitions[0] - name = self._createUniqueStackName(name, definition.getName()) + name = self._createUniqueName("machine", name, definition.getName()) new_global_stack = UM.Settings.ContainerStack(name) new_global_stack.addMetaDataEntry("type", "machine") @@ -168,7 +169,7 @@ class MachineManagerModel(QObject): Application.getInstance().setGlobalContainerStack(new_global_stack) # Create a name that is not empty and unique - def _createUniqueStackName(self, name, fallback_name): + def _createUniqueName(self, object_type, name, fallback_name): name = name.strip() num_check = re.compile("(.*?)\s*#\d$").match(name) if(num_check): @@ -179,10 +180,16 @@ class MachineManagerModel(QObject): i = 1 # Check both the id and the name, because they may not be the same and it is better if they are both unique - while UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = unique_name, type = "machine") or \ - UM.Settings.ContainerRegistry.getInstance().findContainerStacks(name = unique_name, type = "machine"): - i += 1 - unique_name = "%s #%d" % (name, i) + if object_type == "machine": + while UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = unique_name, type = "machine") or \ + UM.Settings.ContainerRegistry.getInstance().findContainerStacks(name = unique_name, type = "machine"): + i += 1 + unique_name = "%s #%d" % (name, i) + else: + while UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = unique_name, type = object_type) or \ + UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(name = unique_name, type = object_type): + i += 1 + unique_name = "%s #%d" % (name, i) return unique_name @@ -282,7 +289,7 @@ class MachineManagerModel(QObject): if not self._global_container_stack: return - name = self._createUniqueStackName("Custom profile", "") + name = self._createUniqueName("quality", self.activeQualityName, catalog.i18nc("@label", "Custom profile")) user_settings = self._global_container_stack.getTop() new_quality_container = InstanceContainer("") @@ -311,7 +318,7 @@ class MachineManagerModel(QObject): return containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=container_id) if containers: - new_name = self._createUniqueStackName(containers[0].getName(), "") + new_name = self._createUniqueName("quality", containers[0].getName(), catalog.i18nc("@label", "Custom profile")) new_container = InstanceContainer("") @@ -424,7 +431,7 @@ class MachineManagerModel(QObject): def renameMachine(self, machine_id, new_name): containers = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = machine_id) if containers: - new_name = self._createUniqueStackName(new_name, containers[0].getBottom().getName()) + new_name = self._createUniqueName("machine", new_name, containers[0].getBottom().getName()) containers[0].setName(new_name) self.globalContainerChanged.emit() From df71269f8244ed4c3e15b32a20af241df4463384 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 6 Jun 2016 15:56:45 +0200 Subject: [PATCH 472/705] Mark custom profiles as not read-only CURA-1585 --- cura/MachineManagerModel.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 4deea99afc..ad7669b43a 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -303,7 +303,8 @@ class MachineManagerModel(QObject): new_quality_container.setDefinition(UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = "fdmprinter")[0]) ## Change type / id / name - new_quality_container.setMetaDataEntry("type","quality") + new_quality_container.setMetaDataEntry("type", "quality") + new_quality_container.setMetaDataEntry("read_only", False) new_quality_container.setName(name) new_quality_container._id = name From 03914674c7f105be37a3a7dc222a9659c3d741f4 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Mon, 6 Jun 2016 16:03:16 +0200 Subject: [PATCH 473/705] Cache all of the settings list items instead of recreating them all the time. Fixes CURA-1630 Settings disappear after selecting all options of Experimental Modes --- resources/qml/Settings/SettingView.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 0eb13d668c..ba7b5e32a9 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -24,6 +24,7 @@ ScrollView { id: contents spacing: UM.Theme.getSize("default_lining").height; + cacheBuffer: 1000000; // A huge to cache to effectively cache everything. model: UM.SettingDefinitionsModel { id: definitionsModel; From a2def606c68b1d91fbe15c0dca8ff4fdd3968424 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 6 Jun 2016 17:10:56 +0200 Subject: [PATCH 474/705] Fix Profile (application-)menu and add separators to profiles dropdown CURA-1585 --- resources/qml/Cura.qml | 43 ++++++++++++++++++++-------------- resources/qml/ProfileSetup.qml | 18 ++++---------- 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 851e7c984f..46ebc25369 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -226,7 +226,26 @@ UM.MainWindow Instantiator { id: profileMenuInstantiator -// model: UM.ProfilesModel {} + model: UM.InstanceContainersModel + { + filter: + { + var result = { "type": "quality" }; + if(Cura.MachineManager.filterQualityByMachine) + { + result.definition = Cura.MachineManager.activeDefinitionId; + if(Cura.MachineManager.hasMaterials) + { + result.material = Cura.MachineManager.activeMaterialId; + } + } + else + { + result.definition = "fdmprinter" + } + return result + } + } property int separatorIndex: -1 Loader { @@ -239,13 +258,13 @@ UM.MainWindow { //Insert a separator between readonly and custom profiles if(separatorIndex < 0 && index > 0) { - if(model.getItem(index-1).readOnly != model.getItem(index).readOnly) { + if(model.getItem(index-1).metadata.read_only != model.getItem(index).metadata.read_only) { profileMenu.insertSeparator(index); separatorIndex = index; } } //Because of the separator, custom profiles move one index lower - profileMenu.insertItem((model.getItem(index).readOnly) ? index : index + 1, object.item); + profileMenu.insertItem((model.getItem(index).metadata.read_only) ? index : index + 1, object.item); } onObjectRemoved: { @@ -269,20 +288,10 @@ UM.MainWindow { id: item text: model_data ? model_data.name : "" - checkable: true; - checked: model_data ? model_data.active : false; - exclusiveGroup: profileMenuGroup; - onTriggered: - { - UM.MachineManager.setActiveProfile(model_data.name); - if (!model_data.active) { - //Selecting a profile was canceled; undo menu selection - profileMenuInstantiator.model.setProperty(model_index, "active", false); - var activeProfileName = UM.MachineManager.activeProfile; - var activeProfileIndex = profileMenuInstantiator.model.find("name", activeProfileName); - profileMenuInstantiator.model.setProperty(activeProfileIndex, "active", true); - } - } + checkable: true + checked: Cura.MachineManager.activeQualityId == model_data.id + exclusiveGroup: profileMenuGroup + onTriggered: Cura.MachineManager.setActiveQuality(model_data.id) } } diff --git a/resources/qml/ProfileSetup.qml b/resources/qml/ProfileSetup.qml index 3175a4e2b3..c6291c8c85 100644 --- a/resources/qml/ProfileSetup.qml +++ b/resources/qml/ProfileSetup.qml @@ -88,13 +88,13 @@ Item{ { //Insert a separator between readonly and custom profiles if(separatorIndex < 0 && index > 0) { - if(model.getItem(index-1).readOnly != model.getItem(index).readOnly) { + if(model.getItem(index-1).metadata.read_only != model.getItem(index).metadata.read_only) { profileSelectionMenu.insertSeparator(index); separatorIndex = index; } } //Because of the separator, custom profiles move one index lower - profileSelectionMenu.insertItem((model.getItem(index).readOnly) ? index : index + 1, object.item); + profileSelectionMenu.insertItem((model.getItem(index).metadata.read_only) ? index : index + 1, object.item); } onObjectRemoved: { @@ -117,20 +117,10 @@ Item{ { id: item text: model_data ? model_data.name : "" - checkable: true; + checkable: true checked: Cura.MachineManager.activeQualityId == model_data.id exclusiveGroup: profileSelectionMenuGroup; - onTriggered: - { - Cura.MachineManager.setActiveQuality(model_data.id); - /*if (!model_data.active) { - //Selecting a profile was canceled; undo menu selection - profileSelectionInstantiator.model.setProperty(model_index, "active", false); - var activeProfileName = UM.MachineManager.activeProfile; - var activeProfileIndex = profileSelectionInstantiator.model.find("name", activeProfileName); - profileSelectionInstantiator.model.setProperty(activeProfileIndex, "active", true); - }*/ - } + onTriggered: Cura.MachineManager.setActiveQuality(model_data.id) } } From 5235f74adfc68420587a3e0d570a3ff3bc66ec5a Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 6 Jun 2016 17:47:33 +0200 Subject: [PATCH 475/705] Prevent unique names like "profile #10 #2" CURA-1606, CURA-1585 --- cura/MachineManagerModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index e57294d871..6d6ff10a4b 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -149,7 +149,7 @@ class MachineManagerModel(QObject): # Create a name that is not empty and unique def _createUniqueName(self, object_type, name, fallback_name): name = name.strip() - num_check = re.compile("(.*?)\s*#\d$").match(name) + num_check = re.compile("(.*?)\s*#\d+$").match(name) if(num_check): name = num_check.group(1) if name == "": From efe3f5e4ee08c3dea2104dc35b29c0b7bc408d4a Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 6 Jun 2016 17:53:34 +0200 Subject: [PATCH 476/705] Remove dependency on QtQml.Models CURA-1278 --- resources/qml/GeneralPage.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/GeneralPage.qml b/resources/qml/GeneralPage.qml index dcd5c66d73..0ae783916b 100644 --- a/resources/qml/GeneralPage.qml +++ b/resources/qml/GeneralPage.qml @@ -5,7 +5,6 @@ import QtQuick 2.1 import QtQuick.Controls 1.1 import QtQuick.Layouts 1.1 import QtQuick.Controls.Styles 1.1 -import QtQml.Models 2.2 import UM 1.1 as UM @@ -207,10 +206,11 @@ UM.PreferencesPage } } - DelegateModel + ListView { id: plugins model: UM.PluginsModel { } + visible: false } } } From 35706734e696ca0c360c4f607b81be21ea6736d3 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 6 Jun 2016 23:13:25 +0200 Subject: [PATCH 477/705] Show settings on Profile page CURA-1585 --- 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 f5d3169508..52ab10cfd6 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -144,7 +144,7 @@ UM.ManagementPage Repeater { model: base.currentItem ? base.currentItem.settings : null Label { - text: modelData.name.toString(); + text: modelData.label elide: Text.ElideMiddle; } } From 05643eca11e8c4cd58645d519db67ad90a4bf4e7 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 7 Jun 2016 08:11:53 +0200 Subject: [PATCH 478/705] Fix renaming profiles from the Profiles page CURA-1585 --- cura/MachineManagerModel.py | 9 +++++++++ resources/qml/Preferences/ProfilesPage.qml | 14 +++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 6d6ff10a4b..6e0e0a6127 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -312,6 +312,15 @@ class MachineManagerModel(QObject): return "" + @pyqtSlot(str, str) + def renameQualityContainer(self, container_id, new_name): + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id, type = "quality") + if containers: + new_name = self._createUniqueName("machine", new_name, catalog.i18nc("@label", "Custom profile")) + containers[0].setName(new_name) + UM.Settings.ContainerRegistry.getInstance().containerChanged.emit(containers[0]) + + @pyqtSlot(str) def removeQualityContainer(self, container_id): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 52ab10cfd6..c031ed9f20 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -184,19 +184,19 @@ UM.ManagementPage UM.ConfirmRemoveDialog { - id: confirmDialog; - object: base.currentItem != null ? base.currentItem.name : ""; - onYes: Cura.MachineManager.removeQualityContainer(base.currentItem.id); + id: confirmDialog + object: base.currentItem != null ? base.currentItem.name : "" + onYes: Cura.MachineManager.removeQualityContainer(base.currentItem.id) } UM.RenameDialog { id: renameDialog; - object: base.currentItem != null ? base.currentItem.name : ""; - property bool removeWhenRejected: false; - onAccepted: base.model.rename(base.currentItem.id, newName.trim()); + object: base.currentItem != null ? base.currentItem.name : "" + property bool removeWhenRejected: false + onAccepted: Cura.MachineManager.renameQualityContainer(base.currentItem.id, newName) onRejected: { if(removeWhenRejected) { - base.model.removeProfile(base.currentItem.name) + Cura.MachineManager.removeQualityContainer(base.currentItem.id) } } } From 0a84867132f899288be59a72ba17b810e81fce87 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 7 Jun 2016 09:33:29 +0200 Subject: [PATCH 479/705] Fixed multiple typos / missing things in extrudermanager --- cura/ExtruderManager.py | 28 ++++++++++++++++++++++++++++ cura/MachineManagerModel.py | 4 ++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index b35243df05..aae90afdc5 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -6,6 +6,7 @@ from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject #For commun import UM.Application #To get the global container stack to find the current machine. import UM.Logger import UM.Settings.ContainerRegistry #Finding containers by ID. +import re ## Manages all existing extruder stacks. @@ -48,6 +49,13 @@ class ExtruderManager(QObject): except KeyError: #Extruder index could be -1 if the global tab is selected, or the entry doesn't exist if the machine definition is wrong. return None + __instance = None + @classmethod + def getInstance(cls): + if not cls.__instance: + cls.__instance = ExtruderManager() + return cls.__instance + @pyqtSlot(int) def setActiveExtruderIndex(self, index): self._active_extruder_index = index @@ -135,5 +143,25 @@ class ExtruderManager(QObject): container_registry.addContainer(container_stack) + + def _uniqueName(self, extruder): + container_registry = UM.Settings.ContainerRegistry.getInstance() + + name = extruder.strip() + num_check = re.compile("(.*?)\s*#\d$").match(name) + if num_check: # There is a number in the name. + name = num_check.group(1) # Filter out the number. + if name == "": # Wait, that deleted everything! + name = "Extruder" + unique_name = name + + i = 1 + while container_registry.findContainers(id=unique_name) or container_registry.findContainers( + name=unique_name): # A container already has this name. + i += 1 # Try next numbering. + unique_name = "%s #%d" % (name, i) # Fill name like this: "Extruder #2". + return unique_name + + def createExtruderManager(engine, script_engine): return ExtruderManager() \ No newline at end of file diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 6d6ff10a4b..e2c097daf5 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -135,14 +135,14 @@ class MachineManagerModel(QObject): new_global_stack.addContainer(quality_instance_container) new_global_stack.addContainer(current_settings_instance_container) - for position, extruder_train_id in definitions.getMetaDataEntry("machine_extruder_trains", default = {}).items(): + for position, extruder_train_id in definition.getMetaDataEntry("machine_extruder_trains", default = {}).items(): extruder_definition = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = extruder_train_id) if extruder_definition: extruder_definition = extruder_definition[0] else: Logger.log("w", "Machine %s references an extruder with ID %s, which doesn't exist.", definition.getName(), extruder_train_id) continue - ExtruderManager.getInstance().createExtruderTrain(extruder_definition, definition, extruder_train_id) + ExtruderManager.ExtruderManager.getInstance().createExtruderTrain(extruder_definition, definition, extruder_train_id) Application.getInstance().setGlobalContainerStack(new_global_stack) From a6870b555b644f2fa91ea313f010551d4f64b61a Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Tue, 7 Jun 2016 10:34:08 +0200 Subject: [PATCH 480/705] Fix up my comment, make it clearer. Fixes CURA-1630 Settings disappear after selecting all options of Experimental Modes --- resources/qml/Settings/SettingView.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index ed66661a8e..7191bff3ef 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -24,7 +24,7 @@ ScrollView { id: contents spacing: UM.Theme.getSize("default_lining").height; - cacheBuffer: 1000000; // A huge to cache to effectively cache everything. + cacheBuffer: 1000000; // Set a large cache to effectively just cache every list item. model: UM.SettingDefinitionsModel { id: definitionsModel; From ce388c4b231aaedc8377668b6c27cdc9d7ed96d8 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 7 Jun 2016 11:18:09 +0200 Subject: [PATCH 481/705] Show settings in profile as a sorted list with section headers CURA-1585 --- resources/qml/Preferences/ProfilesPage.qml | 103 ++++++++++----------- 1 file changed, 48 insertions(+), 55 deletions(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index c031ed9f20..28248b23f4 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -91,70 +91,63 @@ UM.ManagementPage elide: Text.ElideRight } - ScrollView { + Row { + id: currentSettingsActions + visible: base.currentItem.id == -1 || currentItem.id == Cura.MachineManager.activeQualityId + anchors.left: parent.left anchors.top: profileName.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height + + Button + { + text: { + var profileName = Cura.MachineManager.activeQualityName; + profileName = (profileName.length > 20) ? profileName.substring(0, 20) + '...' : profileName; + return catalog.i18nc("@action:button", "Update \"%1\"".arg(profileName)); + } + enabled: Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) + onClicked: Cura.MachineManager.updateUserContainerToQuality() + } + + Button + { + text: catalog.i18nc("@action:button", "Discard changes"); + enabled: Cura.MachineManager.hasUserSettings + onClicked: Cura.MachineManager.clearUserSettings(); + } + } + + ScrollView { + id: scrollView + + anchors.left: parent.left + anchors.top: currentSettingsActions.visible ? currentSettingsActions.bottom : profileName.bottom + anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.right: parent.right anchors.bottom: parent.bottom - Column - { - spacing: UM.Theme.getSize("default_margin").height - - Row - { - visible: base.currentItem.id == -1 || currentItem.id == Cura.MachineManager.activeQualityId - Button - { - text: { - var profileName = Cura.MachineManager.activeQualityName; - profileName = (profileName.length > 20) ? profileName.substring(0, 20) + '...' : profileName; - return catalog.i18nc("@action:button", "Update \"%1\"".arg(profileName)); - } - enabled: Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) - onClicked: Cura.MachineManager.updateUserContainerToQuality() + ListView { + model: base.currentItem ? base.currentItem.settings: null + delegate: Row { + spacing: UM.Theme.getSize("default_margin").width + Label { + text: model.label + elide: Text.ElideMiddle + width: scrollView.width / 100 * 40 } - - Button - { - text: catalog.i18nc("@action:button", "Discard changes"); - enabled: Cura.MachineManager.hasUserSettings - onClicked: Cura.MachineManager.clearUserSettings(); + Label { + text: model.value.toString() + } + Label { + text: model.unit } } - - Grid - { - id: containerGrid - columns: 2 - spacing: UM.Theme.getSize("default_margin").width - - Label { - text: base.currentItem == null ? "" : - base.currentItem.id == -1 ? catalog.i18nc("@label", "Based on") : catalog.i18nc("@label", "Profile type") - } - Label { - text: base.currentItem == null ? "" : - base.currentItem.id == -1 ? Cura.MachineManager.activeQualityName: - base.currentItem.metadata.read_only ? catalog.i18nc("@label", "Protected profile") : catalog.i18nc("@label", "Custom profile") - } - - Column { - Repeater { - model: base.currentItem ? base.currentItem.settings : null - Label { - text: modelData.label - elide: Text.ElideMiddle; - } - } - } - Column { - Repeater { - model: base.currentItem ? base.currentItem.settings : null - Label { text: modelData.value.toString(); } - } - } + section.property: "category" + section.criteria: ViewSection.FullString + section.delegate: Label { + text: section + font.bold: true } } } From 889844e34bfd5733aa23e58a392ca9f2f031cfd3 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Tue, 7 Jun 2016 11:39:23 +0200 Subject: [PATCH 482/705] profiles: speed changes (extra overrides) (CURA-1662) --- resources/profiles/ultimaker2+/abs_0.4_fast.curaprofile | 2 ++ resources/profiles/ultimaker2+/abs_0.4_high.curaprofile | 1 + resources/profiles/ultimaker2+/abs_0.4_normal.curaprofile | 1 + resources/profiles/ultimaker2+/abs_0.6_normal.curaprofile | 1 + resources/profiles/ultimaker2+/cpe_0.4_fast.curaprofile | 1 + resources/profiles/ultimaker2+/cpe_0.4_high.curaprofile | 1 + resources/profiles/ultimaker2+/cpe_0.4_normal.curaprofile | 1 + resources/profiles/ultimaker2+/pla_0.4_fast.curaprofile | 2 ++ resources/profiles/ultimaker2+/pla_0.4_high.curaprofile | 1 + resources/profiles/ultimaker2+/pla_0.4_normal.curaprofile | 1 + resources/profiles/ultimaker2+/pla_0.6_normal.curaprofile | 3 +++ resources/profiles/ultimaker2+/pla_0.8_normal.curaprofile | 1 + 12 files changed, 16 insertions(+) diff --git a/resources/profiles/ultimaker2+/abs_0.4_fast.curaprofile b/resources/profiles/ultimaker2+/abs_0.4_fast.curaprofile index 50018372b5..96e99f8a3d 100644 --- a/resources/profiles/ultimaker2+/abs_0.4_fast.curaprofile +++ b/resources/profiles/ultimaker2+/abs_0.4_fast.curaprofile @@ -12,6 +12,8 @@ wall_thickness = 0.7 top_bottom_thickness = 0.75 infill_sparse_density = 18 speed_print = 55 +speed_wall = 40 +speed_topbottom = 30 speed_travel = 150 speed_layer_0 = 30 cool_min_layer_time = 3 diff --git a/resources/profiles/ultimaker2+/abs_0.4_high.curaprofile b/resources/profiles/ultimaker2+/abs_0.4_high.curaprofile index 341c9cc34f..66a72e17bf 100644 --- a/resources/profiles/ultimaker2+/abs_0.4_high.curaprofile +++ b/resources/profiles/ultimaker2+/abs_0.4_high.curaprofile @@ -12,6 +12,7 @@ wall_thickness = 1.05 top_bottom_thickness = 0.72 infill_sparse_density = 22 speed_print = 45 +speed_wall = 30 cool_min_layer_time = 3 cool_fan_speed_min = 20 cool_min_speed = 10 diff --git a/resources/profiles/ultimaker2+/abs_0.4_normal.curaprofile b/resources/profiles/ultimaker2+/abs_0.4_normal.curaprofile index d8fce8a4dd..c6baaf448e 100644 --- a/resources/profiles/ultimaker2+/abs_0.4_normal.curaprofile +++ b/resources/profiles/ultimaker2+/abs_0.4_normal.curaprofile @@ -12,6 +12,7 @@ wall_thickness = 1.05 top_bottom_thickness = 0.8 infill_sparse_density = 20 speed_print = 45 +speed_wall = 30 cool_min_layer_time = 3 cool_fan_speed_min = 20 cool_min_speed = 10 diff --git a/resources/profiles/ultimaker2+/abs_0.6_normal.curaprofile b/resources/profiles/ultimaker2+/abs_0.6_normal.curaprofile index 5512450471..9699b4e0c9 100644 --- a/resources/profiles/ultimaker2+/abs_0.6_normal.curaprofile +++ b/resources/profiles/ultimaker2+/abs_0.6_normal.curaprofile @@ -12,6 +12,7 @@ wall_thickness = 1.59 top_bottom_thickness = 1.2 infill_sparse_density = 20 speed_print = 40 +speed_infill = 55 cool_min_layer_time = 3 cool_fan_speed_min = 50 cool_min_speed = 20 diff --git a/resources/profiles/ultimaker2+/cpe_0.4_fast.curaprofile b/resources/profiles/ultimaker2+/cpe_0.4_fast.curaprofile index f9050e5ce5..550b8f46e3 100644 --- a/resources/profiles/ultimaker2+/cpe_0.4_fast.curaprofile +++ b/resources/profiles/ultimaker2+/cpe_0.4_fast.curaprofile @@ -12,6 +12,7 @@ wall_thickness = 0.7 top_bottom_thickness = 0.75 infill_sparse_density = 18 speed_print = 45 +speed_wall = 40 speed_travel = 150 speed_layer_0 = 30 cool_min_layer_time = 3 diff --git a/resources/profiles/ultimaker2+/cpe_0.4_high.curaprofile b/resources/profiles/ultimaker2+/cpe_0.4_high.curaprofile index 377ab5b257..88db3c4bec 100644 --- a/resources/profiles/ultimaker2+/cpe_0.4_high.curaprofile +++ b/resources/profiles/ultimaker2+/cpe_0.4_high.curaprofile @@ -12,6 +12,7 @@ wall_thickness = 1.05 top_bottom_thickness = 0.72 infill_sparse_density = 22 speed_print = 45 +speed_wall = 30 cool_min_layer_time = 2 cool_fan_speed_min = 80 cool_min_speed = 15 diff --git a/resources/profiles/ultimaker2+/cpe_0.4_normal.curaprofile b/resources/profiles/ultimaker2+/cpe_0.4_normal.curaprofile index e8142405ff..91a82753ac 100644 --- a/resources/profiles/ultimaker2+/cpe_0.4_normal.curaprofile +++ b/resources/profiles/ultimaker2+/cpe_0.4_normal.curaprofile @@ -12,6 +12,7 @@ wall_thickness = 1.05 top_bottom_thickness = 0.8 infill_sparse_density = 20 speed_print = 45 +speed_wall = 30 cool_min_layer_time = 3 cool_fan_speed_min = 80 cool_min_speed = 10 diff --git a/resources/profiles/ultimaker2+/pla_0.4_fast.curaprofile b/resources/profiles/ultimaker2+/pla_0.4_fast.curaprofile index 06e401c139..c03c8ce621 100644 --- a/resources/profiles/ultimaker2+/pla_0.4_fast.curaprofile +++ b/resources/profiles/ultimaker2+/pla_0.4_fast.curaprofile @@ -12,6 +12,8 @@ wall_thickness = 0.7 top_bottom_thickness = 0.75 infill_sparse_density = 18 speed_print = 60 +speed_wall = 50 +speed_topbottom = 30 speed_travel = 150 speed_layer_0 = 30 cool_min_layer_time = 5 diff --git a/resources/profiles/ultimaker2+/pla_0.4_high.curaprofile b/resources/profiles/ultimaker2+/pla_0.4_high.curaprofile index 5e2f762354..7cba49b71e 100644 --- a/resources/profiles/ultimaker2+/pla_0.4_high.curaprofile +++ b/resources/profiles/ultimaker2+/pla_0.4_high.curaprofile @@ -12,5 +12,6 @@ wall_thickness = 1.05 top_bottom_thickness = 0.72 infill_sparse_density = 22 speed_print = 50 +speed_topbottom = 20 cool_min_layer_time = 5 cool_min_speed = 10 diff --git a/resources/profiles/ultimaker2+/pla_0.4_normal.curaprofile b/resources/profiles/ultimaker2+/pla_0.4_normal.curaprofile index 689a3251b2..4989b0e780 100644 --- a/resources/profiles/ultimaker2+/pla_0.4_normal.curaprofile +++ b/resources/profiles/ultimaker2+/pla_0.4_normal.curaprofile @@ -12,5 +12,6 @@ wall_thickness = 1.05 top_bottom_thickness = 0.8 infill_sparse_density = 20 speed_print = 50 +speed_topbottom = 20 cool_min_layer_time = 5 cool_min_speed = 10 diff --git a/resources/profiles/ultimaker2+/pla_0.6_normal.curaprofile b/resources/profiles/ultimaker2+/pla_0.6_normal.curaprofile index 188ed42a95..767a3d5ef5 100644 --- a/resources/profiles/ultimaker2+/pla_0.6_normal.curaprofile +++ b/resources/profiles/ultimaker2+/pla_0.6_normal.curaprofile @@ -12,5 +12,8 @@ wall_thickness = 1.59 top_bottom_thickness = 1.2 infill_sparse_density = 20 speed_print = 55 +speed_wall = 40 +speed_wall_0 = 25 +speed_topbottom = 20 cool_min_layer_time = 5 cool_min_speed = 10 diff --git a/resources/profiles/ultimaker2+/pla_0.8_normal.curaprofile b/resources/profiles/ultimaker2+/pla_0.8_normal.curaprofile index 92cb4a6054..a8d50c78df 100644 --- a/resources/profiles/ultimaker2+/pla_0.8_normal.curaprofile +++ b/resources/profiles/ultimaker2+/pla_0.8_normal.curaprofile @@ -12,5 +12,6 @@ wall_thickness = 2.1 top_bottom_thickness = 1.2 infill_sparse_density = 20 speed_print = 40 +speed_wall_0 = 25 cool_min_layer_time = 5 cool_min_speed = 10 From 890303da146a77d6be6be51bb1eda1104930f556 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 11:33:10 +0200 Subject: [PATCH 483/705] Add function to add all extruder trains of a machine This function only adds extruder trains if they have not been added already. Contributes to issues CURA-340 and CURA-1278. --- cura/ExtruderManager.py | 41 +++++++++++++++++++++++++++++++++---- cura/MachineManagerModel.py | 9 +------- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index aae90afdc5..8c467ede00 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -61,6 +61,38 @@ class ExtruderManager(QObject): self._active_extruder_index = index self.activeExtruderChanged.emit() + ## Adds all extruders of a specific machine definition to the extruder + # manager. + # + # \param machine_definition The machine to add the extruders for. + def addMachineExtruders(self, machine_definition): + machine_id = machine_definition.getId() + if not self._extruder_trains[machine_id]: + self._extruder_trains[machine_id] = { } + + container_registry = UM.Settings.ContainerRegistry.getInstance() + if not container_registry: #Then we shouldn't have any machine definition either. In any case, there are no extruder trains then so bye bye. + return + + #Add the extruder trains that don't exist yet. + for position, extruder_definition_id in machine_definition.getMetaDataEntry("machine_extruder_trains", default = {}).items(): + extruder_definition = container_registry.findDefinitionContainers(id = extruder_definition_id) + if extruder_definition: + extruder_definition = extruder_definition[0] + else: + Logger.log("w", "Machine %s references an extruder with ID %s, which doesn't exist.", machine_definition.getName(), extruder_definition_id) + continue + name = self._uniqueName(extruder_definition_id) #Make a name based on the ID of the definition. + if not container_registry.findContainerStacks(id = name): #Doesn't exist yet. + self.createExtruderTrain(extruder_definition, machine_definition, name, position) + + #Gets the extruder trains that we just created as well as any that still existed. + extruder_trains = container_registry.findContainerStacks(type = "extruder_train", machine = machine_definition.getId()) + for extruder_train in extruder_trains: + self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train.getId() + if extruder_trains: + self.extrudersChanged.emit() + ## (Re)populates the collections of extruders by machine. def _repopulate(self): self._extruder_trains = { } @@ -78,13 +110,14 @@ class ExtruderManager(QObject): self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train.getId() self.extrudersChanged.emit() - def createExtruderTrain(self, extruder_definition, machine_definition, extruder_id): + def createExtruderTrain(self, extruder_definition, machine_definition, extruder_train_id, position): container_registry = UM.Settings.ContainerRegistry.getInstance() #Create a container stack for this extruder. - name = self._uniqueName(extruder_id) - container_stack = UM.Settings.ContainerStack(name) + container_stack = UM.Settings.ContainerStack(extruder_train_id) container_stack.addMetaDataEntry("type", "extruder_train") + container_stack.addMetaDataEntry("machine", machine_definition.getId()) + container_stack.addMetaDataEntry("position", position) container_stack.addContainer(extruder_definition) """ @@ -133,7 +166,7 @@ class ExtruderManager(QObject): """ #Add an empty user profile. - user_profile = UM.Settings.InstanceContainer(name + "_current_settings") + user_profile = UM.Settings.InstanceContainer(extruder_train_id + "_current_settings") user_profile.addMetaDataEntry("type", "user") user_profile.setDefinition(machine_definition) container_stack.addContainer(user_profile) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 576cf1acc0..86e74e8302 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -135,14 +135,7 @@ class MachineManagerModel(QObject): new_global_stack.addContainer(quality_instance_container) new_global_stack.addContainer(current_settings_instance_container) - for position, extruder_train_id in definition.getMetaDataEntry("machine_extruder_trains", default = {}).items(): - extruder_definition = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = extruder_train_id) - if extruder_definition: - extruder_definition = extruder_definition[0] - else: - Logger.log("w", "Machine %s references an extruder with ID %s, which doesn't exist.", definition.getName(), extruder_train_id) - continue - ExtruderManager.ExtruderManager.getInstance().createExtruderTrain(extruder_definition, definition, extruder_train_id) + ExtruderManager.ExtruderManager.getInstance().addMachineExtruders(definition) Application.getInstance().setGlobalContainerStack(new_global_stack) From 9fe543596316fb11c5478b750465f958228983a9 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 11:34:00 +0200 Subject: [PATCH 484/705] Rename parameter in _uniqueName Original means the original name. That's better. Contributes to issues CURA-1278 and CURA-340. --- cura/ExtruderManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 8c467ede00..15fbbe2a1c 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -177,10 +177,10 @@ class ExtruderManager(QObject): container_registry.addContainer(container_stack) - def _uniqueName(self, extruder): + def _uniqueName(self, original): container_registry = UM.Settings.ContainerRegistry.getInstance() - name = extruder.strip() + name = original.strip() num_check = re.compile("(.*?)\s*#\d$").match(name) if num_check: # There is a number in the name. name = num_check.group(1) # Filter out the number. From dff94b4559e558aeadea7a8694393557b838c3f5 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 11:54:16 +0200 Subject: [PATCH 485/705] Make ExtruderManager a QML context item There were two singletons of this manager: One created by QML and managed by QML, and one created by us and managed by our own singleton pattern. That won't work! So we now manage just our own singleton type, and make it a context item for QML so it can use the manager too. Contributes to issues CURA-340 and CURA-1278. --- cura/CuraApplication.py | 7 +++++-- cura/ExtruderManager.py | 6 +----- resources/qml/Settings/SettingView.qml | 2 +- resources/qml/SidebarHeader.qml | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 126d8b2864..7edb0bf8bd 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -353,8 +353,6 @@ class CuraApplication(QtApplication): qmlRegisterSingletonType(MachineManagerModel.MachineManagerModel, "Cura", 1, 0, "MachineManager", MachineManagerModel.createMachineManagerModel) - qmlRegisterSingletonType(ExtruderManager.ExtruderManager, "Cura", 1, 0, "ExtruderManager", - ExtruderManager.createExtruderManager) self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml")) self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles)) @@ -386,6 +384,9 @@ class CuraApplication(QtApplication): def getPrintInformation(self): return self._print_information + ## Registers objects for the QML engine to use. + # + # \param engine The QML engine. def registerObjects(self, engine): engine.rootContext().setContextProperty("Printer", self) self._print_information = PrintInformation.PrintInformation() @@ -399,6 +400,8 @@ class CuraApplication(QtApplication): qmlRegisterSingletonType(QUrl.fromLocalFile(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")), "Cura", 1, 0, "Actions") + engine.rootContext().setContextProperty("ExtruderManager", ExtruderManager.ExtruderManager.getInstance()) + for path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.QmlFiles): type_name = os.path.splitext(os.path.basename(path))[0] if type_name in ("Cura", "Actions"): diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 15fbbe2a1c..4f8c58be07 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -76,7 +76,7 @@ class ExtruderManager(QObject): #Add the extruder trains that don't exist yet. for position, extruder_definition_id in machine_definition.getMetaDataEntry("machine_extruder_trains", default = {}).items(): - extruder_definition = container_registry.findDefinitionContainers(id = extruder_definition_id) + extruder_definition = container_registry.findDefinitionContainers(machine = machine_definition.getId()) if extruder_definition: extruder_definition = extruder_definition[0] else: @@ -194,7 +194,3 @@ class ExtruderManager(QObject): i += 1 # Try next numbering. unique_name = "%s #%d" % (name, i) # Fill name like this: "Extruder #2". return unique_name - - -def createExtruderManager(engine, script_engine): - return ExtruderManager() \ No newline at end of file diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 7191bff3ef..6261496c84 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -80,7 +80,7 @@ ScrollView { id: provider - containerStackId: Cura.ExtruderManager.activeExtruderStackId ? Cura.ExtruderManager.activeExtruderStackId : Cura.MachineManager.activeMachineId + containerStackId: ExtruderManager.activeExtruderStackId ? ExtruderManager.activeExtruderStackId : Cura.MachineManager.activeMachineId key: model.key watchedProperties: [ "value", "enabled", "state", "validationState" ] storeIndex: 0 diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index b38f65772d..237746ac0d 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -111,7 +111,7 @@ Item onClicked: { base.currentExtruderIndex = index - Cura.ExtruderManager.setActiveExtruderIndex(index) + ExtruderManager.setActiveExtruderIndex(index) } style: ButtonStyle { From 66bf0831f310e7f56090843d31db0ba057218903 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 11:55:07 +0200 Subject: [PATCH 486/705] Document _uniqueName This function should really just be moved to ContainerRegistry... I'll do that later. Contributes to issues CURA-340 and CURA-1278. --- cura/ExtruderManager.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 4f8c58be07..f8bcd75151 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -176,7 +176,14 @@ class ExtruderManager(QObject): container_registry.addContainer(container_stack) - + ## Creates a new unique name for a container that doesn't exist yet. + # + # It tries if the original name you provide exists, and if it doesn't + # it'll add a " #1" or " #2" after the name to make it unique. + # + # \param original The original name that may not be unique. + # \return A unique name that looks a lot like the original but may have + # a number behind it to make it unique. def _uniqueName(self, original): container_registry = UM.Settings.ContainerRegistry.getInstance() @@ -189,8 +196,7 @@ class ExtruderManager(QObject): unique_name = name i = 1 - while container_registry.findContainers(id=unique_name) or container_registry.findContainers( - name=unique_name): # A container already has this name. + while container_registry.findContainers(id = unique_name) or container_registry.findContainers(name = unique_name): # A container already has this name. i += 1 # Try next numbering. unique_name = "%s #%d" % (name, i) # Fill name like this: "Extruder #2". return unique_name From 4fb66afe069ba9f6b7dff397448d6f659232cb79 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 7 Jun 2016 11:58:44 +0200 Subject: [PATCH 487/705] Mark duplicated profiles as non-read-only CURA-1585 --- cura/MachineManagerModel.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 576cf1acc0..e179eb2ebd 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -304,6 +304,7 @@ class MachineManagerModel(QObject): ## Copy all values new_container.deserialize(containers[0].serialize()) + new_container.setMetaDataEntry("read_only", False) new_container.setName(new_name) new_container._id = new_name UM.Settings.ContainerRegistry.getInstance().addContainer(new_container) From b14b05d6fb5615b5c8fc30f228d430b4017a4fcc Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Tue, 7 Jun 2016 12:12:14 +0200 Subject: [PATCH 488/705] JSON: upped the retraction_count_max further up to 90 (CURA-1662) --- resources/machines/fdmprinter.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/machines/fdmprinter.json b/resources/machines/fdmprinter.json index 2b172d1720..a523627b7d 100644 --- a/resources/machines/fdmprinter.json +++ b/resources/machines/fdmprinter.json @@ -760,7 +760,7 @@ "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": 45, + "default": 90, "min_value": "0", "max_value_warning": "100", "type": "int", From 68837a089ad46ca990969188169bcd0b69de6e06 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 7 Jun 2016 12:50:57 +0200 Subject: [PATCH 489/705] Moved some properties to bindings due to bug in qt 5.5.1 CURA-1494 --- resources/qml/Settings/SettingItem.qml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index f476349c42..e4edc267ef 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -22,6 +22,10 @@ Item { property var showInheritButton: true property var doDepthIdentation: true + // Create properties to put property provider stuff in (bindings break in qt 5.5.1 otherwise) + property var state: propertyProvider.properties.state + property var stackLevel: propertyProvider.stackLevel + signal contextMenuRequested() signal showTooltip(string text); signal hideTooltip(); @@ -128,7 +132,7 @@ Item { { id: revertButton; - visible: propertyProvider.stackLevel == 0 && base.showRevertButton + visible: base.stackLevel == 0 && base.showRevertButton height: parent.height; width: height; @@ -155,14 +159,14 @@ Item { id: inheritButton; //visible: has_profile_value && base.has_inherit_function && base.is_enabled - visible: propertyProvider.properties.state == "InstanceState.User" && propertyProvider.stackLevel > 0 && base.showInheritButton + visible: base.state == "InstanceState.User" && base.stackLevel > 0 && base.showInheritButton height: parent.height; width: height; onClicked: { focus = true; - propertyProvider.removeFromContainer(propertyProvider.stackLevel) + propertyProvider.removeFromContainer(base.stackLevel) } backgroundColor: UM.Theme.getColor("setting_control"); From ca1b199c7e4d57e4ef071b64add53ad2d895be3d Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 7 Jun 2016 13:17:35 +0200 Subject: [PATCH 490/705] Fix PerObjectSettings to use the right objects when instantiating setting items Contributes to CURA-1592 --- .../PerObjectSettingsPanel.qml | 62 ++++++++++++++++--- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index 8ab05e90c1..c89485517e 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -64,24 +64,26 @@ Item { settingLoader.item.doDepthIdentation = false } - source: + sourceComponent: { - switch(model.type) // TODO: This needs to be fixed properly. Got frustrated with it not working, so this is the patch job! + switch(model.type) { case "int": - return "../../resources/qml/Settings/SettingTextField.qml" + return settingTextField case "float": - return "../../resources/qml/Settings/SettingTextField.qml" + return settingTextField case "enum": - return "../../resources/qml/Settings/SettingComboBox.qml" + return settingComboBox + case "extruder": + return settingExtruder case "bool": - return "../../resources/qml/Settings/SettingCheckBox.qml" + return settingCheckBox case "str": - return "../../resources/qml/Settings/SettingTextField.qml" + return settingTextField case "category": - return "../../resources/qml/Settings/SettingCategory.qml" + return settingCategory default: - return "../../resources/qml/Settings/SettingUnknown.qml" + return settingUnknown } } } @@ -257,4 +259,46 @@ Item { } SystemPalette { id: palette; } + + Component + { + id: settingTextField; + + Cura.SettingTextField { } + } + + Component + { + id: settingComboBox; + + Cura.SettingComboBox { } + } + + Component + { + id: settingExtruder; + + Cura.SettingExtruder { } + } + + Component + { + id: settingCheckBox; + + Cura.SettingCheckBox { } + } + + Component + { + id: settingCategory; + + Cura.SettingCategory { } + } + + Component + { + id: settingUnknown; + + Cura.SettingUnknown { } + } } From 227c0f9f8c9d71d264f1959c18b2fdf550f05a5b Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 12:01:12 +0200 Subject: [PATCH 491/705] Move _uniqueName to ContainerRegistry It's not specific to any type of container and we might re-use this anyway. Contributes to issues CURA-1278 and CURA-340. --- cura/ExtruderManager.py | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index f8bcd75151..31943be747 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -26,8 +26,6 @@ class ExtruderManager(QObject): self._next_item = 0 #For when you use this class as iterator. self._active_extruder_index = 0 - self._repopulate() - ## Creates an iterator over the extruders in this manager. # # \return An iterator over the extruders in this manager. @@ -82,7 +80,7 @@ class ExtruderManager(QObject): else: Logger.log("w", "Machine %s references an extruder with ID %s, which doesn't exist.", machine_definition.getName(), extruder_definition_id) continue - name = self._uniqueName(extruder_definition_id) #Make a name based on the ID of the definition. + name = container_registry.uniqueName(extruder_definition_id) #Make a name based on the ID of the definition. if not container_registry.findContainerStacks(id = name): #Doesn't exist yet. self.createExtruderTrain(extruder_definition, machine_definition, name, position) @@ -175,28 +173,3 @@ class ExtruderManager(QObject): container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack()) container_registry.addContainer(container_stack) - - ## Creates a new unique name for a container that doesn't exist yet. - # - # It tries if the original name you provide exists, and if it doesn't - # it'll add a " #1" or " #2" after the name to make it unique. - # - # \param original The original name that may not be unique. - # \return A unique name that looks a lot like the original but may have - # a number behind it to make it unique. - def _uniqueName(self, original): - container_registry = UM.Settings.ContainerRegistry.getInstance() - - name = original.strip() - num_check = re.compile("(.*?)\s*#\d$").match(name) - if num_check: # There is a number in the name. - name = num_check.group(1) # Filter out the number. - if name == "": # Wait, that deleted everything! - name = "Extruder" - unique_name = name - - i = 1 - while container_registry.findContainers(id = unique_name) or container_registry.findContainers(name = unique_name): # A container already has this name. - i += 1 # Try next numbering. - unique_name = "%s #%d" % (name, i) # Fill name like this: "Extruder #2". - return unique_name From c5b07debdcf5583de189c13beeb6bcf333eae252 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 13:22:47 +0200 Subject: [PATCH 492/705] Remove iterability from ExtruderManager This is no longer used. Contributes to issues CURA-1278 and CURA-340. --- cura/ExtruderManager.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 31943be747..a1f901ce54 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -23,15 +23,8 @@ class ExtruderManager(QObject): def __init__(self, parent = None): super().__init__(parent) self._extruder_trains = { } #Extruders for the current machine. - self._next_item = 0 #For when you use this class as iterator. self._active_extruder_index = 0 - ## Creates an iterator over the extruders in this manager. - # - # \return An iterator over the extruders in this manager. - def __iter__(self): - return iter(self._extruders) - ## Gets the unique identifier of the currently active extruder stack. # # The currently active extruder stack is the stack that is currently being From 253061cfa492adeb628e9f7fa4929c43df0fafd6 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 13:24:03 +0200 Subject: [PATCH 493/705] Remove unused import The _uniqueName function was using this but it was moved to ContainerRegistry. Contributes to issues CURA-340 and CURA-1278. --- cura/ExtruderManager.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index a1f901ce54..d157cbb08e 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -6,7 +6,6 @@ from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject #For commun import UM.Application #To get the global container stack to find the current machine. import UM.Logger import UM.Settings.ContainerRegistry #Finding containers by ID. -import re ## Manages all existing extruder stacks. From b991743053edf2778a2395dc9ede7007b99386eb Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 7 Jun 2016 13:30:13 +0200 Subject: [PATCH 494/705] Fix ExtruderManager.py --- cura/ExtruderManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index d157cbb08e..b2c3b47e8e 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -4,7 +4,7 @@ from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject #For communicating data and events to Qt. import UM.Application #To get the global container stack to find the current machine. -import UM.Logger +from UM.Logger import Logger import UM.Settings.ContainerRegistry #Finding containers by ID. @@ -57,7 +57,7 @@ class ExtruderManager(QObject): # \param machine_definition The machine to add the extruders for. def addMachineExtruders(self, machine_definition): machine_id = machine_definition.getId() - if not self._extruder_trains[machine_id]: + if machine_id not in self._extruder_trains: self._extruder_trains[machine_id] = { } container_registry = UM.Settings.ContainerRegistry.getInstance() From 4695862b491dc0edd2560b89f689b170f385e391 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 7 Jun 2016 13:33:19 +0200 Subject: [PATCH 495/705] Added deepcopy function to settingOverrideDecorator CURA-1636 --- cura/SettingOverrideDecorator.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/cura/SettingOverrideDecorator.py b/cura/SettingOverrideDecorator.py index e212d93dac..04e77b0d3f 100644 --- a/cura/SettingOverrideDecorator.py +++ b/cura/SettingOverrideDecorator.py @@ -7,7 +7,7 @@ from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Application import Application - +import copy ## A decorator that adds a container stack to a Node. This stack should be queried for all settings regarding # the linked node. The Stack in question will refer to the global stack (so that settings that are not defined by # this stack still resolve. @@ -25,6 +25,15 @@ class SettingOverrideDecorator(SceneNodeDecorator): Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged) self._onGlobalContainerStackChanged() + def __deepcopy__(self, memo): + ## Create a fresh decorator object + deep_copy = SettingOverrideDecorator() + ## Copy the stack + deep_copy._stack = copy.deepcopy(self._stack, memo) + ## Ensure that the id is unique. + deep_copy._stack._id = id(deep_copy) + return deep_copy + def _onSettingChanged(self, instance, property): if property == "value": # Only reslice if the value has changed. Application.getInstance().getBackend().forceSlice() From 08d116590d2aac424be9f222b171a9ada751eabf Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 13:32:36 +0200 Subject: [PATCH 496/705] Revert "Fix ExtruderManager.py" That is not a fix. That is a patch. This reverts commit b991743053edf2778a2395dc9ede7007b99386eb. --- cura/ExtruderManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index b2c3b47e8e..d157cbb08e 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -4,7 +4,7 @@ from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject #For communicating data and events to Qt. import UM.Application #To get the global container stack to find the current machine. -from UM.Logger import Logger +import UM.Logger import UM.Settings.ContainerRegistry #Finding containers by ID. @@ -57,7 +57,7 @@ class ExtruderManager(QObject): # \param machine_definition The machine to add the extruders for. def addMachineExtruders(self, machine_definition): machine_id = machine_definition.getId() - if machine_id not in self._extruder_trains: + if not self._extruder_trains[machine_id]: self._extruder_trains[machine_id] = { } container_registry = UM.Settings.ContainerRegistry.getInstance() From 8feed746bf82d7fccaf5c6966685aba49c96b8ac Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 13:40:49 +0200 Subject: [PATCH 497/705] Re-apply part of b991743053edf2778a2395dc9ede7007b99386eb that worked This was indeed a mistake. Contributes to issues CURA-340 and CURA-1278. --- cura/ExtruderManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index d157cbb08e..9fbfc8eb84 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -57,7 +57,7 @@ class ExtruderManager(QObject): # \param machine_definition The machine to add the extruders for. def addMachineExtruders(self, machine_definition): machine_id = machine_definition.getId() - if not self._extruder_trains[machine_id]: + if machine_id not in self._extruder_trains: self._extruder_trains[machine_id] = { } container_registry = UM.Settings.ContainerRegistry.getInstance() From a9376cffd1b19c43ecc068e8c579b6ab96d1e3d0 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 13:41:28 +0200 Subject: [PATCH 498/705] Fix logging Specify the fully qualified name. Contributes to issues CURA-340 and CURA-1278. --- cura/ExtruderManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 9fbfc8eb84..9ec17c1abd 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -70,7 +70,7 @@ class ExtruderManager(QObject): if extruder_definition: extruder_definition = extruder_definition[0] else: - Logger.log("w", "Machine %s references an extruder with ID %s, which doesn't exist.", machine_definition.getName(), extruder_definition_id) + UM.Logger.log("w", "Machine %s references an extruder with ID %s, which doesn't exist.", machine_definition.getName(), extruder_definition_id) continue name = container_registry.uniqueName(extruder_definition_id) #Make a name based on the ID of the definition. if not container_registry.findContainerStacks(id = name): #Doesn't exist yet. From 499a0557bd55492871a0160f7cd6f9b61fe1d0cb Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 13:59:58 +0200 Subject: [PATCH 499/705] Fix checking if an extruder train already exists Contributes to issues CURA-340 and CURA-1278. --- cura/ExtruderManager.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 9ec17c1abd..df31cbacdf 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -65,15 +65,12 @@ class ExtruderManager(QObject): return #Add the extruder trains that don't exist yet. - for position, extruder_definition_id in machine_definition.getMetaDataEntry("machine_extruder_trains", default = {}).items(): - extruder_definition = container_registry.findDefinitionContainers(machine = machine_definition.getId()) - if extruder_definition: - extruder_definition = extruder_definition[0] - else: - UM.Logger.log("w", "Machine %s references an extruder with ID %s, which doesn't exist.", machine_definition.getName(), extruder_definition_id) - continue - name = container_registry.uniqueName(extruder_definition_id) #Make a name based on the ID of the definition. - if not container_registry.findContainerStacks(id = name): #Doesn't exist yet. + for extruder_definition in container_registry.findDefinitionContainers(machine = machine_definition.getId()): + position = extruder_definition.getMetaDataEntry("position", None) + if not position: + UM.Logger.Log("w", "Extruder definition %s specifies no position metadata entry.", extruder_definition.getId()) + if not container_registry.findContainerStacks(machine = machine_id, position = position): #Doesn't exist yet. + name = container_registry.uniqueName(extruder_definition.getId()) #Make a name based on the ID of the definition. self.createExtruderTrain(extruder_definition, machine_definition, name, position) #Gets the extruder trains that we just created as well as any that still existed. From d2405a24d26f0c23b1be3349438232142234e842 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 7 Jun 2016 14:56:29 +0200 Subject: [PATCH 500/705] Perobject stacks are no longer saved CURA-1278 --- cura/SettingOverrideDecorator.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/SettingOverrideDecorator.py b/cura/SettingOverrideDecorator.py index 04e77b0d3f..10a14007f3 100644 --- a/cura/SettingOverrideDecorator.py +++ b/cura/SettingOverrideDecorator.py @@ -15,6 +15,7 @@ class SettingOverrideDecorator(SceneNodeDecorator): def __init__(self): super().__init__() self._stack = ContainerStack(stack_id = id(self)) + self._stack.setDirty(False) # This stack does not need to be saved. self._instance = InstanceContainer(container_id = "SettingOverrideInstanceContainer") self._stack.addContainer(self._instance) From 5761307b336c5dcdea2c8d162a78d04f4ac39863 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 7 Jun 2016 15:45:51 +0200 Subject: [PATCH 501/705] Updated deepcopy to correctly copy the instance container CURA-1636 --- cura/SettingOverrideDecorator.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cura/SettingOverrideDecorator.py b/cura/SettingOverrideDecorator.py index 10a14007f3..f9878e436c 100644 --- a/cura/SettingOverrideDecorator.py +++ b/cura/SettingOverrideDecorator.py @@ -29,10 +29,10 @@ class SettingOverrideDecorator(SceneNodeDecorator): def __deepcopy__(self, memo): ## Create a fresh decorator object deep_copy = SettingOverrideDecorator() - ## Copy the stack - deep_copy._stack = copy.deepcopy(self._stack, memo) - ## Ensure that the id is unique. - deep_copy._stack._id = id(deep_copy) + ## Copy the instance + deep_copy._instance = copy.deepcopy(self._instance, memo) + ## Set the copied instance as the first (and only) instance container of the stack. + deep_copy._stack.replaceContainer(0, deep_copy._instance) return deep_copy def _onSettingChanged(self, instance, property): From 9a14a3e8b755bb9f85015670d0fb85bf2c90f50f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 7 Jun 2016 15:46:37 +0200 Subject: [PATCH 502/705] Per object settings no longer watches "state" property CURA-1278 --- plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index c89485517e..9565b0e345 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -120,7 +120,7 @@ Item { containerStackId: UM.ActiveTool.properties.getValue("ContainerID") key: model.key - watchedProperties: [ "value", "enabled", "state", "validationState" ] + watchedProperties: [ "value", "enabled", "validationState" ] storeIndex: 0 } } From b2782ced0a088274b2f483cc7502fc53abc70ab2 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 7 Jun 2016 15:56:59 +0200 Subject: [PATCH 503/705] Fix "renaming" profiles/machines to their current name without adding an increment CURA-1585 --- cura/MachineManagerModel.py | 66 ++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index c764296a68..7d8403afdd 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -9,6 +9,7 @@ from UM.Logger import Logger import UM.Settings from UM.Settings.Validator import ValidatorState from UM.Settings.InstanceContainer import InstanceContainer +from UM.Settings.ContainerStack import ContainerStack from . import ExtruderManager from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") @@ -109,7 +110,7 @@ class MachineManagerModel(QObject): definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id=definition_id) if definitions: definition = definitions[0] - name = self._createUniqueName("machine", name, definition.getName()) + name = self._createUniqueName(containers[0], "machine", name, definition.getName()) new_global_stack = UM.Settings.ContainerStack(name) new_global_stack.addMetaDataEntry("type", "machine") @@ -139,31 +140,42 @@ class MachineManagerModel(QObject): Application.getInstance().setGlobalContainerStack(new_global_stack) - # Create a name that is not empty and unique - def _createUniqueName(self, object_type, name, fallback_name): - name = name.strip() - num_check = re.compile("(.*?)\s*#\d+$").match(name) - if(num_check): - name = num_check.group(1) - if name == "": - name = fallback_name - unique_name = name - i = 1 + ## Create a name that is not empty and unique + # \param container \type{} container to create a unique name for + # \param container_type \type{string} Type of the container (machine, quality, ...) + # \param new_name \type{string} Name base name, which may not be unique + # \param fallback_name \type{string} Name to use when (stripped) new_name is empty + # \return \type{string} Name that is unique for the specified type and name/id + def _createUniqueName(self, container, object_type, new_name, fallback_name): + new_name = new_name.strip() + num_check = re.compile("(.*?)\s*#\d+$").match(new_name) + if num_check: + new_name = num_check.group(1) + if new_name == "": + new_name = fallback_name - # Check both the id and the name, because they may not be the same and it is better if they are both unique - if object_type == "machine": - while UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = unique_name, type = "machine") or \ - UM.Settings.ContainerRegistry.getInstance().findContainerStacks(name = unique_name, type = "machine"): - i += 1 - unique_name = "%s #%d" % (name, i) - else: - while UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = unique_name, type = object_type) or \ - UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(name = unique_name, type = object_type): - i += 1 - unique_name = "%s #%d" % (name, i) + unique_name = new_name + i = 1 + while self._containerWithIdOrNameExists(unique_name, object_type, container): + i += 1 + unique_name = "%s #%d" % (new_name, i) return unique_name + ## Check if a container with of a certain type and a certain name or id exists + # Both the id and the name are checked, because they may not be the same and it is better if they are both unique + def _containerWithIdOrNameExists(self, id_or_name, container_type, exclude_container = None): + container_class = ContainerStack if container_type == "machine" else InstanceContainer + + containers = UM.Settings.ContainerRegistry.getInstance().findContainers(container_class, id = id_or_name, type = container_type) + if containers and containers[0] != exclude_container: + return True + containers = UM.Settings.ContainerRegistry.getInstance().findContainers(container_class, name = id_or_name, type = container_type) + if containers and containers[0] != exclude_container: + return True + + return False + ## Convenience function to check if a stack has errors. def _checkStackForErrors(self, stack): if stack is None: @@ -260,9 +272,9 @@ class MachineManagerModel(QObject): if not self._global_container_stack: return - name = self._createUniqueName("quality", self.activeQualityName, catalog.i18nc("@label", "Custom profile")) - user_settings = self._global_container_stack.getTop() new_quality_container = InstanceContainer("") + name = self._createUniqueName(new_quality_container, "quality", self.activeQualityName, catalog.i18nc("@label", "Custom profile")) + user_settings = self._global_container_stack.getTop() ## Copy all values new_quality_container.deserialize(user_settings.serialize()) @@ -290,7 +302,7 @@ class MachineManagerModel(QObject): return containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=container_id) if containers: - new_name = self._createUniqueName("quality", containers[0].getName(), catalog.i18nc("@label", "Custom profile")) + new_name = self._createUniqueName(containers[0], "quality", containers[0].getName(), catalog.i18nc("@label", "Custom profile")) new_container = InstanceContainer("") @@ -310,7 +322,7 @@ class MachineManagerModel(QObject): def renameQualityContainer(self, container_id, new_name): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id, type = "quality") if containers: - new_name = self._createUniqueName("machine", new_name, catalog.i18nc("@label", "Custom profile")) + new_name = self._createUniqueName(containers[0], "quality", new_name, catalog.i18nc("@label", "Custom profile")) containers[0].setName(new_name) UM.Settings.ContainerRegistry.getInstance().containerChanged.emit(containers[0]) @@ -413,7 +425,7 @@ class MachineManagerModel(QObject): def renameMachine(self, machine_id, new_name): containers = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = machine_id) if containers: - new_name = self._createUniqueName("machine", new_name, containers[0].getBottom().getName()) + new_name = self._createUniqueName(containers[0], "machine", new_name, containers[0].getBottom().getName()) containers[0].setName(new_name) self.globalContainerChanged.emit() From 44d9fefd5d622bc5a3edaeb553173627fb9705f4 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Tue, 7 Jun 2016 16:11:44 +0200 Subject: [PATCH 504/705] Profile export from the Profiles window. Contributed to CURA-1667 Profile import/export --- 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 28248b23f4..ed9c20f65f 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -237,7 +237,7 @@ UM.ManagementPage folder: base.model.getDefaultPath() onAccepted: { - var result = base.model.exportProfile(base.currentItem.id, base.currentItem.name, fileUrl, selectedNameFilter) + var result = base.model.exportProfile(base.currentItem.id, fileUrl) if(result && result.status == "error") { messageDialog.icon = StandardIcon.Critical From cca432742b124f3103cad5fd8b52cf077a67050b Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 7 Jun 2016 17:01:08 +0200 Subject: [PATCH 505/705] Fix creating a name for a new MachineManagerModel CURA-1585 --- cura/MachineManagerModel.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 7d8403afdd..c0ac74abe4 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -110,9 +110,10 @@ class MachineManagerModel(QObject): definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id=definition_id) if definitions: definition = definitions[0] - name = self._createUniqueName(containers[0], "machine", name, definition.getName()) - new_global_stack = UM.Settings.ContainerStack(name) + name = self._createUniqueName(new_global_stack, "machine", name, definition.getName()) + new_global_stack._id = name + new_global_stack.setName(name) new_global_stack.addMetaDataEntry("type", "machine") UM.Settings.ContainerRegistry.getInstance().addContainer(new_global_stack) From e33eb52e936dab1cffa98e6568a41ca0dea3782a Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 7 Jun 2016 17:32:28 +0200 Subject: [PATCH 506/705] Hide Support Extruder in advanced mode when support is disabled CURA-1663 --- resources/definitions/fdmprinter.def.json | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index ec27abd9f5..79bdf4399a 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -2139,6 +2139,7 @@ "default_value": 0, "minimum_value": "0", "maximum_value": "machine_extruder_count - 1", + "enabled": "support_enable", "global_only": "True", "children": { "support_infill_extruder_nr": From 4d0bb217af1d7f35c75576e44b1b4e0d61967fb9 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 7 Jun 2016 18:13:19 +0200 Subject: [PATCH 507/705] Fix crash when enabling setting visibility for adhesion_extruder_nr or support_extruder_nr The fix is likely not what was intended by the author of the offending code (and does not seem to be functional), but at least it fixes the hard crash outlined in CURA-1666 --- cura/ExtrudersModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/ExtrudersModel.py b/cura/ExtrudersModel.py index eb63bc4257..7e00611742 100644 --- a/cura/ExtrudersModel.py +++ b/cura/ExtrudersModel.py @@ -46,7 +46,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): def _updateExtruders(self): self.clear() manager = cura.ExtruderManager.ExtruderManager.getInstance() - for index, extruder in enumerate(manager): + for index, extruder in enumerate(manager._extruder_trains): item = { #Construct an item with only the relevant information. "name": extruder.name, "colour": extruder.material.getMetaDataEntry("color_code", default = "#FFFF00"), From 406baf49af7183fcc13e5f2279f3f3507e0d3474 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Tue, 7 Jun 2016 18:25:03 +0200 Subject: [PATCH 508/705] JSON feat: replaced global_only with four properties settable_per_[mesh|extruder|meshgroup] and settable_globally (CURA-1558) --- resources/definitions/fdmprinter.def.json | 1264 +++++++++++++++++---- 1 file changed, 1016 insertions(+), 248 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index ec27abd9f5..f80d5d0d8f 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -32,151 +32,209 @@ "description": "Whether to show the different variants of this machine, which are described in separate json files.", "default_value": false, "type": "bool", - "label": "Show machine variants" + "label": "Show machine variants", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "machine_start_gcode": { "description": "Gcode commands to be executed at the very start - separated by \\n.", "default_value": "G28 ;Home\nG1 Z15.0 F6000 ;Move the platform down 15mm\n;Prime the extruder\nG92 E0\nG1 F200 E3\nG92 E0", "label": "Start GCode", - "global_only": true, - "type": "str" + "type": "str", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "machine_end_gcode": { "description": "Gcode commands to be executed at the very end - separated by \\n.", "default_value": "M104 S0\nM140 S0\n;Retract the filament\nG92 E1\nG1 E-1 F300\nG28 X0 Y0\nM84", "label": "End GCode", - "global_only": true, - "type": "str" + "type": "str", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "material_bed_temp_wait": { "description": "Whether to insert a command to wait until the bed temperature is reached at the start.", "label": "Wait for bed heatup", "default_value": true, - "global_only": true, - "type": "bool" + "type": "bool", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "material_print_temp_prepend": { "description": "Whether to include nozzle temperature commands at the start of the gcode. When the start_gcode already contains nozzle temperature commands Cura frontend will automatically disable this setting.", "default_value": true, - "global_only": true, "type": "bool", - "label": "Wait for material heatup" + "label": "Wait for material heatup", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "machine_width": { "description": "The width (X-direction) of the printable area.", "default_value": 100, - "global_only": true, "type": "float", - "label": "Machine width" + "label": "Machine width", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "machine_depth": { "description": "The depth (Y-direction) of the printable area.", "default_value": 100, - "global_only": true, "type": "float", - "label": "Machine depth" + "label": "Machine depth", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "machine_height": { "description": "The height (Z-direction) of the printable area.", "default_value": 100, - "global_only": true, "type": "float", - "label": "Machine height" + "label": "Machine height", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "machine_heated_bed": { "description": "Whether the machine has a heated bed present.", "default_value": false, - "global_only": true, "label": "Has heated bed", - "type": "bool" + "type": "bool", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "machine_center_is_zero": { "description": "Whether the X/Y coordinates of the zero position of the printer is at the center of the printable area.", "default_value": false, - "global_only": true, "type": "bool", - "label": "Is center origin" + "label": "Is center origin", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "machine_extruder_count": { "description": "Number of extruder trains. An extruder train is the combination of a feeder, bowden tube, and nozzle.", "default_value": 1, - "global_only": true, "type": "int", - "label": "Number extruders" + "label": "Number extruders", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "machine_nozzle_tip_outer_diameter": { "description": "The outer diameter of the tip of the nozzle.", "label": "Outer nozzle diameter", "default_value": 1, - "global_only": true, - "type": "float" + "type": "float", + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": false, + "settable_globally": false }, "machine_nozzle_head_distance": { "description": "The height difference between the tip of the nozzle and the lowest part of the print head.", "default_value": 3, - "global_only": true, "type": "float", - "label": "Nozzle length" + "label": "Nozzle length", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "machine_nozzle_expansion_angle": { "description": "The angle between the horizontal plane and the conical part right above the tip of the nozzle.", "default_value": 45, - "global_only": true, "type": "int", - "label": "Nozzle angle" + "label": "Nozzle angle", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "machine_heat_zone_length": { "description": "The distance from the tip of the nozzle in which heat from the nozzle is transfered to the filament.", "default_value": 16, - "global_only": true, "type": "float", - "label": "Heat zone length" + "label": "Heat zone length", + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": false, + "settable_globally": true }, "machine_nozzle_heat_up_speed": { "description": "The speed (°C/s) by which the nozzle heats up averaged over the window of normal printing temperatures and the standby temperature.", "default_value": 2.0, - "global_only": true, "type": "float", - "label": "Heat up speed" + "label": "Heat up speed", + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "machine_nozzle_cool_down_speed": { "description": "The speed (°C/s) by which the nozzle cools down averaged over the window of normal printing temperatures and the standby temperature.", "default_value": 2.0, - "global_only": true, "type": "float", - "label": "Cool down speed" + "label": "Cool down speed", + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "machine_gcode_flavor": { "description": "The type of gcode to be generated.", "default_value": "RepRap", - "global_only": true, "type": "str", - "label": "Gcode flavour" + "label": "Gcode flavour", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "machine_disallowed_areas": { "description": "A list of polygons with areas the print head is not allowed to enter.", "type": "polygons", "default_value": [], - "global_only": true, - "label": "Disallowed areas" + "label": "Disallowed areas", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "machine_head_polygon": { @@ -201,8 +259,11 @@ 1 ] ], - "global_only": true, - "label": "Machine head polygon" + "label": "Machine head polygon", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "machine_head_with_fans_polygon": { @@ -227,16 +288,22 @@ -10 ] ], - "global_only": true, - "label": "Machine head & Fan polygon" + "label": "Machine head & Fan polygon", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "gantry_height": { "description": "The height difference between the tip of the nozzle and the gantry system (X and Y axes).", "default_value": 99999999999, - "global_only": true, "label": "Gantry height", - "type": "float" + "type": "float", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "machine_nozzle_size": { @@ -246,14 +313,22 @@ "type": "float", "default_value": 0.4, "minimum_value": "0.001", - "maximum_value_warning": "10" + "maximum_value_warning": "10", + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "machine_use_extruder_offset_to_offset_coords": { "label": "Offset With Extruder", "description": "Apply the extruder offset to the coordinate system.", "type": "bool", - "default_value": true + "default_value": true, + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true } } }, @@ -275,7 +350,11 @@ "minimum_value": "0.001", "minimum_value_warning": "0.04", "maximum_value_warning": "0.8 * machine_nozzle_size", - "global_only": "True" + "default_value": true, + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "layer_height_0": { @@ -287,7 +366,11 @@ "minimum_value": "0.001", "minimum_value_warning": "0.04", "maximum_value_warning": "0.8 * machine_nozzle_size", - "global_only": "True" + "default_value": true, + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "line_width": { @@ -313,6 +396,11 @@ "value":"line_width", "default_value": 0.4, "type": "float", + "default_value": true, + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "wall_line_width_0": @@ -325,7 +413,11 @@ "maximum_value_warning": "5", "default_value": 0.4, "value":"wall_line_width", - "type": "float" + "type": "float", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "wall_line_width_x": { @@ -337,7 +429,11 @@ "maximum_value_warning": "5", "default_value": 0.4, "value":"wall_line_width", - "type": "float" + "type": "float", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -351,7 +447,11 @@ "maximum_value_warning": "5", "default_value": 0.4, "type": "float", - "value": "line_width" + "value": "line_width", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "infill_line_width": { @@ -363,7 +463,11 @@ "maximum_value_warning": "5", "default_value": 0.4, "type": "float", - "value": "line_width" + "value": "line_width", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "skirt_line_width": { @@ -375,8 +479,11 @@ "maximum_value_warning": "5", "default_value": 0.4, "type": "float", - "global_only": true, - "value": "line_width" + "value": "line_width", + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_line_width": { @@ -389,8 +496,11 @@ "default_value": 0.4, "type": "float", "enabled": "support_enable", - "global_only": true, - "value": "line_width" + "value": "line_width", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_roof_line_width": { @@ -402,8 +512,11 @@ "maximum_value_warning": "machine_nozzle_size * 2", "type": "float", "enabled": "support_roof_enable", - "global_only": true, - "value": "line_width" + "value": "line_width", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "prime_tower_line_width": { @@ -417,7 +530,10 @@ "minimum_value": "0.0001", "minimum_value_warning": "0.2", "maximum_value_warning": "5", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } } @@ -441,6 +557,10 @@ "minimum_value_warning": "line_width", "maximum_value_warning": "5 * line_width", "type": "float", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "wall_line_count": @@ -450,7 +570,11 @@ "default_value": 2, "minimum_value": "0", "type": "int", - "value": "1 if magic_spiralize else max(1, round((wall_thickness - wall_line_width_0) / wall_line_width_x) + 1)" + "value": "1 if magic_spiralize else max(1, round((wall_thickness - wall_line_width_0) / wall_line_width_x) + 1)", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -464,6 +588,10 @@ "maximum_value": "5", "minimum_value_warning": "0.6", "type": "float", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "top_thickness": @@ -476,6 +604,10 @@ "maximum_value_warning": "100", "type": "float", "value": "top_bottom_thickness", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "top_layers": @@ -486,7 +618,11 @@ "minimum_value": "0", "maximum_value_warning": "100", "type": "int", - "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 / layer_height, 4))", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -499,6 +635,10 @@ "minimum_value": "0", "type": "float", "value": "top_bottom_thickness", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "bottom_layers": @@ -508,7 +648,11 @@ "minimum_value": "0", "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 / layer_height, 4))", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } } @@ -525,7 +669,11 @@ "concentric": "Concentric", "zigzag": "Zig Zag" }, - "default_value": "lines" + "default_value": "lines", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "wall_0_inset": { @@ -536,14 +684,22 @@ "default_value": 0.0, "value": "(machine_nozzle_size - wall_line_width_0) / 2 if wall_line_width_0 < machine_nozzle_size else 0", "minimum_value_warning": "0", - "maximum_value_warning": "machine_nozzle_size" + "maximum_value_warning": "machine_nozzle_size", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "alternate_extra_perimeter": { "label": "Alternate Extra Wall", "description": "Prints an extra wall at every other layer. This way infill gets caught between these extra walls, resulting in stronger prints.", "type": "bool", - "default_value": false + "default_value": false, + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "travel_compensate_overlapping_walls_enabled": { @@ -551,6 +707,10 @@ "description": "Compensate the flow for parts of a wall being printed where there is already a wall in place.", "type": "bool", "default_value": true, + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "travel_compensate_overlapping_walls_0_enabled": { @@ -558,14 +718,22 @@ "description": "Compensate the flow for parts of an outer wall being printed where there is already a wall in place.", "type": "bool", "default_value": true, - "value": "travel_compensate_overlapping_walls_enabled" + "value": "travel_compensate_overlapping_walls_enabled", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "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", "default_value": true, - "value": "travel_compensate_overlapping_walls_enabled" + "value": "travel_compensate_overlapping_walls_enabled", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -577,7 +745,11 @@ "type": "float", "minimum_value_warning": "-10", "maximum_value_warning": "10", - "default_value": 0 + "default_value": 0, + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "z_seam_type": { @@ -590,14 +762,22 @@ "shortest": "Shortest", "random": "Random" }, - "default_value": "shortest" + "default_value": "shortest", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "skin_no_small_gaps_heuristic": { "label": "Ignore Small Z Gaps", "description": "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such case, disable the setting.", "type": "bool", - "default_value": true + "default_value": true, + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -618,6 +798,10 @@ "default_value": 20, "minimum_value": "0", "maximum_value_warning": "100", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "infill_line_distance": @@ -628,7 +812,11 @@ "type": "float", "default_value": 2, "minimum_value": "0", - "value": "0 if infill_sparse_density == 0 else (infill_line_width * 100) / infill_sparse_density * (2 if infill_pattern == \"grid\" else (3 if infill_pattern == \"triangles\" else 1))" + "value": "0 if infill_sparse_density == 0 else (infill_line_width * 100) / infill_sparse_density * (2 if infill_pattern == \"grid\" else (3 if infill_pattern == \"triangles\" else 1))", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -646,7 +834,11 @@ "zigzag": "Zig Zag" }, "default_value": "grid", - "value": "'lines' if infill_sparse_density > 25 else 'grid'" + "value": "'lines' if infill_sparse_density > 25 else 'grid'", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "infill_overlap": { @@ -659,6 +851,10 @@ "minimum_value_warning": "-50", "maximum_value_warning": "100", "enabled": "infill_pattern != 'concentric'", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "infill_overlap_mm": @@ -671,7 +867,11 @@ "minimum_value_warning": "-0.5 * machine_nozzle_size", "maximum_value_warning": "machine_nozzle_size", "value": "infill_line_width * infill_overlap / 100 if infill_sparse_density < 95 and infill_pattern != 'concentric' else 0", - "enabled": "infill_pattern != 'concentric'" + "enabled": "infill_pattern != 'concentric'", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -685,6 +885,10 @@ "maximum_value_warning": "100", "value": "5 if top_bottom_pattern != 'concentric' else 0", "enabled": "top_bottom_pattern != 'concentric'", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "skin_overlap_mm": { "label": "Skin Overlap", @@ -695,7 +899,11 @@ "minimum_value_warning": "-0.5 * machine_nozzle_size", "maximum_value_warning": "machine_nozzle_size", "value": "skin_line_width * skin_overlap / 100 if top_bottom_pattern != 'concentric' else 0", - "enabled": "top_bottom_pattern != 'concentric'" + "enabled": "top_bottom_pattern != 'concentric'", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -708,7 +916,11 @@ "default_value": 0.04, "value": "wall_line_width_0 / 4 if wall_line_count == 1 else wall_line_width_x / 4", "minimum_value_warning": "0", - "maximum_value_warning": "machine_nozzle_size" + "maximum_value_warning": "machine_nozzle_size", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "infill_sparse_thickness": { @@ -720,14 +932,22 @@ "minimum_value": "0.0001", "maximum_value_warning": "0.32", "maximum_value": "layer_height * 8", - "value": "layer_height" + "value": "layer_height", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "infill_before_walls": { "label": "Infill Before Walls", "description": "Print the infill before printing the walls. Printing the walls first may lead to more accurate walls, but overhangs print worse. Printing the infill first leads to sturdier walls, but the infill pattern might sometimes show through the surface.", "type": "bool", - "default_value": true + "default_value": true, + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -746,7 +966,10 @@ "type": "bool", "default_value": false, "enabled": "False", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "material_print_temperature": { @@ -757,7 +980,11 @@ "default_value": 210, "minimum_value": "0", "maximum_value_warning": "260", - "enabled": "not (material_flow_dependent_temperature)" + "enabled": "not (material_flow_dependent_temperature)", + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "material_flow_temp_graph": { @@ -768,7 +995,10 @@ "default_value": "[[3.5,200],[7.0,240]]", "enabled": "False", "comments": "old enabled function: material_flow_dependent_temperature", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "material_extrusion_cool_down_speed": { "label": "Extrusion Cool Down Speed Modifier", @@ -778,9 +1008,12 @@ "default_value": 0.5, "minimum_value": "0", "maximum_value_warning": "10.0", - "global_only": "True", "enabled": "False", - "comments": "old enabled function: material_flow_dependent_temperature or machine_extruder_count > 1" + "comments": "old enabled function: material_flow_dependent_temperature or machine_extruder_count > 1", + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "material_bed_temperature": { "label": "Bed Temperature", @@ -791,7 +1024,10 @@ "minimum_value": "0", "maximum_value_warning": "260", "enabled": "machine_heated_bed", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "material_diameter": { "label": "Diameter", @@ -802,7 +1038,10 @@ "minimum_value": "0.0001", "minimum_value_warning": "0.4", "maximum_value_warning": "3.5", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "material_flow": { "label": "Flow", @@ -812,13 +1051,21 @@ "type": "float", "minimum_value": "5", "minimum_value_warning": "50", - "maximum_value_warning": "150" + "maximum_value_warning": "150", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "retraction_enable": { "label": "Enable Retraction", "description": "Retract the filament when the nozzle is moving over a non-printed area. ", "type": "bool", - "default_value": true + "default_value": true, + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "retraction_amount": { "label": "Retraction Distance", @@ -828,7 +1075,11 @@ "default_value": 6.5, "minimum_value_warning": "-0.0001", "maximum_value_warning": "10.0", - "enabled": "retraction_enable" + "enabled": "retraction_enable", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "retraction_speed": { "label": "Retraction Speed", @@ -840,6 +1091,10 @@ "maximum_value": "299792458000", "maximum_value_warning": "100", "enabled": "retraction_enable", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "retraction_retract_speed": { "label": "Retraction Retract Speed", @@ -851,7 +1106,11 @@ "maximum_value": "299792458000", "maximum_value_warning": "100", "enabled": "retraction_enable", - "value": "retraction_speed" + "value": "retraction_speed", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "retraction_prime_speed": { "label": "Retraction Prime Speed", @@ -863,7 +1122,11 @@ "maximum_value": "299792458000", "maximum_value_warning": "100", "enabled": "retraction_enable", - "value": "retraction_speed" + "value": "retraction_speed", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -875,7 +1138,11 @@ "default_value": 0, "minimum_value_warning": "-0.0001", "maximum_value_warning": "5.0", - "enabled": "retraction_enable" + "enabled": "retraction_enable", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "retraction_min_travel": { "label": "Retraction Minimum Travel", @@ -886,7 +1153,11 @@ "value": "line_width * 2", "minimum_value": "0", "maximum_value_warning": "10", - "enabled": "retraction_enable" + "enabled": "retraction_enable", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "retraction_count_max": { "label": "Maximum Retraction Count", @@ -895,7 +1166,11 @@ "minimum_value": "0", "maximum_value_warning": "100", "type": "int", - "enabled": "retraction_enable" + "enabled": "retraction_enable", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "retraction_extrusion_window": { "label": "Minimum Extrusion Distance Window", @@ -906,7 +1181,11 @@ "minimum_value": "0", "maximum_value_warning": "retraction_amount * 2", "value": "retraction_amount", - "enabled": "retraction_enable" + "enabled": "retraction_enable", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "retraction_hop": { "label": "Z Hop when Retracting", @@ -916,7 +1195,11 @@ "default_value": 0, "minimum_value_warning": "-0.0001", "maximum_value_warning": "10", - "enabled": "retraction_enable" + "enabled": "retraction_enable", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "material_standby_temperature": { @@ -927,7 +1210,10 @@ "default_value": 150, "minimum_value": "0", "maximum_value_warning": "260", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "switch_extruder_retraction_amount": { @@ -940,7 +1226,10 @@ "value": "machine_heat_zone_length", "minimum_value_warning": "0", "maximum_value_warning": "100", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "switch_extruder_retraction_speeds": { @@ -952,7 +1241,10 @@ "default_value": 20, "minimum_value": "0.1", "maximum_value_warning": "300", - "global_only": "True", + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "switch_extruder_retraction_speed": @@ -966,7 +1258,10 @@ "value": "switch_extruder_retraction_speeds", "minimum_value": "0.1", "maximum_value_warning": "300", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "switch_extruder_prime_speed": { @@ -979,7 +1274,10 @@ "value": "switch_extruder_retraction_speeds", "minimum_value": "0.1", "maximum_value_warning": "300", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -992,7 +1290,11 @@ "default_value": 1, "minimum_value_warning": "-0.0001", "maximum_value_warning": "10", - "enabled": "retraction_enable" + "enabled": "retraction_enable", + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -1014,6 +1316,10 @@ "maximum_value_warning": "150", "maximum_value": "299792458000", "default_value": 60, + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "speed_infill": @@ -1026,7 +1332,11 @@ "maximum_value": "299792458000", "maximum_value_warning": "150", "default_value": 60, - "value": "speed_print" + "value": "speed_print", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "speed_wall": { @@ -1039,6 +1349,10 @@ "maximum_value_warning": "150", "default_value": 30, "value": "speed_print / 2", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "speed_wall_0": @@ -1051,7 +1365,11 @@ "maximum_value": "299792458000", "maximum_value_warning": "150", "default_value": 30, - "value": "speed_wall" + "value": "speed_wall", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "speed_wall_x": { @@ -1063,7 +1381,11 @@ "maximum_value": "299792458000", "maximum_value_warning": "150", "default_value": 60, - "value": "speed_wall * 2" + "value": "speed_wall * 2", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -1077,7 +1399,11 @@ "maximum_value": "299792458000", "maximum_value_warning": "150", "default_value": 30, - "value": "speed_print / 2" + "value": "speed_print / 2", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "speed_support": { @@ -1091,6 +1417,10 @@ "default_value": 60, "value": "speed_print", "enabled": "support_roof_enable", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "speed_support_infill": @@ -1105,7 +1435,10 @@ "maximum_value_warning": "150", "value": "speed_support", "enabled": "support_enable", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "speed_support_roof": { @@ -1119,7 +1452,10 @@ "maximum_value_warning": "150", "enabled": "support_roof_enable and support_enable", "value": "speed_support / 1.5", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -1134,7 +1470,10 @@ "value": "speed_print", "minimum_value": "0.1", "maximum_value_warning": "150", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -1149,7 +1488,10 @@ "maximum_value": "299792458000", "maximum_value_warning": "300", "value": "speed_print if magic_spiralize else 120", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "speed_layer_0": { "label": "Initial Layer Speed", @@ -1159,7 +1501,11 @@ "default_value": 30, "minimum_value": "0.1", "maximum_value": "299792458000", - "maximum_value_warning": "300" + "maximum_value_warning": "300", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "skirt_speed": { "label": "Skirt Speed", @@ -1171,7 +1517,10 @@ "maximum_value": "299792458000", "maximum_value_warning": "300", "value": "speed_layer_0", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "speed_slowdown_layers": { @@ -1182,7 +1531,10 @@ "minimum_value": "0", "maximum_value": "299792458000", "maximum_value_warning": "300", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -1206,7 +1558,10 @@ "noskin": "No Skin" }, "default_value": "all", - "global_only": true + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "travel_avoid_other_parts": { @@ -1215,7 +1570,10 @@ "type": "bool", "default_value": true, "enabled": "retraction_combing != \"off\"", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "travel_avoid_distance": { @@ -1228,7 +1586,10 @@ "minimum_value": "0", "maximum_value_warning": "machine_nozzle_tip_outer_diameter * 5", "enabled": "retraction_combing != \"off\" and travel_avoid_other_parts", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -1246,7 +1607,10 @@ "description": "Enables the cooling fans while printing. The fans improve print quality on layers with short layer times and bridging / overhangs.", "type": "bool", "default_value": true, - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "cool_fan_speed": { @@ -1259,7 +1623,10 @@ "default_value": 100, "value": "100.0 if cool_fan_enabled else 0.0", "enabled": "cool_fan_enabled", - "global_only": "True", + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "cool_fan_speed_min": @@ -1273,7 +1640,10 @@ "value": "cool_fan_speed", "default_value": 100, "enabled": "cool_fan_enabled", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "cool_fan_speed_max": { @@ -1285,8 +1655,11 @@ "maximum_value": "100", "default_value": 100, "enabled": "cool_fan_enabled", - "global_only": "True", - "value": "cool_fan_speed" + "value": "cool_fan_speed", + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -1299,7 +1672,10 @@ "default_value": 10, "minimum_value": "cool_min_layer_time", "maximum_value_warning": "600", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "cool_fan_full_at_height": { @@ -1311,7 +1687,10 @@ "value": "layer_height_0", "minimum_value": "0", "maximum_value_warning": "10.0", - "global_only": "True", + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "cool_fan_full_layer": @@ -1323,7 +1702,10 @@ "minimum_value": "0", "maximum_value_warning": "100", "value": "max(0, int(round((cool_fan_full_at_height - layer_height_0) / layer_height, 0)))", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -1336,7 +1718,10 @@ "default_value": 5, "minimum_value": "0", "maximum_value_warning": "600", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "cool_min_speed": { @@ -1347,7 +1732,10 @@ "default_value": 10, "minimum_value": "0", "maximum_value_warning": "100", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "cool_lift_head": { @@ -1355,7 +1743,10 @@ "description": "When the minimum speed is hit because of minimum layer time, lift the head away from the print and wait the extra time until the minimum layer time is reached.", "type": "bool", "default_value": false, - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -1372,7 +1763,11 @@ "label": "Enable Support", "description": "Enable support structures. These structures support parts of the model with severe overhangs.", "type": "bool", - "default_value": false + "default_value": false, + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_type": { @@ -1385,7 +1780,11 @@ "everywhere": "Everywhere" }, "default_value": "everywhere", - "enabled": "support_enable" + "enabled": "support_enable", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_angle": { @@ -1396,7 +1795,11 @@ "minimum_value": "0", "maximum_value": "90", "default_value": 50, - "enabled": "support_enable" + "enabled": "support_enable", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_pattern": { @@ -1413,7 +1816,10 @@ }, "default_value": "zigzag", "enabled": "support_enable", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_connect_zigzags": { @@ -1422,7 +1828,10 @@ "type": "bool", "default_value": true, "enabled": "support_enable and (support_pattern == \"zigzag\")", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_infill_rate": { @@ -1434,7 +1843,10 @@ "maximum_value_warning": "100", "default_value": 15, "enabled": "support_enable", - "global_only": true, + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "support_line_distance": { @@ -1446,7 +1858,10 @@ "default_value": 2.66, "enabled": "support_enable", "value": "(support_line_width * 100) / support_infill_rate * (2 if support_pattern == \"grid\" else (3 if support_pattern == \"triangles\" else 1))", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -1460,7 +1875,10 @@ "maximum_value_warning": "10", "default_value": 0.15, "enabled": "support_enable", - + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "support_top_distance": @@ -1473,7 +1891,11 @@ "default_value": 0.15, "type": "float", "enabled": "support_enable", - "value": "support_z_distance" + "value": "support_z_distance", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_bottom_distance": { @@ -1485,7 +1907,11 @@ "default_value": 0.1, "value": "0.1 if support_type == 'everywhere' else 0", "type": "float", - "enabled": "support_enable and support_type == 'everywhere'" + "enabled": "support_enable and support_type == 'everywhere'", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -1498,7 +1924,11 @@ "minimum_value": "0", "maximum_value_warning": "10", "default_value": 0.7, - "enabled": "support_enable" + "enabled": "support_enable", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_xy_overrides_z": { "label": "Support Distance Priority", @@ -1509,7 +1939,11 @@ "z_overrides_xy": "Z overrides X/Y" }, "default_value": "z_overrides_xy", - "enabled": "support_enable" + "enabled": "support_enable", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_xy_distance_overhang": { "label": "Minimum Support X/Y Distance", @@ -1520,7 +1954,11 @@ "maximum_value_warning": "10", "default_value": 0.2, "value": "machine_nozzle_size / 2", - "enabled": "support_enable and support_xy_overrides_z=='z_overrides_xy'" + "enabled": "support_enable and support_xy_overrides_z=='z_overrides_xy'", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_bottom_stair_step_height": { @@ -1531,7 +1969,11 @@ "default_value": 0.3, "minimum_value": "0", "maximum_value_warning": "1.0", - "enabled": "support_enable" + "enabled": "support_enable", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_join_distance": { @@ -1542,7 +1984,11 @@ "default_value": 2.0, "minimum_value_warning": "0", "maximum_value_warning": "10", - "enabled": "support_enable" + "enabled": "support_enable", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_offset": { @@ -1553,7 +1999,11 @@ "default_value": 0.2, "minimum_value_warning": "-0.5", "maximum_value_warning": "5.0", - "enabled": "support_enable" + "enabled": "support_enable", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_area_smoothing": { @@ -1564,7 +2014,11 @@ "default_value": 0.6, "minimum_value": "0", "maximum_value_warning": "1.0", - "enabled": "support_enable" + "enabled": "support_enable", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_roof_enable": { @@ -1572,7 +2026,11 @@ "description": "Generate a dense top skin at the top of the support on which the model is printed.", "type": "bool", "default_value": false, - "enabled": "support_enable" + "enabled": "support_enable", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_roof_height": { @@ -1583,7 +2041,11 @@ "default_value": 1, "minimum_value": "0", "maximum_value_warning": "10", - "enabled": "support_roof_enable" + "enabled": "support_roof_enable", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_roof_density": { @@ -1595,7 +2057,10 @@ "minimum_value": "0", "maximum_value_warning": "100", "enabled":"support_roof_enable", - "global_only": true, + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "support_roof_line_distance": @@ -1608,7 +2073,10 @@ "minimum_value": "0", "value": "0 if support_roof_density == 0 else (support_roof_line_width * 100) / support_roof_density * (2 if support_roof_pattern == \"grid\" else (3 if support_roof_pattern == \"triangles\" else 1))", "enabled": "support_roof_enable", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -1627,7 +2095,10 @@ }, "default_value": "concentric", "enabled": "support_roof_enable", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_use_towers": { @@ -1635,7 +2106,11 @@ "description": "Use specialized towers to support tiny overhang areas. These towers have a larger diameter than the region they support. Near the overhang the towers' diameter decreases, forming a roof.", "type": "bool", "default_value": true, - "enabled": "support_enable" + "enabled": "support_enable", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_tower_diameter": { @@ -1646,7 +2121,11 @@ "default_value": 3.0, "minimum_value": "0", "maximum_value_warning": "10", - "enabled": "support_enable and support_use_towers" + "enabled": "support_enable and support_use_towers", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_minimal_diameter": { @@ -1658,7 +2137,11 @@ "minimum_value": "0", "maximum_value_warning": "10", "maximum_value": "support_tower_diameter", - "enabled": "support_enable and support_use_towers" + "enabled": "support_enable and support_use_towers", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_tower_roof_angle": { @@ -1669,7 +2152,11 @@ "minimum_value": "0", "maximum_value": "90", "default_value": 65, - "enabled": "support_enable and support_use_towers" + "enabled": "support_enable and support_use_towers", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -1693,7 +2180,10 @@ "raft": "Raft" }, "default_value": "brim", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "skirt_line_count": { @@ -1704,7 +2194,10 @@ "minimum_value": "0", "maximum_value_warning": "10", "enabled": "adhesion_type == \"skirt\"", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "skirt_gap": { @@ -1716,7 +2209,10 @@ "minimum_value_warning": "0", "maximum_value_warning": "100", "enabled": "adhesion_type == \"skirt\"", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "skirt_minimal_length": { @@ -1729,7 +2225,10 @@ "minimum_value_warning": "25", "maximum_value_warning": "2500", "enabled": "adhesion_type == \"skirt\"", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "brim_width": { @@ -1741,7 +2240,10 @@ "minimum_value": "0.0", "maximum_value_warning": "100.0", "enabled": "adhesion_type == \"brim\"", - "global_only": "True", + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "brim_line_count": @@ -1754,7 +2256,10 @@ "maximum_value_warning": "300", "value": "math.ceil(brim_width / skirt_line_width)", "enabled": "adhesion_type == \"brim\"", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -1767,8 +2272,7 @@ "default_value": 5, "minimum_value_warning": "0", "maximum_value_warning": "10", - "enabled": "adhesion_type == \"raft\"", - "global_only": "True" + "enabled": "adhesion_type == \"raft\"" }, "raft_airgap": { @@ -1780,7 +2284,10 @@ "minimum_value": "0", "maximum_value_warning": "1.0", "enabled": "adhesion_type == \"raft\"", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "layer_0_z_overlap": { "label": "Initial Layer Z Overlap", @@ -1792,7 +2299,10 @@ "minimum_value": "0", "maximum_value_warning": "layer_height", "enabled": "adhesion_type == 'raft'", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "raft_surface_layers": { @@ -1803,7 +2313,10 @@ "minimum_value": "0", "maximum_value_warning": "20", "enabled": "adhesion_type == \"raft\"", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "raft_surface_thickness": { @@ -1815,7 +2328,10 @@ "minimum_value": "0", "maximum_value_warning": "2.0", "enabled": "adhesion_type == \"raft\"", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "raft_surface_line_width": { @@ -1827,7 +2343,10 @@ "minimum_value": "0.0001", "maximum_value_warning": "machine_nozzle_size * 2", "enabled": "adhesion_type == \"raft\"", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "raft_surface_line_spacing": { @@ -1840,7 +2359,10 @@ "maximum_value_warning": "5.0", "enabled": "adhesion_type == \"raft\"", "value": "raft_surface_line_width", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "raft_interface_thickness": { @@ -1852,7 +2374,10 @@ "minimum_value": "0", "maximum_value_warning": "5.0", "enabled": "adhesion_type == \"raft\"", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "raft_interface_line_width": { @@ -1865,7 +2390,10 @@ "minimum_value": "0.0001", "maximum_value_warning": "machine_nozzle_size * 2", "enabled": "adhesion_type == \"raft\"", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "raft_interface_line_spacing": { @@ -1877,7 +2405,10 @@ "minimum_value": "0", "maximum_value_warning": "15.0", "enabled": "adhesion_type == \"raft\"", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "raft_base_thickness": { @@ -1889,7 +2420,10 @@ "minimum_value": "0", "maximum_value_warning": "5.0", "enabled": "adhesion_type == \"raft\"", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "raft_base_line_width": { @@ -1902,7 +2436,10 @@ "value": "line_width", "maximum_value_warning": "machine_nozzle_size * 2", "enabled": "adhesion_type == \"raft\"", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "raft_base_line_spacing": { @@ -1914,7 +2451,10 @@ "minimum_value": "0.0001", "maximum_value_warning": "100", "enabled": "adhesion_type == \"raft\"", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "raft_speed": { @@ -1928,7 +2468,10 @@ "maximum_value_warning": "200", "enabled": "adhesion_type == \"raft\"", "value": "speed_print / 60 * 30", - "global_only": "True", + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "raft_surface_speed": @@ -1943,7 +2486,10 @@ "maximum_value_warning": "100", "enabled": "adhesion_type == \"raft\"", "value": "raft_speed", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "raft_interface_speed": { @@ -1957,7 +2503,10 @@ "maximum_value_warning": "150", "enabled": "adhesion_type == \"raft\"", "value": "0.5 * raft_speed", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "raft_base_speed": { @@ -1971,7 +2520,10 @@ "maximum_value_warning": "200", "enabled": "adhesion_type == \"raft\"", "value": "0.5 * raft_speed", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -1984,7 +2536,10 @@ "minimum_value": "0", "maximum_value": "100", "default_value": 0, - "global_only": "True", + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true, "enabled": "adhesion_type == \"raft\"", "children": { @@ -1997,9 +2552,12 @@ "minimum_value": "0", "maximum_value": "100", "default_value": 0, - "global_only": "True", "value": "raft_fan_speed", - "enabled": "adhesion_type == \"raft\"" + "enabled": "adhesion_type == \"raft\"", + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "raft_interface_fan_speed": { @@ -2010,9 +2568,12 @@ "minimum_value": "0", "maximum_value": "100", "default_value": 0, - "global_only": "True", "value": "raft_fan_speed", - "enabled": "adhesion_type == \"raft\"" + "enabled": "adhesion_type == \"raft\"", + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "raft_base_fan_speed": { @@ -2023,9 +2584,12 @@ "minimum_value": "0", "maximum_value": "100", "default_value": 0, - "global_only": "True", "value": "raft_fan_speed", - "enabled": "adhesion_type == \"raft\"" + "enabled": "adhesion_type == \"raft\"", + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } } @@ -2044,28 +2608,44 @@ "label": "Union Overlapping Volumes", "description": "Ignore the internal geometry arising from overlapping volumes and print the volumes as one. This may cause internal cavities to disappear.", "type": "bool", - "default_value": true + "default_value": true, + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "meshfix_union_all_remove_holes": { "label": "Remove All Holes", "description": "Remove the holes in each layer and keep only the outside shape. This will ignore any invisible internal geometry. However, it also ignores layer holes which can be viewed from above or below.", "type": "bool", - "default_value": false + "default_value": false, + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "meshfix_extensive_stitching": { "label": "Extensive Stitching", "description": "Extensive stitching tries to stitch up open holes in the mesh by closing the hole with touching polygons. This option can introduce a lot of processing time.", "type": "bool", - "default_value": false + "default_value": false, + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "meshfix_keep_open_polygons": { "label": "Keep Disconnected Faces", "description": "Normally Cura tries to stitch up small holes in the mesh and remove parts of a layer with big holes. Enabling this option keeps those parts which cannot be stitched. This option should be used as a last resort option when everything else fails to produce proper GCode.", "type": "bool", - "default_value": false + "default_value": false, + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -2088,7 +2668,10 @@ "one_at_a_time": "One at a Time" }, "default_value": "all_at_once", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "magic_mesh_surface_mode": { @@ -2101,7 +2684,11 @@ "surface": "Surface", "both": "Both" }, - "default_value": "normal" + "default_value": "normal", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "magic_spiralize": { @@ -2109,7 +2696,10 @@ "description": "Spiralize smooths out the Z move of the outer edge. This will create a steady Z increase over the whole print. This feature turns a solid object into a single walled print with a solid bottom. This feature used to be called Joris in older versions.", "type": "bool", "default_value": false, - "global_only": "True" + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -2129,7 +2719,10 @@ "default_value": 0, "minimum_value": "0", "maximum_value": "machine_extruder_count - 1", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_extruder_nr": { @@ -2139,7 +2732,10 @@ "default_value": 0, "minimum_value": "0", "maximum_value": "machine_extruder_count - 1", - "global_only": "True", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "support_infill_extruder_nr": { @@ -2150,7 +2746,10 @@ "value": "support_extruder_nr", "minimum_value": "0", "maximum_value": "machine_extruder_count - 1", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_extruder_nr_layer_0": { @@ -2161,7 +2760,10 @@ "value": "support_extruder_nr", "minimum_value": "0", "maximum_value": "machine_extruder_count - 1", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_roof_extruder_nr": { @@ -2172,7 +2774,10 @@ "value": "support_extruder_nr", "minimum_value": "0", "maximum_value": "machine_extruder_count - 1", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -2182,7 +2787,10 @@ "description": "Print a tower next to the print which serves to prime the material after each nozzle switch.", "type": "bool", "default_value": false, - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "prime_tower_size": { @@ -2195,7 +2803,10 @@ "value": "15 if prime_tower_enable else 0", "minimum_value": "0", "maximum_value_warning": "20", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "prime_tower_position_x": { @@ -2207,7 +2818,10 @@ "default_value": 200, "minimum_value_warning": "-1000", "maximum_value_warning": "1000", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "prime_tower_position_y": { @@ -2219,7 +2833,10 @@ "default_value": 200, "minimum_value_warning": "-1000", "maximum_value_warning": "1000", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "prime_tower_flow": { @@ -2232,7 +2849,10 @@ "minimum_value": "0.0001", "minimum_value_warning": "50", "maximum_value_warning": "150", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "prime_tower_wipe_enabled": { @@ -2241,7 +2861,10 @@ "type": "bool", "enabled": "prime_tower_enable", "default_value": false, - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "multiple_mesh_overlap": { @@ -2251,7 +2874,11 @@ "unit": "mm", "default_value": 0.15, "minimum_value": "0", - "maximum_value_warning": "1.0" + "maximum_value_warning": "1.0", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "ooze_shield_enabled": { @@ -2259,7 +2886,10 @@ "description": "Enable exterior ooze shield. This will create a shell around the object which is likely to wipe a second nozzle if it's at the same height as the first nozzle.", "type": "bool", "default_value": false, - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "ooze_shield_angle": { @@ -2271,7 +2901,10 @@ "default_value": 60, "minimum_value": "0", "maximum_value": "90", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "ooze_shield_dist": { @@ -2283,7 +2916,10 @@ "default_value": 2, "minimum_value": "0", "maximum_value_warning": "30", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -2301,7 +2937,10 @@ "description": "This will create a wall around the object, which traps (hot) air and shields against exterior airflow. Especially useful for materials which warp easily.", "type": "bool", "default_value": false, - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "draft_shield_dist": { @@ -2313,7 +2952,10 @@ "maximum_value_warning": "100", "default_value": 10, "enabled": "draft_shield_enabled", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "draft_shield_height_limitation": { @@ -2327,7 +2969,10 @@ }, "default_value": "full", "enabled": "draft_shield_enabled", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "draft_shield_height": { @@ -2340,7 +2985,10 @@ "default_value": 0, "value": "9999 if draft_shield_height_limitation == 'full' and draft_shield_enabled else 0.0", "enabled": "draft_shield_height_limitation == \"limited\"", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": true, + "settable_globally": true }, "conical_overhang_enabled": { "label": "Make Overhang Printable", @@ -2364,7 +3012,10 @@ "description": "Coasting replaces the last part of an extrusion path with a travel path. The oozed material is used to print the last piece of the extrusion path in order to reduce stringing.", "type": "bool", "default_value": false, - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "coasting_volume": { @@ -2376,7 +3027,10 @@ "minimum_value": "0", "maximum_value_warning": "2.0", "enabled": "coasting_enable", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "coasting_min_volume": { @@ -2388,7 +3042,10 @@ "minimum_value": "0", "maximum_value_warning": "10.0", "enabled": "coasting_enable", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "coasting_speed": { @@ -2400,7 +3057,10 @@ "minimum_value": "0.0001", "maximum_value_warning": "100", "enabled": "coasting_enable", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "skin_outline_count": { @@ -2409,7 +3069,11 @@ "default_value": 0, "minimum_value": "0", "maximum_value_warning": "10", - "type": "int" + "type": "int", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "skin_alternate_rotation": { @@ -2417,7 +3081,11 @@ "description": "Alternate the direction in which the top/bottom layers are printed. Normally they are printed diagonally only. This setting adds the X-only and Y-only directions.", "type": "bool", "default_value": false, - "enabled": "top_bottom_pattern != \"concentric\"" + "enabled": "top_bottom_pattern != \"concentric\"", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_conical_enabled": { @@ -2425,7 +3093,11 @@ "description": "Experimental feature: Make support areas smaller at the bottom than at the overhang.", "type": "bool", "default_value": false, - "enabled": "support_enable" + "enabled": "support_enable", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_conical_angle": { @@ -2438,7 +3110,11 @@ "maximum_value_warning": "45", "maximum_value": "90", "default_value": 30, - "enabled": "support_conical_enabled and support_enable" + "enabled": "support_conical_enabled and support_enable", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "support_conical_min_width": { @@ -2450,14 +3126,22 @@ "minimum_value_warning": "machine_nozzle_size * 3", "maximum_value_warning": "100.0", "type": "float", - "enabled": "support_conical_enabled and support_enable" + "enabled": "support_conical_enabled and support_enable", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "magic_fuzzy_skin_enabled": { "label": "Fuzzy Skin", "description": "Randomly jitter while printing the outer wall, so that the surface has a rough and fuzzy look.", "type": "bool", - "default_value": false + "default_value": false, + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "magic_fuzzy_skin_thickness": { @@ -2468,7 +3152,11 @@ "default_value": 0.3, "minimum_value": "0.001", "maximum_value_warning": "wall_line_width_0", - "enabled": "magic_fuzzy_skin_enabled" + "enabled": "magic_fuzzy_skin_enabled", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true }, "magic_fuzzy_skin_point_density": { @@ -2482,6 +3170,10 @@ "maximum_value_warning": "10", "maximum_value": "2 / magic_fuzzy_skin_thickness", "enabled": "magic_fuzzy_skin_enabled", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true, "children": { "magic_fuzzy_skin_point_dist": @@ -2495,7 +3187,11 @@ "minimum_value_warning": "0.1", "maximum_value_warning": "10", "value": "10000 if magic_fuzzy_skin_point_density == 0 else 1 / magic_fuzzy_skin_point_density", - "enabled": "magic_fuzzy_skin_enabled" + "enabled": "magic_fuzzy_skin_enabled", + "settable_per_mesh": true, + "settable_per_extruder": true, + "settable_per_meshgroup": true, + "settable_globally": true } } }, @@ -2505,7 +3201,10 @@ "description": "Print only the outside surface with a sparse webbed structure, printing 'in thin air'. This is realized by horizontally printing the contours of the model at given Z intervals which are connected via upward and diagonally downward lines.", "type": "bool", "default_value": false, - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "wireframe_height": { @@ -2517,7 +3216,10 @@ "minimum_value": "0.0001", "maximum_value_warning": "20", "enabled": "wireframe_enabled", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "wireframe_roof_inset": { @@ -2531,7 +3233,10 @@ "maximum_value_warning": "20", "enabled": "wireframe_enabled", "value": "wireframe_height", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "wireframe_printspeed": { @@ -2544,7 +3249,10 @@ "maximum_value": "299792458000", "maximum_value_warning": "50", "enabled": "wireframe_enabled", - "global_only": "True", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true, "children": { "wireframe_printspeed_bottom": @@ -2558,8 +3266,11 @@ "maximum_value": "299792458000", "maximum_value_warning": "50", "enabled": "wireframe_enabled", - "global_only": "True", - "value": "wireframe_printspeed" + "value": "wireframe_printspeed", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "wireframe_printspeed_up": { @@ -2572,8 +3283,11 @@ "maximum_value": "299792458000", "maximum_value_warning": "50", "enabled": "wireframe_enabled", - "global_only": "True", - "value": "wireframe_printspeed" + "value": "wireframe_printspeed", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "wireframe_printspeed_down": { @@ -2586,8 +3300,11 @@ "maximum_value": "299792458000", "maximum_value_warning": "50", "enabled": "wireframe_enabled", - "global_only": "True", - "value": "wireframe_printspeed" + "value": "wireframe_printspeed", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "wireframe_printspeed_flat": { @@ -2601,7 +3318,10 @@ "maximum_value_warning": "100", "value": "wireframe_printspeed", "enabled": "wireframe_enabled", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true } } }, @@ -2615,7 +3335,10 @@ "maximum_value_warning": "100", "type": "float", "enabled": "wireframe_enabled", - "global_only": "True", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true, "children": { "wireframe_flow_connection": @@ -2628,8 +3351,11 @@ "maximum_value_warning": "100", "type": "float", "enabled": "wireframe_enabled", - "global_only": "True", - "value": "wireframe_flow" + "value": "wireframe_flow", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "wireframe_flow_flat": { @@ -2641,8 +3367,11 @@ "maximum_value_warning": "100", "type": "float", "enabled": "wireframe_enabled", - "global_only": "True", - "value": "wireframe_flow" + "value": "wireframe_flow", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true } } }, @@ -2656,7 +3385,10 @@ "minimum_value": "0", "maximum_value_warning": "1", "enabled": "wireframe_enabled", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "wireframe_bottom_delay": { @@ -2668,7 +3400,10 @@ "minimum_value": "0", "maximum_value_warning": "1", "enabled": "wireframe_enabled", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "wireframe_flat_delay": { @@ -2680,7 +3415,10 @@ "minimum_value": "0", "maximum_value_warning": "0.5", "enabled": "wireframe_enabled", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "wireframe_up_half_speed": { @@ -2692,7 +3430,10 @@ "minimum_value": "0", "maximum_value_warning": "5.0", "enabled": "wireframe_enabled", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "wireframe_top_jump": { @@ -2704,7 +3445,10 @@ "minimum_value": "0", "maximum_value_warning": "2.0", "enabled": "wireframe_enabled", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "wireframe_fall_down": { @@ -2716,7 +3460,10 @@ "minimum_value": "0", "maximum_value_warning": "wireframe_height", "enabled": "wireframe_enabled", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "wireframe_drag_along": { @@ -2728,7 +3475,10 @@ "minimum_value": "0", "maximum_value_warning": "wireframe_height", "enabled": "wireframe_enabled", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "wireframe_strategy": { @@ -2743,7 +3493,10 @@ }, "default_value": "compensate", "enabled": "wireframe_enabled", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "wireframe_straight_before_down": { @@ -2755,7 +3508,10 @@ "minimum_value": "0", "maximum_value": "100", "enabled": "wireframe_enabled", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "wireframe_roof_fall_down": { @@ -2767,7 +3523,10 @@ "minimum_value_warning": "0", "maximum_value_warning": "wireframe_roof_inset", "enabled": "wireframe_enabled", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "wireframe_roof_drag_along": { @@ -2779,7 +3538,10 @@ "minimum_value": "0", "maximum_value_warning": "10", "enabled": "wireframe_enabled", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "wireframe_roof_outer_delay": { @@ -2791,7 +3553,10 @@ "minimum_value": "0", "maximum_value_warning": "2.0", "enabled": "wireframe_enabled", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true }, "wireframe_nozzle_clearance": { @@ -2803,7 +3568,10 @@ "minimum_value_warning": "0", "maximum_value_warning": "10.0", "enabled": "wireframe_enabled", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": true } } } From fc0a3c83472e77b0fa0ff7484361c4a92a665ca2 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Tue, 7 Jun 2016 18:30:30 +0200 Subject: [PATCH 509/705] JSON feat: replaced global_only with four properties settable_per_[mesh|extruder|meshgroup] and settable_globally for fdmextruder settings (CURA-1558) --- resources/definitions/fdmextruder.def.json | 56 +++++++++++++++++----- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/resources/definitions/fdmextruder.def.json b/resources/definitions/fdmextruder.def.json index 69797385a1..940b0bb3ed 100644 --- a/resources/definitions/fdmextruder.def.json +++ b/resources/definitions/fdmextruder.def.json @@ -24,7 +24,11 @@ "description": "The extruder train used for printing. This is used in multi-extrusion.", "type": "extruder", "default_value": 0, - "minimum_value": "0" + "minimum_value": "0", + "settable_per_mesh": true, + "settable_per_extruder": false, + "settable_per_meshgroup": false, + "settable_globally": false }, "machine_nozzle_offset_x": { @@ -33,7 +37,10 @@ "type": "float", "unit": "mm", "default_value": 0, - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": false, + "settable_globally": false }, "machine_nozzle_offset_y": { @@ -42,7 +49,10 @@ "type": "float", "unit": "mm", "default_value": 0, - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": false, + "settable_globally": false }, "machine_extruder_start_code": { @@ -50,7 +60,10 @@ "description": "Start g-code to execute whenever turning the extruder on.", "type": "str", "default_value": "", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": false, + "settable_globally": false }, "machine_extruder_start_pos_abs": { @@ -58,7 +71,10 @@ "description": "Make the extruder starting position absolute rather than relative to the last-known location of the head.", "type": "bool", "default_value": false, - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": false, + "settable_globally": false }, "machine_extruder_start_pos_x": { @@ -67,7 +83,10 @@ "type": "float", "unit": "mm", "default_value": 0, - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": false, + "settable_globally": false }, "machine_extruder_start_pos_y": { @@ -76,7 +95,10 @@ "type": "float", "unit": "mm", "default_value": 0, - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": false, + "settable_globally": false }, "machine_extruder_end_code": { @@ -84,7 +106,10 @@ "description": "End g-code to execute whenever turning the extruder off.", "type": "str", "default_value": "", - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": false, + "settable_globally": false }, "machine_extruder_end_pos_abs": { @@ -92,7 +117,10 @@ "description": "Make the extruder ending position absolute rather than relative to the last-known location of the head.", "type": "bool", "default_value": false, - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": false, + "settable_globally": false }, "machine_extruder_end_pos_x": { @@ -101,7 +129,10 @@ "type": "float", "unit": "mm", "default_value": 0, - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": false, + "settable_globally": false }, "machine_extruder_end_pos_y": { @@ -110,7 +141,10 @@ "type": "float", "unit": "mm", "default_value": 0, - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": false, + "settable_globally": false } } } From 21b1891c0ee72afa44a6d606fe40ff5a11bc8776 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 7 Jun 2016 18:55:27 +0200 Subject: [PATCH 510/705] Make unique name generation more robust and simpler CURA-1585 --- cura/MachineManagerModel.py | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index c0ac74abe4..202ca3611c 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -106,14 +106,12 @@ class MachineManagerModel(QObject): Application.getInstance().setGlobalContainerStack(containers[0]) @pyqtSlot(str, str) - def addMachine(self,name, definition_id): + def addMachine(self, name, definition_id): definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id=definition_id) if definitions: definition = definitions[0] + name = self._createUniqueName("machine", "", name, definition.getName()) new_global_stack = UM.Settings.ContainerStack(name) - name = self._createUniqueName(new_global_stack, "machine", name, definition.getName()) - new_global_stack._id = name - new_global_stack.setName(name) new_global_stack.addMetaDataEntry("type", "machine") UM.Settings.ContainerRegistry.getInstance().addContainer(new_global_stack) @@ -142,12 +140,12 @@ class MachineManagerModel(QObject): Application.getInstance().setGlobalContainerStack(new_global_stack) ## Create a name that is not empty and unique - # \param container \type{} container to create a unique name for # \param container_type \type{string} Type of the container (machine, quality, ...) - # \param new_name \type{string} Name base name, which may not be unique + # \param current_name \type{} Current name of the container, which may be an acceptable option + # \param new_name \type{string} Base name, which may not be unique # \param fallback_name \type{string} Name to use when (stripped) new_name is empty # \return \type{string} Name that is unique for the specified type and name/id - def _createUniqueName(self, container, object_type, new_name, fallback_name): + def _createUniqueName(self, container_type, current_name, new_name, fallback_name): new_name = new_name.strip() num_check = re.compile("(.*?)\s*#\d+$").match(new_name) if num_check: @@ -157,7 +155,8 @@ class MachineManagerModel(QObject): unique_name = new_name i = 1 - while self._containerWithIdOrNameExists(unique_name, object_type, container): + # In case we are renaming, the current name of the container is also a valid end-result + while self._containerExists(container_type, unique_name) and unique_name != current_name: i += 1 unique_name = "%s #%d" % (new_name, i) @@ -165,17 +164,13 @@ class MachineManagerModel(QObject): ## Check if a container with of a certain type and a certain name or id exists # Both the id and the name are checked, because they may not be the same and it is better if they are both unique - def _containerWithIdOrNameExists(self, id_or_name, container_type, exclude_container = None): + # \param container_type \type{string} Type of the container (machine, quality, ...) + # \param container_name \type{string} Name to check + def _containerExists(self, container_type, container_name): container_class = ContainerStack if container_type == "machine" else InstanceContainer - containers = UM.Settings.ContainerRegistry.getInstance().findContainers(container_class, id = id_or_name, type = container_type) - if containers and containers[0] != exclude_container: - return True - containers = UM.Settings.ContainerRegistry.getInstance().findContainers(container_class, name = id_or_name, type = container_type) - if containers and containers[0] != exclude_container: - return True - - return False + return UM.Settings.ContainerRegistry.getInstance().findContainers(container_class, id = container_name, type = container_type) or \ + UM.Settings.ContainerRegistry.getInstance().findContainers(container_class, name = container_name, type = container_type) ## Convenience function to check if a stack has errors. def _checkStackForErrors(self, stack): @@ -274,7 +269,7 @@ class MachineManagerModel(QObject): return new_quality_container = InstanceContainer("") - name = self._createUniqueName(new_quality_container, "quality", self.activeQualityName, catalog.i18nc("@label", "Custom profile")) + name = self._createUniqueName("quality", "", self.activeQualityName, catalog.i18nc("@label", "Custom profile")) user_settings = self._global_container_stack.getTop() ## Copy all values @@ -303,7 +298,7 @@ class MachineManagerModel(QObject): return containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=container_id) if containers: - new_name = self._createUniqueName(containers[0], "quality", containers[0].getName(), catalog.i18nc("@label", "Custom profile")) + new_name = self._createUniqueName("quality", "", containers[0].getName(), catalog.i18nc("@label", "Custom profile")) new_container = InstanceContainer("") @@ -323,7 +318,7 @@ class MachineManagerModel(QObject): def renameQualityContainer(self, container_id, new_name): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id, type = "quality") if containers: - new_name = self._createUniqueName(containers[0], "quality", new_name, catalog.i18nc("@label", "Custom profile")) + new_name = self._createUniqueName("quality", containers[0].getName(), new_name, catalog.i18nc("@label", "Custom profile")) containers[0].setName(new_name) UM.Settings.ContainerRegistry.getInstance().containerChanged.emit(containers[0]) @@ -426,7 +421,7 @@ class MachineManagerModel(QObject): def renameMachine(self, machine_id, new_name): containers = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = machine_id) if containers: - new_name = self._createUniqueName(containers[0], "machine", new_name, containers[0].getBottom().getName()) + new_name = self._createUniqueName("machine", containers[0].getName(), new_name, containers[0].getBottom().getName()) containers[0].setName(new_name) self.globalContainerChanged.emit() From f7480baca2c7f1648571fbf8bb9d1e9a892cddc1 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 7 Jun 2016 19:25:12 +0200 Subject: [PATCH 511/705] Fix selecting another quality when the currently active quality is removed CURA-1585 --- cura/MachineManagerModel.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 202ca3611c..5f3ca0b7af 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -335,11 +335,11 @@ class MachineManagerModel(QObject): UM.Settings.ContainerRegistry.getInstance().removeContainer(container_id) if activate_new_container: - old_container = self._global_container_stack.findInstanceContainers({"type": "quality"}) - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = container_type) - if containers and old_container: - container_index = self._global_container_stack.getContainerIndex(old_container) - self._global_container_stack.replaceContainer(container_index, containers[0]) + definition_id = "fdmprinter" if not self.filterQualityByMachine else self.activeDefinitionId + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "quality", definition = definition_id) + if containers: + self.setActiveQuality(containers[0].getId()) + self.activeQualityChanged.emit() @pyqtSlot() From b452af5dbf5997c92e47ea09a4366d7f876c538d Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 7 Jun 2016 19:31:35 +0200 Subject: [PATCH 512/705] Update Profile dropdown when renaming a quality profile CURA-1585 --- cura/MachineManagerModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 5f3ca0b7af..02d8db8290 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -320,7 +320,7 @@ class MachineManagerModel(QObject): if containers: new_name = self._createUniqueName("quality", containers[0].getName(), new_name, catalog.i18nc("@label", "Custom profile")) containers[0].setName(new_name) - UM.Settings.ContainerRegistry.getInstance().containerChanged.emit(containers[0]) + self.activeQualityChanged.emit() @pyqtSlot(str) From ec2657947345c7b76f59bbec4ab0898b658c26cc Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 14:59:32 +0200 Subject: [PATCH 513/705] Remove unused _repopulate function It is replaced by the addMachineExtruders function. Contributes to issues CURA-340 and CURA-1278. --- cura/ExtruderManager.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index df31cbacdf..23a72b2c3b 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -80,23 +80,6 @@ class ExtruderManager(QObject): if extruder_trains: self.extrudersChanged.emit() - ## (Re)populates the collections of extruders by machine. - def _repopulate(self): - self._extruder_trains = { } - if not UM.Application.getInstance().getGlobalContainerStack(): #No machine has been added yet. - self.extrudersChanged.emit() #Yes, we just cleared the _extruders list! - return #Then leave them empty! - - extruder_trains = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(type = "extruder_train") - for extruder_train in extruder_trains: - machine_id = extruder_train.getMetaDataEntry("machine") - if not machine_id: - continue - if machine_id not in self._extruder_trains: - self._extruder_trains[machine_id] = { } - self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train.getId() - self.extrudersChanged.emit() - def createExtruderTrain(self, extruder_definition, machine_definition, extruder_train_id, position): container_registry = UM.Settings.ContainerRegistry.getInstance() From f461ed0f5f62f2cbf556c32037298bb5c7052514 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 15:26:51 +0200 Subject: [PATCH 514/705] Document singleton Contributes to issues CURA-340 and CURA-1278. --- cura/ExtruderManager.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 23a72b2c3b..b40bb0f664 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -39,7 +39,18 @@ class ExtruderManager(QObject): except KeyError: #Extruder index could be -1 if the global tab is selected, or the entry doesn't exist if the machine definition is wrong. return None + ## The instance of the singleton pattern. + # + # It's None if the extruder manager hasn't been created yet. __instance = None + + ## Gets an instance of the extruder manager, or creates one if no instance + # exists yet. + # + # This is an implementation of singleton. If an extruder manager already + # exists, it is re-used. + # + # \return The extruder manager. @classmethod def getInstance(cls): if not cls.__instance: From 98a0f90dae4764bfb77ca6feaf92412e7716aaf3 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 16:56:55 +0200 Subject: [PATCH 515/705] Remove unused variable _active_extruder_index This index is managed by ExtruderManager. Contributes to issues CURA-340 and CURA-1278. --- cura/MachineManagerModel.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 02d8db8290..e7034412f5 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -36,8 +36,6 @@ class MachineManagerModel(QObject): active_machine_id = Preferences.getInstance().getValue("cura/active_machine") - self._active_extruder_index = 0 - if active_machine_id != "": # An active machine was saved, so restore it. self.setActiveMachine(active_machine_id) From 8b1c36393261608ade3257386d613cb72d5e32cd Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 17:37:25 +0200 Subject: [PATCH 516/705] Load current machine's extruders upon creation, start and switch of machines This requires some trickery of initialising the extruder manager before the machine manager is initialised, so that it properly listens to global container stack changes. Contributes to issues CURA-340 and CURA-1278. --- cura/CuraApplication.py | 1 + cura/ExtruderManager.py | 29 ++++++++++++++++++++++++----- cura/ExtrudersModel.py | 11 ++++++++--- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 7edb0bf8bd..37ba6cf7ad 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -351,6 +351,7 @@ class CuraApplication(QtApplication): self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Loading interface...")) + ExtruderManager.ExtruderManager.getInstance() #Initialise extruder so as to listen to global container stack changes before the first global container stack is set. qmlRegisterSingletonType(MachineManagerModel.MachineManagerModel, "Cura", 1, 0, "MachineManager", MachineManagerModel.createMachineManagerModel) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index b40bb0f664..c71dd27414 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -1,7 +1,7 @@ # Copyright (c) 2016 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. -from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject #For communicating data and events to Qt. +from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject, QVariant #For communicating data and events to Qt. import UM.Application #To get the global container stack to find the current machine. import UM.Logger @@ -13,7 +13,7 @@ import UM.Settings.ContainerRegistry #Finding containers by ID. # This keeps a list of extruder stacks for each machine. class ExtruderManager(QObject): ## Signal to notify other components when the list of extruders changes. - extrudersChanged = pyqtSignal() + extrudersChanged = pyqtSignal(QVariant) ## Notify when the user switches the currently active extruder. activeExtruderChanged = pyqtSignal() @@ -21,8 +21,9 @@ class ExtruderManager(QObject): ## Registers listeners and such to listen to changes to the extruders. def __init__(self, parent = None): super().__init__(parent) - self._extruder_trains = { } #Extruders for the current machine. + self._extruder_trains = { } #Per machine, a dictionary of extruder container stack IDs. self._active_extruder_index = 0 + UM.Application.getInstance().globalContainerStackChanged.connect(self._addCurrentMachineExtruders) ## Gets the unique identifier of the currently active extruder stack. # @@ -79,7 +80,7 @@ class ExtruderManager(QObject): for extruder_definition in container_registry.findDefinitionContainers(machine = machine_definition.getId()): position = extruder_definition.getMetaDataEntry("position", None) if not position: - UM.Logger.Log("w", "Extruder definition %s specifies no position metadata entry.", extruder_definition.getId()) + UM.Logger.log("w", "Extruder definition %s specifies no position metadata entry.", extruder_definition.getId()) if not container_registry.findContainerStacks(machine = machine_id, position = position): #Doesn't exist yet. name = container_registry.uniqueName(extruder_definition.getId()) #Make a name based on the ID of the definition. self.createExtruderTrain(extruder_definition, machine_definition, name, position) @@ -89,7 +90,7 @@ class ExtruderManager(QObject): for extruder_train in extruder_trains: self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train.getId() if extruder_trains: - self.extrudersChanged.emit() + self.extrudersChanged.emit(machine_definition) def createExtruderTrain(self, extruder_definition, machine_definition, extruder_train_id, position): container_registry = UM.Settings.ContainerRegistry.getInstance() @@ -156,3 +157,21 @@ class ExtruderManager(QObject): container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack()) container_registry.addContainer(container_stack) + + ## Generates extruders for a specific machine. + def getMachineExtruders(self, machine_definition): + container_registry = UM.Settings.ContainerRegistry.getInstance() + machine_id = machine_definition.getId() + if not machine_id in self._extruder_trains: + UM.Logger.log("w", "Tried to get the extruder trains for machine %s, which doesn't exist.", machine_id) + return + for extruder_train_id in self._extruder_trains[machine_id]: + extruder_train = container_registry.findContainerStacks(id = extruder_train_id) + if extruder_train: + yield extruder_train[0] + + ## Adds the extruders of the currently active machine. + def _addCurrentMachineExtruders(self): + global_stack = UM.Application.getInstance().getGlobalContainerStack() + if global_stack and global_stack.getBottom(): + self.addMachineExtruders(global_stack.getBottom()) \ No newline at end of file diff --git a/cura/ExtrudersModel.py b/cura/ExtrudersModel.py index 7e00611742..691a5c7690 100644 --- a/cura/ExtrudersModel.py +++ b/cura/ExtrudersModel.py @@ -9,7 +9,8 @@ import UM.Qt.ListModel ## Model that holds extruders. # # This model is designed for use by any list of extruders, but specifically -# intended for drop-down lists of extruders in place of settings. +# intended for drop-down lists of the current machine's extruders in place of +# settings. class ExtrudersModel(UM.Qt.ListModel.ListModel): ## Human-readable name of the extruder. NameRole = Qt.UserRole + 1 @@ -37,7 +38,8 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): #Listen to changes. manager = cura.ExtruderManager.ExtruderManager.getInstance() - manager.extrudersChanged.connect(self._updateExtruders) + manager.extrudersChanged.connect(self._updateExtruders) #When the list of extruders changes in general. + UM.Application.globalContainerStackChanged.connect(self._updateExtruders) #When the current machine changes. self._updateExtruders() ## Update the list of extruders. @@ -46,7 +48,10 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): def _updateExtruders(self): self.clear() manager = cura.ExtruderManager.ExtruderManager.getInstance() - for index, extruder in enumerate(manager._extruder_trains): + global_container_stack = UM.Application.getInstance().getGlobalContainerStack() + if not global_container_stack: + return #There is no machine to get the extruders of. + for index, extruder in manager.getMachineExtruders(global_container_stack.getBottom()): item = { #Construct an item with only the relevant information. "name": extruder.name, "colour": extruder.material.getMetaDataEntry("color_code", default = "#FFFF00"), From 2e2437d1632250aa1588b9b24faebbdcb38b50f9 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Wed, 8 Jun 2016 10:50:40 +0200 Subject: [PATCH 517/705] feat: use settable_per_[mesh|extruder|meshgroup|globally] instead of global_only (CURA-1560) --- cura/CuraApplication.py | 5 ++++- plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 7edb0bf8bd..646e257ff3 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -91,7 +91,10 @@ class CuraApplication(QtApplication): self._open_file_queue = [] # Files to open when plug-ins are loaded. # Need to do this before ContainerRegistry tries to load the machines - SettingDefinition.addSupportedProperty("global_only", DefinitionPropertyType.Function, default = False) + SettingDefinition.addSupportedProperty("settable_per_mesh", DefinitionPropertyType.Function, default = True) + SettingDefinition.addSupportedProperty("settable_per_extruder", DefinitionPropertyType.Function, default = True) + SettingDefinition.addSupportedProperty("settable_per_meshgroup", DefinitionPropertyType.Function, default = True) + SettingDefinition.addSupportedProperty("settable_globally", DefinitionPropertyType.Function, default = True) SettingDefinition.addSettingType("extruder", int, str, UM.Settings.Validator) super().__init__(name = "cura", version = CuraVersion, buildtype = CuraBuildType) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index c89485517e..bc721782ae 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -190,11 +190,11 @@ Item { { if(text != "") { - listview.model.filter = {"global_only": false, "label": "*" + text} + listview.model.filter = {"settable_per_mesh": true, "label": "*" + text} } else { - listview.model.filter = {"global_only": false} + listview.model.filter = {"settable_per_mesh": true} } } } @@ -219,7 +219,7 @@ Item { containerId: Cura.MachineManager.activeDefinitionId filter: { - "global_only": false + "settable_per_mesh": true } visibilityHandler: UM.SettingPreferenceVisibilityHandler {} } From 1a8fe6aa1fb7dd22034f02d61338d1e8d1faab04 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 8 Jun 2016 10:55:48 +0200 Subject: [PATCH 518/705] Fix customised settings indicator CURA-1585 --- resources/qml/ProfileSetup.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/ProfileSetup.qml b/resources/qml/ProfileSetup.qml index c6291c8c85..48d52c539a 100644 --- a/resources/qml/ProfileSetup.qml +++ b/resources/qml/ProfileSetup.qml @@ -143,7 +143,7 @@ Item{ UM.SimpleButton { id: customisedSettings - visible: UM.ActiveProfile.hasCustomisedValues + visible: Cura.MachineManager.hasUserSettings height: parent.height * 0.6 width: parent.height * 0.6 From 77431b01a3ddb88952c6d2283e420386cb92d19e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 8 Jun 2016 11:02:04 +0200 Subject: [PATCH 519/705] Inherit button now has the same behaviour as 2.1 again CURA-1278 --- resources/qml/Settings/SettingItem.qml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index e4edc267ef..eb8fabec28 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -24,7 +24,7 @@ Item { // Create properties to put property provider stuff in (bindings break in qt 5.5.1 otherwise) property var state: propertyProvider.properties.state - property var stackLevel: propertyProvider.stackLevel + property var stackLevel: propertyProvider.stackLevels[0] signal contextMenuRequested() signal showTooltip(string text); @@ -166,7 +166,15 @@ Item { onClicked: { focus = true; - propertyProvider.removeFromContainer(base.stackLevel) + // Get the deepest entry of this setting that we can find. TODO: This is a bit naive, in some cases + // there might be multiple profiles saying something about the same setting. There is no strategy + // how to handle this as of yet. + var last_entry = propertyProvider.stackLevels.slice(-1)[0] + // Put that entry into the "top" instance container. + // This ensures that the value in any of the deeper containers need not be removed, which is + // needed for the reset button (which deletes the top value) to correctly go back to profile + // defaults. + propertyProvider.setPropertyValue("value", propertyProvider.getPropertyValue("value", last_entry)) } backgroundColor: UM.Theme.getColor("setting_control"); From af484b03d80a5379c5eebd38b1a26f3e89a66cfd Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 8 Jun 2016 10:45:32 +0200 Subject: [PATCH 520/705] Fix typo in variable name --- plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml | 2 +- resources/qml/Settings/SettingItem.qml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index 9565b0e345..667f842469 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -61,7 +61,7 @@ Item { onLoaded: { settingLoader.item.showRevertButton = false settingLoader.item.showInheritButton = false - settingLoader.item.doDepthIdentation = false + settingLoader.item.doDepthIndentation = false } sourceComponent: diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index eb8fabec28..4fa615134b 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -20,7 +20,7 @@ Item { property var showRevertButton: true property var showInheritButton: true - property var doDepthIdentation: true + property var doDepthIndentation: true // Create properties to put property provider stuff in (bindings break in qt 5.5.1 otherwise) property var state: propertyProvider.properties.state @@ -101,7 +101,7 @@ Item { id: label; anchors.left: parent.left; - anchors.leftMargin: doDepthIdentation ? (UM.Theme.getSize("section_icon_column").width + 5) + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width) : 0 + anchors.leftMargin: doDepthIndentation ? (UM.Theme.getSize("section_icon_column").width + 5) + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width) : 0 anchors.right: settingControls.left; anchors.verticalCenter: parent.verticalCenter From 4aa495f9efa8dba6120c129f193186502c6d802b Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 8 Jun 2016 10:56:51 +0200 Subject: [PATCH 521/705] Fix getting name and colour from extruder There used to be an extruder object from which we could ask these properties. But now we have a container stack in its place, so we need to get the properties in a slightly different way. Contributes to issues CURA-1278 and CURA-340. --- cura/ExtrudersModel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/ExtrudersModel.py b/cura/ExtrudersModel.py index 691a5c7690..cd85181787 100644 --- a/cura/ExtrudersModel.py +++ b/cura/ExtrudersModel.py @@ -53,8 +53,8 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): return #There is no machine to get the extruders of. for index, extruder in manager.getMachineExtruders(global_container_stack.getBottom()): item = { #Construct an item with only the relevant information. - "name": extruder.name, - "colour": extruder.material.getMetaDataEntry("color_code", default = "#FFFF00"), + "name": extruder.getName(), + "colour": extruder.findContainer(type = "material").getMetaDataEntry("color_code", default = "#FFFF00"), "index": index } self.appendItem(item) From 675a8c140e1bf22ed9c396298ff150d66f9d7e69 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 8 Jun 2016 11:00:50 +0200 Subject: [PATCH 522/705] Give default colour if there is no material Otherwise it would try to call getMetaDataEntry on None. Contributes to issues CURA-340 and CURA-1278. --- cura/ExtrudersModel.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cura/ExtrudersModel.py b/cura/ExtrudersModel.py index cd85181787..a915a21506 100644 --- a/cura/ExtrudersModel.py +++ b/cura/ExtrudersModel.py @@ -52,9 +52,11 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): if not global_container_stack: return #There is no machine to get the extruders of. for index, extruder in manager.getMachineExtruders(global_container_stack.getBottom()): + material = extruder.findContainer(type = "material") + colour = material.getMetaDataEntry("color_code", default = "#FFFF00") if material else "#FFFF00" item = { #Construct an item with only the relevant information. "name": extruder.getName(), - "colour": extruder.findContainer(type = "material").getMetaDataEntry("color_code", default = "#FFFF00"), + "colour": colour, "index": index } self.appendItem(item) From 91797c3944c24e41b16883bb55f48d4294c046c1 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 8 Jun 2016 11:09:08 +0200 Subject: [PATCH 523/705] Log error if the machine refers to invalid extruder train ID This helped mostly for debugging but it should be a genuine warning. Contributes to issues CURA-1278 and CURA-340. --- cura/ExtruderManager.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index c71dd27414..3be0694440 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -169,6 +169,8 @@ class ExtruderManager(QObject): extruder_train = container_registry.findContainerStacks(id = extruder_train_id) if extruder_train: yield extruder_train[0] + else: + UM.Logger.log("w", "Machine %s refers to an extruder train with ID %s, which doesn't exist.", machine_id, extruder_train_id) ## Adds the extruders of the currently active machine. def _addCurrentMachineExtruders(self): From 21545af5c8eb425faee88caf1ca703ea8ea9ef1a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 8 Jun 2016 11:10:41 +0200 Subject: [PATCH 524/705] Get only values from extruder trains dictionary Instead of getting the keys, which are labeled '0' and '1', we'd like to get the values, which are the extruder train IDs themselves. Contributes to issues CURA-340 and CURA-1278. --- cura/ExtruderManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 3be0694440..8219066eca 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -165,7 +165,7 @@ class ExtruderManager(QObject): if not machine_id in self._extruder_trains: UM.Logger.log("w", "Tried to get the extruder trains for machine %s, which doesn't exist.", machine_id) return - for extruder_train_id in self._extruder_trains[machine_id]: + for _,extruder_train_id in self._extruder_trains[machine_id].items(): extruder_train = container_registry.findContainerStacks(id = extruder_train_id) if extruder_train: yield extruder_train[0] From 8c7b3a05b654e2eea12cf6a2a6525e6e97950bfc Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 8 Jun 2016 11:22:03 +0200 Subject: [PATCH 525/705] Enumerate again over the machine's extruders We needed to get the index, after all. Contributes to issues CURA-340 and CURA-1278. --- cura/ExtrudersModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/ExtrudersModel.py b/cura/ExtrudersModel.py index a915a21506..a95f9f8a99 100644 --- a/cura/ExtrudersModel.py +++ b/cura/ExtrudersModel.py @@ -51,7 +51,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): global_container_stack = UM.Application.getInstance().getGlobalContainerStack() if not global_container_stack: return #There is no machine to get the extruders of. - for index, extruder in manager.getMachineExtruders(global_container_stack.getBottom()): + for index, extruder in enumerate(manager.getMachineExtruders(global_container_stack.getBottom())): material = extruder.findContainer(type = "material") colour = material.getMetaDataEntry("color_code", default = "#FFFF00") if material else "#FFFF00" item = { #Construct an item with only the relevant information. From 8b75a230a0adad455787278683863bd70c63df41 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 8 Jun 2016 11:24:41 +0200 Subject: [PATCH 526/705] Fix findContainer call without kwargs It has no kwargs. This needs to be provided as dictionary. Contributes to issues CURA-340 and CURA-1278. --- cura/ExtrudersModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/ExtrudersModel.py b/cura/ExtrudersModel.py index a95f9f8a99..60bd60abab 100644 --- a/cura/ExtrudersModel.py +++ b/cura/ExtrudersModel.py @@ -52,7 +52,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): if not global_container_stack: return #There is no machine to get the extruders of. for index, extruder in enumerate(manager.getMachineExtruders(global_container_stack.getBottom())): - material = extruder.findContainer(type = "material") + material = extruder.findContainer({ "type": "material" }) colour = material.getMetaDataEntry("color_code", default = "#FFFF00") if material else "#FFFF00" item = { #Construct an item with only the relevant information. "name": extruder.getName(), From 56b00ad4250b276c69eceee517d90c9c3c8dfde4 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Wed, 8 Jun 2016 11:54:25 +0200 Subject: [PATCH 527/705] JSON cleanup: removed settable_per_x when they were obvious and default (CURA-1560) removed:settable_globally: true settable_per_meshgroup: true settable_per_extruder: true when settable_per_mesh was also true --- cura/CuraApplication.py | 8 +- resources/definitions/fdmprinter.def.json | 886 +++++----------------- 2 files changed, 203 insertions(+), 691 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 646e257ff3..da2b38ade7 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -91,10 +91,10 @@ class CuraApplication(QtApplication): self._open_file_queue = [] # Files to open when plug-ins are loaded. # Need to do this before ContainerRegistry tries to load the machines - SettingDefinition.addSupportedProperty("settable_per_mesh", DefinitionPropertyType.Function, default = True) - SettingDefinition.addSupportedProperty("settable_per_extruder", DefinitionPropertyType.Function, default = True) - SettingDefinition.addSupportedProperty("settable_per_meshgroup", DefinitionPropertyType.Function, default = True) - SettingDefinition.addSupportedProperty("settable_globally", DefinitionPropertyType.Function, default = True) + SettingDefinition.addSupportedProperty("settable_per_mesh", DefinitionPropertyType.Any, default = True) + SettingDefinition.addSupportedProperty("settable_per_extruder", DefinitionPropertyType.Any, default = True) + SettingDefinition.addSupportedProperty("settable_per_meshgroup", DefinitionPropertyType.Any, default = True) + SettingDefinition.addSupportedProperty("settable_globally", DefinitionPropertyType.Any, default = True) SettingDefinition.addSettingType("extruder", int, str, UM.Settings.Validator) super().__init__(name = "cura", version = CuraVersion, buildtype = CuraBuildType) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index f80d5d0d8f..504a0eac83 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -35,8 +35,7 @@ "label": "Show machine variants", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "machine_start_gcode": { @@ -46,8 +45,7 @@ "type": "str", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "machine_end_gcode": { @@ -57,8 +55,7 @@ "type": "str", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "material_bed_temp_wait": { @@ -68,8 +65,7 @@ "type": "bool", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "material_print_temp_prepend": { @@ -79,8 +75,7 @@ "label": "Wait for material heatup", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "machine_width": { @@ -90,8 +85,7 @@ "label": "Machine width", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "machine_depth": { @@ -101,8 +95,7 @@ "label": "Machine depth", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "machine_height": { @@ -112,8 +105,7 @@ "label": "Machine height", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "machine_heated_bed": { @@ -123,8 +115,7 @@ "type": "bool", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "machine_center_is_zero": { @@ -134,8 +125,7 @@ "label": "Is center origin", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "machine_extruder_count": { @@ -145,8 +135,7 @@ "label": "Number extruders", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "machine_nozzle_tip_outer_diameter": { @@ -167,8 +156,7 @@ "label": "Nozzle length", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "machine_nozzle_expansion_angle": { @@ -178,8 +166,7 @@ "label": "Nozzle angle", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "machine_heat_zone_length": { @@ -189,8 +176,7 @@ "label": "Heat zone length", "settable_per_mesh": false, "settable_per_extruder": true, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "machine_nozzle_heat_up_speed": { @@ -199,9 +185,7 @@ "type": "float", "label": "Heat up speed", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "machine_nozzle_cool_down_speed": { @@ -210,9 +194,7 @@ "type": "float", "label": "Cool down speed", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "machine_gcode_flavor": { @@ -222,8 +204,7 @@ "label": "Gcode flavour", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "machine_disallowed_areas": { @@ -233,8 +214,7 @@ "label": "Disallowed areas", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "machine_head_polygon": { @@ -262,8 +242,7 @@ "label": "Machine head polygon", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "machine_head_with_fans_polygon": { @@ -291,8 +270,7 @@ "label": "Machine head & Fan polygon", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "gantry_height": { @@ -302,8 +280,7 @@ "type": "float", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "machine_nozzle_size": { @@ -315,9 +292,7 @@ "minimum_value": "0.001", "maximum_value_warning": "10", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "machine_use_extruder_offset_to_offset_coords": { @@ -327,8 +302,7 @@ "default_value": true, "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false } } }, @@ -352,9 +326,7 @@ "maximum_value_warning": "0.8 * machine_nozzle_size", "default_value": true, "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "layer_height_0": { @@ -368,9 +340,7 @@ "maximum_value_warning": "0.8 * machine_nozzle_size", "default_value": true, "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "line_width": { @@ -398,9 +368,6 @@ "type": "float", "default_value": true, "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "wall_line_width_0": @@ -414,10 +381,7 @@ "default_value": 0.4, "value":"wall_line_width", "type": "float", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "wall_line_width_x": { @@ -430,10 +394,7 @@ "default_value": 0.4, "value":"wall_line_width", "type": "float", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true } } }, @@ -448,10 +409,7 @@ "default_value": 0.4, "type": "float", "value": "line_width", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "infill_line_width": { @@ -464,10 +422,7 @@ "default_value": 0.4, "type": "float", "value": "line_width", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "skirt_line_width": { @@ -481,9 +436,7 @@ "type": "float", "value": "line_width", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "support_line_width": { @@ -498,9 +451,7 @@ "enabled": "support_enable", "value": "line_width", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "support_roof_line_width": { @@ -514,9 +465,7 @@ "enabled": "support_roof_enable", "value": "line_width", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "prime_tower_line_width": { @@ -531,9 +480,7 @@ "minimum_value_warning": "0.2", "maximum_value_warning": "5", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true } } } @@ -558,9 +505,6 @@ "maximum_value_warning": "5 * line_width", "type": "float", "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "wall_line_count": @@ -571,10 +515,7 @@ "minimum_value": "0", "type": "int", "value": "1 if magic_spiralize else max(1, round((wall_thickness - wall_line_width_0) / wall_line_width_x) + 1)", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true } } }, @@ -589,9 +530,6 @@ "minimum_value_warning": "0.6", "type": "float", "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "top_thickness": @@ -605,9 +543,6 @@ "type": "float", "value": "top_bottom_thickness", "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "top_layers": @@ -619,10 +554,7 @@ "maximum_value_warning": "100", "type": "int", "value": "0 if infill_sparse_density == 100 else math.ceil(round(top_thickness / layer_height, 4))", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true } } }, @@ -636,9 +568,6 @@ "type": "float", "value": "top_bottom_thickness", "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "bottom_layers": @@ -649,10 +578,7 @@ "default_value": 6, "type": "int", "value": "999999 if infill_sparse_density == 100 else math.ceil(round(bottom_thickness / layer_height, 4))", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true } } } @@ -670,10 +596,7 @@ "zigzag": "Zig Zag" }, "default_value": "lines", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "wall_0_inset": { @@ -685,10 +608,7 @@ "value": "(machine_nozzle_size - wall_line_width_0) / 2 if wall_line_width_0 < machine_nozzle_size else 0", "minimum_value_warning": "0", "maximum_value_warning": "machine_nozzle_size", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "alternate_extra_perimeter": { @@ -696,10 +616,7 @@ "description": "Prints an extra wall at every other layer. This way infill gets caught between these extra walls, resulting in stronger prints.", "type": "bool", "default_value": false, - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "travel_compensate_overlapping_walls_enabled": { @@ -708,9 +625,6 @@ "type": "bool", "default_value": true, "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "travel_compensate_overlapping_walls_0_enabled": { @@ -719,10 +633,7 @@ "type": "bool", "default_value": true, "value": "travel_compensate_overlapping_walls_enabled", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "travel_compensate_overlapping_walls_x_enabled": { "label": "Compensate Inner Wall Overlaps", @@ -730,10 +641,7 @@ "type": "bool", "default_value": true, "value": "travel_compensate_overlapping_walls_enabled", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true } } }, @@ -746,10 +654,7 @@ "minimum_value_warning": "-10", "maximum_value_warning": "10", "default_value": 0, - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "z_seam_type": { @@ -763,10 +668,7 @@ "random": "Random" }, "default_value": "shortest", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "skin_no_small_gaps_heuristic": { @@ -774,10 +676,7 @@ "description": "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such case, disable the setting.", "type": "bool", "default_value": true, - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true } } }, @@ -799,9 +698,6 @@ "minimum_value": "0", "maximum_value_warning": "100", "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "infill_line_distance": @@ -813,10 +709,7 @@ "default_value": 2, "minimum_value": "0", "value": "0 if infill_sparse_density == 0 else (infill_line_width * 100) / infill_sparse_density * (2 if infill_pattern == \"grid\" else (3 if infill_pattern == \"triangles\" else 1))", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true } } }, @@ -835,10 +728,7 @@ }, "default_value": "grid", "value": "'lines' if infill_sparse_density > 25 else 'grid'", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "infill_overlap": { @@ -852,9 +742,6 @@ "maximum_value_warning": "100", "enabled": "infill_pattern != 'concentric'", "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "infill_overlap_mm": @@ -868,10 +755,7 @@ "maximum_value_warning": "machine_nozzle_size", "value": "infill_line_width * infill_overlap / 100 if infill_sparse_density < 95 and infill_pattern != 'concentric' else 0", "enabled": "infill_pattern != 'concentric'", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true } } }, @@ -886,9 +770,6 @@ "value": "5 if top_bottom_pattern != 'concentric' else 0", "enabled": "top_bottom_pattern != 'concentric'", "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "skin_overlap_mm": { "label": "Skin Overlap", @@ -900,10 +781,7 @@ "maximum_value_warning": "machine_nozzle_size", "value": "skin_line_width * skin_overlap / 100 if top_bottom_pattern != 'concentric' else 0", "enabled": "top_bottom_pattern != 'concentric'", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true } } }, @@ -917,10 +795,7 @@ "value": "wall_line_width_0 / 4 if wall_line_count == 1 else wall_line_width_x / 4", "minimum_value_warning": "0", "maximum_value_warning": "machine_nozzle_size", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "infill_sparse_thickness": { @@ -933,10 +808,7 @@ "maximum_value_warning": "0.32", "maximum_value": "layer_height * 8", "value": "layer_height", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "infill_before_walls": { @@ -944,10 +816,7 @@ "description": "Print the infill before printing the walls. Printing the walls first may lead to more accurate walls, but overhangs print worse. Printing the infill first leads to sturdier walls, but the infill pattern might sometimes show through the surface.", "type": "bool", "default_value": true, - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true } } }, @@ -967,9 +836,7 @@ "default_value": false, "enabled": "False", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "material_print_temperature": { @@ -982,9 +849,7 @@ "maximum_value_warning": "260", "enabled": "not (material_flow_dependent_temperature)", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "material_flow_temp_graph": { @@ -996,9 +861,7 @@ "enabled": "False", "comments": "old enabled function: material_flow_dependent_temperature", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "material_extrusion_cool_down_speed": { "label": "Extrusion Cool Down Speed Modifier", @@ -1011,9 +874,7 @@ "enabled": "False", "comments": "old enabled function: material_flow_dependent_temperature or machine_extruder_count > 1", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "material_bed_temperature": { "label": "Bed Temperature", @@ -1026,8 +887,7 @@ "enabled": "machine_heated_bed", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "material_diameter": { "label": "Diameter", @@ -1039,9 +899,7 @@ "minimum_value_warning": "0.4", "maximum_value_warning": "3.5", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "material_flow": { "label": "Flow", @@ -1052,20 +910,14 @@ "minimum_value": "5", "minimum_value_warning": "50", "maximum_value_warning": "150", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "retraction_enable": { "label": "Enable Retraction", "description": "Retract the filament when the nozzle is moving over a non-printed area. ", "type": "bool", "default_value": true, - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "retraction_amount": { "label": "Retraction Distance", @@ -1076,10 +928,7 @@ "minimum_value_warning": "-0.0001", "maximum_value_warning": "10.0", "enabled": "retraction_enable", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "retraction_speed": { "label": "Retraction Speed", @@ -1092,9 +941,6 @@ "maximum_value_warning": "100", "enabled": "retraction_enable", "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "retraction_retract_speed": { "label": "Retraction Retract Speed", @@ -1107,10 +953,7 @@ "maximum_value_warning": "100", "enabled": "retraction_enable", "value": "retraction_speed", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "retraction_prime_speed": { "label": "Retraction Prime Speed", @@ -1123,10 +966,7 @@ "maximum_value_warning": "100", "enabled": "retraction_enable", "value": "retraction_speed", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true } } }, @@ -1139,10 +979,7 @@ "minimum_value_warning": "-0.0001", "maximum_value_warning": "5.0", "enabled": "retraction_enable", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "retraction_min_travel": { "label": "Retraction Minimum Travel", @@ -1154,10 +991,7 @@ "minimum_value": "0", "maximum_value_warning": "10", "enabled": "retraction_enable", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "retraction_count_max": { "label": "Maximum Retraction Count", @@ -1167,10 +1001,7 @@ "maximum_value_warning": "100", "type": "int", "enabled": "retraction_enable", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "retraction_extrusion_window": { "label": "Minimum Extrusion Distance Window", @@ -1182,10 +1013,7 @@ "maximum_value_warning": "retraction_amount * 2", "value": "retraction_amount", "enabled": "retraction_enable", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "retraction_hop": { "label": "Z Hop when Retracting", @@ -1196,10 +1024,7 @@ "minimum_value_warning": "-0.0001", "maximum_value_warning": "10", "enabled": "retraction_enable", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "material_standby_temperature": { @@ -1211,9 +1036,7 @@ "minimum_value": "0", "maximum_value_warning": "260", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "switch_extruder_retraction_amount": { @@ -1227,9 +1050,7 @@ "minimum_value_warning": "0", "maximum_value_warning": "100", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "switch_extruder_retraction_speeds": { @@ -1243,8 +1064,6 @@ "maximum_value_warning": "300", "settable_per_mesh": false, "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "switch_extruder_retraction_speed": @@ -1259,9 +1078,7 @@ "minimum_value": "0.1", "maximum_value_warning": "300", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "switch_extruder_prime_speed": { @@ -1275,9 +1092,7 @@ "minimum_value": "0.1", "maximum_value_warning": "300", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true } } }, @@ -1292,9 +1107,7 @@ "maximum_value_warning": "10", "enabled": "retraction_enable", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true } } }, @@ -1317,9 +1130,6 @@ "maximum_value": "299792458000", "default_value": 60, "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "speed_infill": @@ -1333,10 +1143,7 @@ "maximum_value_warning": "150", "default_value": 60, "value": "speed_print", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "speed_wall": { @@ -1350,9 +1157,6 @@ "default_value": 30, "value": "speed_print / 2", "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "speed_wall_0": @@ -1366,10 +1170,7 @@ "maximum_value_warning": "150", "default_value": 30, "value": "speed_wall", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "speed_wall_x": { @@ -1382,10 +1183,7 @@ "maximum_value_warning": "150", "default_value": 60, "value": "speed_wall * 2", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true } } }, @@ -1400,10 +1198,7 @@ "maximum_value_warning": "150", "default_value": 30, "value": "speed_print / 2", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "speed_support": { @@ -1419,8 +1214,6 @@ "enabled": "support_roof_enable", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "speed_support_infill": @@ -1436,9 +1229,7 @@ "value": "speed_support", "enabled": "support_enable", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "speed_support_roof": { @@ -1453,9 +1244,7 @@ "enabled": "support_roof_enable and support_enable", "value": "speed_support / 1.5", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false } } }, @@ -1471,9 +1260,7 @@ "minimum_value": "0.1", "maximum_value_warning": "150", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true } } }, @@ -1489,9 +1276,7 @@ "maximum_value_warning": "300", "value": "speed_print if magic_spiralize else 120", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "speed_layer_0": { "label": "Initial Layer Speed", @@ -1502,10 +1287,7 @@ "minimum_value": "0.1", "maximum_value": "299792458000", "maximum_value_warning": "300", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "skirt_speed": { "label": "Skirt Speed", @@ -1518,9 +1300,7 @@ "maximum_value_warning": "300", "value": "speed_layer_0", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "speed_slowdown_layers": { @@ -1532,9 +1312,7 @@ "maximum_value": "299792458000", "maximum_value_warning": "300", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false } } }, @@ -1558,10 +1336,7 @@ "noskin": "No Skin" }, "default_value": "all", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "travel_avoid_other_parts": { @@ -1571,9 +1346,7 @@ "default_value": true, "enabled": "retraction_combing != \"off\"", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "travel_avoid_distance": { @@ -1587,9 +1360,7 @@ "maximum_value_warning": "machine_nozzle_tip_outer_diameter * 5", "enabled": "retraction_combing != \"off\" and travel_avoid_other_parts", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true } } }, @@ -1608,9 +1379,7 @@ "type": "bool", "default_value": true, "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "cool_fan_speed": { @@ -1625,8 +1394,6 @@ "enabled": "cool_fan_enabled", "settable_per_mesh": false, "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "cool_fan_speed_min": @@ -1641,9 +1408,7 @@ "default_value": 100, "enabled": "cool_fan_enabled", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "cool_fan_speed_max": { @@ -1657,9 +1422,7 @@ "enabled": "cool_fan_enabled", "value": "cool_fan_speed", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true } } }, @@ -1673,9 +1436,7 @@ "minimum_value": "cool_min_layer_time", "maximum_value_warning": "600", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "cool_fan_full_at_height": { @@ -1689,8 +1450,6 @@ "maximum_value_warning": "10.0", "settable_per_mesh": false, "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "cool_fan_full_layer": @@ -1703,9 +1462,7 @@ "maximum_value_warning": "100", "value": "max(0, int(round((cool_fan_full_at_height - layer_height_0) / layer_height, 0)))", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true } } }, @@ -1719,9 +1476,7 @@ "minimum_value": "0", "maximum_value_warning": "600", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "cool_min_speed": { @@ -1733,9 +1488,7 @@ "minimum_value": "0", "maximum_value_warning": "100", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "cool_lift_head": { @@ -1744,9 +1497,7 @@ "type": "bool", "default_value": false, "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true } } }, @@ -1764,10 +1515,7 @@ "description": "Enable support structures. These structures support parts of the model with severe overhangs.", "type": "bool", "default_value": false, - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "support_type": { @@ -1782,9 +1530,7 @@ "default_value": "everywhere", "enabled": "support_enable", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "support_angle": { @@ -1796,10 +1542,7 @@ "maximum_value": "90", "default_value": 50, "enabled": "support_enable", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "support_pattern": { @@ -1817,9 +1560,7 @@ "default_value": "zigzag", "enabled": "support_enable", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "support_connect_zigzags": { @@ -1829,9 +1570,7 @@ "default_value": true, "enabled": "support_enable and (support_pattern == \"zigzag\")", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "support_infill_rate": { @@ -1845,8 +1584,6 @@ "enabled": "support_enable", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "support_line_distance": { @@ -1859,9 +1596,7 @@ "enabled": "support_enable", "value": "(support_line_width * 100) / support_infill_rate * (2 if support_pattern == \"grid\" else (3 if support_pattern == \"triangles\" else 1))", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false } } }, @@ -1876,9 +1611,6 @@ "default_value": 0.15, "enabled": "support_enable", "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "support_top_distance": @@ -1892,10 +1624,7 @@ "type": "float", "enabled": "support_enable", "value": "support_z_distance", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "support_bottom_distance": { @@ -1908,10 +1637,7 @@ "value": "0.1 if support_type == 'everywhere' else 0", "type": "float", "enabled": "support_enable and support_type == 'everywhere'", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true } } }, @@ -1925,10 +1651,7 @@ "maximum_value_warning": "10", "default_value": 0.7, "enabled": "support_enable", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "support_xy_overrides_z": { "label": "Support Distance Priority", @@ -1940,10 +1663,7 @@ }, "default_value": "z_overrides_xy", "enabled": "support_enable", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "support_xy_distance_overhang": { "label": "Minimum Support X/Y Distance", @@ -1955,10 +1675,7 @@ "default_value": 0.2, "value": "machine_nozzle_size / 2", "enabled": "support_enable and support_xy_overrides_z=='z_overrides_xy'", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "support_bottom_stair_step_height": { @@ -1970,10 +1687,7 @@ "minimum_value": "0", "maximum_value_warning": "1.0", "enabled": "support_enable", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "support_join_distance": { @@ -1985,10 +1699,7 @@ "minimum_value_warning": "0", "maximum_value_warning": "10", "enabled": "support_enable", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "support_offset": { @@ -2000,10 +1711,7 @@ "minimum_value_warning": "-0.5", "maximum_value_warning": "5.0", "enabled": "support_enable", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "support_area_smoothing": { @@ -2015,10 +1723,7 @@ "minimum_value": "0", "maximum_value_warning": "1.0", "enabled": "support_enable", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "support_roof_enable": { @@ -2027,10 +1732,7 @@ "type": "bool", "default_value": false, "enabled": "support_enable", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "support_roof_height": { @@ -2042,10 +1744,7 @@ "minimum_value": "0", "maximum_value_warning": "10", "enabled": "support_roof_enable", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "support_roof_density": { @@ -2059,8 +1758,6 @@ "enabled":"support_roof_enable", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "support_roof_line_distance": @@ -2074,9 +1771,7 @@ "value": "0 if support_roof_density == 0 else (support_roof_line_width * 100) / support_roof_density * (2 if support_roof_pattern == \"grid\" else (3 if support_roof_pattern == \"triangles\" else 1))", "enabled": "support_roof_enable", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false } } }, @@ -2096,9 +1791,7 @@ "default_value": "concentric", "enabled": "support_roof_enable", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "support_use_towers": { @@ -2107,10 +1800,7 @@ "type": "bool", "default_value": true, "enabled": "support_enable", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "support_tower_diameter": { @@ -2122,10 +1812,7 @@ "minimum_value": "0", "maximum_value_warning": "10", "enabled": "support_enable and support_use_towers", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "support_minimal_diameter": { @@ -2138,10 +1825,7 @@ "maximum_value_warning": "10", "maximum_value": "support_tower_diameter", "enabled": "support_enable and support_use_towers", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "support_tower_roof_angle": { @@ -2153,10 +1837,7 @@ "maximum_value": "90", "default_value": 65, "enabled": "support_enable and support_use_towers", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true } } }, @@ -2181,9 +1862,7 @@ }, "default_value": "brim", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "skirt_line_count": { @@ -2195,9 +1874,7 @@ "maximum_value_warning": "10", "enabled": "adhesion_type == \"skirt\"", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "skirt_gap": { @@ -2210,9 +1887,7 @@ "maximum_value_warning": "100", "enabled": "adhesion_type == \"skirt\"", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "skirt_minimal_length": { @@ -2226,9 +1901,7 @@ "maximum_value_warning": "2500", "enabled": "adhesion_type == \"skirt\"", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "brim_width": { @@ -2242,8 +1915,6 @@ "enabled": "adhesion_type == \"brim\"", "settable_per_mesh": false, "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "brim_line_count": @@ -2257,9 +1928,7 @@ "value": "math.ceil(brim_width / skirt_line_width)", "enabled": "adhesion_type == \"brim\"", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true } } }, @@ -2285,9 +1954,7 @@ "maximum_value_warning": "1.0", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "layer_0_z_overlap": { "label": "Initial Layer Z Overlap", @@ -2300,9 +1967,7 @@ "maximum_value_warning": "layer_height", "enabled": "adhesion_type == 'raft'", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "raft_surface_layers": { @@ -2314,9 +1979,7 @@ "maximum_value_warning": "20", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "raft_surface_thickness": { @@ -2329,9 +1992,7 @@ "maximum_value_warning": "2.0", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "raft_surface_line_width": { @@ -2344,9 +2005,7 @@ "maximum_value_warning": "machine_nozzle_size * 2", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "raft_surface_line_spacing": { @@ -2360,9 +2019,7 @@ "enabled": "adhesion_type == \"raft\"", "value": "raft_surface_line_width", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "raft_interface_thickness": { @@ -2375,9 +2032,7 @@ "maximum_value_warning": "5.0", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "raft_interface_line_width": { @@ -2391,9 +2046,7 @@ "maximum_value_warning": "machine_nozzle_size * 2", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "raft_interface_line_spacing": { @@ -2406,9 +2059,7 @@ "maximum_value_warning": "15.0", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "raft_base_thickness": { @@ -2421,9 +2072,7 @@ "maximum_value_warning": "5.0", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "raft_base_line_width": { @@ -2437,9 +2086,7 @@ "maximum_value_warning": "machine_nozzle_size * 2", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "raft_base_line_spacing": { @@ -2452,9 +2099,7 @@ "maximum_value_warning": "100", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "raft_speed": { @@ -2470,8 +2115,6 @@ "value": "speed_print / 60 * 30", "settable_per_mesh": false, "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "raft_surface_speed": @@ -2487,9 +2130,7 @@ "enabled": "adhesion_type == \"raft\"", "value": "raft_speed", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "raft_interface_speed": { @@ -2504,9 +2145,7 @@ "enabled": "adhesion_type == \"raft\"", "value": "0.5 * raft_speed", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "raft_base_speed": { @@ -2521,9 +2160,7 @@ "enabled": "adhesion_type == \"raft\"", "value": "0.5 * raft_speed", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true } } }, @@ -2538,8 +2175,6 @@ "default_value": 0, "settable_per_mesh": false, "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true, "enabled": "adhesion_type == \"raft\"", "children": { @@ -2555,9 +2190,7 @@ "value": "raft_fan_speed", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "raft_interface_fan_speed": { @@ -2571,9 +2204,7 @@ "value": "raft_fan_speed", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "raft_base_fan_speed": { @@ -2587,9 +2218,7 @@ "value": "raft_fan_speed", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true } } } @@ -2609,10 +2238,7 @@ "description": "Ignore the internal geometry arising from overlapping volumes and print the volumes as one. This may cause internal cavities to disappear.", "type": "bool", "default_value": true, - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "meshfix_union_all_remove_holes": { @@ -2620,10 +2246,7 @@ "description": "Remove the holes in each layer and keep only the outside shape. This will ignore any invisible internal geometry. However, it also ignores layer holes which can be viewed from above or below.", "type": "bool", "default_value": false, - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "meshfix_extensive_stitching": { @@ -2631,10 +2254,7 @@ "description": "Extensive stitching tries to stitch up open holes in the mesh by closing the hole with touching polygons. This option can introduce a lot of processing time.", "type": "bool", "default_value": false, - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "meshfix_keep_open_polygons": { @@ -2642,10 +2262,7 @@ "description": "Normally Cura tries to stitch up small holes in the mesh and remove parts of a layer with big holes. Enabling this option keeps those parts which cannot be stitched. This option should be used as a last resort option when everything else fails to produce proper GCode.", "type": "bool", "default_value": false, - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true } } }, @@ -2670,8 +2287,7 @@ "default_value": "all_at_once", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "magic_mesh_surface_mode": { @@ -2685,10 +2301,7 @@ "both": "Both" }, "default_value": "normal", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "magic_spiralize": { @@ -2696,10 +2309,7 @@ "description": "Spiralize smooths out the Z move of the outer edge. This will create a steady Z increase over the whole print. This feature turns a solid object into a single walled print with a solid bottom. This feature used to be called Joris in older versions.", "type": "bool", "default_value": false, - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true } } }, @@ -2720,9 +2330,7 @@ "minimum_value": "0", "maximum_value": "machine_extruder_count - 1", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "support_extruder_nr": { @@ -2734,8 +2342,6 @@ "maximum_value": "machine_extruder_count - 1", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "support_infill_extruder_nr": { @@ -2747,9 +2353,7 @@ "minimum_value": "0", "maximum_value": "machine_extruder_count - 1", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "support_extruder_nr_layer_0": { @@ -2761,9 +2365,7 @@ "minimum_value": "0", "maximum_value": "machine_extruder_count - 1", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "support_roof_extruder_nr": { @@ -2775,9 +2377,7 @@ "minimum_value": "0", "maximum_value": "machine_extruder_count - 1", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false } } }, @@ -2788,9 +2388,7 @@ "type": "bool", "default_value": false, "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "prime_tower_size": { @@ -2804,9 +2402,7 @@ "minimum_value": "0", "maximum_value_warning": "20", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "prime_tower_position_x": { @@ -2819,9 +2415,7 @@ "minimum_value_warning": "-1000", "maximum_value_warning": "1000", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "prime_tower_position_y": { @@ -2834,9 +2428,7 @@ "minimum_value_warning": "-1000", "maximum_value_warning": "1000", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "prime_tower_flow": { @@ -2850,9 +2442,7 @@ "minimum_value_warning": "50", "maximum_value_warning": "150", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "prime_tower_wipe_enabled": { @@ -2862,9 +2452,7 @@ "enabled": "prime_tower_enable", "default_value": false, "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "multiple_mesh_overlap": { @@ -2875,10 +2463,7 @@ "default_value": 0.15, "minimum_value": "0", "maximum_value_warning": "1.0", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "ooze_shield_enabled": { @@ -2887,9 +2472,7 @@ "type": "bool", "default_value": false, "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "ooze_shield_angle": { @@ -2902,9 +2485,7 @@ "minimum_value": "0", "maximum_value": "90", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "ooze_shield_dist": { @@ -2917,9 +2498,7 @@ "minimum_value": "0", "maximum_value_warning": "30", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false } } }, @@ -2938,9 +2517,7 @@ "type": "bool", "default_value": false, "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "draft_shield_dist": { @@ -2953,9 +2530,7 @@ "default_value": 10, "enabled": "draft_shield_enabled", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "draft_shield_height_limitation": { @@ -2970,9 +2545,7 @@ "default_value": "full", "enabled": "draft_shield_enabled", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "draft_shield_height": { @@ -2986,9 +2559,7 @@ "value": "9999 if draft_shield_height_limitation == 'full' and draft_shield_enabled else 0.0", "enabled": "draft_shield_height_limitation == \"limited\"", "settable_per_mesh": false, - "settable_per_extruder": false, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": false }, "conical_overhang_enabled": { "label": "Make Overhang Printable", @@ -3013,9 +2584,7 @@ "type": "bool", "default_value": false, "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "coasting_volume": { @@ -3028,9 +2597,7 @@ "maximum_value_warning": "2.0", "enabled": "coasting_enable", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "coasting_min_volume": { @@ -3043,9 +2610,7 @@ "maximum_value_warning": "10.0", "enabled": "coasting_enable", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "coasting_speed": { @@ -3058,9 +2623,7 @@ "maximum_value_warning": "100", "enabled": "coasting_enable", "settable_per_mesh": false, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_extruder": true }, "skin_outline_count": { @@ -3070,10 +2633,7 @@ "minimum_value": "0", "maximum_value_warning": "10", "type": "int", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "skin_alternate_rotation": { @@ -3082,10 +2642,7 @@ "type": "bool", "default_value": false, "enabled": "top_bottom_pattern != \"concentric\"", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "support_conical_enabled": { @@ -3094,10 +2651,7 @@ "type": "bool", "default_value": false, "enabled": "support_enable", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "support_conical_angle": { @@ -3111,10 +2665,7 @@ "maximum_value": "90", "default_value": 30, "enabled": "support_conical_enabled and support_enable", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "support_conical_min_width": { @@ -3127,10 +2678,7 @@ "maximum_value_warning": "100.0", "type": "float", "enabled": "support_conical_enabled and support_enable", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "magic_fuzzy_skin_enabled": { @@ -3138,10 +2686,7 @@ "description": "Randomly jitter while printing the outer wall, so that the surface has a rough and fuzzy look.", "type": "bool", "default_value": false, - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "magic_fuzzy_skin_thickness": { @@ -3153,10 +2698,7 @@ "minimum_value": "0.001", "maximum_value_warning": "wall_line_width_0", "enabled": "magic_fuzzy_skin_enabled", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true }, "magic_fuzzy_skin_point_density": { @@ -3171,9 +2713,6 @@ "maximum_value": "2 / magic_fuzzy_skin_thickness", "enabled": "magic_fuzzy_skin_enabled", "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true, "children": { "magic_fuzzy_skin_point_dist": @@ -3188,10 +2727,7 @@ "maximum_value_warning": "10", "value": "10000 if magic_fuzzy_skin_point_density == 0 else 1 / magic_fuzzy_skin_point_density", "enabled": "magic_fuzzy_skin_enabled", - "settable_per_mesh": true, - "settable_per_extruder": true, - "settable_per_meshgroup": true, - "settable_globally": true + "settable_per_mesh": true } } }, @@ -3203,8 +2739,7 @@ "default_value": false, "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "wireframe_height": { @@ -3218,8 +2753,7 @@ "enabled": "wireframe_enabled", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "wireframe_roof_inset": { @@ -3235,8 +2769,7 @@ "value": "wireframe_height", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "wireframe_printspeed": { @@ -3252,7 +2785,6 @@ "settable_per_mesh": false, "settable_per_extruder": false, "settable_per_meshgroup": false, - "settable_globally": true, "children": { "wireframe_printspeed_bottom": @@ -3269,8 +2801,7 @@ "value": "wireframe_printspeed", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "wireframe_printspeed_up": { @@ -3286,8 +2817,7 @@ "value": "wireframe_printspeed", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "wireframe_printspeed_down": { @@ -3303,8 +2833,7 @@ "value": "wireframe_printspeed", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "wireframe_printspeed_flat": { @@ -3320,8 +2849,7 @@ "enabled": "wireframe_enabled", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false } } }, @@ -3338,7 +2866,6 @@ "settable_per_mesh": false, "settable_per_extruder": false, "settable_per_meshgroup": false, - "settable_globally": true, "children": { "wireframe_flow_connection": @@ -3354,8 +2881,7 @@ "value": "wireframe_flow", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "wireframe_flow_flat": { @@ -3370,8 +2896,7 @@ "value": "wireframe_flow", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false } } }, @@ -3387,8 +2912,7 @@ "enabled": "wireframe_enabled", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "wireframe_bottom_delay": { @@ -3402,8 +2926,7 @@ "enabled": "wireframe_enabled", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "wireframe_flat_delay": { @@ -3417,8 +2940,7 @@ "enabled": "wireframe_enabled", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "wireframe_up_half_speed": { @@ -3432,8 +2954,7 @@ "enabled": "wireframe_enabled", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "wireframe_top_jump": { @@ -3447,8 +2968,7 @@ "enabled": "wireframe_enabled", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "wireframe_fall_down": { @@ -3462,8 +2982,7 @@ "enabled": "wireframe_enabled", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "wireframe_drag_along": { @@ -3477,8 +2996,7 @@ "enabled": "wireframe_enabled", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "wireframe_strategy": { @@ -3495,8 +3013,7 @@ "enabled": "wireframe_enabled", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "wireframe_straight_before_down": { @@ -3510,8 +3027,7 @@ "enabled": "wireframe_enabled", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "wireframe_roof_fall_down": { @@ -3525,8 +3041,7 @@ "enabled": "wireframe_enabled", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "wireframe_roof_drag_along": { @@ -3540,8 +3055,7 @@ "enabled": "wireframe_enabled", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "wireframe_roof_outer_delay": { @@ -3555,8 +3069,7 @@ "enabled": "wireframe_enabled", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false }, "wireframe_nozzle_clearance": { @@ -3570,8 +3083,7 @@ "enabled": "wireframe_enabled", "settable_per_mesh": false, "settable_per_extruder": false, - "settable_per_meshgroup": false, - "settable_globally": true + "settable_per_meshgroup": false } } } From 2b3efe43293e9aab001145c698086887d18f9d22 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Wed, 8 Jun 2016 12:23:54 +0200 Subject: [PATCH 528/705] JSON fix: type boolean should be bool (CURA-1443) --- resources/definitions/fdmprinter.def.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 716f7aa55f..6912c88904 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1188,7 +1188,7 @@ "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": "boolean", + "type": "bool", "default_value": false, "global_only": "True" }, @@ -1354,7 +1354,7 @@ "jerk_enabled": { "label": "Enable Jerk Control", "description": "Enables adjusting the jerk of print head when the X ar Y axis halts or starts to move. Increasing the jerk can reduce printing time at the cost of print quality.", - "type": "boolean", + "type": "bool", "default_value": false, "global_only": "True" }, From 6cca612d7d3e915fce1f720daf461f4436619caf Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Wed, 8 Jun 2016 12:30:29 +0200 Subject: [PATCH 529/705] JSON rename: Raft Interface ==> Raft Middle ; Raft Surface ==> Raft Top (CURA-1443) --- 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 6912c88904..37be736d34 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -2264,8 +2264,8 @@ { "raft_surface_speed": { - "label": "Raft Surface Print Speed", - "description": "The speed at which the surface raft layers are printed. These should be printed a bit slower, so that the nozzle can slowly smooth out adjacent surface lines.", + "label": "Raft Top Print Speed", + "description": "The speed at which the top raft layers are printed. These should be printed a bit slower, so that the nozzle can slowly smooth out adjacent surface lines.", "unit": "mm/s", "type": "float", "default_value": 30, @@ -2278,8 +2278,8 @@ }, "raft_interface_speed": { - "label": "Raft Interface Print Speed", - "description": "The speed at which the interface raft layer is printed. This should be printed quite slowly, as the volume of material coming out of the nozzle is quite high.", + "label": "Raft Middle Print Speed", + "description": "The speed at which the middle raft layer is printed. This should be printed quite slowly, as the volume of material coming out of the nozzle is quite high.", "unit": "mm/s", "type": "float", "default_value": 15, @@ -2323,8 +2323,8 @@ "enabled": "adhesion_type == \"raft\" and acceleration_enabled", "children": { "raft_surface_acceleration": { - "label": "Raft Surface Print Acceleration", - "description": "The acceleration with which the surface raft layers are printed.", + "label": "Raft Top Print Acceleration", + "description": "The acceleration with which the top raft layers are printed.", "unit": "mm/s²", "type": "float", "default_value": 3000, @@ -2335,8 +2335,8 @@ "enabled": "adhesion_type == \"raft\" and acceleration_enabled" }, "raft_interface_acceleration": { - "label": "Raft Interface Print Acceleration", - "description": "The acceleration with which the interface raft layer is printed.", + "label": "Raft Middle Print Acceleration", + "description": "The acceleration with which the middle raft layer is printed.", "unit": "mm/s²", "type": "float", "default_value": 3000, @@ -2377,8 +2377,8 @@ "enabled": "adhesion_type == \"raft\" and jerk_enabled", "children": { "raft_surface_jerk": { - "label": "Raft Surface Print Jerk", - "description": "The jerk with which the surface raft layers are printed.", + "label": "Raft Top Print Jerk", + "description": "The jerk with which the top raft layers are printed.", "unit": "mm/s³", "type": "float", "default_value": 20, @@ -2389,8 +2389,8 @@ "enabled": "adhesion_type == \"raft\" and jerk_enabled" }, "raft_interface_jerk": { - "label": "Raft Interface Print Jerk", - "description": "The jerk with which the interface raft layer is printed.", + "label": "Raft Middle Print Jerk", + "description": "The jerk with which the middle raft layer is printed.", "unit": "mm/s³", "type": "float", "default_value": 20, @@ -2430,8 +2430,8 @@ { "raft_surface_fan_speed": { - "label": "Raft Surface Fan Speed", - "description": "The fan speed for the surface raft layers.", + "label": "Raft Top Fan Speed", + "description": "The fan speed for the top raft layers.", "unit": "%", "type": "float", "minimum_value": "0", @@ -2443,8 +2443,8 @@ }, "raft_interface_fan_speed": { - "label": "Raft Interface Fan Speed", - "description": "The fan speed for the interface raft layer.", + "label": "Raft Middle Fan Speed", + "description": "The fan speed for the middle raft layer.", "unit": "%", "type": "float", "minimum_value": "0", From 0dcf13a243e284b46e347b855f502287433ee47f Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Wed, 8 Jun 2016 13:26:24 +0200 Subject: [PATCH 530/705] JSON fix typo: ar ==> or (CURA-1443) --- 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 37be736d34..1c5f8ed97a 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1353,7 +1353,7 @@ "jerk_enabled": { "label": "Enable Jerk Control", - "description": "Enables adjusting the jerk of print head when the X ar Y axis halts or starts to move. Increasing the jerk can reduce printing time at the cost of print quality.", + "description": "Enables adjusting the jerk of print head when the X or Y axis halts or starts to move. Increasing the jerk can reduce printing time at the cost of print quality.", "type": "bool", "default_value": false, "global_only": "True" From 472477eee29b72503db734238ca794bb88f95464 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Wed, 8 Jun 2016 13:27:06 +0200 Subject: [PATCH 531/705] JSON fix type: effect ==> affect (CURA-1443) --- 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 1c5f8ed97a..2ed0d1632b 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1043,7 +1043,7 @@ "speed_wall_0": { "label": "Outer Wall Speed", - "description": "The speed at which the outermost walls are printed. Printing the outer wall at a lower speed improves the final skin quality. However, having a large difference between the inner wall speed and the outer wall speed will effect quality in a negative way.", + "description": "The speed at which the outermost walls are printed. Printing the outer wall at a lower speed improves the final skin quality. However, having a large difference between the inner wall speed and the outer wall speed will affect quality in a negative way.", "unit": "mm/s", "type": "float", "minimum_value": "0.1", From 61b674b74e0385ea26de7e38f33eb40bdbbcf0b9 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Wed, 8 Jun 2016 13:28:11 +0200 Subject: [PATCH 532/705] JSON fix: removed sentences from jerk settings which were only applicable for speed. (CURA-1443) --- resources/definitions/fdmprinter.def.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 2ed0d1632b..89aa40192c 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1393,7 +1393,7 @@ "children": { "jerk_wall_0": { "label": "Outer Wall Jerk", - "description": "The jerk with which the outermost walls are printed. Printing the outer wall at a lower jerk improves the final skin quality. However, having a large difference between the inner wall jerk and the outer wall jerk will effect quality in a negative way.", + "description": "The jerk with which the outermost walls are printed.", "unit": "mm/s³", "type": "float", "minimum_value": "0.1", @@ -1404,7 +1404,7 @@ }, "jerk_wall_x": { "label": "Inner Wall Jerk", - "description": "The jerk with which all inner walls are printed Printing the inner wall faster than the outer wall will reduce printing time. It works well to set this in between the outer wall jerk and the infill jerk.", + "description": "The jerk with which all inner walls are printed.", "unit": "mm/s³", "type": "float", "minimum_value": "0.1", @@ -1428,7 +1428,7 @@ }, "jerk_support": { "label": "Support Jerk", - "description": "The jerk with which the support structure is printed. Printing support at higher jerks can greatly reduce printing time. The surface quality of the support structure is not important since it is removed after printing.", + "description": "The jerk with which the support structure is printed.", "unit": "mm/s³", "type": "float", "minimum_value": "0.1", @@ -1439,7 +1439,7 @@ "children": { "jerk_support_infill": { "label": "Support Infill Jerk", - "description": "The jerk with which the infill of support is printed. Printing the infill at lower jerks improves stability.", + "description": "The jerk with which the infill of support is printed.", "unit": "mm/s³", "type": "float", "default_value": 20, @@ -1451,7 +1451,7 @@ }, "jerk_support_roof": { "label": "Support Roof Jerk", - "description": "The jerk with which the roofs of support are printed. Printing the support roof at lower jerks can improve overhang quality.", + "description": "The jerk with which the roofs of support are printed.", "unit": "mm/s³", "type": "float", "default_value": 20, @@ -1493,7 +1493,7 @@ }, "jerk_layer_0": { "label": "Initial Layer Jerk", - "description": "The print jerk for the initial layer. A lower value is advised to improve adhesion to the build plate.", + "description": "The print jerk for the initial layer.", "unit": "mm/s³", "type": "float", "default_value": 20, @@ -1504,7 +1504,7 @@ }, "jerk_skirt": { "label": "Skirt Jerk", - "description": "The jerk with which the skirt and brim are printed. Normally this is done at the initial layer jerk, but sometimes you might want to print the skirt with a different jerk.", + "description": "The jerk with which the skirt and brim are printed.", "unit": "mm/s³", "type": "float", "default_value": 20, From 3e10335e037dfc565e9260ea461c5396be3dab24 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Wed, 8 Jun 2016 13:28:37 +0200 Subject: [PATCH 533/705] JSON fix typo: missing dot --- 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 89aa40192c..6828b8dd89 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1055,7 +1055,7 @@ "speed_wall_x": { "label": "Inner Wall Speed", - "description": "The speed at which all inner walls are printed Printing the inner wall faster than the outer wall will reduce printing time. It works well to set this in between the outer wall speed and the infill speed.", + "description": "The speed at which all inner walls are printed. Printing the inner wall faster than the outer wall will reduce printing time. It works well to set this in between the outer wall speed and the infill speed.", "unit": "mm/s", "type": "float", "minimum_value": "0.1", From b53926b9de53abc85b2bd8a6345a34563c1acc9f Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 8 Jun 2016 13:29:36 +0200 Subject: [PATCH 534/705] Exclude machine_settings from the settings visible in the sidebar Contrivbutes to CURA-1645 --- resources/qml/Settings/SettingView.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 6261496c84..a6bb60f865 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -29,7 +29,8 @@ ScrollView model: UM.SettingDefinitionsModel { id: definitionsModel; containerId: Cura.MachineManager.activeDefinitionId - visibilityHandler: UM.SettingPreferenceVisibilityHandler {} + exclude: ["machine_settings"] + visibilityHandler: UM.SettingPreferenceVisibilityHandler { } } delegate: Loader From 2cedc69ed19c309f9c348a6ca597ba5b1761d22b Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 8 Jun 2016 13:46:30 +0200 Subject: [PATCH 535/705] Remove all special floating point handling code from SettingTextField Since we now always send setting values as string and the conversion from float to string already does the rounding, there is no need to also do it here. Contributes to CURA-1278 Contributes to CURA-389 --- resources/qml/Settings/SettingTextField.qml | 36 +-------------------- 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/resources/qml/Settings/SettingTextField.qml b/resources/qml/Settings/SettingTextField.qml index 2a1fb96330..bf6fc34c93 100644 --- a/resources/qml/Settings/SettingTextField.qml +++ b/resources/qml/Settings/SettingTextField.qml @@ -90,21 +90,11 @@ SettingItem Keys.onReleased: { -// text = text.replace(",", ".") // User convenience. We use dots for decimal values -// if(parseFloat(text) != base.parentValue) -// { -// base.valueChanged(parseFloat(text)); -// } - propertyProvider.setPropertyValue("value", text) } onEditingFinished: { -// if(parseFloat(text) != base.parentValue) -// { -// base.valueChanged(parseFloat(text)); -// } propertyProvider.setPropertyValue("value", text) } @@ -121,33 +111,9 @@ SettingItem { target: input property: "text" - value: control.format(propertyProvider.properties.value) + value: propertyProvider.properties.value when: !input.activeFocus } } - - //Rounds a floating point number to 4 decimals. This prevents floating - //point rounding errors. - // - //input: The number to round. - //decimals: The number of decimals (digits after the radix) to round to. - //return: The rounded number. - function roundFloat(input, decimals) - { - //First convert to fixed-point notation to round the number to 4 decimals and not introduce new floating point errors. - //Then convert to a string (is implicit). The fixed-point notation will be something like "3.200". - //Then remove any trailing zeroes and the radix. - return input.toFixed(decimals).replace(/\.?0*$/, ""); //Match on periods, if any ( \.? ), followed by any number of zeros ( 0* ), then the end of string ( $ ). - } - - //Formats a value for display in the text field. - // - //This correctly handles formatting of float values. - // - //input: The string value to format. - //return: The formatted string. - function format(inputValue) { - return parseFloat(inputValue) ? roundFloat(parseFloat(inputValue), 4) : inputValue //If it's a float, round to four decimals. - } } } From e53a961ba72e5090467689d9e95722f7d393d24d Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Wed, 8 Jun 2016 13:49:27 +0200 Subject: [PATCH 536/705] JSON fix: topbottom thickness had max value for no apparent reason (CURA-1352) --- resources/definitions/fdmprinter.def.json | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index ec27abd9f5..2443e08b47 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -461,7 +461,6 @@ "unit": "mm", "default_value": 0.8, "minimum_value": "0", - "maximum_value": "5", "minimum_value_warning": "0.6", "type": "float", "children": From 163642f9ada9585f8582826b89c6f77c171b1a83 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 8 Jun 2016 14:05:16 +0200 Subject: [PATCH 537/705] Also remove the "current_settings" container when removing a machine Contributes to CURA-1628 --- cura/MachineManagerModel.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index e7034412f5..2738bfd764 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -427,7 +427,13 @@ class MachineManagerModel(QObject): def removeMachine(self, machine_id): # If the machine that is being removed is the currently active machine, set another machine as the active machine activate_new_machine = (self._global_container_stack and self._global_container_stack.getId() == machine_id) + + current_settings_id = machine_id + "_current_settings" + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = current_settings_id) + for container in containers: + UM.Settings.ContainerRegistry.getInstance().removeContainer(container.getId()) UM.Settings.ContainerRegistry.getInstance().removeContainer(machine_id) + if activate_new_machine: stacks = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(type = "machine") if stacks: From f6ece126c31f62e0984f6a5b31f35e827c3f2dc8 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 8 Jun 2016 12:22:45 +0200 Subject: [PATCH 538/705] Don't re-create user profile if one is loaded from files The user profiles are also saved because they are added to the container registry. So if one exists for this extruder, don't create a new blank name, but use the pre-loaded one which contained the user settings the user had before he closed down Cura previously. Contributes to issues CURA-340 and CURA-1278. --- cura/ExtruderManager.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 8219066eca..a5960be552 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -147,12 +147,15 @@ class ExtruderManager(QObject): self._container_stack.addContainer(self._quality) """ - #Add an empty user profile. - user_profile = UM.Settings.InstanceContainer(extruder_train_id + "_current_settings") - user_profile.addMetaDataEntry("type", "user") - user_profile.setDefinition(machine_definition) + user_profile = container_registry.findInstanceContainers(id = extruder_train_id + "_current_settings") + if user_profile: #There was already a user profile, loaded from settings. + user_profile = user_profile[0] + else: + user_profile = UM.Settings.InstanceContainer(extruder_train_id + "_current_settings") #Add an empty user profile. + user_profile.addMetaDataEntry("type", "user") + user_profile.setDefinition(machine_definition) + container_registry.addContainer(user_profile) container_stack.addContainer(user_profile) - container_registry.addContainer(user_profile) container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack()) From 32f90ad8676d69e536f5775fa912d35e5ec44586 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 8 Jun 2016 13:19:46 +0200 Subject: [PATCH 539/705] Re-add per-extruder nozzles, materials, qualities Slightly more efficient and correct implementation.Contributes to issue CURA-340. --- cura/ExtruderManager.py | 77 +++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index a5960be552..e03bcfd3b3 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -93,7 +93,9 @@ class ExtruderManager(QObject): self.extrudersChanged.emit(machine_definition) def createExtruderTrain(self, extruder_definition, machine_definition, extruder_train_id, position): + #Cache some things. container_registry = UM.Settings.ContainerRegistry.getInstance() + machine_id = machine_definition.getId() #Create a container stack for this extruder. container_stack = UM.Settings.ContainerStack(extruder_train_id) @@ -102,50 +104,59 @@ class ExtruderManager(QObject): container_stack.addMetaDataEntry("position", position) container_stack.addContainer(extruder_definition) - """ - Yes, I'm committing this code which needs to be transformed to work later. #Find the nozzle to use for this extruder. nozzle = container_registry.getEmptyInstanceContainer() - if definition.getMetaDataEntry("has_nozzles", default = "False") == "True": - if len(self._nozzles) >= 1: #First add any extruder. Later, overwrite with preference if the preference is valid. - self._nozzle = self._nozzles[0] - preferred_nozzle_id = definition.getMetaDataEntry("preferred_nozzle") + if machine_definition.getMetaDataEntry("has_nozzles", default = "False") == "True": + #First add any nozzle. Later, overwrite with preference if the preference is valid. + nozzles = container_registry.findInstanceContainers(machine = machine_id, type = "nozzle") + if len(nozzles) >= 1: + nozzle = nozzles[0] + preferred_nozzle_id = machine_definition.getMetaDataEntry("preferred_nozzle") if preferred_nozzle_id: - for nozzle in self._nozzles: - if nozzle.getId() == preferred_nozzle_id: - self._nozzle = nozzle - break - self._container_stack.addContainer(self._nozzle) + preferred_nozzles = container_registry.findInstanceContainers(id = preferred_nozzle_id, type = "nozzle") + if len(preferred_nozzles) >= 1: + nozzle = preferred_nozzles[0] + else: + UM.Logger.log("w", "The preferred nozzle \"%s\" of machine %s doesn't exist or is not a nozzle profile.", preferred_nozzle_id, machine_id) + #And leave it at the default nozzle. + container_stack.addContainer(nozzle) #Find a material to use for this nozzle. - self._material = container_registry.getEmptyInstanceContainer() - if self._definition.getMetaDataEntry("has_materials", default = "False") == "True": - if self._definition.getMetaDataEntry("has_nozzle_materials", default = "False") == "True": - all_materials = container_registry.findInstanceContainers(type = "material", nozzle = self._nozzle.getId()) + material = container_registry.getEmptyInstanceContainer() + if machine_definition.getMetaDataEntry("has_materials", default = "False") == "True": + #First add any material. Later, overwrite with preference if the preference is valid. + if machine_definition.getMetaDataEntry("has_nozzle_materials", default = "False") == "True": + materials = container_registry.findInstanceContainers(type = "material", machine = machine_id, nozzle = nozzle.getId()) else: - all_materials = container_registry.findInstanceContainers(type = "material") - if len(all_materials) >= 1: - self._material = all_materials[0] - preferred_material_id = self._definition.getMetaDataEntry("preferred_material") + materials = container_registry.findInstanceContainers(type = "material", machine = machine_id) + if len(materials) >= 1: + material = materials[0] + preferred_material_id = machine_definition.getMetaDataEntry("preferred_material") if preferred_material_id: - preferred_material = container_registry.findInstanceContainers(type = "material", id = preferred_material_id.lower()) - if len(preferred_material) >= 1: - self._material = preferred_material[0] - self._container_stack.addContainer(self._material) + preferred_materials = container_registry.findInstanceContainers(id = preferred_material_id, type = "material") + if len(preferred_materials) >= 1: + material = preferred_materials[0] + else: + UM.Logger.log("w", "The preferred material \"%s\" of machine %s doesn't exist or is not a material profile.", preferred_material_id, machine_id) + #And leave it at the default material. + container_stack.addContainer(material) #Find a quality to use for this extruder. - self._quality = container_registry.getEmptyInstanceContainer() - if self._definition.getMetaDataEntry("has_machine_quality"): - all_qualities = container_registry.findInstanceContainers(type = "quality") - if len(all_qualities) >= 1: - self._quality = all_qualities[0] - preferred_quality_id = self._definition.getMetaDataEntry("preferred_quality") + quality = container_registry.getEmptyInstanceContainer() + if machine_definition.getMetaDataEntry("has_machine_quality"): + #First add any quality. Later, overwrite with preference if the preference is valid. + qualities = container_registry.findInstanceContainers(type = "quality") + if len(qualities) >= 1: + quality = qualities[0] + preferred_quality_id = machine_definition.getMetaDataEntry("preferred_quality") if preferred_quality_id: - preferred_quality = container_registry.findInstanceContainers(type = "quality", id = preferred_quality_id.lower()) + preferred_quality = container_registry.findInstanceContainers(id = preferred_quality_id.lower(), type = "quality") if len(preferred_quality) >= 1: - self._quality = preferred_quality[0] - self._container_stack.addContainer(self._quality) - """ + quality = preferred_quality[0] + else: + UM.Logger.log("w", "The preferred quality \"%s\" of machine %s doesn't exist or is not a quality profile.", preferred_quality_id, machine_id) + #And leave it at the default quality. + container_stack.addContainer(quality) user_profile = container_registry.findInstanceContainers(id = extruder_train_id + "_current_settings") if user_profile: #There was already a user profile, loaded from settings. From fffe9b3a943afa39621f803c21273f5c6c57b101 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 8 Jun 2016 13:56:42 +0200 Subject: [PATCH 540/705] Better naming for extruder slot The name of the extruder stack is now the same as the name for the extruder definition. The IDs are different though! Contributes to issues CURA-1278 and CURA-340. --- cura/ExtruderManager.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index e03bcfd3b3..b67a7f1542 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -82,8 +82,7 @@ class ExtruderManager(QObject): if not position: UM.Logger.log("w", "Extruder definition %s specifies no position metadata entry.", extruder_definition.getId()) if not container_registry.findContainerStacks(machine = machine_id, position = position): #Doesn't exist yet. - name = container_registry.uniqueName(extruder_definition.getId()) #Make a name based on the ID of the definition. - self.createExtruderTrain(extruder_definition, machine_definition, name, position) + self.createExtruderTrain(extruder_definition, machine_definition, position) #Gets the extruder trains that we just created as well as any that still existed. extruder_trains = container_registry.findContainerStacks(type = "extruder_train", machine = machine_definition.getId()) @@ -92,13 +91,15 @@ class ExtruderManager(QObject): if extruder_trains: self.extrudersChanged.emit(machine_definition) - def createExtruderTrain(self, extruder_definition, machine_definition, extruder_train_id, position): + def createExtruderTrain(self, extruder_definition, machine_definition, position): #Cache some things. container_registry = UM.Settings.ContainerRegistry.getInstance() machine_id = machine_definition.getId() #Create a container stack for this extruder. - container_stack = UM.Settings.ContainerStack(extruder_train_id) + extruder_stack_id = container_registry.uniqueName(extruder_definition.getId()) + container_stack = UM.Settings.ContainerStack(extruder_stack_id) + container_stack.setName(extruder_definition.getName()) #Take over the display name to display the stack with. container_stack.addMetaDataEntry("type", "extruder_train") container_stack.addMetaDataEntry("machine", machine_definition.getId()) container_stack.addMetaDataEntry("position", position) @@ -158,11 +159,11 @@ class ExtruderManager(QObject): #And leave it at the default quality. container_stack.addContainer(quality) - user_profile = container_registry.findInstanceContainers(id = extruder_train_id + "_current_settings") + user_profile = container_registry.findInstanceContainers(id = extruder_stack_id + "_current_settings") if user_profile: #There was already a user profile, loaded from settings. user_profile = user_profile[0] else: - user_profile = UM.Settings.InstanceContainer(extruder_train_id + "_current_settings") #Add an empty user profile. + user_profile = UM.Settings.InstanceContainer(extruder_stack_id + "_current_settings") #Add an empty user profile. user_profile.addMetaDataEntry("type", "user") user_profile.setDefinition(machine_definition) container_registry.addContainer(user_profile) From 0a34577fdb898cc24e4cea1305bc53b24669c8f4 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 8 Jun 2016 13:59:26 +0200 Subject: [PATCH 541/705] Add documentation for createExtruderTrain Contributes to issues CURA-340 and CURA-1278. --- cura/ExtruderManager.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index b67a7f1542..b4d05d7e6c 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -91,6 +91,20 @@ class ExtruderManager(QObject): if extruder_trains: self.extrudersChanged.emit(machine_definition) + ## Creates a container stack for an extruder train. + # + # The container stack has an extruder definition at the bottom, which is + # linked to a machine definition. Then it has a nozzle profile, a material + # profile, a quality profile and a user profile, in that order. + # + # The resulting container stack is added to the registry. + # + # \param extruder_definition The extruder to create the extruder train + # for. + # \param machine_definition The machine that the extruder train belongs + # to. + # \param position The position of this extruder train in the extruder + # slots of the machine. def createExtruderTrain(self, extruder_definition, machine_definition, position): #Cache some things. container_registry = UM.Settings.ContainerRegistry.getInstance() From 59c8a4e66d5c0b8f5a2cc1b5fbb2a3e9af9c4629 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 8 Jun 2016 14:16:13 +0200 Subject: [PATCH 542/705] Fix validation of extruder-type settings Based on how ints are validated, since the data is the same. Contributes to issues CURA-1278 and CURA-340. --- cura/CuraApplication.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 37ba6cf7ad..8acd3eda2a 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -47,6 +47,7 @@ from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty, QEvent, Q_ENU from PyQt5.QtGui import QColor, QIcon from PyQt5.QtQml import qmlRegisterUncreatableType, qmlRegisterSingletonType, qmlRegisterType +import ast #For literal eval of extruder setting types. import platform import sys import os.path @@ -92,7 +93,7 @@ class CuraApplication(QtApplication): # Need to do this before ContainerRegistry tries to load the machines SettingDefinition.addSupportedProperty("global_only", DefinitionPropertyType.Function, default = False) - SettingDefinition.addSettingType("extruder", int, str, UM.Settings.Validator) + SettingDefinition.addSettingType("extruder", str, ast.literal_eval, UM.Settings.Validator) super().__init__(name = "cura", version = CuraVersion, buildtype = CuraBuildType) From 061cbfe46bc4c9f8e32290484402a2b62a51b419 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Wed, 8 Jun 2016 14:20:06 +0200 Subject: [PATCH 543/705] JSON fix: make base of raft with thicker lines than nozzle size (CURA-695) --- resources/definitions/fdmprinter.def.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index da99c36d51..29db032aa1 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1860,7 +1860,7 @@ "unit": "mm", "type": "float", "default_value": 1, - "value": "line_width", + "value": "line_width * 2", "minimum_value": "0.0001", "maximum_value_warning": "machine_nozzle_size * 2", "enabled": "adhesion_type == \"raft\"", @@ -1898,7 +1898,7 @@ "type": "float", "default_value": 1, "minimum_value": "0.0001", - "value": "line_width", + "value": "line_width * 2", "maximum_value_warning": "machine_nozzle_size * 2", "enabled": "adhesion_type == \"raft\"", "global_only": "True" From 3881ed8a61f40249b96c5e6f2103b73f588e95fb Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 8 Jun 2016 14:58:05 +0200 Subject: [PATCH 544/705] Fixed behaviour of inheritance button CURA-1278 --- resources/qml/Settings/SettingItem.qml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index 4fa615134b..2f1a74dba6 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -24,7 +24,8 @@ Item { // Create properties to put property provider stuff in (bindings break in qt 5.5.1 otherwise) property var state: propertyProvider.properties.state - property var stackLevel: propertyProvider.stackLevels[0] + property var stackLevels: propertyProvider.stackLevels + property var stackLevel: stackLevels[0] signal contextMenuRequested() signal showTooltip(string text); @@ -159,7 +160,7 @@ Item { id: inheritButton; //visible: has_profile_value && base.has_inherit_function && base.is_enabled - visible: base.state == "InstanceState.User" && base.stackLevel > 0 && base.showInheritButton + visible: base.state == "InstanceState.User" && base.showInheritButton height: parent.height; width: height; @@ -175,6 +176,7 @@ Item { // needed for the reset button (which deletes the top value) to correctly go back to profile // defaults. propertyProvider.setPropertyValue("value", propertyProvider.getPropertyValue("value", last_entry)) + propertyProvider.setPropertyValue("state", "InstanceState.Calculated") } backgroundColor: UM.Theme.getColor("setting_control"); From cf15f9e2a11a593648bd4217408f6b64934858f6 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 8 Jun 2016 15:31:28 +0200 Subject: [PATCH 545/705] Added handling of special case when only user & definition were set CURA-1278 --- resources/qml/Settings/SettingItem.qml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index 2f1a74dba6..9ed75bdecf 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -175,8 +175,17 @@ Item { // This ensures that the value in any of the deeper containers need not be removed, which is // needed for the reset button (which deletes the top value) to correctly go back to profile // defaults. - propertyProvider.setPropertyValue("value", propertyProvider.getPropertyValue("value", last_entry)) - propertyProvider.setPropertyValue("state", "InstanceState.Calculated") + if(last_entry == 4 && base.stackLevel == 0) + { + // Special case of the inherit reset. If only the definition (4th container) and the first + // entry (user container) are set, we can simply remove the container. + propertyProvider.removeFromContainer(0) + } + else + { + propertyProvider.setPropertyValue("value", propertyProvider.getPropertyValue("value", last_entry)) + propertyProvider.setPropertyValue("state", "InstanceState.Calculated") + } } backgroundColor: UM.Theme.getColor("setting_control"); From 8a7e549a27c6b6f9fe28c7d944097f093fdf1224 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Wed, 8 Jun 2016 15:40:15 +0200 Subject: [PATCH 546/705] Merge fix of 2.1 Max Retraction count 45 ==> 90 wasn't taken along --- 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 29db032aa1..8be258c79e 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -890,7 +890,7 @@ "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": 45, + "default_value": 90, "minimum_value": "0", "maximum_value_warning": "100", "type": "int", From cc7369c59476aa49bb7c515dc6dca2d4ce75db83 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Wed, 8 Jun 2016 15:43:22 +0200 Subject: [PATCH 547/705] profiles fix: duplicated UM2+ profile changes from 2.1 to the UM2E+ profiles (CURA-1662) --- .../ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg | 2 ++ .../ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg | 1 + .../ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg | 1 + .../ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg | 1 + .../ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg | 1 + .../ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg | 1 + .../ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg | 1 + 7 files changed, 8 insertions(+) diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg index f554c7f058..139c8cb976 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg @@ -15,6 +15,8 @@ wall_thickness = 0.7 top_bottom_thickness = 0.75 infill_sparse_density = 18 speed_print = 55 +speed_wall = 40 +speed_topbottom = 30 speed_travel = 150 speed_layer_0 = 30 cool_min_layer_time = 3 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg index c1a8136cf5..8d021f4d91 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg @@ -15,6 +15,7 @@ wall_thickness = 1.05 top_bottom_thickness = 0.72 infill_sparse_density = 22 speed_print = 45 +speed_wall = 30 cool_min_layer_time = 3 cool_fan_speed_min = 20 cool_min_speed = 10 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg index eabc9827a1..3f89bdeee6 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg @@ -15,6 +15,7 @@ wall_thickness = 1.05 top_bottom_thickness = 0.8 infill_sparse_density = 20 speed_print = 45 +speed_wall = 30 cool_min_layer_time = 3 cool_fan_speed_min = 20 cool_min_speed = 10 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg index 64e0ec72fb..ea67bcc0b2 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg @@ -15,6 +15,7 @@ wall_thickness = 1.59 top_bottom_thickness = 1.2 infill_sparse_density = 20 speed_print = 40 +speed_infill = 55 cool_min_layer_time = 3 cool_fan_speed_min = 50 cool_min_speed = 20 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg index ae9b437010..5f402d50aa 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg @@ -15,6 +15,7 @@ wall_thickness = 0.7 top_bottom_thickness = 0.75 infill_sparse_density = 18 speed_print = 45 +speed_wall = 40 speed_travel = 150 speed_layer_0 = 30 cool_min_layer_time = 3 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg index e3fa254a74..2b35097f66 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg @@ -15,6 +15,7 @@ wall_thickness = 1.05 top_bottom_thickness = 0.72 infill_sparse_density = 22 speed_print = 45 +speed_wall = 30 cool_min_layer_time = 2 cool_fan_speed_min = 80 cool_min_speed = 15 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg index 48e767e1cb..41e9fab6d3 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg @@ -15,6 +15,7 @@ wall_thickness = 1.05 top_bottom_thickness = 0.8 infill_sparse_density = 20 speed_print = 45 +speed_wall = 30 cool_min_layer_time = 3 cool_fan_speed_min = 80 cool_min_speed = 10 From 860846880212c89f2b0aca718b23b15acba4a3e8 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 8 Jun 2016 16:32:39 +0200 Subject: [PATCH 548/705] Add a method to get the id of the current user profile CURA-1668 --- cura/MachineManagerModel.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 2738bfd764..e719c05743 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -105,7 +105,7 @@ class MachineManagerModel(QObject): @pyqtSlot(str, str) def addMachine(self, name, definition_id): - definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id=definition_id) + definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = definition_id) if definitions: definition = definitions[0] name = self._createUniqueName("machine", "", name, definition.getName()) @@ -205,6 +205,13 @@ class MachineManagerModel(QObject): def isGlobalStackValid(self): return self._global_stack_valid + @pyqtProperty(str, notify = globalContainerChanged) + def activeUserProfileId(self): + if self._global_container_stack: + return self._global_container_stack.getTop().getId() + + return "" + @pyqtProperty(str, notify = globalContainerChanged) def activeMachineName(self): if self._global_container_stack: From 1131623278227f9e7ab4db9b5fd42ff54a27f961 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 8 Jun 2016 16:33:58 +0200 Subject: [PATCH 549/705] Disable the property editor when the value of the setting is not used Contributes to CURA-1278 --- resources/qml/Settings/SettingItem.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index 9ed75bdecf..8160489b01 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -205,6 +205,8 @@ Item { { id: controlContainer; + enabled: provider.isValueUsed + anchors.right: parent.right; anchors.rightMargin: UM.Theme.getSize("default_margin").width anchors.verticalCenter: parent.verticalCenter; From 485ae53660d5c234084403ab7d13125470ca7bcf Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 8 Jun 2016 16:35:10 +0200 Subject: [PATCH 550/705] Show quality profile and user profile settings side-by-side on Profiles manager Introduces ContainerSettingsModel, which can combine the settings of instances from multiple containers into one model. Towards CURA-1668 --- cura/ContainerSettingsModel.py | 104 +++++++++++++++++++++ cura/CuraApplication.py | 3 + resources/qml/Preferences/ProfilesPage.qml | 11 ++- 3 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 cura/ContainerSettingsModel.py diff --git a/cura/ContainerSettingsModel.py b/cura/ContainerSettingsModel.py new file mode 100644 index 0000000000..23d20cd6e2 --- /dev/null +++ b/cura/ContainerSettingsModel.py @@ -0,0 +1,104 @@ +from UM.Application import Application +from UM.Qt.ListModel import ListModel + +from PyQt5.QtCore import pyqtProperty, Qt, pyqtSignal, pyqtSlot, QUrl + +from UM.Settings.ContainerRegistry import ContainerRegistry +from UM.Settings.InstanceContainer import InstanceContainer + +class ContainerSettingsModel(ListModel): + LabelRole = Qt.UserRole + 1 + CategoryRole = Qt.UserRole + 2 + UnitRole = Qt.UserRole + 3 + ValuesRole = Qt.UserRole + 4 + + def __init__(self, parent = None): + super().__init__(parent) + self.addRoleName(self.LabelRole, "label") + self.addRoleName(self.CategoryRole, "category") + self.addRoleName(self.UnitRole, "unit") + self.addRoleName(self.ValuesRole, "values") + + self._container_ids = [] + self._container = None + + self._global_container_stack = None + Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged) + self._update() + + def _onGlobalContainerChanged(self): + if self._global_container_stack: + self._global_container_stack.containersChanged.disconnect(self._onInstanceContainersChanged) + self._global_container_stack.propertyChanged.disconnect(self._onGlobalPropertyChanged) + + self._global_container_stack = Application.getInstance().getGlobalContainerStack() + + if self._global_container_stack: + Preferences.getInstance().setValue("cura/active_machine", self._global_container_stack.getId()) + self._global_container_stack.containersChanged.connect(self._onInstanceContainersChanged) + self._global_container_stack.propertyChanged.connect(self._onGlobalPropertyChanged) + + self._update() + + def _onGlobalPropertyChanged(self, key, property_name): + if property_name == "value": + self._update() + + def _onInstanceContainersChanged(self, container): + self._update() + + def _update(self): + self.clear() + + if len(self._container_ids) == 0: + return + + keys = [] + containers = [] + for container_id in self._container_ids: + container = ContainerRegistry.getInstance().findContainers(id = container_id) + if not container: + return + + keys = keys + list(container[0].getAllKeys()) + containers.append(container[0]) + + keys = list(set(keys)) + keys.sort() + + for key in keys: + definition = None + category = None + values = [] + for container in containers: + + instance = container.getInstance(key) + if instance: + definition = instance.definition + + # Traverse up to find the category + category = definition + while category.type != "category": + category = category.parent + + values.append(container.getProperty(key, "value")) + else: + values.append("") + + self.appendItem({ + "key": key, + "values": values, + "label": definition.label, + "unit": definition.unit, + "category": category.label + }) + + ## Set the id of the container which has the settings this model should list. + def setContainers(self, container_ids): + self._container_ids = container_ids + self._update() + + containersChanged = pyqtSignal() + @pyqtProperty("QVariantList", fset = setContainers, notify = containersChanged) + def containers(self): + return self.container_ids \ No newline at end of file diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 8acd3eda2a..9abfabc7b2 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -42,6 +42,7 @@ from . import MultiMaterialDecorator from . import ZOffsetDecorator from . import CuraSplashScreen from . import MachineManagerModel +from . import ContainerSettingsModel from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty, QEvent, Q_ENUMS from PyQt5.QtGui import QColor, QIcon @@ -400,6 +401,8 @@ class CuraApplication(QtApplication): qmlRegisterType(ExtrudersModel.ExtrudersModel, "Cura", 1, 0, "ExtrudersModel") + qmlRegisterType(ContainerSettingsModel.ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel") + qmlRegisterSingletonType(QUrl.fromLocalFile(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")), "Cura", 1, 0, "Actions") engine.rootContext().setContextProperty("ExtruderManager", ExtruderManager.ExtruderManager.getInstance()) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index ed9c20f65f..ee7653f96e 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -128,16 +128,21 @@ UM.ManagementPage anchors.bottom: parent.bottom ListView { - model: base.currentItem ? base.currentItem.settings: null + model: Cura.ContainerSettingsModel{ containers: [base.currentItem.id, Cura.MachineManager.activeUserProfileId] } delegate: Row { + property variant setting: model spacing: UM.Theme.getSize("default_margin").width Label { text: model.label elide: Text.ElideMiddle width: scrollView.width / 100 * 40 } - Label { - text: model.value.toString() + Repeater { + model: setting.values.length + Label { + text: setting.values[index].toString() + width: scrollView.width / 100 * 10 + } } Label { text: model.unit From 7dbafa06d1ae2b53e77726dee45662d721470ccb Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 8 Jun 2016 16:00:52 +0200 Subject: [PATCH 551/705] Make SidebarHeader use ExtrudersModel This model is also used by the extruder selection drop-downs, and it's automatically filled already so that was double logic. Contributes to issues CURA-340 and CURA-1278. --- resources/qml/SidebarHeader.qml | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 237746ac0d..75f5393d57 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -104,7 +104,7 @@ Item anchors.leftMargin: model.index * (extruderSelection.width / machineExtruderCount.properties.value) anchors.verticalCenter: parent.verticalCenter width: parent.width / machineExtruderCount.properties.value - text: model.text + text: model.name exclusiveGroup: extruderMenuGroup; checkable: true; checked: base.currentExtruderIndex == index @@ -138,10 +138,11 @@ Item } } ExclusiveGroup { id: extruderMenuGroup; } - ListView{ + ListView + { id: extrudersList property var index: 0 - model: extrudersListModel + model: Cura.ExtrudersModel {} delegate: wizardDelegate anchors.top: parent.top anchors.left: parent.left @@ -149,28 +150,6 @@ Item } } - ListModel - { - id: extrudersListModel - Component.onCompleted: populateExtruderModel() - } - Connections - { - id: machineChange - target: Cura.MachineManager - onGlobalContainerChanged: populateExtruderModel() - } - - function populateExtruderModel() - { - extrudersListModel.clear(); - for(var extruder = 0; extruder < machineExtruderCount.properties.value ; extruder++) { - extrudersListModel.append({ - text: catalog.i18nc("@label", "Extruder %1").arg(extruder + 1) - }) - } - } - Rectangle { id: variantRow anchors.top: extruderSelection.visible ? extruderSelection.bottom : machineSelectionRow.bottom From 4d418a7c1a94ddfe11a3f3e6b252821b9e077d73 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 8 Jun 2016 16:26:57 +0200 Subject: [PATCH 552/705] When switching active extruder, get the extruder train from definition id Not from extruder container stack ID. Contributes to issues CURA-340 and CURA-1278. --- cura/ExtruderManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index b4d05d7e6c..c8a07a4000 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -36,7 +36,7 @@ class ExtruderManager(QObject): if not UM.Application.getInstance().getGlobalContainerStack(): return None #No active machine, so no active extruder. try: - return self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getId()][str(self._active_extruder_index)] + return self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getBottom().getId()][str(self._active_extruder_index)] except KeyError: #Extruder index could be -1 if the global tab is selected, or the entry doesn't exist if the machine definition is wrong. return None From da467b9b2806af69fb55f51f2b8a73b095c69cd6 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 8 Jun 2016 16:45:20 +0200 Subject: [PATCH 553/705] Only shown the current settings column when the currently active quality profile is selected CURA-1668 --- resources/qml/Preferences/ProfilesPage.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index ee7653f96e..3307c1e2a5 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -93,7 +93,7 @@ UM.ManagementPage Row { id: currentSettingsActions - visible: base.currentItem.id == -1 || currentItem.id == Cura.MachineManager.activeQualityId + visible: currentItem.id == Cura.MachineManager.activeQualityId anchors.left: parent.left anchors.top: profileName.bottom @@ -128,7 +128,7 @@ UM.ManagementPage anchors.bottom: parent.bottom ListView { - model: Cura.ContainerSettingsModel{ containers: [base.currentItem.id, Cura.MachineManager.activeUserProfileId] } + model: Cura.ContainerSettingsModel{ containers: (currentItem.id == Cura.MachineManager.activeQualityId) ? [base.currentItem.id, Cura.MachineManager.activeUserProfileId] : [base.currentItem.id] } delegate: Row { property variant setting: model spacing: UM.Theme.getSize("default_margin").width From 07b51d0ca8813f95a76e252651113bf398c68010 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 8 Jun 2016 17:04:04 +0200 Subject: [PATCH 554/705] Strike out profile value if it is overridden by the current setting CURA-1668 --- resources/qml/Preferences/ProfilesPage.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 3307c1e2a5..14569464d6 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -142,6 +142,8 @@ UM.ManagementPage Label { text: setting.values[index].toString() width: scrollView.width / 100 * 10 + font.strikeout: index < setting.values.length - 1 && setting.values[index + 1] != "" + opacity: font.strikeout ? 0.5 : 1 } } Label { From fcd6f0959f0b15281074af4ab717eb8536e0660c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 8 Jun 2016 17:47:23 +0200 Subject: [PATCH 555/705] Inheritance button now only shows if there is a function in the container stack at some point CURA-1278 --- resources/qml/Settings/SettingItem.qml | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index 9ed75bdecf..1b80cb68f5 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -158,9 +158,24 @@ Item { { // This button shows when the setting has an inherited function, but is overriden by profile. id: inheritButton; - - //visible: has_profile_value && base.has_inherit_function && base.is_enabled - visible: base.state == "InstanceState.User" && base.showInheritButton + // Inherit button needs to be visible if; + // - User made changes that override any loaded settings + // - This setting item uses inherit button at all + // - The type of the value of any deeper container is an "object" (eg; is a function) + visible: + { + var state = base.state == "InstanceState.User"; + var has_setting_function = false; + for (var i = 1; i < base.stackLevels.length; i++) + { + has_setting_function = typeof(propertyProvider.getPropertyValue("value", base.stackLevels[i])) == "object"; + if(has_setting_function) + { + break; + } + } + return state && base.showInheritButton && has_setting_function + } height: parent.height; width: height; From ca308c5b05f37d0205b5392e31de927eae0a5b31 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 8 Jun 2016 17:50:54 +0200 Subject: [PATCH 556/705] Add notice if a profile has no settings, and if the current settings are "empty" CURA-1668, CURA-696 --- resources/qml/Preferences/ProfilesPage.qml | 26 +++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 14569464d6..97dd2c5d77 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -118,11 +118,35 @@ UM.ManagementPage } } + Column { + id: profileNotices + anchors.top: currentSettingsActions.visible ? currentSettingsActions.bottom : currentSettingsActions.anchors.top + anchors.topMargin: UM.Theme.getSize("default_margin").height + anchors.left: parent.left + anchors.right: parent.right + spacing: UM.Theme.getSize("default_margin").height + + Label { + id: defaultsMessage + visible: !currentItem.hasSettings + text: catalog.i18nc("@action:label", "This profile has no settings and uses the defaults specified by the printer.") + wrapMode: Text.WordWrap + width: parent.width + } + Label { + id: noCurrentSettingsMessage + visible: currentItem.id == Cura.MachineManager.activeQualityId && !Cura.MachineManager.hasUserSettings + text: catalog.i18nc("@action:label", "Your current settings match the selected profile.") + wrapMode: Text.WordWrap + width: parent.width + } + } + ScrollView { id: scrollView anchors.left: parent.left - anchors.top: currentSettingsActions.visible ? currentSettingsActions.bottom : profileName.bottom + anchors.top: profileNotices.visible ? profileNotices.bottom : profileNotices.anchors.top anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.right: parent.right anchors.bottom: parent.bottom From e702fef44b185f51da79112aeedeffcb85cbf0cb Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 8 Jun 2016 22:07:57 +0200 Subject: [PATCH 557/705] Add header to profile settings table --- resources/qml/Preferences/ProfilesPage.qml | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 97dd2c5d77..3ca8d77461 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -155,7 +155,7 @@ UM.ManagementPage model: Cura.ContainerSettingsModel{ containers: (currentItem.id == Cura.MachineManager.activeQualityId) ? [base.currentItem.id, Cura.MachineManager.activeUserProfileId] : [base.currentItem.id] } delegate: Row { property variant setting: model - spacing: UM.Theme.getSize("default_margin").width + spacing: UM.Theme.getSize("default_margin").width/2 Label { text: model.label elide: Text.ElideMiddle @@ -165,7 +165,8 @@ UM.ManagementPage model: setting.values.length Label { text: setting.values[index].toString() - width: scrollView.width / 100 * 10 + width: scrollView.width / 100 * 15 + elide: Text.ElideRight font.strikeout: index < setting.values.length - 1 && setting.values[index + 1] != "" opacity: font.strikeout ? 0.5 : 1 } @@ -174,6 +175,21 @@ UM.ManagementPage text: model.unit } } + header: Row { + visible: currentItem.id == Cura.MachineManager.activeQualityId + spacing: UM.Theme.getSize("default_margin").width + Label { + text: catalog.i18nc("@action:label", "Profile value") + width: scrollView.width / 100 * 55 + horizontalAlignment: Text.AlignRight + font.bold: true + } + Label { + text: catalog.i18nc("@action:label", "Current setting") + visible: currentItem.id == Cura.MachineManager.activeQualityId + font.bold: true + } + } section.property: "category" section.criteria: ViewSection.FullString section.delegate: Label { From b85a8ca404a59e09def6b0e901b7b6374a221308 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 9 Jun 2016 07:54:13 +0200 Subject: [PATCH 558/705] Update ContainerSettingsModel when its containers have property changes CURA-1668 --- cura/ContainerSettingsModel.py | 52 ++++++++++++---------------------- 1 file changed, 18 insertions(+), 34 deletions(-) diff --git a/cura/ContainerSettingsModel.py b/cura/ContainerSettingsModel.py index 23d20cd6e2..1dea88cac3 100644 --- a/cura/ContainerSettingsModel.py +++ b/cura/ContainerSettingsModel.py @@ -22,31 +22,10 @@ class ContainerSettingsModel(ListModel): self._container_ids = [] self._container = None - self._global_container_stack = None - Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged) - self._update() - - def _onGlobalContainerChanged(self): - if self._global_container_stack: - self._global_container_stack.containersChanged.disconnect(self._onInstanceContainersChanged) - self._global_container_stack.propertyChanged.disconnect(self._onGlobalPropertyChanged) - - self._global_container_stack = Application.getInstance().getGlobalContainerStack() - - if self._global_container_stack: - Preferences.getInstance().setValue("cura/active_machine", self._global_container_stack.getId()) - self._global_container_stack.containersChanged.connect(self._onInstanceContainersChanged) - self._global_container_stack.propertyChanged.connect(self._onGlobalPropertyChanged) - - self._update() - - def _onGlobalPropertyChanged(self, key, property_name): + def _onPropertyChanged(self, key, property_name): if property_name == "value": self._update() - def _onInstanceContainersChanged(self, container): - self._update() - def _update(self): self.clear() @@ -54,24 +33,17 @@ class ContainerSettingsModel(ListModel): return keys = [] - containers = [] - for container_id in self._container_ids: - container = ContainerRegistry.getInstance().findContainers(id = container_id) - if not container: - return + for container in self._containers: + keys = keys + list(container.getAllKeys()) - keys = keys + list(container[0].getAllKeys()) - containers.append(container[0]) - - keys = list(set(keys)) + keys = list(set(keys)) # remove duplicate keys keys.sort() for key in keys: definition = None category = None values = [] - for container in containers: - + for container in self._containers: instance = container.getInstance(key) if instance: definition = instance.definition @@ -93,9 +65,21 @@ class ContainerSettingsModel(ListModel): "category": category.label }) - ## Set the id of the container which has the settings this model should list. + ## Set the ids of the containers which have the settings this model should list. + # Also makes sure the model updates when the containers have property changes def setContainers(self, container_ids): + for container in self._containers: + container.propertyChanged.disconnect(self._onPropertyChanged) + self._container_ids = container_ids + self._containers = [] + + for container_id in self._container_ids: + containers = ContainerRegistry.getInstance().findContainers(id = container_id) + if containers: + containers[0].propertyChanged.connect(self._onPropertyChanged) + self._containers.append(containers[0]) + self._update() containersChanged = pyqtSignal() From a6dd9e74158e3fad24a2ef0d0740318b8fb0cbf4 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 9 Jun 2016 08:14:06 +0200 Subject: [PATCH 559/705] Fix initialization of ContainerSettingsModel CURA-1668 --- cura/ContainerSettingsModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/ContainerSettingsModel.py b/cura/ContainerSettingsModel.py index 1dea88cac3..83a1f3ccd4 100644 --- a/cura/ContainerSettingsModel.py +++ b/cura/ContainerSettingsModel.py @@ -20,7 +20,7 @@ class ContainerSettingsModel(ListModel): self.addRoleName(self.ValuesRole, "values") self._container_ids = [] - self._container = None + self._containers = [] def _onPropertyChanged(self, key, property_name): if property_name == "value": From ecfd7e599356a6f84ef8a3983fa25f9680f5c91c Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 9 Jun 2016 08:21:18 +0200 Subject: [PATCH 560/705] Move InstanceContainersModel has_settings into metadata to clean up the model CURA-1668 --- 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 3ca8d77461..faf72bfc7a 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -128,7 +128,7 @@ UM.ManagementPage Label { id: defaultsMessage - visible: !currentItem.hasSettings + visible: !currentItem.metadata.has_settings text: catalog.i18nc("@action:label", "This profile has no settings and uses the defaults specified by the printer.") wrapMode: Text.WordWrap width: parent.width From a21498c37536fead27f63e91a9adfd94d504e9c1 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 9 Jun 2016 08:29:05 +0200 Subject: [PATCH 561/705] Add weights to generic quality profiles CURA-1278 --- resources/quality/high.inst.cfg | 1 + resources/quality/low.inst.cfg | 1 + resources/quality/normal.inst.cfg | 1 + 3 files changed, 3 insertions(+) diff --git a/resources/quality/high.inst.cfg b/resources/quality/high.inst.cfg index 86df9dab92..b2413bba23 100644 --- a/resources/quality/high.inst.cfg +++ b/resources/quality/high.inst.cfg @@ -5,6 +5,7 @@ definition = fdmprinter [metadata] type = quality +weight = -3 read_only = True [values] diff --git a/resources/quality/low.inst.cfg b/resources/quality/low.inst.cfg index 6cebc46dd5..43ac4ac02d 100644 --- a/resources/quality/low.inst.cfg +++ b/resources/quality/low.inst.cfg @@ -5,6 +5,7 @@ definition = fdmprinter [metadata] type = quality +weight = -1 read_only = True [values] diff --git a/resources/quality/normal.inst.cfg b/resources/quality/normal.inst.cfg index b12603f921..df9448097b 100644 --- a/resources/quality/normal.inst.cfg +++ b/resources/quality/normal.inst.cfg @@ -5,6 +5,7 @@ definition = fdmprinter [metadata] type = quality +weight = -2 read_only = True [values] From a070684ade3e89f6dbb18e2ba5d7692d07eafb4c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 9 Jun 2016 09:59:06 +0200 Subject: [PATCH 562/705] Fixed minor issue for inheritance button It didn't always reset to correct value. CURA-1278 --- resources/qml/Settings/SettingItem.qml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index 0cb1c169df..6095ab10d1 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -185,12 +185,22 @@ Item { // Get the deepest entry of this setting that we can find. TODO: This is a bit naive, in some cases // there might be multiple profiles saying something about the same setting. There is no strategy // how to handle this as of yet. - var last_entry = propertyProvider.stackLevels.slice(-1)[0] + var last_entry = propertyProvider.stackLevels[propertyProvider.stackLevels.length] + + for (var i = 1; i < base.stackLevels.length; i++) + { + var has_setting_function = typeof(propertyProvider.getPropertyValue("value", base.stackLevels[i])) == "object"; + if(has_setting_function) + { + last_entry = propertyProvider.stackLevels[i] + break; + } + } // Put that entry into the "top" instance container. // This ensures that the value in any of the deeper containers need not be removed, which is // needed for the reset button (which deletes the top value) to correctly go back to profile // defaults. - if(last_entry == 4 && base.stackLevel == 0) + if(last_entry == 4 && base.stackLevel == 0 && base.stackLevels.length == 2) { // Special case of the inherit reset. If only the definition (4th container) and the first // entry (user container) are set, we can simply remove the container. From e4e307cd2a08f8024ebc4237857b41317be08578 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 9 Jun 2016 10:25:01 +0200 Subject: [PATCH 563/705] Inheritance button now works if instance containers contain functions CURA-1686 --- resources/qml/Settings/SettingItem.qml | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index 6095ab10d1..4fd84759fd 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -174,7 +174,7 @@ Item { break; } } - return state && base.showInheritButton && has_setting_function + return state && base.showInheritButton && has_setting_function && typeof(propertyProvider.getPropertyValue("value", base.stackLevels[0])) != "object" } height: parent.height; @@ -182,11 +182,9 @@ Item { onClicked: { focus = true; - // Get the deepest entry of this setting that we can find. TODO: This is a bit naive, in some cases - // there might be multiple profiles saying something about the same setting. There is no strategy - // how to handle this as of yet. - var last_entry = propertyProvider.stackLevels[propertyProvider.stackLevels.length] + // Get the most shallow function value (eg not a number) that we can find. + var last_entry = propertyProvider.stackLevels[propertyProvider.stackLevels.length] for (var i = 1; i < base.stackLevels.length; i++) { var has_setting_function = typeof(propertyProvider.getPropertyValue("value", base.stackLevels[i])) == "object"; @@ -196,18 +194,25 @@ Item { break; } } - // Put that entry into the "top" instance container. - // This ensures that the value in any of the deeper containers need not be removed, which is - // needed for the reset button (which deletes the top value) to correctly go back to profile - // defaults. + if(last_entry == 4 && base.stackLevel == 0 && base.stackLevels.length == 2) { // Special case of the inherit reset. If only the definition (4th container) and the first // entry (user container) are set, we can simply remove the container. propertyProvider.removeFromContainer(0) } + else if(last_entry - 1 == base.stackLevel) + { + // Another special case. The setting that is overriden is only 1 instance container deeper, + // so we can remove it. + propertyProvider.removeFromContainer(0) + } else { + // Put that entry into the "top" instance container. + // This ensures that the value in any of the deeper containers need not be removed, which is + // needed for the reset button (which deletes the top value) to correctly go back to profile + // defaults. propertyProvider.setPropertyValue("value", propertyProvider.getPropertyValue("value", last_entry)) propertyProvider.setPropertyValue("state", "InstanceState.Calculated") } From 20f657af888692f4f8620c974d3781429d2f4c6c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 9 Jun 2016 10:40:28 +0200 Subject: [PATCH 564/705] Updated proto file Objects & global settings are now sent in one message. Also added support for extruder settings CURA-1681 --- plugins/CuraEngineBackend/Cura.proto | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/CuraEngineBackend/Cura.proto b/plugins/CuraEngineBackend/Cura.proto index 0d4975aca4..c51829aeff 100644 --- a/plugins/CuraEngineBackend/Cura.proto +++ b/plugins/CuraEngineBackend/Cura.proto @@ -11,6 +11,8 @@ message ObjectList message Slice { repeated ObjectList object_lists = 1; + SettingList global_settings = 2; + repeated SettingsList extruder_settings = 3; } message Object From 14b9294a3944196eef01401741807e279570969a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 8 Jun 2016 17:02:00 +0200 Subject: [PATCH 565/705] Document setActiveExtruderIndex Contributes to issues CURA-340 and CURA-1278. --- cura/ExtruderManager.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index c8a07a4000..bd0c3956d3 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -58,6 +58,9 @@ class ExtruderManager(QObject): cls.__instance = ExtruderManager() return cls.__instance + ## Changes the active extruder by index. + # + # \param index The index of the new active extruder. @pyqtSlot(int) def setActiveExtruderIndex(self, index): self._active_extruder_index = index From 1149a96d70c2ff44167d6c607e95ee4636605ea4 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 9 Jun 2016 10:45:20 +0200 Subject: [PATCH 566/705] Fix spelling --- 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 8be258c79e..2bb1f6acff 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1043,7 +1043,7 @@ "speed_wall_0": { "label": "Outer Wall Speed", - "description": "The speed at which the outermost walls are printed. Printing the outer wall at a lower speed improves the final skin quality. However, having a large difference between the inner wall speed and the outer wall speed will effect quality in a negative way.", + "description": "The speed at which the outermost walls are printed. Printing the outer wall at a lower speed improves the final skin quality. However, having a large difference between the inner wall speed and the outer wall speed will affect quality in a negative way.", "unit": "mm/s", "type": "float", "minimum_value": "0.1", From ce9d8b6dd0ea1b6147913dd317a1b8ca6cb8ae97 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 9 Jun 2016 10:48:44 +0200 Subject: [PATCH 567/705] proto file typo fix (CURA-1681 CURA-1682) --- plugins/CuraEngineBackend/Cura.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/CuraEngineBackend/Cura.proto b/plugins/CuraEngineBackend/Cura.proto index c51829aeff..c2b6a142b4 100644 --- a/plugins/CuraEngineBackend/Cura.proto +++ b/plugins/CuraEngineBackend/Cura.proto @@ -12,7 +12,7 @@ message Slice { repeated ObjectList object_lists = 1; SettingList global_settings = 2; - repeated SettingsList extruder_settings = 3; + repeated SettingList extruder_settings = 3; } message Object From 5da366583273b4a9fe1061d1ed1c3f104276f630 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 9 Jun 2016 11:22:33 +0200 Subject: [PATCH 568/705] Fix duplicating the first item on the Profiles page CURA-1585 --- resources/qml/Preferences/ProfilesPage.qml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index faf72bfc7a..ac57dbba35 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -49,8 +49,7 @@ UM.ManagementPage onActivateObject: Cura.MachineManager.setActiveQuality(currentItem.id) onAddObject: { var selectedContainer; - if (objectList.currentIndex == 0) { - // Current settings + if (objectList.currentItem.id == Cura.MachineManager.activeQualityId) { selectedContainer = Cura.MachineManager.convertUserContainerToQuality(); } else { selectedContainer = Cura.MachineManager.duplicateContainer(base.currentItem.id); From 123c2f5c85148bb74b5e510f5d7cc06d2ba31cc9 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 9 Jun 2016 11:33:15 +0200 Subject: [PATCH 569/705] Moved global settings into slice message (as per API changes) CURA-1681 --- plugins/CuraEngineBackend/CuraEngineBackend.py | 4 +--- plugins/CuraEngineBackend/StartSliceJob.py | 8 ++------ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 9607ba407b..3e22f8f6fb 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -145,8 +145,7 @@ class CuraEngineBackend(Backend): self.slicingStarted.emit() slice_message = self._socket.createMessage("cura.proto.Slice") - settings_message = self._socket.createMessage("cura.proto.SettingList") - self._start_slice_job = StartSliceJob.StartSliceJob(slice_message, settings_message) + self._start_slice_job = StartSliceJob.StartSliceJob(slice_message) self._start_slice_job.start() self._start_slice_job.finished.connect(self._onStartSliceCompleted) @@ -205,7 +204,6 @@ class CuraEngineBackend(Backend): return # Preparation completed, send it to the backend. - self._socket.sendMessage(job.getSettingsMessage()) self._socket.sendMessage(job.getSliceMessage()) ## Listener for when the scene has changed. diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index dee6f2b64c..75bbd4073f 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -37,17 +37,13 @@ class GcodeStartEndFormatter(Formatter): ## Job class that builds up the message of scene data to send to CuraEngine. class StartSliceJob(Job): - def __init__(self, slice_message, settings_message): + def __init__(self, slice_message): super().__init__() self._scene = Application.getInstance().getController().getScene() self._slice_message = slice_message - self._settings_message = settings_message self._is_cancelled = False - def getSettingsMessage(self): - return self._settings_message - def getSliceMessage(self): return self._slice_message @@ -185,7 +181,7 @@ class StartSliceJob(Job): settings["material_print_temp_prepend"] = "{material_print_temperature}" not in start_gcode for key, value in settings.items(): #Add all submessages for each individual setting. - setting_message = self._settings_message.addRepeatedMessage("settings") + setting_message = self._slice_message.getMessage("global_settings").addRepeatedMessage("settings") setting_message.name = key if key == "machine_start_gcode" or key == "machine_end_gcode": #If it's a g-code message, use special formatting. setting_message.value = self._expandGcodeTokens(key, value, settings) From 899e4cc175ff8b78ccea35be29e163805c53ea20 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 9 Jun 2016 11:46:52 +0200 Subject: [PATCH 570/705] Fixed sending of per-object settings to engine CURA-1681 --- plugins/CuraEngineBackend/StartSliceJob.py | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 75bbd4073f..9a3dc3a263 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -189,21 +189,10 @@ class StartSliceJob(Job): setting_message.value = str(value).encode("utf-8") def _handlePerObjectSettings(self, node, message): - profile = node.callDecoration("getProfile") - if profile: - for key, value in profile.getAllSettingValues().items(): + stack = node.callDecoration("getStack") + if stack: + for key in stack.getAllKeys(): setting = message.addRepeatedMessage("settings") setting.name = key - setting.value = str(value).encode() - - Job.yieldThread() - - object_settings = node.callDecoration("getAllSettingValues") - if not object_settings: - return - for key, value in object_settings.items(): - setting = message.addRepeatedMessage("settings") - setting.name = key - setting.value = str(value).encode() - - Job.yieldThread() + setting.value = str(stack.getProperty(key, "value")).encode("utf-8") + Job.yieldThread() \ No newline at end of file From 4bdd5713f19e2d8a7c2c656dec5d2ee24fe6b105 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 9 Jun 2016 11:35:23 +0200 Subject: [PATCH 571/705] Fix extruder number attached to extruders It reads that from position in the extruder definition file. Contributes to issues CURA-1278 and CURA-340. --- cura/ExtrudersModel.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cura/ExtrudersModel.py b/cura/ExtrudersModel.py index 60bd60abab..37487f838c 100644 --- a/cura/ExtrudersModel.py +++ b/cura/ExtrudersModel.py @@ -51,13 +51,18 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): global_container_stack = UM.Application.getInstance().getGlobalContainerStack() if not global_container_stack: return #There is no machine to get the extruders of. - for index, extruder in enumerate(manager.getMachineExtruders(global_container_stack.getBottom())): + for extruder in manager.getMachineExtruders(global_container_stack.getBottom()): material = extruder.findContainer({ "type": "material" }) colour = material.getMetaDataEntry("color_code", default = "#FFFF00") if material else "#FFFF00" + position = extruder.getBottom().getMetaDataEntry("position", default = "0") #Position in the definition. + try: + position = int(position) + except ValueError: #Not a proper int. + position = -1 item = { #Construct an item with only the relevant information. "name": extruder.getName(), "colour": colour, - "index": index + "index": position } self.appendItem(item) self.sort(lambda item: item["index"]) \ No newline at end of file From 6a520cad47c547b896db6dc02c4125e760faff6d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 9 Jun 2016 11:48:21 +0200 Subject: [PATCH 572/705] Change focus upon extruder switch This applies a setting that is currently being typed by the user. Otherwise it would take the currently being typed value along to the next tab, since it can't update a setting value while it is in focus. Contributes to issues CURA-340 and CURA-1278. --- resources/qml/SidebarHeader.qml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 75f5393d57..60f5af2e73 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -110,8 +110,9 @@ Item checked: base.currentExtruderIndex == index onClicked: { - base.currentExtruderIndex = index - ExtruderManager.setActiveExtruderIndex(index) + extruderSelection.focus = true; //Changing focus applies the currently-being-typed values so it can change the displayed setting values. + base.currentExtruderIndex = index; + ExtruderManager.setActiveExtruderIndex(index); } style: ButtonStyle { From a01b554ee3320a148753417df8ebcaa933a097ce Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 9 Jun 2016 11:56:41 +0200 Subject: [PATCH 573/705] Added extruder to proto message CURA-1681 --- plugins/CuraEngineBackend/Cura.proto | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/CuraEngineBackend/Cura.proto b/plugins/CuraEngineBackend/Cura.proto index c2b6a142b4..aa42ed989a 100644 --- a/plugins/CuraEngineBackend/Cura.proto +++ b/plugins/CuraEngineBackend/Cura.proto @@ -12,7 +12,13 @@ message Slice { repeated ObjectList object_lists = 1; SettingList global_settings = 2; - repeated SettingList extruder_settings = 3; + repeated Extruder extruders = 3; +} + +message Extruder +{ + int32 id = 1; + SettingList settings = 2; } message Object From b6649eab3aef1dbd72058618dfd441d56c65f8a4 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 9 Jun 2016 12:08:10 +0200 Subject: [PATCH 574/705] dox: documented proto file (CURA-1681 CURA-1682) --- plugins/CuraEngineBackend/Cura.proto | 32 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/plugins/CuraEngineBackend/Cura.proto b/plugins/CuraEngineBackend/Cura.proto index aa42ed989a..38753fd804 100644 --- a/plugins/CuraEngineBackend/Cura.proto +++ b/plugins/CuraEngineBackend/Cura.proto @@ -5,14 +5,14 @@ package cura.proto; message ObjectList { repeated Object objects = 1; - repeated Setting settings = 2; + repeated Setting settings = 2; // meshgroup settings (for one-at-a-time printing) } message Slice { - repeated ObjectList object_lists = 1; - SettingList global_settings = 2; - repeated Extruder extruders = 3; + repeated ObjectList object_lists = 1; // The meshgroups to be printed one after another + SettingList global_settings = 2; // The global settings used for the whole print job + repeated Extruder extruders = 3; // The settings sent to each extruder object } message Extruder @@ -37,10 +37,10 @@ message Progress message Layer { int32 id = 1; - float height = 2; - float thickness = 3; + float height = 2; // Z position + float thickness = 3; // height of a single layer - repeated Polygon polygons = 4; + repeated Polygon polygons = 4; // layer data } message Polygon { @@ -56,19 +56,19 @@ message Polygon { MoveCombingType = 8; MoveRetractionType = 9; } - Type type = 1; - bytes points = 2; - float line_width = 3; + Type type = 1; // Type of move + bytes points = 2; // The points of the polygon, or two points if only a line segment (Currently only line segments are used) + float line_width = 3; // The width of the line being laid down } message GCodeLayer { bytes data = 2; } -message ObjectPrintTime { +message ObjectPrintTime { // The print time for the whole print and material estimates for the first extruder int64 id = 1; - float time = 2; - float material_amount = 3; + float time = 2; // Total time estimate + float material_amount = 3; // material used in the first extruder } message SettingList { @@ -76,13 +76,13 @@ message SettingList { } message Setting { - string name = 1; + string name = 1; // Internal key to signify a setting - bytes value = 2; + bytes value = 2; // The value of the setting } message GCodePrefix { - bytes data = 2; + bytes data = 2; // Header string to be prenpended before the rest of the gcode sent from the engine } message SlicingFinished { From d93044a338cc2e9603c6a027c2c29d9813935a52 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 9 Jun 2016 13:04:07 +0200 Subject: [PATCH 575/705] Added setting sending per extruder CURA-1681 --- cura/ExtruderManager.py | 13 ++++++------- cura/ExtrudersModel.py | 2 +- plugins/CuraEngineBackend/StartSliceJob.py | 13 +++++++++++++ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index c8a07a4000..102f7d7fc0 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -187,19 +187,18 @@ class ExtruderManager(QObject): container_registry.addContainer(container_stack) - ## Generates extruders for a specific machine. - def getMachineExtruders(self, machine_definition): + ## Gets extruders for a specific machine. + def getMachineExtruders(self, machine_definition_id): container_registry = UM.Settings.ContainerRegistry.getInstance() - machine_id = machine_definition.getId() - if not machine_id in self._extruder_trains: - UM.Logger.log("w", "Tried to get the extruder trains for machine %s, which doesn't exist.", machine_id) + if not machine_definition_id in self._extruder_trains: + UM.Logger.log("w", "Tried to get the extruder trains for machine %s, which doesn't exist.", machine_definition_id) return - for _,extruder_train_id in self._extruder_trains[machine_id].items(): + for _,extruder_train_id in self._extruder_trains[machine_definition_id].items(): extruder_train = container_registry.findContainerStacks(id = extruder_train_id) if extruder_train: yield extruder_train[0] else: - UM.Logger.log("w", "Machine %s refers to an extruder train with ID %s, which doesn't exist.", machine_id, extruder_train_id) + UM.Logger.log("w", "Machine %s refers to an extruder train with ID %s, which doesn't exist.", machine_definition_id, extruder_train_id) ## Adds the extruders of the currently active machine. def _addCurrentMachineExtruders(self): diff --git a/cura/ExtrudersModel.py b/cura/ExtrudersModel.py index 60bd60abab..1efc86d9c5 100644 --- a/cura/ExtrudersModel.py +++ b/cura/ExtrudersModel.py @@ -51,7 +51,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): global_container_stack = UM.Application.getInstance().getGlobalContainerStack() if not global_container_stack: return #There is no machine to get the extruders of. - for index, extruder in enumerate(manager.getMachineExtruders(global_container_stack.getBottom())): + for index, extruder in enumerate(manager.getMachineExtruders(global_container_stack.getBottom().getId())): material = extruder.findContainer({ "type": "material" }) colour = material.getMetaDataEntry("color_code", default = "#FFFF00") if material else "#FFFF00" item = { #Construct an item with only the relevant information. diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 9a3dc3a263..259750d098 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -15,6 +15,7 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Settings.Validator import ValidatorState from cura.OneAtATimeIterator import OneAtATimeIterator +from cura.ExtruderManager import ExtruderManager class StartJobResult(IntEnum): Finished = 1 @@ -127,6 +128,9 @@ class StartSliceJob(Job): self._buildGlobalSettingsMessage(stack) + for extruder_stack in ExtruderManager.getInstance().getMachineExtruders(stack.getBottom().getId()): + self._buildExtruderMessage(extruder_stack) + for group in object_groups: group_message = self._slice_message.addRepeatedMessage("object_lists") if group[0].getParent().callDecoration("isGroup"): @@ -166,6 +170,15 @@ class StartSliceJob(Job): Logger.logException("w", "Unable to do token replacement on start/end gcode") return str(value).encode("utf-8") + def _buildExtruderMessage(self, stack): + message = self._slice_message.addRepeatedMessage("extruders") + message.id = int(stack.getMetaDataEntry("position")) + for key in stack.getAllKeys(): + setting = message.addRepeatedMessage("settings") + setting.name = key + setting.value = str(stack.getProperty(key, "value")).encode("utf-8") + Job.yieldThread() + ## Sends all global settings to the engine. # # The settings are taken from the global stack. This does not include any From cd803bc36ecbf85ea1846c780dd054fb56362b11 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 9 Jun 2016 13:16:23 +0200 Subject: [PATCH 576/705] Determine readonly state from location in filesystem instead of a metadata property CURA-1684 --- cura/MachineManagerModel.py | 6 +++--- resources/qml/Cura.qml | 4 ++-- resources/qml/Preferences/ProfilesPage.qml | 4 ++-- resources/qml/ProfileSetup.qml | 4 ++-- resources/quality/high.inst.cfg | 1 - resources/quality/low.inst.cfg | 1 - resources/quality/normal.inst.cfg | 1 - .../ultimaker2_extended_plus/um2ep_abs_0.25_normal.inst.cfg | 1 - .../ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg | 1 - .../ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg | 1 - .../ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg | 1 - .../ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg | 1 - .../ultimaker2_extended_plus/um2ep_abs_0.8_normal.inst.cfg | 1 - .../ultimaker2_extended_plus/um2ep_cpe_0.25_normal.inst.cfg | 1 - .../ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg | 1 - .../ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg | 1 - .../ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg | 1 - .../ultimaker2_extended_plus/um2ep_cpe_0.6_normal.inst.cfg | 1 - .../ultimaker2_extended_plus/um2ep_cpe_0.8_normal.inst.cfg | 1 - .../ultimaker2_extended_plus/um2ep_pla_0.25_normal.inst.cfg | 1 - .../ultimaker2_extended_plus/um2ep_pla_0.4_fast.inst.cfg | 1 - .../ultimaker2_extended_plus/um2ep_pla_0.4_high.inst.cfg | 1 - .../ultimaker2_extended_plus/um2ep_pla_0.4_normal.inst.cfg | 1 - .../ultimaker2_extended_plus/um2ep_pla_0.6_normal.inst.cfg | 1 - .../ultimaker2_extended_plus/um2ep_pla_0.8_normal.inst.cfg | 1 - resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg | 1 - resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg | 1 - resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg | 1 - resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg | 1 - resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg | 1 - resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg | 1 - .../quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg | 1 - .../quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg | 1 - .../quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg | 1 - .../quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg | 1 - .../quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg | 1 - .../quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg | 1 - .../quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg | 1 - .../quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg | 1 - .../quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg | 1 - .../quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg | 1 - .../quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg | 1 - .../quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg | 1 - 43 files changed, 9 insertions(+), 48 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index e719c05743..816dbc4600 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -266,7 +266,7 @@ class MachineManagerModel(QObject): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=container_id) if not containers or not self._global_container_stack: return True - return containers[0].getMetaDataEntry("read_only", False) == "True" + return containers[0].isReadOnly() @pyqtSlot(result = str) def convertUserContainerToQuality(self): @@ -288,7 +288,7 @@ class MachineManagerModel(QObject): ## Change type / id / name new_quality_container.setMetaDataEntry("type", "quality") - new_quality_container.setMetaDataEntry("read_only", False) + new_quality_container.setReadOnly(False) new_quality_container.setName(name) new_quality_container._id = name @@ -310,7 +310,7 @@ class MachineManagerModel(QObject): ## Copy all values new_container.deserialize(containers[0].serialize()) - new_container.setMetaDataEntry("read_only", False) + new_container.setReadOnly(False) new_container.setName(new_name) new_container._id = new_name UM.Settings.ContainerRegistry.getInstance().addContainer(new_container) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 46ebc25369..74f5e8bdd8 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -258,13 +258,13 @@ UM.MainWindow { //Insert a separator between readonly and custom profiles if(separatorIndex < 0 && index > 0) { - if(model.getItem(index-1).metadata.read_only != model.getItem(index).metadata.read_only) { + if(model.getItem(index-1).readOnly != model.getItem(index).readOnly) { profileMenu.insertSeparator(index); separatorIndex = index; } } //Because of the separator, custom profiles move one index lower - profileMenu.insertItem((model.getItem(index).metadata.read_only) ? index : index + 1, object.item); + profileMenu.insertItem((model.getItem(index).readOnly) ? index : index + 1, object.item); } onObjectRemoved: { diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index ac57dbba35..a5992a3f8c 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -65,8 +65,8 @@ UM.ManagementPage activateEnabled: currentItem != null ? currentItem.id != Cura.MachineManager.activeQualityId : false; addEnabled: currentItem != null; - removeEnabled: currentItem != null ? !currentItem.metadata.read_only : false; - renameEnabled: currentItem != null ? !currentItem.metadata.read_only : false; + removeEnabled: currentItem != null ? !currentItem.readOnly : false; + renameEnabled: currentItem != null ? !currentItem.readOnly : false; scrollviewCaption: catalog.i18nc("@label %1 is printer name","Printer: %1").arg(Cura.MachineManager.activeMachineName) diff --git a/resources/qml/ProfileSetup.qml b/resources/qml/ProfileSetup.qml index 48d52c539a..a168d87ff1 100644 --- a/resources/qml/ProfileSetup.qml +++ b/resources/qml/ProfileSetup.qml @@ -88,13 +88,13 @@ Item{ { //Insert a separator between readonly and custom profiles if(separatorIndex < 0 && index > 0) { - if(model.getItem(index-1).metadata.read_only != model.getItem(index).metadata.read_only) { + if(model.getItem(index-1).readOnly != model.getItem(index).readOnly) { profileSelectionMenu.insertSeparator(index); separatorIndex = index; } } //Because of the separator, custom profiles move one index lower - profileSelectionMenu.insertItem((model.getItem(index).metadata.read_only) ? index : index + 1, object.item); + profileSelectionMenu.insertItem((model.getItem(index).readOnly) ? index : index + 1, object.item); } onObjectRemoved: { diff --git a/resources/quality/high.inst.cfg b/resources/quality/high.inst.cfg index b2413bba23..b4498c6c8b 100644 --- a/resources/quality/high.inst.cfg +++ b/resources/quality/high.inst.cfg @@ -6,7 +6,6 @@ definition = fdmprinter [metadata] type = quality weight = -3 -read_only = True [values] layer_height = 0.06 diff --git a/resources/quality/low.inst.cfg b/resources/quality/low.inst.cfg index 43ac4ac02d..d34a7c6461 100644 --- a/resources/quality/low.inst.cfg +++ b/resources/quality/low.inst.cfg @@ -6,7 +6,6 @@ definition = fdmprinter [metadata] type = quality weight = -1 -read_only = True [values] infill_sparse_density = 10 diff --git a/resources/quality/normal.inst.cfg b/resources/quality/normal.inst.cfg index df9448097b..417c7c700f 100644 --- a/resources/quality/normal.inst.cfg +++ b/resources/quality/normal.inst.cfg @@ -6,6 +6,5 @@ definition = fdmprinter [metadata] type = quality weight = -2 -read_only = True [values] diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.25_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.25_normal.inst.cfg index 07d3fae601..11b926378d 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.25_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_extended_plus type = quality material = generic_abs_ultimaker2_extended_plus_0.25_mm weight = -2 -read_only = True [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg index 139c8cb976..bdeeb935f4 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_extended_plus type = quality material = generic_abs_ultimaker2_extended_plus_0.4_mm weight = -1 -read_only = True [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg index 8d021f4d91..d658ee5bb5 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_extended_plus type = quality material = generic_abs_ultimaker2_extended_plus_0.4_mm weight = -3 -read_only = True [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg index 3f89bdeee6..ff024ccc69 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_extended_plus type = quality material = generic_abs_ultimaker2_extended_plus_0.4_mm weight = -2 -read_only = True [values] layer_height = 0.1 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg index ea67bcc0b2..c2f4daa86f 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_extended_plus type = quality material = generic_abs_ultimaker2_extended_plus_0.6_mm weight = -2 -read_only = True [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.8_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.8_normal.inst.cfg index 8857db6cc1..362e844214 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.8_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_extended_plus type = quality material = generic_abs_ultimaker2_extended_plus_0.8_mm weight = -2 -read_only = True [values] layer_height = 0.2 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.25_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.25_normal.inst.cfg index d34ea88798..f4d9264d3e 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.25_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_extended_plus type = quality material = generic_cpe_ultimaker2_extended_plus_0.25_mm weight = -2 -read_only = True [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg index 5f402d50aa..f514f22294 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_extended_plus type = quality material = generic_cpe_ultimaker2_extended_plus_0.4_mm weight = -1 -read_only = True [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg index 2b35097f66..0c68be2f5f 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_extended_plus type = quality material = generic_cpe_ultimaker2_extended_plus_0.4_mm weight = -3 -read_only = True [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg index 41e9fab6d3..26ea8ce9bc 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_extended_plus type = quality material = generic_cpe_ultimaker2_extended_plus_0.4_mm weight = -2 -read_only = True [values] layer_height = 0.1 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.6_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.6_normal.inst.cfg index 675c949364..d6d10dbe1a 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.6_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_extended_plus type = quality material = generic_cpe_ultimaker2_extended_plus_0.6_mm weight = -2 -read_only = True [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.8_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.8_normal.inst.cfg index b631baea42..53d5e0bc8c 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.8_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_extended_plus type = quality material = generic_cpe_ultimaker2_extended_plus_0.8_mm weight = -2 -read_only = True [values] layer_height = 0.2 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.25_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.25_normal.inst.cfg index 142ee42b71..5e54b3194a 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.25_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_extended_plus type = quality material = generic_pla_ultimaker2_extended_plus_0.25_mm weight = -2 -read_only = True [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_fast.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_fast.inst.cfg index 8fd8fedf4c..893256bb33 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_fast.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_extended_plus type = quality material = generic_pla_ultimaker2_extended_plus_0.4_mm weight = -1 -read_only = True [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_high.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_high.inst.cfg index 3fc5cb39a0..844e2b3eac 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_high.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_extended_plus type = quality material = generic_pla_ultimaker2_extended_plus_0.4_mm weight = -3 -read_only = True [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_normal.inst.cfg index 94816b233c..47d511446a 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_extended_plus type = quality material = generic_pla_ultimaker2_extended_plus_0.4_mm weight = -2 -read_only = True [values] layer_height = 0.1 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.6_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.6_normal.inst.cfg index 2de9b6a482..a2b15b6f16 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.6_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_extended_plus material = generic_pla_ultimaker2_extended_plus_0.6_mm type = quality weight = -2 -read_only = True [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.8_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.8_normal.inst.cfg index f3a1a14f73..08b5bec667 100644 --- a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.8_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_extended_plus material = generic_pla_ultimaker2_extended_plus_0.8_mm type = quality weight = -2 -read_only = True [values] layer_height = 0.2 diff --git a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg index 7a1da403ff..9a44582610 100644 --- a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_plus type = quality material = generic_pla_ultimaker2_plus_0.25_mm weight = -2 -read_only = True [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg index 48fa105f80..0df882e418 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_plus type = quality material = generic_pla_ultimaker2_plus_0.4_mm weight = -1 -read_only = True [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg index 8024ebe8d9..a8abdb081f 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_plus type = quality material = generic_pla_ultimaker2_plus_0.4_mm weight = -3 -read_only = True [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg index 5205a4d057..c29b017bbe 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_plus type = quality material = generic_pla_ultimaker2_plus_0.4_mm weight = -2 -read_only = True [values] layer_height = 0.1 diff --git a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg index db3e208c8d..5a0a840ae7 100644 --- a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_plus material = generic_pla_ultimaker2_plus_0.6_mm type = quality weight = -2 -read_only = True [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg index 4a52e0ff2c..bd90b8c059 100644 --- a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_plus material = generic_pla_ultimaker2_plus_0.8_mm type = quality weight = -2 -read_only = True [values] layer_height = 0.2 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg index 0b7a371ff1..05a9bce71c 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_plus type = quality material = generic_abs_ultimaker2_plus_0.25_mm weight = -2 -read_only = True [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg index 71f93ffe6f..cd0a25981a 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_plus type = quality material = generic_abs_ultimaker2_plus_0.4_mm weight = -1 -read_only = True [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg index 3ceb8ce198..4b1ece31ef 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_plus type = quality material = generic_abs_ultimaker2_plus_0.4_mm weight = -3 -read_only = True [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg index 762ad08eca..f1b01fd408 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_plus type = quality material = generic_abs_ultimaker2_plus_0.4_mm weight = -2 -read_only = True [values] layer_height = 0.1 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg index ea88fe3616..89e73dda38 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_plus type = quality material = generic_abs_ultimaker2_plus_0.6_mm weight = -2 -read_only = True [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg index d5b9557ebb..2171fd3837 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_plus type = quality material = generic_abs_ultimaker2_plus_0.8_mm weight = -2 -read_only = True [values] layer_height = 0.2 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg index eaab2ff2b6..6a300ba27d 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_plus type = quality material = generic_cpe_ultimaker2_plus_0.25_mm weight = -2 -read_only = True [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg index 25e96fd948..e76c5205f5 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_plus type = quality material = generic_cpe_ultimaker2_plus_0.4_mm weight = -1 -read_only = True [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg index 6680d78195..60f171dc17 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_plus type = quality material = generic_cpe_ultimaker2_plus_0.4_mm weight = -3 -read_only = True [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg index acaedff20a..04116dbe21 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_plus type = quality material = generic_cpe_ultimaker2_plus_0.4_mm weight = -2 -read_only = True [values] layer_height = 0.1 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg index f19032a95e..35e666e6d9 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_plus type = quality material = generic_cpe_ultimaker2_plus_0.6_mm weight = -2 -read_only = True [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg index 45372fdf39..c36d1714a0 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg @@ -7,7 +7,6 @@ definition = ultimaker2_plus type = quality material = generic_cpe_ultimaker2_plus_0.8_mm weight = -2 -read_only = True [values] layer_height = 0.2 From 3df1bc4e62c302721d89974838104c948cea6a0e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 9 Jun 2016 13:23:09 +0200 Subject: [PATCH 577/705] Fixed minor issue in buildExtruderMessage CURA-1681 --- plugins/CuraEngineBackend/StartSliceJob.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 259750d098..3d2eb0ed4a 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -174,7 +174,7 @@ class StartSliceJob(Job): message = self._slice_message.addRepeatedMessage("extruders") message.id = int(stack.getMetaDataEntry("position")) for key in stack.getAllKeys(): - setting = message.addRepeatedMessage("settings") + setting = message.getMessage("settings").addRepeatedMessage("settings") setting.name = key setting.value = str(stack.getProperty(key, "value")).encode("utf-8") Job.yieldThread() From 8729dce531e4b2f8ba655ff03491e2339e4fc9ab Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 9 Jun 2016 13:30:17 +0200 Subject: [PATCH 578/705] Store the actual extruder stack in ExtruderManager instead of just the ID Contributes to CURA-340 --- cura/ExtruderManager.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index c8a07a4000..5c695de1f1 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -36,7 +36,7 @@ class ExtruderManager(QObject): if not UM.Application.getInstance().getGlobalContainerStack(): return None #No active machine, so no active extruder. try: - return self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getBottom().getId()][str(self._active_extruder_index)] + return self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getBottom().getId()][str(self._active_extruder_index)].getId() except KeyError: #Extruder index could be -1 if the global tab is selected, or the entry doesn't exist if the machine definition is wrong. return None @@ -87,7 +87,7 @@ class ExtruderManager(QObject): #Gets the extruder trains that we just created as well as any that still existed. extruder_trains = container_registry.findContainerStacks(type = "extruder_train", machine = machine_definition.getId()) for extruder_train in extruder_trains: - self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train.getId() + self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train if extruder_trains: self.extrudersChanged.emit(machine_definition) @@ -194,15 +194,11 @@ class ExtruderManager(QObject): if not machine_id in self._extruder_trains: UM.Logger.log("w", "Tried to get the extruder trains for machine %s, which doesn't exist.", machine_id) return - for _,extruder_train_id in self._extruder_trains[machine_id].items(): - extruder_train = container_registry.findContainerStacks(id = extruder_train_id) - if extruder_train: - yield extruder_train[0] - else: - UM.Logger.log("w", "Machine %s refers to an extruder train with ID %s, which doesn't exist.", machine_id, extruder_train_id) + for name in self._extruder_trains[machine_id]: + yield self._extruder_trains[machine_id][name] ## Adds the extruders of the currently active machine. def _addCurrentMachineExtruders(self): global_stack = UM.Application.getInstance().getGlobalContainerStack() if global_stack and global_stack.getBottom(): - self.addMachineExtruders(global_stack.getBottom()) \ No newline at end of file + self.addMachineExtruders(global_stack.getBottom()) From 8f4f67d552f2b6993137e9429c4ea53f2949bc78 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 9 Jun 2016 13:41:33 +0200 Subject: [PATCH 579/705] Show "Protected profiles" / "Custom profiles" section on profiles page CURA-855 --- resources/qml/Preferences/ProfilesPage.qml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index a5992a3f8c..2030ced505 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -36,6 +36,22 @@ UM.ManagementPage } } + section.property: "readOnly" + section.delegate: Rectangle + { + width: objectListContainer.viewport.width; + height: childrenRect.height; + color: palette.light + + Label + { + anchors.left: parent.left; + anchors.leftMargin: UM.Theme.getSize("default_lining").width; + text: section == "true" ? catalog.i18nc("@label", "Protected profiles") : catalog.i18nc("@label", "Custom profiles") + font.bold: true + } + } + activeId: Cura.MachineManager.activeQualityId activeIndex: { for(var i = 0; i < model.rowCount(); i++) { From d57e2b2e225fbe851cc0e26d166078df6ae417c3 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 9 Jun 2016 13:46:39 +0200 Subject: [PATCH 580/705] Add an ID role and addGlobal property to ExtrudersModel Contributes to CURA-340 --- cura/ExtrudersModel.py | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/cura/ExtrudersModel.py b/cura/ExtrudersModel.py index 37487f838c..3265667dc6 100644 --- a/cura/ExtrudersModel.py +++ b/cura/ExtrudersModel.py @@ -1,7 +1,7 @@ # Copyright (c) 2016 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. -from PyQt5.QtCore import Qt +from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty import cura.ExtruderManager import UM.Qt.ListModel @@ -12,18 +12,21 @@ import UM.Qt.ListModel # intended for drop-down lists of the current machine's extruders in place of # settings. class ExtrudersModel(UM.Qt.ListModel.ListModel): + # The ID of the container stack for the extruder. + IdRole = Qt.UserRole + 1 + ## Human-readable name of the extruder. - NameRole = Qt.UserRole + 1 + NameRole = Qt.UserRole + 2 ## Colour of the material loaded in the extruder. - ColourRole = Qt.UserRole + 2 + ColourRole = Qt.UserRole + 3 ## Index of the extruder, which is also the value of the setting itself. # # An index of 0 indicates the first extruder, an index of 1 the second # one, and so on. This is the value that will be saved in instance # containers. - IndexRole = Qt.UserRole + 3 + IndexRole = Qt.UserRole + 4 ## Initialises the extruders model, defining the roles and listening for # changes in the data. @@ -32,16 +35,30 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): def __init__(self, parent = None): super().__init__(parent) + self.addRoleName(self.IdRole, "id") self.addRoleName(self.NameRole, "name") self.addRoleName(self.ColourRole, "colour") self.addRoleName(self.IndexRole, "index") + self._add_global = False + #Listen to changes. manager = cura.ExtruderManager.ExtruderManager.getInstance() manager.extrudersChanged.connect(self._updateExtruders) #When the list of extruders changes in general. UM.Application.globalContainerStackChanged.connect(self._updateExtruders) #When the current machine changes. self._updateExtruders() + def setAddGlobal(self, add): + if add != self._add_global: + self._add_global = add + self._updateExtruders() + self.addGlobalChanged.emit() + + addGlobalChanged = pyqtSignal() + @pyqtProperty(bool, fset = setAddGlobal, notify = addGlobalChanged) + def addGlobal(self): + return self._add_global + ## Update the list of extruders. # # This should be called whenever the list of extruders changes. @@ -51,6 +68,18 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): global_container_stack = UM.Application.getInstance().getGlobalContainerStack() if not global_container_stack: return #There is no machine to get the extruders of. + + if self._add_global: + material = global_container_stack.findContainer({ "type": "material" }) + colour = material.getMetaDataEntry("color_code", default = "#FFFF00") if material else "#FFFF00" + item = { + "id": global_container_stack.getId(), + "name": "Global", + "colour": colour, + "index": -1 + } + self.appendItem(item) + for extruder in manager.getMachineExtruders(global_container_stack.getBottom()): material = extruder.findContainer({ "type": "material" }) colour = material.getMetaDataEntry("color_code", default = "#FFFF00") if material else "#FFFF00" @@ -60,9 +89,11 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): except ValueError: #Not a proper int. position = -1 item = { #Construct an item with only the relevant information. + "id": extruder.getId(), "name": extruder.getName(), "colour": colour, "index": position } self.appendItem(item) - self.sort(lambda item: item["index"]) \ No newline at end of file + + self.sort(lambda item: item["index"]) From c03588c6e576f3e164f5b28baf848b8072e2e78c Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Wed, 8 Jun 2016 14:40:10 +0200 Subject: [PATCH 581/705] Profile export now goes via the plugin system, and does the same filename checks as before. Contributed to CURA-1667 Profile import/export --- cura/CuraApplication.py | 4 ++++ plugins/CuraProfileReader/CuraProfileReader.py | 1 - plugins/CuraProfileReader/__init__.py | 2 +- plugins/CuraProfileWriter/CuraProfileWriter.py | 4 ++-- plugins/CuraProfileWriter/__init__.py | 2 +- resources/qml/Preferences/ProfilesPage.qml | 2 +- 6 files changed, 9 insertions(+), 6 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index a2415478a4..12828971cd 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -294,6 +294,7 @@ class CuraApplication(QtApplication): # \sa PluginRegistery def _loadPlugins(self): self._plugin_registry.addType("profile_reader", self._addProfileReader) + self._plugin_registry.addType("profile_writer", self._addProfileWriter) self._plugin_registry.addPluginLocation(os.path.join(QtApplication.getInstallPrefix(), "lib", "cura")) if not hasattr(sys, "frozen"): self._plugin_registry.addPluginLocation(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "plugins")) @@ -788,3 +789,6 @@ class CuraApplication(QtApplication): def _addProfileReader(self, profile_reader): # TODO: Add the profile reader to the list of plug-ins that can be used when importing profiles. pass + + def _addProfileWriter(self, profile_writer): + pass diff --git a/plugins/CuraProfileReader/CuraProfileReader.py b/plugins/CuraProfileReader/CuraProfileReader.py index 1d27649498..c9b4e60046 100644 --- a/plugins/CuraProfileReader/CuraProfileReader.py +++ b/plugins/CuraProfileReader/CuraProfileReader.py @@ -3,7 +3,6 @@ from UM.Application import Application #To get the machine manager to create the new profile in. from UM.Logger import Logger -from UM.Settings.Profile import Profile from UM.Settings.ProfileReader import ProfileReader diff --git a/plugins/CuraProfileReader/__init__.py b/plugins/CuraProfileReader/__init__.py index bfaa16ed5e..c4206ab763 100644 --- a/plugins/CuraProfileReader/__init__.py +++ b/plugins/CuraProfileReader/__init__.py @@ -13,7 +13,7 @@ def getMetaData(): "author": "Ultimaker", "version": "1.0", "description": catalog.i18nc("@info:whatsthis", "Provides support for importing Cura profiles."), - "api": 2 + "api": 3 }, "profile_reader": [ { diff --git a/plugins/CuraProfileWriter/CuraProfileWriter.py b/plugins/CuraProfileWriter/CuraProfileWriter.py index 82df446b8a..c6c4244948 100644 --- a/plugins/CuraProfileWriter/CuraProfileWriter.py +++ b/plugins/CuraProfileWriter/CuraProfileWriter.py @@ -16,10 +16,10 @@ class CuraProfileWriter(ProfileWriter): # \return \code True \endcode if the writing was successful, or \code # False \endcode if it wasn't. def write(self, path, profile): - serialised = profile.serialise() + serialized = profile.serialize() try: with SaveFile(path, "wt", -1, "utf-8") as f: # Open the specified file. - f.write(serialised) + f.write(serialized) except Exception as e: Logger.log("e", "Failed to write profile to %s: %s", path, str(e)) return False diff --git a/plugins/CuraProfileWriter/__init__.py b/plugins/CuraProfileWriter/__init__.py index 43890de469..30528b8167 100644 --- a/plugins/CuraProfileWriter/__init__.py +++ b/plugins/CuraProfileWriter/__init__.py @@ -13,7 +13,7 @@ def getMetaData(): "author": "Ultimaker", "version": "1.0", "description": catalog.i18nc("@info:whatsthis", "Provides support for exporting Cura profiles."), - "api": 2 + "api": 3 }, "profile_writer": [ { diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 2030ced505..b382065a7e 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -299,7 +299,7 @@ UM.ManagementPage folder: base.model.getDefaultPath() onAccepted: { - var result = base.model.exportProfile(base.currentItem.id, fileUrl) + var result = base.model.exportProfile(base.currentItem.id, fileUrl, selectedNameFilter) if(result && result.status == "error") { messageDialog.icon = StandardIcon.Critical From 97d64a0749633606e57ed2d566bbadcc96d4dc00 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Wed, 8 Jun 2016 15:36:26 +0200 Subject: [PATCH 582/705] Move ProfileReader and ProfileWriter over to Cura itself. Contributes to CURA-1667 Profile import/export --- cura/ProfileWriter.py | 25 +++++++++++++++++++ .../CuraProfileReader/CuraProfileReader.py | 7 +++--- .../CuraProfileWriter/CuraProfileWriter.py | 2 +- 3 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 cura/ProfileWriter.py diff --git a/cura/ProfileWriter.py b/cura/ProfileWriter.py new file mode 100644 index 0000000000..6c719205ec --- /dev/null +++ b/cura/ProfileWriter.py @@ -0,0 +1,25 @@ +# Copyright (c) 2015 Ultimaker B.V. +# Uranium is released under the terms of the AGPLv3 or higher. + +from UM.PluginObject import PluginObject + +## Base class for profile writer plugins. +# +# This class defines a write() function to write profiles to files with. +class ProfileWriter(PluginObject): + ## Initialises the profile writer. + # + # This currently doesn't do anything since the writer is basically static. + def __init__(self): + super().__init__() + + ## Writes a profile to the specified file path. + # + # The profile writer may write its own file format to the specified file. + # + # \param path \type{string} The file to output to. + # \param profile \type{Profile} The profile to write to the file. + # \return \code True \endcode if the writing was successful, or \code + # False \endcode if it wasn't. + def write(self, path, node): + raise NotImplementedError("Profile writer plugin was not correctly implemented. No write was specified.") diff --git a/plugins/CuraProfileReader/CuraProfileReader.py b/plugins/CuraProfileReader/CuraProfileReader.py index c9b4e60046..9ff2955b22 100644 --- a/plugins/CuraProfileReader/CuraProfileReader.py +++ b/plugins/CuraProfileReader/CuraProfileReader.py @@ -3,7 +3,7 @@ from UM.Application import Application #To get the machine manager to create the new profile in. from UM.Logger import Logger -from UM.Settings.ProfileReader import ProfileReader +from cura.ProfileReader import ProfileReader ## A plugin that reads profile data from Cura profile files. @@ -25,16 +25,15 @@ class CuraProfileReader(ProfileReader): def read(self, file_name): # Create an empty profile. profile = Profile(machine_manager = Application.getInstance().getMachineManager(), read_only = False) - serialised = "" try: with open(file_name) as f: # Open file for reading. - serialised = f.read() + serialized = f.read() except IOError as e: Logger.log("e", "Unable to open file %s for reading: %s", file_name, str(e)) return None try: - profile.unserialise(serialised) + profile.deserialize(serialized) except Exception as e: # Parsing error. This is not a (valid) Cura profile then. Logger.log("e", "Error while trying to parse profile: %s", str(e)) return None diff --git a/plugins/CuraProfileWriter/CuraProfileWriter.py b/plugins/CuraProfileWriter/CuraProfileWriter.py index c6c4244948..86b4f7dc89 100644 --- a/plugins/CuraProfileWriter/CuraProfileWriter.py +++ b/plugins/CuraProfileWriter/CuraProfileWriter.py @@ -4,7 +4,7 @@ from UM.Logger import Logger from UM.SaveFile import SaveFile -from UM.Settings.ProfileWriter import ProfileWriter +from cura.ProfileWriter import ProfileWriter ## Writes profiles to Cura's own profile format with config files. From b93137545f8db44383985ddf02c7b2a8500afd04 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Thu, 9 Jun 2016 14:14:09 +0200 Subject: [PATCH 583/705] Support for importing a profile. Contributes to CURA-1667 Profile import/export --- plugins/CuraProfileReader/CuraProfileReader.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/CuraProfileReader/CuraProfileReader.py b/plugins/CuraProfileReader/CuraProfileReader.py index 9ff2955b22..b9c1f208ea 100644 --- a/plugins/CuraProfileReader/CuraProfileReader.py +++ b/plugins/CuraProfileReader/CuraProfileReader.py @@ -1,11 +1,13 @@ # Copyright (c) 2015 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. +import os.path + from UM.Application import Application #To get the machine manager to create the new profile in. from UM.Logger import Logger +from UM.Settings.InstanceContainer import InstanceContainer #The new profile to make. from cura.ProfileReader import ProfileReader - ## A plugin that reads profile data from Cura profile files. # # It reads a profile from a .curaprofile file, and returns it as a profile @@ -24,7 +26,8 @@ class CuraProfileReader(ProfileReader): # returned. def read(self, file_name): # Create an empty profile. - profile = Profile(machine_manager = Application.getInstance().getMachineManager(), read_only = False) + profile = InstanceContainer(os.path.basename(os.path.splitext(file_name)[0])) + profile.addMetaDataEntry("type", "quality") try: with open(file_name) as f: # Open file for reading. serialized = f.read() From 725086b0dd10085ab9f25e5b1aa6814cb28ad6be Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 9 Jun 2016 14:31:32 +0200 Subject: [PATCH 584/705] Remove ProfileSetup and move its contents to SidebaarHeader Contributes to CURA-340 --- resources/qml/ProfileSetup.qml | 166 -------------------------------- resources/qml/Sidebar.qml | 16 +-- resources/qml/SidebarHeader.qml | 153 +++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+), 180 deletions(-) delete mode 100644 resources/qml/ProfileSetup.qml diff --git a/resources/qml/ProfileSetup.qml b/resources/qml/ProfileSetup.qml deleted file mode 100644 index a168d87ff1..0000000000 --- a/resources/qml/ProfileSetup.qml +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright (c) 2015 Ultimaker B.V. -// Cura is released under the terms of the AGPLv3 or higher. - -import QtQuick 2.2 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 -import QtQuick.Layouts 1.1 - -import UM 1.2 as UM -import Cura 1.0 as Cura - -Item{ - id: base; - UM.I18nCatalog { id: catalog; name:"cura"} - property int totalHeightProfileSetup: childrenRect.height - property Action manageProfilesAction - property Action addProfileAction - property Action updateProfileAction - property Action resetProfileAction - - signal showTooltip(Item item, point location, string text) - signal hideTooltip() - - Rectangle{ - id: globalProfileRow - anchors.top: base.top - height: UM.Theme.getSize("sidebar_setup").height - width: base.width - - Label{ - id: globalProfileLabel - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width; - anchors.verticalCenter: parent.verticalCenter - text: catalog.i18nc("@label","Profile:"); - width: parent.width/100*45 - font: UM.Theme.getFont("default"); - color: UM.Theme.getColor("text"); - } - - ToolButton { - property int rightMargin: customisedSettings.visible ? customisedSettings.width + UM.Theme.getSize("default_margin").width / 2 : 0 - - id: globalProfileSelection - text: Cura.MachineManager.activeQualityName - width: parent.width/100*55 - height: UM.Theme.getSize("setting_control").height - anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("default_margin").width - anchors.verticalCenter: parent.verticalCenter - tooltip: Cura.MachineManager.activeQualityName - style: UM.Theme.styles.sidebar_header_button - - menu: Menu - { - id: profileSelectionMenu - Instantiator - { - id: profileSelectionInstantiator - model: UM.InstanceContainersModel - { - filter: - { - var result = { "type": "quality" }; - if(Cura.MachineManager.filterQualityByMachine) - { - result.definition = Cura.MachineManager.activeDefinitionId; - if(Cura.MachineManager.hasMaterials) - { - result.material = Cura.MachineManager.activeMaterialId; - } - } - else - { - result.definition = "fdmprinter" - } - return result - } - } - property int separatorIndex: -1 - - Loader { - property QtObject model_data: model - property int model_index: index - sourceComponent: menuItemDelegate - } - onObjectAdded: - { - //Insert a separator between readonly and custom profiles - if(separatorIndex < 0 && index > 0) { - if(model.getItem(index-1).readOnly != model.getItem(index).readOnly) { - profileSelectionMenu.insertSeparator(index); - separatorIndex = index; - } - } - //Because of the separator, custom profiles move one index lower - profileSelectionMenu.insertItem((model.getItem(index).readOnly) ? index : index + 1, object.item); - } - onObjectRemoved: - { - //When adding a profile, the menu is rebuild by removing all items. - //If a separator was added, we need to remove that too. - if(separatorIndex >= 0) - { - profileSelectionMenu.removeItem(profileSelectionMenu.items[separatorIndex]) - separatorIndex = -1; - } - profileSelectionMenu.removeItem(object.item); - } - } - ExclusiveGroup { id: profileSelectionMenuGroup; } - - Component - { - id: menuItemDelegate - MenuItem - { - id: item - text: model_data ? model_data.name : "" - checkable: true - checked: Cura.MachineManager.activeQualityId == model_data.id - exclusiveGroup: profileSelectionMenuGroup; - onTriggered: Cura.MachineManager.setActiveQuality(model_data.id) - } - } - - MenuSeparator { } - MenuItem { - action: base.updateProfileAction; - } - MenuItem { - action: base.resetProfileAction; - } - MenuItem { - action: base.addProfileAction; - } - MenuSeparator { } - MenuItem { - action: base.manageProfilesAction; - } - } - } - UM.SimpleButton { - id: customisedSettings - - visible: Cura.MachineManager.hasUserSettings - height: parent.height * 0.6 - width: parent.height * 0.6 - - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("setting_preferences_button_margin").width - - color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button"); - iconSource: UM.Theme.getIcon("star"); - - onClicked: base.manageProfilesAction.trigger() - onEntered: - { - var content = catalog.i18nc("@tooltip","Some setting values are different from the values stored in the profile.\n\nClick to open the profile manager.") - base.showTooltip(globalProfileRow, Qt.point(0, globalProfileRow.height / 2), content) - } - onExited: base.hideTooltip() - } - } -} diff --git a/resources/qml/Sidebar.qml b/resources/qml/Sidebar.qml index 4109fd1586..29814ca42e 100644 --- a/resources/qml/Sidebar.qml +++ b/resources/qml/Sidebar.qml @@ -52,20 +52,8 @@ Rectangle width: parent.width height: totalHeightHeader - addMachineAction: base.addMachineAction; - configureMachinesAction: base.configureMachinesAction; - } - - ProfileSetup { - id: profileItem - addProfileAction: base.addProfileAction - updateProfileAction: base.updateProfileAction - resetProfileAction: base.resetProfileAction - manageProfilesAction: base.manageProfilesAction - anchors.top: header.bottom + anchors.top: parent.top anchors.topMargin: UM.Theme.getSize("default_margin").height - width: parent.width - height: totalHeightProfileSetup onShowTooltip: base.showTooltip(item, location, text) onHideTooltip: base.hideTooltip() @@ -76,7 +64,7 @@ Rectangle width: parent.width height: UM.Theme.getSize("sidebar_lining").height color: UM.Theme.getColor("sidebar_lining") - anchors.top: profileItem.bottom + anchors.top: header.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height } diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 60f5af2e73..83daf00be0 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -296,6 +296,159 @@ Item } } + Row + { + id: globalProfileRow + height: UM.Theme.getSize("sidebar_setup").height + + anchors + { + left: parent.left + leftMargin: UM.Theme.getSize("default_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width + } + + + Label + { + id: globalProfileLabel + text: catalog.i18nc("@label","Profile:"); + width: parent.width * 0.45 - UM.Theme.getSize("default_margin").width + font: UM.Theme.getFont("default"); + color: UM.Theme.getColor("text"); + } + + ToolButton + { + id: globalProfileSelection + text: Cura.MachineManager.activeQualityName + width: parent.width * 0.55 + UM.Theme.getSize("default_margin").width + height: UM.Theme.getSize("setting_control").height + tooltip: Cura.MachineManager.activeQualityName + style: UM.Theme.styles.sidebar_header_button + + menu: Menu + { + id: profileSelectionMenu + Instantiator + { + id: profileSelectionInstantiator + model: UM.InstanceContainersModel + { + filter: + { + var result = { "type": "quality" }; + if(Cura.MachineManager.filterQualityByMachine) + { + result.definition = Cura.MachineManager.activeDefinitionId; + if(Cura.MachineManager.hasMaterials) + { + result.material = Cura.MachineManager.activeMaterialId; + } + } + else + { + result.definition = "fdmprinter" + } + return result + } + } + property int separatorIndex: -1 + + Loader { + property QtObject model_data: model + property int model_index: index + sourceComponent: menuItemDelegate + } + onObjectAdded: + { + //Insert a separator between readonly and custom profiles + if(separatorIndex < 0 && index > 0) + { + if(model.getItem(index-1).readOnly != model.getItem(index).metadata.read_only) + { + profileSelectionMenu.insertSeparator(index); + separatorIndex = index; + } + } + //Because of the separator, custom profiles move one index lower + profileSelectionMenu.insertItem((model.getItem(index).readOnly) ? index : index + 1, object.item); + } + onObjectRemoved: + { + //When adding a profile, the menu is rebuild by removing all items. + //If a separator was added, we need to remove that too. + if(separatorIndex >= 0) + { + profileSelectionMenu.removeItem(profileSelectionMenu.items[separatorIndex]) + separatorIndex = -1; + } + profileSelectionMenu.removeItem(object.item); + } + } + ExclusiveGroup { id: profileSelectionMenuGroup; } + + Component + { + id: menuItemDelegate + MenuItem + { + id: item + text: model_data ? model_data.name : "" + checkable: true + checked: model_data != null ? Cura.MachineManager.activeQualityId == model_data.id : false + exclusiveGroup: profileSelectionMenuGroup; + onTriggered: Cura.MachineManager.setActiveQuality(model_data.id) + } + } + + MenuSeparator { } + MenuItem + { + action: Cura.Actions.updateProfile; + } + MenuItem + { + action: Cura.Actions.resetProfile; + } + MenuItem + { + action: Cura.Actions.addProfile; + } + MenuSeparator { } + MenuItem + { + action: Cura.Actions.manageProfiles; + } + } + + UM.SimpleButton + { + id: customisedSettings + + visible: Cura.MachineManager.hasUserSettings + height: parent.height * 0.6 + width: parent.height * 0.6 + + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("setting_preferences_button_margin").width + + color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button"); + iconSource: UM.Theme.getIcon("star"); + + onClicked: base.manageProfilesAction.trigger() + onEntered: + { + var content = catalog.i18nc("@tooltip","Some setting values are different from the values stored in the profile.\n\nClick to open the profile manager.") + base.showTooltip(globalProfileRow, Qt.point(0, globalProfileRow.height / 2), content) + } + onExited: base.hideTooltip() + } + } + } + UM.SettingPropertyProvider { id: machineExtruderCount From 88d87e8e8558dcd840cd3d2e5f8768e8ed83c9c9 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 9 Jun 2016 14:31:56 +0200 Subject: [PATCH 585/705] Cleanup sidebarheader and fix extruder selection Contributes to CURA-340 --- resources/qml/SidebarHeader.qml | 225 ++++++++++++++++---------------- 1 file changed, 113 insertions(+), 112 deletions(-) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 83daf00be0..f1c0bf7d8b 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -8,54 +8,54 @@ import QtQuick.Controls.Styles 1.1 import UM 1.2 as UM import Cura 1.0 as Cura -Item +Column { id: base; - // Machine Setup - property Action addMachineAction; - property Action configureMachinesAction; - UM.I18nCatalog { id: catalog; name:"cura"} + property int totalHeightHeader: childrenRect.height property int currentExtruderIndex; - Rectangle { - id: sidebarTabRow - width: base.width - height: 0 - anchors.top: parent.top - color: UM.Theme.getColor("sidebar_header_bar") - } + spacing: UM.Theme.getSize("default_margin").height - Rectangle { + signal showTooltip(Item item, point location, string text) + signal hideTooltip() + + Row + { id: machineSelectionRow - width: base.width height: UM.Theme.getSize("sidebar_setup").height - anchors.top: sidebarTabRow.bottom - anchors.topMargin: UM.Theme.getSize("default_margin").height - anchors.horizontalCenter: parent.horizontalCenter - Label{ + anchors + { + left: parent.left + leftMargin: UM.Theme.getSize("default_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width + } + + Label + { id: machineSelectionLabel - //: Machine selection label - text: catalog.i18nc("@label:listbox","Printer:"); - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width + text: catalog.i18nc("@label:listbox", "Printer:"); anchors.verticalCenter: parent.verticalCenter font: UM.Theme.getFont("default"); color: UM.Theme.getColor("text"); + + width: parent.width * 0.45 - UM.Theme.getSize("default_margin").width } - ToolButton { + ToolButton + { id: machineSelection text: Cura.MachineManager.activeMachineName; - width: parent.width/100*55 + height: UM.Theme.getSize("setting_control").height tooltip: Cura.MachineManager.activeMachineName; - anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("default_margin").width anchors.verticalCenter: parent.verticalCenter style: UM.Theme.styles.sidebar_header_button + width: parent.width * 0.55 + UM.Theme.getSize("default_margin").width + menu: Menu { id: machineSelectionMenu @@ -81,103 +81,116 @@ Item MenuSeparator { } - MenuItem { action: base.addMachineAction; } - MenuItem { action: base.configureMachinesAction; } + MenuItem { action: Cura.Actions.addMachine; } + MenuItem { action: Cura.Actions.configureMachines; } } } } - Rectangle { - id: extruderSelection - width: parent.width/100*55 + ListView + { + id: extrudersList + property var index: 0 + visible: machineExtruderCount.properties.value > 1 - height: visible ? UM.Theme.getSize("sidebar_header_mode_toggle").height : 0 - anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("default_margin").width - anchors.top: machineSelectionRow.bottom - anchors.topMargin: visible ? UM.Theme.getSize("default_margin").height : 0 - Component{ - id: wizardDelegate - Button { - height: extruderSelection.height - anchors.left: parent.left - anchors.leftMargin: model.index * (extruderSelection.width / machineExtruderCount.properties.value) - anchors.verticalCenter: parent.verticalCenter - width: parent.width / machineExtruderCount.properties.value - text: model.name - exclusiveGroup: extruderMenuGroup; - checkable: true; - checked: base.currentExtruderIndex == index - onClicked: - { - extruderSelection.focus = true; //Changing focus applies the currently-being-typed values so it can change the displayed setting values. - base.currentExtruderIndex = index; - ExtruderManager.setActiveExtruderIndex(index); - } + height: UM.Theme.getSize("sidebar_header_mode_toggle").height - style: ButtonStyle { - background: Rectangle { - border.width: UM.Theme.getSize("default_lining").width - border.color: control.checked ? UM.Theme.getColor("toggle_checked_border") : - control.pressed ? UM.Theme.getColor("toggle_active_border") : - control.hovered ? UM.Theme.getColor("toggle_hovered_border") : UM.Theme.getColor("toggle_unchecked_border") - color: control.checked ? UM.Theme.getColor("toggle_checked") : - control.pressed ? UM.Theme.getColor("toggle_active") : - control.hovered ? UM.Theme.getColor("toggle_hovered") : UM.Theme.getColor("toggle_unchecked") - Behavior on color { ColorAnimation { duration: 50; } } - Label { - anchors.centerIn: parent - color: control.checked ? UM.Theme.getColor("toggle_checked_text") : - control.pressed ? UM.Theme.getColor("toggle_active_text") : - control.hovered ? UM.Theme.getColor("toggle_hovered_text") : UM.Theme.getColor("toggle_unchecked_text") - font: UM.Theme.getFont("default") - text: control.text; - } - } - label: Item { } - } - } - } - ExclusiveGroup { id: extruderMenuGroup; } - ListView + boundsBehavior: Flickable.StopAtBounds + + anchors { - id: extrudersList - property var index: 0 - model: Cura.ExtrudersModel {} - delegate: wizardDelegate - anchors.top: parent.top - anchors.left: parent.left - width: parent.width + left: parent.left + leftMargin: UM.Theme.getSize("default_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width + } + + ExclusiveGroup { id: extruderMenuGroup; } + + orientation: ListView.Horizontal + + model: Cura.ExtrudersModel { id: extrudersModel; addGlobal: true } + + delegate: Button + { + height: ListView.view.height + width: ListView.view.width / extrudersModel.rowCount() + + text: model.name + exclusiveGroup: extruderMenuGroup; + checkable: true; + checked: base.currentExtruderIndex == index + + onClicked: + { + extruderSelection.focus = true; //Changing focus applies the currently-being-typed values so it can change the displayed setting values. + base.currentExtruderIndex = index; + ExtruderManager.setActiveExtruderIndex(index); + } + + Component.onCompleted: console.log(model.name); + + style: ButtonStyle + { + background: Rectangle + { + border.width: UM.Theme.getSize("default_lining").width + border.color: control.checked ? UM.Theme.getColor("toggle_checked_border") : + control.pressed ? UM.Theme.getColor("toggle_active_border") : + control.hovered ? UM.Theme.getColor("toggle_hovered_border") : UM.Theme.getColor("toggle_unchecked_border") + color: control.checked ? UM.Theme.getColor("toggle_checked") : + control.pressed ? UM.Theme.getColor("toggle_active") : + control.hovered ? UM.Theme.getColor("toggle_hovered") : UM.Theme.getColor("toggle_unchecked") + Behavior on color { ColorAnimation { duration: 50; } } + + Label + { + anchors.centerIn: parent + color: control.checked ? UM.Theme.getColor("toggle_checked_text") : + control.pressed ? UM.Theme.getColor("toggle_active_text") : + control.hovered ? UM.Theme.getColor("toggle_hovered_text") : UM.Theme.getColor("toggle_unchecked_text") + + font: UM.Theme.getFont("default") + text: control.text; + } + } + label: Item { } + } } } - Rectangle { + Row + { id: variantRow - anchors.top: extruderSelection.visible ? extruderSelection.bottom : machineSelectionRow.bottom - anchors.topMargin: visible ? UM.Theme.getSize("default_margin").height : 0 - width: base.width - height: visible ? UM.Theme.getSize("sidebar_setup").height : 0 + + height: UM.Theme.getSize("sidebar_setup").height visible: Cura.MachineManager.hasVariants || Cura.MachineManager.hasMaterials - Label{ + anchors + { + left: parent.left + leftMargin: UM.Theme.getSize("default_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width + } + + Label + { id: variantLabel text: (Cura.MachineManager.hasVariants && Cura.MachineManager.hasMaterials) ? catalog.i18nc("@label","Nozzle & Material:"): Cura.MachineManager.hasVariants ? catalog.i18nc("@label","Nozzle:") : catalog.i18nc("@label","Material:"); - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width + anchors.verticalCenter: parent.verticalCenter - width: parent.width/100*45 + width: parent.width * 0.45 - UM.Theme.getSize("default_margin").width font: UM.Theme.getFont("default"); color: UM.Theme.getColor("text"); } Rectangle { - anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("default_margin").width anchors.verticalCenter: parent.verticalCenter - width: parent.width/100*55 + width: parent.width * 0.55 + UM.Theme.getSize("default_margin").width height: UM.Theme.getSize("setting_control").height ToolButton { @@ -214,13 +227,6 @@ Item onTriggered: { Cura.MachineManager.setActiveVariant(model.id); - /*if (typeof(model) !== "undefined" && !model.active) { - //Selecting a variant was canceled; undo menu selection - variantSelectionInstantiator.model.setProperty(index, "active", false); - var activeMachineVariantName = UM.MachineManager.activeMachineVariant; - var activeMachineVariantIndex = variantSelectionInstantiator.model.find("name", activeMachineVariantName); - variantSelectionInstantiator.model.setProperty(activeMachineVariantIndex, "active", true); - }*/ } } onObjectAdded: variantsSelectionMenu.insertItem(index, object) @@ -277,13 +283,6 @@ Item onTriggered: { Cura.MachineManager.setActiveMaterial(model.id); - /*if (typeof(model) !== "undefined" && !model.active) { - //Selecting a material was canceled; undo menu selection - materialSelectionInstantiator.model.setProperty(index, "active", false); - var activeMaterialName = Cura.MachineManager.activeMaterialName - var activeMaterialIndex = materialSelectionInstantiator.model.find("name", activeMaterialName); - materialSelectionInstantiator.model.setProperty(activeMaterialIndex, "active", true); - }*/ } } onObjectAdded: materialSelectionMenu.insertItem(index, object) @@ -458,4 +457,6 @@ Item watchedProperties: [ "value" ] storeIndex: 0 } + + UM.I18nCatalog { id: catalog; name:"cura" } } From 4a43b50b7a99b4dce6d72826eca23e772ee7255b Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 9 Jun 2016 14:59:32 +0200 Subject: [PATCH 586/705] Remove unused action properties from Sidebar --- resources/qml/Cura.qml | 7 ------- resources/qml/Sidebar.qml | 7 ------- 2 files changed, 14 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 74f5e8bdd8..a1023d8ef2 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -533,13 +533,6 @@ UM.MainWindow } width: UM.Theme.getSize("sidebar").width; - - addMachineAction: Cura.Actions.addMachine; - configureMachinesAction: Cura.Actions.configureMachines; - addProfileAction: Cura.Actions.addProfile; - updateProfileAction: Cura.Actions.updateProfile; - resetProfileAction: Cura.Actions.resetProfile; - manageProfilesAction: Cura.Actions.manageProfiles; } } } diff --git a/resources/qml/Sidebar.qml b/resources/qml/Sidebar.qml index 29814ca42e..b7ff0743de 100644 --- a/resources/qml/Sidebar.qml +++ b/resources/qml/Sidebar.qml @@ -12,13 +12,6 @@ Rectangle { id: base; - property Action addMachineAction; - property Action configureMachinesAction; - property Action addProfileAction; - property Action updateProfileAction; - property Action resetProfileAction; - property Action manageProfilesAction; - property Action configureSettingsAction; property int currentModeIndex; color: UM.Theme.getColor("sidebar"); From 3a75e1fb795740398d668ba0c3bacbce2b0e456b Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 9 Jun 2016 15:12:37 +0200 Subject: [PATCH 587/705] Fix setting the active extruder Contributes to CURA-340 --- resources/qml/SidebarHeader.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index f1c0bf7d8b..7d7161256a 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -123,7 +123,7 @@ Column onClicked: { - extruderSelection.focus = true; //Changing focus applies the currently-being-typed values so it can change the displayed setting values. + focus = true; //Changing focus applies the currently-being-typed values so it can change the displayed setting values. base.currentExtruderIndex = index; ExtruderManager.setActiveExtruderIndex(index); } From abf634c0b0ed7cac37be69ba4d44e08e3977f190 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 9 Jun 2016 15:14:32 +0200 Subject: [PATCH 588/705] Filter visible settings based on if they can be set per extruder Contributes to CURA-340 --- resources/qml/Settings/SettingView.qml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index a6bb60f865..d1ddb12e34 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -31,6 +31,15 @@ ScrollView containerId: Cura.MachineManager.activeDefinitionId exclude: ["machine_settings"] visibilityHandler: UM.SettingPreferenceVisibilityHandler { } + + filter: + { + if(ExtruderManager.activeExtruderStackId) + { + return { "settable_per_extruder": true } + } + return { } + } } delegate: Loader From 98c9f202a293d7409b36865ca61d2ad096000e4c Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 9 Jun 2016 15:32:41 +0200 Subject: [PATCH 589/705] Do not produce an error when a setting has been filtered out Contributes to CURA-340 --- resources/qml/Settings/SettingView.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index d1ddb12e34..4be2326b0a 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -91,7 +91,7 @@ ScrollView id: provider containerStackId: ExtruderManager.activeExtruderStackId ? ExtruderManager.activeExtruderStackId : Cura.MachineManager.activeMachineId - key: model.key + key: model.key ? model.key : "" watchedProperties: [ "value", "enabled", "state", "validationState" ] storeIndex: 0 } From 90ddff1c7ffe8e5c0b4624275d75b5ec9a49f8c7 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 9 Jun 2016 15:35:37 +0200 Subject: [PATCH 590/705] Remove obsolete debug statement Contributes to 1685 --- resources/qml/SidebarHeader.qml | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 7d7161256a..db9b580907 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -128,8 +128,6 @@ Column ExtruderManager.setActiveExtruderIndex(index); } - Component.onCompleted: console.log(model.name); - style: ButtonStyle { background: Rectangle From 12a7b99cf7c7aa6a21c40e8279c3334886ab55ca Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 9 Jun 2016 15:43:18 +0200 Subject: [PATCH 591/705] fix: merge b3cfa62 went wrong, no slicing happened (CURA-1558) --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 12828971cd..15c41f9c56 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -97,7 +97,7 @@ class CuraApplication(QtApplication): SettingDefinition.addSupportedProperty("settable_per_extruder", DefinitionPropertyType.Any, default = True) SettingDefinition.addSupportedProperty("settable_per_meshgroup", DefinitionPropertyType.Any, default = True) SettingDefinition.addSupportedProperty("settable_globally", DefinitionPropertyType.Any, default = True) - SettingDefinition.addSettingType("extruder", str, ast.literal_eval, UM.Settings.Validator) + SettingDefinition.addSettingType("extruder", int, str, UM.Settings.Validator) super().__init__(name = "cura", version = CuraVersion, buildtype = CuraBuildType) From bd76c3e30f68560fc8d1bc821e6f488a9978f61d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 9 Jun 2016 15:46:22 +0200 Subject: [PATCH 592/705] Add drop-down in per-object settings to select extruder Actually selecting an extruder has no effect because there are dragons in that area and I need better armour with bonus damage against bugs before I venture in there. Contributes to issues CURA-340 and CURA-1278. --- cura/SettingOverrideDecorator.py | 38 ++++++-- .../PerObjectSettingsPanel.qml | 94 ++++++++++++++++++- .../PerObjectSettingsTool.py | 19 +++- 3 files changed, 142 insertions(+), 9 deletions(-) diff --git a/cura/SettingOverrideDecorator.py b/cura/SettingOverrideDecorator.py index f9878e436c..06dbc2cb31 100644 --- a/cura/SettingOverrideDecorator.py +++ b/cura/SettingOverrideDecorator.py @@ -1,5 +1,9 @@ # Copyright (c) 2016 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. + +from PyQt5.QtCore import pyqtSignal +import copy + from UM.Scene.SceneNodeDecorator import SceneNodeDecorator from UM.Settings.ContainerStack import ContainerStack @@ -7,24 +11,29 @@ from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Application import Application -import copy + ## A decorator that adds a container stack to a Node. This stack should be queried for all settings regarding # the linked node. The Stack in question will refer to the global stack (so that settings that are not defined by # this stack still resolve. class SettingOverrideDecorator(SceneNodeDecorator): + ## Event indicating that the user selected a different extruder. + activeExtruderChanged = pyqtSignal() + def __init__(self): super().__init__() self._stack = ContainerStack(stack_id = id(self)) self._stack.setDirty(False) # This stack does not need to be saved. self._instance = InstanceContainer(container_id = "SettingOverrideInstanceContainer") self._stack.addContainer(self._instance) + self._extruder_stack = None #Stack upon which our stack is based. self._stack.propertyChanged.connect(self._onSettingChanged) ContainerRegistry.getInstance().addContainer(self._stack) - Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged) - self._onGlobalContainerStackChanged() + Application.getInstance().globalContainerStackChanged.connect(self._updateNextStack) + self.activeExtruderChanged.connect(self._updateNextStack) + self._updateNextStack() def __deepcopy__(self, memo): ## Create a fresh decorator object @@ -35,13 +44,30 @@ class SettingOverrideDecorator(SceneNodeDecorator): deep_copy._stack.replaceContainer(0, deep_copy._instance) return deep_copy + ## Gets the currently active extruder to print this object with. + # + # \return An extruder's container stack. + def getActiveExtruder(self): + return self._extruder_stack + def _onSettingChanged(self, instance, property): if property == "value": # Only reslice if the value has changed. Application.getInstance().getBackend().forceSlice() - def _onGlobalContainerStackChanged(self): - ## Ensure that the next stack is always the global stack. - self._stack.setNextStack(Application.getInstance().getGlobalContainerStack()) + ## Makes sure that the stack upon which the container stack is placed is + # kept up to date. + def _updateNextStack(self): + if self._extruder_stack: + self._stack.setNextStack(ContainerRegistry.getInstance().findContainerStack(id = self._extruder_stack)) + else: + self._stack.setNextStack(Application.getInstance().getGlobalContainerStack()) + + ## Changes the extruder with which to print this node. + # + # \param extruder_stack_id The new extruder stack to print with. + def setActiveExtruder(self, extruder_stack_id): + self._extruder_stack = extruder_stack_id + self.activeExtruderChanged.emit() def getStack(self): return self._stack \ No newline at end of file diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index d07db2e212..4610083674 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2015 Ultimaker B.V. +// Copyright (c) 2016 Ultimaker B.V. // Uranium is released under the terms of the AGPLv3 or higher. import QtQuick 2.2 @@ -26,6 +26,98 @@ Item { spacing: UM.Theme.getSize("default_margin").height; + Row + { + ComboBox + { + id: extruderSelector + + model: Cura.ExtrudersModel + { + id: extruders_model + } + textRole: "name" + width: items.width + height: UM.Theme.getSize("section").height + MouseArea + { + anchors.fill: parent + acceptedButtons: Qt.NoButton + onWheel: wheel.accepted = true; + } + + style: ComboBoxStyle + { + background: Rectangle + { + color: + { + if(extruderSelector.hovered || base.activeFocus) + { + return UM.Theme.getColor("setting_control_highlight"); + } + else + { + return extruders_model.getItem(extruderSelector.currentIndex).colour; + } + } + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("setting_control_border") + } + label: Item + { + Label + { + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_lining").width + anchors.right: downArrow.left + anchors.rightMargin: UM.Theme.getSize("default_lining").width + anchors.verticalCenter: parent.verticalCenter + + text: extruderSelector.currentText + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("setting_control_disabled_text") + + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + + UM.RecolorImage + { + id: downArrow + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("default_lining").width * 2 + anchors.verticalCenter: parent.verticalCenter + + source: UM.Theme.getIcon("arrow_bottom") + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width + 5 + sourceSize.height: width + 5 + + color: UM.Theme.getColor("setting_control_text") + } + } + } + + onActivated: UM.ActiveTool.properties.setValue("SelectedActiveExtruder", extruders_model.getItem(index).id); + onModelChanged: updateCurrentIndex(); + + function updateCurrentIndex() + { + for(var i = 0; i < extruders_model.rowCount(); ++i) + { + if(extruders_model.getItem(i).id == UM.ActiveTool.properties.getValue("SelectedActiveExtruder")) + { + extruderSelector.currentIndex = i; + return; + } + } + extruderSelector.currentIndex = -1; + } + } + } + Repeater { id: contents diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py index 6ae44c2671..255277c3af 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 Ultimaker B.V. +# Copyright (c) 2016 Ultimaker B.V. # Uranium is released under the terms of the AGPLv3 or higher. from UM.Tool import Tool @@ -14,7 +14,7 @@ class PerObjectSettingsTool(Tool): super().__init__() self._model = None - self.setExposedProperties("SelectedObjectId", "ContainerID") + self.setExposedProperties("SelectedObjectId", "ContainerID", "SelectedActiveExtruder") Preferences.getInstance().preferenceChanged.connect(self._onPreferenceChanged) Selection.selectionChanged.connect(self.propertyChanged) @@ -42,6 +42,21 @@ class PerObjectSettingsTool(Tool): except AttributeError: return "" + ## Gets the active extruder of the currently selected object. + # + # \return The active extruder of the currently selected object. + def getSelectedActiveExtruder(self): + selected_object = Selection.getSelectedObject(0) + selected_object.callDecoration("getActiveExtruder") + + ## Changes the active extruder of the currently selected object. + # + # \param extruder_stack_id The ID of the extruder to print the currently + # selected object with. + def setSelectedActiveExtruder(self, extruder_stack_id): + selected_object = Selection.getSelectedObject(0) + selected_object.callDecoration("setActiveExtruder", extruder_stack_id) + def _onPreferenceChanged(self, preference): if preference == "cura/active_mode": enabled = Preferences.getInstance().getValue(preference)==1 From 38c6c3cb0160b45c94d15e9b221dc338b2b0a3b5 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 9 Jun 2016 15:51:28 +0200 Subject: [PATCH 593/705] Minor fixes to SidebarHeader CURA-1689 --- resources/qml/SidebarHeader.qml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index f1c0bf7d8b..17fb473b74 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -128,8 +128,6 @@ Column ExtruderManager.setActiveExtruderIndex(index); } - Component.onCompleted: console.log(model.name); - style: ButtonStyle { background: Rectangle @@ -365,7 +363,7 @@ Column //Insert a separator between readonly and custom profiles if(separatorIndex < 0 && index > 0) { - if(model.getItem(index-1).readOnly != model.getItem(index).metadata.read_only) + if(model.getItem(index-1).readOnly != model.getItem(index).readOnly) { profileSelectionMenu.insertSeparator(index); separatorIndex = index; @@ -376,7 +374,7 @@ Column } onObjectRemoved: { - //When adding a profile, the menu is rebuild by removing all items. + //When adding a profile, the menu is rebuilt by removing all items. //If a separator was added, we need to remove that too. if(separatorIndex >= 0) { From 0952dd0327b4fd90545208b628c4c3b5b5c1cdb4 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 9 Jun 2016 16:01:08 +0200 Subject: [PATCH 594/705] Removed warnings about undefined properties CURA-1278 --- resources/qml/Preferences/ProfilesPage.qml | 1 - resources/qml/Settings/SettingCategory.qml | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index b382065a7e..cd37df3cc5 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -41,7 +41,6 @@ UM.ManagementPage { width: objectListContainer.viewport.width; height: childrenRect.height; - color: palette.light Label { diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index f4c35f876e..6e23158a1c 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -56,9 +56,9 @@ Button { anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("setting_preferences_button_margin").width - visible: hiddenValuesCount > 0 - height: parent.height / 2; - width: height; + visible: false //hiddenValuesCount > 0 + height: parent.height / 2 + width: height onClicked: { base.showAllHiddenInheritedSettings() From 392d237b4746b013affc749b192ab48033dabc04 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 9 Jun 2016 16:55:04 +0200 Subject: [PATCH 595/705] Fix filtering UM2+ profiles Profiles did not show before selecting a material CURA-1278 --- cura/MachineManagerModel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 816dbc4600..e9a07f58f7 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -114,8 +114,8 @@ class MachineManagerModel(QObject): UM.Settings.ContainerRegistry.getInstance().addContainer(new_global_stack) variant_instance_container = self._updateVariantContainer(definition) - material_instance_container = self._updateMaterialContainer(definition) - quality_instance_container = self._updateQualityContainer(definition) + material_instance_container = self._updateMaterialContainer(definition, variant_instance_container) + quality_instance_container = self._updateQualityContainer(definition, material_instance_container) current_settings_instance_container = UM.Settings.InstanceContainer(name + "_current_settings") current_settings_instance_container.addMetaDataEntry("machine", name) From e793ce1a2c289cca27c1d4b42b788118521c4855 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 9 Jun 2016 16:57:40 +0200 Subject: [PATCH 596/705] Use ID instead of definition --- cura/ExtrudersModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/ExtrudersModel.py b/cura/ExtrudersModel.py index 3265667dc6..2a4ae54310 100644 --- a/cura/ExtrudersModel.py +++ b/cura/ExtrudersModel.py @@ -80,7 +80,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): } self.appendItem(item) - for extruder in manager.getMachineExtruders(global_container_stack.getBottom()): + for extruder in manager.getMachineExtruders(global_container_stack.getBottom().getId()): material = extruder.findContainer({ "type": "material" }) colour = material.getMetaDataEntry("color_code", default = "#FFFF00") if material else "#FFFF00" position = extruder.getBottom().getMetaDataEntry("position", default = "0") #Position in the definition. From beb263025b5041ec00a222355d02bd6625d9f983 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 9 Jun 2016 15:59:57 +0200 Subject: [PATCH 597/705] Make ExtruderSelector invisible if there is no choice in extruders It doesn't yet update well if you keep the panel open while switching machines. Contributes to issue CURA-340. --- plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index 4610083674..03158266f5 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -36,6 +36,7 @@ Item { { id: extruders_model } + visible: extruders_model.rowCount() > 1 textRole: "name" width: items.width height: UM.Theme.getSize("section").height From 9d618282ed614b78ee263187af71f6ed25c3603f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 9 Jun 2016 16:30:54 +0200 Subject: [PATCH 598/705] Save default material colour statically So if you wish to change that colour, you only need to change it in one place. Contributes to issue CURA-340. --- cura/ExtrudersModel.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cura/ExtrudersModel.py b/cura/ExtrudersModel.py index 2a4ae54310..960c05bd5e 100644 --- a/cura/ExtrudersModel.py +++ b/cura/ExtrudersModel.py @@ -28,6 +28,10 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): # containers. IndexRole = Qt.UserRole + 4 + ## Colour to display if there is no material or the material has no known + # colour. + defaultColour = "#FFFF00" + ## Initialises the extruders model, defining the roles and listening for # changes in the data. # @@ -71,7 +75,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): if self._add_global: material = global_container_stack.findContainer({ "type": "material" }) - colour = material.getMetaDataEntry("color_code", default = "#FFFF00") if material else "#FFFF00" + colour = material.getMetaDataEntry("color_code", default = self.defaultColour) if material else self.defaultColour item = { "id": global_container_stack.getId(), "name": "Global", @@ -82,7 +86,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): for extruder in manager.getMachineExtruders(global_container_stack.getBottom().getId()): material = extruder.findContainer({ "type": "material" }) - colour = material.getMetaDataEntry("color_code", default = "#FFFF00") if material else "#FFFF00" + colour = material.getMetaDataEntry("color_code", default = self.defaultColour) if material else self.defaultColour position = extruder.getBottom().getMetaDataEntry("position", default = "0") #Position in the definition. try: position = int(position) From 9f3752276f701f5fb417f06d28aa94a6b3f34532 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 9 Jun 2016 16:43:53 +0200 Subject: [PATCH 599/705] Fix check if machine's extruders are processed Luckily this did never occur anyway since the rest of the code was sound. Contributes to issue CURA-340. --- cura/ExtruderManager.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index f5971ac141..edd6ab7d23 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -191,9 +191,10 @@ class ExtruderManager(QObject): container_registry.addContainer(container_stack) ## Generates extruders for a specific machine. + # + # \param machine_id The machine to get the extruders of. def getMachineExtruders(self, machine_id): - container_registry = UM.Settings.ContainerRegistry.getInstance() - if not machine_id in self._extruder_trains: + if machine_id not in self._extruder_trains: UM.Logger.log("w", "Tried to get the extruder trains for machine %s, which doesn't exist.", machine_id) return for name in self._extruder_trains[machine_id]: From 3206650f39cf6f7b034307d5f5afad79b632acb8 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 9 Jun 2016 16:59:01 +0200 Subject: [PATCH 600/705] Fix signal, repair per-object settings This was the wrong type of signal, which gave an error. Contributes to issue CURA-340. --- cura/SettingOverrideDecorator.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/SettingOverrideDecorator.py b/cura/SettingOverrideDecorator.py index 06dbc2cb31..23730fee60 100644 --- a/cura/SettingOverrideDecorator.py +++ b/cura/SettingOverrideDecorator.py @@ -1,11 +1,10 @@ # Copyright (c) 2016 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. -from PyQt5.QtCore import pyqtSignal import copy from UM.Scene.SceneNodeDecorator import SceneNodeDecorator - +from UM.Signal import Signal, signalemitter from UM.Settings.ContainerStack import ContainerStack from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.ContainerRegistry import ContainerRegistry @@ -15,9 +14,10 @@ from UM.Application import Application ## A decorator that adds a container stack to a Node. This stack should be queried for all settings regarding # the linked node. The Stack in question will refer to the global stack (so that settings that are not defined by # this stack still resolve. +@signalemitter class SettingOverrideDecorator(SceneNodeDecorator): ## Event indicating that the user selected a different extruder. - activeExtruderChanged = pyqtSignal() + activeExtruderChanged = Signal() def __init__(self): super().__init__() From 959305ddf72769d5154771996b7a6c78e2db492d Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 9 Jun 2016 17:26:43 +0200 Subject: [PATCH 601/705] JSOn fix: removed buggy default:true for numeric values (CURA-1558) --- resources/definitions/fdmprinter.def.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 52aab1d26c..bc4b8dbc40 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -324,7 +324,6 @@ "minimum_value": "0.001", "minimum_value_warning": "0.04", "maximum_value_warning": "0.8 * machine_nozzle_size", - "default_value": true, "settable_per_mesh": false, "settable_per_extruder": false }, @@ -338,7 +337,6 @@ "minimum_value": "0.001", "minimum_value_warning": "0.04", "maximum_value_warning": "0.8 * machine_nozzle_size", - "default_value": true, "settable_per_mesh": false, "settable_per_extruder": false }, @@ -366,7 +364,6 @@ "value":"line_width", "default_value": 0.4, "type": "float", - "default_value": true, "settable_per_mesh": true, "children": { From b0198aedb089afb64be4322424503ddf9138e3f1 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 9 Jun 2016 17:27:20 +0200 Subject: [PATCH 602/705] JSON fix: line_width didn't supply any settable_per info (CURA-1558) --- resources/definitions/fdmprinter.def.json | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index bc4b8dbc40..1f7ed7c78a 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -351,6 +351,7 @@ "default_value": 0.4, "type": "float", "value": "machine_nozzle_size", + "settable_per_mesh": true, "children": { "wall_line_width": From c6b17064601eb59837d9f109c2ffe5e2435c5b58 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 9 Jun 2016 17:49:33 +0200 Subject: [PATCH 603/705] Fix customisedSettings button (profiles dropdown) layout and behavior CURA-1685 --- resources/qml/SidebarHeader.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index fdae096aee..1083496f36 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -430,12 +430,12 @@ Column anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("setting_preferences_button_margin").width + anchors.rightMargin: UM.Theme.getSize("setting_preferences_button_margin").width - UM.Theme.getSize("default_margin").width color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button"); iconSource: UM.Theme.getIcon("star"); - onClicked: base.manageProfilesAction.trigger() + onClicked: Cura.Actions.manageProfiles.trigger() onEntered: { var content = catalog.i18nc("@tooltip","Some setting values are different from the values stored in the profile.\n\nClick to open the profile manager.") From d34d398e9660060233024d338823567bd04a1444 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 9 Jun 2016 18:40:42 +0200 Subject: [PATCH 604/705] Change the implementation of creating a profile from the current settings The newly created profile now combines the settings of the active quality profile and the current settings CURA-970, CURA-1585 --- cura/MachineManagerModel.py | 34 +++++----------------- resources/qml/Actions.qml | 2 +- resources/qml/Cura.qml | 2 +- resources/qml/Preferences/ProfilesPage.qml | 4 +-- 4 files changed, 11 insertions(+), 31 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index e9a07f58f7..6768a357a5 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -269,38 +269,18 @@ class MachineManagerModel(QObject): return containers[0].isReadOnly() @pyqtSlot(result = str) - def convertUserContainerToQuality(self): - if not self._global_container_stack: + def newQualityContainerFromQualityAndUser(self): + new_container_id = self.duplicateContainer(self.activeQualityId) + if new_container_id == "": return + self.setActiveQuality(new_container_id) + self.updateQualityContainerFromUserContainer() - new_quality_container = InstanceContainer("") - name = self._createUniqueName("quality", "", self.activeQualityName, catalog.i18nc("@label", "Custom profile")) - user_settings = self._global_container_stack.getTop() - - ## Copy all values - new_quality_container.deserialize(user_settings.serialize()) - - ## If the currently active machine does not have quality profiles of its own, - # make the new quality profile available for all machines that don't have - # unique quality profiles (including the current machine) - if not self.filterQualityByMachine: - new_quality_container.setDefinition(UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = "fdmprinter")[0]) - - ## Change type / id / name - new_quality_container.setMetaDataEntry("type", "quality") - new_quality_container.setReadOnly(False) - new_quality_container.setName(name) - new_quality_container._id = name - - UM.Settings.ContainerRegistry.getInstance().addContainer(new_quality_container) - self.clearUserSettings() # As all users settings are now transfered to the new quality profile, remove them. - self.setActiveQuality(name) - return name @pyqtSlot(str, result=str) def duplicateContainer(self, container_id): if not self._global_container_stack: - return + return "" containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=container_id) if containers: new_name = self._createUniqueName("quality", "", containers[0].getName(), catalog.i18nc("@label", "Custom profile")) @@ -348,7 +328,7 @@ class MachineManagerModel(QObject): @pyqtSlot() - def updateUserContainerToQuality(self): + def updateQualityContainerFromUserContainer(self): if not self._global_container_stack: return user_settings = self._global_container_stack.getTop() diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index e09b6b5424..3ef40644d2 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -112,7 +112,7 @@ Item id: updateProfileAction; enabled: Cura.MachineManager.isGlobalStackValid && Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) text: catalog.i18nc("@action:inmenu menubar:profile","&Update Current Profile"); - onTriggered: Cura.MachineManager.updateUserContainerToQuality() + onTriggered: Cura.MachineManager.updateQualityContainerFromUserContainer() } Action diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index a1023d8ef2..547f05d056 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -582,7 +582,7 @@ UM.MainWindow target: Cura.Actions.addProfile onTriggered: { - Cura.MachineManager.convertUserContainerToQuality(); + Cura.MachineManager.newQualityContainerFromQualityAndUser(); preferences.setPage(5); preferences.show(); diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index cd37df3cc5..71afdd98ac 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -65,7 +65,7 @@ UM.ManagementPage onAddObject: { var selectedContainer; if (objectList.currentItem.id == Cura.MachineManager.activeQualityId) { - selectedContainer = Cura.MachineManager.convertUserContainerToQuality(); + selectedContainer = Cura.MachineManager.newQualityContainerFromQualityAndUser(); } else { selectedContainer = Cura.MachineManager.duplicateContainer(base.currentItem.id); } @@ -121,7 +121,7 @@ UM.ManagementPage return catalog.i18nc("@action:button", "Update \"%1\"".arg(profileName)); } enabled: Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) - onClicked: Cura.MachineManager.updateUserContainerToQuality() + onClicked: Cura.MachineManager.updateQualityContainerFromUserContainer() } Button From c8070cff052083751f0a17bd0058e9f8888876c5 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Thu, 9 Jun 2016 18:43:54 +0200 Subject: [PATCH 605/705] Don't ignore the directory but the link, too. --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index cc21d3092c..8bcc055115 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,4 @@ resources/firmware .pydevproject # Debian packaging -debian/ +debian* From 330481d2d604913199c408deccf79f24c118a72f Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Thu, 9 Jun 2016 18:45:48 +0200 Subject: [PATCH 606/705] Ignore settings set on Eclipse --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 8bcc055115..dc951a52b7 100644 --- a/.gitignore +++ b/.gitignore @@ -16,8 +16,11 @@ resources/firmware *~ *.qm .idea + +# Eclipse+PyDev .project .pydevproject +.settings # Debian packaging debian* From f5f711b7dc38270860d2c54e3403fc647aae716c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 9 Jun 2016 18:59:28 +0200 Subject: [PATCH 607/705] On extruder switch create OverrideDecorator if needed The SettingOverrideDecorator is only applied if the node has a per-object setting. Now it also creates a decorator also if you've ever switched the extruder, which was needed because the decorator contains the information which extruder to print with. Contributes to issue CURA-340. --- plugins/PerObjectSettingsTool/PerObjectSettingsTool.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py index 255277c3af..395dbdc594 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py @@ -5,7 +5,7 @@ from UM.Tool import Tool from UM.Scene.Selection import Selection from UM.Application import Application from UM.Preferences import Preferences - +from cura.SettingOverrideDecorator import SettingOverrideDecorator ## This tool allows the user to add & change settings per node in the scene. # The settings per object are kept in a ContainerStack, which is linked to a node by decorator. @@ -55,6 +55,9 @@ class PerObjectSettingsTool(Tool): # selected object with. def setSelectedActiveExtruder(self, extruder_stack_id): selected_object = Selection.getSelectedObject(0) + stack = selected_object.callDecoration("getStack") #Don't try to get the active extruder since it may be None anyway. + if not stack: + selected_object.addDecorator(SettingOverrideDecorator()) selected_object.callDecoration("setActiveExtruder", extruder_stack_id) def _onPreferenceChanged(self, preference): From 9e86cd5c85312d54d120a0d769560ae833055443 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 9 Jun 2016 19:03:41 +0200 Subject: [PATCH 608/705] Fix call to findContainerStack[s] Was a typo. Now it also checks if the stack ID is correct here. Not because it went wrong, but for defensive programming. Contributes to issue CURA-340. --- cura/SettingOverrideDecorator.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cura/SettingOverrideDecorator.py b/cura/SettingOverrideDecorator.py index 23730fee60..7417e47bf2 100644 --- a/cura/SettingOverrideDecorator.py +++ b/cura/SettingOverrideDecorator.py @@ -8,6 +8,7 @@ from UM.Signal import Signal, signalemitter from UM.Settings.ContainerStack import ContainerStack from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.ContainerRegistry import ContainerRegistry +import UM.Logger from UM.Application import Application @@ -58,7 +59,11 @@ class SettingOverrideDecorator(SceneNodeDecorator): # kept up to date. def _updateNextStack(self): if self._extruder_stack: - self._stack.setNextStack(ContainerRegistry.getInstance().findContainerStack(id = self._extruder_stack)) + extruder_stack = ContainerRegistry.getInstance().findContainerStacks(id = self._extruder_stack) + if extruder_stack: + self._stack.setNextStack(extruder_stack) + else: + UM.Logger.log("e", "Extruder stack %s below per-object settings does not exist.", self._extruder_stack) else: self._stack.setNextStack(Application.getInstance().getGlobalContainerStack()) From 598ff1e398d662f2f4570417d1893f071f7bd31b Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 9 Jun 2016 19:05:52 +0200 Subject: [PATCH 609/705] Fix changing active extruder from per-object drop-down Apparently this is the way you do it. Contributes to issue CURA-340. --- plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index 03158266f5..502e903416 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -101,7 +101,7 @@ Item { } } - onActivated: UM.ActiveTool.properties.setValue("SelectedActiveExtruder", extruders_model.getItem(index).id); + onActivated: UM.ActiveTool.setProperty("SelectedActiveExtruder", extruders_model.getItem(index).id); onModelChanged: updateCurrentIndex(); function updateCurrentIndex() From af238d5a7656b243550c426405e2b356de877365 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 9 Jun 2016 19:17:31 +0200 Subject: [PATCH 610/705] Renaming profiles now also renames them on disk CURA-1683 --- cura/MachineManagerModel.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index e9a07f58f7..7e588574d8 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -5,12 +5,17 @@ from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal from UM.Application import Application from UM.Preferences import Preferences from UM.Logger import Logger +from UM.Resources import Resources + +import os +import urllib import UM.Settings from UM.Settings.Validator import ValidatorState from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.ContainerStack import ContainerStack from . import ExtruderManager +import cura.CuraApplication from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") @@ -323,8 +328,19 @@ class MachineManagerModel(QObject): def renameQualityContainer(self, container_id, new_name): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id, type = "quality") if containers: + + # Remove old container form drive. + old_id = containers[0].getId() + file_name = urllib.parse.quote_plus(old_id) + ".inst.cfg" + path = Resources.getStoragePath(cura.CuraApplication.CuraApplication.ResourceTypes.QualityInstanceContainer, + file_name) + os.remove(path) + + ## Check if the new name is allowed. new_name = self._createUniqueName("quality", containers[0].getName(), new_name, catalog.i18nc("@label", "Custom profile")) + containers[0].setName(new_name) + containers[0]._id = new_name # Todo: Fix proper id change function for this. self.activeQualityChanged.emit() From 0d7a7d9299a945a5da32445897d758b11b5d6b81 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 9 Jun 2016 19:18:46 +0200 Subject: [PATCH 611/705] Update wording to make storing/updating/discarding current settings more clear CURA-970 --- resources/qml/Actions.qml | 8 ++++---- resources/qml/Cura.qml | 8 ++++---- resources/qml/Preferences/ProfilesPage.qml | 8 +++----- resources/qml/SidebarHeader.qml | 20 ++++---------------- 4 files changed, 15 insertions(+), 29 deletions(-) diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index 3ef40644d2..7e03bd7102 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -111,7 +111,7 @@ Item { id: updateProfileAction; enabled: Cura.MachineManager.isGlobalStackValid && Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) - text: catalog.i18nc("@action:inmenu menubar:profile","&Update Current Profile"); + text: catalog.i18nc("@action:inmenu menubar:profile","&Update profile with current settings"); onTriggered: Cura.MachineManager.updateQualityContainerFromUserContainer() } @@ -119,15 +119,15 @@ Item { id: resetProfileAction; enabled: Cura.MachineManager.hasUserSettings - text: catalog.i18nc("@action:inmenu menubar:profile","&Reload Current Profile"); + text: catalog.i18nc("@action:inmenu menubar:profile","&Discard current settings"); onTriggered: Cura.MachineManager.clearUserSettings(); } Action { id: addProfileAction; - enabled: Cura.MachineManager.isGlobalStackValid - text: catalog.i18nc("@action:inmenu menubar:profile","&Create New Profile..."); + enabled: Cura.MachineManager.isGlobalStackValid && Cura.MachineManager.hasUserSettings + text: catalog.i18nc("@action:inmenu menubar:profile","&Create profile from current settings..."); } Action diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 547f05d056..c3dc95b454 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -297,11 +297,11 @@ UM.MainWindow MenuSeparator { id: profileMenuSeparator } - MenuItem { action: Cura.Actions.updateProfile; } - MenuItem { action: Cura.Actions.resetProfile; } - MenuItem { action: Cura.Actions.addProfile; } + MenuItem { action: Cura.Actions.addProfile } + MenuItem { action: Cura.Actions.updateProfile } + MenuItem { action: Cura.Actions.resetProfile } MenuSeparator { } - MenuItem { action: Cura.Actions.manageProfiles; } + MenuItem { action: Cura.Actions.manageProfiles } } Menu diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 71afdd98ac..93fd8ae61f 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -13,7 +13,7 @@ UM.ManagementPage id: base; title: catalog.i18nc("@title:tab", "Profiles"); - addText: catalog.i18nc("@label", "Duplicate") + addText: base.currentItem && (base.currentItem.id == Cura.MachineManager.activeQualityId) ? catalog.i18nc("@label", "Create") : catalog.i18nc("@label", "Duplicate") model: UM.InstanceContainersModel { @@ -116,9 +116,7 @@ UM.ManagementPage Button { text: { - var profileName = Cura.MachineManager.activeQualityName; - profileName = (profileName.length > 20) ? profileName.substring(0, 20) + '...' : profileName; - return catalog.i18nc("@action:button", "Update \"%1\"".arg(profileName)); + return catalog.i18nc("@action:button", "Update profile with current settings"); } enabled: Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) onClicked: Cura.MachineManager.updateQualityContainerFromUserContainer() @@ -126,7 +124,7 @@ UM.ManagementPage Button { - text: catalog.i18nc("@action:button", "Discard changes"); + text: catalog.i18nc("@action:button", "Discard current settings"); enabled: Cura.MachineManager.hasUserSettings onClicked: Cura.MachineManager.clearUserSettings(); } diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 1083496f36..282068ee2c 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -401,23 +401,11 @@ Column } MenuSeparator { } - MenuItem - { - action: Cura.Actions.updateProfile; - } - MenuItem - { - action: Cura.Actions.resetProfile; - } - MenuItem - { - action: Cura.Actions.addProfile; - } + MenuItem { action: Cura.Actions.addProfile } + MenuItem { action: Cura.Actions.updateProfile } + MenuItem { action: Cura.Actions.resetProfile } MenuSeparator { } - MenuItem - { - action: Cura.Actions.manageProfiles; - } + MenuItem { action: Cura.Actions.manageProfiles } } UM.SimpleButton From 7d2a7bd157a334fe96dd8e215a0faf2de3e391e1 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 9 Jun 2016 21:40:07 +0200 Subject: [PATCH 612/705] Abbreviate headers CURA-1668 --- resources/qml/Preferences/ProfilesPage.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 93fd8ae61f..670bf79956 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -191,13 +191,13 @@ UM.ManagementPage visible: currentItem.id == Cura.MachineManager.activeQualityId spacing: UM.Theme.getSize("default_margin").width Label { - text: catalog.i18nc("@action:label", "Profile value") + text: catalog.i18nc("@action:label", "Profile:") width: scrollView.width / 100 * 55 horizontalAlignment: Text.AlignRight font.bold: true } Label { - text: catalog.i18nc("@action:label", "Current setting") + text: catalog.i18nc("@action:label", "Current:") visible: currentItem.id == Cura.MachineManager.activeQualityId font.bold: true } From 2287c2daa698c0300074af37c65d9c8c96855391 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 9 Jun 2016 21:40:53 +0200 Subject: [PATCH 613/705] Show that a value is being calculated instead of showing "QVariant..." CURA-1668 --- cura/ContainerSettingsModel.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cura/ContainerSettingsModel.py b/cura/ContainerSettingsModel.py index 83a1f3ccd4..2ff1a5f401 100644 --- a/cura/ContainerSettingsModel.py +++ b/cura/ContainerSettingsModel.py @@ -5,6 +5,7 @@ from PyQt5.QtCore import pyqtProperty, Qt, pyqtSignal, pyqtSlot, QUrl from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.InstanceContainer import InstanceContainer +from UM.Settings.SettingFunction import SettingFunction class ContainerSettingsModel(ListModel): LabelRole = Qt.UserRole + 1 @@ -53,7 +54,11 @@ class ContainerSettingsModel(ListModel): while category.type != "category": category = category.parent - values.append(container.getProperty(key, "value")) + value = container.getProperty(key, "value") + if type(value) == SettingFunction: + values.append("=\u0192") + else: + values.append(container.getProperty(key, "value")) else: values.append("") From d8e8b0740ac2b1d776c13cd8078fe1b8e4f5a45d Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 10 Jun 2016 00:12:35 +0200 Subject: [PATCH 614/705] Temporarily revert "Renaming profiles now also renames them on disk" This reverts commit af238d5a7656b243550c426405e2b356de877365. --- cura/MachineManagerModel.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index e3f0bd6241..6768a357a5 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -5,17 +5,12 @@ from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal from UM.Application import Application from UM.Preferences import Preferences from UM.Logger import Logger -from UM.Resources import Resources - -import os -import urllib import UM.Settings from UM.Settings.Validator import ValidatorState from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.ContainerStack import ContainerStack from . import ExtruderManager -import cura.CuraApplication from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") @@ -308,19 +303,8 @@ class MachineManagerModel(QObject): def renameQualityContainer(self, container_id, new_name): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id, type = "quality") if containers: - - # Remove old container form drive. - old_id = containers[0].getId() - file_name = urllib.parse.quote_plus(old_id) + ".inst.cfg" - path = Resources.getStoragePath(cura.CuraApplication.CuraApplication.ResourceTypes.QualityInstanceContainer, - file_name) - os.remove(path) - - ## Check if the new name is allowed. new_name = self._createUniqueName("quality", containers[0].getName(), new_name, catalog.i18nc("@label", "Custom profile")) - containers[0].setName(new_name) - containers[0]._id = new_name # Todo: Fix proper id change function for this. self.activeQualityChanged.emit() From 070a522abb772854d5d59214a30f18ff8f25b940 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 10 Jun 2016 09:17:12 +0200 Subject: [PATCH 615/705] Revert "Temporarily revert "Renaming profiles now also renames them on disk"" Starting work on it again, so unreverting the revert (i guess) This reverts commit d8e8b0740ac2b1d776c13cd8078fe1b8e4f5a45d. --- cura/MachineManagerModel.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 6768a357a5..e3f0bd6241 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -5,12 +5,17 @@ from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal from UM.Application import Application from UM.Preferences import Preferences from UM.Logger import Logger +from UM.Resources import Resources + +import os +import urllib import UM.Settings from UM.Settings.Validator import ValidatorState from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.ContainerStack import ContainerStack from . import ExtruderManager +import cura.CuraApplication from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") @@ -303,8 +308,19 @@ class MachineManagerModel(QObject): def renameQualityContainer(self, container_id, new_name): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id, type = "quality") if containers: + + # Remove old container form drive. + old_id = containers[0].getId() + file_name = urllib.parse.quote_plus(old_id) + ".inst.cfg" + path = Resources.getStoragePath(cura.CuraApplication.CuraApplication.ResourceTypes.QualityInstanceContainer, + file_name) + os.remove(path) + + ## Check if the new name is allowed. new_name = self._createUniqueName("quality", containers[0].getName(), new_name, catalog.i18nc("@label", "Custom profile")) + containers[0].setName(new_name) + containers[0]._id = new_name # Todo: Fix proper id change function for this. self.activeQualityChanged.emit() From 962b4e84a963f8799691b829ff701b077307065e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 10 Jun 2016 09:38:47 +0200 Subject: [PATCH 616/705] Fixed renaming of profiles. They are now correctly renamed (and saved under different name on disk as well) CURA-1683 --- cura/MachineManagerModel.py | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index e3f0bd6241..7cb80bbf20 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -6,6 +6,7 @@ from UM.Application import Application from UM.Preferences import Preferences from UM.Logger import Logger from UM.Resources import Resources +import copy import os import urllib @@ -303,26 +304,32 @@ class MachineManagerModel(QObject): return "" - @pyqtSlot(str, str) def renameQualityContainer(self, container_id, new_name): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id, type = "quality") if containers: + new_name = self._createUniqueName("quality", containers[0].getName(), new_name, + catalog.i18nc("@label", "Custom profile")) - # Remove old container form drive. - old_id = containers[0].getId() - file_name = urllib.parse.quote_plus(old_id) + ".inst.cfg" - path = Resources.getStoragePath(cura.CuraApplication.CuraApplication.ResourceTypes.QualityInstanceContainer, - file_name) - os.remove(path) + # As we also want the id of the container to be changed (so that profile name is the name of the file + # on disk. We need to create a new instance and remove it (so the old file of the container is removed) + # If we don't do that, we might get duplicates & other weird issues. + new_container = InstanceContainer("") + new_container.deserialize(containers[0].serialize()) - ## Check if the new name is allowed. - new_name = self._createUniqueName("quality", containers[0].getName(), new_name, catalog.i18nc("@label", "Custom profile")) + # Actually set the name + new_container.setName(new_name) + new_container._id = new_name # Todo: Fix proper id change function for this. - containers[0].setName(new_name) - containers[0]._id = new_name # Todo: Fix proper id change function for this. - self.activeQualityChanged.emit() + # Add the "new" container. + UM.Settings.ContainerRegistry.getInstance().addContainer(new_container) + # Ensure that the renamed profile is saved -before- we remove the old profile. + Application.getInstance().saveSettings() + + # Actually set & remove new / old quality. + self.setActiveQuality(new_name) + self.removeQualityContainer(containers[0].getId()) @pyqtSlot(str) def removeQualityContainer(self, container_id): From 0cf3fd36240849d30415057bb307ec70959abbf7 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 10 Jun 2016 09:41:51 +0200 Subject: [PATCH 617/705] Removed unused imports CURA-1278 --- cura/MachineManagerModel.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 7cb80bbf20..443c19d302 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -4,22 +4,16 @@ import re from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal from UM.Application import Application from UM.Preferences import Preferences -from UM.Logger import Logger -from UM.Resources import Resources -import copy - -import os -import urllib import UM.Settings from UM.Settings.Validator import ValidatorState from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.ContainerStack import ContainerStack from . import ExtruderManager -import cura.CuraApplication from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") + class MachineManagerModel(QObject): def __init__(self, parent = None): super().__init__(parent) @@ -47,7 +41,6 @@ class MachineManagerModel(QObject): self.setActiveMachine(active_machine_id) pass - globalContainerChanged = pyqtSignal() activeMaterialChanged = pyqtSignal() activeVariantChanged = pyqtSignal() From b61b0a7ee2e11adf6bbf150a61bf48e226fd57c5 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Fri, 10 Jun 2016 10:52:12 +0200 Subject: [PATCH 618/705] Removing unneeded import of os' --- cura_app.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cura_app.py b/cura_app.py index dc748435f9..3bcce18fb5 100755 --- a/cura_app.py +++ b/cura_app.py @@ -36,7 +36,6 @@ import Arcus #@UnusedImport import cura.CuraApplication if sys.platform == "win32" and hasattr(sys, "frozen"): - import os dirpath = os.path.expanduser("~/AppData/Local/cura/") os.makedirs(dirpath, exist_ok = True) sys.stdout = open(os.path.join(dirpath, "stdout.log"), "w") From e2e9e7964c2bbfb1274df5f017350746fc7385e2 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 10 Jun 2016 11:48:33 +0200 Subject: [PATCH 619/705] Fixed duplication if no name was changed CURA-1427 --- cura/MachineManagerModel.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 443c19d302..0e7230fb79 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -304,6 +304,10 @@ class MachineManagerModel(QObject): new_name = self._createUniqueName("quality", containers[0].getName(), new_name, catalog.i18nc("@label", "Custom profile")) + if containers[0].getName() == new_name: + # Nothing to do. + return + # As we also want the id of the container to be changed (so that profile name is the name of the file # on disk. We need to create a new instance and remove it (so the old file of the container is removed) # If we don't do that, we might get duplicates & other weird issues. From 9672b3360c92728fba54466f7e1584e444aae7a2 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 10 Jun 2016 12:26:11 +0200 Subject: [PATCH 620/705] Changing settings in extruder stack now also triggers reslice CURA-1689 --- cura/ExtruderManager.py | 6 ++++++ plugins/CuraEngineBackend/CuraEngineBackend.py | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index edd6ab7d23..578905a63a 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -66,6 +66,12 @@ class ExtruderManager(QObject): self._active_extruder_index = index self.activeExtruderChanged.emit() + def getActiveExtruderStack(self): + try: + return self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getBottom().getId()][str(self._active_extruder_index)] + except AttributeError: + return None + ## Adds all extruders of a specific machine definition to the extruder # manager. # diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 3e22f8f6fb..80f2614e87 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -12,6 +12,8 @@ from UM.PluginRegistry import PluginRegistry from UM.Resources import Resources from UM.Settings.Validator import ValidatorState #To find if a setting is in an error state. We can't slice then. +from cura.ExtruderManager import ExtruderManager + from cura.OneAtATimeIterator import OneAtATimeIterator from . import ProcessSlicedLayersJob from . import ProcessGCodeJob @@ -59,6 +61,10 @@ class CuraEngineBackend(Backend): Application.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged) self._onGlobalStackChanged() + self._active_extruder_stack = None + ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderChanged) + self._onActiveExtruderChanged() + #When you update a setting and other settings get changed through inheritance, many propertyChanged signals are fired. #This timer will group them up, and only slice for the last setting changed signal. #TODO: Properly group propertyChanged signals by whether they are triggered by the same user interaction. @@ -367,4 +373,16 @@ class CuraEngineBackend(Backend): if self._global_container_stack: self._global_container_stack.propertyChanged.connect(self._onSettingChanged) #Note: Only starts slicing when the value changed. self._global_container_stack.containersChanged.connect(self._onChanged) + self._onActiveExtruderChanged() self._onChanged() + + def _onActiveExtruderChanged(self): + if self._active_extruder_stack: + self._active_extruder_stack.propertyChanged.disconnect(self._onSettingChanged) + self._active_extruder_stack.containersChanged.disconnect(self._onChanged) + + self._active_extruder_stack = ExtruderManager.getInstance().getActiveExtruderStack() + if self._active_extruder_stack: + self._active_extruder_stack.propertyChanged.connect(self._onSettingChanged) # Note: Only starts slicing when the value changed. + self._active_extruder_stack.containersChanged.connect(self._onChanged) + self._onChanged() \ No newline at end of file From 179b6eeaac0381b5ddc4faa941da981dba4ade30 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 10 Jun 2016 13:16:54 +0200 Subject: [PATCH 621/705] Fixed issue where not having a machine caused extruder retrieval to fail CURA-1689 --- cura/ExtruderManager.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 578905a63a..72b6086e26 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -71,6 +71,8 @@ class ExtruderManager(QObject): return self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getBottom().getId()][str(self._active_extruder_index)] except AttributeError: return None + except KeyError: + return None ## Adds all extruders of a specific machine definition to the extruder # manager. From b2d57207a4934d969d08f1b9a8c139852fceb03a Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Fri, 10 Jun 2016 13:20:55 +0200 Subject: [PATCH 622/705] fix: global_only ==> settable_per_X for acceleration and jerk settings (CURA-1560 CURA-1443) --- resources/definitions/fdmprinter.def.json | 104 +++++++++++++--------- 1 file changed, 64 insertions(+), 40 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 5c1d45442b..ff46047e48 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1318,7 +1318,8 @@ "description": "Enables adjusting the print head acceleration. Increasing the accelerations can reduce printing time at the cost of print quality.", "type": "bool", "default_value": false, - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false }, "acceleration_print": { "label": "Print Acceleration", @@ -1330,6 +1331,7 @@ "maximum_value_warning": "10000", "default_value": 3000, "enabled": "acceleration_enabled", + "settable_per_mesh": true, "children": { "acceleration_infill": { "label": "Infill Acceleration", @@ -1340,7 +1342,8 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default_value": 3000, - "enabled": "acceleration_enabled" + "enabled": "acceleration_enabled", + "settable_per_mesh": true }, "acceleration_wall": { "label": "Wall Acceleration", @@ -1352,6 +1355,7 @@ "maximum_value_warning": "10000", "default_value": 3000, "enabled": "acceleration_enabled", + "settable_per_mesh": true, "children": { "acceleration_wall_0": { "label": "Outer Wall Acceleration", @@ -1362,7 +1366,8 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default_value": 3000, - "enabled": "acceleration_enabled" + "enabled": "acceleration_enabled", + "settable_per_mesh": true }, "acceleration_wall_x": { "label": "Inner Wall Acceleration", @@ -1373,7 +1378,8 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default_value": 3000, - "enabled": "acceleration_enabled" + "enabled": "acceleration_enabled", + "settable_per_mesh": true } } }, @@ -1386,7 +1392,8 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default_value": 3000, - "enabled": "acceleration_enabled" + "enabled": "acceleration_enabled", + "settable_per_mesh": true }, "acceleration_support": { "label": "Support Acceleration", @@ -1398,6 +1405,8 @@ "maximum_value_warning": "10000", "default_value": 3000, "enabled": "acceleration_enabled and support_roof_enable", + "settable_per_mesh": false, + "settable_per_extruder": false, "children": { "acceleration_support_infill": { "label": "Support Infill Acceleration", @@ -1409,7 +1418,8 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "enabled": "acceleration_enabled and support_enable", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": false }, "acceleration_support_roof": { "label": "Support Roof Acceleration", @@ -1421,7 +1431,8 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "enabled": "acceleration_enabled and support_roof_enable", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": false } } }, @@ -1435,7 +1446,7 @@ "maximum_value_warning": "10000", "default_value": 3000, "enabled": "prime_tower_enable and acceleration_enabled", - "global_only": true + "settable_per_mesh": false } } }, @@ -1449,8 +1460,8 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default": "acceleration_print if magic_spiralize else 5000", - "global_only": true, - "enabled": "acceleration_enabled" + "enabled": "acceleration_enabled", + "settable_per_mesh": false }, "acceleration_layer_0": { "label": "Initial Layer Acceleration", @@ -1461,7 +1472,8 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "enabled": "acceleration_enabled" + "enabled": "acceleration_enabled", + "settable_per_mesh": true }, "acceleration_skirt": { "label": "Skirt Acceleration", @@ -1473,8 +1485,8 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default": "acceleration_layer_0", - "global_only": true, - "enabled": "acceleration_enabled" + "enabled": "acceleration_enabled", + "settable_per_mesh": false }, @@ -1484,7 +1496,8 @@ "description": "Enables adjusting the jerk of print head when the X or Y axis halts or starts to move. Increasing the jerk can reduce printing time at the cost of print quality.", "type": "bool", "default_value": false, - "global_only": "True" + "settable_per_mesh": false, + "settable_per_extruder": false }, "jerk_print": { "label": "Print Jerk", @@ -1496,6 +1509,7 @@ "maximum_value_warning": "50", "default_value": 20, "enabled": "jerk_enabled", + "settable_per_mesh": true, "children": { "jerk_infill": { "label": "Infill Jerk", @@ -1506,7 +1520,8 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default_value": 20, - "enabled": "jerk_enabled" + "enabled": "jerk_enabled", + "settable_per_mesh": true }, "jerk_wall": { "label": "Wall Jerk", @@ -1518,6 +1533,7 @@ "maximum_value_warning": "50", "default_value": 20, "enabled": "jerk_enabled", + "settable_per_mesh": true, "children": { "jerk_wall_0": { "label": "Outer Wall Jerk", @@ -1528,7 +1544,8 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default_value": 20, - "enabled": "jerk_enabled" + "enabled": "jerk_enabled", + "settable_per_mesh": true }, "jerk_wall_x": { "label": "Inner Wall Jerk", @@ -1539,7 +1556,8 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default_value": 20, - "enabled": "jerk_enabled" + "enabled": "jerk_enabled", + "settable_per_mesh": true } } }, @@ -1552,7 +1570,8 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default_value": 20, - "enabled": "jerk_enabled" + "enabled": "jerk_enabled", + "settable_per_mesh": true }, "jerk_support": { "label": "Support Jerk", @@ -1564,6 +1583,8 @@ "maximum_value_warning": "50", "default_value": 20, "enabled": "jerk_enabled and support_roof_enable", + "settable_per_mesh": false, + "settable_per_extruder": false, "children": { "jerk_support_infill": { "label": "Support Infill Jerk", @@ -1575,7 +1596,8 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "enabled": "jerk_enabled and support_enable", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": false }, "jerk_support_roof": { "label": "Support Roof Jerk", @@ -1587,7 +1609,8 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "enabled": "jerk_enabled and support_roof_enable", - "global_only": true + "settable_per_mesh": false, + "settable_per_extruder": false } } }, @@ -1601,7 +1624,7 @@ "maximum_value_warning": "50", "default_value": 20, "enabled": "prime_tower_enable and jerk_enabled", - "global_only": true + "settable_per_mesh": false } } }, @@ -1615,9 +1638,9 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default": "jerk_print if magic_spiralize else 30", - "global_only": true, "visible": true, - "enabled": "jerk_enabled" + "enabled": "jerk_enabled", + "settable_per_mesh": false }, "jerk_layer_0": { "label": "Initial Layer Jerk", @@ -1628,7 +1651,8 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "enabled": "jerk_enabled" + "enabled": "jerk_enabled", + "settable_per_mesh": true }, "jerk_skirt": { "label": "Skirt Jerk", @@ -1640,8 +1664,8 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default": "jerk_layer_0", - "global_only": true, - "enabled": "jerk_enabled" + "enabled": "jerk_enabled", + "settable_per_mesh": false } } }, @@ -2506,8 +2530,8 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default": "acceleration_print", - "global_only": "True", "enabled": "adhesion_type == \"raft\" and acceleration_enabled", + "settable_per_mesh": false, "children": { "raft_surface_acceleration": { "label": "Raft Top Print Acceleration", @@ -2518,8 +2542,8 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "global_only": "True", - "enabled": "adhesion_type == \"raft\" and acceleration_enabled" + "enabled": "adhesion_type == \"raft\" and acceleration_enabled", + "settable_per_mesh": false }, "raft_interface_acceleration": { "label": "Raft Middle Print Acceleration", @@ -2530,8 +2554,8 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "global_only": "True", - "enabled": "adhesion_type == \"raft\" and acceleration_enabled" + "enabled": "adhesion_type == \"raft\" and acceleration_enabled", + "settable_per_mesh": false }, "raft_base_acceleration": { "label": "Raft Base Print Acceleration", @@ -2542,8 +2566,8 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "global_only": "True", - "enabled": "adhesion_type == \"raft\" and acceleration_enabled" + "enabled": "adhesion_type == \"raft\" and acceleration_enabled", + "settable_per_mesh": false } } }, @@ -2560,8 +2584,8 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default": "jerk_print", - "global_only": "True", "enabled": "adhesion_type == \"raft\" and jerk_enabled", + "settable_per_mesh": false, "children": { "raft_surface_jerk": { "label": "Raft Top Print Jerk", @@ -2572,8 +2596,8 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "100", - "global_only": "True", - "enabled": "adhesion_type == \"raft\" and jerk_enabled" + "enabled": "adhesion_type == \"raft\" and jerk_enabled", + "settable_per_mesh": false }, "raft_interface_jerk": { "label": "Raft Middle Print Jerk", @@ -2584,8 +2608,8 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "global_only": "True", - "enabled": "adhesion_type == \"raft\" and jerk_enabled" + "enabled": "adhesion_type == \"raft\" and jerk_enabled", + "settable_per_mesh": false }, "raft_base_jerk": { "label": "Raft Base Print Jerk", @@ -2596,8 +2620,8 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "global_only": "True", - "enabled": "adhesion_type == \"raft\" and jerk_enabled" + "enabled": "adhesion_type == \"raft\" and jerk_enabled", + "settable_per_mesh": false } } }, From 795291a117575430461269b1a290cae7c6147318 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Fri, 10 Jun 2016 13:32:57 +0200 Subject: [PATCH 623/705] fix/feat: introduced and fixed inheritance for all acceleration and jerk settings (CURA-1443) --- resources/definitions/fdmprinter.def.json | 38 +++++++++++++++++++---- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index ff46047e48..6b54136840 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1342,6 +1342,7 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default_value": 3000, + "value": "acceleration_print", "enabled": "acceleration_enabled", "settable_per_mesh": true }, @@ -1354,6 +1355,7 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default_value": 3000, + "value": "acceleration_print", "enabled": "acceleration_enabled", "settable_per_mesh": true, "children": { @@ -1366,6 +1368,7 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default_value": 3000, + "value": "acceleration_wall", "enabled": "acceleration_enabled", "settable_per_mesh": true }, @@ -1378,6 +1381,7 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default_value": 3000, + "value": "acceleration_wall", "enabled": "acceleration_enabled", "settable_per_mesh": true } @@ -1392,6 +1396,7 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default_value": 3000, + "value": "acceleration_print", "enabled": "acceleration_enabled", "settable_per_mesh": true }, @@ -1404,6 +1409,7 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default_value": 3000, + "value": "acceleration_print", "enabled": "acceleration_enabled and support_roof_enable", "settable_per_mesh": false, "settable_per_extruder": false, @@ -1414,6 +1420,7 @@ "unit": "mm/s²", "type": "float", "default_value": 3000, + "value": "acceleration_support", "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", @@ -1427,6 +1434,7 @@ "unit": "mm/s²", "type": "float", "default_value": 3000, + "value": "acceleration_support", "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", @@ -1445,6 +1453,7 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "default_value": 3000, + "value": "acceleration_print", "enabled": "prime_tower_enable and acceleration_enabled", "settable_per_mesh": false } @@ -1459,7 +1468,7 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "default": "acceleration_print if magic_spiralize else 5000", + "value": "acceleration_print if magic_spiralize else 5000", "enabled": "acceleration_enabled", "settable_per_mesh": false }, @@ -1469,6 +1478,7 @@ "unit": "mm/s²", "type": "float", "default_value": 3000, + "value": "acceleration_print", "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", @@ -1481,10 +1491,10 @@ "unit": "mm/s²", "type": "float", "default_value": 3000, + "value": "acceleration_layer_0", "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "default": "acceleration_layer_0", "enabled": "acceleration_enabled", "settable_per_mesh": false }, @@ -1520,6 +1530,7 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default_value": 20, + "value": "jerk_print", "enabled": "jerk_enabled", "settable_per_mesh": true }, @@ -1532,6 +1543,7 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default_value": 20, + "value": "jerk_print", "enabled": "jerk_enabled", "settable_per_mesh": true, "children": { @@ -1544,6 +1556,7 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default_value": 20, + "value": "jerk_wall", "enabled": "jerk_enabled", "settable_per_mesh": true }, @@ -1556,6 +1569,7 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default_value": 20, + "value": "jerk_wall", "enabled": "jerk_enabled", "settable_per_mesh": true } @@ -1570,6 +1584,7 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default_value": 20, + "value": "jerk_print", "enabled": "jerk_enabled", "settable_per_mesh": true }, @@ -1582,6 +1597,7 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default_value": 20, + "value": "jerk_print", "enabled": "jerk_enabled and support_roof_enable", "settable_per_mesh": false, "settable_per_extruder": false, @@ -1592,6 +1608,7 @@ "unit": "mm/s³", "type": "float", "default_value": 20, + "value": "jerk_support", "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", @@ -1605,6 +1622,7 @@ "unit": "mm/s³", "type": "float", "default_value": 20, + "value": "jerk_support", "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", @@ -1623,6 +1641,7 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "default_value": 20, + "value": "jerk_print", "enabled": "prime_tower_enable and jerk_enabled", "settable_per_mesh": false } @@ -1637,7 +1656,7 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "default": "jerk_print if magic_spiralize else 30", + "value": "jerk_print if magic_spiralize else 30", "visible": true, "enabled": "jerk_enabled", "settable_per_mesh": false @@ -1648,6 +1667,7 @@ "unit": "mm/s³", "type": "float", "default_value": 20, + "value": "jerk_print", "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", @@ -1663,7 +1683,7 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "default": "jerk_layer_0", + "value": "jerk_layer_0", "enabled": "jerk_enabled", "settable_per_mesh": false } @@ -2529,7 +2549,7 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "default": "acceleration_print", + "value": "acceleration_print", "enabled": "adhesion_type == \"raft\" and acceleration_enabled", "settable_per_mesh": false, "children": { @@ -2539,6 +2559,7 @@ "unit": "mm/s²", "type": "float", "default_value": 3000, + "value": "raft_acceleration", "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", @@ -2551,6 +2572,7 @@ "unit": "mm/s²", "type": "float", "default_value": 3000, + "value": "raft_acceleration", "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", @@ -2563,6 +2585,7 @@ "unit": "mm/s²", "type": "float", "default_value": 3000, + "value": "raft_acceleration", "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", @@ -2583,7 +2606,7 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "default": "jerk_print", + "value": "jerk_print", "enabled": "adhesion_type == \"raft\" and jerk_enabled", "settable_per_mesh": false, "children": { @@ -2593,6 +2616,7 @@ "unit": "mm/s³", "type": "float", "default_value": 20, + "value": "raft_jerk", "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "100", @@ -2605,6 +2629,7 @@ "unit": "mm/s³", "type": "float", "default_value": 20, + "value": "raft_jerk", "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", @@ -2617,6 +2642,7 @@ "unit": "mm/s³", "type": "float", "default_value": 20, + "value": "raft_jerk", "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", From 6bb1793d12ce912883b6535255fc5eabf67115df Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Fri, 10 Jun 2016 13:48:43 +0200 Subject: [PATCH 624/705] fix: moved jerk_travel visibility from json to CuraApplication (CURA-1443) --- cura/CuraApplication.py | 1 + resources/definitions/fdmprinter.def.json | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 472a4e6424..3ff0b4a008 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -198,6 +198,7 @@ class CuraApplication(QtApplication): acceleration_print acceleration_travel jerk_print + jerk_travel travel cooling cool_fan_enabled diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 6b54136840..6e6474053f 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1657,7 +1657,6 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "value": "jerk_print if magic_spiralize else 30", - "visible": true, "enabled": "jerk_enabled", "settable_per_mesh": false }, From c0472e0068a9461a8c168ded92c8de1c16856362 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Fri, 10 Jun 2016 13:57:52 +0200 Subject: [PATCH 625/705] LayerView: Using resetLayerData() Currently resetLayerData() is not used at all, but found in two places the same code like found in resetLayerData(). So replaced them with resetLayerData(). --- plugins/LayerView/LayerView.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/LayerView/LayerView.py b/plugins/LayerView/LayerView.py index 4a73f5de9c..50ab7f968e 100644 --- a/plugins/LayerView/LayerView.py +++ b/plugins/LayerView/LayerView.py @@ -129,8 +129,7 @@ class LayerView(View): if self._current_layer_num > self._max_layers: self._current_layer_num = self._max_layers - self._current_layer_mesh = None - self._current_layer_jumps = None + self.resetLayerData() self._top_layer_timer.start() @@ -219,8 +218,7 @@ class LayerView(View): self._solid_layers = int(Preferences.getInstance().getValue("view/top_layer_count")) - self._current_layer_mesh = None - self._current_layer_jumps = None + self.resetLayerData() self._top_layer_timer.start() class _CreateTopLayersJob(Job): From df1ca39c7b4295f2afa561c94af69c165211cc49 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 10 Jun 2016 12:48:41 +0200 Subject: [PATCH 626/705] Fix getting proper container stack in decorator Using the filter function now but the resulting list wasn't properly accounted for. Contributes to issue CURA-340. --- cura/SettingOverrideDecorator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/SettingOverrideDecorator.py b/cura/SettingOverrideDecorator.py index 7417e47bf2..806c0c008e 100644 --- a/cura/SettingOverrideDecorator.py +++ b/cura/SettingOverrideDecorator.py @@ -61,7 +61,7 @@ class SettingOverrideDecorator(SceneNodeDecorator): if self._extruder_stack: extruder_stack = ContainerRegistry.getInstance().findContainerStacks(id = self._extruder_stack) if extruder_stack: - self._stack.setNextStack(extruder_stack) + self._stack.setNextStack(extruder_stack[0]) else: UM.Logger.log("e", "Extruder stack %s below per-object settings does not exist.", self._extruder_stack) else: From f302e06654528925067806c45b396d5e8791778d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 10 Jun 2016 13:37:07 +0200 Subject: [PATCH 627/705] Reslice when per-object extruder changes Not when you activate the dropdown but it doesn't change though. Contributes to issue CURA-340. --- cura/SettingOverrideDecorator.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cura/SettingOverrideDecorator.py b/cura/SettingOverrideDecorator.py index 806c0c008e..e3e3555016 100644 --- a/cura/SettingOverrideDecorator.py +++ b/cura/SettingOverrideDecorator.py @@ -61,7 +61,10 @@ class SettingOverrideDecorator(SceneNodeDecorator): if self._extruder_stack: extruder_stack = ContainerRegistry.getInstance().findContainerStacks(id = self._extruder_stack) if extruder_stack: + old_extruder_stack_id = self._stack.getNextStack().getId() self._stack.setNextStack(extruder_stack[0]) + if self._stack.getNextStack().getId() != old_extruder_stack_id: #Only reslice if the extruder changed. + Application.getInstance().getBackend().forceSlice() else: UM.Logger.log("e", "Extruder stack %s below per-object settings does not exist.", self._extruder_stack) else: From 67058c3d452f2605ae458131baf23ac8f06dd89a Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Fri, 10 Jun 2016 14:52:15 +0200 Subject: [PATCH 628/705] fix: definition visibility got borked (CURA-1443) machine definition visibility should be a metadata property and should be set to true for only those definitions which are actually machines --- resources/definitions/ultimaker.def.json | 4 ++-- resources/definitions/ultimaker2_extended_plus.def.json | 3 +-- resources/definitions/ultimaker2_plus.def.json | 1 - 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/resources/definitions/ultimaker.def.json b/resources/definitions/ultimaker.def.json index d70d55ecf4..5df38d07cb 100644 --- a/resources/definitions/ultimaker.def.json +++ b/resources/definitions/ultimaker.def.json @@ -5,7 +5,7 @@ "inherits": "fdmprinter", "metadata": { "author": "Ultimaker", - "manufacturer": "Ultimaker" - "visible": false, + "manufacturer": "Ultimaker", + "visible": false } } diff --git a/resources/definitions/ultimaker2_extended_plus.def.json b/resources/definitions/ultimaker2_extended_plus.def.json index 96239fa804..50f0e73b9f 100644 --- a/resources/definitions/ultimaker2_extended_plus.def.json +++ b/resources/definitions/ultimaker2_extended_plus.def.json @@ -9,8 +9,7 @@ "category": "Ultimaker", "file_formats": "text/x-gcode", "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2ExtendedPlusbackplate.png", - "visible": false + "platform_texture": "Ultimaker2ExtendedPlusbackplate.png" }, "overrides": { diff --git a/resources/definitions/ultimaker2_plus.def.json b/resources/definitions/ultimaker2_plus.def.json index b29f904095..4432fab170 100644 --- a/resources/definitions/ultimaker2_plus.def.json +++ b/resources/definitions/ultimaker2_plus.def.json @@ -3,7 +3,6 @@ "version": 2, "name": "Ultimaker 2+", "inherits": "ultimaker2", - "visible": "false", "metadata": { "author": "Ultimaker", "manufacturer": "Ultimaker", From 0aea7bdb5c67e7dde3be31cfd1a8d48b72c5d322 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Fri, 10 Jun 2016 14:54:21 +0200 Subject: [PATCH 629/705] Use callLater to set the active machine in MachineManager This prevents exceptions in setActiveMachine from preventing Cura to start. --- cura/MachineManagerModel.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 0e7230fb79..86b044ae84 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -38,8 +38,7 @@ class MachineManagerModel(QObject): if active_machine_id != "": # An active machine was saved, so restore it. - self.setActiveMachine(active_machine_id) - pass + Application.getInstance().callLater(self.setActiveMachine, active_machine_id) globalContainerChanged = pyqtSignal() activeMaterialChanged = pyqtSignal() From 44f8744c847c5a8a466c75247c61c969742299bc Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Fri, 10 Jun 2016 14:56:08 +0200 Subject: [PATCH 630/705] Use the Logger to report uncaught exceptions Makes for a nicer and clearer output of uncaught exceptions --- cura/CrashHandler.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cura/CrashHandler.py b/cura/CrashHandler.py index 57de2959eb..4efcfbe1e5 100644 --- a/cura/CrashHandler.py +++ b/cura/CrashHandler.py @@ -5,6 +5,8 @@ import webbrowser from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR, QCoreApplication from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout, QLabel, QTextEdit + +from UM.Logger import Logger from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") @@ -13,7 +15,10 @@ def show(exception_type, value, tb): if QCoreApplication.instance(): debug_mode = QCoreApplication.instance().getCommandLineOption("debug-mode", False) - traceback.print_exception(exception_type, value, tb) + Logger.log("c", "An uncaught exception has occurred!") + for line in traceback.format_exception(exception_type, value, tb): + for part in line.rstrip("\n").split("\n"): + Logger.log("c", part) if not debug_mode: return From a4e37d9ae7e2fc04dcee1558018cbc2aaa88a393 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Fri, 10 Jun 2016 15:07:59 +0200 Subject: [PATCH 631/705] Mark certain types of exceptions as fatal and abort the application if they occur We simply cannot recover properly from things like an uncaught MemoryError since that usually means any follow up operation will also fail. So Instead of silently ignoring it and having the application in a broken state we properly abort. Right now the list of fatal exceptions is a bare minimum that contains the most prominent things we cannot recover from. --- cura/CrashHandler.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/cura/CrashHandler.py b/cura/CrashHandler.py index 4efcfbe1e5..e86e407902 100644 --- a/cura/CrashHandler.py +++ b/cura/CrashHandler.py @@ -10,6 +10,17 @@ from UM.Logger import Logger from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") +# List of exceptions that should be considered "fatal" and abort the program. +# These are primarily some exception types that we simply cannot really recover from +# (MemoryError and SystemError) and exceptions that indicate grave errors in the +# code that cause the Python interpreter to fail (SyntaxError, ImportError). +fatal_exception_types = [ + MemoryError, + SyntaxError, + ImportError, + SystemError, +] + def show(exception_type, value, tb): debug_mode = False if QCoreApplication.instance(): @@ -20,7 +31,7 @@ def show(exception_type, value, tb): for part in line.rstrip("\n").split("\n"): Logger.log("c", part) - if not debug_mode: + if not debug_mode and exception_type not in fatal_exception_types: return application = QCoreApplication.instance() @@ -34,7 +45,7 @@ def show(exception_type, value, tb): label = QLabel(dialog) layout.addWidget(label) - label.setText(catalog.i18nc("@label", "

    An uncaught exception has occurred!

    Please use the information below to post a bug report at http://github.com/Ultimaker/Cura/issues

    ")) + label.setText(catalog.i18nc("@label", "

    A fatal exception has occurred that we could not recover from!

    Please use the information below to post a bug report at http://github.com/Ultimaker/Cura/issues

    ")) textarea = QTextEdit(dialog) layout.addWidget(textarea) From c4a1bd2fd3a87bc68ca7e4d9b8ecb4404319c498 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 10 Jun 2016 16:13:47 +0200 Subject: [PATCH 632/705] Automatically use global- or extruder- containerstack CURA-1585 --- cura/MachineManagerModel.py | 116 ++++++++++++++++++++---------------- 1 file changed, 66 insertions(+), 50 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 0e7230fb79..f5661320ec 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -18,16 +18,25 @@ class MachineManagerModel(QObject): def __init__(self, parent = None): super().__init__(parent) + self._active_container_stack = None self._global_container_stack = None + Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged) self._global_stack_valid = None self._onGlobalContainerChanged() + ExtruderManager.ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderStackChanged) + self._onActiveExtruderStackChanged() + ## When the global container is changed, active material probably needs to be updated. self.globalContainerChanged.connect(self.activeMaterialChanged) self.globalContainerChanged.connect(self.activeVariantChanged) self.globalContainerChanged.connect(self.activeQualityChanged) + self.globalContainerChanged.connect(self.activeStackChanged) + self.globalValueChanged.connect(self.activeStackChanged) + ExtruderManager.ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeStackChanged) + self._empty_variant_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_variant")[0] self._empty_material_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_material")[0] self._empty_quality_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_quality")[0] @@ -45,6 +54,7 @@ class MachineManagerModel(QObject): activeMaterialChanged = pyqtSignal() activeVariantChanged = pyqtSignal() activeQualityChanged = pyqtSignal() + activeStackChanged = pyqtSignal() globalValueChanged = pyqtSignal() # Emitted whenever a value inside global container is changed. globalValidationChanged = pyqtSignal() # Emitted whenever a validation inside global container is changed. @@ -63,12 +73,12 @@ class MachineManagerModel(QObject): self.globalValueChanged.emit() if property_name == "validationState": if self._global_stack_valid: - changed_validation_state = self._global_container_stack.getProperty(key, property_name) + changed_validation_state = self._active_container_stack.getProperty(key, property_name) if changed_validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError): self._global_stack_valid = False self.globalValidationChanged.emit() else: - new_validation_state = self._checkStackForErrors(self._global_container_stack) + new_validation_state = self._checkStackForErrors(self._active_container_stack) if new_validation_state: self._global_stack_valid = True self.globalValidationChanged.emit() @@ -87,6 +97,11 @@ class MachineManagerModel(QObject): self._global_container_stack.propertyChanged.connect(self._onGlobalPropertyChanged) self._global_stack_valid = not self._checkStackForErrors(self._global_container_stack) + def _onActiveExtruderStackChanged(self): + self._active_container_stack = ExtruderManager.ExtruderManager.getInstance().getActiveExtruderStack() + if not self._active_container_stack: + self._active_container_stack = self._global_container_stack + def _onInstanceContainersChanged(self, container): container_type = container.getMetaDataEntry("type") if container_type == "material": @@ -183,18 +198,19 @@ class MachineManagerModel(QObject): ## Remove all instances from the top instanceContainer (effectively removing all user-changed settings) @pyqtSlot() def clearUserSettings(self): - if not self._global_container_stack: + if not self._active_container_stack: return - user_settings = self._global_container_stack.getTop() + + user_settings = self._active_container_stack.getTop() user_settings.clear() ## Check if the global_container has instances in the user container - @pyqtProperty(bool, notify = globalValueChanged) + @pyqtProperty(bool, notify = activeStackChanged) def hasUserSettings(self): - if not self._global_container_stack: + if not self._active_container_stack: return - user_settings = self._global_container_stack.getTop().findInstances(**{}) + user_settings = self._active_container_stack.getTop().findInstances(**{}) return len(user_settings) != 0 ## Check if the global profile does not contain error states @@ -206,8 +222,8 @@ class MachineManagerModel(QObject): @pyqtProperty(str, notify = globalContainerChanged) def activeUserProfileId(self): - if self._global_container_stack: - return self._global_container_stack.getTop().getId() + if self._active_container_stack: + return self._active_container_stack.getTop().getId() return "" @@ -227,8 +243,8 @@ class MachineManagerModel(QObject): @pyqtProperty(str, notify = activeMaterialChanged) def activeMaterialName(self): - if self._global_container_stack: - material = self._global_container_stack.findContainer({"type":"material"}) + if self._active_container_stack: + material = self._active_container_stack.findContainer({"type":"material"}) if material: return material.getName() @@ -236,8 +252,8 @@ class MachineManagerModel(QObject): @pyqtProperty(str, notify=activeMaterialChanged) def activeMaterialId(self): - if self._global_container_stack: - material = self._global_container_stack.findContainer({"type": "material"}) + if self._active_container_stack: + material = self._active_container_stack.findContainer({"type": "material"}) if material: return material.getId() @@ -245,16 +261,16 @@ class MachineManagerModel(QObject): @pyqtProperty(str, notify=activeQualityChanged) def activeQualityName(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.getName() return "" @pyqtProperty(str, notify=activeQualityChanged) def activeQualityId(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.getId() return "" @@ -262,8 +278,8 @@ class MachineManagerModel(QObject): ## Check if a container is read_only @pyqtSlot(str, result = bool) def isReadOnly(self, container_id): - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=container_id) - if not containers or not self._global_container_stack: + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id) + if not containers or not self._active_container_stack: return True return containers[0].isReadOnly() @@ -278,9 +294,9 @@ class MachineManagerModel(QObject): @pyqtSlot(str, result=str) def duplicateContainer(self, container_id): - if not self._global_container_stack: + if not self._active_container_stack: return "" - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=container_id) + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id) if containers: new_name = self._createUniqueName("quality", "", containers[0].getName(), catalog.i18nc("@label", "Custom profile")) @@ -331,7 +347,7 @@ class MachineManagerModel(QObject): @pyqtSlot(str) def removeQualityContainer(self, container_id): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id) - if not containers or not self._global_container_stack: + if not containers or not self._active_container_stack: return # If the container that is being removed is the currently active container, set another machine as the active container @@ -349,10 +365,10 @@ class MachineManagerModel(QObject): @pyqtSlot() def updateQualityContainerFromUserContainer(self): - if not self._global_container_stack: + if not self._active_container_stack: return - user_settings = self._global_container_stack.getTop() - quality = self._global_container_stack.findContainer({"type": "quality"}) + user_settings = self._active_container_stack.getTop() + quality = self._active_container_stack.findContainer({"type": "quality"}) for key in user_settings.getAllKeys(): quality.setProperty(key, "value", user_settings.getProperty(key, "value")) self.clearUserSettings() # As all users settings are noq a quality, remove them. @@ -360,45 +376,45 @@ class MachineManagerModel(QObject): @pyqtSlot(str) def setActiveMaterial(self, material_id): - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=material_id) - if not containers or not self._global_container_stack: + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = material_id) + if not containers or not self._active_container_stack: return - old_material = self._global_container_stack.findContainer({"type":"material"}) + old_material = self._active_container_stack.findContainer({"type":"material"}) if old_material: - material_index = self._global_container_stack.getContainerIndex(old_material) - self._global_container_stack.replaceContainer(material_index, containers[0]) + material_index = self._active_container_stack.getContainerIndex(old_material) + self._active_container_stack.replaceContainer(material_index, containers[0]) - self.setActiveQuality(self._updateQualityContainer(self._global_container_stack.getBottom(), containers[0]).id) + self.setActiveQuality(self._updateQualityContainer(self._active_container_stack.getBottom(), containers[0]).id) @pyqtSlot(str) def setActiveVariant(self, variant_id): - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=variant_id) - if not containers or not self._global_container_stack: + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = variant_id) + if not containers or not self._active_container_stack: return - old_variant = self._global_container_stack.findContainer({"type": "variant"}) + old_variant = self._active_container_stack.findContainer({"type": "variant"}) if old_variant: - variant_index = self._global_container_stack.getContainerIndex(old_variant) - self._global_container_stack.replaceContainer(variant_index, containers[0]) + variant_index = self._active_container_stack.getContainerIndex(old_variant) + self._active_container_stack.replaceContainer(variant_index, containers[0]) - self.setActiveMaterial(self._updateMaterialContainer(self._global_container_stack.getBottom(), containers[0]).id) + self.setActiveMaterial(self._updateMaterialContainer(self._active_container_stack.getBottom(), containers[0]).id) @pyqtSlot(str) def setActiveQuality(self, quality_id): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = quality_id) - if not containers or not self._global_container_stack: + if not containers or not self._active_container_stack: return - old_quality = self._global_container_stack.findContainer({"type": "quality"}) + old_quality = self._active_container_stack.findContainer({"type": "quality"}) if old_quality: - quality_index = self._global_container_stack.getContainerIndex(old_quality) - self._global_container_stack.replaceContainer(quality_index, containers[0]) + quality_index = self._active_container_stack.getContainerIndex(old_quality) + self._active_container_stack.replaceContainer(quality_index, containers[0]) @pyqtProperty(str, notify = activeVariantChanged) def activeVariantName(self): - if self._global_container_stack: - variant = self._global_container_stack.findContainer({"type": "variant"}) + if self._active_container_stack: + variant = self._active_container_stack.findContainer({"type": "variant"}) if variant: return variant.getName() @@ -406,8 +422,8 @@ class MachineManagerModel(QObject): @pyqtProperty(str, notify = activeVariantChanged) def activeVariantId(self): - if self._global_container_stack: - variant = self._global_container_stack.findContainer({"type": "variant"}) + if self._active_container_stack: + variant = self._active_container_stack.findContainer({"type": "variant"}) if variant: return variant.getId() @@ -415,7 +431,7 @@ class MachineManagerModel(QObject): @pyqtProperty(str, notify = globalContainerChanged) def activeDefinitionId(self): - if self._global_container_stack: + if self._active_container_stack: definition = self._global_container_stack.getBottom() if definition: return definition.id @@ -449,15 +465,15 @@ class MachineManagerModel(QObject): @pyqtProperty(bool, notify = globalContainerChanged) def hasMaterials(self): - if self._global_container_stack: - return bool(self._global_container_stack.getMetaDataEntry("has_materials", False)) + if self._active_container_stack: + return bool(self._active_container_stack.getMetaDataEntry("has_materials", False)) return False @pyqtProperty(bool, notify = globalContainerChanged) def hasVariants(self): - if self._global_container_stack: - return bool(self._global_container_stack.getMetaDataEntry("has_variants", False)) + if self._active_container_stack: + return bool(self._active_container_stack.getMetaDataEntry("has_variants", False)) return False From 57dfc2ae7959943a66ea06a46ff72716eb4569f5 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 10 Jun 2016 16:37:43 +0200 Subject: [PATCH 633/705] Change active containerstack when the global containerstack is changed CURA-1585 --- cura/MachineManagerModel.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index f5661320ec..0104b343f4 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -26,6 +26,7 @@ class MachineManagerModel(QObject): self._onGlobalContainerChanged() ExtruderManager.ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderStackChanged) + self.globalContainerChanged.connect(self._onActiveExtruderStackChanged) self._onActiveExtruderStackChanged() ## When the global container is changed, active material probably needs to be updated. From e150b1887eb9d8337a130fa40de6b2e063a508ec Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 10 Jun 2016 16:50:11 +0200 Subject: [PATCH 634/705] Update active variant, material and quality id when switching extruders CURA-1585 --- cura/MachineManagerModel.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 0104b343f4..321f5af486 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -33,6 +33,9 @@ class MachineManagerModel(QObject): self.globalContainerChanged.connect(self.activeMaterialChanged) self.globalContainerChanged.connect(self.activeVariantChanged) self.globalContainerChanged.connect(self.activeQualityChanged) + ExtruderManager.ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeMaterialChanged) + ExtruderManager.ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeVariantChanged) + ExtruderManager.ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeQualityChanged) self.globalContainerChanged.connect(self.activeStackChanged) self.globalValueChanged.connect(self.activeStackChanged) @@ -221,7 +224,7 @@ class MachineManagerModel(QObject): def isGlobalStackValid(self): return self._global_stack_valid - @pyqtProperty(str, notify = globalContainerChanged) + @pyqtProperty(str, notify = activeStackChanged) def activeUserProfileId(self): if self._active_container_stack: return self._active_container_stack.getTop().getId() From 9626cddf3490e11d3cb4bd62bd44837bd7a9f52c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 10 Jun 2016 16:53:59 +0200 Subject: [PATCH 635/705] Extruder trains are now correctly saved --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 3ff0b4a008..393f1e5634 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -283,7 +283,7 @@ class CuraApplication(QtApplication): path = None if not stack_type or stack_type == "machine": path = Resources.getStoragePath(self.ResourceTypes.MachineStack, file_name) - elif stack_type == "extruder": + elif stack_type == "extruder_train": path = Resources.getStoragePath(self.ResourceTypes.ExtruderStack, file_name) if path: with SaveFile(path, "wt", -1, "utf-8") as f: From 8c43d4c4cb03e2733dcd24e558a6a043ff7231a6 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 10 Jun 2016 17:04:25 +0200 Subject: [PATCH 636/705] Quality is now set for extruder, regardless if the machine has machine specific qualities --- cura/ExtruderManager.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 72b6086e26..123388296b 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -18,7 +18,7 @@ class ExtruderManager(QObject): ## Notify when the user switches the currently active extruder. activeExtruderChanged = pyqtSignal() - ## Registers listeners and such to listen to changes to the extruders. + ## Registers listeners and such to listen to chafnges to the extruders. def __init__(self, parent = None): super().__init__(parent) self._extruder_trains = { } #Per machine, a dictionary of extruder container stack IDs. @@ -169,19 +169,19 @@ class ExtruderManager(QObject): #Find a quality to use for this extruder. quality = container_registry.getEmptyInstanceContainer() - if machine_definition.getMetaDataEntry("has_machine_quality"): - #First add any quality. Later, overwrite with preference if the preference is valid. - qualities = container_registry.findInstanceContainers(type = "quality") - if len(qualities) >= 1: - quality = qualities[0] - preferred_quality_id = machine_definition.getMetaDataEntry("preferred_quality") - if preferred_quality_id: - preferred_quality = container_registry.findInstanceContainers(id = preferred_quality_id.lower(), type = "quality") - if len(preferred_quality) >= 1: - quality = preferred_quality[0] - else: - UM.Logger.log("w", "The preferred quality \"%s\" of machine %s doesn't exist or is not a quality profile.", preferred_quality_id, machine_id) - #And leave it at the default quality. + + #First add any quality. Later, overwrite with preference if the preference is valid. + qualities = container_registry.findInstanceContainers(type = "quality") + if len(qualities) >= 1: + quality = qualities[0] + preferred_quality_id = machine_definition.getMetaDataEntry("preferred_quality") + if preferred_quality_id: + preferred_quality = container_registry.findInstanceContainers(id = preferred_quality_id.lower(), type = "quality") + if len(preferred_quality) >= 1: + quality = preferred_quality[0] + else: + UM.Logger.log("w", "The preferred quality \"%s\" of machine %s doesn't exist or is not a quality profile.", preferred_quality_id, machine_id) + #And leave it at the default quality. container_stack.addContainer(quality) user_profile = container_registry.findInstanceContainers(id = extruder_stack_id + "_current_settings") From 204bf4d7ddaeb20cea8a0329b4e6fd1daa9df34a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 10 Jun 2016 16:32:19 +0200 Subject: [PATCH 637/705] Update visibility of extruder dropdown on change It currently only works when switching to a dual-extrusion printer, since the model is not updated when switching away to a non-dual-extrusion printer... Contributes to issue CURA-340. --- plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index 502e903416..920196d447 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -35,6 +35,8 @@ Item { model: Cura.ExtrudersModel { id: extruders_model + onRowsInserted: extruderSelector.visible = extruders_model.rowCount() > 1 + onModelReset: extruderSelector.visible = extruders_model.rowCount() > 1 } visible: extruders_model.rowCount() > 1 textRole: "name" From d89c9d882712c747b0bc9a31ccc02710fe9ba2af Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 10 Jun 2016 17:04:17 +0200 Subject: [PATCH 638/705] Make getSelectedActiveExtruder return its misbegotten gains It was getting a value from the decorator, then keeping it to itself all greedy like. It must return what it found. Contributes to issue CURA-340. --- plugins/PerObjectSettingsTool/PerObjectSettingsTool.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py index 395dbdc594..cb7d1766d2 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py @@ -47,7 +47,7 @@ class PerObjectSettingsTool(Tool): # \return The active extruder of the currently selected object. def getSelectedActiveExtruder(self): selected_object = Selection.getSelectedObject(0) - selected_object.callDecoration("getActiveExtruder") + return selected_object.callDecoration("getActiveExtruder") ## Changes the active extruder of the currently selected object. # From cc17c2897806b4333191ab4c9d6b7ccf149f66ca Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 10 Jun 2016 17:26:09 +0200 Subject: [PATCH 639/705] Fixed global stack not being set as next stack for extruder trains --- cura/ExtruderManager.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 123388296b..84c3028c72 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -99,6 +99,10 @@ class ExtruderManager(QObject): extruder_trains = container_registry.findContainerStacks(type = "extruder_train", machine = machine_definition.getId()) for extruder_train in extruder_trains: self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train + + ## Ensure that the extruder train stacks are linked to global stack. + extruder_train.setNextStack(UM.Application.getInstance().getGlobalContainerStack()) + if extruder_trains: self.extrudersChanged.emit(machine_definition) From b321a8a053838b97351e3802a5ab347de3afd4fd Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 10 Jun 2016 23:36:36 +0200 Subject: [PATCH 640/705] Add definition Printrbot Simple by Calvindog717 Source: https://www.reddit.com/r/3Dprinting/comments/4n1lyd/cura_212_has_been_released_it_features_major_ui/d409udf I've converted Calvin's profile that he was using personally to be up to date after the settings rework. --- .../definitions/printrbot_simple.def.json | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 resources/definitions/printrbot_simple.def.json diff --git a/resources/definitions/printrbot_simple.def.json b/resources/definitions/printrbot_simple.def.json new file mode 100644 index 0000000000..5d0af46f85 --- /dev/null +++ b/resources/definitions/printrbot_simple.def.json @@ -0,0 +1,41 @@ +{ + "id": "printrbot_simple", + "version": 2, + "name": "Printrbot Simple", + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "Calvindog717", + "manufacturer": "PrintrBot", + "file_formats": "text/x-gcode" + }, + + "overrides": { + "machine_heated_bed": { "default_value": false }, + "machine_width": { "default_value": 150 }, + "machine_height": { "default_value": 150 }, + "machine_depth": { "default_value": 140 }, + "machine_center_is_zero": { "default_value": false }, + "machine_nozzle_size": { "default_value": 0.3 }, + "material_diameter": { "default_value": 1.75 }, + "machine_nozzle_heat_up_speed": { "default_value": 2 }, + "machine_nozzle_cool_down_speed": { "default_value": 2 }, + "machine_head_with_fans_polygon": { + "default_value": [ + [ -3, 3 ], + [ -3, -3 ], + [ 3, -3 ], + [ 3, 3 ] + ] + }, + "gantry_height": { "default_value": 15 }, + "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" }, + + "machine_start_gcode": { + "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG29 ; auto bed-levelling\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." + }, + "machine_end_gcode": { + "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" + } + } +} From 6311cea372d75b365e246afee5755784091a3022 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Sat, 11 Jun 2016 00:57:49 +0200 Subject: [PATCH 641/705] Machine head polygon with measured dimensions The collision polygon of the machine head is rectangular, but the arm on which the nozzle hangs extends to the edge of the build plate on one side. These measurements were taken also by Calvindog717. The orientation is guessed. Usually the Y+ direction is towards the front... Let's hope it's good! --- resources/definitions/printrbot_simple.def.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/resources/definitions/printrbot_simple.def.json b/resources/definitions/printrbot_simple.def.json index 5d0af46f85..5950055a76 100644 --- a/resources/definitions/printrbot_simple.def.json +++ b/resources/definitions/printrbot_simple.def.json @@ -22,13 +22,13 @@ "machine_nozzle_cool_down_speed": { "default_value": 2 }, "machine_head_with_fans_polygon": { "default_value": [ - [ -3, 3 ], - [ -3, -3 ], - [ 3, -3 ], - [ 3, 3 ] + [ -55, 20 ], + [ -55, -99999 ], + [ 49, -99999 ], + [ 49, 20 ] ] }, - "gantry_height": { "default_value": 15 }, + "gantry_height": { "default_value": 99999 }, "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" }, "machine_start_gcode": { From 49649f4cd848372852f4da53624e8b45ecfa19f2 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Sat, 11 Jun 2016 02:51:48 +0200 Subject: [PATCH 642/705] Mirror Y-axis of head polygon Apparently, the machine homes to maximum-Y, so the open end of the machine is on the other side. I'm rotating it 180 degrees. --- resources/definitions/printrbot_simple.def.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/definitions/printrbot_simple.def.json b/resources/definitions/printrbot_simple.def.json index 5950055a76..0116ba6244 100644 --- a/resources/definitions/printrbot_simple.def.json +++ b/resources/definitions/printrbot_simple.def.json @@ -22,10 +22,10 @@ "machine_nozzle_cool_down_speed": { "default_value": 2 }, "machine_head_with_fans_polygon": { "default_value": [ - [ -55, 20 ], - [ -55, -99999 ], - [ 49, -99999 ], - [ 49, 20 ] + [ 55, -20 ], + [ 55, 99999 ], + [ -49, 99999 ], + [ -49, -20 ] ] }, "gantry_height": { "default_value": 99999 }, From 0d8292df49a47e6c1a5d563ecca638fcbc02fbe3 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Sat, 11 Jun 2016 12:50:28 +0200 Subject: [PATCH 643/705] Using platform.system() for Windows detection This is just cosmetics. It works the same as system.platform, but looks better. Additionally "win32" might be misleading, as it sounds like we are checking for Windows 32bit here. --- cura/CuraApplication2.py | 784 +++++++++++++++++++++++++++++++++++++++ cura_app.py | 3 +- 2 files changed, 786 insertions(+), 1 deletion(-) create mode 100644 cura/CuraApplication2.py diff --git a/cura/CuraApplication2.py b/cura/CuraApplication2.py new file mode 100644 index 0000000000..85c269fc8b --- /dev/null +++ b/cura/CuraApplication2.py @@ -0,0 +1,784 @@ +# Copyright (c) 2015 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. + +from memory_profiler import profile + +from UM.Qt.QtApplication import QtApplication +from UM.Scene.SceneNode import SceneNode +from UM.Scene.Camera import Camera +from UM.Scene.Platform import Platform +from UM.Math.Vector import Vector +from UM.Math.Quaternion import Quaternion +from UM.Math.AxisAlignedBox import AxisAlignedBox +from UM.Resources import Resources +from UM.Scene.ToolHandle import ToolHandle +from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator +from UM.Mesh.ReadMeshJob import ReadMeshJob +from UM.Logger import Logger +from UM.Preferences import Preferences +from UM.JobQueue import JobQueue +from UM.SaveFile import SaveFile +from UM.Scene.Selection import Selection +from UM.Scene.GroupDecorator import GroupDecorator +import UM.Settings.Validator + +from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation +from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation +from UM.Operations.GroupedOperation import GroupedOperation +from UM.Operations.SetTransformOperation import SetTransformOperation +from cura.SetParentOperation import SetParentOperation + +from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyType +from UM.Settings.ContainerRegistry import ContainerRegistry + +from UM.i18n import i18nCatalog + +from . import ExtruderManager +from . import ExtrudersModel +from . import PlatformPhysics +from . import BuildVolume +from . import CameraAnimation +from . import PrintInformation +from . import CuraActions +from . import MultiMaterialDecorator +from . import ZOffsetDecorator +from . import CuraSplashScreen +from . import MachineManagerModel + +from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty, QEvent, Q_ENUMS +from PyQt5.QtGui import QColor, QIcon +from PyQt5.QtQml import qmlRegisterUncreatableType, qmlRegisterSingletonType, qmlRegisterType + +import platform +import sys +import os.path +import numpy +import copy +import urllib +numpy.seterr(all="ignore") + +#WORKAROUND: GITHUB-88 GITHUB-385 GITHUB-612 +if platform.system() == "Linux": # Needed for platform.linux_distribution, which is not available on Windows and OSX + # For Ubuntu: https://bugs.launchpad.net/ubuntu/+source/python-qt4/+bug/941826 + if platform.linux_distribution()[0] in ("Ubuntu", ): # TODO: Needs a "if X11_GFX == 'nvidia'" here. The workaround is only needed on Ubuntu+NVidia drivers. Other drivers are not affected, but fine with this fix. + import ctypes + from ctypes.util import find_library + ctypes.CDLL(find_library('GL'), ctypes.RTLD_GLOBAL) + +try: + from cura.CuraVersion import CuraVersion, CuraBuildType +except ImportError: + CuraVersion = "master" # [CodeStyle: Reflecting imported value] + CuraBuildType = "" + +@profile +class CuraApplication(QtApplication): + class ResourceTypes: + QmlFiles = Resources.UserType + 1 + Firmware = Resources.UserType + 2 + QualityInstanceContainer = Resources.UserType + 3 + MaterialInstanceContainer = Resources.UserType + 4 + VariantInstanceContainer = Resources.UserType + 5 + UserInstanceContainer = Resources.UserType + 6 + MachineStack = Resources.UserType + 7 + ExtruderStack = Resources.UserType + 8 + + Q_ENUMS(ResourceTypes) + + def __init__(self): + Resources.addSearchPath(os.path.join(QtApplication.getInstallPrefix(), "share", "cura", "resources")) + if not hasattr(sys, "frozen"): + Resources.addSearchPath(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "resources")) + + self._open_file_queue = [] # Files to open when plug-ins are loaded. + + # Need to do this before ContainerRegistry tries to load the machines + SettingDefinition.addSupportedProperty("global_only", DefinitionPropertyType.Function, default = False) + SettingDefinition.addSettingType("extruder", int, str, UM.Settings.Validator) + + super().__init__(name = "cura", version = CuraVersion, buildtype = CuraBuildType) + + self.setWindowIcon(QIcon(Resources.getPath(Resources.Images, "cura-icon.png"))) + + self.setRequiredPlugins([ + "CuraEngineBackend", + "MeshView", + "LayerView", + "STLReader", + "SelectionTool", + "CameraTool", + "GCodeWriter", + "LocalFileOutputDevice" + ]) + self._physics = None + self._volume = None + self._platform = None + self._output_devices = {} + self._print_information = None + self._i18n_catalog = None + self._previous_active_tool = None + self._platform_activity = False + self._scene_bounding_box = AxisAlignedBox() + self._job_name = None + self._center_after_select = False + self._camera_animation = None + self._cura_actions = None + self._started = False + + self.getController().getScene().sceneChanged.connect(self.updatePlatformActivity) + self.getController().toolOperationStopped.connect(self._onToolOperationStopped) + + Resources.addType(self.ResourceTypes.QmlFiles, "qml") + Resources.addType(self.ResourceTypes.Firmware, "firmware") + + ## Add the 4 types of profiles to storage. + Resources.addStorageType(self.ResourceTypes.QualityInstanceContainer, "quality") + Resources.addStorageType(self.ResourceTypes.VariantInstanceContainer, "variants") + Resources.addStorageType(self.ResourceTypes.MaterialInstanceContainer, "materials") + Resources.addStorageType(self.ResourceTypes.UserInstanceContainer, "user") + Resources.addStorageType(self.ResourceTypes.ExtruderStack, "extruders") + Resources.addStorageType(self.ResourceTypes.MachineStack, "machine_instances") + + ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.QualityInstanceContainer) + ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.VariantInstanceContainer) + ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MaterialInstanceContainer) + ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.UserInstanceContainer) + ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.ExtruderStack) + ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MachineStack) + + # Add empty variant, material and quality containers. + # Since they are empty, they should never be serialized and instead just programmatically created. + # We need them to simplify the switching between materials. + empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer() + empty_variant_container = copy.deepcopy(empty_container) + empty_variant_container._id = "empty_variant" + empty_variant_container.addMetaDataEntry("type", "variant") + ContainerRegistry.getInstance().addContainer(empty_variant_container) + empty_material_container = copy.deepcopy(empty_container) + empty_material_container._id = "empty_material" + empty_material_container.addMetaDataEntry("type", "material") + ContainerRegistry.getInstance().addContainer(empty_material_container) + empty_quality_container = copy.deepcopy(empty_container) + empty_quality_container._id = "empty_quality" + empty_quality_container.addMetaDataEntry("type", "quality") + ContainerRegistry.getInstance().addContainer(empty_quality_container) + + ContainerRegistry.getInstance().load() + + Preferences.getInstance().addPreference("cura/active_mode", "simple") + Preferences.getInstance().addPreference("cura/recent_files", "") + Preferences.getInstance().addPreference("cura/categories_expanded", "") + Preferences.getInstance().addPreference("cura/jobname_prefix", True) + Preferences.getInstance().addPreference("view/center_on_select", True) + Preferences.getInstance().addPreference("mesh/scale_to_fit", True) + Preferences.getInstance().addPreference("mesh/scale_tiny_meshes", True) + Preferences.getInstance().setDefault("local_file/last_used_type", "text/x-gcode") + + Preferences.getInstance().setDefault("general/visible_settings", """ + machine_settings + resolution + layer_height + shell + wall_thickness + top_bottom_thickness + infill + infill_sparse_density + material + material_print_temperature + material_bed_temperature + material_diameter + material_flow + retraction_enable + speed + speed_print + speed_travel + travel + cooling + cool_fan_enabled + support + support_enable + support_type + support_roof_density + platform_adhesion + adhesion_type + brim_width + raft_airgap + layer_0_z_overlap + raft_surface_layers + meshfix + blackmagic + print_sequence + dual + experimental + """.replace("\n", ";").replace(" ", "")) + + JobQueue.getInstance().jobFinished.connect(self._onJobFinished) + + self.applicationShuttingDown.connect(self.saveSettings) + + self._recent_files = [] + files = Preferences.getInstance().getValue("cura/recent_files").split(";") + for f in files: + if not os.path.isfile(f): + continue + + self._recent_files.append(QUrl.fromLocalFile(f)) + + ## Cura has multiple locations where instance containers need to be saved, so we need to handle this differently. + # + # Note that the AutoSave plugin also calls this method. + def saveSettings(self): + if not self._started: # Do not do saving during application start + return + + for instance in ContainerRegistry.getInstance().findInstanceContainers(): + if not instance.isDirty(): + continue + + try: + data = instance.serialize() + except NotImplementedError: + continue + except Exception: + Logger.logException("e", "An exception occurred when serializing container %s", instance.getId()) + continue + + file_name = urllib.parse.quote_plus(instance.getId()) + ".inst.cfg" + instance_type = instance.getMetaDataEntry("type") + path = None + if instance_type == "material": + path = Resources.getStoragePath(self.ResourceTypes.MaterialInstanceContainer, file_name) + elif instance_type == "quality": + path = Resources.getStoragePath(self.ResourceTypes.QualityInstanceContainer, file_name) + elif instance_type == "user": + path = Resources.getStoragePath(self.ResourceTypes.UserInstanceContainer, file_name) + elif instance_type == "variant": + path = Resources.getStoragePath(self.ResourceTypes.VariantInstanceContainer, file_name) + + if path: + with SaveFile(path, "wt", -1, "utf-8") as f: + f.write(data) + + for stack in ContainerRegistry.getInstance().findContainerStacks(): + if not stack.isDirty(): + continue + + try: + data = stack.serialize() + except NotImplementedError: + continue + except Exception: + Logger.logException("e", "An exception occurred when serializing container %s", instance.getId()) + continue + + file_name = urllib.parse.quote_plus(stack.getId()) + ".stack.cfg" + stack_type = stack.getMetaDataEntry("type", None) + path = None + if not stack_type or stack_type == "machine": + path = Resources.getStoragePath(self.ResourceTypes.MachineStack, file_name) + elif stack_type == "extruder": + path = Resources.getStoragePath(self.ResourceTypes.ExtruderStack, file_name) + if path: + with SaveFile(path, "wt", -1, "utf-8") as f: + f.write(data) + + + @pyqtSlot(result = QUrl) + def getDefaultPath(self): + return QUrl.fromLocalFile(os.path.expanduser("~/")) + + ## Handle loading of all plugin types (and the backend explicitly) + # \sa PluginRegistery + def _loadPlugins(self): + self._plugin_registry.addType("profile_reader", self._addProfileReader) + self._plugin_registry.addPluginLocation(os.path.join(QtApplication.getInstallPrefix(), "lib", "cura")) + if not hasattr(sys, "frozen"): + self._plugin_registry.addPluginLocation(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "plugins")) + self._plugin_registry.loadPlugin("ConsoleLogger") + self._plugin_registry.loadPlugin("CuraEngineBackend") + + self._plugin_registry.loadPlugins() + + if self.getBackend() == None: + raise RuntimeError("Could not load the backend plugin!") + + self._plugins_loaded = True + + def addCommandLineOptions(self, parser): + super().addCommandLineOptions(parser) + parser.add_argument("file", nargs="*", help="Files to load after starting the application.") + parser.add_argument("--debug", dest="debug-mode", action="store_true", default=False, help="Enable detailed crash reports.") + + def run(self): + self._i18n_catalog = i18nCatalog("cura"); + + i18nCatalog.setTagReplacements({ + "filename": "font color=\"black\"", + "message": "font color=UM.Theme.colors.message_text;", + }) + + self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Setting up scene...")) + + controller = self.getController() + + controller.setActiveView("SolidView") + controller.setCameraTool("CameraTool") + controller.setSelectionTool("SelectionTool") + + t = controller.getTool("TranslateTool") + if t: + t.setEnabledAxis([ToolHandle.XAxis, ToolHandle.YAxis,ToolHandle.ZAxis]) + + Selection.selectionChanged.connect(self.onSelectionChanged) + + root = controller.getScene().getRoot() + self._platform = Platform(root) + + self._volume = BuildVolume.BuildVolume(root) + + self.getRenderer().setBackgroundColor(QColor(245, 245, 245)) + + self._physics = PlatformPhysics.PlatformPhysics(controller, self._volume) + + camera = Camera("3d", root) + camera.setPosition(Vector(-80, 250, 700)) + camera.setPerspective(True) + camera.lookAt(Vector(0, 0, 0)) + controller.getScene().setActiveCamera("3d") + + self.getController().getTool("CameraTool").setOrigin(Vector(0, 100, 0)) + + self._camera_animation = CameraAnimation.CameraAnimation() + self._camera_animation.setCameraTool(self.getController().getTool("CameraTool")) + + self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Loading interface...")) + + qmlRegisterSingletonType(MachineManagerModel.MachineManagerModel, "Cura", 1, 0, "MachineManager", + MachineManagerModel.createMachineManagerModel) + + self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml")) + self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles)) + self.initializeEngine() + + if self._engine.rootObjects: + self.closeSplash() + + for file in self.getCommandLineOption("file", []): + self._openFile(file) + for file_name in self._open_file_queue: #Open all the files that were queued up while plug-ins were loading. + self._openFile(file_name) + + self._started = True + + self.exec_() + + ## Handle Qt events + def event(self, event): + if event.type() == QEvent.FileOpen: + if self._plugins_loaded: + self._openFile(event.file()) + else: + self._open_file_queue.append(event.file()) + + return super().event(event) + + ## Get print information (duration / material used) + def getPrintInformation(self): + return self._print_information + + ## Registers objects for the QML engine to use. + # + # \param engine The QML engine. + def registerObjects(self, engine): + engine.rootContext().setContextProperty("Printer", self) + self._print_information = PrintInformation.PrintInformation() + engine.rootContext().setContextProperty("PrintInformation", self._print_information) + self._cura_actions = CuraActions.CuraActions(self) + engine.rootContext().setContextProperty("CuraActions", self._cura_actions) + + qmlRegisterUncreatableType(CuraApplication, "Cura", 1, 0, "ResourceTypes", "Just an Enum type") + + qmlRegisterType(ExtrudersModel.ExtrudersModel, "Cura", 1, 0, "ExtrudersModel") + + qmlRegisterSingletonType(QUrl.fromLocalFile(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")), "Cura", 1, 0, "Actions") + + engine.rootContext().setContextProperty("ExtruderManager", ExtruderManager.ExtruderManager.getInstance()) + + for path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.QmlFiles): + type_name = os.path.splitext(os.path.basename(path))[0] + if type_name in ("Cura", "Actions"): + continue + + qmlRegisterType(QUrl.fromLocalFile(path), "Cura", 1, 0, type_name) + + def onSelectionChanged(self): + if Selection.hasSelection(): + if not self.getController().getActiveTool(): + if self._previous_active_tool: + self.getController().setActiveTool(self._previous_active_tool) + self._previous_active_tool = None + else: + self.getController().setActiveTool("TranslateTool") + if Preferences.getInstance().getValue("view/center_on_select"): + self._center_after_select = True + else: + if self.getController().getActiveTool(): + self._previous_active_tool = self.getController().getActiveTool().getPluginId() + self.getController().setActiveTool(None) + else: + self._previous_active_tool = None + + def _onToolOperationStopped(self, event): + if self._center_after_select: + self._center_after_select = False + self._camera_animation.setStart(self.getController().getTool("CameraTool").getOrigin()) + self._camera_animation.setTarget(Selection.getSelectedObject(0).getWorldPosition()) + self._camera_animation.start() + + requestAddPrinter = pyqtSignal() + activityChanged = pyqtSignal() + sceneBoundingBoxChanged = pyqtSignal() + + @pyqtProperty(bool, notify = activityChanged) + def getPlatformActivity(self): + return self._platform_activity + + @pyqtProperty(str, notify = sceneBoundingBoxChanged) + def getSceneBoundingBoxString(self): + return self._i18n_catalog.i18nc("@info", "%(width).1f x %(depth).1f x %(height).1f mm") % {'width' : self._scene_bounding_box.width.item(), 'depth': self._scene_bounding_box.depth.item(), 'height' : self._scene_bounding_box.height.item()} + + def updatePlatformActivity(self, node = None): + count = 0 + scene_bounding_box = None + for node in DepthFirstIterator(self.getController().getScene().getRoot()): + if type(node) is not SceneNode or not node.getMeshData(): + continue + + count += 1 + if not scene_bounding_box: + scene_bounding_box = copy.deepcopy(node.getBoundingBox()) + else: + scene_bounding_box += node.getBoundingBox() + + if not scene_bounding_box: + scene_bounding_box = AxisAlignedBox() + + if repr(self._scene_bounding_box) != repr(scene_bounding_box): + self._scene_bounding_box = scene_bounding_box + self.sceneBoundingBoxChanged.emit() + + self._platform_activity = True if count > 0 else False + self.activityChanged.emit() + + # Remove all selected objects from the scene. + @pyqtSlot() + def deleteSelection(self): + if not self.getController().getToolsEnabled(): + return + + op = GroupedOperation() + nodes = Selection.getAllSelectedObjects() + for node in nodes: + op.addOperation(RemoveSceneNodeOperation(node)) + + op.push() + + pass + + ## Remove an object from the scene. + # Note that this only removes an object if it is selected. + @pyqtSlot("quint64") + def deleteObject(self, object_id): + if not self.getController().getToolsEnabled(): + return + + node = self.getController().getScene().findObject(object_id) + + if not node and object_id != 0: # Workaround for tool handles overlapping the selected object + node = Selection.getSelectedObject(0) + + if node: + if node.getParent(): + group_node = node.getParent() + if not group_node.callDecoration("isGroup"): + op = RemoveSceneNodeOperation(node) + else: + while group_node.getParent().callDecoration("isGroup"): + group_node = group_node.getParent() + op = RemoveSceneNodeOperation(group_node) + op.push() + + ## Create a number of copies of existing object. + @pyqtSlot("quint64", int) + def multiplyObject(self, object_id, count): + node = self.getController().getScene().findObject(object_id) + + if not node and object_id != 0: # Workaround for tool handles overlapping the selected object + node = Selection.getSelectedObject(0) + + if node: + op = GroupedOperation() + for _ in range(count): + if node.getParent() and node.getParent().callDecoration("isGroup"): + new_node = copy.deepcopy(node.getParent()) #Copy the group node. + new_node.callDecoration("setConvexHull",None) + + op.addOperation(AddSceneNodeOperation(new_node,node.getParent().getParent())) + else: + new_node = copy.deepcopy(node) + new_node.callDecoration("setConvexHull", None) + op.addOperation(AddSceneNodeOperation(new_node, node.getParent())) + + op.push() + + ## Center object on platform. + @pyqtSlot("quint64") + def centerObject(self, object_id): + node = self.getController().getScene().findObject(object_id) + if not node and object_id != 0: # Workaround for tool handles overlapping the selected object + node = Selection.getSelectedObject(0) + + if not node: + return + + if node.getParent() and node.getParent().callDecoration("isGroup"): + node = node.getParent() + + if node: + op = SetTransformOperation(node, Vector()) + op.push() + + ## Delete all nodes containing mesh data in the scene. + @pyqtSlot() + def deleteAll(self): + if not self.getController().getToolsEnabled(): + return + + nodes = [] + for node in DepthFirstIterator(self.getController().getScene().getRoot()): + if type(node) is not SceneNode: + continue + if not node.getMeshData() and not node.callDecoration("isGroup"): + continue # Node that doesnt have a mesh and is not a group. + if node.getParent() and node.getParent().callDecoration("isGroup"): + continue # Grouped nodes don't need resetting as their parent (the group) is resetted) + nodes.append(node) + if nodes: + op = GroupedOperation() + + for node in nodes: + op.addOperation(RemoveSceneNodeOperation(node)) + + op.push() + + ## Reset all translation on nodes with mesh data. + @pyqtSlot() + def resetAllTranslation(self): + nodes = [] + for node in DepthFirstIterator(self.getController().getScene().getRoot()): + if type(node) is not SceneNode: + continue + if not node.getMeshData() and not node.callDecoration("isGroup"): + continue # Node that doesnt have a mesh and is not a group. + if node.getParent() and node.getParent().callDecoration("isGroup"): + continue # Grouped nodes don't need resetting as their parent (the group) is resetted) + + nodes.append(node) + + if nodes: + op = GroupedOperation() + for node in nodes: + node.removeDecorator(ZOffsetDecorator.ZOffsetDecorator) + op.addOperation(SetTransformOperation(node, Vector(0,0,0))) + + op.push() + + ## Reset all transformations on nodes with mesh data. + @pyqtSlot() + def resetAll(self): + nodes = [] + for node in DepthFirstIterator(self.getController().getScene().getRoot()): + if type(node) is not SceneNode: + continue + if not node.getMeshData() and not node.callDecoration("isGroup"): + continue # Node that doesnt have a mesh and is not a group. + if node.getParent() and node.getParent().callDecoration("isGroup"): + continue # Grouped nodes don't need resetting as their parent (the group) is resetted) + nodes.append(node) + + if nodes: + op = GroupedOperation() + + for node in nodes: + # Ensure that the object is above the build platform + node.removeDecorator(ZOffsetDecorator.ZOffsetDecorator) + op.addOperation(SetTransformOperation(node, Vector(0,0,0), Quaternion(), Vector(1, 1, 1))) + + op.push() + + ## Reload all mesh data on the screen from file. + @pyqtSlot() + def reloadAll(self): + nodes = [] + for node in DepthFirstIterator(self.getController().getScene().getRoot()): + if type(node) is not SceneNode or not node.getMeshData(): + continue + + nodes.append(node) + + if not nodes: + return + + for node in nodes: + if not node.getMeshData(): + continue + + file_name = node.getMeshData().getFileName() + if file_name: + job = ReadMeshJob(file_name) + job._node = node + job.finished.connect(self._reloadMeshFinished) + job.start() + + ## Get logging data of the backend engine + # \returns \type{string} Logging data + @pyqtSlot(result = str) + def getEngineLog(self): + log = "" + + for entry in self.getBackend().getLog(): + log += entry.decode() + + return log + + recentFilesChanged = pyqtSignal() + + @pyqtProperty("QVariantList", notify = recentFilesChanged) + def recentFiles(self): + return self._recent_files + + @pyqtSlot("QStringList") + def setExpandedCategories(self, categories): + categories = list(set(categories)) + categories.sort() + joined = ";".join(categories) + if joined != Preferences.getInstance().getValue("cura/categories_expanded"): + Preferences.getInstance().setValue("cura/categories_expanded", joined) + self.expandedCategoriesChanged.emit() + + expandedCategoriesChanged = pyqtSignal() + + @pyqtProperty("QStringList", notify = expandedCategoriesChanged) + def expandedCategories(self): + return Preferences.getInstance().getValue("cura/categories_expanded").split(";") + + @pyqtSlot() + def mergeSelected(self): + self.groupSelected() + try: + group_node = Selection.getAllSelectedObjects()[0] + except Exception as e: + Logger.log("d", "mergeSelected: Exception:", e) + return + multi_material_decorator = MultiMaterialDecorator.MultiMaterialDecorator() + group_node.addDecorator(multi_material_decorator) + # Reset the position of each node + for node in group_node.getChildren(): + new_position = node.getMeshData().getCenterPosition() + new_position = new_position.scale(node.getScale()) + node.setPosition(new_position) + + # Use the previously found center of the group bounding box as the new location of the group + group_node.setPosition(group_node.getBoundingBox().center) + + @pyqtSlot() + def groupSelected(self): + # Create a group-node + group_node = SceneNode() + group_decorator = GroupDecorator() + group_node.addDecorator(group_decorator) + group_node.setParent(self.getController().getScene().getRoot()) + group_node.setSelectable(True) + center = Selection.getSelectionCenter() + group_node.setPosition(center) + group_node.setCenterPosition(center) + + # Move selected nodes into the group-node + Selection.applyOperation(SetParentOperation, group_node) + + # Deselect individual nodes and select the group-node instead + for node in group_node.getChildren(): + Selection.remove(node) + Selection.add(group_node) + + @pyqtSlot() + def ungroupSelected(self): + selected_objects = Selection.getAllSelectedObjects().copy() + for node in selected_objects: + if node.callDecoration("isGroup"): + op = GroupedOperation() + + group_parent = node.getParent() + children = node.getChildren().copy() + for child in children: + # Set the parent of the children to the parent of the group-node + op.addOperation(SetParentOperation(child, group_parent)) + + # Add all individual nodes to the selection + Selection.add(child) + child.callDecoration("setConvexHull", None) + + op.push() + # Note: The group removes itself from the scene once all its children have left it, + # see GroupDecorator._onChildrenChanged + + def _createSplashScreen(self): + return CuraSplashScreen.CuraSplashScreen() + + def _onActiveMachineChanged(self): + pass + + fileLoaded = pyqtSignal(str) + + def _onFileLoaded(self, job): + node = job.getResult() + if node != None: + self.fileLoaded.emit(job.getFileName()) + node.setSelectable(True) + node.setName(os.path.basename(job.getFileName())) + op = AddSceneNodeOperation(node, self.getController().getScene().getRoot()) + op.push() + + self.getController().getScene().sceneChanged.emit(node) #Force scene change. + + def _onJobFinished(self, job): + if type(job) is not ReadMeshJob or not job.getResult(): + return + + f = QUrl.fromLocalFile(job.getFileName()) + if f in self._recent_files: + self._recent_files.remove(f) + + self._recent_files.insert(0, f) + if len(self._recent_files) > 10: + del self._recent_files[10] + + pref = "" + for path in self._recent_files: + pref += path.toLocalFile() + ";" + + Preferences.getInstance().setValue("cura/recent_files", pref) + self.recentFilesChanged.emit() + + def _reloadMeshFinished(self, job): + # TODO; This needs to be fixed properly. We now make the assumption that we only load a single mesh! + job._node.setMeshData(job.getResult().getMeshData()) + + def _openFile(self, file): + job = ReadMeshJob(os.path.abspath(file)) + job.finished.connect(self._onFileLoaded) + job.start() + + def _addProfileReader(self, profile_reader): + # TODO: Add the profile reader to the list of plug-ins that can be used when importing profiles. + pass diff --git a/cura_app.py b/cura_app.py index 3bcce18fb5..4f61ef415d 100755 --- a/cura_app.py +++ b/cura_app.py @@ -4,6 +4,7 @@ # Cura is released under the terms of the AGPLv3 or higher. import os +import platform import sys #WORKAROUND: GITHUB-704 GITHUB-708 @@ -35,7 +36,7 @@ sys.excepthook = exceptHook import Arcus #@UnusedImport import cura.CuraApplication -if sys.platform == "win32" and hasattr(sys, "frozen"): +if platform.system() == "Windows" and hasattr(sys, "frozen"): dirpath = os.path.expanduser("~/AppData/Local/cura/") os.makedirs(dirpath, exist_ok = True) sys.stdout = open(os.path.join(dirpath, "stdout.log"), "w") From 41d03536eb2c175ce3dbdda522d338e73964c926 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Sat, 11 Jun 2016 13:16:40 +0200 Subject: [PATCH 644/705] Using a save name for variable "property" Using "property" here might be not save. Just replaced that variable with "attribute" and added a reminder, so nobody renames it to "property" again. --- cura/SettingOverrideDecorator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/SettingOverrideDecorator.py b/cura/SettingOverrideDecorator.py index e3e3555016..7615dbe873 100644 --- a/cura/SettingOverrideDecorator.py +++ b/cura/SettingOverrideDecorator.py @@ -51,8 +51,8 @@ class SettingOverrideDecorator(SceneNodeDecorator): def getActiveExtruder(self): return self._extruder_stack - def _onSettingChanged(self, instance, property): - if property == "value": # Only reslice if the value has changed. + def _onSettingChanged(self, instance, attribute): # Reminder: 'property' is a built-in function + if attribute == "value": # Only reslice if the value has changed. Application.getInstance().getBackend().forceSlice() ## Makes sure that the stack upon which the container stack is placed is From c38e31f0e35dd3a28c58b45b3c36af7f3ecd6941 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Sat, 11 Jun 2016 13:21:52 +0200 Subject: [PATCH 645/705] BuildVolume: Remove worthless line Just a small clean up. skirt_size was initialized twice. --- cura/BuildVolume.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index 61802167a7..f071bf4057 100644 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -199,7 +199,6 @@ class BuildVolume(SceneNode): disallowed_areas = self._active_container_stack.getProperty("machine_disallowed_areas", "value") areas = [] - skirt_size = 0.0 skirt_size = self._getSkirtSize(self._active_container_stack) if disallowed_areas: From f11ef0c0c06a9b599566304964b4c2e7afbca959 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Sat, 11 Jun 2016 13:42:09 +0200 Subject: [PATCH 646/705] Using UM.Platform for Windows detection The diff says everything. --- cura_app.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura_app.py b/cura_app.py index 4f61ef415d..6b9f006d95 100755 --- a/cura_app.py +++ b/cura_app.py @@ -4,7 +4,6 @@ # Cura is released under the terms of the AGPLv3 or higher. import os -import platform import sys #WORKAROUND: GITHUB-704 GITHUB-708 @@ -34,9 +33,10 @@ sys.excepthook = exceptHook # first seems to prevent Sip from going into a state where it # tries to create PyQt objects on a non-main thread. import Arcus #@UnusedImport +from UM.Platform import Platform import cura.CuraApplication -if platform.system() == "Windows" and hasattr(sys, "frozen"): +if Platform.isWindows() and hasattr(sys, "frozen"): dirpath = os.path.expanduser("~/AppData/Local/cura/") os.makedirs(dirpath, exist_ok = True) sys.stdout = open(os.path.join(dirpath, "stdout.log"), "w") From b047db36fdd750384c81b51ed864e1055c7d1c00 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Sat, 11 Jun 2016 13:43:50 +0200 Subject: [PATCH 647/705] Using isLinux() for Linux detection Of course there are more places where we can replace these checks. --- cura/CuraApplication.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 15c41f9c56..7431feed00 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -14,6 +14,7 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Mesh.ReadMeshJob import ReadMeshJob from UM.Logger import Logger from UM.Preferences import Preferences +from UM.Platform import Platform from UM.JobQueue import JobQueue from UM.SaveFile import SaveFile from UM.Scene.Selection import Selection @@ -58,7 +59,7 @@ import urllib numpy.seterr(all="ignore") #WORKAROUND: GITHUB-88 GITHUB-385 GITHUB-612 -if platform.system() == "Linux": # Needed for platform.linux_distribution, which is not available on Windows and OSX +if Platform.isLinux(): # Needed for platform.linux_distribution, which is not available on Windows and OSX # For Ubuntu: https://bugs.launchpad.net/ubuntu/+source/python-qt4/+bug/941826 if platform.linux_distribution()[0] in ("Ubuntu", ): # TODO: Needs a "if X11_GFX == 'nvidia'" here. The workaround is only needed on Ubuntu+NVidia drivers. Other drivers are not affected, but fine with this fix. import ctypes From a9671cdcfd0686010951aedea02c2facaf8efd9f Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Sat, 11 Jun 2016 23:00:44 +0200 Subject: [PATCH 648/705] Deleting a backup This removes a backup, which I made when switching between git branches. --- cura/CuraApplication2.py | 784 --------------------------------------- 1 file changed, 784 deletions(-) delete mode 100644 cura/CuraApplication2.py diff --git a/cura/CuraApplication2.py b/cura/CuraApplication2.py deleted file mode 100644 index 85c269fc8b..0000000000 --- a/cura/CuraApplication2.py +++ /dev/null @@ -1,784 +0,0 @@ -# Copyright (c) 2015 Ultimaker B.V. -# Cura is released under the terms of the AGPLv3 or higher. - -from memory_profiler import profile - -from UM.Qt.QtApplication import QtApplication -from UM.Scene.SceneNode import SceneNode -from UM.Scene.Camera import Camera -from UM.Scene.Platform import Platform -from UM.Math.Vector import Vector -from UM.Math.Quaternion import Quaternion -from UM.Math.AxisAlignedBox import AxisAlignedBox -from UM.Resources import Resources -from UM.Scene.ToolHandle import ToolHandle -from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator -from UM.Mesh.ReadMeshJob import ReadMeshJob -from UM.Logger import Logger -from UM.Preferences import Preferences -from UM.JobQueue import JobQueue -from UM.SaveFile import SaveFile -from UM.Scene.Selection import Selection -from UM.Scene.GroupDecorator import GroupDecorator -import UM.Settings.Validator - -from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation -from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation -from UM.Operations.GroupedOperation import GroupedOperation -from UM.Operations.SetTransformOperation import SetTransformOperation -from cura.SetParentOperation import SetParentOperation - -from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyType -from UM.Settings.ContainerRegistry import ContainerRegistry - -from UM.i18n import i18nCatalog - -from . import ExtruderManager -from . import ExtrudersModel -from . import PlatformPhysics -from . import BuildVolume -from . import CameraAnimation -from . import PrintInformation -from . import CuraActions -from . import MultiMaterialDecorator -from . import ZOffsetDecorator -from . import CuraSplashScreen -from . import MachineManagerModel - -from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty, QEvent, Q_ENUMS -from PyQt5.QtGui import QColor, QIcon -from PyQt5.QtQml import qmlRegisterUncreatableType, qmlRegisterSingletonType, qmlRegisterType - -import platform -import sys -import os.path -import numpy -import copy -import urllib -numpy.seterr(all="ignore") - -#WORKAROUND: GITHUB-88 GITHUB-385 GITHUB-612 -if platform.system() == "Linux": # Needed for platform.linux_distribution, which is not available on Windows and OSX - # For Ubuntu: https://bugs.launchpad.net/ubuntu/+source/python-qt4/+bug/941826 - if platform.linux_distribution()[0] in ("Ubuntu", ): # TODO: Needs a "if X11_GFX == 'nvidia'" here. The workaround is only needed on Ubuntu+NVidia drivers. Other drivers are not affected, but fine with this fix. - import ctypes - from ctypes.util import find_library - ctypes.CDLL(find_library('GL'), ctypes.RTLD_GLOBAL) - -try: - from cura.CuraVersion import CuraVersion, CuraBuildType -except ImportError: - CuraVersion = "master" # [CodeStyle: Reflecting imported value] - CuraBuildType = "" - -@profile -class CuraApplication(QtApplication): - class ResourceTypes: - QmlFiles = Resources.UserType + 1 - Firmware = Resources.UserType + 2 - QualityInstanceContainer = Resources.UserType + 3 - MaterialInstanceContainer = Resources.UserType + 4 - VariantInstanceContainer = Resources.UserType + 5 - UserInstanceContainer = Resources.UserType + 6 - MachineStack = Resources.UserType + 7 - ExtruderStack = Resources.UserType + 8 - - Q_ENUMS(ResourceTypes) - - def __init__(self): - Resources.addSearchPath(os.path.join(QtApplication.getInstallPrefix(), "share", "cura", "resources")) - if not hasattr(sys, "frozen"): - Resources.addSearchPath(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "resources")) - - self._open_file_queue = [] # Files to open when plug-ins are loaded. - - # Need to do this before ContainerRegistry tries to load the machines - SettingDefinition.addSupportedProperty("global_only", DefinitionPropertyType.Function, default = False) - SettingDefinition.addSettingType("extruder", int, str, UM.Settings.Validator) - - super().__init__(name = "cura", version = CuraVersion, buildtype = CuraBuildType) - - self.setWindowIcon(QIcon(Resources.getPath(Resources.Images, "cura-icon.png"))) - - self.setRequiredPlugins([ - "CuraEngineBackend", - "MeshView", - "LayerView", - "STLReader", - "SelectionTool", - "CameraTool", - "GCodeWriter", - "LocalFileOutputDevice" - ]) - self._physics = None - self._volume = None - self._platform = None - self._output_devices = {} - self._print_information = None - self._i18n_catalog = None - self._previous_active_tool = None - self._platform_activity = False - self._scene_bounding_box = AxisAlignedBox() - self._job_name = None - self._center_after_select = False - self._camera_animation = None - self._cura_actions = None - self._started = False - - self.getController().getScene().sceneChanged.connect(self.updatePlatformActivity) - self.getController().toolOperationStopped.connect(self._onToolOperationStopped) - - Resources.addType(self.ResourceTypes.QmlFiles, "qml") - Resources.addType(self.ResourceTypes.Firmware, "firmware") - - ## Add the 4 types of profiles to storage. - Resources.addStorageType(self.ResourceTypes.QualityInstanceContainer, "quality") - Resources.addStorageType(self.ResourceTypes.VariantInstanceContainer, "variants") - Resources.addStorageType(self.ResourceTypes.MaterialInstanceContainer, "materials") - Resources.addStorageType(self.ResourceTypes.UserInstanceContainer, "user") - Resources.addStorageType(self.ResourceTypes.ExtruderStack, "extruders") - Resources.addStorageType(self.ResourceTypes.MachineStack, "machine_instances") - - ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.QualityInstanceContainer) - ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.VariantInstanceContainer) - ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MaterialInstanceContainer) - ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.UserInstanceContainer) - ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.ExtruderStack) - ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MachineStack) - - # Add empty variant, material and quality containers. - # Since they are empty, they should never be serialized and instead just programmatically created. - # We need them to simplify the switching between materials. - empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer() - empty_variant_container = copy.deepcopy(empty_container) - empty_variant_container._id = "empty_variant" - empty_variant_container.addMetaDataEntry("type", "variant") - ContainerRegistry.getInstance().addContainer(empty_variant_container) - empty_material_container = copy.deepcopy(empty_container) - empty_material_container._id = "empty_material" - empty_material_container.addMetaDataEntry("type", "material") - ContainerRegistry.getInstance().addContainer(empty_material_container) - empty_quality_container = copy.deepcopy(empty_container) - empty_quality_container._id = "empty_quality" - empty_quality_container.addMetaDataEntry("type", "quality") - ContainerRegistry.getInstance().addContainer(empty_quality_container) - - ContainerRegistry.getInstance().load() - - Preferences.getInstance().addPreference("cura/active_mode", "simple") - Preferences.getInstance().addPreference("cura/recent_files", "") - Preferences.getInstance().addPreference("cura/categories_expanded", "") - Preferences.getInstance().addPreference("cura/jobname_prefix", True) - Preferences.getInstance().addPreference("view/center_on_select", True) - Preferences.getInstance().addPreference("mesh/scale_to_fit", True) - Preferences.getInstance().addPreference("mesh/scale_tiny_meshes", True) - Preferences.getInstance().setDefault("local_file/last_used_type", "text/x-gcode") - - Preferences.getInstance().setDefault("general/visible_settings", """ - machine_settings - resolution - layer_height - shell - wall_thickness - top_bottom_thickness - infill - infill_sparse_density - material - material_print_temperature - material_bed_temperature - material_diameter - material_flow - retraction_enable - speed - speed_print - speed_travel - travel - cooling - cool_fan_enabled - support - support_enable - support_type - support_roof_density - platform_adhesion - adhesion_type - brim_width - raft_airgap - layer_0_z_overlap - raft_surface_layers - meshfix - blackmagic - print_sequence - dual - experimental - """.replace("\n", ";").replace(" ", "")) - - JobQueue.getInstance().jobFinished.connect(self._onJobFinished) - - self.applicationShuttingDown.connect(self.saveSettings) - - self._recent_files = [] - files = Preferences.getInstance().getValue("cura/recent_files").split(";") - for f in files: - if not os.path.isfile(f): - continue - - self._recent_files.append(QUrl.fromLocalFile(f)) - - ## Cura has multiple locations where instance containers need to be saved, so we need to handle this differently. - # - # Note that the AutoSave plugin also calls this method. - def saveSettings(self): - if not self._started: # Do not do saving during application start - return - - for instance in ContainerRegistry.getInstance().findInstanceContainers(): - if not instance.isDirty(): - continue - - try: - data = instance.serialize() - except NotImplementedError: - continue - except Exception: - Logger.logException("e", "An exception occurred when serializing container %s", instance.getId()) - continue - - file_name = urllib.parse.quote_plus(instance.getId()) + ".inst.cfg" - instance_type = instance.getMetaDataEntry("type") - path = None - if instance_type == "material": - path = Resources.getStoragePath(self.ResourceTypes.MaterialInstanceContainer, file_name) - elif instance_type == "quality": - path = Resources.getStoragePath(self.ResourceTypes.QualityInstanceContainer, file_name) - elif instance_type == "user": - path = Resources.getStoragePath(self.ResourceTypes.UserInstanceContainer, file_name) - elif instance_type == "variant": - path = Resources.getStoragePath(self.ResourceTypes.VariantInstanceContainer, file_name) - - if path: - with SaveFile(path, "wt", -1, "utf-8") as f: - f.write(data) - - for stack in ContainerRegistry.getInstance().findContainerStacks(): - if not stack.isDirty(): - continue - - try: - data = stack.serialize() - except NotImplementedError: - continue - except Exception: - Logger.logException("e", "An exception occurred when serializing container %s", instance.getId()) - continue - - file_name = urllib.parse.quote_plus(stack.getId()) + ".stack.cfg" - stack_type = stack.getMetaDataEntry("type", None) - path = None - if not stack_type or stack_type == "machine": - path = Resources.getStoragePath(self.ResourceTypes.MachineStack, file_name) - elif stack_type == "extruder": - path = Resources.getStoragePath(self.ResourceTypes.ExtruderStack, file_name) - if path: - with SaveFile(path, "wt", -1, "utf-8") as f: - f.write(data) - - - @pyqtSlot(result = QUrl) - def getDefaultPath(self): - return QUrl.fromLocalFile(os.path.expanduser("~/")) - - ## Handle loading of all plugin types (and the backend explicitly) - # \sa PluginRegistery - def _loadPlugins(self): - self._plugin_registry.addType("profile_reader", self._addProfileReader) - self._plugin_registry.addPluginLocation(os.path.join(QtApplication.getInstallPrefix(), "lib", "cura")) - if not hasattr(sys, "frozen"): - self._plugin_registry.addPluginLocation(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "plugins")) - self._plugin_registry.loadPlugin("ConsoleLogger") - self._plugin_registry.loadPlugin("CuraEngineBackend") - - self._plugin_registry.loadPlugins() - - if self.getBackend() == None: - raise RuntimeError("Could not load the backend plugin!") - - self._plugins_loaded = True - - def addCommandLineOptions(self, parser): - super().addCommandLineOptions(parser) - parser.add_argument("file", nargs="*", help="Files to load after starting the application.") - parser.add_argument("--debug", dest="debug-mode", action="store_true", default=False, help="Enable detailed crash reports.") - - def run(self): - self._i18n_catalog = i18nCatalog("cura"); - - i18nCatalog.setTagReplacements({ - "filename": "font color=\"black\"", - "message": "font color=UM.Theme.colors.message_text;", - }) - - self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Setting up scene...")) - - controller = self.getController() - - controller.setActiveView("SolidView") - controller.setCameraTool("CameraTool") - controller.setSelectionTool("SelectionTool") - - t = controller.getTool("TranslateTool") - if t: - t.setEnabledAxis([ToolHandle.XAxis, ToolHandle.YAxis,ToolHandle.ZAxis]) - - Selection.selectionChanged.connect(self.onSelectionChanged) - - root = controller.getScene().getRoot() - self._platform = Platform(root) - - self._volume = BuildVolume.BuildVolume(root) - - self.getRenderer().setBackgroundColor(QColor(245, 245, 245)) - - self._physics = PlatformPhysics.PlatformPhysics(controller, self._volume) - - camera = Camera("3d", root) - camera.setPosition(Vector(-80, 250, 700)) - camera.setPerspective(True) - camera.lookAt(Vector(0, 0, 0)) - controller.getScene().setActiveCamera("3d") - - self.getController().getTool("CameraTool").setOrigin(Vector(0, 100, 0)) - - self._camera_animation = CameraAnimation.CameraAnimation() - self._camera_animation.setCameraTool(self.getController().getTool("CameraTool")) - - self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Loading interface...")) - - qmlRegisterSingletonType(MachineManagerModel.MachineManagerModel, "Cura", 1, 0, "MachineManager", - MachineManagerModel.createMachineManagerModel) - - self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml")) - self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles)) - self.initializeEngine() - - if self._engine.rootObjects: - self.closeSplash() - - for file in self.getCommandLineOption("file", []): - self._openFile(file) - for file_name in self._open_file_queue: #Open all the files that were queued up while plug-ins were loading. - self._openFile(file_name) - - self._started = True - - self.exec_() - - ## Handle Qt events - def event(self, event): - if event.type() == QEvent.FileOpen: - if self._plugins_loaded: - self._openFile(event.file()) - else: - self._open_file_queue.append(event.file()) - - return super().event(event) - - ## Get print information (duration / material used) - def getPrintInformation(self): - return self._print_information - - ## Registers objects for the QML engine to use. - # - # \param engine The QML engine. - def registerObjects(self, engine): - engine.rootContext().setContextProperty("Printer", self) - self._print_information = PrintInformation.PrintInformation() - engine.rootContext().setContextProperty("PrintInformation", self._print_information) - self._cura_actions = CuraActions.CuraActions(self) - engine.rootContext().setContextProperty("CuraActions", self._cura_actions) - - qmlRegisterUncreatableType(CuraApplication, "Cura", 1, 0, "ResourceTypes", "Just an Enum type") - - qmlRegisterType(ExtrudersModel.ExtrudersModel, "Cura", 1, 0, "ExtrudersModel") - - qmlRegisterSingletonType(QUrl.fromLocalFile(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")), "Cura", 1, 0, "Actions") - - engine.rootContext().setContextProperty("ExtruderManager", ExtruderManager.ExtruderManager.getInstance()) - - for path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.QmlFiles): - type_name = os.path.splitext(os.path.basename(path))[0] - if type_name in ("Cura", "Actions"): - continue - - qmlRegisterType(QUrl.fromLocalFile(path), "Cura", 1, 0, type_name) - - def onSelectionChanged(self): - if Selection.hasSelection(): - if not self.getController().getActiveTool(): - if self._previous_active_tool: - self.getController().setActiveTool(self._previous_active_tool) - self._previous_active_tool = None - else: - self.getController().setActiveTool("TranslateTool") - if Preferences.getInstance().getValue("view/center_on_select"): - self._center_after_select = True - else: - if self.getController().getActiveTool(): - self._previous_active_tool = self.getController().getActiveTool().getPluginId() - self.getController().setActiveTool(None) - else: - self._previous_active_tool = None - - def _onToolOperationStopped(self, event): - if self._center_after_select: - self._center_after_select = False - self._camera_animation.setStart(self.getController().getTool("CameraTool").getOrigin()) - self._camera_animation.setTarget(Selection.getSelectedObject(0).getWorldPosition()) - self._camera_animation.start() - - requestAddPrinter = pyqtSignal() - activityChanged = pyqtSignal() - sceneBoundingBoxChanged = pyqtSignal() - - @pyqtProperty(bool, notify = activityChanged) - def getPlatformActivity(self): - return self._platform_activity - - @pyqtProperty(str, notify = sceneBoundingBoxChanged) - def getSceneBoundingBoxString(self): - return self._i18n_catalog.i18nc("@info", "%(width).1f x %(depth).1f x %(height).1f mm") % {'width' : self._scene_bounding_box.width.item(), 'depth': self._scene_bounding_box.depth.item(), 'height' : self._scene_bounding_box.height.item()} - - def updatePlatformActivity(self, node = None): - count = 0 - scene_bounding_box = None - for node in DepthFirstIterator(self.getController().getScene().getRoot()): - if type(node) is not SceneNode or not node.getMeshData(): - continue - - count += 1 - if not scene_bounding_box: - scene_bounding_box = copy.deepcopy(node.getBoundingBox()) - else: - scene_bounding_box += node.getBoundingBox() - - if not scene_bounding_box: - scene_bounding_box = AxisAlignedBox() - - if repr(self._scene_bounding_box) != repr(scene_bounding_box): - self._scene_bounding_box = scene_bounding_box - self.sceneBoundingBoxChanged.emit() - - self._platform_activity = True if count > 0 else False - self.activityChanged.emit() - - # Remove all selected objects from the scene. - @pyqtSlot() - def deleteSelection(self): - if not self.getController().getToolsEnabled(): - return - - op = GroupedOperation() - nodes = Selection.getAllSelectedObjects() - for node in nodes: - op.addOperation(RemoveSceneNodeOperation(node)) - - op.push() - - pass - - ## Remove an object from the scene. - # Note that this only removes an object if it is selected. - @pyqtSlot("quint64") - def deleteObject(self, object_id): - if not self.getController().getToolsEnabled(): - return - - node = self.getController().getScene().findObject(object_id) - - if not node and object_id != 0: # Workaround for tool handles overlapping the selected object - node = Selection.getSelectedObject(0) - - if node: - if node.getParent(): - group_node = node.getParent() - if not group_node.callDecoration("isGroup"): - op = RemoveSceneNodeOperation(node) - else: - while group_node.getParent().callDecoration("isGroup"): - group_node = group_node.getParent() - op = RemoveSceneNodeOperation(group_node) - op.push() - - ## Create a number of copies of existing object. - @pyqtSlot("quint64", int) - def multiplyObject(self, object_id, count): - node = self.getController().getScene().findObject(object_id) - - if not node and object_id != 0: # Workaround for tool handles overlapping the selected object - node = Selection.getSelectedObject(0) - - if node: - op = GroupedOperation() - for _ in range(count): - if node.getParent() and node.getParent().callDecoration("isGroup"): - new_node = copy.deepcopy(node.getParent()) #Copy the group node. - new_node.callDecoration("setConvexHull",None) - - op.addOperation(AddSceneNodeOperation(new_node,node.getParent().getParent())) - else: - new_node = copy.deepcopy(node) - new_node.callDecoration("setConvexHull", None) - op.addOperation(AddSceneNodeOperation(new_node, node.getParent())) - - op.push() - - ## Center object on platform. - @pyqtSlot("quint64") - def centerObject(self, object_id): - node = self.getController().getScene().findObject(object_id) - if not node and object_id != 0: # Workaround for tool handles overlapping the selected object - node = Selection.getSelectedObject(0) - - if not node: - return - - if node.getParent() and node.getParent().callDecoration("isGroup"): - node = node.getParent() - - if node: - op = SetTransformOperation(node, Vector()) - op.push() - - ## Delete all nodes containing mesh data in the scene. - @pyqtSlot() - def deleteAll(self): - if not self.getController().getToolsEnabled(): - return - - nodes = [] - for node in DepthFirstIterator(self.getController().getScene().getRoot()): - if type(node) is not SceneNode: - continue - if not node.getMeshData() and not node.callDecoration("isGroup"): - continue # Node that doesnt have a mesh and is not a group. - if node.getParent() and node.getParent().callDecoration("isGroup"): - continue # Grouped nodes don't need resetting as their parent (the group) is resetted) - nodes.append(node) - if nodes: - op = GroupedOperation() - - for node in nodes: - op.addOperation(RemoveSceneNodeOperation(node)) - - op.push() - - ## Reset all translation on nodes with mesh data. - @pyqtSlot() - def resetAllTranslation(self): - nodes = [] - for node in DepthFirstIterator(self.getController().getScene().getRoot()): - if type(node) is not SceneNode: - continue - if not node.getMeshData() and not node.callDecoration("isGroup"): - continue # Node that doesnt have a mesh and is not a group. - if node.getParent() and node.getParent().callDecoration("isGroup"): - continue # Grouped nodes don't need resetting as their parent (the group) is resetted) - - nodes.append(node) - - if nodes: - op = GroupedOperation() - for node in nodes: - node.removeDecorator(ZOffsetDecorator.ZOffsetDecorator) - op.addOperation(SetTransformOperation(node, Vector(0,0,0))) - - op.push() - - ## Reset all transformations on nodes with mesh data. - @pyqtSlot() - def resetAll(self): - nodes = [] - for node in DepthFirstIterator(self.getController().getScene().getRoot()): - if type(node) is not SceneNode: - continue - if not node.getMeshData() and not node.callDecoration("isGroup"): - continue # Node that doesnt have a mesh and is not a group. - if node.getParent() and node.getParent().callDecoration("isGroup"): - continue # Grouped nodes don't need resetting as their parent (the group) is resetted) - nodes.append(node) - - if nodes: - op = GroupedOperation() - - for node in nodes: - # Ensure that the object is above the build platform - node.removeDecorator(ZOffsetDecorator.ZOffsetDecorator) - op.addOperation(SetTransformOperation(node, Vector(0,0,0), Quaternion(), Vector(1, 1, 1))) - - op.push() - - ## Reload all mesh data on the screen from file. - @pyqtSlot() - def reloadAll(self): - nodes = [] - for node in DepthFirstIterator(self.getController().getScene().getRoot()): - if type(node) is not SceneNode or not node.getMeshData(): - continue - - nodes.append(node) - - if not nodes: - return - - for node in nodes: - if not node.getMeshData(): - continue - - file_name = node.getMeshData().getFileName() - if file_name: - job = ReadMeshJob(file_name) - job._node = node - job.finished.connect(self._reloadMeshFinished) - job.start() - - ## Get logging data of the backend engine - # \returns \type{string} Logging data - @pyqtSlot(result = str) - def getEngineLog(self): - log = "" - - for entry in self.getBackend().getLog(): - log += entry.decode() - - return log - - recentFilesChanged = pyqtSignal() - - @pyqtProperty("QVariantList", notify = recentFilesChanged) - def recentFiles(self): - return self._recent_files - - @pyqtSlot("QStringList") - def setExpandedCategories(self, categories): - categories = list(set(categories)) - categories.sort() - joined = ";".join(categories) - if joined != Preferences.getInstance().getValue("cura/categories_expanded"): - Preferences.getInstance().setValue("cura/categories_expanded", joined) - self.expandedCategoriesChanged.emit() - - expandedCategoriesChanged = pyqtSignal() - - @pyqtProperty("QStringList", notify = expandedCategoriesChanged) - def expandedCategories(self): - return Preferences.getInstance().getValue("cura/categories_expanded").split(";") - - @pyqtSlot() - def mergeSelected(self): - self.groupSelected() - try: - group_node = Selection.getAllSelectedObjects()[0] - except Exception as e: - Logger.log("d", "mergeSelected: Exception:", e) - return - multi_material_decorator = MultiMaterialDecorator.MultiMaterialDecorator() - group_node.addDecorator(multi_material_decorator) - # Reset the position of each node - for node in group_node.getChildren(): - new_position = node.getMeshData().getCenterPosition() - new_position = new_position.scale(node.getScale()) - node.setPosition(new_position) - - # Use the previously found center of the group bounding box as the new location of the group - group_node.setPosition(group_node.getBoundingBox().center) - - @pyqtSlot() - def groupSelected(self): - # Create a group-node - group_node = SceneNode() - group_decorator = GroupDecorator() - group_node.addDecorator(group_decorator) - group_node.setParent(self.getController().getScene().getRoot()) - group_node.setSelectable(True) - center = Selection.getSelectionCenter() - group_node.setPosition(center) - group_node.setCenterPosition(center) - - # Move selected nodes into the group-node - Selection.applyOperation(SetParentOperation, group_node) - - # Deselect individual nodes and select the group-node instead - for node in group_node.getChildren(): - Selection.remove(node) - Selection.add(group_node) - - @pyqtSlot() - def ungroupSelected(self): - selected_objects = Selection.getAllSelectedObjects().copy() - for node in selected_objects: - if node.callDecoration("isGroup"): - op = GroupedOperation() - - group_parent = node.getParent() - children = node.getChildren().copy() - for child in children: - # Set the parent of the children to the parent of the group-node - op.addOperation(SetParentOperation(child, group_parent)) - - # Add all individual nodes to the selection - Selection.add(child) - child.callDecoration("setConvexHull", None) - - op.push() - # Note: The group removes itself from the scene once all its children have left it, - # see GroupDecorator._onChildrenChanged - - def _createSplashScreen(self): - return CuraSplashScreen.CuraSplashScreen() - - def _onActiveMachineChanged(self): - pass - - fileLoaded = pyqtSignal(str) - - def _onFileLoaded(self, job): - node = job.getResult() - if node != None: - self.fileLoaded.emit(job.getFileName()) - node.setSelectable(True) - node.setName(os.path.basename(job.getFileName())) - op = AddSceneNodeOperation(node, self.getController().getScene().getRoot()) - op.push() - - self.getController().getScene().sceneChanged.emit(node) #Force scene change. - - def _onJobFinished(self, job): - if type(job) is not ReadMeshJob or not job.getResult(): - return - - f = QUrl.fromLocalFile(job.getFileName()) - if f in self._recent_files: - self._recent_files.remove(f) - - self._recent_files.insert(0, f) - if len(self._recent_files) > 10: - del self._recent_files[10] - - pref = "" - for path in self._recent_files: - pref += path.toLocalFile() + ";" - - Preferences.getInstance().setValue("cura/recent_files", pref) - self.recentFilesChanged.emit() - - def _reloadMeshFinished(self, job): - # TODO; This needs to be fixed properly. We now make the assumption that we only load a single mesh! - job._node.setMeshData(job.getResult().getMeshData()) - - def _openFile(self, file): - job = ReadMeshJob(os.path.abspath(file)) - job.finished.connect(self._onFileLoaded) - job.start() - - def _addProfileReader(self, profile_reader): - # TODO: Add the profile reader to the list of plug-ins that can be used when importing profiles. - pass From 6d43ec700d2c28f326c0764024bc802b7e3467ec Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Sun, 12 Jun 2016 11:02:15 +0200 Subject: [PATCH 649/705] CuraEngineBackend: Using Platform.isWindows() --- plugins/CuraEngineBackend/CuraEngineBackend.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 80f2614e87..f530091ba0 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -11,6 +11,7 @@ from UM.Message import Message from UM.PluginRegistry import PluginRegistry from UM.Resources import Resources from UM.Settings.Validator import ValidatorState #To find if a setting is in an error state. We can't slice then. +from UM.Platform import Platform from cura.ExtruderManager import ExtruderManager @@ -42,7 +43,7 @@ class CuraEngineBackend(Backend): default_engine_location = os.path.join(Application.getInstallPrefix(), "bin", "CuraEngine") if hasattr(sys, "frozen"): default_engine_location = os.path.join(os.path.dirname(os.path.abspath(sys.executable)), "CuraEngine") - if sys.platform == "win32": + if Platform.isWindows(): default_engine_location += ".exe" default_engine_location = os.path.abspath(default_engine_location) Preferences.getInstance().addPreference("backend/location", default_engine_location) From 3df124e3cfc4a228c10b3543de38312e8b4a14de Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Sun, 12 Jun 2016 12:46:19 +0200 Subject: [PATCH 650/705] CuraEngineBackend: Removing duplicate close() close() is already defined in this class. This removes the useless code. --- plugins/CuraEngineBackend/CuraEngineBackend.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 80f2614e87..9d2addabe8 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -112,9 +112,6 @@ class CuraEngineBackend(Backend): json_path = Resources.getPath(Resources.DefinitionContainers, "fdmprinter.def.json") return [Preferences.getInstance().getValue("backend/location"), "connect", "127.0.0.1:{0}".format(self._port), "-j", json_path, "-vv"] - def close(self): - self._terminate() # Forcefully shutdown the backend. - ## Emitted when we get a message containing print duration and material amount. This also implies the slicing has finished. # \param time The amount of time the print will take. # \param material_amount The amount of material the print will use. From 293d7c06d955aa9a2e1d42fdac4df37acd744013 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sun, 12 Jun 2016 13:55:47 +0200 Subject: [PATCH 651/705] Revert "Use callLater to set the active machine in MachineManager" This reverts commit 0aea7bdb5c67e7dde3be31cfd1a8d48b72c5d322. Advanced mode showed no settings, and things were generally not working after this commit, so I am reverting the change for now. --- cura/MachineManagerModel.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 4667777b68..321f5af486 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -51,7 +51,8 @@ class MachineManagerModel(QObject): if active_machine_id != "": # An active machine was saved, so restore it. - Application.getInstance().callLater(self.setActiveMachine, active_machine_id) + self.setActiveMachine(active_machine_id) + pass globalContainerChanged = pyqtSignal() activeMaterialChanged = pyqtSignal() From 168415554debc1a70f09eabee21134abcdb3ba3a Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sun, 12 Jun 2016 13:56:37 +0200 Subject: [PATCH 652/705] Typo and codestyle --- cura/ExtruderManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 84c3028c72..da5887be61 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -18,7 +18,7 @@ class ExtruderManager(QObject): ## Notify when the user switches the currently active extruder. activeExtruderChanged = pyqtSignal() - ## Registers listeners and such to listen to chafnges to the extruders. + ## Registers listeners and such to listen to changes to the extruders. def __init__(self, parent = None): super().__init__(parent) self._extruder_trains = { } #Per machine, a dictionary of extruder container stack IDs. @@ -100,7 +100,7 @@ class ExtruderManager(QObject): for extruder_train in extruder_trains: self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train - ## Ensure that the extruder train stacks are linked to global stack. + #Ensure that the extruder train stacks are linked to global stack. extruder_train.setNextStack(UM.Application.getInstance().getGlobalContainerStack()) if extruder_trains: From 17d1dbd804504114693cd68eed2a6bca53f1e512 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sun, 12 Jun 2016 14:26:12 +0200 Subject: [PATCH 653/705] Fix updating the sidebar when a setting is changed in an extruder CURA-1585 --- cura/MachineManagerModel.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 321f5af486..4464ceffc2 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -102,8 +102,15 @@ class MachineManagerModel(QObject): self._global_stack_valid = not self._checkStackForErrors(self._global_container_stack) def _onActiveExtruderStackChanged(self): + 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._onGlobalPropertyChanged) + self._active_container_stack = ExtruderManager.ExtruderManager.getInstance().getActiveExtruderStack() - if not self._active_container_stack: + if self._active_container_stack: + self._active_container_stack.containersChanged.connect(self._onInstanceContainersChanged) + self._active_container_stack.propertyChanged.connect(self._onGlobalPropertyChanged) + else: self._active_container_stack = self._global_container_stack def _onInstanceContainersChanged(self, container): From aeccfe3509b37c184a24a88864c3550beebb45b1 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sun, 12 Jun 2016 15:25:39 +0200 Subject: [PATCH 654/705] Rearrange preferences Merges general & view into a single page Introduces sections on general page Cleans up code --- resources/qml/Cura.qml | 19 +-- .../qml/{ => Preferences}/GeneralPage.qml | 150 +++++++++++++++--- .../qml/{ => Preferences}/MachinesPage.qml | 0 resources/qml/ViewPage.qml | 96 ----------- 4 files changed, 138 insertions(+), 127 deletions(-) rename resources/qml/{ => Preferences}/GeneralPage.qml (66%) rename resources/qml/{ => Preferences}/MachinesPage.qml (100%) delete mode 100644 resources/qml/ViewPage.qml diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index c3dc95b454..6dd57e17c8 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -545,16 +545,13 @@ UM.MainWindow { //; Remove & re-add the general page as we want to use our own instead of uranium standard. removePage(0); - insertPage(0, catalog.i18nc("@title:tab","General"), Qt.resolvedUrl("GeneralPage.qml")); + insertPage(0, catalog.i18nc("@title:tab","General"), Qt.resolvedUrl("Preferences/GeneralPage.qml")); - //: View preferences page title - insertPage(1, catalog.i18nc("@title:tab","View"), Qt.resolvedUrl("ViewPage.qml")); + insertPage(2, catalog.i18nc("@title:tab", "Printers"), Qt.resolvedUrl("Preferences/MachinesPage.qml")); - insertPage(3, catalog.i18nc("@title:tab", "Printers"), Qt.resolvedUrl("MachinesPage.qml")); + insertPage(3, catalog.i18nc("@title:tab", "Materials"), Qt.resolvedUrl("Preferences/MaterialsPage.qml")); - insertPage(4, catalog.i18nc("@title:tab", "Materials"), Qt.resolvedUrl("Preferences/MaterialsPage.qml")); - - insertPage(5, catalog.i18nc("@title:tab", "Profiles"), Qt.resolvedUrl("Preferences/ProfilesPage.qml")); + insertPage(4, catalog.i18nc("@title:tab", "Profiles"), Qt.resolvedUrl("Preferences/ProfilesPage.qml")); //Force refresh setPage(0); @@ -583,7 +580,7 @@ UM.MainWindow onTriggered: { Cura.MachineManager.newQualityContainerFromQualityAndUser(); - preferences.setPage(5); + preferences.setPage(4); preferences.show(); // Show the renameDialog after a very short delay so the preference page has time to initiate @@ -597,7 +594,7 @@ UM.MainWindow onTriggered: { preferences.visible = true; - preferences.setPage(3); + preferences.setPage(2); } } @@ -607,7 +604,7 @@ UM.MainWindow onTriggered: { preferences.visible = true; - preferences.setPage(5); + preferences.setPage(4); } } @@ -617,7 +614,7 @@ UM.MainWindow onTriggered: { preferences.visible = true; - preferences.setPage(2); + preferences.setPage(1); preferences.getCurrentItem().scrollToSection(source.key); } } diff --git a/resources/qml/GeneralPage.qml b/resources/qml/Preferences/GeneralPage.qml similarity index 66% rename from resources/qml/GeneralPage.qml rename to resources/qml/Preferences/GeneralPage.qml index 0ae783916b..2886f94d92 100644 --- a/resources/qml/GeneralPage.qml +++ b/resources/qml/Preferences/GeneralPage.qml @@ -39,6 +39,12 @@ UM.PreferencesPage scaleTinyCheckbox.checked = boolCheck(UM.Preferences.getValue("mesh/scale_tiny_meshes")) UM.Preferences.resetPreference("cura/jobname_prefix") prefixJobNameCheckbox.checked = boolCheck(UM.Preferences.getValue("cura/jobname_prefix")) + UM.Preferences.resetPreference("view/show_overhang"); + showOverhangCheckbox.checked = boolCheck(UM.Preferences.getValue("view/show_overhang")) + UM.Preferences.resetPreference("view/center_on_select"); + centerOnSelectCheckbox.checked = boolCheck(UM.Preferences.getValue("view/center_on_select")) + UM.Preferences.resetPreference("view/top_layer_count"); + topLayerCountCheckbox.checked = boolCheck(UM.Preferences.getValue("view/top_layer_count")) if (plugins.model.find("id", "SliceInfoPlugin") > -1) { UM.Preferences.resetPreference("info/send_slice_info") @@ -50,17 +56,24 @@ UM.PreferencesPage } } - ColumnLayout + Column { //: Language selection label UM.I18nCatalog{id: catalog; name:"cura"} - RowLayout + Label + { + font.bold: true + text: catalog.i18nc("@label","Interface") + } + + Row { Label { id: languageLabel text: catalog.i18nc("@label","Language:") + anchors.verticalCenter: languageComboBox.verticalCenter } ComboBox @@ -120,6 +133,51 @@ UM.PreferencesPage font.italic: true } + Item + { + //: Spacer + height: UM.Theme.getSize("default_margin").height + width: UM.Theme.getSize("default_margin").width + } + + Label + { + font.bold: true + text: catalog.i18nc("@label","Viewport behavior") + } + + UM.TooltipArea + { + width: childrenRect.width; + height: childrenRect.height; + + text: catalog.i18nc("@info:tooltip","Highlight unsupported areas of the model in red. Without support these areas will not print properly.") + + CheckBox + { + id: showOverhangCheckbox + + checked: boolCheck(UM.Preferences.getValue("view/show_overhang")) + onClicked: UM.Preferences.setValue("view/show_overhang", checked) + + text: catalog.i18nc("@option:check","Display overhang"); + } + } + + UM.TooltipArea { + width: childrenRect.width; + height: childrenRect.height; + text: catalog.i18nc("@info:tooltip","Moves the camera so the object is in the center of the view when an object is selected") + + CheckBox + { + id: centerOnSelectCheckbox + text: catalog.i18nc("@action:button","Center camera when item is selected"); + checked: boolCheck(UM.Preferences.getValue("view/center_on_select")) + onClicked: UM.Preferences.setValue("view/center_on_select", checked) + } + } + UM.TooltipArea { width: childrenRect.width height: childrenRect.height @@ -134,15 +192,52 @@ UM.PreferencesPage } } + UM.TooltipArea { + width: childrenRect.width; + height: childrenRect.height; + text: catalog.i18nc("@info:tooltip","Display 5 top layers in layer view or only the top-most layer. Rendering 5 layers takes longer, but may show more information.") + + CheckBox + { + id: topLayerCountCheckbox + text: catalog.i18nc("@action:button","Display five top layers in layer view"); + checked: UM.Preferences.getValue("view/top_layer_count") == 5 + onClicked: + { + if(UM.Preferences.getValue("view/top_layer_count") == 5) + { + UM.Preferences.setValue("view/top_layer_count", 1) + } + else + { + UM.Preferences.setValue("view/top_layer_count", 5) + } + } + } + } + + Item + { + //: Spacer + height: UM.Theme.getSize("default_margin").height + width: UM.Theme.getSize("default_margin").height + } + + Label + { + font.bold: true + text: catalog.i18nc("@label","Opening files") + } + UM.TooltipArea { width: childrenRect.width height: childrenRect.height - text: catalog.i18nc("@info:tooltip","Should opened files be scaled to the build volume if they are too large?") + text: catalog.i18nc("@info:tooltip","Should objects be scaled to the build volume if they are too large?") CheckBox { id: scaleToFitCheckbox - text: catalog.i18nc("@option:check","Scale large files") + text: catalog.i18nc("@option:check","Scale large objects") checked: boolCheck(UM.Preferences.getValue("mesh/scale_to_fit")) onCheckedChanged: UM.Preferences.setValue("mesh/scale_to_fit", checked) } @@ -151,17 +246,45 @@ UM.PreferencesPage UM.TooltipArea { width: childrenRect.width height: childrenRect.height - text: catalog.i18nc("@info:tooltip","Should opened files be scaled up if they are extremely small?") + text: catalog.i18nc("@info:tooltip","Should objects be scaled up if they are extremely small?") CheckBox { id: scaleTinyCheckbox - text: catalog.i18nc("@option:check","Scale extremely small files") + text: catalog.i18nc("@option:check","Scale extremely small objects") checked: boolCheck(UM.Preferences.getValue("mesh/scale_tiny_meshes")) onCheckedChanged: UM.Preferences.setValue("mesh/scale_tiny_meshes", checked) } } + UM.TooltipArea { + width: childrenRect.width + height: childrenRect.height + text: catalog.i18nc("@info:tooltip", "Should a prefix based on the printer name be added to the print job name automatically?") + + CheckBox + { + id: prefixJobNameCheckbox + text: catalog.i18nc("@option:check", "Add machine prefix to job name") + checked: boolCheck(UM.Preferences.getValue("cura/jobname_prefix")) + onCheckedChanged: UM.Preferences.setValue("cura/jobname_prefix", checked) + } + } + + Item + { + //: Spacer + height: UM.Theme.getSize("default_margin").height + width: UM.Theme.getSize("default_margin").height + } + + Label + { + font.bold: true + visible: checkUpdatesCheckbox.visible || sendDataCheckbox.visible + text: catalog.i18nc("@label","Privacy") + } + UM.TooltipArea { visible: plugins.model.find("id", "UpdateChecker") > -1 width: childrenRect.width @@ -192,20 +315,7 @@ UM.PreferencesPage } } - UM.TooltipArea { - width: childrenRect.width - height: childrenRect.height - text: catalog.i18nc("@info:tooltip", "Should a prefix based on the printer name be added to the print job name automatically?") - - CheckBox - { - id: prefixJobNameCheckbox - text: catalog.i18nc("@option:check", "Add machine prefix to job name") - checked: boolCheck(UM.Preferences.getValue("cura/jobname_prefix")) - onCheckedChanged: UM.Preferences.setValue("cura/jobname_prefix", checked) - } - } - + //: Invisible list used to check if a plugin exists ListView { id: plugins diff --git a/resources/qml/MachinesPage.qml b/resources/qml/Preferences/MachinesPage.qml similarity index 100% rename from resources/qml/MachinesPage.qml rename to resources/qml/Preferences/MachinesPage.qml diff --git a/resources/qml/ViewPage.qml b/resources/qml/ViewPage.qml deleted file mode 100644 index baf56db116..0000000000 --- a/resources/qml/ViewPage.qml +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) 2015 Ultimaker B.V. -// Cura is released under the terms of the AGPLv3 or higher. - -import QtQuick 2.1 -import QtQuick.Controls 1.1 -import QtQuick.Layouts 1.1 -import QtQuick.Controls.Styles 1.1 - -import UM 1.1 as UM - -UM.PreferencesPage -{ - id: preferencesPage - - //: View configuration page title - title: catalog.i18nc("@title:window","View"); - - function reset() - { - UM.Preferences.resetPreference("view/show_overhang"); - UM.Preferences.resetPreference("view/center_on_select"); - UM.Preferences.resetPreference("view/top_layer_count"); - } - - Column - { - UM.I18nCatalog { id: catalog; name:"cura"} - - UM.TooltipArea - { - width: childrenRect.width; - height: childrenRect.height; - - text: catalog.i18nc("@info:tooltip","Highlight unsupported areas of the model in red. Without support these areas will not print properly.") - - CheckBox - { - id: overhangCheckbox - - checked: boolCheck(UM.Preferences.getValue("view/show_overhang")) - onClicked: UM.Preferences.setValue("view/show_overhang", checked) - - text: catalog.i18nc("@option:check","Display overhang"); - } - } - - UM.TooltipArea { - width: childrenRect.width; - height: childrenRect.height; - text: catalog.i18nc("@info:tooltip","Moves the camera so the object is in the center of the view when an object is selected") - - CheckBox - { - id: centerCheckbox - text: catalog.i18nc("@action:button","Center camera when item is selected"); - checked: boolCheck(UM.Preferences.getValue("view/center_on_select")) - onClicked: UM.Preferences.setValue("view/center_on_select", checked) - } - } - - UM.TooltipArea { - width: childrenRect.width; - height: childrenRect.height; - text: catalog.i18nc("@info:tooltip","Display 5 top layers in layer view or only the top-most layer. Rendering 5 layers takes longer, but may show more information.") - - CheckBox - { - id: topLayerCheckbox - text: catalog.i18nc("@action:button","Display five top layers in layer view."); - checked: UM.Preferences.getValue("view/top_layer_count") == 5 - onClicked: - { - if(UM.Preferences.getValue("view/top_layer_count") == 5) - { - UM.Preferences.setValue("view/top_layer_count", 1) - } - else - { - UM.Preferences.setValue("view/top_layer_count", 5) - } - } - } - } - - Connections { - target: UM.Preferences - onPreferenceChanged: - { - overhangCheckbox.checked = boolCheck(UM.Preferences.getValue("view/show_overhang")) - centerCheckbox.checked = boolCheck(UM.Preferences.getValue("view/center_on_select")) - topLayerCheckbox = UM.Preferences.getValue("view/top_layer_count") == 5 - - } - } - } -} From bf1cb8ae5207d6f916bf5ea4ede809e0c990a004 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Sun, 12 Jun 2016 15:49:13 +0200 Subject: [PATCH 655/705] Rename 'attribute' to 'property_name' --- cura/SettingOverrideDecorator.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/SettingOverrideDecorator.py b/cura/SettingOverrideDecorator.py index 7615dbe873..24360ed992 100644 --- a/cura/SettingOverrideDecorator.py +++ b/cura/SettingOverrideDecorator.py @@ -51,8 +51,8 @@ class SettingOverrideDecorator(SceneNodeDecorator): def getActiveExtruder(self): return self._extruder_stack - def _onSettingChanged(self, instance, attribute): # Reminder: 'property' is a built-in function - if attribute == "value": # Only reslice if the value has changed. + 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() ## Makes sure that the stack upon which the container stack is placed is @@ -78,4 +78,4 @@ class SettingOverrideDecorator(SceneNodeDecorator): self.activeExtruderChanged.emit() def getStack(self): - return self._stack \ No newline at end of file + return self._stack From c592d7105125e89fbdf0037aa94c9f4fffafd984 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sun, 12 Jun 2016 15:58:52 +0200 Subject: [PATCH 656/705] Make "save" button on AddMachineDialog translatable CURA-1278 --- resources/qml/AddMachineDialog.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/AddMachineDialog.qml b/resources/qml/AddMachineDialog.qml index 4a5e14f183..9d2d1a24ff 100644 --- a/resources/qml/AddMachineDialog.qml +++ b/resources/qml/AddMachineDialog.qml @@ -154,7 +154,7 @@ UM.Dialog Button { - text:"save" + text: catalog.i18nc("@action:button", "Add Printer") anchors.bottom: parent.bottom anchors.right: parent.right onClicked: From f2ed22da2ab52080d6b00d3277c07582885334aa Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Sun, 12 Jun 2016 18:47:49 +0200 Subject: [PATCH 657/705] Updating platform_offset for BQ printers Fixes the reason why the Cura UI freezes when choosing my printer from the wizard. --- resources/definitions/bq_hephestos.def.json | 8 +------- resources/definitions/bq_hephestos_2.def.json | 2 +- resources/definitions/bq_hephestos_xl.def.json | 7 +------ resources/definitions/bq_witbox.def.json | 8 +------- 4 files changed, 4 insertions(+), 21 deletions(-) diff --git a/resources/definitions/bq_hephestos.def.json b/resources/definitions/bq_hephestos.def.json index 65d6fc38a3..37eac85639 100644 --- a/resources/definitions/bq_hephestos.def.json +++ b/resources/definitions/bq_hephestos.def.json @@ -10,13 +10,7 @@ "category": "Other", "file_formats": "text/x-gcode", "platform": "bq_hephestos_platform.stl", - "platform_offset": { - "value": [ - 0, - -82, - 0 - ] - } + "platform_offset": [ 0, -82, 0] }, "overrides": { diff --git a/resources/definitions/bq_hephestos_2.def.json b/resources/definitions/bq_hephestos_2.def.json index 8afd4135f1..e4e58cb6c2 100644 --- a/resources/definitions/bq_hephestos_2.def.json +++ b/resources/definitions/bq_hephestos_2.def.json @@ -9,7 +9,7 @@ "manufacturer": "BQ", "category": "Other", "platform": "bq_hephestos_2_platform.stl", - "platform_offset": { "value": [6, 1320, 0 ] }, + "platform_offset": [6, 1320, 0 ], "file_formats": "text/x-gcode" }, diff --git a/resources/definitions/bq_hephestos_xl.def.json b/resources/definitions/bq_hephestos_xl.def.json index 9cf5b685db..19b6d3e1b5 100644 --- a/resources/definitions/bq_hephestos_xl.def.json +++ b/resources/definitions/bq_hephestos_xl.def.json @@ -10,12 +10,7 @@ "category": "Other", "file_formats": "text/x-code", "platform": "bq_hephestos_platform.stl", - "platform_offset": { - "value": [ - 0, - -82, - 0 - ] + "platform_offset": [ 0, -82, 0] } }, diff --git a/resources/definitions/bq_witbox.def.json b/resources/definitions/bq_witbox.def.json index 77826a1576..4a7dc09c3a 100644 --- a/resources/definitions/bq_witbox.def.json +++ b/resources/definitions/bq_witbox.def.json @@ -10,13 +10,7 @@ "category": "Other", "file_formats": "text/x-gcode", "platform": "bq_witbox_platform.stl", - "platform_offset": { - "value": [ - 0, - -145, - -38 - ] - } + "platform_offset": [ 0, -145, -38] }, "overrides": { From 534a4adc8e1e15dfbe5942706181c6d9660e9946 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sun, 12 Jun 2016 20:55:25 +0200 Subject: [PATCH 658/705] Fix showing/hiding variant/material dropdowns when switching between machines CURA-340 --- cura/MachineManagerModel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 4464ceffc2..f82d0e8a67 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -477,14 +477,14 @@ class MachineManagerModel(QObject): @pyqtProperty(bool, notify = globalContainerChanged) def hasMaterials(self): if self._active_container_stack: - return bool(self._active_container_stack.getMetaDataEntry("has_materials", False)) + return bool(self._global_container_stack.getMetaDataEntry("has_materials", False)) return False @pyqtProperty(bool, notify = globalContainerChanged) def hasVariants(self): if self._active_container_stack: - return bool(self._active_container_stack.getMetaDataEntry("has_variants", False)) + return bool(self._global_container_stack.getMetaDataEntry("has_variants", False)) return False From a545cde4a8ba556bf49d3cdd73de7ed20018d4c3 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 13 Jun 2016 11:53:57 +0200 Subject: [PATCH 659/705] Force setting fields to update when discarding changes Textfields that have the focus don't (always) update when a new value is set. CURA-1585 --- cura/MachineManagerModel.py | 6 +++++- resources/qml/Settings/SettingItem.qml | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index f82d0e8a67..46425ba55e 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -61,7 +61,9 @@ class MachineManagerModel(QObject): activeStackChanged = pyqtSignal() globalValueChanged = pyqtSignal() # Emitted whenever a value inside global container is changed. - globalValidationChanged = pyqtSignal() # Emitted whenever a validation inside global container is changed. + globalValidationChanged = pyqtSignal() # Emitted whenever a validation inside global container is changed + + blurSettings = pyqtSignal() # Emitted to force fields in the advanced sidebar to un-focus, so they update properly @pyqtProperty("QVariantMap", notify = globalContainerChanged) def extrudersIds(self): @@ -212,6 +214,7 @@ class MachineManagerModel(QObject): if not self._active_container_stack: return + self.blurSettings.emit() user_settings = self._active_container_stack.getTop() user_settings.clear() @@ -299,6 +302,7 @@ class MachineManagerModel(QObject): new_container_id = self.duplicateContainer(self.activeQualityId) if new_container_id == "": return + self.blurSettings.emit() self.setActiveQuality(new_container_id) self.updateQualityContainerFromUserContainer() diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index 4fd84759fd..e98c06329d 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -7,6 +7,7 @@ import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 import UM 1.1 as UM +import Cura 1.0 as Cura import "." @@ -245,5 +246,14 @@ Item { } } + Connections + { + target: Cura.MachineManager + onBlurSettings: + { + revertButton.focus = true + } + } + UM.I18nCatalog { id: catalog; name: "cura" } } From 18e69c75808a1c9bc9c382fa078752f09a708bb7 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 13 Jun 2016 13:09:52 +0200 Subject: [PATCH 660/705] Add missing "enabled" functions for support_extruder_nr children CURA-1278 --- resources/definitions/fdmprinter.def.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 6e6474053f..9675c905e9 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -2751,6 +2751,7 @@ "value": "support_extruder_nr", "minimum_value": "0", "maximum_value": "machine_extruder_count - 1", + "enabled": "support_enable", "settable_per_mesh": false, "settable_per_extruder": false }, @@ -2763,6 +2764,7 @@ "value": "support_extruder_nr", "minimum_value": "0", "maximum_value": "machine_extruder_count - 1", + "enabled": "support_enable", "settable_per_mesh": false, "settable_per_extruder": false }, @@ -2775,6 +2777,7 @@ "value": "support_extruder_nr", "minimum_value": "0", "maximum_value": "machine_extruder_count - 1", + "enabled": "support_enable", "settable_per_mesh": false, "settable_per_extruder": false } From 33c4e861639e897dfab1af751f20ac6a7960f777 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 13 Jun 2016 16:14:16 +0200 Subject: [PATCH 661/705] Change abbreviation of "seconds" to IEEE-recommended "s" (instead of "sec") --- plugins/USBPrinting/USBPrinterOutputDevice.py | 2 +- resources/definitions/bq_hephestos.def.json | 2 +- resources/definitions/bq_hephestos_xl.def.json | 2 +- resources/definitions/bq_witbox.def.json | 2 +- resources/definitions/fdmprinter.def.json | 12 ++++++------ 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index 68c4567450..58b75c2987 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -256,7 +256,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice): if not self.setBaudRate(baud_rate): continue # Could not set the baud rate, go to the next - time.sleep(1.5) # Ensure that we are not talking to the bootloader. 1.5 sec seems to be the magic number + time.sleep(1.5) # Ensure that we are not talking to the bootloader. 1.5 seconds seems to be the magic number sucesfull_responses = 0 timeout_time = time.time() + 5 self._serial.write(b"\n") diff --git a/resources/definitions/bq_hephestos.def.json b/resources/definitions/bq_hephestos.def.json index 37eac85639..4c90ae9ecd 100644 --- a/resources/definitions/bq_hephestos.def.json +++ b/resources/definitions/bq_hephestos.def.json @@ -15,7 +15,7 @@ "overrides": { "machine_start_gcode": { - "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/s\n; -- end of START GCODE --" }, "machine_end_gcode": { "default_value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" diff --git a/resources/definitions/bq_hephestos_xl.def.json b/resources/definitions/bq_hephestos_xl.def.json index 19b6d3e1b5..2b451627a9 100644 --- a/resources/definitions/bq_hephestos_xl.def.json +++ b/resources/definitions/bq_hephestos_xl.def.json @@ -16,7 +16,7 @@ "overrides": { "machine_start_gcode": { - "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/s\n; -- end of START GCODE --" }, "machine_end_gcode": { "default_value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" diff --git a/resources/definitions/bq_witbox.def.json b/resources/definitions/bq_witbox.def.json index 4a7dc09c3a..b8d4cbf015 100644 --- a/resources/definitions/bq_witbox.def.json +++ b/resources/definitions/bq_witbox.def.json @@ -15,7 +15,7 @@ "overrides": { "machine_start_gcode": { - "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/s\n; -- end of START GCODE --" }, "machine_end_gcode": { "default_value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG90 ;set to absolute positioning\nG1 Z200 ;move the platform to the bottom\nG28 X0 Y0 ;move to the X/Y origin (Home)\nM84 ;turn off steppers\n; -- end of END GCODE --" diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 9675c905e9..c5acbd49bb 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1802,7 +1802,7 @@ { "label": "Regular/Maximum Fan Speed Threshold", "description": "The layer time which sets the threshold between regular fan speed and maximum fan speed. Layers that print slower than this time use regular fan speed. For faster layers the fan speed gradually increases towards the maximum fan speed.", - "unit": "sec", + "unit": "s", "type": "float", "default_value": 10, "minimum_value": "cool_min_layer_time", @@ -1842,7 +1842,7 @@ { "label": "Minimum Layer Time", "description": "The minimum time spent in a layer. This forces the printer to slow down, to at least spend the time set here in one layer. This allows the printed material to cool down properly before printing the next layer.", - "unit": "sec", + "unit": "s", "type": "float", "default_value": 5, "minimum_value": "0", @@ -3395,7 +3395,7 @@ { "label": "WP Top Delay", "description": "Delay time after an upward move, so that the upward line can harden. Only applies to Wire Printing.", - "unit": "sec", + "unit": "s", "type": "float", "default_value": 0, "minimum_value": "0", @@ -3409,7 +3409,7 @@ { "label": "WP Bottom Delay", "description": "Delay time after a downward move. Only applies to Wire Printing.", - "unit": "sec", + "unit": "s", "type": "float", "default_value": 0, "minimum_value": "0", @@ -3423,7 +3423,7 @@ { "label": "WP Flat Delay", "description": "Delay time between two horizontal segments. Introducing such a delay can cause better adhesion to previous layers at the connection points, while too long delays cause sagging. Only applies to Wire Printing.", - "unit": "sec", + "unit": "s", "type": "float", "default_value": 0.1, "minimum_value": "0", @@ -3553,7 +3553,7 @@ "label": "WP Roof Outer Delay", "description": "Time spent at the outer perimeters of hole which is to become a roof. Longer times can ensure a better connection. Only applies to Wire Printing.", "type": "float", - "unit": "sec", + "unit": "s", "default_value": 0.2, "minimum_value": "0", "maximum_value_warning": "2.0", From 213e20bf4b9b6b8f417406994be8c2e15ceb9d93 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 13 Jun 2016 16:55:10 +0200 Subject: [PATCH 662/705] Enable per object settings for objects inside a group CURA-1054 --- plugins/PerObjectSettingsTool/PerObjectSettingsTool.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py index cb7d1766d2..416d8cce6a 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py @@ -24,19 +24,12 @@ class PerObjectSettingsTool(Tool): return False def getSelectedObjectId(self): - try: - selected_object = Selection.getSelectedObject(0) - if selected_object.getParent().callDecoration("isGroup"): - selected_object = selected_object.getParent() - except: - selected_object = None + selected_object = Selection.getSelectedObject(0) selected_object_id = id(selected_object) return selected_object_id def getContainerID(self): selected_object = Selection.getSelectedObject(0) - if selected_object.getParent().callDecoration("isGroup"): - selected_object = selected_object.getParent() try: return selected_object.callDecoration("getStack").getId() except AttributeError: From 11b120a483e22d17ae50e74445c2491a8535280a Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 13 Jun 2016 18:23:53 +0200 Subject: [PATCH 663/705] Redesign extruder selection widget Adds a colorswatch instead of coloring the whole widget (which looks like a warning state) CURA-340 --- .../PerObjectSettingsPanel.qml | 19 ++++++++++++++++--- resources/qml/Settings/SettingExtruder.qml | 19 ++++++++++++++++--- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index 920196d447..aa4a749e92 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -61,7 +61,7 @@ Item { } else { - return extruders_model.getItem(extruderSelector.currentIndex).colour; + return UM.Theme.getColor("setting_control"); } } border.width: UM.Theme.getSize("default_lining").width @@ -69,9 +69,22 @@ Item { } label: Item { + Rectangle + { + id: swatch + height: UM.Theme.getSize("setting_control").height / 2 + width: height + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_lining").width + anchors.verticalCenter: parent.verticalCenter + + color: extruders_model.getItem(extruderSelector.currentIndex).colour + border.width: UM.Theme.getSize("default_lining").width + border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : UM.Theme.getColor("setting_control_border") + } Label { - anchors.left: parent.left + anchors.left: swatch.right anchors.leftMargin: UM.Theme.getSize("default_lining").width anchors.right: downArrow.left anchors.rightMargin: UM.Theme.getSize("default_lining").width @@ -79,7 +92,7 @@ Item { text: extruderSelector.currentText font: UM.Theme.getFont("default") - color: UM.Theme.getColor("setting_control_disabled_text") + color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text") elide: Text.ElideRight verticalAlignment: Text.AlignVCenter diff --git a/resources/qml/Settings/SettingExtruder.qml b/resources/qml/Settings/SettingExtruder.qml index 0160dab7fa..8acd75c88e 100644 --- a/resources/qml/Settings/SettingExtruder.qml +++ b/resources/qml/Settings/SettingExtruder.qml @@ -47,7 +47,7 @@ SettingItem } else { - return extruders_model.getItem(index).colour; + return UM.Theme.getColor("setting_control"); } } border.width: UM.Theme.getSize("default_lining").width @@ -55,9 +55,22 @@ SettingItem } label: Item { + Rectangle + { + id: swatch + height: UM.Theme.getSize("setting_control").height / 2 + width: height + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_lining").width + anchors.verticalCenter: parent.verticalCenter + + color: extruders_model.getItem(control.currentIndex).colour + border.width: UM.Theme.getSize("default_lining").width + border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : UM.Theme.getColor("setting_control_border") + } Label { - anchors.left: parent.left + anchors.left: swatch.right anchors.leftMargin: UM.Theme.getSize("default_lining").width anchors.right: downArrow.left anchors.rightMargin: UM.Theme.getSize("default_lining").width @@ -65,7 +78,7 @@ SettingItem text: control.currentText font: UM.Theme.getFont("default") - color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : extruders_model.getItem(index).colour + color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text") elide: Text.ElideRight verticalAlignment: Text.AlignVCenter From 8f86a19d6be013410de88bf5e05bd991e46071e4 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 13 Jun 2016 22:12:45 +0200 Subject: [PATCH 664/705] Fix bq_hephestos_xl.def.json to valid json --- resources/definitions/bq_hephestos_xl.def.json | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/definitions/bq_hephestos_xl.def.json b/resources/definitions/bq_hephestos_xl.def.json index 2b451627a9..867f5f37aa 100644 --- a/resources/definitions/bq_hephestos_xl.def.json +++ b/resources/definitions/bq_hephestos_xl.def.json @@ -11,7 +11,6 @@ "file_formats": "text/x-code", "platform": "bq_hephestos_platform.stl", "platform_offset": [ 0, -82, 0] - } }, "overrides": { From b429f98d6af9648438d21e414e8db50892b1eade Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 14 Jun 2016 09:42:05 +0200 Subject: [PATCH 665/705] Added signalemitter decoration CURA-49 --- cura/PrinterOutputDevice.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 7025646294..5ed103ca9b 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -3,6 +3,7 @@ from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from enum import IntEnum # For the connection state tracking. from UM.Logger import Logger +from UM.Signal import signalemitter ## Printer output device adds extra interface options on top of output device. # @@ -13,6 +14,7 @@ from UM.Logger import Logger # functions to actually have the implementation. # # For all other uses it should be used in the same way as a "regular" OutputDevice. +@signalemitter class PrinterOutputDevice(OutputDevice, QObject): def __init__(self, device_id, parent = None): super().__init__(device_id = device_id, parent = parent) From 24e165b964b55d0dccd66227cbb4a746dd5f9bfc Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 14 Jun 2016 10:41:06 +0200 Subject: [PATCH 666/705] Remove error on ProfilesPage CURA-1585 --- resources/qml/Preferences/ProfilesPage.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 670bf79956..c2ad84b581 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -39,7 +39,6 @@ UM.ManagementPage section.property: "readOnly" section.delegate: Rectangle { - width: objectListContainer.viewport.width; height: childrenRect.height; Label From 4ece9b0997ded3b9698ec749ef9548c4f934744e Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 14 Jun 2016 10:42:33 +0200 Subject: [PATCH 667/705] Add swatch to extruder tabs CURA-340 --- resources/qml/SidebarHeader.qml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 282068ee2c..166c1fbe6d 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -141,6 +141,20 @@ Column control.hovered ? UM.Theme.getColor("toggle_hovered") : UM.Theme.getColor("toggle_unchecked") Behavior on color { ColorAnimation { duration: 50; } } + Rectangle + { + id: swatch + height: UM.Theme.getSize("setting_control").height / 2 + width: height + anchors.left: parent.left + anchors.leftMargin: (parent.height - height) / 2 + anchors.verticalCenter: parent.verticalCenter + + color: model.colour + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("toggle_checked") + } + Label { anchors.centerIn: parent From 7faae685e5730becc613fc64a2524fb95ff56243 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 14 Jun 2016 10:58:26 +0200 Subject: [PATCH 668/705] Use different default colors for each extruder CURA-340 --- cura/ExtrudersModel.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cura/ExtrudersModel.py b/cura/ExtrudersModel.py index 960c05bd5e..3ba6c5a99a 100644 --- a/cura/ExtrudersModel.py +++ b/cura/ExtrudersModel.py @@ -28,9 +28,9 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): # containers. IndexRole = Qt.UserRole + 4 - ## Colour to display if there is no material or the material has no known + ## List of colours to display if there is no material or the material has no known # colour. - defaultColour = "#FFFF00" + defaultColours = ["#ffc924", "#86ec21", "#22eeee", "#245bff", "#9124ff", "#ff24c8"] ## Initialises the extruders model, defining the roles and listening for # changes in the data. @@ -75,7 +75,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): if self._add_global: material = global_container_stack.findContainer({ "type": "material" }) - colour = material.getMetaDataEntry("color_code", default = self.defaultColour) if material else self.defaultColour + colour = material.getMetaDataEntry("color_code", default = self.defaultColours[0]) if material else self.defaultColours[0] item = { "id": global_container_stack.getId(), "name": "Global", @@ -86,12 +86,13 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): for extruder in manager.getMachineExtruders(global_container_stack.getBottom().getId()): material = extruder.findContainer({ "type": "material" }) - colour = material.getMetaDataEntry("color_code", default = self.defaultColour) if material else self.defaultColour position = extruder.getBottom().getMetaDataEntry("position", default = "0") #Position in the definition. try: position = int(position) except ValueError: #Not a proper int. position = -1 + default_colour = self.defaultColours[position] if position >= 0 and position < len(self.defaultColours) else defaultColours[0] + colour = material.getMetaDataEntry("color_code", default = default_colour) if material else default_colour item = { #Construct an item with only the relevant information. "id": extruder.getId(), "name": extruder.getName(), From 2498e7110d45faee570cb763a09d38e107bfb614 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 14 Jun 2016 11:05:50 +0200 Subject: [PATCH 669/705] Allow setting the diffuse_color with a uniform binding CURA-345 --- resources/shaders/overhang.shader | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/shaders/overhang.shader b/resources/shaders/overhang.shader index 4ae2821c7d..99cbdf913d 100644 --- a/resources/shaders/overhang.shader +++ b/resources/shaders/overhang.shader @@ -74,6 +74,7 @@ u_viewProjectionMatrix = view_projection_matrix u_normalMatrix = normal_matrix u_viewPosition = view_position u_lightPosition = light_0_position +u_diffuseColor = diffuse_color [attributes] a_vertex = vertex From 175b5429b45457818e3e3faed15a50977ce4101c Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Tue, 14 Jun 2016 11:44:11 +0200 Subject: [PATCH 670/705] Refactor the profile and Cura specific import/export code, put the cura stuff in Cura itself. Contributes to CURA-1667 Profile import/export --- cura/CuraContainerRegistry.py | 167 +++++++++++++++++++++ cura_app.py | 4 + resources/qml/Preferences/ProfilesPage.qml | 4 +- 3 files changed, 173 insertions(+), 2 deletions(-) create mode 100644 cura/CuraContainerRegistry.py diff --git a/cura/CuraContainerRegistry.py b/cura/CuraContainerRegistry.py new file mode 100644 index 0000000000..66ef5c3695 --- /dev/null +++ b/cura/CuraContainerRegistry.py @@ -0,0 +1,167 @@ +# Copyright (c) 2016 Ultimaker B.V. +# Uranium is released under the terms of the AGPLv3 or higher. + +import os +from PyQt5.QtWidgets import QMessageBox + +from UM.Settings.ContainerRegistry import ContainerRegistry +from UM.Application import Application +from UM.Logger import Logger +from UM.Message import Message +from UM.Platform import Platform +from UM.PluginRegistry import PluginRegistry #For getting the possible profile writers to write with. +from UM.Util import parseBool + +from UM.i18n import i18nCatalog +catalog = i18nCatalog("uranium") + +class CuraContainerRegistry(ContainerRegistry): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + ## Exports an profile to a file + # + # \param instance_id \type{str} the ID of the profile to export. + # \param file_name \type{str} the full path and filename to export to. + # \param file_type \type{str} the file type with the format " (*.)" + def exportProfile(self, instance_id, file_name, file_type): + Logger.log('d', 'exportProfile instance_id: '+str(instance_id)) + + # Parse the fileType to deduce what plugin can save the file format. + # fileType has the format " (*.)" + split = file_type.rfind(" (*.") # Find where the description ends and the extension starts. + if split < 0: # Not found. Invalid format. + Logger.log("e", "Invalid file format identifier %s", file_type) + return + description = file_type[:split] + extension = file_type[split + 4:-1] # Leave out the " (*." and ")". + if not file_name.endswith("." + extension): # Auto-fill the extension if the user did not provide any. + file_name += "." + extension + + # On Windows, QML FileDialog properly asks for overwrite confirm, but not on other platforms, so handle those ourself. + if not Platform.isWindows(): + if os.path.exists(file_name): + result = QMessageBox.question(None, catalog.i18nc("@title:window", "File Already Exists"), + catalog.i18nc("@label", "The file {0} already exists. Are you sure you want to overwrite it?").format(file_name)) + if result == QMessageBox.No: + return + + containers = ContainerRegistry.getInstance().findInstanceContainers(id=instance_id) + if not containers: + return + container = containers[0] + + profile_writer = self._findProfileWriter(extension, description) + + try: + success = profile_writer.write(file_name, container) + except Exception as e: + Logger.log("e", "Failed to export profile to %s: %s", file_name, str(e)) + m = Message(catalog.i18nc("@info:status", "Failed to export profile to {0}: {1}", file_name, str(e)), lifetime = 0) + m.show() + return + if not success: + Logger.log("w", "Failed to export profile to %s: Writer plugin reported failure.", file_name) + m = Message(catalog.i18nc("@info:status", "Failed to export profile to {0}: Writer plugin reported failure.", file_name), lifetime = 0) + m.show() + return + m = Message(catalog.i18nc("@info:status", "Exported profile to {0}", file_name)) + m.show() + + ## Gets the plugin object matching the criteria + # \param extension + # \param description + # \return The plugin object matching the given extension and description. + def _findProfileWriter(self, extension, description): + pr = PluginRegistry.getInstance() + for plugin_id, meta_data in self._getIOPlugins("profile_writer"): + for supported_type in meta_data["profile_writer"]: # All file types this plugin can supposedly write. + supported_extension = supported_type.get("extension", None) + if supported_extension == extension: # This plugin supports a file type with the same extension. + supported_description = supported_type.get("description", None) + if supported_description == description: # The description is also identical. Assume it's the same file type. + return pr.getPluginObject(plugin_id) + return None + + ## Imports a profile from a file + # + # \param file_name \type{str} the full path and filename of the profile to import + # \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): + if not file_name: + return { "status": "error", "message": catalog.i18nc("@info:status", "Failed to import profile from {0}: {1}", file_name, "Invalid path")} + + pr = PluginRegistry.getInstance() + for plugin_id, meta_data in self._getIOPlugins("profile_reader"): + profile_reader = pr.getPluginObject(plugin_id) + try: + profile = profile_reader.read(file_name) #Try to open the file with the profile reader. + except Exception as e: + #Note that this will fail quickly. That is, if any profile reader throws an exception, it will stop reading. It will only continue reading if the reader returned None. + Logger.log("e", "Failed to import profile from %s: %s", file_name, str(e)) + return { "status": "error", "message": catalog.i18nc("@info:status", "Failed to import profile from {0}: {1}", file_name, str(e))} + if profile: #Success! + profile.setReadOnly(False) + + if self._machineHasOwnQualities(): + profile.setDefinition(self._activeDefinition()) + if self._machineHasOwnMaterials(): + profile.addMetaDataEntry("material", self._activeMaterialId()) + else: + profile.setDefinition(ContainerRegistry.getInstance().findDefinitionContainers(id="fdmprinter")[0]) + ContainerRegistry.getInstance().addContainer(profile) + + return { "status": "ok", "message": catalog.i18nc("@info:status", "Successfully imported profile {0}", profile.getName()) } + + #If it hasn't returned by now, none of the plugins loaded the profile successfully. + return { "status": "error", "message": catalog.i18nc("@info:status", "Profile {0} has an unknown file type.", file_name)} + + ## Gets a list of profile writer plugins + # \return List of tuples of (plugin_id, meta_data). + def _getIOPlugins(self, io_type): + pr = PluginRegistry.getInstance() + active_plugin_ids = pr.getActivePlugins() + + result = [] + for plugin_id in active_plugin_ids: + meta_data = pr.getMetaData(plugin_id) + if io_type in meta_data: + result.append( (plugin_id, meta_data) ) + return result + + ## Gets the active definition + # \return the active definition object or None if there is no definition + def _activeDefinition(self): + global_container_stack = Application.getInstance().getGlobalContainerStack() + if global_container_stack: + definition = global_container_stack.getBottom() + if definition: + return definition + return None + + ## Returns true if the current machine requires its own materials + # \return True if the current machine requires its own materials + def _machineHasOwnMaterials(self): + global_container_stack = Application.getInstance().getGlobalContainerStack() + if global_container_stack: + return global_container_stack.getMetaDataEntry("has_materials", False) + return False + + ## Gets the ID of the active material + # \return the ID of the active material or the empty string + def _activeMaterialId(self): + global_container_stack = Application.getInstance().getGlobalContainerStack() + if global_container_stack: + material = global_container_stack.findContainer({"type": "material"}) + if material: + return material.getId() + return "" + + ## Returns true if the current machien requires its own quality profiles + # \return true if the current machien requires its own quality profiles + def _machineHasOwnQualities(self): + global_container_stack = Application.getInstance().getGlobalContainerStack() + if global_container_stack: + return parseBool(global_container_stack.getMetaDataEntry("has_machine_quality", False)) + return False diff --git a/cura_app.py b/cura_app.py index 3bcce18fb5..15bdf10ad6 100755 --- a/cura_app.py +++ b/cura_app.py @@ -34,6 +34,7 @@ sys.excepthook = exceptHook # tries to create PyQt objects on a non-main thread. import Arcus #@UnusedImport import cura.CuraApplication +import cura.CuraContainerRegistry if sys.platform == "win32" and hasattr(sys, "frozen"): dirpath = os.path.expanduser("~/AppData/Local/cura/") @@ -41,5 +42,8 @@ if sys.platform == "win32" and hasattr(sys, "frozen"): sys.stdout = open(os.path.join(dirpath, "stdout.log"), "w") sys.stderr = open(os.path.join(dirpath, "stderr.log"), "w") +# Force an instance of CuraContainerRegistry to be created and reused later. +cura.CuraContainerRegistry.CuraContainerRegistry.getInstance() + app = cura.CuraApplication.CuraApplication.getInstance() app.run() diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index c2ad84b581..1f90d7c889 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -264,7 +264,7 @@ UM.ManagementPage id: importDialog; title: catalog.i18nc("@title:window", "Import Profile"); selectExisting: true; - nameFilters: base.model.getFileNameFiltersRead() + nameFilters: base.model.getFileNameFilters("profile_reader") folder: base.model.getDefaultPath() onAccepted: { @@ -291,7 +291,7 @@ UM.ManagementPage id: exportDialog; title: catalog.i18nc("@title:window", "Export Profile"); selectExisting: false; - nameFilters: base.model.getFileNameFiltersWrite() + nameFilters: base.model.getFileNameFilters("profile_writer") folder: base.model.getDefaultPath() onAccepted: { From 3777acd4cdce176068377d9a4c4348ec48063fd3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 14 Jun 2016 11:50:59 +0200 Subject: [PATCH 671/705] Changed order of inheritance. Because the python new is stupid, it fails to notice the qObject if it's not defined first --- cura/PrinterOutputDevice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 5ed103ca9b..7649106523 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -15,7 +15,7 @@ from UM.Signal import signalemitter # # For all other uses it should be used in the same way as a "regular" OutputDevice. @signalemitter -class PrinterOutputDevice(OutputDevice, QObject): +class PrinterOutputDevice(QObject, OutputDevice): def __init__(self, device_id, parent = None): super().__init__(device_id = device_id, parent = parent) From e473d7a4e95ed749a23da045d44dc2339694dbbc Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 14 Jun 2016 17:28:40 +0200 Subject: [PATCH 672/705] Ensure the control has active focus when clicking a SettingItem This way we ensure that things update properly when for example changing infill pattern. Fixes CURA-1494 --- resources/qml/Settings/SettingCategory.qml | 14 +++++++++----- resources/qml/Settings/SettingCheckBox.qml | 2 +- resources/qml/Settings/SettingComboBox.qml | 2 +- resources/qml/Settings/SettingExtruder.qml | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index 6e23158a1c..83bd7f1f82 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -24,9 +24,10 @@ Button { checkable: true checked: definition.expanded - onClicked: definition.expanded ? settingDefinitionsModel.collapse(definition.key) : settingDefinitionsModel.expandAll(definition.key) + onClicked: { forceActiveFocus(); definition.expanded ? settingDefinitionsModel.collapse(definition.key) : settingDefinitionsModel.expandAll(definition.key) } - UM.SimpleButton { + UM.SimpleButton + { id: settingsButton visible: base.hovered || settingsButton.hovered @@ -60,7 +61,8 @@ Button { height: parent.height / 2 width: height - onClicked: { + onClicked: + { base.showAllHiddenInheritedSettings() } @@ -68,11 +70,13 @@ Button { hoverColor: UM.Theme.getColor("setting_control_button_hover") iconSource: UM.Theme.getIcon("notice") - onEntered: { + onEntered: + { base.showTooltip(catalog.i18nc("@label","Some hidden settings use values different from their normal calculated value.\n\nClick to make these settings visible.")) } - onExited: { + onExited: + { base.hideTooltip(); } diff --git a/resources/qml/Settings/SettingCheckBox.qml b/resources/qml/Settings/SettingCheckBox.qml index 1d66e509d0..9b50c82395 100644 --- a/resources/qml/Settings/SettingCheckBox.qml +++ b/resources/qml/Settings/SettingCheckBox.qml @@ -31,7 +31,7 @@ SettingItem } } - onClicked: propertyProvider.setPropertyValue("value", !checked) + onClicked: { forceActiveFocus(); propertyProvider.setPropertyValue("value", !checked) } Rectangle { diff --git a/resources/qml/Settings/SettingComboBox.qml b/resources/qml/Settings/SettingComboBox.qml index c9f3cb727b..5308e45f5a 100644 --- a/resources/qml/Settings/SettingComboBox.qml +++ b/resources/qml/Settings/SettingComboBox.qml @@ -86,7 +86,7 @@ SettingItem } } - onActivated: provider.setPropertyValue("value", definition.options[index].key) + onActivated: { forceActiveFocus(); provider.setPropertyValue("value", definition.options[index].key) } onModelChanged: updateCurrentIndex(); Connections diff --git a/resources/qml/Settings/SettingExtruder.qml b/resources/qml/Settings/SettingExtruder.qml index 8acd75c88e..5800a0943e 100644 --- a/resources/qml/Settings/SettingExtruder.qml +++ b/resources/qml/Settings/SettingExtruder.qml @@ -102,7 +102,7 @@ SettingItem } } - onActivated: provider.setPropertyValue("value", extruders_model.getItem(index).index); + onActivated: { forceActiveFocus(); provider.setPropertyValue("value", extruders_model.getItem(index).index) }; onModelChanged: updateCurrentIndex(); Connections From 004a000d51507e0e4617ec7ce4138c54ebd869a5 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Tue, 14 Jun 2016 21:04:24 +0200 Subject: [PATCH 673/705] Corrected the i18n catalog used. Contributes to CURA-1667 Profile import/export --- cura/CuraContainerRegistry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraContainerRegistry.py b/cura/CuraContainerRegistry.py index 66ef5c3695..bee54fc7ef 100644 --- a/cura/CuraContainerRegistry.py +++ b/cura/CuraContainerRegistry.py @@ -13,7 +13,7 @@ from UM.PluginRegistry import PluginRegistry #For getting the possible profile w from UM.Util import parseBool from UM.i18n import i18nCatalog -catalog = i18nCatalog("uranium") +catalog = i18nCatalog("cura") class CuraContainerRegistry(ContainerRegistry): def __init__(self, *args, **kwargs): From 1bab4032fd706cfbeb53008d2270068ccd7a0e7d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 15 Jun 2016 09:41:32 +0200 Subject: [PATCH 674/705] Fixed broken perobject setting panel CURA-1725 --- resources/qml/Settings/SettingExtruder.qml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingExtruder.qml b/resources/qml/Settings/SettingExtruder.qml index 5800a0943e..72c5299b15 100644 --- a/resources/qml/Settings/SettingExtruder.qml +++ b/resources/qml/Settings/SettingExtruder.qml @@ -102,7 +102,11 @@ SettingItem } } - onActivated: { forceActiveFocus(); provider.setPropertyValue("value", extruders_model.getItem(index).index) }; + onActivated: + { + forceActiveFocus(); + provider.setPropertyValue("value", extruders_model.getItem(index).index) + } onModelChanged: updateCurrentIndex(); Connections From 61db0a766011fc2e26576fdad563dbcd0bd5b37f Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 15 Jun 2016 09:45:55 +0200 Subject: [PATCH 675/705] Fix extruder tabs for >2 extruders or long extruder names CURA-340 --- resources/qml/SidebarHeader.qml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 166c1fbe6d..55a104a21f 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -157,13 +157,19 @@ Column Label { - anchors.centerIn: parent + anchors.verticalCenter: parent.verticalCenter + anchors.left: swatch.right + anchors.leftMargin: UM.Theme.getSize("default_margin").width / 2 + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("default_margin").width / 2 + color: control.checked ? UM.Theme.getColor("toggle_checked_text") : control.pressed ? UM.Theme.getColor("toggle_active_text") : control.hovered ? UM.Theme.getColor("toggle_hovered_text") : UM.Theme.getColor("toggle_unchecked_text") font: UM.Theme.getFont("default") - text: control.text; + text: control.text + elide: Text.ElideRight } } label: Item { } From f0340c6d630dbf96319648c038e7c9cb0432a3b7 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 15 Jun 2016 09:50:05 +0200 Subject: [PATCH 676/705] Rework based on review CURA-1689 --- cura/ExtruderManager.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index da5887be61..159db42919 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -67,12 +67,14 @@ class ExtruderManager(QObject): self.activeExtruderChanged.emit() def getActiveExtruderStack(self): - try: - return self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getBottom().getId()][str(self._active_extruder_index)] - except AttributeError: - return None - except KeyError: - return None + global_container_stack = UM.Application.getInstance().getGlobalContainerStack() + if global_container_stack: + global_definition_container = UM.Application.getInstance().getGlobalContainerStack().getBottom() + if global_definition_container: + if str(self._active_extruder_index) in self._extruder_trains[global_definition_container.getId()]: + return self._extruder_trains[global_definition_container.getId()][str(self._active_extruder_index)] + return self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getBottom().getId()][str(self._active_extruder_index)] + ## Adds all extruders of a specific machine definition to the extruder # manager. From 9e6f5a4a6898609766b138d82e87e980f0b4e5ff Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Wed, 15 Jun 2016 10:04:47 +0200 Subject: [PATCH 677/705] CURA-1615 - Updating for API 3 This updates the firmware updater to use the new MachineManagerModel Additionally renamed "machine_type" to "machine_id", which makes it more selfexplaining, when reading the code. My printers firmware is not available here and has no heated bed, so please test this commit! --- cura/MachineManagerModel.py | 7 +++++++ .../USBPrinterOutputDeviceManager.py | 21 ++++++++++--------- plugins/USBPrinting/__init__.py | 2 +- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 46425ba55e..fc978916e1 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -485,6 +485,13 @@ class MachineManagerModel(QObject): return False + @pyqtProperty(bool, notify = globalContainerChanged) + def hasHeatedBed(self): + if self._active_container_stack: + return bool(self._global_container_stack.getMetaDataEntry("machine_heated_bed", False)) + + return False + @pyqtProperty(bool, notify = globalContainerChanged) def hasVariants(self): if self._active_container_stack: diff --git a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py index 24e2148375..74072e324e 100644 --- a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py +++ b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py @@ -13,6 +13,7 @@ from UM.Qt.ListModel import ListModel from UM.Message import Message from cura.CuraApplication import CuraApplication +from cura.MachineManagerModel import MachineManagerModel import threading import platform @@ -128,8 +129,9 @@ class USBPrinterOutputDeviceManager(QObject, SignalEmitter, OutputDevicePlugin, return USBPrinterOutputDeviceManager._instance def _getDefaultFirmwareName(self): - machine_instance = Application.getInstance().getMachineManager().getActiveMachineInstance() - machine_type = machine_instance.getMachineDefinition().getId() + machine_manager_model = MachineManagerModel() + machine_id = machine_manager_model.activeDefinitionId + if platform.system() == "Linux": baudrate = 115200 else: @@ -151,23 +153,22 @@ class USBPrinterOutputDeviceManager(QObject, SignalEmitter, OutputDevicePlugin, } machine_with_heated_bed = {"ultimaker_original" : "MarlinUltimaker-HBK-{baudrate}.hex", } - ##TODO: Add check for multiple extruders hex_file = None - if machine_type in machine_without_extras.keys(): # The machine needs to be defined here! - if machine_type in machine_with_heated_bed.keys() and machine_instance.getMachineSettingValue("machine_heated_bed"): + if machine_id in machine_without_extras.keys(): # The machine needs to be defined here! + if machine_id in machine_with_heated_bed.keys() and machine_manager_model.hasHeatedBed: Logger.log("d", "Choosing firmware with heated bed enabled for machine %s.", machine_type) - hex_file = machine_with_heated_bed[machine_type] # Return firmware with heated bed enabled + hex_file = machine_with_heated_bed[machine_id] # Return firmware with heated bed enabled else: - Logger.log("d", "Choosing basic firmware for machine %s.", machine_type) - hex_file = machine_without_extras[machine_type] # Return "basic" firmware + Logger.log("d", "Choosing basic firmware for machine %s.", machine_id) + hex_file = machine_without_extras[machine_id] # Return "basic" firmware else: - Logger.log("e", "There is no firmware for machine %s.", machine_type) + Logger.log("e", "There is no firmware for machine %s.", machine_id) if hex_file: return hex_file.format(baudrate=baudrate) else: - Logger.log("e", "Could not find any firmware for machine %s.", machine_type) + Logger.log("e", "Could not find any firmware for machine %s.", machine_id) raise FileNotFoundError() ## Helper to identify serial ports (and scan for them) diff --git a/plugins/USBPrinting/__init__.py b/plugins/USBPrinting/__init__.py index 4fab439bad..b8581586d8 100644 --- a/plugins/USBPrinting/__init__.py +++ b/plugins/USBPrinting/__init__.py @@ -13,7 +13,7 @@ def getMetaData(): "name": i18n_catalog.i18nc("@label", "USB printing"), "author": "Ultimaker", "version": "1.0", - "api": 2, + "api": 3, "description": i18n_catalog.i18nc("@info:whatsthis","Accepts G-Code and sends them to a printer. Plugin can also update firmware.") } } From 7176c98d8a67358bb8f418cceff4ed86971d11d4 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 15 Jun 2016 10:21:06 +0200 Subject: [PATCH 678/705] Fixed stupid mistake with getting active extruder stack CURA-1689 --- cura/ExtruderManager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 159db42919..9be1d8dc53 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -71,9 +71,9 @@ class ExtruderManager(QObject): if global_container_stack: global_definition_container = UM.Application.getInstance().getGlobalContainerStack().getBottom() if global_definition_container: - if str(self._active_extruder_index) in self._extruder_trains[global_definition_container.getId()]: - return self._extruder_trains[global_definition_container.getId()][str(self._active_extruder_index)] - return self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getBottom().getId()][str(self._active_extruder_index)] + if global_definition_container.getId() in self._extruder_trains: + if str(self._active_extruder_index) in self._extruder_trains[global_definition_container.getId()]: + return self._extruder_trains[global_definition_container.getId()][str(self._active_extruder_index)] ## Adds all extruders of a specific machine definition to the extruder From 253bb5f43c039b793fbc73a3f892db780b4c8389 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Wed, 15 Jun 2016 10:56:01 +0200 Subject: [PATCH 679/705] Removing hasHeatedBed from MachineManagerModel again.. --- cura/MachineManagerModel.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index fc978916e1..46425ba55e 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -485,13 +485,6 @@ class MachineManagerModel(QObject): return False - @pyqtProperty(bool, notify = globalContainerChanged) - def hasHeatedBed(self): - if self._active_container_stack: - return bool(self._global_container_stack.getMetaDataEntry("machine_heated_bed", False)) - - return False - @pyqtProperty(bool, notify = globalContainerChanged) def hasVariants(self): if self._active_container_stack: From 5128ea41c46b94784cf582589e27121b39d8767f Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Wed, 15 Jun 2016 10:57:58 +0200 Subject: [PATCH 680/705] Getting "machine_heated_bed" (hopefully) correctly + little fix --- plugins/USBPrinting/USBPrinterOutputDeviceManager.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py index 74072e324e..7c5d63c381 100644 --- a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py +++ b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py @@ -129,8 +129,13 @@ class USBPrinterOutputDeviceManager(QObject, SignalEmitter, OutputDevicePlugin, return USBPrinterOutputDeviceManager._instance def _getDefaultFirmwareName(self): + # Detecting id of the current machine machine_manager_model = MachineManagerModel() machine_id = machine_manager_model.activeDefinitionId + + # Detecting whether it has a heated bed + _active_container_stack = Application.getInstance().getGlobalContainerStack() + machine_has_heated_bed = _active_container_stack.getProperty("machine_heated_bed", "value") if platform.system() == "Linux": baudrate = 115200 @@ -156,8 +161,8 @@ class USBPrinterOutputDeviceManager(QObject, SignalEmitter, OutputDevicePlugin, ##TODO: Add check for multiple extruders hex_file = None if machine_id in machine_without_extras.keys(): # The machine needs to be defined here! - if machine_id in machine_with_heated_bed.keys() and machine_manager_model.hasHeatedBed: - Logger.log("d", "Choosing firmware with heated bed enabled for machine %s.", machine_type) + if machine_id in machine_with_heated_bed.keys() and machine_has_heated_bed: + Logger.log("d", "Choosing firmware with heated bed enabled for machine %s.", machine_id) hex_file = machine_with_heated_bed[machine_id] # Return firmware with heated bed enabled else: Logger.log("d", "Choosing basic firmware for machine %s.", machine_id) From 2460b37c994e0fc03f0319945bf31a810a11e926 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 15 Jun 2016 11:13:31 +0200 Subject: [PATCH 681/705] Fix check for self._global_container_stack for consistency CURA-340 --- cura/MachineManagerModel.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 46425ba55e..2ef9932d24 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -446,7 +446,7 @@ class MachineManagerModel(QObject): @pyqtProperty(str, notify = globalContainerChanged) def activeDefinitionId(self): - if self._active_container_stack: + if self._global_container_stack: definition = self._global_container_stack.getBottom() if definition: return definition.id @@ -480,14 +480,14 @@ class MachineManagerModel(QObject): @pyqtProperty(bool, notify = globalContainerChanged) def hasMaterials(self): - if self._active_container_stack: + if self._global_container_stack: return bool(self._global_container_stack.getMetaDataEntry("has_materials", False)) return False @pyqtProperty(bool, notify = globalContainerChanged) def hasVariants(self): - if self._active_container_stack: + if self._global_container_stack: return bool(self._global_container_stack.getMetaDataEntry("has_variants", False)) return False From a7fc3258a74ef09ef2f56d75768bcdeb3850bf96 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Wed, 15 Jun 2016 11:16:13 +0200 Subject: [PATCH 682/705] Only use Application.[...].getGlobalContainerStack() to get all values --- plugins/USBPrinting/USBPrinterOutputDeviceManager.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py index 7c5d63c381..aa6a731c22 100644 --- a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py +++ b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py @@ -13,7 +13,6 @@ from UM.Qt.ListModel import ListModel from UM.Message import Message from cura.CuraApplication import CuraApplication -from cura.MachineManagerModel import MachineManagerModel import threading import platform @@ -130,13 +129,11 @@ class USBPrinterOutputDeviceManager(QObject, SignalEmitter, OutputDevicePlugin, def _getDefaultFirmwareName(self): # Detecting id of the current machine - machine_manager_model = MachineManagerModel() - machine_id = machine_manager_model.activeDefinitionId + machine_id = Application.getInstance().getGlobalContainerStack().getBottom().id # Detecting whether it has a heated bed - _active_container_stack = Application.getInstance().getGlobalContainerStack() - machine_has_heated_bed = _active_container_stack.getProperty("machine_heated_bed", "value") - + machine_has_heated_bed = Application.getInstance().getGlobalContainerStack().getProperty("machine_heated_bed", "value") + if platform.system() == "Linux": baudrate = 115200 else: From 70b2311c59d82cab498c6f50f6a7a7d2f9d6c9cb Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Wed, 15 Jun 2016 12:50:44 +0200 Subject: [PATCH 683/705] Use the file name to create the profile name during import. Also moved the createUniqueName() method up into CuraContainerRegistry. Contributes to CURA-1667 Profile import/export --- cura/CuraContainerRegistry.py | 43 ++++++++++++++++++++++++++++++++++- cura/MachineManagerModel.py | 30 +++--------------------- 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/cura/CuraContainerRegistry.py b/cura/CuraContainerRegistry.py index bee54fc7ef..854fe030da 100644 --- a/cura/CuraContainerRegistry.py +++ b/cura/CuraContainerRegistry.py @@ -1,10 +1,14 @@ # 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 os +import os.path +import re from PyQt5.QtWidgets import QMessageBox from UM.Settings.ContainerRegistry import ContainerRegistry +from UM.Settings.ContainerStack import ContainerStack +from UM.Settings.InstanceContainer import InstanceContainer from UM.Application import Application from UM.Logger import Logger from UM.Message import Message @@ -19,6 +23,39 @@ class CuraContainerRegistry(ContainerRegistry): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + ## Create a name that is not empty and unique + # \param container_type \type{string} Type of the container (machine, quality, ...) + # \param current_name \type{} Current name of the container, which may be an acceptable option + # \param new_name \type{string} Base name, which may not be unique + # \param fallback_name \type{string} Name to use when (stripped) new_name is empty + # \return \type{string} Name that is unique for the specified type and name/id + def createUniqueName(self, container_type, current_name, new_name, fallback_name): + new_name = new_name.strip() + num_check = re.compile("(.*?)\s*#\d+$").match(new_name) + if num_check: + new_name = num_check.group(1) + if new_name == "": + new_name = fallback_name + + unique_name = new_name + i = 1 + # In case we are renaming, the current name of the container is also a valid end-result + while self._containerExists(container_type, unique_name) and unique_name != current_name: + i += 1 + unique_name = "%s #%d" % (new_name, i) + + return unique_name + + ## Check if a container with of a certain type and a certain name or id exists + # Both the id and the name are checked, because they may not be the same and it is better if they are both unique + # \param container_type \type{string} Type of the container (machine, quality, ...) + # \param container_name \type{string} Name to check + def _containerExists(self, container_type, container_name): + container_class = ContainerStack if container_type == "machine" else InstanceContainer + + return self.findContainers(container_class, id = container_name, type = container_type) or \ + self.findContainers(container_class, name = container_name, type = container_type) + ## Exports an profile to a file # # \param instance_id \type{str} the ID of the profile to export. @@ -104,6 +141,10 @@ class CuraContainerRegistry(ContainerRegistry): if profile: #Success! profile.setReadOnly(False) + new_name = self.createUniqueName("quality", "", os.path.splitext(os.path.basename(file_name))[0], + catalog.i18nc("@label", "Custom profile")) + profile.setName(new_name) + if self._machineHasOwnQualities(): profile.setDefinition(self._activeDefinition()) if self._machineHasOwnMaterials(): diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 2ef9932d24..e5b4cf1583 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -1,5 +1,5 @@ - -import re +# Copyright (c) 2016 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal from UM.Application import Application @@ -171,31 +171,7 @@ class MachineManagerModel(QObject): # \param fallback_name \type{string} Name to use when (stripped) new_name is empty # \return \type{string} Name that is unique for the specified type and name/id def _createUniqueName(self, container_type, current_name, new_name, fallback_name): - new_name = new_name.strip() - num_check = re.compile("(.*?)\s*#\d+$").match(new_name) - if num_check: - new_name = num_check.group(1) - if new_name == "": - new_name = fallback_name - - unique_name = new_name - i = 1 - # In case we are renaming, the current name of the container is also a valid end-result - while self._containerExists(container_type, unique_name) and unique_name != current_name: - i += 1 - unique_name = "%s #%d" % (new_name, i) - - return unique_name - - ## Check if a container with of a certain type and a certain name or id exists - # Both the id and the name are checked, because they may not be the same and it is better if they are both unique - # \param container_type \type{string} Type of the container (machine, quality, ...) - # \param container_name \type{string} Name to check - def _containerExists(self, container_type, container_name): - container_class = ContainerStack if container_type == "machine" else InstanceContainer - - return UM.Settings.ContainerRegistry.getInstance().findContainers(container_class, id = container_name, type = container_type) or \ - UM.Settings.ContainerRegistry.getInstance().findContainers(container_class, name = container_name, type = container_type) + return UM.Settings.ContainerRegistry.createUniqueName(container_type, current_name, new_name, fallback_name) ## Convenience function to check if a stack has errors. def _checkStackForErrors(self, stack): From 92569d63e93bbeb06a813a345ebf54b87b3a053c Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Wed, 15 Jun 2016 13:40:41 +0200 Subject: [PATCH 684/705] Call the method correctly through the instance. Contributes to CURA-1667 Profile import/export --- cura/MachineManagerModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index e5b4cf1583..275ede0518 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -171,7 +171,7 @@ class MachineManagerModel(QObject): # \param fallback_name \type{string} Name to use when (stripped) new_name is empty # \return \type{string} Name that is unique for the specified type and name/id def _createUniqueName(self, container_type, current_name, new_name, fallback_name): - return UM.Settings.ContainerRegistry.createUniqueName(container_type, current_name, new_name, fallback_name) + return UM.Settings.ContainerRegistry.getInstance().createUniqueName(container_type, current_name, new_name, fallback_name) ## Convenience function to check if a stack has errors. def _checkStackForErrors(self, stack): From 85422ae6a55ce0f710f9b00908ebf1011099667a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 15 Jun 2016 13:52:57 +0200 Subject: [PATCH 685/705] Make extruder_nr a string value It's an enum after all, and the front-end doesn't work well with enums that are ints. The code for the back-end should remain the same. Contributes to issue CURA-1716. --- resources/definitions/fdmextruder.def.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/definitions/fdmextruder.def.json b/resources/definitions/fdmextruder.def.json index 940b0bb3ed..06a736330c 100644 --- a/resources/definitions/fdmextruder.def.json +++ b/resources/definitions/fdmextruder.def.json @@ -23,8 +23,7 @@ "label": "Extruder", "description": "The extruder train used for printing. This is used in multi-extrusion.", "type": "extruder", - "default_value": 0, - "minimum_value": "0", + "default_value": "0", "settable_per_mesh": true, "settable_per_extruder": false, "settable_per_meshgroup": false, From 12faf23af891a2b767ee7f7e851cff5c8d023c9a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 15 Jun 2016 14:13:54 +0200 Subject: [PATCH 686/705] Added a way to check if a printer is connected CURA-1036 --- cura/MachineManagerModel.py | 13 +++++++++++++ resources/qml/Sidebar.qml | 4 ++++ 2 files changed, 17 insertions(+) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 275ede0518..bef949b483 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -8,6 +8,8 @@ from UM.Preferences import Preferences import UM.Settings from UM.Settings.Validator import ValidatorState from UM.Settings.InstanceContainer import InstanceContainer + +from cura.PrinterOutputDevice import PrinterOutputDevice from UM.Settings.ContainerStack import ContainerStack from . import ExtruderManager from UM.i18n import i18nCatalog @@ -49,6 +51,8 @@ class MachineManagerModel(QObject): active_machine_id = Preferences.getInstance().getValue("cura/active_machine") + Application.getInstance().getOutputDeviceManager().outputDevicesChanged.connect(self._onOutputDevicesChanged) + if active_machine_id != "": # An active machine was saved, so restore it. self.setActiveMachine(active_machine_id) @@ -65,6 +69,11 @@ class MachineManagerModel(QObject): blurSettings = pyqtSignal() # Emitted to force fields in the advanced sidebar to un-focus, so they update properly + outputDevicesChanged = pyqtSignal() + + def _onOutputDevicesChanged(self): + self.outputDevicesChanged.emit() + @pyqtProperty("QVariantMap", notify = globalContainerChanged) def extrudersIds(self): ## Find all extruders that reference the new stack @@ -164,6 +173,10 @@ class MachineManagerModel(QObject): Application.getInstance().setGlobalContainerStack(new_global_stack) + @pyqtProperty("QVariantList", notify = outputDevicesChanged) + def printerOutputDevices(self): + return [printer_output_device for printer_output_device in Application.getInstance().getOutputDeviceManager().getOutputDevices() if isinstance(printer_output_device, PrinterOutputDevice)] + ## Create a name that is not empty and unique # \param container_type \type{string} Type of the container (machine, quality, ...) # \param current_name \type{} Current name of the container, which may be an acceptable option diff --git a/resources/qml/Sidebar.qml b/resources/qml/Sidebar.qml index b7ff0743de..4c8d671a7f 100644 --- a/resources/qml/Sidebar.qml +++ b/resources/qml/Sidebar.qml @@ -7,6 +7,7 @@ import QtQuick.Controls.Styles 1.1 import QtQuick.Layouts 1.1 import UM 1.1 as UM +import Cura 1.0 as Cura Rectangle { @@ -14,6 +15,9 @@ Rectangle property int currentModeIndex; + // Is there an output device for this printer? + property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0 + color: UM.Theme.getColor("sidebar"); UM.I18nCatalog { id: catalog; name:"cura"} From cb467f488b4587af8a443a56150296b13d53f2a4 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 15 Jun 2016 14:18:21 +0200 Subject: [PATCH 687/705] Don't convert ids to lowercase Eventually we might have to do this due to case-insensitivity of some file systems, but this is not the place for that anyway. Contributes to issue CURA-340. --- cura/ExtruderManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 9be1d8dc53..b6739740f5 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -182,7 +182,7 @@ class ExtruderManager(QObject): quality = qualities[0] preferred_quality_id = machine_definition.getMetaDataEntry("preferred_quality") if preferred_quality_id: - preferred_quality = container_registry.findInstanceContainers(id = preferred_quality_id.lower(), type = "quality") + preferred_quality = container_registry.findInstanceContainers(id = preferred_quality_id, type = "quality") if len(preferred_quality) >= 1: quality = preferred_quality[0] else: From 7c2c24b8a5efee0f81933aac2d08c8a643f338a9 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 15 Jun 2016 14:36:48 +0200 Subject: [PATCH 688/705] Remove unused function Contributes to issue CURA-340. --- cura/MachineManagerModel.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index bef949b483..2960d48ed1 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -74,15 +74,6 @@ class MachineManagerModel(QObject): def _onOutputDevicesChanged(self): self.outputDevicesChanged.emit() - @pyqtProperty("QVariantMap", notify = globalContainerChanged) - def extrudersIds(self): - ## Find all extruders that reference the new stack - extruders = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(**{"machine": self._global_container_stack.getId()}) - result = {} - for extruder in extruders: - result[extruder.getMetaDataEntry("position")] = extruder.getId() - return result - def _onGlobalPropertyChanged(self, key, property_name): if property_name == "value": self.globalValueChanged.emit() From 2e7db9b732cea603f64f8ed791e156f495830d6d Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Wed, 15 Jun 2016 14:38:23 +0200 Subject: [PATCH 689/705] Adding check whether getGlobalContainerStack() returns None or not. If we get None here, the firmware-updater will be closed and detailed error returned to the logs with an explanation why. --- plugins/USBPrinting/USBPrinterOutputDeviceManager.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py index aa6a731c22..2adacde743 100644 --- a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py +++ b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py @@ -128,11 +128,18 @@ class USBPrinterOutputDeviceManager(QObject, SignalEmitter, OutputDevicePlugin, return USBPrinterOutputDeviceManager._instance def _getDefaultFirmwareName(self): + # Check whether getGlobalContainerStack() returns None or not... + global_container_stack = Application.getInstance().getGlobalContainerStack() + if not global_container_stack: + Logger.log("c", "getGlobalContainerStack() returned None") + Logger.log("i", "Closing firmware-updater UI as a consequence") + self._firmware_view.close() + # Detecting id of the current machine - machine_id = Application.getInstance().getGlobalContainerStack().getBottom().id + machine_id = global_container_stack.getBottom().id # Detecting whether it has a heated bed - machine_has_heated_bed = Application.getInstance().getGlobalContainerStack().getProperty("machine_heated_bed", "value") + machine_has_heated_bed = global_container_stack.getProperty("machine_heated_bed", "value") if platform.system() == "Linux": baudrate = 115200 From 77961e83c257b682e01d221c61373c0ee90329a0 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Wed, 15 Jun 2016 15:05:36 +0200 Subject: [PATCH 690/705] Adding a marker for a correctly unresolved import on Linux and OSX --- plugins/USBPrinting/USBPrinterOutputDeviceManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py index 24e2148375..b17fb0753f 100644 --- a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py +++ b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py @@ -223,7 +223,7 @@ class USBPrinterOutputDeviceManager(QObject, SignalEmitter, OutputDevicePlugin, def getSerialPortList(self, only_list_usb = False): base_list = [] if platform.system() == "Windows": - import winreg + import winreg #@UnresolvedImport try: key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,"HARDWARE\\DEVICEMAP\\SERIALCOMM") i = 0 From 6a89062b0a733b2d0e226834d835ba7a44b0f087 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Wed, 15 Jun 2016 16:03:18 +0200 Subject: [PATCH 691/705] Differencing between Platform from UM.* and UM.Scene.* --- cura/CuraApplication.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 48f3998d09..5f5880e3d5 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -4,7 +4,7 @@ from UM.Qt.QtApplication import QtApplication from UM.Scene.SceneNode import SceneNode from UM.Scene.Camera import Camera -from UM.Scene.Platform import Platform +from UM.Scene.Platform import Platform as Scene_Platform from UM.Math.Vector import Vector from UM.Math.Quaternion import Quaternion from UM.Math.AxisAlignedBox import AxisAlignedBox @@ -341,7 +341,7 @@ class CuraApplication(QtApplication): Selection.selectionChanged.connect(self.onSelectionChanged) root = controller.getScene().getRoot() - self._platform = Platform(root) + self._platform = Scene_Platform(root) self._volume = BuildVolume.BuildVolume(root) From d74cecd9db9d45c7d9273bfa09ad16d48cc4696e Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Wed, 15 Jun 2016 16:27:40 +0200 Subject: [PATCH 692/705] Set the ID of the profile object during import; ensure it is unique. Contributes to CURA-1667 Profile import/export --- cura/CuraContainerRegistry.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/CuraContainerRegistry.py b/cura/CuraContainerRegistry.py index 854fe030da..58f8d6d636 100644 --- a/cura/CuraContainerRegistry.py +++ b/cura/CuraContainerRegistry.py @@ -144,6 +144,7 @@ class CuraContainerRegistry(ContainerRegistry): new_name = self.createUniqueName("quality", "", os.path.splitext(os.path.basename(file_name))[0], catalog.i18nc("@label", "Custom profile")) profile.setName(new_name) + profile._id = new_name if self._machineHasOwnQualities(): profile.setDefinition(self._activeDefinition()) From 51222325b0685307e97fdb6901cb814ec813b7ae Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Wed, 15 Jun 2016 17:29:49 +0200 Subject: [PATCH 693/705] Last cleanup Removing useless comments and replacing the log message with something more simple. --- plugins/USBPrinting/USBPrinterOutputDeviceManager.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py index 2adacde743..b8286e7af5 100644 --- a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py +++ b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py @@ -131,14 +131,12 @@ class USBPrinterOutputDeviceManager(QObject, SignalEmitter, OutputDevicePlugin, # Check whether getGlobalContainerStack() returns None or not... global_container_stack = Application.getInstance().getGlobalContainerStack() if not global_container_stack: - Logger.log("c", "getGlobalContainerStack() returned None") - Logger.log("i", "Closing firmware-updater UI as a consequence") + Logger.log("e", "There is no global container stack. Can not update firmware.") self._firmware_view.close() - # Detecting id of the current machine + # The bottom of the containerstack is the machine definition machine_id = global_container_stack.getBottom().id - # Detecting whether it has a heated bed machine_has_heated_bed = global_container_stack.getProperty("machine_heated_bed", "value") if platform.system() == "Linux": From 6b41608db27782a848a21ac4b8e466f5d8132e79 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Wed, 15 Jun 2016 17:33:52 +0200 Subject: [PATCH 694/705] Correcting the last comment.. --- plugins/USBPrinting/USBPrinterOutputDeviceManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py index b8286e7af5..3974881b0b 100644 --- a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py +++ b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py @@ -128,7 +128,7 @@ class USBPrinterOutputDeviceManager(QObject, SignalEmitter, OutputDevicePlugin, return USBPrinterOutputDeviceManager._instance def _getDefaultFirmwareName(self): - # Check whether getGlobalContainerStack() returns None or not... + # Check if there is a valid global container stack global_container_stack = Application.getInstance().getGlobalContainerStack() if not global_container_stack: Logger.log("e", "There is no global container stack. Can not update firmware.") From 7ef64cd05b3ee3fb7952f19379498a1894275cb5 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Wed, 15 Jun 2016 17:43:28 +0200 Subject: [PATCH 695/705] Return an empty string just to be sure --- plugins/USBPrinting/USBPrinterOutputDeviceManager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py index 3974881b0b..a66df1381a 100644 --- a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py +++ b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py @@ -133,6 +133,7 @@ class USBPrinterOutputDeviceManager(QObject, SignalEmitter, OutputDevicePlugin, if not global_container_stack: Logger.log("e", "There is no global container stack. Can not update firmware.") self._firmware_view.close() + return "" # The bottom of the containerstack is the machine definition machine_id = global_container_stack.getBottom().id From 98f9b4f9a0b1135a7c01057b2d0598b9993ffb70 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Thu, 16 Jun 2016 09:15:34 +0200 Subject: [PATCH 696/705] Minor codestyle/naming fix. Contributes to CURA-1667 Profile import/export --- cura/CuraContainerRegistry.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cura/CuraContainerRegistry.py b/cura/CuraContainerRegistry.py index 58f8d6d636..2ecb22d670 100644 --- a/cura/CuraContainerRegistry.py +++ b/cura/CuraContainerRegistry.py @@ -110,14 +110,14 @@ class CuraContainerRegistry(ContainerRegistry): # \param description # \return The plugin object matching the given extension and description. def _findProfileWriter(self, extension, description): - pr = PluginRegistry.getInstance() + plugin_registry = PluginRegistry.getInstance() for plugin_id, meta_data in self._getIOPlugins("profile_writer"): for supported_type in meta_data["profile_writer"]: # All file types this plugin can supposedly write. supported_extension = supported_type.get("extension", None) if supported_extension == extension: # This plugin supports a file type with the same extension. supported_description = supported_type.get("description", None) if supported_description == description: # The description is also identical. Assume it's the same file type. - return pr.getPluginObject(plugin_id) + return plugin_registry.getPluginObject(plugin_id) return None ## Imports a profile from a file @@ -129,9 +129,9 @@ class CuraContainerRegistry(ContainerRegistry): if not file_name: return { "status": "error", "message": catalog.i18nc("@info:status", "Failed to import profile from {0}: {1}", file_name, "Invalid path")} - pr = PluginRegistry.getInstance() + plugin_registry = PluginRegistry.getInstance() for plugin_id, meta_data in self._getIOPlugins("profile_reader"): - profile_reader = pr.getPluginObject(plugin_id) + profile_reader = plugin_registry.getPluginObject(plugin_id) try: profile = profile_reader.read(file_name) #Try to open the file with the profile reader. except Exception as e: @@ -162,12 +162,12 @@ class CuraContainerRegistry(ContainerRegistry): ## Gets a list of profile writer plugins # \return List of tuples of (plugin_id, meta_data). def _getIOPlugins(self, io_type): - pr = PluginRegistry.getInstance() - active_plugin_ids = pr.getActivePlugins() + plugin_registry = PluginRegistry.getInstance() + active_plugin_ids = plugin_registry.getActivePlugins() result = [] for plugin_id in active_plugin_ids: - meta_data = pr.getMetaData(plugin_id) + meta_data = plugin_registry.getMetaData(plugin_id) if io_type in meta_data: result.append( (plugin_id, meta_data) ) return result From cb05f75f6ab754f1f095e1cabd19f7259ed917bf Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 16 Jun 2016 10:14:17 +0200 Subject: [PATCH 697/705] Fix variant vs nozzle CURA-333 --- cura/ExtruderManager.py | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index b6739740f5..f9079c6328 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -111,7 +111,7 @@ class ExtruderManager(QObject): ## Creates a container stack for an extruder train. # # The container stack has an extruder definition at the bottom, which is - # linked to a machine definition. Then it has a nozzle profile, a material + # linked to a machine definition. Then it has a variant profile, a material # profile, a quality profile and a user profile, in that order. # # The resulting container stack is added to the registry. @@ -136,29 +136,29 @@ class ExtruderManager(QObject): container_stack.addMetaDataEntry("position", position) container_stack.addContainer(extruder_definition) - #Find the nozzle to use for this extruder. - nozzle = container_registry.getEmptyInstanceContainer() - if machine_definition.getMetaDataEntry("has_nozzles", default = "False") == "True": - #First add any nozzle. Later, overwrite with preference if the preference is valid. - nozzles = container_registry.findInstanceContainers(machine = machine_id, type = "nozzle") - if len(nozzles) >= 1: - nozzle = nozzles[0] - preferred_nozzle_id = machine_definition.getMetaDataEntry("preferred_nozzle") - if preferred_nozzle_id: - preferred_nozzles = container_registry.findInstanceContainers(id = preferred_nozzle_id, type = "nozzle") - if len(preferred_nozzles) >= 1: - nozzle = preferred_nozzles[0] + #Find the variant to use for this extruder. + variant = container_registry.getEmptyInstanceContainer() + if machine_definition.getMetaDataEntry("has_variants", default = "False") == "True": + #First add any variant. Later, overwrite with preference if the preference is valid. + variants = container_registry.findInstanceContainers(machine = machine_id, type = "variant") + if len(variants) >= 1: + variant = variants[0] + preferred_variant_id = machine_definition.getMetaDataEntry("preferred_variant") + if preferred_variant_id: + preferred_variants = container_registry.findInstanceContainers(id = preferred_variant_id, type = "variant") + if len(preferred_variants) >= 1: + variant = preferred_variants[0] else: - UM.Logger.log("w", "The preferred nozzle \"%s\" of machine %s doesn't exist or is not a nozzle profile.", preferred_nozzle_id, machine_id) - #And leave it at the default nozzle. - container_stack.addContainer(nozzle) + UM.Logger.log("w", "The preferred variant \"%s\" of machine %s doesn't exist or is not a variant profile.", preferred_variant_id, machine_id) + #And leave it at the default variant. + container_stack.addContainer(variant) - #Find a material to use for this nozzle. + #Find a material to use for this variant. material = container_registry.getEmptyInstanceContainer() if machine_definition.getMetaDataEntry("has_materials", default = "False") == "True": #First add any material. Later, overwrite with preference if the preference is valid. - if machine_definition.getMetaDataEntry("has_nozzle_materials", default = "False") == "True": - materials = container_registry.findInstanceContainers(type = "material", machine = machine_id, nozzle = nozzle.getId()) + if machine_definition.getMetaDataEntry("has_variant_materials", default = "False") == "True": + materials = container_registry.findInstanceContainers(type = "material", machine = machine_id, variant = variant.getId()) else: materials = container_registry.findInstanceContainers(type = "material", machine = machine_id) if len(materials) >= 1: @@ -175,7 +175,7 @@ class ExtruderManager(QObject): #Find a quality to use for this extruder. quality = container_registry.getEmptyInstanceContainer() - + #First add any quality. Later, overwrite with preference if the preference is valid. qualities = container_registry.findInstanceContainers(type = "quality") if len(qualities) >= 1: From 7f093be75a1a31f07eba79ec89ab08ebc2d9622d Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 16 Jun 2016 10:41:50 +0200 Subject: [PATCH 698/705] Fix check for has_variants & has_materials These are defined as bool values instead of strings in UM2+ definitions, so I would expect other machine definitions (including jedi) also use bools. CURA-333 --- cura/ExtruderManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index f9079c6328..c83f8d9af7 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -138,7 +138,7 @@ class ExtruderManager(QObject): #Find the variant to use for this extruder. variant = container_registry.getEmptyInstanceContainer() - if machine_definition.getMetaDataEntry("has_variants", default = "False") == "True": + if machine_definition.getMetaDataEntry("has_variants"): #First add any variant. Later, overwrite with preference if the preference is valid. variants = container_registry.findInstanceContainers(machine = machine_id, type = "variant") if len(variants) >= 1: @@ -155,7 +155,7 @@ class ExtruderManager(QObject): #Find a material to use for this variant. material = container_registry.getEmptyInstanceContainer() - if machine_definition.getMetaDataEntry("has_materials", default = "False") == "True": + if machine_definition.getMetaDataEntry("has_materials"): #First add any material. Later, overwrite with preference if the preference is valid. if machine_definition.getMetaDataEntry("has_variant_materials", default = "False") == "True": materials = container_registry.findInstanceContainers(type = "material", machine = machine_id, variant = variant.getId()) From 623b8f276e8c74023aad1592fc16bf98d50da1d5 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 16 Jun 2016 12:47:08 +0200 Subject: [PATCH 699/705] Fix filtering of variants and materials by definition instead of by machine CURA-333 --- cura/ExtruderManager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index c83f8d9af7..5d0ad612cf 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -140,7 +140,7 @@ class ExtruderManager(QObject): variant = container_registry.getEmptyInstanceContainer() if machine_definition.getMetaDataEntry("has_variants"): #First add any variant. Later, overwrite with preference if the preference is valid. - variants = container_registry.findInstanceContainers(machine = machine_id, type = "variant") + variants = container_registry.findInstanceContainers(definition = machine_id, type = "variant") if len(variants) >= 1: variant = variants[0] preferred_variant_id = machine_definition.getMetaDataEntry("preferred_variant") @@ -158,9 +158,9 @@ class ExtruderManager(QObject): if machine_definition.getMetaDataEntry("has_materials"): #First add any material. Later, overwrite with preference if the preference is valid. if machine_definition.getMetaDataEntry("has_variant_materials", default = "False") == "True": - materials = container_registry.findInstanceContainers(type = "material", machine = machine_id, variant = variant.getId()) + materials = container_registry.findInstanceContainers(type = "material", definition = machine_id, variant = variant.getId()) else: - materials = container_registry.findInstanceContainers(type = "material", machine = machine_id) + materials = container_registry.findInstanceContainers(type = "material", definition = machine_id) if len(materials) >= 1: material = materials[0] preferred_material_id = machine_definition.getMetaDataEntry("preferred_material") From 60d6cc07fb86f5755ffc131ffe10af6032f37fd5 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 16 Jun 2016 13:17:22 +0200 Subject: [PATCH 700/705] Add Mendel90 by Bo Herrmannsen Provided via https://github.com/Ultimaker/Cura/issues/808 --- resources/definitions/mendel90.def.json | 94 + resources/meshes/mendel90_platform.stl | 23858 ++++++++++++++++++++++ 2 files changed, 23952 insertions(+) create mode 100644 resources/definitions/mendel90.def.json create mode 100644 resources/meshes/mendel90_platform.stl diff --git a/resources/definitions/mendel90.def.json b/resources/definitions/mendel90.def.json new file mode 100644 index 0000000000..8d9a6d99a1 --- /dev/null +++ b/resources/definitions/mendel90.def.json @@ -0,0 +1,94 @@ +{ + "id": "mendel90", + "name": "Mendel90", + "version": 2, + "inherits": "fdmprinter", + "metadata": + { + "visible": true, + "author": "Bo Herrmannsen", + "category": "Other", + "manufacturer": "Nophead", + "file_formats": "text/x-gcode", + "platform": "mendel90_platform.stl", + "platform_offset": [0, -23.6, 0] + }, + + "pages": [ + "BedLeveling" + ], + + "overrides": { + "machine_start_gcode": { + "default_value": "G21 ;metric values\nG90 ;absolute positioning\nG92 E0 ;zero the extruded length\nM107 ;start with the fan off\nG1 X90 Y200 F6000 ;go to the middle of the front\nG1 Z0.05 ;close to the bed\nG1 Z0.3 ;lift Z\n" + }, + "machine_end_gcode": { + "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nM107 ;carriage fan off\nG91 ;relative positioning\nG1 Z10 ;Move up Z 10mm\nG90 ;back to absolute mode\nG1 E-1 F1200 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG92 E0 ;zero the extruded length\nG1 Y200 F5000 ;Move Y to middle of bed cooling fan\nM42 P42 S255 ;Turn on Bed cooling fan on\nG4 S420 ;Wait 7 mins\nM42 P42 S0 ;Turn off bed cooling fan\nG1 Y10 F5000 ;Move Y to front\nM84 ;steppers off\n" + }, + "material_bed_temp_wait": { + "default_value": true + }, + "material_print_temp_prepend": { + "default_value": true + }, + "machine_width": { + "default_value": 200 + }, + "machine_height": { + "default_value": 200 + }, + "machine_depth": { + "default_value": 200 + }, + "machine_heated_bed": { + "default_value": true + }, + "machine_center_is_zero": { + "default_value": false + }, + "machine_extruder_count": { + "default_value": 1 + }, + "machine_nozzle_tip_outer_diameter": { + "default_value": 1 + }, + "machine_nozzle_head_distance": { + "default_value": 5 + }, + "machine_nozzle_expansion_angle": { + "default_value": 45 + }, + "machine_heat_zone_length": { + "default_value": 16 + }, + "machine_nozzle_heat_up_speed": { + "default_value": 2.0 + }, + "machine_nozzle_cool_down_speed": { + "default_value": 2.0 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "gantry_height": { + "default_value": 55 + }, + "machine_nozzle_size": { + "default_value": 0.4 + }, + "material_diameter": { + "default_value": 1.75 + }, + "machine_head_with_fans_polygon": + { + "default_value": [ + [ -12, 9 ], + [ -12, -9 ], + [ 14, 9 ], + [ 14, -9 ] + ] + } + } +} + + diff --git a/resources/meshes/mendel90_platform.stl b/resources/meshes/mendel90_platform.stl new file mode 100644 index 0000000000..706c90539d --- /dev/null +++ b/resources/meshes/mendel90_platform.stl @@ -0,0 +1,23858 @@ +solid OpenSCAD_Model + facet normal 0.866025 0.5 0 + outer loop + vertex -101.75 -104.5 20.5 + vertex -103.125 -102.118 0.5 + vertex -103.125 -102.118 20.5 + endloop + endfacet + facet normal 0.866025 0.5 0 + outer loop + vertex -103.125 -102.118 0.5 + vertex -101.75 -104.5 20.5 + vertex -101.75 -104.5 0.5 + endloop + endfacet + facet normal -0.866025 0.5 0 + outer loop + vertex -105.875 -102.118 0.5 + vertex -107 -104.067 20.5 + vertex -105.875 -102.118 20.5 + endloop + endfacet + facet normal -0.866025 0.5 -3.46791e-008 + outer loop + vertex -107.25 -104.5 0.5 + vertex -107 -104.067 20.5 + vertex -105.875 -102.118 0.5 + endloop + endfacet + facet normal -0.866026 0.499999 0 + outer loop + vertex -107 -104.067 20.5 + vertex -107.25 -104.5 0.5 + vertex -107.25 -104.5 20.5 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -103.125 -102.118 0.5 + vertex -105.875 -102.118 20.5 + vertex -103.125 -102.118 20.5 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -105.875 -102.118 20.5 + vertex -103.125 -102.118 0.5 + vertex -105.875 -102.118 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -107 -82 20.5 + vertex -106.981 82 20.5 + vertex -106.981 -82 20.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -106.981 82 20.5 + vertex -107 -82 20.5 + vertex -107 82 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 106.981 -82 20.5 + vertex -106.981 -82 20.5 + vertex 106.981 82 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -106.981 82 20.5 + vertex 106.981 82 20.5 + vertex -106.981 -82 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -106.981 -101 20.5 + vertex -103.125 -102.118 20.5 + vertex -105.875 -102.118 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 106.981 82 20.5 + vertex -106.981 82 20.5 + vertex -101.75 104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.125 -102.118 20.5 + vertex -106.981 -101 20.5 + vertex -106.981 -82 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -107 -101 20.5 + vertex -105.875 -102.118 20.5 + vertex -107 -104.067 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.875 -102.118 20.5 + vertex -107 -101 20.5 + vertex -106.981 -101 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 107 -107 20.5 + vertex 105.875 -106.882 20.5 + vertex 107 -104.933 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 107 -107 20.5 + vertex 103.125 -106.882 20.5 + vertex 105.875 -106.882 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -101.75 -104.5 20.5 + vertex -106.981 -82 20.5 + vertex 106.981 -82 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.125 -106.882 20.5 + vertex -101.75 -104.5 20.5 + vertex 101.75 -104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.125 -106.882 20.5 + vertex 103.125 -106.882 20.5 + vertex 107 -107 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.125 -106.882 20.5 + vertex -103.125 -106.882 20.5 + vertex -101.75 -104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -107 -107 20.5 + vertex -103.125 -106.882 20.5 + vertex 107 -107 20.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -103.125 -106.882 20.5 + vertex -107 -107 20.5 + vertex -105.875 -106.882 20.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -105.875 -106.882 20.5 + vertex -107 -107 20.5 + vertex -107 -104.933 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.875 -102.118 20.5 + vertex 107 -101 20.5 + vertex 107 -104.067 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.125 -102.118 20.5 + vertex 106.981 -82 20.5 + vertex 106.981 -101 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 101.75 -104.5 20.5 + vertex 106.981 -82 20.5 + vertex 103.125 -102.118 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.125 -102.118 20.5 + vertex 106.981 -101 20.5 + vertex 105.875 -102.118 20.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 107 -101 20.5 + vertex 105.875 -102.118 20.5 + vertex 106.981 -101 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 106.981 -82 20.5 + vertex 107 82 20.5 + vertex 107 -82 20.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 107 82 20.5 + vertex 106.981 -82 20.5 + vertex 106.981 82 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.875 102.118 20.5 + vertex 107 101 20.5 + vertex 106.981 101 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 107 101 20.5 + vertex 105.875 102.118 20.5 + vertex 107 104.067 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -101.75 -104.5 20.5 + vertex 106.981 -82 20.5 + vertex 101.75 -104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 106.981 82 20.5 + vertex 103.125 102.118 20.5 + vertex 106.981 101 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 106.981 101 20.5 + vertex 103.125 102.118 20.5 + vertex 105.875 102.118 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -106.981 -82 20.5 + vertex -101.75 -104.5 20.5 + vertex -103.125 -102.118 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 106.981 82 20.5 + vertex 101.75 104.5 20.5 + vertex 103.125 102.118 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.875 106.882 20.5 + vertex 107 107 20.5 + vertex 107 104.933 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.125 106.882 20.5 + vertex 107 107 20.5 + vertex 105.875 106.882 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 106.981 82 20.5 + vertex -101.75 104.5 20.5 + vertex 101.75 104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 101.75 104.5 20.5 + vertex -101.75 104.5 20.5 + vertex 103.125 106.882 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.125 106.882 20.5 + vertex 103.125 106.882 20.5 + vertex -101.75 104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.125 106.882 20.5 + vertex -103.125 106.882 20.5 + vertex 107 107 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -107 107 20.5 + vertex -103.125 106.882 20.5 + vertex -105.875 106.882 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.125 106.882 20.5 + vertex -107 107 20.5 + vertex 107 107 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -107 107 20.5 + vertex -105.875 106.882 20.5 + vertex -107 104.933 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -101.75 104.5 20.5 + vertex -106.981 82 20.5 + vertex -103.125 102.118 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -106.981 101 20.5 + vertex -103.125 102.118 20.5 + vertex -106.981 82 20.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -103.125 102.118 20.5 + vertex -106.981 101 20.5 + vertex -105.875 102.118 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -107 101 20.5 + vertex -105.875 102.118 20.5 + vertex -106.981 101 20.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -105.875 102.118 20.5 + vertex -107 101 20.5 + vertex -107 104.067 20.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 107 104.933 20.5 + vertex 107 104.067 20.5 + vertex 107.25 104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.919 104.013 20.5 + vertex 105.99 104.5 20.5 + vertex 106 104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.919 104.013 20.5 + vertex 105.909 104.016 20.5 + vertex 105.99 104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.684 103.579 20.5 + vertex 105.909 104.016 20.5 + vertex 105.919 104.013 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.684 103.579 20.5 + vertex 105.676 103.585 20.5 + vertex 105.909 104.016 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.32 103.244 20.5 + vertex 105.676 103.585 20.5 + vertex 105.684 103.579 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.32 103.244 20.5 + vertex 105.315 103.253 20.5 + vertex 105.676 103.585 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.868 103.046 20.5 + vertex 105.315 103.253 20.5 + vertex 105.32 103.244 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.868 103.046 20.5 + vertex 104.866 103.056 20.5 + vertex 105.315 103.253 20.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 104.868 103.046 20.5 + vertex 104.377 103.015 20.5 + vertex 104.866 103.056 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.376 103.005 20.5 + vertex 104.377 103.015 20.5 + vertex 104.868 103.046 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.376 103.005 20.5 + vertex 103.901 103.135 20.5 + vertex 104.377 103.015 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.897 103.126 20.5 + vertex 103.901 103.135 20.5 + vertex 104.376 103.005 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.897 103.126 20.5 + vertex 103.491 103.404 20.5 + vertex 103.901 103.135 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.484 103.396 20.5 + vertex 103.491 103.404 20.5 + vertex 103.897 103.126 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.484 103.396 20.5 + vertex 103.19 103.791 20.5 + vertex 103.491 103.404 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.181 103.786 20.5 + vertex 103.19 103.791 20.5 + vertex 103.484 103.396 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.181 103.786 20.5 + vertex 103.03 104.255 20.5 + vertex 103.19 103.791 20.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 103.03 104.255 20.5 + vertex 103.02 104.253 20.5 + vertex 103.03 104.745 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.02 104.253 20.5 + vertex 103.03 104.255 20.5 + vertex 103.181 103.786 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.99 104.5 20.5 + vertex 105.919 104.987 20.5 + vertex 106 104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.909 104.984 20.5 + vertex 105.919 104.987 20.5 + vertex 105.99 104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.909 104.984 20.5 + vertex 105.684 105.421 20.5 + vertex 105.919 104.987 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.676 105.415 20.5 + vertex 105.684 105.421 20.5 + vertex 105.909 104.984 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.676 105.415 20.5 + vertex 105.32 105.756 20.5 + vertex 105.684 105.421 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.315 105.747 20.5 + vertex 105.32 105.756 20.5 + vertex 105.676 105.415 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.315 105.747 20.5 + vertex 104.868 105.954 20.5 + vertex 105.32 105.756 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.866 105.944 20.5 + vertex 104.868 105.954 20.5 + vertex 105.315 105.747 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.377 105.985 20.5 + vertex 104.868 105.954 20.5 + vertex 104.866 105.944 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.377 105.985 20.5 + vertex 104.376 105.995 20.5 + vertex 104.868 105.954 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.901 105.865 20.5 + vertex 104.376 105.995 20.5 + vertex 104.377 105.985 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.901 105.865 20.5 + vertex 103.897 105.874 20.5 + vertex 104.376 105.995 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.491 105.596 20.5 + vertex 103.897 105.874 20.5 + vertex 103.901 105.865 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.491 105.596 20.5 + vertex 103.484 105.604 20.5 + vertex 103.897 105.874 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.19 105.209 20.5 + vertex 103.484 105.604 20.5 + vertex 103.491 105.596 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.19 105.209 20.5 + vertex 103.181 105.214 20.5 + vertex 103.484 105.604 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.03 104.745 20.5 + vertex 103.181 105.214 20.5 + vertex 103.19 105.209 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.03 104.745 20.5 + vertex 103.02 104.747 20.5 + vertex 103.181 105.214 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.02 104.747 20.5 + vertex 103.03 104.745 20.5 + vertex 103.02 104.253 20.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 107 -104.067 20.5 + vertex 107 -104.933 20.5 + vertex 107.25 -104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.919 -104.987 20.5 + vertex 105.99 -104.5 20.5 + vertex 106 -104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.919 -104.987 20.5 + vertex 105.909 -104.984 20.5 + vertex 105.99 -104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.684 -105.421 20.5 + vertex 105.909 -104.984 20.5 + vertex 105.919 -104.987 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.684 -105.421 20.5 + vertex 105.676 -105.415 20.5 + vertex 105.909 -104.984 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.32 -105.756 20.5 + vertex 105.676 -105.415 20.5 + vertex 105.684 -105.421 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.32 -105.756 20.5 + vertex 105.315 -105.747 20.5 + vertex 105.676 -105.415 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.868 -105.954 20.5 + vertex 105.315 -105.747 20.5 + vertex 105.32 -105.756 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.868 -105.954 20.5 + vertex 104.866 -105.944 20.5 + vertex 105.315 -105.747 20.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 104.868 -105.954 20.5 + vertex 104.377 -105.985 20.5 + vertex 104.866 -105.944 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.376 -105.995 20.5 + vertex 104.377 -105.985 20.5 + vertex 104.868 -105.954 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.376 -105.995 20.5 + vertex 103.901 -105.865 20.5 + vertex 104.377 -105.985 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.897 -105.874 20.5 + vertex 103.901 -105.865 20.5 + vertex 104.376 -105.995 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.897 -105.874 20.5 + vertex 103.491 -105.596 20.5 + vertex 103.901 -105.865 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.484 -105.604 20.5 + vertex 103.491 -105.596 20.5 + vertex 103.897 -105.874 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.484 -105.604 20.5 + vertex 103.19 -105.209 20.5 + vertex 103.491 -105.596 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.181 -105.214 20.5 + vertex 103.19 -105.209 20.5 + vertex 103.484 -105.604 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.181 -105.214 20.5 + vertex 103.03 -104.745 20.5 + vertex 103.19 -105.209 20.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 103.03 -104.745 20.5 + vertex 103.02 -104.747 20.5 + vertex 103.03 -104.255 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.02 -104.747 20.5 + vertex 103.03 -104.745 20.5 + vertex 103.181 -105.214 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.99 -104.5 20.5 + vertex 105.919 -104.013 20.5 + vertex 106 -104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.909 -104.016 20.5 + vertex 105.919 -104.013 20.5 + vertex 105.99 -104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.909 -104.016 20.5 + vertex 105.684 -103.579 20.5 + vertex 105.919 -104.013 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.676 -103.585 20.5 + vertex 105.684 -103.579 20.5 + vertex 105.909 -104.016 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.676 -103.585 20.5 + vertex 105.32 -103.244 20.5 + vertex 105.684 -103.579 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.315 -103.253 20.5 + vertex 105.32 -103.244 20.5 + vertex 105.676 -103.585 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.315 -103.253 20.5 + vertex 104.868 -103.046 20.5 + vertex 105.32 -103.244 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.866 -103.056 20.5 + vertex 104.868 -103.046 20.5 + vertex 105.315 -103.253 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.377 -103.015 20.5 + vertex 104.868 -103.046 20.5 + vertex 104.866 -103.056 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.377 -103.015 20.5 + vertex 104.376 -103.005 20.5 + vertex 104.868 -103.046 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.901 -103.135 20.5 + vertex 104.376 -103.005 20.5 + vertex 104.377 -103.015 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.901 -103.135 20.5 + vertex 103.897 -103.126 20.5 + vertex 104.376 -103.005 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.491 -103.404 20.5 + vertex 103.897 -103.126 20.5 + vertex 103.901 -103.135 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.491 -103.404 20.5 + vertex 103.484 -103.396 20.5 + vertex 103.897 -103.126 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.19 -103.791 20.5 + vertex 103.484 -103.396 20.5 + vertex 103.491 -103.404 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.19 -103.791 20.5 + vertex 103.181 -103.786 20.5 + vertex 103.484 -103.396 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.03 -104.255 20.5 + vertex 103.181 -103.786 20.5 + vertex 103.19 -103.791 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.03 -104.255 20.5 + vertex 103.02 -104.253 20.5 + vertex 103.181 -103.786 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.02 -104.253 20.5 + vertex 103.03 -104.255 20.5 + vertex 103.02 -104.747 20.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -107 104.933 20.5 + vertex -107.25 104.5 20.5 + vertex -107 104.067 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.081 104.013 20.5 + vertex -103.01 104.5 20.5 + vertex -103 104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.081 104.013 20.5 + vertex -103.091 104.016 20.5 + vertex -103.01 104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.316 103.579 20.5 + vertex -103.091 104.016 20.5 + vertex -103.081 104.013 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.316 103.579 20.5 + vertex -103.324 103.585 20.5 + vertex -103.091 104.016 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.68 103.244 20.5 + vertex -103.324 103.585 20.5 + vertex -103.316 103.579 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.68 103.244 20.5 + vertex -103.685 103.253 20.5 + vertex -103.324 103.585 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.132 103.046 20.5 + vertex -103.685 103.253 20.5 + vertex -103.68 103.244 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.132 103.046 20.5 + vertex -104.134 103.056 20.5 + vertex -103.685 103.253 20.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -104.132 103.046 20.5 + vertex -104.623 103.015 20.5 + vertex -104.134 103.056 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.624 103.005 20.5 + vertex -104.623 103.015 20.5 + vertex -104.132 103.046 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.624 103.005 20.5 + vertex -105.099 103.135 20.5 + vertex -104.623 103.015 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.103 103.126 20.5 + vertex -105.099 103.135 20.5 + vertex -104.624 103.005 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.103 103.126 20.5 + vertex -105.509 103.404 20.5 + vertex -105.099 103.135 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.516 103.396 20.5 + vertex -105.509 103.404 20.5 + vertex -105.103 103.126 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.516 103.396 20.5 + vertex -105.81 103.791 20.5 + vertex -105.509 103.404 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.819 103.786 20.5 + vertex -105.81 103.791 20.5 + vertex -105.516 103.396 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.819 103.786 20.5 + vertex -105.97 104.255 20.5 + vertex -105.81 103.791 20.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -105.97 104.255 20.5 + vertex -105.98 104.253 20.5 + vertex -105.97 104.745 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.98 104.253 20.5 + vertex -105.97 104.255 20.5 + vertex -105.819 103.786 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.01 104.5 20.5 + vertex -103.081 104.987 20.5 + vertex -103 104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.091 104.984 20.5 + vertex -103.081 104.987 20.5 + vertex -103.01 104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.091 104.984 20.5 + vertex -103.316 105.421 20.5 + vertex -103.081 104.987 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.324 105.415 20.5 + vertex -103.316 105.421 20.5 + vertex -103.091 104.984 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.324 105.415 20.5 + vertex -103.68 105.756 20.5 + vertex -103.316 105.421 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.685 105.747 20.5 + vertex -103.68 105.756 20.5 + vertex -103.324 105.415 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.685 105.747 20.5 + vertex -104.132 105.954 20.5 + vertex -103.68 105.756 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.134 105.944 20.5 + vertex -104.132 105.954 20.5 + vertex -103.685 105.747 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.623 105.985 20.5 + vertex -104.132 105.954 20.5 + vertex -104.134 105.944 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.623 105.985 20.5 + vertex -104.624 105.995 20.5 + vertex -104.132 105.954 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.099 105.865 20.5 + vertex -104.624 105.995 20.5 + vertex -104.623 105.985 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.099 105.865 20.5 + vertex -105.103 105.874 20.5 + vertex -104.624 105.995 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.509 105.596 20.5 + vertex -105.103 105.874 20.5 + vertex -105.099 105.865 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.509 105.596 20.5 + vertex -105.516 105.604 20.5 + vertex -105.103 105.874 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.81 105.209 20.5 + vertex -105.516 105.604 20.5 + vertex -105.509 105.596 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.81 105.209 20.5 + vertex -105.819 105.214 20.5 + vertex -105.516 105.604 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.97 104.745 20.5 + vertex -105.819 105.214 20.5 + vertex -105.81 105.209 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.97 104.745 20.5 + vertex -105.98 104.747 20.5 + vertex -105.819 105.214 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.98 104.747 20.5 + vertex -105.97 104.745 20.5 + vertex -105.98 104.253 20.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -107 -104.067 20.5 + vertex -107.25 -104.5 20.5 + vertex -107 -104.933 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.081 -104.987 20.5 + vertex -103.01 -104.5 20.5 + vertex -103 -104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.081 -104.987 20.5 + vertex -103.091 -104.984 20.5 + vertex -103.01 -104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.316 -105.421 20.5 + vertex -103.091 -104.984 20.5 + vertex -103.081 -104.987 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.316 -105.421 20.5 + vertex -103.324 -105.415 20.5 + vertex -103.091 -104.984 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.68 -105.756 20.5 + vertex -103.324 -105.415 20.5 + vertex -103.316 -105.421 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.68 -105.756 20.5 + vertex -103.685 -105.747 20.5 + vertex -103.324 -105.415 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.132 -105.954 20.5 + vertex -103.685 -105.747 20.5 + vertex -103.68 -105.756 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.132 -105.954 20.5 + vertex -104.134 -105.944 20.5 + vertex -103.685 -105.747 20.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -104.132 -105.954 20.5 + vertex -104.623 -105.985 20.5 + vertex -104.134 -105.944 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.624 -105.995 20.5 + vertex -104.623 -105.985 20.5 + vertex -104.132 -105.954 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.624 -105.995 20.5 + vertex -105.099 -105.865 20.5 + vertex -104.623 -105.985 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.103 -105.874 20.5 + vertex -105.099 -105.865 20.5 + vertex -104.624 -105.995 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.103 -105.874 20.5 + vertex -105.509 -105.596 20.5 + vertex -105.099 -105.865 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.516 -105.604 20.5 + vertex -105.509 -105.596 20.5 + vertex -105.103 -105.874 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.516 -105.604 20.5 + vertex -105.81 -105.209 20.5 + vertex -105.509 -105.596 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.819 -105.214 20.5 + vertex -105.81 -105.209 20.5 + vertex -105.516 -105.604 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.819 -105.214 20.5 + vertex -105.97 -104.745 20.5 + vertex -105.81 -105.209 20.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -105.97 -104.745 20.5 + vertex -105.98 -104.747 20.5 + vertex -105.97 -104.255 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.98 -104.747 20.5 + vertex -105.97 -104.745 20.5 + vertex -105.819 -105.214 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.01 -104.5 20.5 + vertex -103.081 -104.013 20.5 + vertex -103 -104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.091 -104.016 20.5 + vertex -103.081 -104.013 20.5 + vertex -103.01 -104.5 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.091 -104.016 20.5 + vertex -103.316 -103.579 20.5 + vertex -103.081 -104.013 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.324 -103.585 20.5 + vertex -103.316 -103.579 20.5 + vertex -103.091 -104.016 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.324 -103.585 20.5 + vertex -103.68 -103.244 20.5 + vertex -103.316 -103.579 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.685 -103.253 20.5 + vertex -103.68 -103.244 20.5 + vertex -103.324 -103.585 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.685 -103.253 20.5 + vertex -104.132 -103.046 20.5 + vertex -103.68 -103.244 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.134 -103.056 20.5 + vertex -104.132 -103.046 20.5 + vertex -103.685 -103.253 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.623 -103.015 20.5 + vertex -104.132 -103.046 20.5 + vertex -104.134 -103.056 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.623 -103.015 20.5 + vertex -104.624 -103.005 20.5 + vertex -104.132 -103.046 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.099 -103.135 20.5 + vertex -104.624 -103.005 20.5 + vertex -104.623 -103.015 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.099 -103.135 20.5 + vertex -105.103 -103.126 20.5 + vertex -104.624 -103.005 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.509 -103.404 20.5 + vertex -105.103 -103.126 20.5 + vertex -105.099 -103.135 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.509 -103.404 20.5 + vertex -105.516 -103.396 20.5 + vertex -105.103 -103.126 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.81 -103.791 20.5 + vertex -105.516 -103.396 20.5 + vertex -105.509 -103.404 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.81 -103.791 20.5 + vertex -105.819 -103.786 20.5 + vertex -105.516 -103.396 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.97 -104.255 20.5 + vertex -105.819 -103.786 20.5 + vertex -105.81 -103.791 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.97 -104.255 20.5 + vertex -105.98 -104.253 20.5 + vertex -105.819 -103.786 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.98 -104.253 20.5 + vertex -105.97 -104.255 20.5 + vertex -105.98 -104.747 20.5 + endloop + endfacet + facet normal 0.866025 -0.5 0 + outer loop + vertex -103.125 -106.882 20.5 + vertex -101.75 -104.5 0.5 + vertex -101.75 -104.5 20.5 + endloop + endfacet + facet normal 0.866025 -0.5 0 + outer loop + vertex -101.75 -104.5 0.5 + vertex -103.125 -106.882 20.5 + vertex -103.125 -106.882 0.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -101.75 -104.5 0.5 + vertex -103.081 -104.987 0.5 + vertex -103 -104.5 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.316 -105.421 0.5 + vertex -101.75 -104.5 0.5 + vertex -103.125 -106.882 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -101.75 -104.5 0.5 + vertex -103.316 -105.421 0.5 + vertex -103.081 -104.987 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.125 -106.882 0.5 + vertex -103.68 -105.756 0.5 + vertex -103.316 -105.421 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.125 -106.882 0.5 + vertex -104.132 -105.954 0.5 + vertex -103.68 -105.756 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.125 -106.882 0.5 + vertex -104.624 -105.995 0.5 + vertex -104.132 -105.954 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.875 -106.882 0.5 + vertex -104.624 -105.995 0.5 + vertex -103.125 -106.882 0.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -104.624 -105.995 0.5 + vertex -105.875 -106.882 0.5 + vertex -105.103 -105.874 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.875 -106.882 0.5 + vertex -105.516 -105.604 0.5 + vertex -105.103 -105.874 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.875 -106.882 0.5 + vertex -105.819 -105.214 0.5 + vertex -105.516 -105.604 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -107.25 -104.5 0.5 + vertex -105.819 -105.214 0.5 + vertex -105.875 -106.882 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.98 -104.747 0.5 + vertex -107.25 -104.5 0.5 + vertex -105.98 -104.253 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.819 -105.214 0.5 + vertex -107.25 -104.5 0.5 + vertex -105.98 -104.747 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.081 -104.013 0.5 + vertex -101.75 -104.5 0.5 + vertex -103 -104.5 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.316 -103.579 0.5 + vertex -101.75 -104.5 0.5 + vertex -103.081 -104.013 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -101.75 -104.5 0.5 + vertex -103.316 -103.579 0.5 + vertex -103.125 -102.118 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.68 -103.244 0.5 + vertex -103.125 -102.118 0.5 + vertex -103.316 -103.579 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.132 -103.046 0.5 + vertex -103.125 -102.118 0.5 + vertex -103.68 -103.244 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.624 -103.005 0.5 + vertex -103.125 -102.118 0.5 + vertex -104.132 -103.046 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.875 -102.118 0.5 + vertex -104.624 -103.005 0.5 + vertex -105.103 -103.126 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.624 -103.005 0.5 + vertex -105.875 -102.118 0.5 + vertex -103.125 -102.118 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.516 -103.396 0.5 + vertex -105.875 -102.118 0.5 + vertex -105.103 -103.126 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.819 -103.786 0.5 + vertex -105.875 -102.118 0.5 + vertex -105.516 -103.396 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -107.25 -104.5 0.5 + vertex -105.819 -103.786 0.5 + vertex -105.98 -104.253 0.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -105.819 -103.786 0.5 + vertex -107.25 -104.5 0.5 + vertex -105.875 -102.118 0.5 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -105.875 -106.882 0.5 + vertex -103.125 -106.882 20.5 + vertex -105.875 -106.882 20.5 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -103.125 -106.882 20.5 + vertex -105.875 -106.882 0.5 + vertex -103.125 -106.882 0.5 + endloop + endfacet + facet normal -0.866026 -0.499999 0 + outer loop + vertex -107.25 -104.5 0.5 + vertex -107 -104.933 20.5 + vertex -107.25 -104.5 20.5 + endloop + endfacet + facet normal -0.866025 -0.5 -3.46791e-008 + outer loop + vertex -105.875 -106.882 0.5 + vertex -107 -104.933 20.5 + vertex -107.25 -104.5 0.5 + endloop + endfacet + facet normal -0.866025 -0.5 0 + outer loop + vertex -107 -104.933 20.5 + vertex -105.875 -106.882 0.5 + vertex -105.875 -106.882 20.5 + endloop + endfacet + facet normal 0.98636 0.164599 0 + outer loop + vertex -103 -104.5 0.5 + vertex -103.081 -104.013 -6.5 + vertex -103.081 -104.013 0.5 + endloop + endfacet + facet normal 0.98636 0.164599 0 + outer loop + vertex -103.081 -104.013 -6.5 + vertex -103 -104.5 0.5 + vertex -103 -104.5 -6.5 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -105.98 -104.747 -6.5 + vertex -105.98 -104.253 0.5 + vertex -105.98 -104.253 -6.5 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex -105.98 -104.253 0.5 + vertex -105.98 -104.747 -6.5 + vertex -105.98 -104.747 0.5 + endloop + endfacet + facet normal 0.0825698 0.996585 -0 + outer loop + vertex -104.132 -103.046 -6.5 + vertex -104.624 -103.005 0.5 + vertex -104.132 -103.046 0.5 + endloop + endfacet + facet normal 0.0825698 0.996585 0 + outer loop + vertex -104.624 -103.005 0.5 + vertex -104.132 -103.046 -6.5 + vertex -104.624 -103.005 -6.5 + endloop + endfacet + facet normal 0.0825698 -0.996585 0 + outer loop + vertex -104.624 -105.995 -6.5 + vertex -104.132 -105.954 0.5 + vertex -104.624 -105.995 0.5 + endloop + endfacet + facet normal 0.0825698 -0.996585 0 + outer loop + vertex -104.132 -105.954 0.5 + vertex -104.624 -105.995 -6.5 + vertex -104.132 -105.954 -6.5 + endloop + endfacet + facet normal 0.401692 -0.915775 0 + outer loop + vertex -104.132 -105.954 -6.5 + vertex -103.68 -105.756 0.5 + vertex -104.132 -105.954 0.5 + endloop + endfacet + facet normal 0.401692 -0.915775 0 + outer loop + vertex -103.68 -105.756 0.5 + vertex -104.132 -105.954 -6.5 + vertex -103.68 -105.756 -6.5 + endloop + endfacet + facet normal 0.677285 0.73572 -0 + outer loop + vertex -103.316 -103.579 -6.5 + vertex -103.68 -103.244 0.5 + vertex -103.316 -103.579 0.5 + endloop + endfacet + facet normal 0.677285 0.73572 0 + outer loop + vertex -103.68 -103.244 0.5 + vertex -103.316 -103.579 -6.5 + vertex -103.68 -103.244 -6.5 + endloop + endfacet + facet normal 0.879474 0.475946 0 + outer loop + vertex -103.081 -104.013 0.5 + vertex -103.316 -103.579 -6.5 + vertex -103.316 -103.579 0.5 + endloop + endfacet + facet normal 0.879474 0.475946 0 + outer loop + vertex -103.316 -103.579 -6.5 + vertex -103.081 -104.013 0.5 + vertex -103.081 -104.013 -6.5 + endloop + endfacet + facet normal 0.401692 0.915775 -0 + outer loop + vertex -103.68 -103.244 -6.5 + vertex -104.132 -103.046 0.5 + vertex -103.68 -103.244 0.5 + endloop + endfacet + facet normal 0.401692 0.915775 0 + outer loop + vertex -104.132 -103.046 0.5 + vertex -103.68 -103.244 -6.5 + vertex -104.132 -103.046 -6.5 + endloop + endfacet + facet normal -0.789137 0.614218 0 + outer loop + vertex -105.819 -103.786 -6.5 + vertex -105.516 -103.396 0.5 + vertex -105.516 -103.396 -6.5 + endloop + endfacet + facet normal -0.789137 0.614218 0 + outer loop + vertex -105.516 -103.396 0.5 + vertex -105.819 -103.786 -6.5 + vertex -105.819 -103.786 0.5 + endloop + endfacet + facet normal -0.945823 0.324684 0 + outer loop + vertex -105.98 -104.253 -6.5 + vertex -105.819 -103.786 0.5 + vertex -105.819 -103.786 -6.5 + endloop + endfacet + facet normal -0.945823 0.324684 0 + outer loop + vertex -105.819 -103.786 0.5 + vertex -105.98 -104.253 -6.5 + vertex -105.98 -104.253 0.5 + endloop + endfacet + facet normal -0.245487 0.9694 0 + outer loop + vertex -104.624 -103.005 -6.5 + vertex -105.103 -103.126 0.5 + vertex -104.624 -103.005 0.5 + endloop + endfacet + facet normal -0.245487 0.9694 0 + outer loop + vertex -105.103 -103.126 0.5 + vertex -104.624 -103.005 -6.5 + vertex -105.103 -103.126 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.081 -104.987 -6.5 + vertex -103.081 -104.013 -6.5 + vertex -103 -104.5 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.316 -105.421 -6.5 + vertex -103.081 -104.013 -6.5 + vertex -103.081 -104.987 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.316 -105.421 -6.5 + vertex -103.316 -103.579 -6.5 + vertex -103.081 -104.013 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.68 -105.756 -6.5 + vertex -103.316 -103.579 -6.5 + vertex -103.316 -105.421 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.68 -105.756 -6.5 + vertex -103.68 -103.244 -6.5 + vertex -103.316 -103.579 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.132 -105.954 -6.5 + vertex -103.68 -103.244 -6.5 + vertex -103.68 -105.756 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.132 -105.954 -6.5 + vertex -104.132 -103.046 -6.5 + vertex -103.68 -103.244 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.624 -105.995 -6.5 + vertex -104.132 -103.046 -6.5 + vertex -104.132 -105.954 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.624 -105.995 -6.5 + vertex -104.624 -103.005 -6.5 + vertex -104.132 -103.046 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.103 -105.874 -6.5 + vertex -104.624 -103.005 -6.5 + vertex -104.624 -105.995 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.103 -105.874 -6.5 + vertex -105.103 -103.126 -6.5 + vertex -104.624 -103.005 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.516 -105.604 -6.5 + vertex -105.103 -103.126 -6.5 + vertex -105.103 -105.874 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.516 -105.604 -6.5 + vertex -105.516 -103.396 -6.5 + vertex -105.103 -103.126 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.819 -105.214 -6.5 + vertex -105.516 -103.396 -6.5 + vertex -105.516 -105.604 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.819 -105.214 -6.5 + vertex -105.819 -103.786 -6.5 + vertex -105.516 -103.396 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.98 -104.747 -6.5 + vertex -105.819 -103.786 -6.5 + vertex -105.819 -105.214 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.819 -103.786 -6.5 + vertex -105.98 -104.747 -6.5 + vertex -105.98 -104.253 -6.5 + endloop + endfacet + facet normal -0.546943 0.83717 0 + outer loop + vertex -105.103 -103.126 -6.5 + vertex -105.516 -103.396 0.5 + vertex -105.103 -103.126 0.5 + endloop + endfacet + facet normal -0.546943 0.83717 0 + outer loop + vertex -105.516 -103.396 0.5 + vertex -105.103 -103.126 -6.5 + vertex -105.516 -103.396 -6.5 + endloop + endfacet + facet normal 0.98636 -0.164599 0 + outer loop + vertex -103.081 -104.987 0.5 + vertex -103 -104.5 -6.5 + vertex -103 -104.5 0.5 + endloop + endfacet + facet normal 0.98636 -0.164599 0 + outer loop + vertex -103 -104.5 -6.5 + vertex -103.081 -104.987 0.5 + vertex -103.081 -104.987 -6.5 + endloop + endfacet + facet normal 0.677285 -0.73572 0 + outer loop + vertex -103.68 -105.756 -6.5 + vertex -103.316 -105.421 0.5 + vertex -103.68 -105.756 0.5 + endloop + endfacet + facet normal 0.677285 -0.73572 0 + outer loop + vertex -103.316 -105.421 0.5 + vertex -103.68 -105.756 -6.5 + vertex -103.316 -105.421 -6.5 + endloop + endfacet + facet normal 0.879474 -0.475946 0 + outer loop + vertex -103.316 -105.421 0.5 + vertex -103.081 -104.987 -6.5 + vertex -103.081 -104.987 0.5 + endloop + endfacet + facet normal 0.879474 -0.475946 0 + outer loop + vertex -103.081 -104.987 -6.5 + vertex -103.316 -105.421 0.5 + vertex -103.316 -105.421 -6.5 + endloop + endfacet + facet normal -0.245487 -0.9694 0 + outer loop + vertex -105.103 -105.874 -6.5 + vertex -104.624 -105.995 0.5 + vertex -105.103 -105.874 0.5 + endloop + endfacet + facet normal -0.245487 -0.9694 -0 + outer loop + vertex -104.624 -105.995 0.5 + vertex -105.103 -105.874 -6.5 + vertex -104.624 -105.995 -6.5 + endloop + endfacet + facet normal -0.789137 -0.614218 0 + outer loop + vertex -105.516 -105.604 -6.5 + vertex -105.819 -105.214 0.5 + vertex -105.819 -105.214 -6.5 + endloop + endfacet + facet normal -0.789137 -0.614218 0 + outer loop + vertex -105.819 -105.214 0.5 + vertex -105.516 -105.604 -6.5 + vertex -105.516 -105.604 0.5 + endloop + endfacet + facet normal -0.945823 -0.324684 0 + outer loop + vertex -105.819 -105.214 -6.5 + vertex -105.98 -104.747 0.5 + vertex -105.98 -104.747 -6.5 + endloop + endfacet + facet normal -0.945823 -0.324684 0 + outer loop + vertex -105.98 -104.747 0.5 + vertex -105.819 -105.214 -6.5 + vertex -105.819 -105.214 0.5 + endloop + endfacet + facet normal -0.546943 -0.83717 0 + outer loop + vertex -105.516 -105.604 -6.5 + vertex -105.103 -105.874 0.5 + vertex -105.516 -105.604 0.5 + endloop + endfacet + facet normal -0.546943 -0.83717 -0 + outer loop + vertex -105.103 -105.874 0.5 + vertex -105.516 -105.604 -6.5 + vertex -105.103 -105.874 -6.5 + endloop + endfacet + facet normal -0.98636 -0.164599 0 + outer loop + vertex -103 -104.5 13.5 + vertex -103.081 -104.013 20.5 + vertex -103.081 -104.013 13.5 + endloop + endfacet + facet normal -0.98636 -0.164599 0 + outer loop + vertex -103.081 -104.013 20.5 + vertex -103 -104.5 13.5 + vertex -103 -104.5 20.5 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex -105.98 -104.747 20.5 + vertex -105.98 -104.253 13.5 + vertex -105.98 -104.253 20.5 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex -105.98 -104.253 13.5 + vertex -105.98 -104.747 20.5 + vertex -105.98 -104.747 13.5 + endloop + endfacet + facet normal -0.0825698 -0.996585 0 + outer loop + vertex -104.624 -103.005 13.5 + vertex -104.132 -103.046 20.5 + vertex -104.624 -103.005 20.5 + endloop + endfacet + facet normal -0.0825698 -0.996585 -0 + outer loop + vertex -104.132 -103.046 20.5 + vertex -104.624 -103.005 13.5 + vertex -104.132 -103.046 13.5 + endloop + endfacet + facet normal -0.0825698 0.996585 0 + outer loop + vertex -104.132 -105.954 13.5 + vertex -104.624 -105.995 20.5 + vertex -104.132 -105.954 20.5 + endloop + endfacet + facet normal -0.0825698 0.996585 0 + outer loop + vertex -104.624 -105.995 20.5 + vertex -104.132 -105.954 13.5 + vertex -104.624 -105.995 13.5 + endloop + endfacet + facet normal -0.401692 0.915775 0 + outer loop + vertex -103.68 -105.756 13.5 + vertex -104.132 -105.954 20.5 + vertex -103.68 -105.756 20.5 + endloop + endfacet + facet normal -0.401692 0.915775 0 + outer loop + vertex -104.132 -105.954 20.5 + vertex -103.68 -105.756 13.5 + vertex -104.132 -105.954 13.5 + endloop + endfacet + facet normal -0.677285 -0.73572 0 + outer loop + vertex -103.68 -103.244 13.5 + vertex -103.316 -103.579 20.5 + vertex -103.68 -103.244 20.5 + endloop + endfacet + facet normal -0.677285 -0.73572 -0 + outer loop + vertex -103.316 -103.579 20.5 + vertex -103.68 -103.244 13.5 + vertex -103.316 -103.579 13.5 + endloop + endfacet + facet normal -0.879474 -0.475946 0 + outer loop + vertex -103.081 -104.013 13.5 + vertex -103.316 -103.579 20.5 + vertex -103.316 -103.579 13.5 + endloop + endfacet + facet normal -0.879474 -0.475946 0 + outer loop + vertex -103.316 -103.579 20.5 + vertex -103.081 -104.013 13.5 + vertex -103.081 -104.013 20.5 + endloop + endfacet + facet normal -0.401692 -0.915775 0 + outer loop + vertex -104.132 -103.046 13.5 + vertex -103.68 -103.244 20.5 + vertex -104.132 -103.046 20.5 + endloop + endfacet + facet normal -0.401692 -0.915775 -0 + outer loop + vertex -103.68 -103.244 20.5 + vertex -104.132 -103.046 13.5 + vertex -103.68 -103.244 13.5 + endloop + endfacet + facet normal 0.789137 -0.614218 0 + outer loop + vertex -105.819 -103.786 20.5 + vertex -105.516 -103.396 13.5 + vertex -105.516 -103.396 20.5 + endloop + endfacet + facet normal 0.789137 -0.614218 0 + outer loop + vertex -105.516 -103.396 13.5 + vertex -105.819 -103.786 20.5 + vertex -105.819 -103.786 13.5 + endloop + endfacet + facet normal 0.945823 -0.324684 0 + outer loop + vertex -105.98 -104.253 20.5 + vertex -105.819 -103.786 13.5 + vertex -105.819 -103.786 20.5 + endloop + endfacet + facet normal 0.945823 -0.324684 0 + outer loop + vertex -105.819 -103.786 13.5 + vertex -105.98 -104.253 20.5 + vertex -105.98 -104.253 13.5 + endloop + endfacet + facet normal 0.245487 -0.9694 0 + outer loop + vertex -105.103 -103.126 13.5 + vertex -104.624 -103.005 20.5 + vertex -105.103 -103.126 20.5 + endloop + endfacet + facet normal 0.245487 -0.9694 0 + outer loop + vertex -104.624 -103.005 20.5 + vertex -105.103 -103.126 13.5 + vertex -104.624 -103.005 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.081 -104.013 13.5 + vertex -103.01 -104.5 13.5 + vertex -103 -104.5 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.081 -104.013 13.5 + vertex -103.091 -104.016 13.5 + vertex -103.01 -104.5 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.316 -103.579 13.5 + vertex -103.091 -104.016 13.5 + vertex -103.081 -104.013 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.316 -103.579 13.5 + vertex -103.324 -103.585 13.5 + vertex -103.091 -104.016 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.68 -103.244 13.5 + vertex -103.324 -103.585 13.5 + vertex -103.316 -103.579 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.68 -103.244 13.5 + vertex -103.685 -103.253 13.5 + vertex -103.324 -103.585 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.132 -103.046 13.5 + vertex -103.685 -103.253 13.5 + vertex -103.68 -103.244 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.132 -103.046 13.5 + vertex -104.134 -103.056 13.5 + vertex -103.685 -103.253 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.132 -103.046 13.5 + vertex -104.623 -103.015 13.5 + vertex -104.134 -103.056 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.624 -103.005 13.5 + vertex -104.623 -103.015 13.5 + vertex -104.132 -103.046 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.624 -103.005 13.5 + vertex -105.099 -103.135 13.5 + vertex -104.623 -103.015 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -105.103 -103.126 13.5 + vertex -105.099 -103.135 13.5 + vertex -104.624 -103.005 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.103 -103.126 13.5 + vertex -105.509 -103.404 13.5 + vertex -105.099 -103.135 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -105.516 -103.396 13.5 + vertex -105.509 -103.404 13.5 + vertex -105.103 -103.126 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.516 -103.396 13.5 + vertex -105.81 -103.791 13.5 + vertex -105.509 -103.404 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -105.819 -103.786 13.5 + vertex -105.81 -103.791 13.5 + vertex -105.516 -103.396 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.819 -103.786 13.5 + vertex -105.97 -104.255 13.5 + vertex -105.81 -103.791 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.97 -104.255 13.5 + vertex -105.98 -104.253 13.5 + vertex -105.97 -104.745 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -105.98 -104.253 13.5 + vertex -105.97 -104.255 13.5 + vertex -105.819 -103.786 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -103.01 -104.5 13.5 + vertex -103.081 -104.987 13.5 + vertex -103 -104.5 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -103.091 -104.984 13.5 + vertex -103.081 -104.987 13.5 + vertex -103.01 -104.5 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.091 -104.984 13.5 + vertex -103.316 -105.421 13.5 + vertex -103.081 -104.987 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -103.324 -105.415 13.5 + vertex -103.316 -105.421 13.5 + vertex -103.091 -104.984 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.324 -105.415 13.5 + vertex -103.68 -105.756 13.5 + vertex -103.316 -105.421 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -103.685 -105.747 13.5 + vertex -103.68 -105.756 13.5 + vertex -103.324 -105.415 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.685 -105.747 13.5 + vertex -104.132 -105.954 13.5 + vertex -103.68 -105.756 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -104.134 -105.944 13.5 + vertex -104.132 -105.954 13.5 + vertex -103.685 -105.747 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.623 -105.985 13.5 + vertex -104.132 -105.954 13.5 + vertex -104.134 -105.944 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -104.623 -105.985 13.5 + vertex -104.624 -105.995 13.5 + vertex -104.132 -105.954 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.099 -105.865 13.5 + vertex -104.624 -105.995 13.5 + vertex -104.623 -105.985 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.099 -105.865 13.5 + vertex -105.103 -105.874 13.5 + vertex -104.624 -105.995 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.509 -105.596 13.5 + vertex -105.103 -105.874 13.5 + vertex -105.099 -105.865 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.509 -105.596 13.5 + vertex -105.516 -105.604 13.5 + vertex -105.103 -105.874 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.81 -105.209 13.5 + vertex -105.516 -105.604 13.5 + vertex -105.509 -105.596 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.81 -105.209 13.5 + vertex -105.819 -105.214 13.5 + vertex -105.516 -105.604 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.97 -104.745 13.5 + vertex -105.819 -105.214 13.5 + vertex -105.81 -105.209 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.97 -104.745 13.5 + vertex -105.98 -104.747 13.5 + vertex -105.819 -105.214 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.98 -104.747 13.5 + vertex -105.97 -104.745 13.5 + vertex -105.98 -104.253 13.5 + endloop + endfacet + facet normal 0.546943 -0.83717 0 + outer loop + vertex -105.516 -103.396 13.5 + vertex -105.103 -103.126 20.5 + vertex -105.516 -103.396 20.5 + endloop + endfacet + facet normal 0.546943 -0.83717 0 + outer loop + vertex -105.103 -103.126 20.5 + vertex -105.516 -103.396 13.5 + vertex -105.103 -103.126 13.5 + endloop + endfacet + facet normal -0.98636 0.164599 0 + outer loop + vertex -103.081 -104.987 13.5 + vertex -103 -104.5 20.5 + vertex -103 -104.5 13.5 + endloop + endfacet + facet normal -0.98636 0.164599 0 + outer loop + vertex -103 -104.5 20.5 + vertex -103.081 -104.987 13.5 + vertex -103.081 -104.987 20.5 + endloop + endfacet + facet normal 0.945823 0.324684 0 + outer loop + vertex -105.819 -105.214 20.5 + vertex -105.98 -104.747 13.5 + vertex -105.98 -104.747 20.5 + endloop + endfacet + facet normal 0.945823 0.324684 0 + outer loop + vertex -105.98 -104.747 13.5 + vertex -105.819 -105.214 20.5 + vertex -105.819 -105.214 13.5 + endloop + endfacet + facet normal -0.677285 0.73572 0 + outer loop + vertex -103.316 -105.421 13.5 + vertex -103.68 -105.756 20.5 + vertex -103.316 -105.421 20.5 + endloop + endfacet + facet normal -0.677285 0.73572 0 + outer loop + vertex -103.68 -105.756 20.5 + vertex -103.316 -105.421 13.5 + vertex -103.68 -105.756 13.5 + endloop + endfacet + facet normal -0.879474 0.475946 0 + outer loop + vertex -103.316 -105.421 13.5 + vertex -103.081 -104.987 20.5 + vertex -103.081 -104.987 13.5 + endloop + endfacet + facet normal -0.879474 0.475946 0 + outer loop + vertex -103.081 -104.987 20.5 + vertex -103.316 -105.421 13.5 + vertex -103.316 -105.421 20.5 + endloop + endfacet + facet normal 0.245487 0.9694 -0 + outer loop + vertex -104.624 -105.995 13.5 + vertex -105.103 -105.874 20.5 + vertex -104.624 -105.995 20.5 + endloop + endfacet + facet normal 0.245487 0.9694 0 + outer loop + vertex -105.103 -105.874 20.5 + vertex -104.624 -105.995 13.5 + vertex -105.103 -105.874 13.5 + endloop + endfacet + facet normal 0.789137 0.614218 0 + outer loop + vertex -105.516 -105.604 20.5 + vertex -105.819 -105.214 13.5 + vertex -105.819 -105.214 20.5 + endloop + endfacet + facet normal 0.789137 0.614218 0 + outer loop + vertex -105.819 -105.214 13.5 + vertex -105.516 -105.604 20.5 + vertex -105.516 -105.604 13.5 + endloop + endfacet + facet normal 0.546943 0.83717 -0 + outer loop + vertex -105.103 -105.874 13.5 + vertex -105.516 -105.604 20.5 + vertex -105.103 -105.874 20.5 + endloop + endfacet + facet normal 0.546943 0.83717 0 + outer loop + vertex -105.516 -105.604 20.5 + vertex -105.103 -105.874 13.5 + vertex -105.516 -105.604 13.5 + endloop + endfacet + facet normal 0.995974 0.0896469 0 + outer loop + vertex -101.75 -104.5 25.08 + vertex -101.794 -104.009 22.1 + vertex -101.794 -104.009 25.08 + endloop + endfacet + facet normal 0.995974 0.0896469 0 + outer loop + vertex -101.794 -104.009 22.1 + vertex -101.75 -104.5 25.08 + vertex -101.75 -104.5 22.1 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -107.239 -104.747 22.1 + vertex -107.239 -104.253 25.08 + vertex -107.239 -104.253 22.1 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex -107.239 -104.253 25.08 + vertex -107.239 -104.747 22.1 + vertex -107.239 -104.747 25.08 + endloop + endfacet + facet normal 0.0448622 0.998993 -0 + outer loop + vertex -104.131 -101.775 22.1 + vertex -104.623 -101.753 25.08 + vertex -104.131 -101.775 25.08 + endloop + endfacet + facet normal 0.0448622 0.998993 0 + outer loop + vertex -104.623 -101.753 25.08 + vertex -104.131 -101.775 22.1 + vertex -104.623 -101.753 22.1 + endloop + endfacet + facet normal 0.0448622 -0.998993 0 + outer loop + vertex -104.623 -107.247 22.1 + vertex -104.131 -107.225 25.08 + vertex -104.623 -107.247 25.08 + endloop + endfacet + facet normal 0.0448622 -0.998993 0 + outer loop + vertex -104.131 -107.225 25.08 + vertex -104.623 -107.247 22.1 + vertex -104.131 -107.225 22.1 + endloop + endfacet + facet normal 0.809016 -0.587786 0 + outer loop + vertex -102.429 -106.309 25.08 + vertex -102.139 -105.91 22.1 + vertex -102.139 -105.91 25.08 + endloop + endfacet + facet normal 0.809016 -0.587786 0 + outer loop + vertex -102.139 -105.91 22.1 + vertex -102.429 -106.309 25.08 + vertex -102.429 -106.309 22.1 + endloop + endfacet + facet normal 0.691067 0.722791 -0 + outer loop + vertex -102.429 -102.691 22.1 + vertex -102.785 -102.35 25.08 + vertex -102.429 -102.691 25.08 + endloop + endfacet + facet normal 0.691067 0.722791 0 + outer loop + vertex -102.785 -102.35 25.08 + vertex -102.429 -102.691 22.1 + vertex -102.785 -102.35 22.1 + endloop + endfacet + facet normal -0.753075 0.657935 0 + outer loop + vertex -106.725 -102.884 22.1 + vertex -106.4 -102.512 25.08 + vertex -106.4 -102.512 22.1 + endloop + endfacet + facet normal -0.753075 0.657935 0 + outer loop + vertex -106.4 -102.512 25.08 + vertex -106.725 -102.884 22.1 + vertex -106.725 -102.884 25.08 + endloop + endfacet + facet normal -0.47387 0.880595 0 + outer loop + vertex -105.581 -101.971 22.1 + vertex -106.015 -102.205 25.08 + vertex -105.581 -101.971 25.08 + endloop + endfacet + facet normal -0.47387 0.880595 0 + outer loop + vertex -106.015 -102.205 25.08 + vertex -105.581 -101.971 22.1 + vertex -106.015 -102.205 22.1 + endloop + endfacet + facet normal 0.963965 -0.26603 0 + outer loop + vertex -101.925 -105.466 25.08 + vertex -101.794 -104.991 22.1 + vertex -101.794 -104.991 25.08 + endloop + endfacet + facet normal 0.963965 -0.26603 0 + outer loop + vertex -101.794 -104.991 22.1 + vertex -101.925 -105.466 25.08 + vertex -101.925 -105.466 22.1 + endloop + endfacet + facet normal 0.90097 0.433881 0 + outer loop + vertex -101.925 -103.534 25.08 + vertex -102.139 -103.09 22.1 + vertex -102.139 -103.09 25.08 + endloop + endfacet + facet normal 0.90097 0.433881 0 + outer loop + vertex -102.139 -103.09 22.1 + vertex -101.925 -103.534 25.08 + vertex -101.925 -103.534 22.1 + endloop + endfacet + facet normal 0.963965 0.26603 0 + outer loop + vertex -101.794 -104.009 25.08 + vertex -101.925 -103.534 22.1 + vertex -101.925 -103.534 25.08 + endloop + endfacet + facet normal 0.963965 0.26603 0 + outer loop + vertex -101.925 -103.534 22.1 + vertex -101.794 -104.009 25.08 + vertex -101.794 -104.009 22.1 + endloop + endfacet + facet normal 0.809016 0.587786 0 + outer loop + vertex -102.139 -103.09 25.08 + vertex -102.429 -102.691 22.1 + vertex -102.429 -102.691 25.08 + endloop + endfacet + facet normal 0.809016 0.587786 0 + outer loop + vertex -102.429 -102.691 22.1 + vertex -102.139 -103.09 25.08 + vertex -102.139 -103.09 22.1 + endloop + endfacet + facet normal 0.393015 0.919532 -0 + outer loop + vertex -103.197 -102.078 22.1 + vertex -103.65 -101.885 25.08 + vertex -103.197 -102.078 25.08 + endloop + endfacet + facet normal 0.393015 0.919532 0 + outer loop + vertex -103.65 -101.885 25.08 + vertex -103.197 -102.078 22.1 + vertex -103.65 -101.885 22.1 + endloop + endfacet + facet normal 0.222531 0.974926 -0 + outer loop + vertex -103.65 -101.885 22.1 + vertex -104.131 -101.775 25.08 + vertex -103.65 -101.885 25.08 + endloop + endfacet + facet normal 0.222531 0.974926 0 + outer loop + vertex -104.131 -101.775 25.08 + vertex -103.65 -101.885 22.1 + vertex -104.131 -101.775 22.1 + endloop + endfacet + facet normal 0.550891 0.834577 -0 + outer loop + vertex -102.785 -102.35 22.1 + vertex -103.197 -102.078 25.08 + vertex -102.785 -102.35 25.08 + endloop + endfacet + facet normal 0.550891 0.834577 0 + outer loop + vertex -103.197 -102.078 25.08 + vertex -102.785 -102.35 22.1 + vertex -103.197 -102.078 22.1 + endloop + endfacet + facet normal -0.936235 0.351374 0 + outer loop + vertex -107.151 -103.768 22.1 + vertex -106.978 -103.307 25.08 + vertex -106.978 -103.307 22.1 + endloop + endfacet + facet normal -0.936235 0.351374 0 + outer loop + vertex -106.978 -103.307 25.08 + vertex -107.151 -103.768 22.1 + vertex -107.151 -103.768 25.08 + endloop + endfacet + facet normal -0.85845 0.512897 0 + outer loop + vertex -106.978 -103.307 22.1 + vertex -106.725 -102.884 25.08 + vertex -106.725 -102.884 22.1 + endloop + endfacet + facet normal -0.85845 0.512897 0 + outer loop + vertex -106.725 -102.884 25.08 + vertex -106.978 -103.307 22.1 + vertex -106.978 -103.307 25.08 + endloop + endfacet + facet normal -0.983928 0.178565 0 + outer loop + vertex -107.239 -104.253 22.1 + vertex -107.151 -103.768 25.08 + vertex -107.151 -103.768 22.1 + endloop + endfacet + facet normal -0.983928 0.178565 0 + outer loop + vertex -107.151 -103.768 25.08 + vertex -107.239 -104.253 22.1 + vertex -107.239 -104.253 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.057 -104.5 25.08 + vertex -101.75 -104.5 25.08 + vertex -101.794 -104.009 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.057 -104.5 25.08 + vertex -101.794 -104.009 25.08 + vertex -101.925 -103.534 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -101.75 -104.5 25.08 + vertex -103.057 -104.5 25.08 + vertex -101.794 -104.991 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.057 -104.5 25.08 + vertex -101.925 -103.534 25.08 + vertex -102.139 -103.09 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -101.794 -104.991 25.08 + vertex -103.057 -104.5 25.08 + vertex -101.925 -105.466 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.778 -103.25 25.08 + vertex -102.139 -103.09 25.08 + vertex -102.429 -102.691 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -101.925 -105.466 25.08 + vertex -103.057 -104.5 25.08 + vertex -102.139 -105.91 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.778 -103.25 25.08 + vertex -102.429 -102.691 25.08 + vertex -102.785 -102.35 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -103.778 -105.75 25.08 + vertex -102.139 -105.91 25.08 + vertex -103.057 -104.5 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -102.139 -105.91 25.08 + vertex -103.778 -105.75 25.08 + vertex -102.429 -106.309 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.778 -103.25 25.08 + vertex -102.785 -102.35 25.08 + vertex -103.197 -102.078 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.778 -103.25 25.08 + vertex -103.197 -102.078 25.08 + vertex -103.65 -101.885 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -102.139 -103.09 25.08 + vertex -103.778 -103.25 25.08 + vertex -103.057 -104.5 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.131 -101.775 25.08 + vertex -103.778 -103.25 25.08 + vertex -103.65 -101.885 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.623 -101.753 25.08 + vertex -103.778 -103.25 25.08 + vertex -104.131 -101.775 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.222 -103.25 25.08 + vertex -104.623 -101.753 25.08 + vertex -105.112 -101.819 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.623 -101.753 25.08 + vertex -105.222 -103.25 25.08 + vertex -103.778 -103.25 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -105.581 -101.971 25.08 + vertex -105.222 -103.25 25.08 + vertex -105.112 -101.819 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -106.015 -102.205 25.08 + vertex -105.222 -103.25 25.08 + vertex -105.581 -101.971 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -106.4 -102.512 25.08 + vertex -105.222 -103.25 25.08 + vertex -106.015 -102.205 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -102.429 -106.309 25.08 + vertex -103.778 -105.75 25.08 + vertex -102.785 -106.65 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -102.785 -106.65 25.08 + vertex -103.778 -105.75 25.08 + vertex -103.197 -106.922 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.197 -106.922 25.08 + vertex -103.778 -105.75 25.08 + vertex -103.65 -107.115 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.778 -105.75 25.08 + vertex -104.131 -107.225 25.08 + vertex -103.65 -107.115 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.778 -105.75 25.08 + vertex -104.623 -107.247 25.08 + vertex -104.131 -107.225 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -105.222 -105.75 25.08 + vertex -104.623 -107.247 25.08 + vertex -103.778 -105.75 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.623 -107.247 25.08 + vertex -105.222 -105.75 25.08 + vertex -105.112 -107.181 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.222 -105.75 25.08 + vertex -105.581 -107.029 25.08 + vertex -105.112 -107.181 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -106.978 -105.693 25.08 + vertex -105.222 -105.75 25.08 + vertex -105.943 -104.5 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.222 -105.75 25.08 + vertex -106.015 -106.795 25.08 + vertex -105.581 -107.029 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -106.725 -102.884 25.08 + vertex -105.222 -103.25 25.08 + vertex -106.4 -102.512 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -106.978 -103.307 25.08 + vertex -105.222 -103.25 25.08 + vertex -106.725 -102.884 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.222 -105.75 25.08 + vertex -106.4 -106.488 25.08 + vertex -106.015 -106.795 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.222 -103.25 25.08 + vertex -106.978 -103.307 25.08 + vertex -105.943 -104.5 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.222 -105.75 25.08 + vertex -106.725 -106.116 25.08 + vertex -106.4 -106.488 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -107.151 -103.768 25.08 + vertex -105.943 -104.5 25.08 + vertex -106.978 -103.307 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.222 -105.75 25.08 + vertex -106.978 -105.693 25.08 + vertex -106.725 -106.116 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -107.239 -104.253 25.08 + vertex -105.943 -104.5 25.08 + vertex -107.151 -103.768 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.943 -104.5 25.08 + vertex -107.151 -105.232 25.08 + vertex -106.978 -105.693 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -107.239 -104.747 25.08 + vertex -105.943 -104.5 25.08 + vertex -107.239 -104.253 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.943 -104.5 25.08 + vertex -107.239 -104.747 25.08 + vertex -107.151 -105.232 25.08 + endloop + endfacet + facet normal -0.62349 0.781831 0 + outer loop + vertex -106.015 -102.205 22.1 + vertex -106.4 -102.512 25.08 + vertex -106.015 -102.205 25.08 + endloop + endfacet + facet normal -0.62349 0.781831 0 + outer loop + vertex -106.4 -102.512 25.08 + vertex -106.015 -102.205 22.1 + vertex -106.4 -102.512 22.1 + endloop + endfacet + facet normal -0.134229 0.99095 0 + outer loop + vertex -104.623 -101.753 22.1 + vertex -105.112 -101.819 25.08 + vertex -104.623 -101.753 25.08 + endloop + endfacet + facet normal -0.134229 0.99095 0 + outer loop + vertex -105.112 -101.819 25.08 + vertex -104.623 -101.753 22.1 + vertex -105.112 -101.819 22.1 + endloop + endfacet + facet normal 0.995974 -0.0896469 0 + outer loop + vertex -101.794 -104.991 25.08 + vertex -101.75 -104.5 22.1 + vertex -101.75 -104.5 25.08 + endloop + endfacet + facet normal 0.995974 -0.0896469 0 + outer loop + vertex -101.75 -104.5 22.1 + vertex -101.794 -104.991 25.08 + vertex -101.794 -104.991 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.01 -104.5 22.1 + vertex -101.75 -104.5 22.1 + vertex -101.794 -104.991 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.091 -104.984 22.1 + vertex -101.794 -104.991 22.1 + vertex -101.925 -105.466 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -101.75 -104.5 22.1 + vertex -103.01 -104.5 22.1 + vertex -101.794 -104.009 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.091 -104.984 22.1 + vertex -101.925 -105.466 22.1 + vertex -102.139 -105.91 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.091 -104.016 22.1 + vertex -101.794 -104.009 22.1 + vertex -103.01 -104.5 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.324 -105.415 22.1 + vertex -102.139 -105.91 22.1 + vertex -102.429 -106.309 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -101.794 -104.009 22.1 + vertex -103.091 -104.016 22.1 + vertex -101.925 -103.534 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.324 -105.415 22.1 + vertex -102.429 -106.309 22.1 + vertex -102.785 -106.65 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -101.925 -103.534 22.1 + vertex -103.091 -104.016 22.1 + vertex -102.139 -103.09 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.324 -103.585 22.1 + vertex -102.139 -103.09 22.1 + vertex -103.091 -104.016 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -101.794 -104.991 22.1 + vertex -103.091 -104.984 22.1 + vertex -103.01 -104.5 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.685 -105.747 22.1 + vertex -102.785 -106.65 22.1 + vertex -103.197 -106.922 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -102.139 -105.91 22.1 + vertex -103.324 -105.415 22.1 + vertex -103.091 -104.984 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.134 -105.944 22.1 + vertex -103.197 -106.922 22.1 + vertex -103.65 -107.115 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -102.785 -106.65 22.1 + vertex -103.685 -105.747 22.1 + vertex -103.324 -105.415 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.134 -105.944 22.1 + vertex -103.65 -107.115 22.1 + vertex -104.131 -107.225 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.197 -106.922 22.1 + vertex -104.134 -105.944 22.1 + vertex -103.685 -105.747 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.131 -107.225 22.1 + vertex -104.623 -105.985 22.1 + vertex -104.134 -105.944 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.623 -107.247 22.1 + vertex -104.623 -105.985 22.1 + vertex -104.131 -107.225 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.112 -107.181 22.1 + vertex -104.623 -105.985 22.1 + vertex -104.623 -107.247 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -104.623 -105.985 22.1 + vertex -105.112 -107.181 22.1 + vertex -105.099 -105.865 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.581 -107.029 22.1 + vertex -105.099 -105.865 22.1 + vertex -105.112 -107.181 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -106.015 -106.795 22.1 + vertex -105.099 -105.865 22.1 + vertex -105.581 -107.029 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -105.099 -105.865 22.1 + vertex -106.015 -106.795 22.1 + vertex -105.509 -105.596 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -106.4 -106.488 22.1 + vertex -105.509 -105.596 22.1 + vertex -106.015 -106.795 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -105.509 -105.596 22.1 + vertex -106.725 -106.116 22.1 + vertex -105.81 -105.209 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -106.725 -106.116 22.1 + vertex -105.509 -105.596 22.1 + vertex -106.4 -106.488 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -102.139 -103.09 22.1 + vertex -103.324 -103.585 22.1 + vertex -102.429 -102.691 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -102.429 -102.691 22.1 + vertex -103.324 -103.585 22.1 + vertex -102.785 -102.35 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.685 -103.253 22.1 + vertex -102.785 -102.35 22.1 + vertex -103.324 -103.585 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -102.785 -102.35 22.1 + vertex -103.685 -103.253 22.1 + vertex -103.197 -102.078 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.134 -103.056 22.1 + vertex -103.197 -102.078 22.1 + vertex -103.685 -103.253 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -103.197 -102.078 22.1 + vertex -104.134 -103.056 22.1 + vertex -103.65 -101.885 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -103.65 -101.885 22.1 + vertex -104.134 -103.056 22.1 + vertex -104.131 -101.775 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.623 -103.015 22.1 + vertex -104.131 -101.775 22.1 + vertex -104.134 -103.056 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.623 -103.015 22.1 + vertex -104.623 -101.753 22.1 + vertex -104.131 -101.775 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.112 -101.819 22.1 + vertex -104.623 -103.015 22.1 + vertex -105.099 -103.135 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.623 -103.015 22.1 + vertex -105.112 -101.819 22.1 + vertex -104.623 -101.753 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -106.015 -102.205 22.1 + vertex -105.099 -103.135 22.1 + vertex -105.509 -103.404 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.099 -103.135 22.1 + vertex -105.581 -101.971 22.1 + vertex -105.112 -101.819 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -106.725 -102.884 22.1 + vertex -105.509 -103.404 22.1 + vertex -105.81 -103.791 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -107.151 -103.768 22.1 + vertex -105.81 -103.791 22.1 + vertex -105.97 -104.255 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.099 -103.135 22.1 + vertex -106.015 -102.205 22.1 + vertex -105.581 -101.971 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -106.978 -105.693 22.1 + vertex -105.81 -105.209 22.1 + vertex -106.725 -106.116 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -107.151 -105.232 22.1 + vertex -105.81 -105.209 22.1 + vertex -106.978 -105.693 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.509 -103.404 22.1 + vertex -106.4 -102.512 22.1 + vertex -106.015 -102.205 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -105.81 -105.209 22.1 + vertex -107.151 -105.232 22.1 + vertex -105.97 -104.745 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.509 -103.404 22.1 + vertex -106.725 -102.884 22.1 + vertex -106.4 -102.512 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -107.239 -104.747 22.1 + vertex -105.97 -104.745 22.1 + vertex -107.151 -105.232 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.81 -103.791 22.1 + vertex -106.978 -103.307 22.1 + vertex -106.725 -102.884 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -105.97 -104.745 22.1 + vertex -107.239 -104.747 22.1 + vertex -105.97 -104.255 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.81 -103.791 22.1 + vertex -107.151 -103.768 22.1 + vertex -106.978 -103.307 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -107.239 -104.253 22.1 + vertex -105.97 -104.255 22.1 + vertex -107.239 -104.747 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.97 -104.255 22.1 + vertex -107.239 -104.253 22.1 + vertex -107.151 -103.768 22.1 + endloop + endfacet + facet normal 0.222531 -0.974926 0 + outer loop + vertex -104.131 -107.225 22.1 + vertex -103.65 -107.115 25.08 + vertex -104.131 -107.225 25.08 + endloop + endfacet + facet normal 0.222531 -0.974926 0 + outer loop + vertex -103.65 -107.115 25.08 + vertex -104.131 -107.225 22.1 + vertex -103.65 -107.115 22.1 + endloop + endfacet + facet normal -0.309018 0.951056 0 + outer loop + vertex -105.112 -101.819 22.1 + vertex -105.581 -101.971 25.08 + vertex -105.112 -101.819 25.08 + endloop + endfacet + facet normal -0.309018 0.951056 0 + outer loop + vertex -105.581 -101.971 25.08 + vertex -105.112 -101.819 22.1 + vertex -105.581 -101.971 22.1 + endloop + endfacet + facet normal 0.90097 -0.433881 0 + outer loop + vertex -102.139 -105.91 25.08 + vertex -101.925 -105.466 22.1 + vertex -101.925 -105.466 25.08 + endloop + endfacet + facet normal 0.90097 -0.433881 0 + outer loop + vertex -101.925 -105.466 22.1 + vertex -102.139 -105.91 25.08 + vertex -102.139 -105.91 22.1 + endloop + endfacet + facet normal -0.85845 -0.512897 0 + outer loop + vertex -106.725 -106.116 22.1 + vertex -106.978 -105.693 25.08 + vertex -106.978 -105.693 22.1 + endloop + endfacet + facet normal -0.85845 -0.512897 0 + outer loop + vertex -106.978 -105.693 25.08 + vertex -106.725 -106.116 22.1 + vertex -106.725 -106.116 25.08 + endloop + endfacet + facet normal -0.983928 -0.178565 0 + outer loop + vertex -107.151 -105.232 22.1 + vertex -107.239 -104.747 25.08 + vertex -107.239 -104.747 22.1 + endloop + endfacet + facet normal -0.983928 -0.178565 0 + outer loop + vertex -107.239 -104.747 25.08 + vertex -107.151 -105.232 22.1 + vertex -107.151 -105.232 25.08 + endloop + endfacet + facet normal 0.550891 -0.834577 0 + outer loop + vertex -103.197 -106.922 22.1 + vertex -102.785 -106.65 25.08 + vertex -103.197 -106.922 25.08 + endloop + endfacet + facet normal 0.550891 -0.834577 0 + outer loop + vertex -102.785 -106.65 25.08 + vertex -103.197 -106.922 22.1 + vertex -102.785 -106.65 22.1 + endloop + endfacet + facet normal 0.393015 -0.919532 0 + outer loop + vertex -103.65 -107.115 22.1 + vertex -103.197 -106.922 25.08 + vertex -103.65 -107.115 25.08 + endloop + endfacet + facet normal 0.393015 -0.919532 0 + outer loop + vertex -103.197 -106.922 25.08 + vertex -103.65 -107.115 22.1 + vertex -103.197 -106.922 22.1 + endloop + endfacet + facet normal -0.47387 -0.880595 0 + outer loop + vertex -106.015 -106.795 22.1 + vertex -105.581 -107.029 25.08 + vertex -106.015 -106.795 25.08 + endloop + endfacet + facet normal -0.47387 -0.880595 -0 + outer loop + vertex -105.581 -107.029 25.08 + vertex -106.015 -106.795 22.1 + vertex -105.581 -107.029 22.1 + endloop + endfacet + facet normal -0.309018 -0.951056 0 + outer loop + vertex -105.581 -107.029 22.1 + vertex -105.112 -107.181 25.08 + vertex -105.581 -107.029 25.08 + endloop + endfacet + facet normal -0.309018 -0.951056 -0 + outer loop + vertex -105.112 -107.181 25.08 + vertex -105.581 -107.029 22.1 + vertex -105.112 -107.181 22.1 + endloop + endfacet + facet normal -0.134229 -0.99095 0 + outer loop + vertex -105.112 -107.181 22.1 + vertex -104.623 -107.247 25.08 + vertex -105.112 -107.181 25.08 + endloop + endfacet + facet normal -0.134229 -0.99095 -0 + outer loop + vertex -104.623 -107.247 25.08 + vertex -105.112 -107.181 22.1 + vertex -104.623 -107.247 22.1 + endloop + endfacet + facet normal -0.936235 -0.351374 0 + outer loop + vertex -106.978 -105.693 22.1 + vertex -107.151 -105.232 25.08 + vertex -107.151 -105.232 22.1 + endloop + endfacet + facet normal -0.936235 -0.351374 0 + outer loop + vertex -107.151 -105.232 25.08 + vertex -106.978 -105.693 22.1 + vertex -106.978 -105.693 25.08 + endloop + endfacet + facet normal 0.691067 -0.722791 0 + outer loop + vertex -102.785 -106.65 22.1 + vertex -102.429 -106.309 25.08 + vertex -102.785 -106.65 25.08 + endloop + endfacet + facet normal 0.691067 -0.722791 0 + outer loop + vertex -102.429 -106.309 25.08 + vertex -102.785 -106.65 22.1 + vertex -102.429 -106.309 22.1 + endloop + endfacet + facet normal -0.753075 -0.657935 0 + outer loop + vertex -106.4 -106.488 22.1 + vertex -106.725 -106.116 25.08 + vertex -106.725 -106.116 22.1 + endloop + endfacet + facet normal -0.753075 -0.657935 0 + outer loop + vertex -106.725 -106.116 25.08 + vertex -106.4 -106.488 22.1 + vertex -106.4 -106.488 25.08 + endloop + endfacet + facet normal -0.62349 -0.781831 0 + outer loop + vertex -106.4 -106.488 22.1 + vertex -106.015 -106.795 25.08 + vertex -106.4 -106.488 25.08 + endloop + endfacet + facet normal -0.62349 -0.781831 -0 + outer loop + vertex -106.015 -106.795 25.08 + vertex -106.4 -106.488 22.1 + vertex -106.015 -106.795 22.1 + endloop + endfacet + facet normal 0.986363 0.164583 0 + outer loop + vertex -103.01 -104.5 20.5 + vertex -103.091 -104.016 13.5 + vertex -103.091 -104.016 20.5 + endloop + endfacet + facet normal 0.986363 0.164583 0 + outer loop + vertex -103.091 -104.016 13.5 + vertex -103.01 -104.5 20.5 + vertex -103.01 -104.5 13.5 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -105.97 -104.745 13.5 + vertex -105.97 -104.255 20.5 + vertex -105.97 -104.255 13.5 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex -105.97 -104.255 20.5 + vertex -105.97 -104.745 13.5 + vertex -105.97 -104.745 20.5 + endloop + endfacet + facet normal -0.245484 0.969401 0 + outer loop + vertex -104.623 -103.015 13.5 + vertex -105.099 -103.135 20.5 + vertex -104.623 -103.015 20.5 + endloop + endfacet + facet normal -0.245484 0.969401 0 + outer loop + vertex -105.099 -103.135 20.5 + vertex -104.623 -103.015 13.5 + vertex -105.099 -103.135 13.5 + endloop + endfacet + facet normal 0.0825782 -0.996585 0 + outer loop + vertex -104.623 -105.985 13.5 + vertex -104.134 -105.944 20.5 + vertex -104.623 -105.985 20.5 + endloop + endfacet + facet normal 0.0825782 -0.996585 0 + outer loop + vertex -104.134 -105.944 20.5 + vertex -104.623 -105.985 13.5 + vertex -104.134 -105.944 13.5 + endloop + endfacet + facet normal 0.401702 0.915771 -0 + outer loop + vertex -103.685 -103.253 13.5 + vertex -104.134 -103.056 20.5 + vertex -103.685 -103.253 20.5 + endloop + endfacet + facet normal 0.401702 0.915771 0 + outer loop + vertex -104.134 -103.056 20.5 + vertex -103.685 -103.253 13.5 + vertex -104.134 -103.056 13.5 + endloop + endfacet + facet normal 0.0825782 0.996585 -0 + outer loop + vertex -104.134 -103.056 13.5 + vertex -104.623 -103.015 20.5 + vertex -104.134 -103.056 20.5 + endloop + endfacet + facet normal 0.0825782 0.996585 0 + outer loop + vertex -104.623 -103.015 20.5 + vertex -104.134 -103.056 13.5 + vertex -104.623 -103.015 13.5 + endloop + endfacet + facet normal -0.789139 0.614214 0 + outer loop + vertex -105.81 -103.791 13.5 + vertex -105.509 -103.404 20.5 + vertex -105.509 -103.404 13.5 + endloop + endfacet + facet normal -0.789139 0.614214 0 + outer loop + vertex -105.509 -103.404 20.5 + vertex -105.81 -103.791 13.5 + vertex -105.81 -103.791 20.5 + endloop + endfacet + facet normal -0.945816 0.324703 0 + outer loop + vertex -105.97 -104.255 13.5 + vertex -105.81 -103.791 20.5 + vertex -105.81 -103.791 13.5 + endloop + endfacet + facet normal -0.945816 0.324703 0 + outer loop + vertex -105.81 -103.791 20.5 + vertex -105.97 -104.255 13.5 + vertex -105.97 -104.255 20.5 + endloop + endfacet + facet normal -0.546948 0.837167 0 + outer loop + vertex -105.099 -103.135 13.5 + vertex -105.509 -103.404 20.5 + vertex -105.099 -103.135 20.5 + endloop + endfacet + facet normal -0.546948 0.837167 0 + outer loop + vertex -105.509 -103.404 20.5 + vertex -105.099 -103.135 13.5 + vertex -105.509 -103.404 13.5 + endloop + endfacet + facet normal -0.245484 -0.969401 0 + outer loop + vertex -105.099 -105.865 13.5 + vertex -104.623 -105.985 20.5 + vertex -105.099 -105.865 20.5 + endloop + endfacet + facet normal -0.245484 -0.969401 -0 + outer loop + vertex -104.623 -105.985 20.5 + vertex -105.099 -105.865 13.5 + vertex -104.623 -105.985 13.5 + endloop + endfacet + facet normal 0.677276 0.735729 -0 + outer loop + vertex -103.324 -103.585 13.5 + vertex -103.685 -103.253 20.5 + vertex -103.324 -103.585 20.5 + endloop + endfacet + facet normal 0.677276 0.735729 0 + outer loop + vertex -103.685 -103.253 20.5 + vertex -103.324 -103.585 13.5 + vertex -103.685 -103.253 13.5 + endloop + endfacet + facet normal 0.87947 0.475954 0 + outer loop + vertex -103.091 -104.016 20.5 + vertex -103.324 -103.585 13.5 + vertex -103.324 -103.585 20.5 + endloop + endfacet + facet normal 0.87947 0.475954 0 + outer loop + vertex -103.324 -103.585 13.5 + vertex -103.091 -104.016 20.5 + vertex -103.091 -104.016 13.5 + endloop + endfacet + facet normal 0.401702 -0.915771 0 + outer loop + vertex -104.134 -105.944 13.5 + vertex -103.685 -105.747 20.5 + vertex -104.134 -105.944 20.5 + endloop + endfacet + facet normal 0.401702 -0.915771 0 + outer loop + vertex -103.685 -105.747 20.5 + vertex -104.134 -105.944 13.5 + vertex -103.685 -105.747 13.5 + endloop + endfacet + facet normal 0.986363 -0.164583 0 + outer loop + vertex -103.091 -104.984 20.5 + vertex -103.01 -104.5 13.5 + vertex -103.01 -104.5 20.5 + endloop + endfacet + facet normal 0.986363 -0.164583 0 + outer loop + vertex -103.01 -104.5 13.5 + vertex -103.091 -104.984 20.5 + vertex -103.091 -104.984 13.5 + endloop + endfacet + facet normal -0.546948 -0.837167 0 + outer loop + vertex -105.509 -105.596 13.5 + vertex -105.099 -105.865 20.5 + vertex -105.509 -105.596 20.5 + endloop + endfacet + facet normal -0.546948 -0.837167 -0 + outer loop + vertex -105.099 -105.865 20.5 + vertex -105.509 -105.596 13.5 + vertex -105.099 -105.865 13.5 + endloop + endfacet + facet normal -0.945816 -0.324703 0 + outer loop + vertex -105.81 -105.209 13.5 + vertex -105.97 -104.745 20.5 + vertex -105.97 -104.745 13.5 + endloop + endfacet + facet normal -0.945816 -0.324703 0 + outer loop + vertex -105.97 -104.745 20.5 + vertex -105.81 -105.209 13.5 + vertex -105.81 -105.209 20.5 + endloop + endfacet + facet normal 0.677276 -0.735729 0 + outer loop + vertex -103.685 -105.747 13.5 + vertex -103.324 -105.415 20.5 + vertex -103.685 -105.747 20.5 + endloop + endfacet + facet normal 0.677276 -0.735729 0 + outer loop + vertex -103.324 -105.415 20.5 + vertex -103.685 -105.747 13.5 + vertex -103.324 -105.415 13.5 + endloop + endfacet + facet normal -0.789139 -0.614214 0 + outer loop + vertex -105.509 -105.596 13.5 + vertex -105.81 -105.209 20.5 + vertex -105.81 -105.209 13.5 + endloop + endfacet + facet normal -0.789139 -0.614214 0 + outer loop + vertex -105.81 -105.209 20.5 + vertex -105.509 -105.596 13.5 + vertex -105.509 -105.596 20.5 + endloop + endfacet + facet normal 0.87947 -0.475954 0 + outer loop + vertex -103.324 -105.415 20.5 + vertex -103.091 -104.984 13.5 + vertex -103.091 -104.984 20.5 + endloop + endfacet + facet normal 0.87947 -0.475954 0 + outer loop + vertex -103.091 -104.984 13.5 + vertex -103.324 -105.415 20.5 + vertex -103.324 -105.415 13.5 + endloop + endfacet + facet normal -0.866026 -0.5 0 + outer loop + vertex -103.057 -104.5 24.0867 + vertex -103.778 -103.25 25.08 + vertex -103.778 -103.25 24.0867 + endloop + endfacet + facet normal -0.866026 -0.5 0 + outer loop + vertex -103.778 -103.25 25.08 + vertex -103.057 -104.5 24.0867 + vertex -103.057 -104.5 25.08 + endloop + endfacet + facet normal 0.866026 -0.5 0 + outer loop + vertex -105.943 -104.5 25.08 + vertex -105.222 -103.25 24.0867 + vertex -105.222 -103.25 25.08 + endloop + endfacet + facet normal 0.866026 -0.5 0 + outer loop + vertex -105.222 -103.25 24.0867 + vertex -105.943 -104.5 25.08 + vertex -105.943 -104.5 24.0867 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -105.222 -103.25 24.0867 + vertex -103.778 -103.25 25.08 + vertex -105.222 -103.25 25.08 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -103.778 -103.25 25.08 + vertex -105.222 -103.25 24.0867 + vertex -103.778 -103.25 24.0867 + endloop + endfacet + facet normal -0.866026 0.5 0 + outer loop + vertex -103.778 -105.75 24.0867 + vertex -103.057 -104.5 25.08 + vertex -103.057 -104.5 24.0867 + endloop + endfacet + facet normal -0.866026 0.5 0 + outer loop + vertex -103.057 -104.5 25.08 + vertex -103.778 -105.75 24.0867 + vertex -103.778 -105.75 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.778 -103.25 24.0867 + vertex -103.778 -105.75 24.0867 + vertex -103.057 -104.5 24.0867 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -105.222 -103.25 24.0867 + vertex -103.778 -105.75 24.0867 + vertex -103.778 -103.25 24.0867 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.222 -103.25 24.0867 + vertex -105.222 -105.75 24.0867 + vertex -103.778 -105.75 24.0867 + endloop + endfacet + facet normal 0 -0 1 + outer loop + vertex -105.222 -105.75 24.0867 + vertex -105.222 -103.25 24.0867 + vertex -105.943 -104.5 24.0867 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -103.778 -105.75 24.0867 + vertex -105.222 -105.75 25.08 + vertex -103.778 -105.75 25.08 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -105.222 -105.75 25.08 + vertex -103.778 -105.75 24.0867 + vertex -105.222 -105.75 24.0867 + endloop + endfacet + facet normal 0.866026 0.5 0 + outer loop + vertex -105.222 -105.75 25.08 + vertex -105.943 -104.5 24.0867 + vertex -105.943 -104.5 25.08 + endloop + endfacet + facet normal 0.866026 0.5 0 + outer loop + vertex -105.943 -104.5 24.0867 + vertex -105.222 -105.75 25.08 + vertex -105.222 -105.75 24.0867 + endloop + endfacet + facet normal 0.866025 0.5 0 + outer loop + vertex -101.75 104.5 20.5 + vertex -103.125 106.882 0.5 + vertex -103.125 106.882 20.5 + endloop + endfacet + facet normal 0.866025 0.5 0 + outer loop + vertex -103.125 106.882 0.5 + vertex -101.75 104.5 20.5 + vertex -101.75 104.5 0.5 + endloop + endfacet + facet normal -0.866025 0.5 0 + outer loop + vertex -105.875 106.882 0.5 + vertex -107 104.933 20.5 + vertex -105.875 106.882 20.5 + endloop + endfacet + facet normal -0.866025 0.5 -3.46791e-008 + outer loop + vertex -107.25 104.5 0.5 + vertex -107 104.933 20.5 + vertex -105.875 106.882 0.5 + endloop + endfacet + facet normal -0.866026 0.499999 0 + outer loop + vertex -107 104.933 20.5 + vertex -107.25 104.5 0.5 + vertex -107.25 104.5 20.5 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -103.125 106.882 0.5 + vertex -105.875 106.882 20.5 + vertex -103.125 106.882 20.5 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -105.875 106.882 20.5 + vertex -103.125 106.882 0.5 + vertex -105.875 106.882 0.5 + endloop + endfacet + facet normal 0.866025 -0.5 0 + outer loop + vertex -103.125 102.118 20.5 + vertex -101.75 104.5 0.5 + vertex -101.75 104.5 20.5 + endloop + endfacet + facet normal 0.866025 -0.5 0 + outer loop + vertex -101.75 104.5 0.5 + vertex -103.125 102.118 20.5 + vertex -103.125 102.118 0.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -101.75 104.5 0.5 + vertex -103.081 104.013 0.5 + vertex -103 104.5 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.316 103.579 0.5 + vertex -101.75 104.5 0.5 + vertex -103.125 102.118 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -101.75 104.5 0.5 + vertex -103.316 103.579 0.5 + vertex -103.081 104.013 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.125 102.118 0.5 + vertex -103.68 103.244 0.5 + vertex -103.316 103.579 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.125 102.118 0.5 + vertex -104.132 103.046 0.5 + vertex -103.68 103.244 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.125 102.118 0.5 + vertex -104.624 103.005 0.5 + vertex -104.132 103.046 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.875 102.118 0.5 + vertex -104.624 103.005 0.5 + vertex -103.125 102.118 0.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -104.624 103.005 0.5 + vertex -105.875 102.118 0.5 + vertex -105.103 103.126 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.875 102.118 0.5 + vertex -105.516 103.396 0.5 + vertex -105.103 103.126 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.875 102.118 0.5 + vertex -105.819 103.786 0.5 + vertex -105.516 103.396 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -107.25 104.5 0.5 + vertex -105.819 103.786 0.5 + vertex -105.875 102.118 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.98 104.253 0.5 + vertex -107.25 104.5 0.5 + vertex -105.98 104.747 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.819 103.786 0.5 + vertex -107.25 104.5 0.5 + vertex -105.98 104.253 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.081 104.987 0.5 + vertex -101.75 104.5 0.5 + vertex -103 104.5 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.316 105.421 0.5 + vertex -101.75 104.5 0.5 + vertex -103.081 104.987 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -101.75 104.5 0.5 + vertex -103.316 105.421 0.5 + vertex -103.125 106.882 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.68 105.756 0.5 + vertex -103.125 106.882 0.5 + vertex -103.316 105.421 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.132 105.954 0.5 + vertex -103.125 106.882 0.5 + vertex -103.68 105.756 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.624 105.995 0.5 + vertex -103.125 106.882 0.5 + vertex -104.132 105.954 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.875 106.882 0.5 + vertex -104.624 105.995 0.5 + vertex -105.103 105.874 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.624 105.995 0.5 + vertex -105.875 106.882 0.5 + vertex -103.125 106.882 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.516 105.604 0.5 + vertex -105.875 106.882 0.5 + vertex -105.103 105.874 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.819 105.214 0.5 + vertex -105.875 106.882 0.5 + vertex -105.516 105.604 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -107.25 104.5 0.5 + vertex -105.819 105.214 0.5 + vertex -105.98 104.747 0.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -105.819 105.214 0.5 + vertex -107.25 104.5 0.5 + vertex -105.875 106.882 0.5 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -105.875 102.118 0.5 + vertex -103.125 102.118 20.5 + vertex -105.875 102.118 20.5 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -103.125 102.118 20.5 + vertex -105.875 102.118 0.5 + vertex -103.125 102.118 0.5 + endloop + endfacet + facet normal -0.866026 -0.499999 0 + outer loop + vertex -107.25 104.5 0.5 + vertex -107 104.067 20.5 + vertex -107.25 104.5 20.5 + endloop + endfacet + facet normal -0.866025 -0.5 -3.46791e-008 + outer loop + vertex -105.875 102.118 0.5 + vertex -107 104.067 20.5 + vertex -107.25 104.5 0.5 + endloop + endfacet + facet normal -0.866025 -0.5 0 + outer loop + vertex -107 104.067 20.5 + vertex -105.875 102.118 0.5 + vertex -105.875 102.118 20.5 + endloop + endfacet + facet normal 0.98636 0.164599 0 + outer loop + vertex -103 104.5 0.5 + vertex -103.081 104.987 -6.5 + vertex -103.081 104.987 0.5 + endloop + endfacet + facet normal 0.98636 0.164599 0 + outer loop + vertex -103.081 104.987 -6.5 + vertex -103 104.5 0.5 + vertex -103 104.5 -6.5 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -105.98 104.253 -6.5 + vertex -105.98 104.747 0.5 + vertex -105.98 104.747 -6.5 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex -105.98 104.747 0.5 + vertex -105.98 104.253 -6.5 + vertex -105.98 104.253 0.5 + endloop + endfacet + facet normal 0.0825698 0.996585 -0 + outer loop + vertex -104.132 105.954 -6.5 + vertex -104.624 105.995 0.5 + vertex -104.132 105.954 0.5 + endloop + endfacet + facet normal 0.0825698 0.996585 0 + outer loop + vertex -104.624 105.995 0.5 + vertex -104.132 105.954 -6.5 + vertex -104.624 105.995 -6.5 + endloop + endfacet + facet normal 0.0825698 -0.996585 0 + outer loop + vertex -104.624 103.005 -6.5 + vertex -104.132 103.046 0.5 + vertex -104.624 103.005 0.5 + endloop + endfacet + facet normal 0.0825698 -0.996585 0 + outer loop + vertex -104.132 103.046 0.5 + vertex -104.624 103.005 -6.5 + vertex -104.132 103.046 -6.5 + endloop + endfacet + facet normal 0.401692 -0.915775 0 + outer loop + vertex -104.132 103.046 -6.5 + vertex -103.68 103.244 0.5 + vertex -104.132 103.046 0.5 + endloop + endfacet + facet normal 0.401692 -0.915775 0 + outer loop + vertex -103.68 103.244 0.5 + vertex -104.132 103.046 -6.5 + vertex -103.68 103.244 -6.5 + endloop + endfacet + facet normal 0.677285 0.73572 -0 + outer loop + vertex -103.316 105.421 -6.5 + vertex -103.68 105.756 0.5 + vertex -103.316 105.421 0.5 + endloop + endfacet + facet normal 0.677285 0.73572 0 + outer loop + vertex -103.68 105.756 0.5 + vertex -103.316 105.421 -6.5 + vertex -103.68 105.756 -6.5 + endloop + endfacet + facet normal 0.879474 0.475946 0 + outer loop + vertex -103.081 104.987 0.5 + vertex -103.316 105.421 -6.5 + vertex -103.316 105.421 0.5 + endloop + endfacet + facet normal 0.879474 0.475946 0 + outer loop + vertex -103.316 105.421 -6.5 + vertex -103.081 104.987 0.5 + vertex -103.081 104.987 -6.5 + endloop + endfacet + facet normal 0.401692 0.915775 -0 + outer loop + vertex -103.68 105.756 -6.5 + vertex -104.132 105.954 0.5 + vertex -103.68 105.756 0.5 + endloop + endfacet + facet normal 0.401692 0.915775 0 + outer loop + vertex -104.132 105.954 0.5 + vertex -103.68 105.756 -6.5 + vertex -104.132 105.954 -6.5 + endloop + endfacet + facet normal -0.789137 0.614218 0 + outer loop + vertex -105.819 105.214 -6.5 + vertex -105.516 105.604 0.5 + vertex -105.516 105.604 -6.5 + endloop + endfacet + facet normal -0.789137 0.614218 0 + outer loop + vertex -105.516 105.604 0.5 + vertex -105.819 105.214 -6.5 + vertex -105.819 105.214 0.5 + endloop + endfacet + facet normal -0.945823 0.324684 0 + outer loop + vertex -105.98 104.747 -6.5 + vertex -105.819 105.214 0.5 + vertex -105.819 105.214 -6.5 + endloop + endfacet + facet normal -0.945823 0.324684 0 + outer loop + vertex -105.819 105.214 0.5 + vertex -105.98 104.747 -6.5 + vertex -105.98 104.747 0.5 + endloop + endfacet + facet normal -0.245487 0.9694 0 + outer loop + vertex -104.624 105.995 -6.5 + vertex -105.103 105.874 0.5 + vertex -104.624 105.995 0.5 + endloop + endfacet + facet normal -0.245487 0.9694 0 + outer loop + vertex -105.103 105.874 0.5 + vertex -104.624 105.995 -6.5 + vertex -105.103 105.874 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.081 104.013 -6.5 + vertex -103.081 104.987 -6.5 + vertex -103 104.5 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.316 103.579 -6.5 + vertex -103.081 104.987 -6.5 + vertex -103.081 104.013 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.316 103.579 -6.5 + vertex -103.316 105.421 -6.5 + vertex -103.081 104.987 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.68 103.244 -6.5 + vertex -103.316 105.421 -6.5 + vertex -103.316 103.579 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.68 103.244 -6.5 + vertex -103.68 105.756 -6.5 + vertex -103.316 105.421 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.132 103.046 -6.5 + vertex -103.68 105.756 -6.5 + vertex -103.68 103.244 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.132 103.046 -6.5 + vertex -104.132 105.954 -6.5 + vertex -103.68 105.756 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.624 103.005 -6.5 + vertex -104.132 105.954 -6.5 + vertex -104.132 103.046 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.624 103.005 -6.5 + vertex -104.624 105.995 -6.5 + vertex -104.132 105.954 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.103 103.126 -6.5 + vertex -104.624 105.995 -6.5 + vertex -104.624 103.005 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.103 103.126 -6.5 + vertex -105.103 105.874 -6.5 + vertex -104.624 105.995 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.516 103.396 -6.5 + vertex -105.103 105.874 -6.5 + vertex -105.103 103.126 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.516 103.396 -6.5 + vertex -105.516 105.604 -6.5 + vertex -105.103 105.874 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.819 103.786 -6.5 + vertex -105.516 105.604 -6.5 + vertex -105.516 103.396 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.819 103.786 -6.5 + vertex -105.819 105.214 -6.5 + vertex -105.516 105.604 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.98 104.253 -6.5 + vertex -105.819 105.214 -6.5 + vertex -105.819 103.786 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.819 105.214 -6.5 + vertex -105.98 104.253 -6.5 + vertex -105.98 104.747 -6.5 + endloop + endfacet + facet normal -0.546943 0.83717 0 + outer loop + vertex -105.103 105.874 -6.5 + vertex -105.516 105.604 0.5 + vertex -105.103 105.874 0.5 + endloop + endfacet + facet normal -0.546943 0.83717 0 + outer loop + vertex -105.516 105.604 0.5 + vertex -105.103 105.874 -6.5 + vertex -105.516 105.604 -6.5 + endloop + endfacet + facet normal 0.98636 -0.164599 0 + outer loop + vertex -103.081 104.013 0.5 + vertex -103 104.5 -6.5 + vertex -103 104.5 0.5 + endloop + endfacet + facet normal 0.98636 -0.164599 0 + outer loop + vertex -103 104.5 -6.5 + vertex -103.081 104.013 0.5 + vertex -103.081 104.013 -6.5 + endloop + endfacet + facet normal 0.677285 -0.73572 0 + outer loop + vertex -103.68 103.244 -6.5 + vertex -103.316 103.579 0.5 + vertex -103.68 103.244 0.5 + endloop + endfacet + facet normal 0.677285 -0.73572 0 + outer loop + vertex -103.316 103.579 0.5 + vertex -103.68 103.244 -6.5 + vertex -103.316 103.579 -6.5 + endloop + endfacet + facet normal 0.879474 -0.475946 0 + outer loop + vertex -103.316 103.579 0.5 + vertex -103.081 104.013 -6.5 + vertex -103.081 104.013 0.5 + endloop + endfacet + facet normal 0.879474 -0.475946 0 + outer loop + vertex -103.081 104.013 -6.5 + vertex -103.316 103.579 0.5 + vertex -103.316 103.579 -6.5 + endloop + endfacet + facet normal -0.245487 -0.9694 0 + outer loop + vertex -105.103 103.126 -6.5 + vertex -104.624 103.005 0.5 + vertex -105.103 103.126 0.5 + endloop + endfacet + facet normal -0.245487 -0.9694 -0 + outer loop + vertex -104.624 103.005 0.5 + vertex -105.103 103.126 -6.5 + vertex -104.624 103.005 -6.5 + endloop + endfacet + facet normal -0.789137 -0.614218 0 + outer loop + vertex -105.516 103.396 -6.5 + vertex -105.819 103.786 0.5 + vertex -105.819 103.786 -6.5 + endloop + endfacet + facet normal -0.789137 -0.614218 0 + outer loop + vertex -105.819 103.786 0.5 + vertex -105.516 103.396 -6.5 + vertex -105.516 103.396 0.5 + endloop + endfacet + facet normal -0.945823 -0.324684 0 + outer loop + vertex -105.819 103.786 -6.5 + vertex -105.98 104.253 0.5 + vertex -105.98 104.253 -6.5 + endloop + endfacet + facet normal -0.945823 -0.324684 0 + outer loop + vertex -105.98 104.253 0.5 + vertex -105.819 103.786 -6.5 + vertex -105.819 103.786 0.5 + endloop + endfacet + facet normal -0.546943 -0.83717 0 + outer loop + vertex -105.516 103.396 -6.5 + vertex -105.103 103.126 0.5 + vertex -105.516 103.396 0.5 + endloop + endfacet + facet normal -0.546943 -0.83717 -0 + outer loop + vertex -105.103 103.126 0.5 + vertex -105.516 103.396 -6.5 + vertex -105.103 103.126 -6.5 + endloop + endfacet + facet normal -0.98636 -0.164599 0 + outer loop + vertex -103 104.5 13.5 + vertex -103.081 104.987 20.5 + vertex -103.081 104.987 13.5 + endloop + endfacet + facet normal -0.98636 -0.164599 0 + outer loop + vertex -103.081 104.987 20.5 + vertex -103 104.5 13.5 + vertex -103 104.5 20.5 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex -105.98 104.253 20.5 + vertex -105.98 104.747 13.5 + vertex -105.98 104.747 20.5 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex -105.98 104.747 13.5 + vertex -105.98 104.253 20.5 + vertex -105.98 104.253 13.5 + endloop + endfacet + facet normal -0.0825698 -0.996585 0 + outer loop + vertex -104.624 105.995 13.5 + vertex -104.132 105.954 20.5 + vertex -104.624 105.995 20.5 + endloop + endfacet + facet normal -0.0825698 -0.996585 -0 + outer loop + vertex -104.132 105.954 20.5 + vertex -104.624 105.995 13.5 + vertex -104.132 105.954 13.5 + endloop + endfacet + facet normal -0.0825698 0.996585 0 + outer loop + vertex -104.132 103.046 13.5 + vertex -104.624 103.005 20.5 + vertex -104.132 103.046 20.5 + endloop + endfacet + facet normal -0.0825698 0.996585 0 + outer loop + vertex -104.624 103.005 20.5 + vertex -104.132 103.046 13.5 + vertex -104.624 103.005 13.5 + endloop + endfacet + facet normal -0.401692 0.915775 0 + outer loop + vertex -103.68 103.244 13.5 + vertex -104.132 103.046 20.5 + vertex -103.68 103.244 20.5 + endloop + endfacet + facet normal -0.401692 0.915775 0 + outer loop + vertex -104.132 103.046 20.5 + vertex -103.68 103.244 13.5 + vertex -104.132 103.046 13.5 + endloop + endfacet + facet normal -0.677285 -0.73572 0 + outer loop + vertex -103.68 105.756 13.5 + vertex -103.316 105.421 20.5 + vertex -103.68 105.756 20.5 + endloop + endfacet + facet normal -0.677285 -0.73572 -0 + outer loop + vertex -103.316 105.421 20.5 + vertex -103.68 105.756 13.5 + vertex -103.316 105.421 13.5 + endloop + endfacet + facet normal -0.879474 -0.475946 0 + outer loop + vertex -103.081 104.987 13.5 + vertex -103.316 105.421 20.5 + vertex -103.316 105.421 13.5 + endloop + endfacet + facet normal -0.879474 -0.475946 0 + outer loop + vertex -103.316 105.421 20.5 + vertex -103.081 104.987 13.5 + vertex -103.081 104.987 20.5 + endloop + endfacet + facet normal -0.401692 -0.915775 0 + outer loop + vertex -104.132 105.954 13.5 + vertex -103.68 105.756 20.5 + vertex -104.132 105.954 20.5 + endloop + endfacet + facet normal -0.401692 -0.915775 -0 + outer loop + vertex -103.68 105.756 20.5 + vertex -104.132 105.954 13.5 + vertex -103.68 105.756 13.5 + endloop + endfacet + facet normal 0.789137 -0.614218 0 + outer loop + vertex -105.819 105.214 20.5 + vertex -105.516 105.604 13.5 + vertex -105.516 105.604 20.5 + endloop + endfacet + facet normal 0.789137 -0.614218 0 + outer loop + vertex -105.516 105.604 13.5 + vertex -105.819 105.214 20.5 + vertex -105.819 105.214 13.5 + endloop + endfacet + facet normal 0.945823 -0.324684 0 + outer loop + vertex -105.98 104.747 20.5 + vertex -105.819 105.214 13.5 + vertex -105.819 105.214 20.5 + endloop + endfacet + facet normal 0.945823 -0.324684 0 + outer loop + vertex -105.819 105.214 13.5 + vertex -105.98 104.747 20.5 + vertex -105.98 104.747 13.5 + endloop + endfacet + facet normal 0.245487 -0.9694 0 + outer loop + vertex -105.103 105.874 13.5 + vertex -104.624 105.995 20.5 + vertex -105.103 105.874 20.5 + endloop + endfacet + facet normal 0.245487 -0.9694 0 + outer loop + vertex -104.624 105.995 20.5 + vertex -105.103 105.874 13.5 + vertex -104.624 105.995 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.081 104.987 13.5 + vertex -103.01 104.5 13.5 + vertex -103 104.5 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.081 104.987 13.5 + vertex -103.091 104.984 13.5 + vertex -103.01 104.5 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.316 105.421 13.5 + vertex -103.091 104.984 13.5 + vertex -103.081 104.987 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.316 105.421 13.5 + vertex -103.324 105.415 13.5 + vertex -103.091 104.984 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.68 105.756 13.5 + vertex -103.324 105.415 13.5 + vertex -103.316 105.421 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.68 105.756 13.5 + vertex -103.685 105.747 13.5 + vertex -103.324 105.415 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.132 105.954 13.5 + vertex -103.685 105.747 13.5 + vertex -103.68 105.756 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.132 105.954 13.5 + vertex -104.134 105.944 13.5 + vertex -103.685 105.747 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.132 105.954 13.5 + vertex -104.623 105.985 13.5 + vertex -104.134 105.944 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.624 105.995 13.5 + vertex -104.623 105.985 13.5 + vertex -104.132 105.954 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.624 105.995 13.5 + vertex -105.099 105.865 13.5 + vertex -104.623 105.985 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -105.103 105.874 13.5 + vertex -105.099 105.865 13.5 + vertex -104.624 105.995 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.103 105.874 13.5 + vertex -105.509 105.596 13.5 + vertex -105.099 105.865 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -105.516 105.604 13.5 + vertex -105.509 105.596 13.5 + vertex -105.103 105.874 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.516 105.604 13.5 + vertex -105.81 105.209 13.5 + vertex -105.509 105.596 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -105.819 105.214 13.5 + vertex -105.81 105.209 13.5 + vertex -105.516 105.604 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.819 105.214 13.5 + vertex -105.97 104.745 13.5 + vertex -105.81 105.209 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.97 104.745 13.5 + vertex -105.98 104.747 13.5 + vertex -105.97 104.255 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -105.98 104.747 13.5 + vertex -105.97 104.745 13.5 + vertex -105.819 105.214 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -103.01 104.5 13.5 + vertex -103.081 104.013 13.5 + vertex -103 104.5 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -103.091 104.016 13.5 + vertex -103.081 104.013 13.5 + vertex -103.01 104.5 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.091 104.016 13.5 + vertex -103.316 103.579 13.5 + vertex -103.081 104.013 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -103.324 103.585 13.5 + vertex -103.316 103.579 13.5 + vertex -103.091 104.016 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.324 103.585 13.5 + vertex -103.68 103.244 13.5 + vertex -103.316 103.579 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -103.685 103.253 13.5 + vertex -103.68 103.244 13.5 + vertex -103.324 103.585 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.685 103.253 13.5 + vertex -104.132 103.046 13.5 + vertex -103.68 103.244 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -104.134 103.056 13.5 + vertex -104.132 103.046 13.5 + vertex -103.685 103.253 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.623 103.015 13.5 + vertex -104.132 103.046 13.5 + vertex -104.134 103.056 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -104.623 103.015 13.5 + vertex -104.624 103.005 13.5 + vertex -104.132 103.046 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.099 103.135 13.5 + vertex -104.624 103.005 13.5 + vertex -104.623 103.015 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.099 103.135 13.5 + vertex -105.103 103.126 13.5 + vertex -104.624 103.005 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.509 103.404 13.5 + vertex -105.103 103.126 13.5 + vertex -105.099 103.135 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.509 103.404 13.5 + vertex -105.516 103.396 13.5 + vertex -105.103 103.126 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.81 103.791 13.5 + vertex -105.516 103.396 13.5 + vertex -105.509 103.404 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.81 103.791 13.5 + vertex -105.819 103.786 13.5 + vertex -105.516 103.396 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.97 104.255 13.5 + vertex -105.819 103.786 13.5 + vertex -105.81 103.791 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.97 104.255 13.5 + vertex -105.98 104.253 13.5 + vertex -105.819 103.786 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.98 104.253 13.5 + vertex -105.97 104.255 13.5 + vertex -105.98 104.747 13.5 + endloop + endfacet + facet normal 0.546943 -0.83717 0 + outer loop + vertex -105.516 105.604 13.5 + vertex -105.103 105.874 20.5 + vertex -105.516 105.604 20.5 + endloop + endfacet + facet normal 0.546943 -0.83717 0 + outer loop + vertex -105.103 105.874 20.5 + vertex -105.516 105.604 13.5 + vertex -105.103 105.874 13.5 + endloop + endfacet + facet normal -0.98636 0.164599 0 + outer loop + vertex -103.081 104.013 13.5 + vertex -103 104.5 20.5 + vertex -103 104.5 13.5 + endloop + endfacet + facet normal -0.98636 0.164599 0 + outer loop + vertex -103 104.5 20.5 + vertex -103.081 104.013 13.5 + vertex -103.081 104.013 20.5 + endloop + endfacet + facet normal 0.945823 0.324684 0 + outer loop + vertex -105.819 103.786 20.5 + vertex -105.98 104.253 13.5 + vertex -105.98 104.253 20.5 + endloop + endfacet + facet normal 0.945823 0.324684 0 + outer loop + vertex -105.98 104.253 13.5 + vertex -105.819 103.786 20.5 + vertex -105.819 103.786 13.5 + endloop + endfacet + facet normal -0.677285 0.73572 0 + outer loop + vertex -103.316 103.579 13.5 + vertex -103.68 103.244 20.5 + vertex -103.316 103.579 20.5 + endloop + endfacet + facet normal -0.677285 0.73572 0 + outer loop + vertex -103.68 103.244 20.5 + vertex -103.316 103.579 13.5 + vertex -103.68 103.244 13.5 + endloop + endfacet + facet normal -0.879474 0.475946 0 + outer loop + vertex -103.316 103.579 13.5 + vertex -103.081 104.013 20.5 + vertex -103.081 104.013 13.5 + endloop + endfacet + facet normal -0.879474 0.475946 0 + outer loop + vertex -103.081 104.013 20.5 + vertex -103.316 103.579 13.5 + vertex -103.316 103.579 20.5 + endloop + endfacet + facet normal 0.245487 0.9694 -0 + outer loop + vertex -104.624 103.005 13.5 + vertex -105.103 103.126 20.5 + vertex -104.624 103.005 20.5 + endloop + endfacet + facet normal 0.245487 0.9694 0 + outer loop + vertex -105.103 103.126 20.5 + vertex -104.624 103.005 13.5 + vertex -105.103 103.126 13.5 + endloop + endfacet + facet normal 0.789137 0.614218 0 + outer loop + vertex -105.516 103.396 20.5 + vertex -105.819 103.786 13.5 + vertex -105.819 103.786 20.5 + endloop + endfacet + facet normal 0.789137 0.614218 0 + outer loop + vertex -105.819 103.786 13.5 + vertex -105.516 103.396 20.5 + vertex -105.516 103.396 13.5 + endloop + endfacet + facet normal 0.546943 0.83717 -0 + outer loop + vertex -105.103 103.126 13.5 + vertex -105.516 103.396 20.5 + vertex -105.103 103.126 20.5 + endloop + endfacet + facet normal 0.546943 0.83717 0 + outer loop + vertex -105.516 103.396 20.5 + vertex -105.103 103.126 13.5 + vertex -105.516 103.396 13.5 + endloop + endfacet + facet normal 0.995974 0.0896469 0 + outer loop + vertex -101.75 104.5 25.08 + vertex -101.794 104.991 22.1 + vertex -101.794 104.991 25.08 + endloop + endfacet + facet normal 0.995974 0.0896469 0 + outer loop + vertex -101.794 104.991 22.1 + vertex -101.75 104.5 25.08 + vertex -101.75 104.5 22.1 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -107.239 104.253 22.1 + vertex -107.239 104.747 25.08 + vertex -107.239 104.747 22.1 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex -107.239 104.747 25.08 + vertex -107.239 104.253 22.1 + vertex -107.239 104.253 25.08 + endloop + endfacet + facet normal 0.0448622 0.998993 -0 + outer loop + vertex -104.131 107.225 22.1 + vertex -104.623 107.247 25.08 + vertex -104.131 107.225 25.08 + endloop + endfacet + facet normal 0.0448622 0.998993 0 + outer loop + vertex -104.623 107.247 25.08 + vertex -104.131 107.225 22.1 + vertex -104.623 107.247 22.1 + endloop + endfacet + facet normal 0.0448622 -0.998993 0 + outer loop + vertex -104.623 101.753 22.1 + vertex -104.131 101.775 25.08 + vertex -104.623 101.753 25.08 + endloop + endfacet + facet normal 0.0448622 -0.998993 0 + outer loop + vertex -104.131 101.775 25.08 + vertex -104.623 101.753 22.1 + vertex -104.131 101.775 22.1 + endloop + endfacet + facet normal 0.809016 -0.587786 0 + outer loop + vertex -102.429 102.691 25.08 + vertex -102.139 103.09 22.1 + vertex -102.139 103.09 25.08 + endloop + endfacet + facet normal 0.809016 -0.587786 0 + outer loop + vertex -102.139 103.09 22.1 + vertex -102.429 102.691 25.08 + vertex -102.429 102.691 22.1 + endloop + endfacet + facet normal 0.691067 0.722791 -0 + outer loop + vertex -102.429 106.309 22.1 + vertex -102.785 106.65 25.08 + vertex -102.429 106.309 25.08 + endloop + endfacet + facet normal 0.691067 0.722791 0 + outer loop + vertex -102.785 106.65 25.08 + vertex -102.429 106.309 22.1 + vertex -102.785 106.65 22.1 + endloop + endfacet + facet normal -0.753075 0.657935 0 + outer loop + vertex -106.725 106.116 22.1 + vertex -106.4 106.488 25.08 + vertex -106.4 106.488 22.1 + endloop + endfacet + facet normal -0.753075 0.657935 0 + outer loop + vertex -106.4 106.488 25.08 + vertex -106.725 106.116 22.1 + vertex -106.725 106.116 25.08 + endloop + endfacet + facet normal -0.47387 0.880595 0 + outer loop + vertex -105.581 107.029 22.1 + vertex -106.015 106.795 25.08 + vertex -105.581 107.029 25.08 + endloop + endfacet + facet normal -0.47387 0.880595 0 + outer loop + vertex -106.015 106.795 25.08 + vertex -105.581 107.029 22.1 + vertex -106.015 106.795 22.1 + endloop + endfacet + facet normal 0.963965 -0.26603 0 + outer loop + vertex -101.925 103.534 25.08 + vertex -101.794 104.009 22.1 + vertex -101.794 104.009 25.08 + endloop + endfacet + facet normal 0.963965 -0.26603 0 + outer loop + vertex -101.794 104.009 22.1 + vertex -101.925 103.534 25.08 + vertex -101.925 103.534 22.1 + endloop + endfacet + facet normal 0.90097 0.433881 0 + outer loop + vertex -101.925 105.466 25.08 + vertex -102.139 105.91 22.1 + vertex -102.139 105.91 25.08 + endloop + endfacet + facet normal 0.90097 0.433881 0 + outer loop + vertex -102.139 105.91 22.1 + vertex -101.925 105.466 25.08 + vertex -101.925 105.466 22.1 + endloop + endfacet + facet normal 0.963965 0.26603 0 + outer loop + vertex -101.794 104.991 25.08 + vertex -101.925 105.466 22.1 + vertex -101.925 105.466 25.08 + endloop + endfacet + facet normal 0.963965 0.26603 0 + outer loop + vertex -101.925 105.466 22.1 + vertex -101.794 104.991 25.08 + vertex -101.794 104.991 22.1 + endloop + endfacet + facet normal 0.809016 0.587786 0 + outer loop + vertex -102.139 105.91 25.08 + vertex -102.429 106.309 22.1 + vertex -102.429 106.309 25.08 + endloop + endfacet + facet normal 0.809016 0.587786 0 + outer loop + vertex -102.429 106.309 22.1 + vertex -102.139 105.91 25.08 + vertex -102.139 105.91 22.1 + endloop + endfacet + facet normal 0.393015 0.919532 -0 + outer loop + vertex -103.197 106.922 22.1 + vertex -103.65 107.115 25.08 + vertex -103.197 106.922 25.08 + endloop + endfacet + facet normal 0.393015 0.919532 0 + outer loop + vertex -103.65 107.115 25.08 + vertex -103.197 106.922 22.1 + vertex -103.65 107.115 22.1 + endloop + endfacet + facet normal 0.222531 0.974926 -0 + outer loop + vertex -103.65 107.115 22.1 + vertex -104.131 107.225 25.08 + vertex -103.65 107.115 25.08 + endloop + endfacet + facet normal 0.222531 0.974926 0 + outer loop + vertex -104.131 107.225 25.08 + vertex -103.65 107.115 22.1 + vertex -104.131 107.225 22.1 + endloop + endfacet + facet normal 0.550891 0.834577 -0 + outer loop + vertex -102.785 106.65 22.1 + vertex -103.197 106.922 25.08 + vertex -102.785 106.65 25.08 + endloop + endfacet + facet normal 0.550891 0.834577 0 + outer loop + vertex -103.197 106.922 25.08 + vertex -102.785 106.65 22.1 + vertex -103.197 106.922 22.1 + endloop + endfacet + facet normal -0.936235 0.351374 0 + outer loop + vertex -107.151 105.232 22.1 + vertex -106.978 105.693 25.08 + vertex -106.978 105.693 22.1 + endloop + endfacet + facet normal -0.936235 0.351374 0 + outer loop + vertex -106.978 105.693 25.08 + vertex -107.151 105.232 22.1 + vertex -107.151 105.232 25.08 + endloop + endfacet + facet normal -0.85845 0.512897 0 + outer loop + vertex -106.978 105.693 22.1 + vertex -106.725 106.116 25.08 + vertex -106.725 106.116 22.1 + endloop + endfacet + facet normal -0.85845 0.512897 0 + outer loop + vertex -106.725 106.116 25.08 + vertex -106.978 105.693 22.1 + vertex -106.978 105.693 25.08 + endloop + endfacet + facet normal -0.983928 0.178565 0 + outer loop + vertex -107.239 104.747 22.1 + vertex -107.151 105.232 25.08 + vertex -107.151 105.232 22.1 + endloop + endfacet + facet normal -0.983928 0.178565 0 + outer loop + vertex -107.151 105.232 25.08 + vertex -107.239 104.747 22.1 + vertex -107.239 104.747 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.057 104.5 25.08 + vertex -101.75 104.5 25.08 + vertex -101.794 104.991 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.057 104.5 25.08 + vertex -101.794 104.991 25.08 + vertex -101.925 105.466 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -101.75 104.5 25.08 + vertex -103.057 104.5 25.08 + vertex -101.794 104.009 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.057 104.5 25.08 + vertex -101.925 105.466 25.08 + vertex -102.139 105.91 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -101.794 104.009 25.08 + vertex -103.057 104.5 25.08 + vertex -101.925 103.534 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.778 105.75 25.08 + vertex -102.139 105.91 25.08 + vertex -102.429 106.309 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -101.925 103.534 25.08 + vertex -103.057 104.5 25.08 + vertex -102.139 103.09 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.778 105.75 25.08 + vertex -102.429 106.309 25.08 + vertex -102.785 106.65 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -103.778 103.25 25.08 + vertex -102.139 103.09 25.08 + vertex -103.057 104.5 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -102.139 103.09 25.08 + vertex -103.778 103.25 25.08 + vertex -102.429 102.691 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.778 105.75 25.08 + vertex -102.785 106.65 25.08 + vertex -103.197 106.922 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.778 105.75 25.08 + vertex -103.197 106.922 25.08 + vertex -103.65 107.115 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -102.139 105.91 25.08 + vertex -103.778 105.75 25.08 + vertex -103.057 104.5 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.131 107.225 25.08 + vertex -103.778 105.75 25.08 + vertex -103.65 107.115 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.623 107.247 25.08 + vertex -103.778 105.75 25.08 + vertex -104.131 107.225 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.222 105.75 25.08 + vertex -104.623 107.247 25.08 + vertex -105.112 107.181 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.623 107.247 25.08 + vertex -105.222 105.75 25.08 + vertex -103.778 105.75 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -105.581 107.029 25.08 + vertex -105.222 105.75 25.08 + vertex -105.112 107.181 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -106.015 106.795 25.08 + vertex -105.222 105.75 25.08 + vertex -105.581 107.029 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -106.4 106.488 25.08 + vertex -105.222 105.75 25.08 + vertex -106.015 106.795 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -102.429 102.691 25.08 + vertex -103.778 103.25 25.08 + vertex -102.785 102.35 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -102.785 102.35 25.08 + vertex -103.778 103.25 25.08 + vertex -103.197 102.078 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.197 102.078 25.08 + vertex -103.778 103.25 25.08 + vertex -103.65 101.885 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.778 103.25 25.08 + vertex -104.131 101.775 25.08 + vertex -103.65 101.885 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.778 103.25 25.08 + vertex -104.623 101.753 25.08 + vertex -104.131 101.775 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -105.222 103.25 25.08 + vertex -104.623 101.753 25.08 + vertex -103.778 103.25 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.623 101.753 25.08 + vertex -105.222 103.25 25.08 + vertex -105.112 101.819 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.222 103.25 25.08 + vertex -105.581 101.971 25.08 + vertex -105.112 101.819 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -106.978 103.307 25.08 + vertex -105.222 103.25 25.08 + vertex -105.943 104.5 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.222 103.25 25.08 + vertex -106.015 102.205 25.08 + vertex -105.581 101.971 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -106.725 106.116 25.08 + vertex -105.222 105.75 25.08 + vertex -106.4 106.488 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -106.978 105.693 25.08 + vertex -105.222 105.75 25.08 + vertex -106.725 106.116 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.222 103.25 25.08 + vertex -106.4 102.512 25.08 + vertex -106.015 102.205 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.222 105.75 25.08 + vertex -106.978 105.693 25.08 + vertex -105.943 104.5 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.222 103.25 25.08 + vertex -106.725 102.884 25.08 + vertex -106.4 102.512 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -107.151 105.232 25.08 + vertex -105.943 104.5 25.08 + vertex -106.978 105.693 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.222 103.25 25.08 + vertex -106.978 103.307 25.08 + vertex -106.725 102.884 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -107.239 104.747 25.08 + vertex -105.943 104.5 25.08 + vertex -107.151 105.232 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.943 104.5 25.08 + vertex -107.151 103.768 25.08 + vertex -106.978 103.307 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -107.239 104.253 25.08 + vertex -105.943 104.5 25.08 + vertex -107.239 104.747 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.943 104.5 25.08 + vertex -107.239 104.253 25.08 + vertex -107.151 103.768 25.08 + endloop + endfacet + facet normal -0.62349 0.781831 0 + outer loop + vertex -106.015 106.795 22.1 + vertex -106.4 106.488 25.08 + vertex -106.015 106.795 25.08 + endloop + endfacet + facet normal -0.62349 0.781831 0 + outer loop + vertex -106.4 106.488 25.08 + vertex -106.015 106.795 22.1 + vertex -106.4 106.488 22.1 + endloop + endfacet + facet normal -0.134229 0.99095 0 + outer loop + vertex -104.623 107.247 22.1 + vertex -105.112 107.181 25.08 + vertex -104.623 107.247 25.08 + endloop + endfacet + facet normal -0.134229 0.99095 0 + outer loop + vertex -105.112 107.181 25.08 + vertex -104.623 107.247 22.1 + vertex -105.112 107.181 22.1 + endloop + endfacet + facet normal 0.995974 -0.0896469 0 + outer loop + vertex -101.794 104.009 25.08 + vertex -101.75 104.5 22.1 + vertex -101.75 104.5 25.08 + endloop + endfacet + facet normal 0.995974 -0.0896469 0 + outer loop + vertex -101.75 104.5 22.1 + vertex -101.794 104.009 25.08 + vertex -101.794 104.009 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.01 104.5 22.1 + vertex -101.75 104.5 22.1 + vertex -101.794 104.009 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.091 104.016 22.1 + vertex -101.794 104.009 22.1 + vertex -101.925 103.534 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -101.75 104.5 22.1 + vertex -103.01 104.5 22.1 + vertex -101.794 104.991 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.091 104.016 22.1 + vertex -101.925 103.534 22.1 + vertex -102.139 103.09 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.091 104.984 22.1 + vertex -101.794 104.991 22.1 + vertex -103.01 104.5 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.324 103.585 22.1 + vertex -102.139 103.09 22.1 + vertex -102.429 102.691 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -101.794 104.991 22.1 + vertex -103.091 104.984 22.1 + vertex -101.925 105.466 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.324 103.585 22.1 + vertex -102.429 102.691 22.1 + vertex -102.785 102.35 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -101.925 105.466 22.1 + vertex -103.091 104.984 22.1 + vertex -102.139 105.91 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.324 105.415 22.1 + vertex -102.139 105.91 22.1 + vertex -103.091 104.984 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -101.794 104.009 22.1 + vertex -103.091 104.016 22.1 + vertex -103.01 104.5 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.685 103.253 22.1 + vertex -102.785 102.35 22.1 + vertex -103.197 102.078 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -102.139 103.09 22.1 + vertex -103.324 103.585 22.1 + vertex -103.091 104.016 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.134 103.056 22.1 + vertex -103.197 102.078 22.1 + vertex -103.65 101.885 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -102.785 102.35 22.1 + vertex -103.685 103.253 22.1 + vertex -103.324 103.585 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.134 103.056 22.1 + vertex -103.65 101.885 22.1 + vertex -104.131 101.775 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.197 102.078 22.1 + vertex -104.134 103.056 22.1 + vertex -103.685 103.253 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.131 101.775 22.1 + vertex -104.623 103.015 22.1 + vertex -104.134 103.056 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.623 101.753 22.1 + vertex -104.623 103.015 22.1 + vertex -104.131 101.775 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.112 101.819 22.1 + vertex -104.623 103.015 22.1 + vertex -104.623 101.753 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -104.623 103.015 22.1 + vertex -105.112 101.819 22.1 + vertex -105.099 103.135 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.581 101.971 22.1 + vertex -105.099 103.135 22.1 + vertex -105.112 101.819 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -106.015 102.205 22.1 + vertex -105.099 103.135 22.1 + vertex -105.581 101.971 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -105.099 103.135 22.1 + vertex -106.015 102.205 22.1 + vertex -105.509 103.404 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -106.4 102.512 22.1 + vertex -105.509 103.404 22.1 + vertex -106.015 102.205 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -105.509 103.404 22.1 + vertex -106.725 102.884 22.1 + vertex -105.81 103.791 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -106.725 102.884 22.1 + vertex -105.509 103.404 22.1 + vertex -106.4 102.512 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -102.139 105.91 22.1 + vertex -103.324 105.415 22.1 + vertex -102.429 106.309 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -102.429 106.309 22.1 + vertex -103.324 105.415 22.1 + vertex -102.785 106.65 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -103.685 105.747 22.1 + vertex -102.785 106.65 22.1 + vertex -103.324 105.415 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -102.785 106.65 22.1 + vertex -103.685 105.747 22.1 + vertex -103.197 106.922 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.134 105.944 22.1 + vertex -103.197 106.922 22.1 + vertex -103.685 105.747 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -103.197 106.922 22.1 + vertex -104.134 105.944 22.1 + vertex -103.65 107.115 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -103.65 107.115 22.1 + vertex -104.134 105.944 22.1 + vertex -104.131 107.225 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.623 105.985 22.1 + vertex -104.131 107.225 22.1 + vertex -104.134 105.944 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.623 105.985 22.1 + vertex -104.623 107.247 22.1 + vertex -104.131 107.225 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.112 107.181 22.1 + vertex -104.623 105.985 22.1 + vertex -105.099 105.865 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -104.623 105.985 22.1 + vertex -105.112 107.181 22.1 + vertex -104.623 107.247 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -106.015 106.795 22.1 + vertex -105.099 105.865 22.1 + vertex -105.509 105.596 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.099 105.865 22.1 + vertex -105.581 107.029 22.1 + vertex -105.112 107.181 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -106.725 106.116 22.1 + vertex -105.509 105.596 22.1 + vertex -105.81 105.209 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -107.151 105.232 22.1 + vertex -105.81 105.209 22.1 + vertex -105.97 104.745 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.099 105.865 22.1 + vertex -106.015 106.795 22.1 + vertex -105.581 107.029 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -106.978 103.307 22.1 + vertex -105.81 103.791 22.1 + vertex -106.725 102.884 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -107.151 103.768 22.1 + vertex -105.81 103.791 22.1 + vertex -106.978 103.307 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.509 105.596 22.1 + vertex -106.4 106.488 22.1 + vertex -106.015 106.795 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -105.81 103.791 22.1 + vertex -107.151 103.768 22.1 + vertex -105.97 104.255 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.509 105.596 22.1 + vertex -106.725 106.116 22.1 + vertex -106.4 106.488 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -107.239 104.253 22.1 + vertex -105.97 104.255 22.1 + vertex -107.151 103.768 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.81 105.209 22.1 + vertex -106.978 105.693 22.1 + vertex -106.725 106.116 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -105.97 104.255 22.1 + vertex -107.239 104.253 22.1 + vertex -105.97 104.745 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.81 105.209 22.1 + vertex -107.151 105.232 22.1 + vertex -106.978 105.693 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -107.239 104.747 22.1 + vertex -105.97 104.745 22.1 + vertex -107.239 104.253 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -105.97 104.745 22.1 + vertex -107.239 104.747 22.1 + vertex -107.151 105.232 22.1 + endloop + endfacet + facet normal 0.222531 -0.974926 0 + outer loop + vertex -104.131 101.775 22.1 + vertex -103.65 101.885 25.08 + vertex -104.131 101.775 25.08 + endloop + endfacet + facet normal 0.222531 -0.974926 0 + outer loop + vertex -103.65 101.885 25.08 + vertex -104.131 101.775 22.1 + vertex -103.65 101.885 22.1 + endloop + endfacet + facet normal -0.309018 0.951056 0 + outer loop + vertex -105.112 107.181 22.1 + vertex -105.581 107.029 25.08 + vertex -105.112 107.181 25.08 + endloop + endfacet + facet normal -0.309018 0.951056 0 + outer loop + vertex -105.581 107.029 25.08 + vertex -105.112 107.181 22.1 + vertex -105.581 107.029 22.1 + endloop + endfacet + facet normal 0.90097 -0.433881 0 + outer loop + vertex -102.139 103.09 25.08 + vertex -101.925 103.534 22.1 + vertex -101.925 103.534 25.08 + endloop + endfacet + facet normal 0.90097 -0.433881 0 + outer loop + vertex -101.925 103.534 22.1 + vertex -102.139 103.09 25.08 + vertex -102.139 103.09 22.1 + endloop + endfacet + facet normal -0.85845 -0.512897 0 + outer loop + vertex -106.725 102.884 22.1 + vertex -106.978 103.307 25.08 + vertex -106.978 103.307 22.1 + endloop + endfacet + facet normal -0.85845 -0.512897 0 + outer loop + vertex -106.978 103.307 25.08 + vertex -106.725 102.884 22.1 + vertex -106.725 102.884 25.08 + endloop + endfacet + facet normal -0.983928 -0.178565 0 + outer loop + vertex -107.151 103.768 22.1 + vertex -107.239 104.253 25.08 + vertex -107.239 104.253 22.1 + endloop + endfacet + facet normal -0.983928 -0.178565 0 + outer loop + vertex -107.239 104.253 25.08 + vertex -107.151 103.768 22.1 + vertex -107.151 103.768 25.08 + endloop + endfacet + facet normal 0.550891 -0.834577 0 + outer loop + vertex -103.197 102.078 22.1 + vertex -102.785 102.35 25.08 + vertex -103.197 102.078 25.08 + endloop + endfacet + facet normal 0.550891 -0.834577 0 + outer loop + vertex -102.785 102.35 25.08 + vertex -103.197 102.078 22.1 + vertex -102.785 102.35 22.1 + endloop + endfacet + facet normal 0.393015 -0.919532 0 + outer loop + vertex -103.65 101.885 22.1 + vertex -103.197 102.078 25.08 + vertex -103.65 101.885 25.08 + endloop + endfacet + facet normal 0.393015 -0.919532 0 + outer loop + vertex -103.197 102.078 25.08 + vertex -103.65 101.885 22.1 + vertex -103.197 102.078 22.1 + endloop + endfacet + facet normal -0.47387 -0.880595 0 + outer loop + vertex -106.015 102.205 22.1 + vertex -105.581 101.971 25.08 + vertex -106.015 102.205 25.08 + endloop + endfacet + facet normal -0.47387 -0.880595 -0 + outer loop + vertex -105.581 101.971 25.08 + vertex -106.015 102.205 22.1 + vertex -105.581 101.971 22.1 + endloop + endfacet + facet normal -0.309018 -0.951056 0 + outer loop + vertex -105.581 101.971 22.1 + vertex -105.112 101.819 25.08 + vertex -105.581 101.971 25.08 + endloop + endfacet + facet normal -0.309018 -0.951056 -0 + outer loop + vertex -105.112 101.819 25.08 + vertex -105.581 101.971 22.1 + vertex -105.112 101.819 22.1 + endloop + endfacet + facet normal -0.134229 -0.99095 0 + outer loop + vertex -105.112 101.819 22.1 + vertex -104.623 101.753 25.08 + vertex -105.112 101.819 25.08 + endloop + endfacet + facet normal -0.134229 -0.99095 -0 + outer loop + vertex -104.623 101.753 25.08 + vertex -105.112 101.819 22.1 + vertex -104.623 101.753 22.1 + endloop + endfacet + facet normal -0.936235 -0.351374 0 + outer loop + vertex -106.978 103.307 22.1 + vertex -107.151 103.768 25.08 + vertex -107.151 103.768 22.1 + endloop + endfacet + facet normal -0.936235 -0.351374 0 + outer loop + vertex -107.151 103.768 25.08 + vertex -106.978 103.307 22.1 + vertex -106.978 103.307 25.08 + endloop + endfacet + facet normal 0.691067 -0.722791 0 + outer loop + vertex -102.785 102.35 22.1 + vertex -102.429 102.691 25.08 + vertex -102.785 102.35 25.08 + endloop + endfacet + facet normal 0.691067 -0.722791 0 + outer loop + vertex -102.429 102.691 25.08 + vertex -102.785 102.35 22.1 + vertex -102.429 102.691 22.1 + endloop + endfacet + facet normal -0.753075 -0.657935 0 + outer loop + vertex -106.4 102.512 22.1 + vertex -106.725 102.884 25.08 + vertex -106.725 102.884 22.1 + endloop + endfacet + facet normal -0.753075 -0.657935 0 + outer loop + vertex -106.725 102.884 25.08 + vertex -106.4 102.512 22.1 + vertex -106.4 102.512 25.08 + endloop + endfacet + facet normal -0.62349 -0.781831 0 + outer loop + vertex -106.4 102.512 22.1 + vertex -106.015 102.205 25.08 + vertex -106.4 102.512 25.08 + endloop + endfacet + facet normal -0.62349 -0.781831 -0 + outer loop + vertex -106.015 102.205 25.08 + vertex -106.4 102.512 22.1 + vertex -106.015 102.205 22.1 + endloop + endfacet + facet normal 0.986363 0.164583 0 + outer loop + vertex -103.01 104.5 20.5 + vertex -103.091 104.984 13.5 + vertex -103.091 104.984 20.5 + endloop + endfacet + facet normal 0.986363 0.164583 0 + outer loop + vertex -103.091 104.984 13.5 + vertex -103.01 104.5 20.5 + vertex -103.01 104.5 13.5 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -105.97 104.255 13.5 + vertex -105.97 104.745 20.5 + vertex -105.97 104.745 13.5 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex -105.97 104.745 20.5 + vertex -105.97 104.255 13.5 + vertex -105.97 104.255 20.5 + endloop + endfacet + facet normal -0.245484 0.969401 0 + outer loop + vertex -104.623 105.985 13.5 + vertex -105.099 105.865 20.5 + vertex -104.623 105.985 20.5 + endloop + endfacet + facet normal -0.245484 0.969401 0 + outer loop + vertex -105.099 105.865 20.5 + vertex -104.623 105.985 13.5 + vertex -105.099 105.865 13.5 + endloop + endfacet + facet normal 0.0825782 -0.996585 0 + outer loop + vertex -104.623 103.015 13.5 + vertex -104.134 103.056 20.5 + vertex -104.623 103.015 20.5 + endloop + endfacet + facet normal 0.0825782 -0.996585 0 + outer loop + vertex -104.134 103.056 20.5 + vertex -104.623 103.015 13.5 + vertex -104.134 103.056 13.5 + endloop + endfacet + facet normal 0.401702 0.915771 -0 + outer loop + vertex -103.685 105.747 13.5 + vertex -104.134 105.944 20.5 + vertex -103.685 105.747 20.5 + endloop + endfacet + facet normal 0.401702 0.915771 0 + outer loop + vertex -104.134 105.944 20.5 + vertex -103.685 105.747 13.5 + vertex -104.134 105.944 13.5 + endloop + endfacet + facet normal 0.0825782 0.996585 -0 + outer loop + vertex -104.134 105.944 13.5 + vertex -104.623 105.985 20.5 + vertex -104.134 105.944 20.5 + endloop + endfacet + facet normal 0.0825782 0.996585 0 + outer loop + vertex -104.623 105.985 20.5 + vertex -104.134 105.944 13.5 + vertex -104.623 105.985 13.5 + endloop + endfacet + facet normal -0.789139 0.614214 0 + outer loop + vertex -105.81 105.209 13.5 + vertex -105.509 105.596 20.5 + vertex -105.509 105.596 13.5 + endloop + endfacet + facet normal -0.789139 0.614214 0 + outer loop + vertex -105.509 105.596 20.5 + vertex -105.81 105.209 13.5 + vertex -105.81 105.209 20.5 + endloop + endfacet + facet normal -0.945816 0.324703 0 + outer loop + vertex -105.97 104.745 13.5 + vertex -105.81 105.209 20.5 + vertex -105.81 105.209 13.5 + endloop + endfacet + facet normal -0.945816 0.324703 0 + outer loop + vertex -105.81 105.209 20.5 + vertex -105.97 104.745 13.5 + vertex -105.97 104.745 20.5 + endloop + endfacet + facet normal -0.546948 0.837167 0 + outer loop + vertex -105.099 105.865 13.5 + vertex -105.509 105.596 20.5 + vertex -105.099 105.865 20.5 + endloop + endfacet + facet normal -0.546948 0.837167 0 + outer loop + vertex -105.509 105.596 20.5 + vertex -105.099 105.865 13.5 + vertex -105.509 105.596 13.5 + endloop + endfacet + facet normal -0.245484 -0.969401 0 + outer loop + vertex -105.099 103.135 13.5 + vertex -104.623 103.015 20.5 + vertex -105.099 103.135 20.5 + endloop + endfacet + facet normal -0.245484 -0.969401 -0 + outer loop + vertex -104.623 103.015 20.5 + vertex -105.099 103.135 13.5 + vertex -104.623 103.015 13.5 + endloop + endfacet + facet normal 0.677276 0.735729 -0 + outer loop + vertex -103.324 105.415 13.5 + vertex -103.685 105.747 20.5 + vertex -103.324 105.415 20.5 + endloop + endfacet + facet normal 0.677276 0.735729 0 + outer loop + vertex -103.685 105.747 20.5 + vertex -103.324 105.415 13.5 + vertex -103.685 105.747 13.5 + endloop + endfacet + facet normal 0.87947 0.475954 0 + outer loop + vertex -103.091 104.984 20.5 + vertex -103.324 105.415 13.5 + vertex -103.324 105.415 20.5 + endloop + endfacet + facet normal 0.87947 0.475954 0 + outer loop + vertex -103.324 105.415 13.5 + vertex -103.091 104.984 20.5 + vertex -103.091 104.984 13.5 + endloop + endfacet + facet normal 0.401702 -0.915771 0 + outer loop + vertex -104.134 103.056 13.5 + vertex -103.685 103.253 20.5 + vertex -104.134 103.056 20.5 + endloop + endfacet + facet normal 0.401702 -0.915771 0 + outer loop + vertex -103.685 103.253 20.5 + vertex -104.134 103.056 13.5 + vertex -103.685 103.253 13.5 + endloop + endfacet + facet normal 0.986363 -0.164583 0 + outer loop + vertex -103.091 104.016 20.5 + vertex -103.01 104.5 13.5 + vertex -103.01 104.5 20.5 + endloop + endfacet + facet normal 0.986363 -0.164583 0 + outer loop + vertex -103.01 104.5 13.5 + vertex -103.091 104.016 20.5 + vertex -103.091 104.016 13.5 + endloop + endfacet + facet normal -0.546948 -0.837167 0 + outer loop + vertex -105.509 103.404 13.5 + vertex -105.099 103.135 20.5 + vertex -105.509 103.404 20.5 + endloop + endfacet + facet normal -0.546948 -0.837167 -0 + outer loop + vertex -105.099 103.135 20.5 + vertex -105.509 103.404 13.5 + vertex -105.099 103.135 13.5 + endloop + endfacet + facet normal -0.945816 -0.324703 0 + outer loop + vertex -105.81 103.791 13.5 + vertex -105.97 104.255 20.5 + vertex -105.97 104.255 13.5 + endloop + endfacet + facet normal -0.945816 -0.324703 0 + outer loop + vertex -105.97 104.255 20.5 + vertex -105.81 103.791 13.5 + vertex -105.81 103.791 20.5 + endloop + endfacet + facet normal 0.677276 -0.735729 0 + outer loop + vertex -103.685 103.253 13.5 + vertex -103.324 103.585 20.5 + vertex -103.685 103.253 20.5 + endloop + endfacet + facet normal 0.677276 -0.735729 0 + outer loop + vertex -103.324 103.585 20.5 + vertex -103.685 103.253 13.5 + vertex -103.324 103.585 13.5 + endloop + endfacet + facet normal -0.789139 -0.614214 0 + outer loop + vertex -105.509 103.404 13.5 + vertex -105.81 103.791 20.5 + vertex -105.81 103.791 13.5 + endloop + endfacet + facet normal -0.789139 -0.614214 0 + outer loop + vertex -105.81 103.791 20.5 + vertex -105.509 103.404 13.5 + vertex -105.509 103.404 20.5 + endloop + endfacet + facet normal 0.87947 -0.475954 0 + outer loop + vertex -103.324 103.585 20.5 + vertex -103.091 104.016 13.5 + vertex -103.091 104.016 20.5 + endloop + endfacet + facet normal 0.87947 -0.475954 0 + outer loop + vertex -103.091 104.016 13.5 + vertex -103.324 103.585 20.5 + vertex -103.324 103.585 13.5 + endloop + endfacet + facet normal -0.866026 -0.5 0 + outer loop + vertex -103.057 104.5 24.0867 + vertex -103.778 105.75 25.08 + vertex -103.778 105.75 24.0867 + endloop + endfacet + facet normal -0.866026 -0.5 0 + outer loop + vertex -103.778 105.75 25.08 + vertex -103.057 104.5 24.0867 + vertex -103.057 104.5 25.08 + endloop + endfacet + facet normal 0.866026 -0.5 0 + outer loop + vertex -105.943 104.5 25.08 + vertex -105.222 105.75 24.0867 + vertex -105.222 105.75 25.08 + endloop + endfacet + facet normal 0.866026 -0.5 0 + outer loop + vertex -105.222 105.75 24.0867 + vertex -105.943 104.5 25.08 + vertex -105.943 104.5 24.0867 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -105.222 105.75 24.0867 + vertex -103.778 105.75 25.08 + vertex -105.222 105.75 25.08 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -103.778 105.75 25.08 + vertex -105.222 105.75 24.0867 + vertex -103.778 105.75 24.0867 + endloop + endfacet + facet normal -0.866026 0.5 0 + outer loop + vertex -103.778 103.25 24.0867 + vertex -103.057 104.5 25.08 + vertex -103.057 104.5 24.0867 + endloop + endfacet + facet normal -0.866026 0.5 0 + outer loop + vertex -103.057 104.5 25.08 + vertex -103.778 103.25 24.0867 + vertex -103.778 103.25 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.778 105.75 24.0867 + vertex -103.778 103.25 24.0867 + vertex -103.057 104.5 24.0867 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -105.222 105.75 24.0867 + vertex -103.778 103.25 24.0867 + vertex -103.778 105.75 24.0867 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.222 105.75 24.0867 + vertex -105.222 103.25 24.0867 + vertex -103.778 103.25 24.0867 + endloop + endfacet + facet normal 0 -0 1 + outer loop + vertex -105.222 103.25 24.0867 + vertex -105.222 105.75 24.0867 + vertex -105.943 104.5 24.0867 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -103.778 103.25 24.0867 + vertex -105.222 103.25 25.08 + vertex -103.778 103.25 25.08 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -105.222 103.25 25.08 + vertex -103.778 103.25 24.0867 + vertex -105.222 103.25 24.0867 + endloop + endfacet + facet normal 0.866026 0.5 0 + outer loop + vertex -105.222 103.25 25.08 + vertex -105.943 104.5 24.0867 + vertex -105.943 104.5 25.08 + endloop + endfacet + facet normal 0.866026 0.5 0 + outer loop + vertex -105.943 104.5 24.0867 + vertex -105.222 103.25 25.08 + vertex -105.222 103.25 24.0867 + endloop + endfacet + facet normal 0.866025 0.5 0 + outer loop + vertex 107 -104.067 20.5 + vertex 105.875 -102.118 0.5 + vertex 105.875 -102.118 20.5 + endloop + endfacet + facet normal 0.866026 0.499999 -0 + outer loop + vertex 107.25 -104.5 0.5 + vertex 107 -104.067 20.5 + vertex 107.25 -104.5 20.5 + endloop + endfacet + facet normal 0.866025 0.5 -3.46791e-008 + outer loop + vertex 107 -104.067 20.5 + vertex 107.25 -104.5 0.5 + vertex 105.875 -102.118 0.5 + endloop + endfacet + facet normal -0.866025 0.5 0 + outer loop + vertex 101.75 -104.5 0.5 + vertex 103.125 -102.118 20.5 + vertex 103.125 -102.118 0.5 + endloop + endfacet + facet normal -0.866025 0.5 0 + outer loop + vertex 103.125 -102.118 20.5 + vertex 101.75 -104.5 0.5 + vertex 101.75 -104.5 20.5 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 105.875 -102.118 0.5 + vertex 103.125 -102.118 20.5 + vertex 105.875 -102.118 20.5 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 103.125 -102.118 20.5 + vertex 105.875 -102.118 0.5 + vertex 103.125 -102.118 0.5 + endloop + endfacet + facet normal 0.866026 -0.499999 0 + outer loop + vertex 107 -104.933 20.5 + vertex 107.25 -104.5 0.5 + vertex 107.25 -104.5 20.5 + endloop + endfacet + facet normal 0.866025 -0.5 0 + outer loop + vertex 105.875 -106.882 0.5 + vertex 107 -104.933 20.5 + vertex 105.875 -106.882 20.5 + endloop + endfacet + facet normal 0.866025 -0.5 -3.46791e-008 + outer loop + vertex 107 -104.933 20.5 + vertex 105.875 -106.882 0.5 + vertex 107.25 -104.5 0.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 107.25 -104.5 0.5 + vertex 105.919 -104.987 0.5 + vertex 106 -104.5 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.684 -105.421 0.5 + vertex 107.25 -104.5 0.5 + vertex 105.875 -106.882 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 107.25 -104.5 0.5 + vertex 105.684 -105.421 0.5 + vertex 105.919 -104.987 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.875 -106.882 0.5 + vertex 105.32 -105.756 0.5 + vertex 105.684 -105.421 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.875 -106.882 0.5 + vertex 104.868 -105.954 0.5 + vertex 105.32 -105.756 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.875 -106.882 0.5 + vertex 104.376 -105.995 0.5 + vertex 104.868 -105.954 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.125 -106.882 0.5 + vertex 104.376 -105.995 0.5 + vertex 105.875 -106.882 0.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 104.376 -105.995 0.5 + vertex 103.125 -106.882 0.5 + vertex 103.897 -105.874 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.125 -106.882 0.5 + vertex 103.484 -105.604 0.5 + vertex 103.897 -105.874 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.125 -106.882 0.5 + vertex 103.181 -105.214 0.5 + vertex 103.484 -105.604 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 101.75 -104.5 0.5 + vertex 103.181 -105.214 0.5 + vertex 103.125 -106.882 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.02 -104.747 0.5 + vertex 101.75 -104.5 0.5 + vertex 103.02 -104.253 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.181 -105.214 0.5 + vertex 101.75 -104.5 0.5 + vertex 103.02 -104.747 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.919 -104.013 0.5 + vertex 107.25 -104.5 0.5 + vertex 106 -104.5 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.684 -103.579 0.5 + vertex 107.25 -104.5 0.5 + vertex 105.919 -104.013 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 107.25 -104.5 0.5 + vertex 105.684 -103.579 0.5 + vertex 105.875 -102.118 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.32 -103.244 0.5 + vertex 105.875 -102.118 0.5 + vertex 105.684 -103.579 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.868 -103.046 0.5 + vertex 105.875 -102.118 0.5 + vertex 105.32 -103.244 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.376 -103.005 0.5 + vertex 105.875 -102.118 0.5 + vertex 104.868 -103.046 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.125 -102.118 0.5 + vertex 104.376 -103.005 0.5 + vertex 103.897 -103.126 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.376 -103.005 0.5 + vertex 103.125 -102.118 0.5 + vertex 105.875 -102.118 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.484 -103.396 0.5 + vertex 103.125 -102.118 0.5 + vertex 103.897 -103.126 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.181 -103.786 0.5 + vertex 103.125 -102.118 0.5 + vertex 103.484 -103.396 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 101.75 -104.5 0.5 + vertex 103.181 -103.786 0.5 + vertex 103.02 -104.253 0.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 103.181 -103.786 0.5 + vertex 101.75 -104.5 0.5 + vertex 103.125 -102.118 0.5 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 103.125 -106.882 0.5 + vertex 105.875 -106.882 20.5 + vertex 103.125 -106.882 20.5 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 105.875 -106.882 20.5 + vertex 103.125 -106.882 0.5 + vertex 105.875 -106.882 0.5 + endloop + endfacet + facet normal -0.866025 -0.5 0 + outer loop + vertex 103.125 -106.882 0.5 + vertex 101.75 -104.5 20.5 + vertex 101.75 -104.5 0.5 + endloop + endfacet + facet normal -0.866025 -0.5 0 + outer loop + vertex 101.75 -104.5 20.5 + vertex 103.125 -106.882 0.5 + vertex 103.125 -106.882 20.5 + endloop + endfacet + facet normal 0.98636 0.164599 0 + outer loop + vertex 106 -104.5 0.5 + vertex 105.919 -104.013 -6.5 + vertex 105.919 -104.013 0.5 + endloop + endfacet + facet normal 0.98636 0.164599 0 + outer loop + vertex 105.919 -104.013 -6.5 + vertex 106 -104.5 0.5 + vertex 106 -104.5 -6.5 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex 103.02 -104.747 -6.5 + vertex 103.02 -104.253 0.5 + vertex 103.02 -104.253 -6.5 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex 103.02 -104.253 0.5 + vertex 103.02 -104.747 -6.5 + vertex 103.02 -104.747 0.5 + endloop + endfacet + facet normal 0.0825698 0.996585 -0 + outer loop + vertex 104.868 -103.046 -6.5 + vertex 104.376 -103.005 0.5 + vertex 104.868 -103.046 0.5 + endloop + endfacet + facet normal 0.0825698 0.996585 0 + outer loop + vertex 104.376 -103.005 0.5 + vertex 104.868 -103.046 -6.5 + vertex 104.376 -103.005 -6.5 + endloop + endfacet + facet normal 0.0825698 -0.996585 0 + outer loop + vertex 104.376 -105.995 -6.5 + vertex 104.868 -105.954 0.5 + vertex 104.376 -105.995 0.5 + endloop + endfacet + facet normal 0.0825698 -0.996585 0 + outer loop + vertex 104.868 -105.954 0.5 + vertex 104.376 -105.995 -6.5 + vertex 104.868 -105.954 -6.5 + endloop + endfacet + facet normal 0.401692 -0.915775 0 + outer loop + vertex 104.868 -105.954 -6.5 + vertex 105.32 -105.756 0.5 + vertex 104.868 -105.954 0.5 + endloop + endfacet + facet normal 0.401692 -0.915775 0 + outer loop + vertex 105.32 -105.756 0.5 + vertex 104.868 -105.954 -6.5 + vertex 105.32 -105.756 -6.5 + endloop + endfacet + facet normal 0.677285 0.73572 -0 + outer loop + vertex 105.684 -103.579 -6.5 + vertex 105.32 -103.244 0.5 + vertex 105.684 -103.579 0.5 + endloop + endfacet + facet normal 0.677285 0.73572 0 + outer loop + vertex 105.32 -103.244 0.5 + vertex 105.684 -103.579 -6.5 + vertex 105.32 -103.244 -6.5 + endloop + endfacet + facet normal 0.879474 0.475946 0 + outer loop + vertex 105.919 -104.013 0.5 + vertex 105.684 -103.579 -6.5 + vertex 105.684 -103.579 0.5 + endloop + endfacet + facet normal 0.879474 0.475946 0 + outer loop + vertex 105.684 -103.579 -6.5 + vertex 105.919 -104.013 0.5 + vertex 105.919 -104.013 -6.5 + endloop + endfacet + facet normal 0.401692 0.915775 -0 + outer loop + vertex 105.32 -103.244 -6.5 + vertex 104.868 -103.046 0.5 + vertex 105.32 -103.244 0.5 + endloop + endfacet + facet normal 0.401692 0.915775 0 + outer loop + vertex 104.868 -103.046 0.5 + vertex 105.32 -103.244 -6.5 + vertex 104.868 -103.046 -6.5 + endloop + endfacet + facet normal -0.789137 0.614218 0 + outer loop + vertex 103.181 -103.786 -6.5 + vertex 103.484 -103.396 0.5 + vertex 103.484 -103.396 -6.5 + endloop + endfacet + facet normal -0.789137 0.614218 0 + outer loop + vertex 103.484 -103.396 0.5 + vertex 103.181 -103.786 -6.5 + vertex 103.181 -103.786 0.5 + endloop + endfacet + facet normal -0.945823 0.324684 0 + outer loop + vertex 103.02 -104.253 -6.5 + vertex 103.181 -103.786 0.5 + vertex 103.181 -103.786 -6.5 + endloop + endfacet + facet normal -0.945823 0.324684 0 + outer loop + vertex 103.181 -103.786 0.5 + vertex 103.02 -104.253 -6.5 + vertex 103.02 -104.253 0.5 + endloop + endfacet + facet normal -0.245487 0.9694 0 + outer loop + vertex 104.376 -103.005 -6.5 + vertex 103.897 -103.126 0.5 + vertex 104.376 -103.005 0.5 + endloop + endfacet + facet normal -0.245487 0.9694 0 + outer loop + vertex 103.897 -103.126 0.5 + vertex 104.376 -103.005 -6.5 + vertex 103.897 -103.126 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.919 -104.987 -6.5 + vertex 105.919 -104.013 -6.5 + vertex 106 -104.5 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.684 -105.421 -6.5 + vertex 105.919 -104.013 -6.5 + vertex 105.919 -104.987 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.684 -105.421 -6.5 + vertex 105.684 -103.579 -6.5 + vertex 105.919 -104.013 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.32 -105.756 -6.5 + vertex 105.684 -103.579 -6.5 + vertex 105.684 -105.421 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.32 -105.756 -6.5 + vertex 105.32 -103.244 -6.5 + vertex 105.684 -103.579 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.868 -105.954 -6.5 + vertex 105.32 -103.244 -6.5 + vertex 105.32 -105.756 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.868 -105.954 -6.5 + vertex 104.868 -103.046 -6.5 + vertex 105.32 -103.244 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.376 -105.995 -6.5 + vertex 104.868 -103.046 -6.5 + vertex 104.868 -105.954 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.376 -105.995 -6.5 + vertex 104.376 -103.005 -6.5 + vertex 104.868 -103.046 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.897 -105.874 -6.5 + vertex 104.376 -103.005 -6.5 + vertex 104.376 -105.995 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.897 -105.874 -6.5 + vertex 103.897 -103.126 -6.5 + vertex 104.376 -103.005 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.484 -105.604 -6.5 + vertex 103.897 -103.126 -6.5 + vertex 103.897 -105.874 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.484 -105.604 -6.5 + vertex 103.484 -103.396 -6.5 + vertex 103.897 -103.126 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.181 -105.214 -6.5 + vertex 103.484 -103.396 -6.5 + vertex 103.484 -105.604 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.181 -105.214 -6.5 + vertex 103.181 -103.786 -6.5 + vertex 103.484 -103.396 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.02 -104.747 -6.5 + vertex 103.181 -103.786 -6.5 + vertex 103.181 -105.214 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.181 -103.786 -6.5 + vertex 103.02 -104.747 -6.5 + vertex 103.02 -104.253 -6.5 + endloop + endfacet + facet normal -0.546943 0.83717 0 + outer loop + vertex 103.897 -103.126 -6.5 + vertex 103.484 -103.396 0.5 + vertex 103.897 -103.126 0.5 + endloop + endfacet + facet normal -0.546943 0.83717 0 + outer loop + vertex 103.484 -103.396 0.5 + vertex 103.897 -103.126 -6.5 + vertex 103.484 -103.396 -6.5 + endloop + endfacet + facet normal 0.98636 -0.164599 0 + outer loop + vertex 105.919 -104.987 0.5 + vertex 106 -104.5 -6.5 + vertex 106 -104.5 0.5 + endloop + endfacet + facet normal 0.98636 -0.164599 0 + outer loop + vertex 106 -104.5 -6.5 + vertex 105.919 -104.987 0.5 + vertex 105.919 -104.987 -6.5 + endloop + endfacet + facet normal 0.677285 -0.73572 0 + outer loop + vertex 105.32 -105.756 -6.5 + vertex 105.684 -105.421 0.5 + vertex 105.32 -105.756 0.5 + endloop + endfacet + facet normal 0.677285 -0.73572 0 + outer loop + vertex 105.684 -105.421 0.5 + vertex 105.32 -105.756 -6.5 + vertex 105.684 -105.421 -6.5 + endloop + endfacet + facet normal 0.879474 -0.475946 0 + outer loop + vertex 105.684 -105.421 0.5 + vertex 105.919 -104.987 -6.5 + vertex 105.919 -104.987 0.5 + endloop + endfacet + facet normal 0.879474 -0.475946 0 + outer loop + vertex 105.919 -104.987 -6.5 + vertex 105.684 -105.421 0.5 + vertex 105.684 -105.421 -6.5 + endloop + endfacet + facet normal -0.245487 -0.9694 0 + outer loop + vertex 103.897 -105.874 -6.5 + vertex 104.376 -105.995 0.5 + vertex 103.897 -105.874 0.5 + endloop + endfacet + facet normal -0.245487 -0.9694 -0 + outer loop + vertex 104.376 -105.995 0.5 + vertex 103.897 -105.874 -6.5 + vertex 104.376 -105.995 -6.5 + endloop + endfacet + facet normal -0.789137 -0.614218 0 + outer loop + vertex 103.484 -105.604 -6.5 + vertex 103.181 -105.214 0.5 + vertex 103.181 -105.214 -6.5 + endloop + endfacet + facet normal -0.789137 -0.614218 0 + outer loop + vertex 103.181 -105.214 0.5 + vertex 103.484 -105.604 -6.5 + vertex 103.484 -105.604 0.5 + endloop + endfacet + facet normal -0.945823 -0.324684 0 + outer loop + vertex 103.181 -105.214 -6.5 + vertex 103.02 -104.747 0.5 + vertex 103.02 -104.747 -6.5 + endloop + endfacet + facet normal -0.945823 -0.324684 0 + outer loop + vertex 103.02 -104.747 0.5 + vertex 103.181 -105.214 -6.5 + vertex 103.181 -105.214 0.5 + endloop + endfacet + facet normal -0.546943 -0.83717 0 + outer loop + vertex 103.484 -105.604 -6.5 + vertex 103.897 -105.874 0.5 + vertex 103.484 -105.604 0.5 + endloop + endfacet + facet normal -0.546943 -0.83717 -0 + outer loop + vertex 103.897 -105.874 0.5 + vertex 103.484 -105.604 -6.5 + vertex 103.897 -105.874 -6.5 + endloop + endfacet + facet normal -0.98636 -0.164599 0 + outer loop + vertex 106 -104.5 13.5 + vertex 105.919 -104.013 20.5 + vertex 105.919 -104.013 13.5 + endloop + endfacet + facet normal -0.98636 -0.164599 0 + outer loop + vertex 105.919 -104.013 20.5 + vertex 106 -104.5 13.5 + vertex 106 -104.5 20.5 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex 103.02 -104.747 20.5 + vertex 103.02 -104.253 13.5 + vertex 103.02 -104.253 20.5 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 103.02 -104.253 13.5 + vertex 103.02 -104.747 20.5 + vertex 103.02 -104.747 13.5 + endloop + endfacet + facet normal -0.0825698 -0.996585 0 + outer loop + vertex 104.376 -103.005 13.5 + vertex 104.868 -103.046 20.5 + vertex 104.376 -103.005 20.5 + endloop + endfacet + facet normal -0.0825698 -0.996585 -0 + outer loop + vertex 104.868 -103.046 20.5 + vertex 104.376 -103.005 13.5 + vertex 104.868 -103.046 13.5 + endloop + endfacet + facet normal -0.0825698 0.996585 0 + outer loop + vertex 104.868 -105.954 13.5 + vertex 104.376 -105.995 20.5 + vertex 104.868 -105.954 20.5 + endloop + endfacet + facet normal -0.0825698 0.996585 0 + outer loop + vertex 104.376 -105.995 20.5 + vertex 104.868 -105.954 13.5 + vertex 104.376 -105.995 13.5 + endloop + endfacet + facet normal -0.401692 0.915775 0 + outer loop + vertex 105.32 -105.756 13.5 + vertex 104.868 -105.954 20.5 + vertex 105.32 -105.756 20.5 + endloop + endfacet + facet normal -0.401692 0.915775 0 + outer loop + vertex 104.868 -105.954 20.5 + vertex 105.32 -105.756 13.5 + vertex 104.868 -105.954 13.5 + endloop + endfacet + facet normal -0.677285 -0.73572 0 + outer loop + vertex 105.32 -103.244 13.5 + vertex 105.684 -103.579 20.5 + vertex 105.32 -103.244 20.5 + endloop + endfacet + facet normal -0.677285 -0.73572 -0 + outer loop + vertex 105.684 -103.579 20.5 + vertex 105.32 -103.244 13.5 + vertex 105.684 -103.579 13.5 + endloop + endfacet + facet normal -0.879474 -0.475946 0 + outer loop + vertex 105.919 -104.013 13.5 + vertex 105.684 -103.579 20.5 + vertex 105.684 -103.579 13.5 + endloop + endfacet + facet normal -0.879474 -0.475946 0 + outer loop + vertex 105.684 -103.579 20.5 + vertex 105.919 -104.013 13.5 + vertex 105.919 -104.013 20.5 + endloop + endfacet + facet normal -0.401692 -0.915775 0 + outer loop + vertex 104.868 -103.046 13.5 + vertex 105.32 -103.244 20.5 + vertex 104.868 -103.046 20.5 + endloop + endfacet + facet normal -0.401692 -0.915775 -0 + outer loop + vertex 105.32 -103.244 20.5 + vertex 104.868 -103.046 13.5 + vertex 105.32 -103.244 13.5 + endloop + endfacet + facet normal 0.789137 -0.614218 0 + outer loop + vertex 103.181 -103.786 20.5 + vertex 103.484 -103.396 13.5 + vertex 103.484 -103.396 20.5 + endloop + endfacet + facet normal 0.789137 -0.614218 0 + outer loop + vertex 103.484 -103.396 13.5 + vertex 103.181 -103.786 20.5 + vertex 103.181 -103.786 13.5 + endloop + endfacet + facet normal 0.945823 -0.324684 0 + outer loop + vertex 103.02 -104.253 20.5 + vertex 103.181 -103.786 13.5 + vertex 103.181 -103.786 20.5 + endloop + endfacet + facet normal 0.945823 -0.324684 0 + outer loop + vertex 103.181 -103.786 13.5 + vertex 103.02 -104.253 20.5 + vertex 103.02 -104.253 13.5 + endloop + endfacet + facet normal 0.245487 -0.9694 0 + outer loop + vertex 103.897 -103.126 13.5 + vertex 104.376 -103.005 20.5 + vertex 103.897 -103.126 20.5 + endloop + endfacet + facet normal 0.245487 -0.9694 0 + outer loop + vertex 104.376 -103.005 20.5 + vertex 103.897 -103.126 13.5 + vertex 104.376 -103.005 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.919 -104.013 13.5 + vertex 105.99 -104.5 13.5 + vertex 106 -104.5 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.919 -104.013 13.5 + vertex 105.909 -104.016 13.5 + vertex 105.99 -104.5 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.684 -103.579 13.5 + vertex 105.909 -104.016 13.5 + vertex 105.919 -104.013 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.684 -103.579 13.5 + vertex 105.676 -103.585 13.5 + vertex 105.909 -104.016 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.32 -103.244 13.5 + vertex 105.676 -103.585 13.5 + vertex 105.684 -103.579 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.32 -103.244 13.5 + vertex 105.315 -103.253 13.5 + vertex 105.676 -103.585 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 104.868 -103.046 13.5 + vertex 105.315 -103.253 13.5 + vertex 105.32 -103.244 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 104.868 -103.046 13.5 + vertex 104.866 -103.056 13.5 + vertex 105.315 -103.253 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 104.868 -103.046 13.5 + vertex 104.377 -103.015 13.5 + vertex 104.866 -103.056 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 104.376 -103.005 13.5 + vertex 104.377 -103.015 13.5 + vertex 104.868 -103.046 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 104.376 -103.005 13.5 + vertex 103.901 -103.135 13.5 + vertex 104.377 -103.015 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 103.897 -103.126 13.5 + vertex 103.901 -103.135 13.5 + vertex 104.376 -103.005 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.897 -103.126 13.5 + vertex 103.491 -103.404 13.5 + vertex 103.901 -103.135 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 103.484 -103.396 13.5 + vertex 103.491 -103.404 13.5 + vertex 103.897 -103.126 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.484 -103.396 13.5 + vertex 103.19 -103.791 13.5 + vertex 103.491 -103.404 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 103.181 -103.786 13.5 + vertex 103.19 -103.791 13.5 + vertex 103.484 -103.396 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.181 -103.786 13.5 + vertex 103.03 -104.255 13.5 + vertex 103.19 -103.791 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.03 -104.255 13.5 + vertex 103.02 -104.253 13.5 + vertex 103.03 -104.745 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 103.02 -104.253 13.5 + vertex 103.03 -104.255 13.5 + vertex 103.181 -103.786 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 105.99 -104.5 13.5 + vertex 105.919 -104.987 13.5 + vertex 106 -104.5 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 105.909 -104.984 13.5 + vertex 105.919 -104.987 13.5 + vertex 105.99 -104.5 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.909 -104.984 13.5 + vertex 105.684 -105.421 13.5 + vertex 105.919 -104.987 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 105.676 -105.415 13.5 + vertex 105.684 -105.421 13.5 + vertex 105.909 -104.984 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.676 -105.415 13.5 + vertex 105.32 -105.756 13.5 + vertex 105.684 -105.421 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 105.315 -105.747 13.5 + vertex 105.32 -105.756 13.5 + vertex 105.676 -105.415 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.315 -105.747 13.5 + vertex 104.868 -105.954 13.5 + vertex 105.32 -105.756 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 104.866 -105.944 13.5 + vertex 104.868 -105.954 13.5 + vertex 105.315 -105.747 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 104.377 -105.985 13.5 + vertex 104.868 -105.954 13.5 + vertex 104.866 -105.944 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 104.377 -105.985 13.5 + vertex 104.376 -105.995 13.5 + vertex 104.868 -105.954 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.901 -105.865 13.5 + vertex 104.376 -105.995 13.5 + vertex 104.377 -105.985 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.901 -105.865 13.5 + vertex 103.897 -105.874 13.5 + vertex 104.376 -105.995 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.491 -105.596 13.5 + vertex 103.897 -105.874 13.5 + vertex 103.901 -105.865 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.491 -105.596 13.5 + vertex 103.484 -105.604 13.5 + vertex 103.897 -105.874 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.19 -105.209 13.5 + vertex 103.484 -105.604 13.5 + vertex 103.491 -105.596 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.19 -105.209 13.5 + vertex 103.181 -105.214 13.5 + vertex 103.484 -105.604 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.03 -104.745 13.5 + vertex 103.181 -105.214 13.5 + vertex 103.19 -105.209 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.03 -104.745 13.5 + vertex 103.02 -104.747 13.5 + vertex 103.181 -105.214 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.02 -104.747 13.5 + vertex 103.03 -104.745 13.5 + vertex 103.02 -104.253 13.5 + endloop + endfacet + facet normal 0.546943 -0.83717 0 + outer loop + vertex 103.484 -103.396 13.5 + vertex 103.897 -103.126 20.5 + vertex 103.484 -103.396 20.5 + endloop + endfacet + facet normal 0.546943 -0.83717 0 + outer loop + vertex 103.897 -103.126 20.5 + vertex 103.484 -103.396 13.5 + vertex 103.897 -103.126 13.5 + endloop + endfacet + facet normal -0.98636 0.164599 0 + outer loop + vertex 105.919 -104.987 13.5 + vertex 106 -104.5 20.5 + vertex 106 -104.5 13.5 + endloop + endfacet + facet normal -0.98636 0.164599 0 + outer loop + vertex 106 -104.5 20.5 + vertex 105.919 -104.987 13.5 + vertex 105.919 -104.987 20.5 + endloop + endfacet + facet normal 0.945823 0.324684 0 + outer loop + vertex 103.181 -105.214 20.5 + vertex 103.02 -104.747 13.5 + vertex 103.02 -104.747 20.5 + endloop + endfacet + facet normal 0.945823 0.324684 0 + outer loop + vertex 103.02 -104.747 13.5 + vertex 103.181 -105.214 20.5 + vertex 103.181 -105.214 13.5 + endloop + endfacet + facet normal -0.677285 0.73572 0 + outer loop + vertex 105.684 -105.421 13.5 + vertex 105.32 -105.756 20.5 + vertex 105.684 -105.421 20.5 + endloop + endfacet + facet normal -0.677285 0.73572 0 + outer loop + vertex 105.32 -105.756 20.5 + vertex 105.684 -105.421 13.5 + vertex 105.32 -105.756 13.5 + endloop + endfacet + facet normal -0.879474 0.475946 0 + outer loop + vertex 105.684 -105.421 13.5 + vertex 105.919 -104.987 20.5 + vertex 105.919 -104.987 13.5 + endloop + endfacet + facet normal -0.879474 0.475946 0 + outer loop + vertex 105.919 -104.987 20.5 + vertex 105.684 -105.421 13.5 + vertex 105.684 -105.421 20.5 + endloop + endfacet + facet normal 0.245487 0.9694 -0 + outer loop + vertex 104.376 -105.995 13.5 + vertex 103.897 -105.874 20.5 + vertex 104.376 -105.995 20.5 + endloop + endfacet + facet normal 0.245487 0.9694 0 + outer loop + vertex 103.897 -105.874 20.5 + vertex 104.376 -105.995 13.5 + vertex 103.897 -105.874 13.5 + endloop + endfacet + facet normal 0.789137 0.614218 0 + outer loop + vertex 103.484 -105.604 20.5 + vertex 103.181 -105.214 13.5 + vertex 103.181 -105.214 20.5 + endloop + endfacet + facet normal 0.789137 0.614218 0 + outer loop + vertex 103.181 -105.214 13.5 + vertex 103.484 -105.604 20.5 + vertex 103.484 -105.604 13.5 + endloop + endfacet + facet normal 0.546943 0.83717 -0 + outer loop + vertex 103.897 -105.874 13.5 + vertex 103.484 -105.604 20.5 + vertex 103.897 -105.874 20.5 + endloop + endfacet + facet normal 0.546943 0.83717 0 + outer loop + vertex 103.484 -105.604 20.5 + vertex 103.897 -105.874 13.5 + vertex 103.484 -105.604 13.5 + endloop + endfacet + facet normal 0.995974 0.0896469 0 + outer loop + vertex 107.25 -104.5 25.08 + vertex 107.206 -104.009 22.1 + vertex 107.206 -104.009 25.08 + endloop + endfacet + facet normal 0.995974 0.0896469 0 + outer loop + vertex 107.206 -104.009 22.1 + vertex 107.25 -104.5 25.08 + vertex 107.25 -104.5 22.1 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex 101.761 -104.747 22.1 + vertex 101.761 -104.253 25.08 + vertex 101.761 -104.253 22.1 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex 101.761 -104.253 25.08 + vertex 101.761 -104.747 22.1 + vertex 101.761 -104.747 25.08 + endloop + endfacet + facet normal 0.0448622 0.998993 -0 + outer loop + vertex 104.869 -101.775 22.1 + vertex 104.377 -101.753 25.08 + vertex 104.869 -101.775 25.08 + endloop + endfacet + facet normal 0.0448622 0.998993 0 + outer loop + vertex 104.377 -101.753 25.08 + vertex 104.869 -101.775 22.1 + vertex 104.377 -101.753 22.1 + endloop + endfacet + facet normal 0.0448622 -0.998993 0 + outer loop + vertex 104.377 -107.247 22.1 + vertex 104.869 -107.225 25.08 + vertex 104.377 -107.247 25.08 + endloop + endfacet + facet normal 0.0448622 -0.998993 0 + outer loop + vertex 104.869 -107.225 25.08 + vertex 104.377 -107.247 22.1 + vertex 104.869 -107.225 22.1 + endloop + endfacet + facet normal 0.809016 -0.587786 0 + outer loop + vertex 106.571 -106.309 25.08 + vertex 106.861 -105.91 22.1 + vertex 106.861 -105.91 25.08 + endloop + endfacet + facet normal 0.809016 -0.587786 0 + outer loop + vertex 106.861 -105.91 22.1 + vertex 106.571 -106.309 25.08 + vertex 106.571 -106.309 22.1 + endloop + endfacet + facet normal 0.691067 0.722791 -0 + outer loop + vertex 106.571 -102.691 22.1 + vertex 106.215 -102.35 25.08 + vertex 106.571 -102.691 25.08 + endloop + endfacet + facet normal 0.691067 0.722791 0 + outer loop + vertex 106.215 -102.35 25.08 + vertex 106.571 -102.691 22.1 + vertex 106.215 -102.35 22.1 + endloop + endfacet + facet normal -0.753075 0.657935 0 + outer loop + vertex 102.275 -102.884 22.1 + vertex 102.6 -102.512 25.08 + vertex 102.6 -102.512 22.1 + endloop + endfacet + facet normal -0.753075 0.657935 0 + outer loop + vertex 102.6 -102.512 25.08 + vertex 102.275 -102.884 22.1 + vertex 102.275 -102.884 25.08 + endloop + endfacet + facet normal -0.47387 0.880595 0 + outer loop + vertex 103.419 -101.971 22.1 + vertex 102.985 -102.205 25.08 + vertex 103.419 -101.971 25.08 + endloop + endfacet + facet normal -0.47387 0.880595 0 + outer loop + vertex 102.985 -102.205 25.08 + vertex 103.419 -101.971 22.1 + vertex 102.985 -102.205 22.1 + endloop + endfacet + facet normal 0.963965 -0.26603 0 + outer loop + vertex 107.075 -105.466 25.08 + vertex 107.206 -104.991 22.1 + vertex 107.206 -104.991 25.08 + endloop + endfacet + facet normal 0.963965 -0.26603 0 + outer loop + vertex 107.206 -104.991 22.1 + vertex 107.075 -105.466 25.08 + vertex 107.075 -105.466 22.1 + endloop + endfacet + facet normal 0.90097 0.433881 0 + outer loop + vertex 107.075 -103.534 25.08 + vertex 106.861 -103.09 22.1 + vertex 106.861 -103.09 25.08 + endloop + endfacet + facet normal 0.90097 0.433881 0 + outer loop + vertex 106.861 -103.09 22.1 + vertex 107.075 -103.534 25.08 + vertex 107.075 -103.534 22.1 + endloop + endfacet + facet normal 0.963965 0.26603 0 + outer loop + vertex 107.206 -104.009 25.08 + vertex 107.075 -103.534 22.1 + vertex 107.075 -103.534 25.08 + endloop + endfacet + facet normal 0.963965 0.26603 0 + outer loop + vertex 107.075 -103.534 22.1 + vertex 107.206 -104.009 25.08 + vertex 107.206 -104.009 22.1 + endloop + endfacet + facet normal 0.809016 0.587786 0 + outer loop + vertex 106.861 -103.09 25.08 + vertex 106.571 -102.691 22.1 + vertex 106.571 -102.691 25.08 + endloop + endfacet + facet normal 0.809016 0.587786 0 + outer loop + vertex 106.571 -102.691 22.1 + vertex 106.861 -103.09 25.08 + vertex 106.861 -103.09 22.1 + endloop + endfacet + facet normal 0.393015 0.919532 -0 + outer loop + vertex 105.803 -102.078 22.1 + vertex 105.35 -101.885 25.08 + vertex 105.803 -102.078 25.08 + endloop + endfacet + facet normal 0.393015 0.919532 0 + outer loop + vertex 105.35 -101.885 25.08 + vertex 105.803 -102.078 22.1 + vertex 105.35 -101.885 22.1 + endloop + endfacet + facet normal 0.222531 0.974926 -0 + outer loop + vertex 105.35 -101.885 22.1 + vertex 104.869 -101.775 25.08 + vertex 105.35 -101.885 25.08 + endloop + endfacet + facet normal 0.222531 0.974926 0 + outer loop + vertex 104.869 -101.775 25.08 + vertex 105.35 -101.885 22.1 + vertex 104.869 -101.775 22.1 + endloop + endfacet + facet normal 0.550891 0.834577 -0 + outer loop + vertex 106.215 -102.35 22.1 + vertex 105.803 -102.078 25.08 + vertex 106.215 -102.35 25.08 + endloop + endfacet + facet normal 0.550891 0.834577 0 + outer loop + vertex 105.803 -102.078 25.08 + vertex 106.215 -102.35 22.1 + vertex 105.803 -102.078 22.1 + endloop + endfacet + facet normal -0.936235 0.351374 0 + outer loop + vertex 101.849 -103.768 22.1 + vertex 102.022 -103.307 25.08 + vertex 102.022 -103.307 22.1 + endloop + endfacet + facet normal -0.936235 0.351374 0 + outer loop + vertex 102.022 -103.307 25.08 + vertex 101.849 -103.768 22.1 + vertex 101.849 -103.768 25.08 + endloop + endfacet + facet normal -0.85845 0.512897 0 + outer loop + vertex 102.022 -103.307 22.1 + vertex 102.275 -102.884 25.08 + vertex 102.275 -102.884 22.1 + endloop + endfacet + facet normal -0.85845 0.512897 0 + outer loop + vertex 102.275 -102.884 25.08 + vertex 102.022 -103.307 22.1 + vertex 102.022 -103.307 25.08 + endloop + endfacet + facet normal -0.983928 0.178565 0 + outer loop + vertex 101.761 -104.253 22.1 + vertex 101.849 -103.768 25.08 + vertex 101.849 -103.768 22.1 + endloop + endfacet + facet normal -0.983928 0.178565 0 + outer loop + vertex 101.849 -103.768 25.08 + vertex 101.761 -104.253 22.1 + vertex 101.761 -104.253 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.943 -104.5 25.08 + vertex 107.25 -104.5 25.08 + vertex 107.206 -104.009 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.943 -104.5 25.08 + vertex 107.206 -104.009 25.08 + vertex 107.075 -103.534 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 107.25 -104.5 25.08 + vertex 105.943 -104.5 25.08 + vertex 107.206 -104.991 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.943 -104.5 25.08 + vertex 107.075 -103.534 25.08 + vertex 106.861 -103.09 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 107.206 -104.991 25.08 + vertex 105.943 -104.5 25.08 + vertex 107.075 -105.466 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.222 -103.25 25.08 + vertex 106.861 -103.09 25.08 + vertex 106.571 -102.691 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 107.075 -105.466 25.08 + vertex 105.943 -104.5 25.08 + vertex 106.861 -105.91 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.222 -103.25 25.08 + vertex 106.571 -102.691 25.08 + vertex 106.215 -102.35 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 105.222 -105.75 25.08 + vertex 106.861 -105.91 25.08 + vertex 105.943 -104.5 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.861 -105.91 25.08 + vertex 105.222 -105.75 25.08 + vertex 106.571 -106.309 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.222 -103.25 25.08 + vertex 106.215 -102.35 25.08 + vertex 105.803 -102.078 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.222 -103.25 25.08 + vertex 105.803 -102.078 25.08 + vertex 105.35 -101.885 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.861 -103.09 25.08 + vertex 105.222 -103.25 25.08 + vertex 105.943 -104.5 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 104.869 -101.775 25.08 + vertex 105.222 -103.25 25.08 + vertex 105.35 -101.885 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 104.377 -101.753 25.08 + vertex 105.222 -103.25 25.08 + vertex 104.869 -101.775 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.778 -103.25 25.08 + vertex 104.377 -101.753 25.08 + vertex 103.888 -101.819 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 104.377 -101.753 25.08 + vertex 103.778 -103.25 25.08 + vertex 105.222 -103.25 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 103.419 -101.971 25.08 + vertex 103.778 -103.25 25.08 + vertex 103.888 -101.819 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 102.985 -102.205 25.08 + vertex 103.778 -103.25 25.08 + vertex 103.419 -101.971 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 102.6 -102.512 25.08 + vertex 103.778 -103.25 25.08 + vertex 102.985 -102.205 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.571 -106.309 25.08 + vertex 105.222 -105.75 25.08 + vertex 106.215 -106.65 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.215 -106.65 25.08 + vertex 105.222 -105.75 25.08 + vertex 105.803 -106.922 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.803 -106.922 25.08 + vertex 105.222 -105.75 25.08 + vertex 105.35 -107.115 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.222 -105.75 25.08 + vertex 104.869 -107.225 25.08 + vertex 105.35 -107.115 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.222 -105.75 25.08 + vertex 104.377 -107.247 25.08 + vertex 104.869 -107.225 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 103.778 -105.75 25.08 + vertex 104.377 -107.247 25.08 + vertex 105.222 -105.75 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 104.377 -107.247 25.08 + vertex 103.778 -105.75 25.08 + vertex 103.888 -107.181 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.778 -105.75 25.08 + vertex 103.419 -107.029 25.08 + vertex 103.888 -107.181 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 102.022 -105.693 25.08 + vertex 103.778 -105.75 25.08 + vertex 103.057 -104.5 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.778 -105.75 25.08 + vertex 102.985 -106.795 25.08 + vertex 103.419 -107.029 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 102.275 -102.884 25.08 + vertex 103.778 -103.25 25.08 + vertex 102.6 -102.512 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 102.022 -103.307 25.08 + vertex 103.778 -103.25 25.08 + vertex 102.275 -102.884 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.778 -105.75 25.08 + vertex 102.6 -106.488 25.08 + vertex 102.985 -106.795 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.778 -103.25 25.08 + vertex 102.022 -103.307 25.08 + vertex 103.057 -104.5 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.778 -105.75 25.08 + vertex 102.275 -106.116 25.08 + vertex 102.6 -106.488 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 101.849 -103.768 25.08 + vertex 103.057 -104.5 25.08 + vertex 102.022 -103.307 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.778 -105.75 25.08 + vertex 102.022 -105.693 25.08 + vertex 102.275 -106.116 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 101.761 -104.253 25.08 + vertex 103.057 -104.5 25.08 + vertex 101.849 -103.768 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.057 -104.5 25.08 + vertex 101.849 -105.232 25.08 + vertex 102.022 -105.693 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 101.761 -104.747 25.08 + vertex 103.057 -104.5 25.08 + vertex 101.761 -104.253 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.057 -104.5 25.08 + vertex 101.761 -104.747 25.08 + vertex 101.849 -105.232 25.08 + endloop + endfacet + facet normal -0.62349 0.781831 0 + outer loop + vertex 102.985 -102.205 22.1 + vertex 102.6 -102.512 25.08 + vertex 102.985 -102.205 25.08 + endloop + endfacet + facet normal -0.62349 0.781831 0 + outer loop + vertex 102.6 -102.512 25.08 + vertex 102.985 -102.205 22.1 + vertex 102.6 -102.512 22.1 + endloop + endfacet + facet normal -0.134229 0.99095 0 + outer loop + vertex 104.377 -101.753 22.1 + vertex 103.888 -101.819 25.08 + vertex 104.377 -101.753 25.08 + endloop + endfacet + facet normal -0.134229 0.99095 0 + outer loop + vertex 103.888 -101.819 25.08 + vertex 104.377 -101.753 22.1 + vertex 103.888 -101.819 22.1 + endloop + endfacet + facet normal 0.995974 -0.0896469 0 + outer loop + vertex 107.206 -104.991 25.08 + vertex 107.25 -104.5 22.1 + vertex 107.25 -104.5 25.08 + endloop + endfacet + facet normal 0.995974 -0.0896469 0 + outer loop + vertex 107.25 -104.5 22.1 + vertex 107.206 -104.991 25.08 + vertex 107.206 -104.991 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.99 -104.5 22.1 + vertex 107.25 -104.5 22.1 + vertex 107.206 -104.991 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.909 -104.984 22.1 + vertex 107.206 -104.991 22.1 + vertex 107.075 -105.466 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 107.25 -104.5 22.1 + vertex 105.99 -104.5 22.1 + vertex 107.206 -104.009 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.909 -104.984 22.1 + vertex 107.075 -105.466 22.1 + vertex 106.861 -105.91 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.909 -104.016 22.1 + vertex 107.206 -104.009 22.1 + vertex 105.99 -104.5 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.676 -105.415 22.1 + vertex 106.861 -105.91 22.1 + vertex 106.571 -106.309 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 107.206 -104.009 22.1 + vertex 105.909 -104.016 22.1 + vertex 107.075 -103.534 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.676 -105.415 22.1 + vertex 106.571 -106.309 22.1 + vertex 106.215 -106.65 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 107.075 -103.534 22.1 + vertex 105.909 -104.016 22.1 + vertex 106.861 -103.09 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.676 -103.585 22.1 + vertex 106.861 -103.09 22.1 + vertex 105.909 -104.016 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 107.206 -104.991 22.1 + vertex 105.909 -104.984 22.1 + vertex 105.99 -104.5 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.315 -105.747 22.1 + vertex 106.215 -106.65 22.1 + vertex 105.803 -106.922 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 106.861 -105.91 22.1 + vertex 105.676 -105.415 22.1 + vertex 105.909 -104.984 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.866 -105.944 22.1 + vertex 105.803 -106.922 22.1 + vertex 105.35 -107.115 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 106.215 -106.65 22.1 + vertex 105.315 -105.747 22.1 + vertex 105.676 -105.415 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.866 -105.944 22.1 + vertex 105.35 -107.115 22.1 + vertex 104.869 -107.225 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.803 -106.922 22.1 + vertex 104.866 -105.944 22.1 + vertex 105.315 -105.747 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.869 -107.225 22.1 + vertex 104.377 -105.985 22.1 + vertex 104.866 -105.944 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.377 -107.247 22.1 + vertex 104.377 -105.985 22.1 + vertex 104.869 -107.225 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.888 -107.181 22.1 + vertex 104.377 -105.985 22.1 + vertex 104.377 -107.247 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 104.377 -105.985 22.1 + vertex 103.888 -107.181 22.1 + vertex 103.901 -105.865 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.419 -107.029 22.1 + vertex 103.901 -105.865 22.1 + vertex 103.888 -107.181 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 102.985 -106.795 22.1 + vertex 103.901 -105.865 22.1 + vertex 103.419 -107.029 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 103.901 -105.865 22.1 + vertex 102.985 -106.795 22.1 + vertex 103.491 -105.596 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 102.6 -106.488 22.1 + vertex 103.491 -105.596 22.1 + vertex 102.985 -106.795 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 103.491 -105.596 22.1 + vertex 102.275 -106.116 22.1 + vertex 103.19 -105.209 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 102.275 -106.116 22.1 + vertex 103.491 -105.596 22.1 + vertex 102.6 -106.488 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 106.861 -103.09 22.1 + vertex 105.676 -103.585 22.1 + vertex 106.571 -102.691 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 106.571 -102.691 22.1 + vertex 105.676 -103.585 22.1 + vertex 106.215 -102.35 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.315 -103.253 22.1 + vertex 106.215 -102.35 22.1 + vertex 105.676 -103.585 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 106.215 -102.35 22.1 + vertex 105.315 -103.253 22.1 + vertex 105.803 -102.078 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.866 -103.056 22.1 + vertex 105.803 -102.078 22.1 + vertex 105.315 -103.253 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 105.803 -102.078 22.1 + vertex 104.866 -103.056 22.1 + vertex 105.35 -101.885 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 105.35 -101.885 22.1 + vertex 104.866 -103.056 22.1 + vertex 104.869 -101.775 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.377 -103.015 22.1 + vertex 104.869 -101.775 22.1 + vertex 104.866 -103.056 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.377 -103.015 22.1 + vertex 104.377 -101.753 22.1 + vertex 104.869 -101.775 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.888 -101.819 22.1 + vertex 104.377 -103.015 22.1 + vertex 103.901 -103.135 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.377 -103.015 22.1 + vertex 103.888 -101.819 22.1 + vertex 104.377 -101.753 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 102.985 -102.205 22.1 + vertex 103.901 -103.135 22.1 + vertex 103.491 -103.404 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.901 -103.135 22.1 + vertex 103.419 -101.971 22.1 + vertex 103.888 -101.819 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 102.275 -102.884 22.1 + vertex 103.491 -103.404 22.1 + vertex 103.19 -103.791 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 101.849 -103.768 22.1 + vertex 103.19 -103.791 22.1 + vertex 103.03 -104.255 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.901 -103.135 22.1 + vertex 102.985 -102.205 22.1 + vertex 103.419 -101.971 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 102.022 -105.693 22.1 + vertex 103.19 -105.209 22.1 + vertex 102.275 -106.116 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 101.849 -105.232 22.1 + vertex 103.19 -105.209 22.1 + vertex 102.022 -105.693 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.491 -103.404 22.1 + vertex 102.6 -102.512 22.1 + vertex 102.985 -102.205 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 103.19 -105.209 22.1 + vertex 101.849 -105.232 22.1 + vertex 103.03 -104.745 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.491 -103.404 22.1 + vertex 102.275 -102.884 22.1 + vertex 102.6 -102.512 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 101.761 -104.747 22.1 + vertex 103.03 -104.745 22.1 + vertex 101.849 -105.232 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.19 -103.791 22.1 + vertex 102.022 -103.307 22.1 + vertex 102.275 -102.884 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 103.03 -104.745 22.1 + vertex 101.761 -104.747 22.1 + vertex 103.03 -104.255 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.19 -103.791 22.1 + vertex 101.849 -103.768 22.1 + vertex 102.022 -103.307 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 101.761 -104.253 22.1 + vertex 103.03 -104.255 22.1 + vertex 101.761 -104.747 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.03 -104.255 22.1 + vertex 101.761 -104.253 22.1 + vertex 101.849 -103.768 22.1 + endloop + endfacet + facet normal 0.222531 -0.974926 0 + outer loop + vertex 104.869 -107.225 22.1 + vertex 105.35 -107.115 25.08 + vertex 104.869 -107.225 25.08 + endloop + endfacet + facet normal 0.222531 -0.974926 0 + outer loop + vertex 105.35 -107.115 25.08 + vertex 104.869 -107.225 22.1 + vertex 105.35 -107.115 22.1 + endloop + endfacet + facet normal -0.309018 0.951056 0 + outer loop + vertex 103.888 -101.819 22.1 + vertex 103.419 -101.971 25.08 + vertex 103.888 -101.819 25.08 + endloop + endfacet + facet normal -0.309018 0.951056 0 + outer loop + vertex 103.419 -101.971 25.08 + vertex 103.888 -101.819 22.1 + vertex 103.419 -101.971 22.1 + endloop + endfacet + facet normal 0.90097 -0.433881 0 + outer loop + vertex 106.861 -105.91 25.08 + vertex 107.075 -105.466 22.1 + vertex 107.075 -105.466 25.08 + endloop + endfacet + facet normal 0.90097 -0.433881 0 + outer loop + vertex 107.075 -105.466 22.1 + vertex 106.861 -105.91 25.08 + vertex 106.861 -105.91 22.1 + endloop + endfacet + facet normal -0.85845 -0.512897 0 + outer loop + vertex 102.275 -106.116 22.1 + vertex 102.022 -105.693 25.08 + vertex 102.022 -105.693 22.1 + endloop + endfacet + facet normal -0.85845 -0.512897 0 + outer loop + vertex 102.022 -105.693 25.08 + vertex 102.275 -106.116 22.1 + vertex 102.275 -106.116 25.08 + endloop + endfacet + facet normal -0.983928 -0.178565 0 + outer loop + vertex 101.849 -105.232 22.1 + vertex 101.761 -104.747 25.08 + vertex 101.761 -104.747 22.1 + endloop + endfacet + facet normal -0.983928 -0.178565 0 + outer loop + vertex 101.761 -104.747 25.08 + vertex 101.849 -105.232 22.1 + vertex 101.849 -105.232 25.08 + endloop + endfacet + facet normal 0.550891 -0.834577 0 + outer loop + vertex 105.803 -106.922 22.1 + vertex 106.215 -106.65 25.08 + vertex 105.803 -106.922 25.08 + endloop + endfacet + facet normal 0.550891 -0.834577 0 + outer loop + vertex 106.215 -106.65 25.08 + vertex 105.803 -106.922 22.1 + vertex 106.215 -106.65 22.1 + endloop + endfacet + facet normal 0.393015 -0.919532 0 + outer loop + vertex 105.35 -107.115 22.1 + vertex 105.803 -106.922 25.08 + vertex 105.35 -107.115 25.08 + endloop + endfacet + facet normal 0.393015 -0.919532 0 + outer loop + vertex 105.803 -106.922 25.08 + vertex 105.35 -107.115 22.1 + vertex 105.803 -106.922 22.1 + endloop + endfacet + facet normal -0.47387 -0.880595 0 + outer loop + vertex 102.985 -106.795 22.1 + vertex 103.419 -107.029 25.08 + vertex 102.985 -106.795 25.08 + endloop + endfacet + facet normal -0.47387 -0.880595 -0 + outer loop + vertex 103.419 -107.029 25.08 + vertex 102.985 -106.795 22.1 + vertex 103.419 -107.029 22.1 + endloop + endfacet + facet normal -0.309018 -0.951056 0 + outer loop + vertex 103.419 -107.029 22.1 + vertex 103.888 -107.181 25.08 + vertex 103.419 -107.029 25.08 + endloop + endfacet + facet normal -0.309018 -0.951056 -0 + outer loop + vertex 103.888 -107.181 25.08 + vertex 103.419 -107.029 22.1 + vertex 103.888 -107.181 22.1 + endloop + endfacet + facet normal -0.134229 -0.99095 0 + outer loop + vertex 103.888 -107.181 22.1 + vertex 104.377 -107.247 25.08 + vertex 103.888 -107.181 25.08 + endloop + endfacet + facet normal -0.134229 -0.99095 -0 + outer loop + vertex 104.377 -107.247 25.08 + vertex 103.888 -107.181 22.1 + vertex 104.377 -107.247 22.1 + endloop + endfacet + facet normal -0.936235 -0.351374 0 + outer loop + vertex 102.022 -105.693 22.1 + vertex 101.849 -105.232 25.08 + vertex 101.849 -105.232 22.1 + endloop + endfacet + facet normal -0.936235 -0.351374 0 + outer loop + vertex 101.849 -105.232 25.08 + vertex 102.022 -105.693 22.1 + vertex 102.022 -105.693 25.08 + endloop + endfacet + facet normal 0.691067 -0.722791 0 + outer loop + vertex 106.215 -106.65 22.1 + vertex 106.571 -106.309 25.08 + vertex 106.215 -106.65 25.08 + endloop + endfacet + facet normal 0.691067 -0.722791 0 + outer loop + vertex 106.571 -106.309 25.08 + vertex 106.215 -106.65 22.1 + vertex 106.571 -106.309 22.1 + endloop + endfacet + facet normal -0.753075 -0.657935 0 + outer loop + vertex 102.6 -106.488 22.1 + vertex 102.275 -106.116 25.08 + vertex 102.275 -106.116 22.1 + endloop + endfacet + facet normal -0.753075 -0.657935 0 + outer loop + vertex 102.275 -106.116 25.08 + vertex 102.6 -106.488 22.1 + vertex 102.6 -106.488 25.08 + endloop + endfacet + facet normal -0.62349 -0.781831 0 + outer loop + vertex 102.6 -106.488 22.1 + vertex 102.985 -106.795 25.08 + vertex 102.6 -106.488 25.08 + endloop + endfacet + facet normal -0.62349 -0.781831 -0 + outer loop + vertex 102.985 -106.795 25.08 + vertex 102.6 -106.488 22.1 + vertex 102.985 -106.795 22.1 + endloop + endfacet + facet normal 0.986363 0.164583 0 + outer loop + vertex 105.99 -104.5 20.5 + vertex 105.909 -104.016 13.5 + vertex 105.909 -104.016 20.5 + endloop + endfacet + facet normal 0.986363 0.164583 0 + outer loop + vertex 105.909 -104.016 13.5 + vertex 105.99 -104.5 20.5 + vertex 105.99 -104.5 13.5 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex 103.03 -104.745 13.5 + vertex 103.03 -104.255 20.5 + vertex 103.03 -104.255 13.5 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex 103.03 -104.255 20.5 + vertex 103.03 -104.745 13.5 + vertex 103.03 -104.745 20.5 + endloop + endfacet + facet normal -0.245484 0.969401 0 + outer loop + vertex 104.377 -103.015 13.5 + vertex 103.901 -103.135 20.5 + vertex 104.377 -103.015 20.5 + endloop + endfacet + facet normal -0.245484 0.969401 0 + outer loop + vertex 103.901 -103.135 20.5 + vertex 104.377 -103.015 13.5 + vertex 103.901 -103.135 13.5 + endloop + endfacet + facet normal 0.0825782 -0.996585 0 + outer loop + vertex 104.377 -105.985 13.5 + vertex 104.866 -105.944 20.5 + vertex 104.377 -105.985 20.5 + endloop + endfacet + facet normal 0.0825782 -0.996585 0 + outer loop + vertex 104.866 -105.944 20.5 + vertex 104.377 -105.985 13.5 + vertex 104.866 -105.944 13.5 + endloop + endfacet + facet normal 0.401702 0.915771 -0 + outer loop + vertex 105.315 -103.253 13.5 + vertex 104.866 -103.056 20.5 + vertex 105.315 -103.253 20.5 + endloop + endfacet + facet normal 0.401702 0.915771 0 + outer loop + vertex 104.866 -103.056 20.5 + vertex 105.315 -103.253 13.5 + vertex 104.866 -103.056 13.5 + endloop + endfacet + facet normal 0.0825782 0.996585 -0 + outer loop + vertex 104.866 -103.056 13.5 + vertex 104.377 -103.015 20.5 + vertex 104.866 -103.056 20.5 + endloop + endfacet + facet normal 0.0825782 0.996585 0 + outer loop + vertex 104.377 -103.015 20.5 + vertex 104.866 -103.056 13.5 + vertex 104.377 -103.015 13.5 + endloop + endfacet + facet normal -0.789139 0.614214 0 + outer loop + vertex 103.19 -103.791 13.5 + vertex 103.491 -103.404 20.5 + vertex 103.491 -103.404 13.5 + endloop + endfacet + facet normal -0.789139 0.614214 0 + outer loop + vertex 103.491 -103.404 20.5 + vertex 103.19 -103.791 13.5 + vertex 103.19 -103.791 20.5 + endloop + endfacet + facet normal -0.945816 0.324703 0 + outer loop + vertex 103.03 -104.255 13.5 + vertex 103.19 -103.791 20.5 + vertex 103.19 -103.791 13.5 + endloop + endfacet + facet normal -0.945816 0.324703 0 + outer loop + vertex 103.19 -103.791 20.5 + vertex 103.03 -104.255 13.5 + vertex 103.03 -104.255 20.5 + endloop + endfacet + facet normal -0.546948 0.837167 0 + outer loop + vertex 103.901 -103.135 13.5 + vertex 103.491 -103.404 20.5 + vertex 103.901 -103.135 20.5 + endloop + endfacet + facet normal -0.546948 0.837167 0 + outer loop + vertex 103.491 -103.404 20.5 + vertex 103.901 -103.135 13.5 + vertex 103.491 -103.404 13.5 + endloop + endfacet + facet normal -0.245484 -0.969401 0 + outer loop + vertex 103.901 -105.865 13.5 + vertex 104.377 -105.985 20.5 + vertex 103.901 -105.865 20.5 + endloop + endfacet + facet normal -0.245484 -0.969401 -0 + outer loop + vertex 104.377 -105.985 20.5 + vertex 103.901 -105.865 13.5 + vertex 104.377 -105.985 13.5 + endloop + endfacet + facet normal 0.677276 0.735729 -0 + outer loop + vertex 105.676 -103.585 13.5 + vertex 105.315 -103.253 20.5 + vertex 105.676 -103.585 20.5 + endloop + endfacet + facet normal 0.677276 0.735729 0 + outer loop + vertex 105.315 -103.253 20.5 + vertex 105.676 -103.585 13.5 + vertex 105.315 -103.253 13.5 + endloop + endfacet + facet normal 0.87947 0.475954 0 + outer loop + vertex 105.909 -104.016 20.5 + vertex 105.676 -103.585 13.5 + vertex 105.676 -103.585 20.5 + endloop + endfacet + facet normal 0.87947 0.475954 0 + outer loop + vertex 105.676 -103.585 13.5 + vertex 105.909 -104.016 20.5 + vertex 105.909 -104.016 13.5 + endloop + endfacet + facet normal 0.401702 -0.915771 0 + outer loop + vertex 104.866 -105.944 13.5 + vertex 105.315 -105.747 20.5 + vertex 104.866 -105.944 20.5 + endloop + endfacet + facet normal 0.401702 -0.915771 0 + outer loop + vertex 105.315 -105.747 20.5 + vertex 104.866 -105.944 13.5 + vertex 105.315 -105.747 13.5 + endloop + endfacet + facet normal 0.986363 -0.164583 0 + outer loop + vertex 105.909 -104.984 20.5 + vertex 105.99 -104.5 13.5 + vertex 105.99 -104.5 20.5 + endloop + endfacet + facet normal 0.986363 -0.164583 0 + outer loop + vertex 105.99 -104.5 13.5 + vertex 105.909 -104.984 20.5 + vertex 105.909 -104.984 13.5 + endloop + endfacet + facet normal -0.546948 -0.837167 0 + outer loop + vertex 103.491 -105.596 13.5 + vertex 103.901 -105.865 20.5 + vertex 103.491 -105.596 20.5 + endloop + endfacet + facet normal -0.546948 -0.837167 -0 + outer loop + vertex 103.901 -105.865 20.5 + vertex 103.491 -105.596 13.5 + vertex 103.901 -105.865 13.5 + endloop + endfacet + facet normal -0.945816 -0.324703 0 + outer loop + vertex 103.19 -105.209 13.5 + vertex 103.03 -104.745 20.5 + vertex 103.03 -104.745 13.5 + endloop + endfacet + facet normal -0.945816 -0.324703 0 + outer loop + vertex 103.03 -104.745 20.5 + vertex 103.19 -105.209 13.5 + vertex 103.19 -105.209 20.5 + endloop + endfacet + facet normal 0.677276 -0.735729 0 + outer loop + vertex 105.315 -105.747 13.5 + vertex 105.676 -105.415 20.5 + vertex 105.315 -105.747 20.5 + endloop + endfacet + facet normal 0.677276 -0.735729 0 + outer loop + vertex 105.676 -105.415 20.5 + vertex 105.315 -105.747 13.5 + vertex 105.676 -105.415 13.5 + endloop + endfacet + facet normal -0.789139 -0.614214 0 + outer loop + vertex 103.491 -105.596 13.5 + vertex 103.19 -105.209 20.5 + vertex 103.19 -105.209 13.5 + endloop + endfacet + facet normal -0.789139 -0.614214 0 + outer loop + vertex 103.19 -105.209 20.5 + vertex 103.491 -105.596 13.5 + vertex 103.491 -105.596 20.5 + endloop + endfacet + facet normal 0.87947 -0.475954 0 + outer loop + vertex 105.676 -105.415 20.5 + vertex 105.909 -104.984 13.5 + vertex 105.909 -104.984 20.5 + endloop + endfacet + facet normal 0.87947 -0.475954 0 + outer loop + vertex 105.909 -104.984 13.5 + vertex 105.676 -105.415 20.5 + vertex 105.676 -105.415 13.5 + endloop + endfacet + facet normal -0.866026 -0.5 0 + outer loop + vertex 105.943 -104.5 24.0867 + vertex 105.222 -103.25 25.08 + vertex 105.222 -103.25 24.0867 + endloop + endfacet + facet normal -0.866026 -0.5 0 + outer loop + vertex 105.222 -103.25 25.08 + vertex 105.943 -104.5 24.0867 + vertex 105.943 -104.5 25.08 + endloop + endfacet + facet normal 0.866026 -0.5 0 + outer loop + vertex 103.057 -104.5 25.08 + vertex 103.778 -103.25 24.0867 + vertex 103.778 -103.25 25.08 + endloop + endfacet + facet normal 0.866026 -0.5 0 + outer loop + vertex 103.778 -103.25 24.0867 + vertex 103.057 -104.5 25.08 + vertex 103.057 -104.5 24.0867 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 103.778 -103.25 24.0867 + vertex 105.222 -103.25 25.08 + vertex 103.778 -103.25 25.08 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 105.222 -103.25 25.08 + vertex 103.778 -103.25 24.0867 + vertex 105.222 -103.25 24.0867 + endloop + endfacet + facet normal -0.866026 0.5 0 + outer loop + vertex 105.222 -105.75 24.0867 + vertex 105.943 -104.5 25.08 + vertex 105.943 -104.5 24.0867 + endloop + endfacet + facet normal -0.866026 0.5 0 + outer loop + vertex 105.943 -104.5 25.08 + vertex 105.222 -105.75 24.0867 + vertex 105.222 -105.75 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.222 -103.25 24.0867 + vertex 105.222 -105.75 24.0867 + vertex 105.943 -104.5 24.0867 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 103.778 -103.25 24.0867 + vertex 105.222 -105.75 24.0867 + vertex 105.222 -103.25 24.0867 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.778 -103.25 24.0867 + vertex 103.778 -105.75 24.0867 + vertex 105.222 -105.75 24.0867 + endloop + endfacet + facet normal 0 -0 1 + outer loop + vertex 103.778 -105.75 24.0867 + vertex 103.778 -103.25 24.0867 + vertex 103.057 -104.5 24.0867 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 105.222 -105.75 24.0867 + vertex 103.778 -105.75 25.08 + vertex 105.222 -105.75 25.08 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 103.778 -105.75 25.08 + vertex 105.222 -105.75 24.0867 + vertex 103.778 -105.75 24.0867 + endloop + endfacet + facet normal 0.866026 0.5 0 + outer loop + vertex 103.778 -105.75 25.08 + vertex 103.057 -104.5 24.0867 + vertex 103.057 -104.5 25.08 + endloop + endfacet + facet normal 0.866026 0.5 0 + outer loop + vertex 103.057 -104.5 24.0867 + vertex 103.778 -105.75 25.08 + vertex 103.778 -105.75 24.0867 + endloop + endfacet + facet normal 0.866025 0.5 0 + outer loop + vertex 107 104.933 20.5 + vertex 105.875 106.882 0.5 + vertex 105.875 106.882 20.5 + endloop + endfacet + facet normal 0.866026 0.499999 -0 + outer loop + vertex 107.25 104.5 0.5 + vertex 107 104.933 20.5 + vertex 107.25 104.5 20.5 + endloop + endfacet + facet normal 0.866025 0.5 -3.46791e-008 + outer loop + vertex 107 104.933 20.5 + vertex 107.25 104.5 0.5 + vertex 105.875 106.882 0.5 + endloop + endfacet + facet normal -0.866025 0.5 0 + outer loop + vertex 101.75 104.5 0.5 + vertex 103.125 106.882 20.5 + vertex 103.125 106.882 0.5 + endloop + endfacet + facet normal -0.866025 0.5 0 + outer loop + vertex 103.125 106.882 20.5 + vertex 101.75 104.5 0.5 + vertex 101.75 104.5 20.5 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 105.875 106.882 0.5 + vertex 103.125 106.882 20.5 + vertex 105.875 106.882 20.5 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 103.125 106.882 20.5 + vertex 105.875 106.882 0.5 + vertex 103.125 106.882 0.5 + endloop + endfacet + facet normal 0.866026 -0.499999 0 + outer loop + vertex 107 104.067 20.5 + vertex 107.25 104.5 0.5 + vertex 107.25 104.5 20.5 + endloop + endfacet + facet normal 0.866025 -0.5 0 + outer loop + vertex 105.875 102.118 0.5 + vertex 107 104.067 20.5 + vertex 105.875 102.118 20.5 + endloop + endfacet + facet normal 0.866025 -0.5 -3.46791e-008 + outer loop + vertex 107 104.067 20.5 + vertex 105.875 102.118 0.5 + vertex 107.25 104.5 0.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 107.25 104.5 0.5 + vertex 105.919 104.013 0.5 + vertex 106 104.5 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.684 103.579 0.5 + vertex 107.25 104.5 0.5 + vertex 105.875 102.118 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 107.25 104.5 0.5 + vertex 105.684 103.579 0.5 + vertex 105.919 104.013 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.875 102.118 0.5 + vertex 105.32 103.244 0.5 + vertex 105.684 103.579 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.875 102.118 0.5 + vertex 104.868 103.046 0.5 + vertex 105.32 103.244 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.875 102.118 0.5 + vertex 104.376 103.005 0.5 + vertex 104.868 103.046 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.125 102.118 0.5 + vertex 104.376 103.005 0.5 + vertex 105.875 102.118 0.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 104.376 103.005 0.5 + vertex 103.125 102.118 0.5 + vertex 103.897 103.126 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.125 102.118 0.5 + vertex 103.484 103.396 0.5 + vertex 103.897 103.126 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.125 102.118 0.5 + vertex 103.181 103.786 0.5 + vertex 103.484 103.396 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 101.75 104.5 0.5 + vertex 103.181 103.786 0.5 + vertex 103.125 102.118 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.02 104.253 0.5 + vertex 101.75 104.5 0.5 + vertex 103.02 104.747 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.181 103.786 0.5 + vertex 101.75 104.5 0.5 + vertex 103.02 104.253 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.919 104.987 0.5 + vertex 107.25 104.5 0.5 + vertex 106 104.5 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.684 105.421 0.5 + vertex 107.25 104.5 0.5 + vertex 105.919 104.987 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 107.25 104.5 0.5 + vertex 105.684 105.421 0.5 + vertex 105.875 106.882 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.32 105.756 0.5 + vertex 105.875 106.882 0.5 + vertex 105.684 105.421 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.868 105.954 0.5 + vertex 105.875 106.882 0.5 + vertex 105.32 105.756 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.376 105.995 0.5 + vertex 105.875 106.882 0.5 + vertex 104.868 105.954 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.125 106.882 0.5 + vertex 104.376 105.995 0.5 + vertex 103.897 105.874 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.376 105.995 0.5 + vertex 103.125 106.882 0.5 + vertex 105.875 106.882 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.484 105.604 0.5 + vertex 103.125 106.882 0.5 + vertex 103.897 105.874 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.181 105.214 0.5 + vertex 103.125 106.882 0.5 + vertex 103.484 105.604 0.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 101.75 104.5 0.5 + vertex 103.181 105.214 0.5 + vertex 103.02 104.747 0.5 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 103.181 105.214 0.5 + vertex 101.75 104.5 0.5 + vertex 103.125 106.882 0.5 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 103.125 102.118 0.5 + vertex 105.875 102.118 20.5 + vertex 103.125 102.118 20.5 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 105.875 102.118 20.5 + vertex 103.125 102.118 0.5 + vertex 105.875 102.118 0.5 + endloop + endfacet + facet normal -0.866025 -0.5 0 + outer loop + vertex 103.125 102.118 0.5 + vertex 101.75 104.5 20.5 + vertex 101.75 104.5 0.5 + endloop + endfacet + facet normal -0.866025 -0.5 0 + outer loop + vertex 101.75 104.5 20.5 + vertex 103.125 102.118 0.5 + vertex 103.125 102.118 20.5 + endloop + endfacet + facet normal 0.98636 0.164599 0 + outer loop + vertex 106 104.5 0.5 + vertex 105.919 104.987 -6.5 + vertex 105.919 104.987 0.5 + endloop + endfacet + facet normal 0.98636 0.164599 0 + outer loop + vertex 105.919 104.987 -6.5 + vertex 106 104.5 0.5 + vertex 106 104.5 -6.5 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex 103.02 104.253 -6.5 + vertex 103.02 104.747 0.5 + vertex 103.02 104.747 -6.5 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex 103.02 104.747 0.5 + vertex 103.02 104.253 -6.5 + vertex 103.02 104.253 0.5 + endloop + endfacet + facet normal 0.0825698 0.996585 -0 + outer loop + vertex 104.868 105.954 -6.5 + vertex 104.376 105.995 0.5 + vertex 104.868 105.954 0.5 + endloop + endfacet + facet normal 0.0825698 0.996585 0 + outer loop + vertex 104.376 105.995 0.5 + vertex 104.868 105.954 -6.5 + vertex 104.376 105.995 -6.5 + endloop + endfacet + facet normal 0.0825698 -0.996585 0 + outer loop + vertex 104.376 103.005 -6.5 + vertex 104.868 103.046 0.5 + vertex 104.376 103.005 0.5 + endloop + endfacet + facet normal 0.0825698 -0.996585 0 + outer loop + vertex 104.868 103.046 0.5 + vertex 104.376 103.005 -6.5 + vertex 104.868 103.046 -6.5 + endloop + endfacet + facet normal 0.401692 -0.915775 0 + outer loop + vertex 104.868 103.046 -6.5 + vertex 105.32 103.244 0.5 + vertex 104.868 103.046 0.5 + endloop + endfacet + facet normal 0.401692 -0.915775 0 + outer loop + vertex 105.32 103.244 0.5 + vertex 104.868 103.046 -6.5 + vertex 105.32 103.244 -6.5 + endloop + endfacet + facet normal 0.677285 0.73572 -0 + outer loop + vertex 105.684 105.421 -6.5 + vertex 105.32 105.756 0.5 + vertex 105.684 105.421 0.5 + endloop + endfacet + facet normal 0.677285 0.73572 0 + outer loop + vertex 105.32 105.756 0.5 + vertex 105.684 105.421 -6.5 + vertex 105.32 105.756 -6.5 + endloop + endfacet + facet normal 0.879474 0.475946 0 + outer loop + vertex 105.919 104.987 0.5 + vertex 105.684 105.421 -6.5 + vertex 105.684 105.421 0.5 + endloop + endfacet + facet normal 0.879474 0.475946 0 + outer loop + vertex 105.684 105.421 -6.5 + vertex 105.919 104.987 0.5 + vertex 105.919 104.987 -6.5 + endloop + endfacet + facet normal 0.401692 0.915775 -0 + outer loop + vertex 105.32 105.756 -6.5 + vertex 104.868 105.954 0.5 + vertex 105.32 105.756 0.5 + endloop + endfacet + facet normal 0.401692 0.915775 0 + outer loop + vertex 104.868 105.954 0.5 + vertex 105.32 105.756 -6.5 + vertex 104.868 105.954 -6.5 + endloop + endfacet + facet normal -0.789137 0.614218 0 + outer loop + vertex 103.181 105.214 -6.5 + vertex 103.484 105.604 0.5 + vertex 103.484 105.604 -6.5 + endloop + endfacet + facet normal -0.789137 0.614218 0 + outer loop + vertex 103.484 105.604 0.5 + vertex 103.181 105.214 -6.5 + vertex 103.181 105.214 0.5 + endloop + endfacet + facet normal -0.945823 0.324684 0 + outer loop + vertex 103.02 104.747 -6.5 + vertex 103.181 105.214 0.5 + vertex 103.181 105.214 -6.5 + endloop + endfacet + facet normal -0.945823 0.324684 0 + outer loop + vertex 103.181 105.214 0.5 + vertex 103.02 104.747 -6.5 + vertex 103.02 104.747 0.5 + endloop + endfacet + facet normal -0.245487 0.9694 0 + outer loop + vertex 104.376 105.995 -6.5 + vertex 103.897 105.874 0.5 + vertex 104.376 105.995 0.5 + endloop + endfacet + facet normal -0.245487 0.9694 0 + outer loop + vertex 103.897 105.874 0.5 + vertex 104.376 105.995 -6.5 + vertex 103.897 105.874 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.919 104.013 -6.5 + vertex 105.919 104.987 -6.5 + vertex 106 104.5 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.684 103.579 -6.5 + vertex 105.919 104.987 -6.5 + vertex 105.919 104.013 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.684 103.579 -6.5 + vertex 105.684 105.421 -6.5 + vertex 105.919 104.987 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.32 103.244 -6.5 + vertex 105.684 105.421 -6.5 + vertex 105.684 103.579 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.32 103.244 -6.5 + vertex 105.32 105.756 -6.5 + vertex 105.684 105.421 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.868 103.046 -6.5 + vertex 105.32 105.756 -6.5 + vertex 105.32 103.244 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.868 103.046 -6.5 + vertex 104.868 105.954 -6.5 + vertex 105.32 105.756 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.376 103.005 -6.5 + vertex 104.868 105.954 -6.5 + vertex 104.868 103.046 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.376 103.005 -6.5 + vertex 104.376 105.995 -6.5 + vertex 104.868 105.954 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.897 103.126 -6.5 + vertex 104.376 105.995 -6.5 + vertex 104.376 103.005 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.897 103.126 -6.5 + vertex 103.897 105.874 -6.5 + vertex 104.376 105.995 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.484 103.396 -6.5 + vertex 103.897 105.874 -6.5 + vertex 103.897 103.126 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.484 103.396 -6.5 + vertex 103.484 105.604 -6.5 + vertex 103.897 105.874 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.181 103.786 -6.5 + vertex 103.484 105.604 -6.5 + vertex 103.484 103.396 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.181 103.786 -6.5 + vertex 103.181 105.214 -6.5 + vertex 103.484 105.604 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.02 104.253 -6.5 + vertex 103.181 105.214 -6.5 + vertex 103.181 103.786 -6.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.181 105.214 -6.5 + vertex 103.02 104.253 -6.5 + vertex 103.02 104.747 -6.5 + endloop + endfacet + facet normal -0.546943 0.83717 0 + outer loop + vertex 103.897 105.874 -6.5 + vertex 103.484 105.604 0.5 + vertex 103.897 105.874 0.5 + endloop + endfacet + facet normal -0.546943 0.83717 0 + outer loop + vertex 103.484 105.604 0.5 + vertex 103.897 105.874 -6.5 + vertex 103.484 105.604 -6.5 + endloop + endfacet + facet normal 0.98636 -0.164599 0 + outer loop + vertex 105.919 104.013 0.5 + vertex 106 104.5 -6.5 + vertex 106 104.5 0.5 + endloop + endfacet + facet normal 0.98636 -0.164599 0 + outer loop + vertex 106 104.5 -6.5 + vertex 105.919 104.013 0.5 + vertex 105.919 104.013 -6.5 + endloop + endfacet + facet normal 0.677285 -0.73572 0 + outer loop + vertex 105.32 103.244 -6.5 + vertex 105.684 103.579 0.5 + vertex 105.32 103.244 0.5 + endloop + endfacet + facet normal 0.677285 -0.73572 0 + outer loop + vertex 105.684 103.579 0.5 + vertex 105.32 103.244 -6.5 + vertex 105.684 103.579 -6.5 + endloop + endfacet + facet normal 0.879474 -0.475946 0 + outer loop + vertex 105.684 103.579 0.5 + vertex 105.919 104.013 -6.5 + vertex 105.919 104.013 0.5 + endloop + endfacet + facet normal 0.879474 -0.475946 0 + outer loop + vertex 105.919 104.013 -6.5 + vertex 105.684 103.579 0.5 + vertex 105.684 103.579 -6.5 + endloop + endfacet + facet normal -0.245487 -0.9694 0 + outer loop + vertex 103.897 103.126 -6.5 + vertex 104.376 103.005 0.5 + vertex 103.897 103.126 0.5 + endloop + endfacet + facet normal -0.245487 -0.9694 -0 + outer loop + vertex 104.376 103.005 0.5 + vertex 103.897 103.126 -6.5 + vertex 104.376 103.005 -6.5 + endloop + endfacet + facet normal -0.789137 -0.614218 0 + outer loop + vertex 103.484 103.396 -6.5 + vertex 103.181 103.786 0.5 + vertex 103.181 103.786 -6.5 + endloop + endfacet + facet normal -0.789137 -0.614218 0 + outer loop + vertex 103.181 103.786 0.5 + vertex 103.484 103.396 -6.5 + vertex 103.484 103.396 0.5 + endloop + endfacet + facet normal -0.945823 -0.324684 0 + outer loop + vertex 103.181 103.786 -6.5 + vertex 103.02 104.253 0.5 + vertex 103.02 104.253 -6.5 + endloop + endfacet + facet normal -0.945823 -0.324684 0 + outer loop + vertex 103.02 104.253 0.5 + vertex 103.181 103.786 -6.5 + vertex 103.181 103.786 0.5 + endloop + endfacet + facet normal -0.546943 -0.83717 0 + outer loop + vertex 103.484 103.396 -6.5 + vertex 103.897 103.126 0.5 + vertex 103.484 103.396 0.5 + endloop + endfacet + facet normal -0.546943 -0.83717 -0 + outer loop + vertex 103.897 103.126 0.5 + vertex 103.484 103.396 -6.5 + vertex 103.897 103.126 -6.5 + endloop + endfacet + facet normal -0.98636 -0.164599 0 + outer loop + vertex 106 104.5 13.5 + vertex 105.919 104.987 20.5 + vertex 105.919 104.987 13.5 + endloop + endfacet + facet normal -0.98636 -0.164599 0 + outer loop + vertex 105.919 104.987 20.5 + vertex 106 104.5 13.5 + vertex 106 104.5 20.5 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex 103.02 104.253 20.5 + vertex 103.02 104.747 13.5 + vertex 103.02 104.747 20.5 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 103.02 104.747 13.5 + vertex 103.02 104.253 20.5 + vertex 103.02 104.253 13.5 + endloop + endfacet + facet normal -0.0825698 -0.996585 0 + outer loop + vertex 104.376 105.995 13.5 + vertex 104.868 105.954 20.5 + vertex 104.376 105.995 20.5 + endloop + endfacet + facet normal -0.0825698 -0.996585 -0 + outer loop + vertex 104.868 105.954 20.5 + vertex 104.376 105.995 13.5 + vertex 104.868 105.954 13.5 + endloop + endfacet + facet normal -0.0825698 0.996585 0 + outer loop + vertex 104.868 103.046 13.5 + vertex 104.376 103.005 20.5 + vertex 104.868 103.046 20.5 + endloop + endfacet + facet normal -0.0825698 0.996585 0 + outer loop + vertex 104.376 103.005 20.5 + vertex 104.868 103.046 13.5 + vertex 104.376 103.005 13.5 + endloop + endfacet + facet normal -0.401692 0.915775 0 + outer loop + vertex 105.32 103.244 13.5 + vertex 104.868 103.046 20.5 + vertex 105.32 103.244 20.5 + endloop + endfacet + facet normal -0.401692 0.915775 0 + outer loop + vertex 104.868 103.046 20.5 + vertex 105.32 103.244 13.5 + vertex 104.868 103.046 13.5 + endloop + endfacet + facet normal -0.677285 -0.73572 0 + outer loop + vertex 105.32 105.756 13.5 + vertex 105.684 105.421 20.5 + vertex 105.32 105.756 20.5 + endloop + endfacet + facet normal -0.677285 -0.73572 -0 + outer loop + vertex 105.684 105.421 20.5 + vertex 105.32 105.756 13.5 + vertex 105.684 105.421 13.5 + endloop + endfacet + facet normal -0.879474 -0.475946 0 + outer loop + vertex 105.919 104.987 13.5 + vertex 105.684 105.421 20.5 + vertex 105.684 105.421 13.5 + endloop + endfacet + facet normal -0.879474 -0.475946 0 + outer loop + vertex 105.684 105.421 20.5 + vertex 105.919 104.987 13.5 + vertex 105.919 104.987 20.5 + endloop + endfacet + facet normal -0.401692 -0.915775 0 + outer loop + vertex 104.868 105.954 13.5 + vertex 105.32 105.756 20.5 + vertex 104.868 105.954 20.5 + endloop + endfacet + facet normal -0.401692 -0.915775 -0 + outer loop + vertex 105.32 105.756 20.5 + vertex 104.868 105.954 13.5 + vertex 105.32 105.756 13.5 + endloop + endfacet + facet normal 0.789137 -0.614218 0 + outer loop + vertex 103.181 105.214 20.5 + vertex 103.484 105.604 13.5 + vertex 103.484 105.604 20.5 + endloop + endfacet + facet normal 0.789137 -0.614218 0 + outer loop + vertex 103.484 105.604 13.5 + vertex 103.181 105.214 20.5 + vertex 103.181 105.214 13.5 + endloop + endfacet + facet normal 0.945823 -0.324684 0 + outer loop + vertex 103.02 104.747 20.5 + vertex 103.181 105.214 13.5 + vertex 103.181 105.214 20.5 + endloop + endfacet + facet normal 0.945823 -0.324684 0 + outer loop + vertex 103.181 105.214 13.5 + vertex 103.02 104.747 20.5 + vertex 103.02 104.747 13.5 + endloop + endfacet + facet normal 0.245487 -0.9694 0 + outer loop + vertex 103.897 105.874 13.5 + vertex 104.376 105.995 20.5 + vertex 103.897 105.874 20.5 + endloop + endfacet + facet normal 0.245487 -0.9694 0 + outer loop + vertex 104.376 105.995 20.5 + vertex 103.897 105.874 13.5 + vertex 104.376 105.995 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.919 104.987 13.5 + vertex 105.99 104.5 13.5 + vertex 106 104.5 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.919 104.987 13.5 + vertex 105.909 104.984 13.5 + vertex 105.99 104.5 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.684 105.421 13.5 + vertex 105.909 104.984 13.5 + vertex 105.919 104.987 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.684 105.421 13.5 + vertex 105.676 105.415 13.5 + vertex 105.909 104.984 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.32 105.756 13.5 + vertex 105.676 105.415 13.5 + vertex 105.684 105.421 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.32 105.756 13.5 + vertex 105.315 105.747 13.5 + vertex 105.676 105.415 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 104.868 105.954 13.5 + vertex 105.315 105.747 13.5 + vertex 105.32 105.756 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 104.868 105.954 13.5 + vertex 104.866 105.944 13.5 + vertex 105.315 105.747 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 104.868 105.954 13.5 + vertex 104.377 105.985 13.5 + vertex 104.866 105.944 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 104.376 105.995 13.5 + vertex 104.377 105.985 13.5 + vertex 104.868 105.954 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 104.376 105.995 13.5 + vertex 103.901 105.865 13.5 + vertex 104.377 105.985 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 103.897 105.874 13.5 + vertex 103.901 105.865 13.5 + vertex 104.376 105.995 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.897 105.874 13.5 + vertex 103.491 105.596 13.5 + vertex 103.901 105.865 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 103.484 105.604 13.5 + vertex 103.491 105.596 13.5 + vertex 103.897 105.874 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.484 105.604 13.5 + vertex 103.19 105.209 13.5 + vertex 103.491 105.596 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 103.181 105.214 13.5 + vertex 103.19 105.209 13.5 + vertex 103.484 105.604 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.181 105.214 13.5 + vertex 103.03 104.745 13.5 + vertex 103.19 105.209 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.03 104.745 13.5 + vertex 103.02 104.747 13.5 + vertex 103.03 104.255 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 103.02 104.747 13.5 + vertex 103.03 104.745 13.5 + vertex 103.181 105.214 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 105.99 104.5 13.5 + vertex 105.919 104.013 13.5 + vertex 106 104.5 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 105.909 104.016 13.5 + vertex 105.919 104.013 13.5 + vertex 105.99 104.5 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.909 104.016 13.5 + vertex 105.684 103.579 13.5 + vertex 105.919 104.013 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 105.676 103.585 13.5 + vertex 105.684 103.579 13.5 + vertex 105.909 104.016 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.676 103.585 13.5 + vertex 105.32 103.244 13.5 + vertex 105.684 103.579 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 105.315 103.253 13.5 + vertex 105.32 103.244 13.5 + vertex 105.676 103.585 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.315 103.253 13.5 + vertex 104.868 103.046 13.5 + vertex 105.32 103.244 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 104.866 103.056 13.5 + vertex 104.868 103.046 13.5 + vertex 105.315 103.253 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 104.377 103.015 13.5 + vertex 104.868 103.046 13.5 + vertex 104.866 103.056 13.5 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 104.377 103.015 13.5 + vertex 104.376 103.005 13.5 + vertex 104.868 103.046 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.901 103.135 13.5 + vertex 104.376 103.005 13.5 + vertex 104.377 103.015 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.901 103.135 13.5 + vertex 103.897 103.126 13.5 + vertex 104.376 103.005 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.491 103.404 13.5 + vertex 103.897 103.126 13.5 + vertex 103.901 103.135 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.491 103.404 13.5 + vertex 103.484 103.396 13.5 + vertex 103.897 103.126 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.19 103.791 13.5 + vertex 103.484 103.396 13.5 + vertex 103.491 103.404 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.19 103.791 13.5 + vertex 103.181 103.786 13.5 + vertex 103.484 103.396 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.03 104.255 13.5 + vertex 103.181 103.786 13.5 + vertex 103.19 103.791 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.03 104.255 13.5 + vertex 103.02 104.253 13.5 + vertex 103.181 103.786 13.5 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.02 104.253 13.5 + vertex 103.03 104.255 13.5 + vertex 103.02 104.747 13.5 + endloop + endfacet + facet normal 0.546943 -0.83717 0 + outer loop + vertex 103.484 105.604 13.5 + vertex 103.897 105.874 20.5 + vertex 103.484 105.604 20.5 + endloop + endfacet + facet normal 0.546943 -0.83717 0 + outer loop + vertex 103.897 105.874 20.5 + vertex 103.484 105.604 13.5 + vertex 103.897 105.874 13.5 + endloop + endfacet + facet normal -0.98636 0.164599 0 + outer loop + vertex 105.919 104.013 13.5 + vertex 106 104.5 20.5 + vertex 106 104.5 13.5 + endloop + endfacet + facet normal -0.98636 0.164599 0 + outer loop + vertex 106 104.5 20.5 + vertex 105.919 104.013 13.5 + vertex 105.919 104.013 20.5 + endloop + endfacet + facet normal 0.945823 0.324684 0 + outer loop + vertex 103.181 103.786 20.5 + vertex 103.02 104.253 13.5 + vertex 103.02 104.253 20.5 + endloop + endfacet + facet normal 0.945823 0.324684 0 + outer loop + vertex 103.02 104.253 13.5 + vertex 103.181 103.786 20.5 + vertex 103.181 103.786 13.5 + endloop + endfacet + facet normal -0.677285 0.73572 0 + outer loop + vertex 105.684 103.579 13.5 + vertex 105.32 103.244 20.5 + vertex 105.684 103.579 20.5 + endloop + endfacet + facet normal -0.677285 0.73572 0 + outer loop + vertex 105.32 103.244 20.5 + vertex 105.684 103.579 13.5 + vertex 105.32 103.244 13.5 + endloop + endfacet + facet normal -0.879474 0.475946 0 + outer loop + vertex 105.684 103.579 13.5 + vertex 105.919 104.013 20.5 + vertex 105.919 104.013 13.5 + endloop + endfacet + facet normal -0.879474 0.475946 0 + outer loop + vertex 105.919 104.013 20.5 + vertex 105.684 103.579 13.5 + vertex 105.684 103.579 20.5 + endloop + endfacet + facet normal 0.245487 0.9694 -0 + outer loop + vertex 104.376 103.005 13.5 + vertex 103.897 103.126 20.5 + vertex 104.376 103.005 20.5 + endloop + endfacet + facet normal 0.245487 0.9694 0 + outer loop + vertex 103.897 103.126 20.5 + vertex 104.376 103.005 13.5 + vertex 103.897 103.126 13.5 + endloop + endfacet + facet normal 0.789137 0.614218 0 + outer loop + vertex 103.484 103.396 20.5 + vertex 103.181 103.786 13.5 + vertex 103.181 103.786 20.5 + endloop + endfacet + facet normal 0.789137 0.614218 0 + outer loop + vertex 103.181 103.786 13.5 + vertex 103.484 103.396 20.5 + vertex 103.484 103.396 13.5 + endloop + endfacet + facet normal 0.546943 0.83717 -0 + outer loop + vertex 103.897 103.126 13.5 + vertex 103.484 103.396 20.5 + vertex 103.897 103.126 20.5 + endloop + endfacet + facet normal 0.546943 0.83717 0 + outer loop + vertex 103.484 103.396 20.5 + vertex 103.897 103.126 13.5 + vertex 103.484 103.396 13.5 + endloop + endfacet + facet normal 0.995974 0.0896469 0 + outer loop + vertex 107.25 104.5 25.08 + vertex 107.206 104.991 22.1 + vertex 107.206 104.991 25.08 + endloop + endfacet + facet normal 0.995974 0.0896469 0 + outer loop + vertex 107.206 104.991 22.1 + vertex 107.25 104.5 25.08 + vertex 107.25 104.5 22.1 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex 101.761 104.253 22.1 + vertex 101.761 104.747 25.08 + vertex 101.761 104.747 22.1 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex 101.761 104.747 25.08 + vertex 101.761 104.253 22.1 + vertex 101.761 104.253 25.08 + endloop + endfacet + facet normal 0.0448622 0.998993 -0 + outer loop + vertex 104.869 107.225 22.1 + vertex 104.377 107.247 25.08 + vertex 104.869 107.225 25.08 + endloop + endfacet + facet normal 0.0448622 0.998993 0 + outer loop + vertex 104.377 107.247 25.08 + vertex 104.869 107.225 22.1 + vertex 104.377 107.247 22.1 + endloop + endfacet + facet normal 0.0448622 -0.998993 0 + outer loop + vertex 104.377 101.753 22.1 + vertex 104.869 101.775 25.08 + vertex 104.377 101.753 25.08 + endloop + endfacet + facet normal 0.0448622 -0.998993 0 + outer loop + vertex 104.869 101.775 25.08 + vertex 104.377 101.753 22.1 + vertex 104.869 101.775 22.1 + endloop + endfacet + facet normal 0.809016 -0.587786 0 + outer loop + vertex 106.571 102.691 25.08 + vertex 106.861 103.09 22.1 + vertex 106.861 103.09 25.08 + endloop + endfacet + facet normal 0.809016 -0.587786 0 + outer loop + vertex 106.861 103.09 22.1 + vertex 106.571 102.691 25.08 + vertex 106.571 102.691 22.1 + endloop + endfacet + facet normal 0.691067 0.722791 -0 + outer loop + vertex 106.571 106.309 22.1 + vertex 106.215 106.65 25.08 + vertex 106.571 106.309 25.08 + endloop + endfacet + facet normal 0.691067 0.722791 0 + outer loop + vertex 106.215 106.65 25.08 + vertex 106.571 106.309 22.1 + vertex 106.215 106.65 22.1 + endloop + endfacet + facet normal -0.753075 0.657935 0 + outer loop + vertex 102.275 106.116 22.1 + vertex 102.6 106.488 25.08 + vertex 102.6 106.488 22.1 + endloop + endfacet + facet normal -0.753075 0.657935 0 + outer loop + vertex 102.6 106.488 25.08 + vertex 102.275 106.116 22.1 + vertex 102.275 106.116 25.08 + endloop + endfacet + facet normal -0.47387 0.880595 0 + outer loop + vertex 103.419 107.029 22.1 + vertex 102.985 106.795 25.08 + vertex 103.419 107.029 25.08 + endloop + endfacet + facet normal -0.47387 0.880595 0 + outer loop + vertex 102.985 106.795 25.08 + vertex 103.419 107.029 22.1 + vertex 102.985 106.795 22.1 + endloop + endfacet + facet normal 0.963965 -0.26603 0 + outer loop + vertex 107.075 103.534 25.08 + vertex 107.206 104.009 22.1 + vertex 107.206 104.009 25.08 + endloop + endfacet + facet normal 0.963965 -0.26603 0 + outer loop + vertex 107.206 104.009 22.1 + vertex 107.075 103.534 25.08 + vertex 107.075 103.534 22.1 + endloop + endfacet + facet normal 0.90097 0.433881 0 + outer loop + vertex 107.075 105.466 25.08 + vertex 106.861 105.91 22.1 + vertex 106.861 105.91 25.08 + endloop + endfacet + facet normal 0.90097 0.433881 0 + outer loop + vertex 106.861 105.91 22.1 + vertex 107.075 105.466 25.08 + vertex 107.075 105.466 22.1 + endloop + endfacet + facet normal 0.963965 0.26603 0 + outer loop + vertex 107.206 104.991 25.08 + vertex 107.075 105.466 22.1 + vertex 107.075 105.466 25.08 + endloop + endfacet + facet normal 0.963965 0.26603 0 + outer loop + vertex 107.075 105.466 22.1 + vertex 107.206 104.991 25.08 + vertex 107.206 104.991 22.1 + endloop + endfacet + facet normal 0.809016 0.587786 0 + outer loop + vertex 106.861 105.91 25.08 + vertex 106.571 106.309 22.1 + vertex 106.571 106.309 25.08 + endloop + endfacet + facet normal 0.809016 0.587786 0 + outer loop + vertex 106.571 106.309 22.1 + vertex 106.861 105.91 25.08 + vertex 106.861 105.91 22.1 + endloop + endfacet + facet normal 0.393015 0.919532 -0 + outer loop + vertex 105.803 106.922 22.1 + vertex 105.35 107.115 25.08 + vertex 105.803 106.922 25.08 + endloop + endfacet + facet normal 0.393015 0.919532 0 + outer loop + vertex 105.35 107.115 25.08 + vertex 105.803 106.922 22.1 + vertex 105.35 107.115 22.1 + endloop + endfacet + facet normal 0.222531 0.974926 -0 + outer loop + vertex 105.35 107.115 22.1 + vertex 104.869 107.225 25.08 + vertex 105.35 107.115 25.08 + endloop + endfacet + facet normal 0.222531 0.974926 0 + outer loop + vertex 104.869 107.225 25.08 + vertex 105.35 107.115 22.1 + vertex 104.869 107.225 22.1 + endloop + endfacet + facet normal 0.550891 0.834577 -0 + outer loop + vertex 106.215 106.65 22.1 + vertex 105.803 106.922 25.08 + vertex 106.215 106.65 25.08 + endloop + endfacet + facet normal 0.550891 0.834577 0 + outer loop + vertex 105.803 106.922 25.08 + vertex 106.215 106.65 22.1 + vertex 105.803 106.922 22.1 + endloop + endfacet + facet normal -0.936235 0.351374 0 + outer loop + vertex 101.849 105.232 22.1 + vertex 102.022 105.693 25.08 + vertex 102.022 105.693 22.1 + endloop + endfacet + facet normal -0.936235 0.351374 0 + outer loop + vertex 102.022 105.693 25.08 + vertex 101.849 105.232 22.1 + vertex 101.849 105.232 25.08 + endloop + endfacet + facet normal -0.85845 0.512897 0 + outer loop + vertex 102.022 105.693 22.1 + vertex 102.275 106.116 25.08 + vertex 102.275 106.116 22.1 + endloop + endfacet + facet normal -0.85845 0.512897 0 + outer loop + vertex 102.275 106.116 25.08 + vertex 102.022 105.693 22.1 + vertex 102.022 105.693 25.08 + endloop + endfacet + facet normal -0.983928 0.178565 0 + outer loop + vertex 101.761 104.747 22.1 + vertex 101.849 105.232 25.08 + vertex 101.849 105.232 22.1 + endloop + endfacet + facet normal -0.983928 0.178565 0 + outer loop + vertex 101.849 105.232 25.08 + vertex 101.761 104.747 22.1 + vertex 101.761 104.747 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.943 104.5 25.08 + vertex 107.25 104.5 25.08 + vertex 107.206 104.991 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.943 104.5 25.08 + vertex 107.206 104.991 25.08 + vertex 107.075 105.466 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 107.25 104.5 25.08 + vertex 105.943 104.5 25.08 + vertex 107.206 104.009 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.943 104.5 25.08 + vertex 107.075 105.466 25.08 + vertex 106.861 105.91 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 107.206 104.009 25.08 + vertex 105.943 104.5 25.08 + vertex 107.075 103.534 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.222 105.75 25.08 + vertex 106.861 105.91 25.08 + vertex 106.571 106.309 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 107.075 103.534 25.08 + vertex 105.943 104.5 25.08 + vertex 106.861 103.09 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.222 105.75 25.08 + vertex 106.571 106.309 25.08 + vertex 106.215 106.65 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 105.222 103.25 25.08 + vertex 106.861 103.09 25.08 + vertex 105.943 104.5 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.861 103.09 25.08 + vertex 105.222 103.25 25.08 + vertex 106.571 102.691 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.222 105.75 25.08 + vertex 106.215 106.65 25.08 + vertex 105.803 106.922 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.222 105.75 25.08 + vertex 105.803 106.922 25.08 + vertex 105.35 107.115 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.861 105.91 25.08 + vertex 105.222 105.75 25.08 + vertex 105.943 104.5 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 104.869 107.225 25.08 + vertex 105.222 105.75 25.08 + vertex 105.35 107.115 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 104.377 107.247 25.08 + vertex 105.222 105.75 25.08 + vertex 104.869 107.225 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.778 105.75 25.08 + vertex 104.377 107.247 25.08 + vertex 103.888 107.181 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 104.377 107.247 25.08 + vertex 103.778 105.75 25.08 + vertex 105.222 105.75 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 103.419 107.029 25.08 + vertex 103.778 105.75 25.08 + vertex 103.888 107.181 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 102.985 106.795 25.08 + vertex 103.778 105.75 25.08 + vertex 103.419 107.029 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 102.6 106.488 25.08 + vertex 103.778 105.75 25.08 + vertex 102.985 106.795 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.571 102.691 25.08 + vertex 105.222 103.25 25.08 + vertex 106.215 102.35 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.215 102.35 25.08 + vertex 105.222 103.25 25.08 + vertex 105.803 102.078 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.803 102.078 25.08 + vertex 105.222 103.25 25.08 + vertex 105.35 101.885 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.222 103.25 25.08 + vertex 104.869 101.775 25.08 + vertex 105.35 101.885 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.222 103.25 25.08 + vertex 104.377 101.753 25.08 + vertex 104.869 101.775 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 103.778 103.25 25.08 + vertex 104.377 101.753 25.08 + vertex 105.222 103.25 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 104.377 101.753 25.08 + vertex 103.778 103.25 25.08 + vertex 103.888 101.819 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.778 103.25 25.08 + vertex 103.419 101.971 25.08 + vertex 103.888 101.819 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 102.022 103.307 25.08 + vertex 103.778 103.25 25.08 + vertex 103.057 104.5 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.778 103.25 25.08 + vertex 102.985 102.205 25.08 + vertex 103.419 101.971 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 102.275 106.116 25.08 + vertex 103.778 105.75 25.08 + vertex 102.6 106.488 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 102.022 105.693 25.08 + vertex 103.778 105.75 25.08 + vertex 102.275 106.116 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.778 103.25 25.08 + vertex 102.6 102.512 25.08 + vertex 102.985 102.205 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.778 105.75 25.08 + vertex 102.022 105.693 25.08 + vertex 103.057 104.5 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.778 103.25 25.08 + vertex 102.275 102.884 25.08 + vertex 102.6 102.512 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 101.849 105.232 25.08 + vertex 103.057 104.5 25.08 + vertex 102.022 105.693 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.778 103.25 25.08 + vertex 102.022 103.307 25.08 + vertex 102.275 102.884 25.08 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 101.761 104.747 25.08 + vertex 103.057 104.5 25.08 + vertex 101.849 105.232 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.057 104.5 25.08 + vertex 101.849 103.768 25.08 + vertex 102.022 103.307 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 101.761 104.253 25.08 + vertex 103.057 104.5 25.08 + vertex 101.761 104.747 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.057 104.5 25.08 + vertex 101.761 104.253 25.08 + vertex 101.849 103.768 25.08 + endloop + endfacet + facet normal -0.62349 0.781831 0 + outer loop + vertex 102.985 106.795 22.1 + vertex 102.6 106.488 25.08 + vertex 102.985 106.795 25.08 + endloop + endfacet + facet normal -0.62349 0.781831 0 + outer loop + vertex 102.6 106.488 25.08 + vertex 102.985 106.795 22.1 + vertex 102.6 106.488 22.1 + endloop + endfacet + facet normal -0.134229 0.99095 0 + outer loop + vertex 104.377 107.247 22.1 + vertex 103.888 107.181 25.08 + vertex 104.377 107.247 25.08 + endloop + endfacet + facet normal -0.134229 0.99095 0 + outer loop + vertex 103.888 107.181 25.08 + vertex 104.377 107.247 22.1 + vertex 103.888 107.181 22.1 + endloop + endfacet + facet normal 0.995974 -0.0896469 0 + outer loop + vertex 107.206 104.009 25.08 + vertex 107.25 104.5 22.1 + vertex 107.25 104.5 25.08 + endloop + endfacet + facet normal 0.995974 -0.0896469 0 + outer loop + vertex 107.25 104.5 22.1 + vertex 107.206 104.009 25.08 + vertex 107.206 104.009 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.99 104.5 22.1 + vertex 107.25 104.5 22.1 + vertex 107.206 104.009 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.909 104.016 22.1 + vertex 107.206 104.009 22.1 + vertex 107.075 103.534 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 107.25 104.5 22.1 + vertex 105.99 104.5 22.1 + vertex 107.206 104.991 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.909 104.016 22.1 + vertex 107.075 103.534 22.1 + vertex 106.861 103.09 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.909 104.984 22.1 + vertex 107.206 104.991 22.1 + vertex 105.99 104.5 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.676 103.585 22.1 + vertex 106.861 103.09 22.1 + vertex 106.571 102.691 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 107.206 104.991 22.1 + vertex 105.909 104.984 22.1 + vertex 107.075 105.466 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.676 103.585 22.1 + vertex 106.571 102.691 22.1 + vertex 106.215 102.35 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 107.075 105.466 22.1 + vertex 105.909 104.984 22.1 + vertex 106.861 105.91 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.676 105.415 22.1 + vertex 106.861 105.91 22.1 + vertex 105.909 104.984 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 107.206 104.009 22.1 + vertex 105.909 104.016 22.1 + vertex 105.99 104.5 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.315 103.253 22.1 + vertex 106.215 102.35 22.1 + vertex 105.803 102.078 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 106.861 103.09 22.1 + vertex 105.676 103.585 22.1 + vertex 105.909 104.016 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.866 103.056 22.1 + vertex 105.803 102.078 22.1 + vertex 105.35 101.885 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 106.215 102.35 22.1 + vertex 105.315 103.253 22.1 + vertex 105.676 103.585 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.866 103.056 22.1 + vertex 105.35 101.885 22.1 + vertex 104.869 101.775 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.803 102.078 22.1 + vertex 104.866 103.056 22.1 + vertex 105.315 103.253 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.869 101.775 22.1 + vertex 104.377 103.015 22.1 + vertex 104.866 103.056 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.377 101.753 22.1 + vertex 104.377 103.015 22.1 + vertex 104.869 101.775 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.888 101.819 22.1 + vertex 104.377 103.015 22.1 + vertex 104.377 101.753 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 104.377 103.015 22.1 + vertex 103.888 101.819 22.1 + vertex 103.901 103.135 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.419 101.971 22.1 + vertex 103.901 103.135 22.1 + vertex 103.888 101.819 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 102.985 102.205 22.1 + vertex 103.901 103.135 22.1 + vertex 103.419 101.971 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 103.901 103.135 22.1 + vertex 102.985 102.205 22.1 + vertex 103.491 103.404 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 102.6 102.512 22.1 + vertex 103.491 103.404 22.1 + vertex 102.985 102.205 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 103.491 103.404 22.1 + vertex 102.275 102.884 22.1 + vertex 103.19 103.791 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 102.275 102.884 22.1 + vertex 103.491 103.404 22.1 + vertex 102.6 102.512 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 106.861 105.91 22.1 + vertex 105.676 105.415 22.1 + vertex 106.571 106.309 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 106.571 106.309 22.1 + vertex 105.676 105.415 22.1 + vertex 106.215 106.65 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 105.315 105.747 22.1 + vertex 106.215 106.65 22.1 + vertex 105.676 105.415 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 106.215 106.65 22.1 + vertex 105.315 105.747 22.1 + vertex 105.803 106.922 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.866 105.944 22.1 + vertex 105.803 106.922 22.1 + vertex 105.315 105.747 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 105.803 106.922 22.1 + vertex 104.866 105.944 22.1 + vertex 105.35 107.115 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 105.35 107.115 22.1 + vertex 104.866 105.944 22.1 + vertex 104.869 107.225 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.377 105.985 22.1 + vertex 104.869 107.225 22.1 + vertex 104.866 105.944 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.377 105.985 22.1 + vertex 104.377 107.247 22.1 + vertex 104.869 107.225 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.888 107.181 22.1 + vertex 104.377 105.985 22.1 + vertex 103.901 105.865 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 104.377 105.985 22.1 + vertex 103.888 107.181 22.1 + vertex 104.377 107.247 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 102.985 106.795 22.1 + vertex 103.901 105.865 22.1 + vertex 103.491 105.596 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.901 105.865 22.1 + vertex 103.419 107.029 22.1 + vertex 103.888 107.181 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 102.275 106.116 22.1 + vertex 103.491 105.596 22.1 + vertex 103.19 105.209 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 101.849 105.232 22.1 + vertex 103.19 105.209 22.1 + vertex 103.03 104.745 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.901 105.865 22.1 + vertex 102.985 106.795 22.1 + vertex 103.419 107.029 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 102.022 103.307 22.1 + vertex 103.19 103.791 22.1 + vertex 102.275 102.884 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 101.849 103.768 22.1 + vertex 103.19 103.791 22.1 + vertex 102.022 103.307 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.491 105.596 22.1 + vertex 102.6 106.488 22.1 + vertex 102.985 106.795 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 103.19 103.791 22.1 + vertex 101.849 103.768 22.1 + vertex 103.03 104.255 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.491 105.596 22.1 + vertex 102.275 106.116 22.1 + vertex 102.6 106.488 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 101.761 104.253 22.1 + vertex 103.03 104.255 22.1 + vertex 101.849 103.768 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.19 105.209 22.1 + vertex 102.022 105.693 22.1 + vertex 102.275 106.116 22.1 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 103.03 104.255 22.1 + vertex 101.761 104.253 22.1 + vertex 103.03 104.745 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.19 105.209 22.1 + vertex 101.849 105.232 22.1 + vertex 102.022 105.693 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 101.761 104.747 22.1 + vertex 103.03 104.745 22.1 + vertex 101.761 104.253 22.1 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 103.03 104.745 22.1 + vertex 101.761 104.747 22.1 + vertex 101.849 105.232 22.1 + endloop + endfacet + facet normal 0.222531 -0.974926 0 + outer loop + vertex 104.869 101.775 22.1 + vertex 105.35 101.885 25.08 + vertex 104.869 101.775 25.08 + endloop + endfacet + facet normal 0.222531 -0.974926 0 + outer loop + vertex 105.35 101.885 25.08 + vertex 104.869 101.775 22.1 + vertex 105.35 101.885 22.1 + endloop + endfacet + facet normal -0.309018 0.951056 0 + outer loop + vertex 103.888 107.181 22.1 + vertex 103.419 107.029 25.08 + vertex 103.888 107.181 25.08 + endloop + endfacet + facet normal -0.309018 0.951056 0 + outer loop + vertex 103.419 107.029 25.08 + vertex 103.888 107.181 22.1 + vertex 103.419 107.029 22.1 + endloop + endfacet + facet normal 0.90097 -0.433881 0 + outer loop + vertex 106.861 103.09 25.08 + vertex 107.075 103.534 22.1 + vertex 107.075 103.534 25.08 + endloop + endfacet + facet normal 0.90097 -0.433881 0 + outer loop + vertex 107.075 103.534 22.1 + vertex 106.861 103.09 25.08 + vertex 106.861 103.09 22.1 + endloop + endfacet + facet normal -0.85845 -0.512897 0 + outer loop + vertex 102.275 102.884 22.1 + vertex 102.022 103.307 25.08 + vertex 102.022 103.307 22.1 + endloop + endfacet + facet normal -0.85845 -0.512897 0 + outer loop + vertex 102.022 103.307 25.08 + vertex 102.275 102.884 22.1 + vertex 102.275 102.884 25.08 + endloop + endfacet + facet normal -0.983928 -0.178565 0 + outer loop + vertex 101.849 103.768 22.1 + vertex 101.761 104.253 25.08 + vertex 101.761 104.253 22.1 + endloop + endfacet + facet normal -0.983928 -0.178565 0 + outer loop + vertex 101.761 104.253 25.08 + vertex 101.849 103.768 22.1 + vertex 101.849 103.768 25.08 + endloop + endfacet + facet normal 0.550891 -0.834577 0 + outer loop + vertex 105.803 102.078 22.1 + vertex 106.215 102.35 25.08 + vertex 105.803 102.078 25.08 + endloop + endfacet + facet normal 0.550891 -0.834577 0 + outer loop + vertex 106.215 102.35 25.08 + vertex 105.803 102.078 22.1 + vertex 106.215 102.35 22.1 + endloop + endfacet + facet normal 0.393015 -0.919532 0 + outer loop + vertex 105.35 101.885 22.1 + vertex 105.803 102.078 25.08 + vertex 105.35 101.885 25.08 + endloop + endfacet + facet normal 0.393015 -0.919532 0 + outer loop + vertex 105.803 102.078 25.08 + vertex 105.35 101.885 22.1 + vertex 105.803 102.078 22.1 + endloop + endfacet + facet normal -0.47387 -0.880595 0 + outer loop + vertex 102.985 102.205 22.1 + vertex 103.419 101.971 25.08 + vertex 102.985 102.205 25.08 + endloop + endfacet + facet normal -0.47387 -0.880595 -0 + outer loop + vertex 103.419 101.971 25.08 + vertex 102.985 102.205 22.1 + vertex 103.419 101.971 22.1 + endloop + endfacet + facet normal -0.309018 -0.951056 0 + outer loop + vertex 103.419 101.971 22.1 + vertex 103.888 101.819 25.08 + vertex 103.419 101.971 25.08 + endloop + endfacet + facet normal -0.309018 -0.951056 -0 + outer loop + vertex 103.888 101.819 25.08 + vertex 103.419 101.971 22.1 + vertex 103.888 101.819 22.1 + endloop + endfacet + facet normal -0.134229 -0.99095 0 + outer loop + vertex 103.888 101.819 22.1 + vertex 104.377 101.753 25.08 + vertex 103.888 101.819 25.08 + endloop + endfacet + facet normal -0.134229 -0.99095 -0 + outer loop + vertex 104.377 101.753 25.08 + vertex 103.888 101.819 22.1 + vertex 104.377 101.753 22.1 + endloop + endfacet + facet normal -0.936235 -0.351374 0 + outer loop + vertex 102.022 103.307 22.1 + vertex 101.849 103.768 25.08 + vertex 101.849 103.768 22.1 + endloop + endfacet + facet normal -0.936235 -0.351374 0 + outer loop + vertex 101.849 103.768 25.08 + vertex 102.022 103.307 22.1 + vertex 102.022 103.307 25.08 + endloop + endfacet + facet normal 0.691067 -0.722791 0 + outer loop + vertex 106.215 102.35 22.1 + vertex 106.571 102.691 25.08 + vertex 106.215 102.35 25.08 + endloop + endfacet + facet normal 0.691067 -0.722791 0 + outer loop + vertex 106.571 102.691 25.08 + vertex 106.215 102.35 22.1 + vertex 106.571 102.691 22.1 + endloop + endfacet + facet normal -0.753075 -0.657935 0 + outer loop + vertex 102.6 102.512 22.1 + vertex 102.275 102.884 25.08 + vertex 102.275 102.884 22.1 + endloop + endfacet + facet normal -0.753075 -0.657935 0 + outer loop + vertex 102.275 102.884 25.08 + vertex 102.6 102.512 22.1 + vertex 102.6 102.512 25.08 + endloop + endfacet + facet normal -0.62349 -0.781831 0 + outer loop + vertex 102.6 102.512 22.1 + vertex 102.985 102.205 25.08 + vertex 102.6 102.512 25.08 + endloop + endfacet + facet normal -0.62349 -0.781831 -0 + outer loop + vertex 102.985 102.205 25.08 + vertex 102.6 102.512 22.1 + vertex 102.985 102.205 22.1 + endloop + endfacet + facet normal 0.986363 0.164583 0 + outer loop + vertex 105.99 104.5 20.5 + vertex 105.909 104.984 13.5 + vertex 105.909 104.984 20.5 + endloop + endfacet + facet normal 0.986363 0.164583 0 + outer loop + vertex 105.909 104.984 13.5 + vertex 105.99 104.5 20.5 + vertex 105.99 104.5 13.5 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex 103.03 104.255 13.5 + vertex 103.03 104.745 20.5 + vertex 103.03 104.745 13.5 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex 103.03 104.745 20.5 + vertex 103.03 104.255 13.5 + vertex 103.03 104.255 20.5 + endloop + endfacet + facet normal -0.245484 0.969401 0 + outer loop + vertex 104.377 105.985 13.5 + vertex 103.901 105.865 20.5 + vertex 104.377 105.985 20.5 + endloop + endfacet + facet normal -0.245484 0.969401 0 + outer loop + vertex 103.901 105.865 20.5 + vertex 104.377 105.985 13.5 + vertex 103.901 105.865 13.5 + endloop + endfacet + facet normal 0.0825782 -0.996585 0 + outer loop + vertex 104.377 103.015 13.5 + vertex 104.866 103.056 20.5 + vertex 104.377 103.015 20.5 + endloop + endfacet + facet normal 0.0825782 -0.996585 0 + outer loop + vertex 104.866 103.056 20.5 + vertex 104.377 103.015 13.5 + vertex 104.866 103.056 13.5 + endloop + endfacet + facet normal 0.401702 0.915771 -0 + outer loop + vertex 105.315 105.747 13.5 + vertex 104.866 105.944 20.5 + vertex 105.315 105.747 20.5 + endloop + endfacet + facet normal 0.401702 0.915771 0 + outer loop + vertex 104.866 105.944 20.5 + vertex 105.315 105.747 13.5 + vertex 104.866 105.944 13.5 + endloop + endfacet + facet normal 0.0825782 0.996585 -0 + outer loop + vertex 104.866 105.944 13.5 + vertex 104.377 105.985 20.5 + vertex 104.866 105.944 20.5 + endloop + endfacet + facet normal 0.0825782 0.996585 0 + outer loop + vertex 104.377 105.985 20.5 + vertex 104.866 105.944 13.5 + vertex 104.377 105.985 13.5 + endloop + endfacet + facet normal -0.789139 0.614214 0 + outer loop + vertex 103.19 105.209 13.5 + vertex 103.491 105.596 20.5 + vertex 103.491 105.596 13.5 + endloop + endfacet + facet normal -0.789139 0.614214 0 + outer loop + vertex 103.491 105.596 20.5 + vertex 103.19 105.209 13.5 + vertex 103.19 105.209 20.5 + endloop + endfacet + facet normal -0.945816 0.324703 0 + outer loop + vertex 103.03 104.745 13.5 + vertex 103.19 105.209 20.5 + vertex 103.19 105.209 13.5 + endloop + endfacet + facet normal -0.945816 0.324703 0 + outer loop + vertex 103.19 105.209 20.5 + vertex 103.03 104.745 13.5 + vertex 103.03 104.745 20.5 + endloop + endfacet + facet normal -0.546948 0.837167 0 + outer loop + vertex 103.901 105.865 13.5 + vertex 103.491 105.596 20.5 + vertex 103.901 105.865 20.5 + endloop + endfacet + facet normal -0.546948 0.837167 0 + outer loop + vertex 103.491 105.596 20.5 + vertex 103.901 105.865 13.5 + vertex 103.491 105.596 13.5 + endloop + endfacet + facet normal -0.245484 -0.969401 0 + outer loop + vertex 103.901 103.135 13.5 + vertex 104.377 103.015 20.5 + vertex 103.901 103.135 20.5 + endloop + endfacet + facet normal -0.245484 -0.969401 -0 + outer loop + vertex 104.377 103.015 20.5 + vertex 103.901 103.135 13.5 + vertex 104.377 103.015 13.5 + endloop + endfacet + facet normal 0.677276 0.735729 -0 + outer loop + vertex 105.676 105.415 13.5 + vertex 105.315 105.747 20.5 + vertex 105.676 105.415 20.5 + endloop + endfacet + facet normal 0.677276 0.735729 0 + outer loop + vertex 105.315 105.747 20.5 + vertex 105.676 105.415 13.5 + vertex 105.315 105.747 13.5 + endloop + endfacet + facet normal 0.87947 0.475954 0 + outer loop + vertex 105.909 104.984 20.5 + vertex 105.676 105.415 13.5 + vertex 105.676 105.415 20.5 + endloop + endfacet + facet normal 0.87947 0.475954 0 + outer loop + vertex 105.676 105.415 13.5 + vertex 105.909 104.984 20.5 + vertex 105.909 104.984 13.5 + endloop + endfacet + facet normal 0.401702 -0.915771 0 + outer loop + vertex 104.866 103.056 13.5 + vertex 105.315 103.253 20.5 + vertex 104.866 103.056 20.5 + endloop + endfacet + facet normal 0.401702 -0.915771 0 + outer loop + vertex 105.315 103.253 20.5 + vertex 104.866 103.056 13.5 + vertex 105.315 103.253 13.5 + endloop + endfacet + facet normal 0.986363 -0.164583 0 + outer loop + vertex 105.909 104.016 20.5 + vertex 105.99 104.5 13.5 + vertex 105.99 104.5 20.5 + endloop + endfacet + facet normal 0.986363 -0.164583 0 + outer loop + vertex 105.99 104.5 13.5 + vertex 105.909 104.016 20.5 + vertex 105.909 104.016 13.5 + endloop + endfacet + facet normal -0.546948 -0.837167 0 + outer loop + vertex 103.491 103.404 13.5 + vertex 103.901 103.135 20.5 + vertex 103.491 103.404 20.5 + endloop + endfacet + facet normal -0.546948 -0.837167 -0 + outer loop + vertex 103.901 103.135 20.5 + vertex 103.491 103.404 13.5 + vertex 103.901 103.135 13.5 + endloop + endfacet + facet normal -0.945816 -0.324703 0 + outer loop + vertex 103.19 103.791 13.5 + vertex 103.03 104.255 20.5 + vertex 103.03 104.255 13.5 + endloop + endfacet + facet normal -0.945816 -0.324703 0 + outer loop + vertex 103.03 104.255 20.5 + vertex 103.19 103.791 13.5 + vertex 103.19 103.791 20.5 + endloop + endfacet + facet normal 0.677276 -0.735729 0 + outer loop + vertex 105.315 103.253 13.5 + vertex 105.676 103.585 20.5 + vertex 105.315 103.253 20.5 + endloop + endfacet + facet normal 0.677276 -0.735729 0 + outer loop + vertex 105.676 103.585 20.5 + vertex 105.315 103.253 13.5 + vertex 105.676 103.585 13.5 + endloop + endfacet + facet normal -0.789139 -0.614214 0 + outer loop + vertex 103.491 103.404 13.5 + vertex 103.19 103.791 20.5 + vertex 103.19 103.791 13.5 + endloop + endfacet + facet normal -0.789139 -0.614214 0 + outer loop + vertex 103.19 103.791 20.5 + vertex 103.491 103.404 13.5 + vertex 103.491 103.404 20.5 + endloop + endfacet + facet normal 0.87947 -0.475954 0 + outer loop + vertex 105.676 103.585 20.5 + vertex 105.909 104.016 13.5 + vertex 105.909 104.016 20.5 + endloop + endfacet + facet normal 0.87947 -0.475954 0 + outer loop + vertex 105.909 104.016 13.5 + vertex 105.676 103.585 20.5 + vertex 105.676 103.585 13.5 + endloop + endfacet + facet normal -0.866026 -0.5 0 + outer loop + vertex 105.943 104.5 24.0867 + vertex 105.222 105.75 25.08 + vertex 105.222 105.75 24.0867 + endloop + endfacet + facet normal -0.866026 -0.5 0 + outer loop + vertex 105.222 105.75 25.08 + vertex 105.943 104.5 24.0867 + vertex 105.943 104.5 25.08 + endloop + endfacet + facet normal 0.866026 -0.5 0 + outer loop + vertex 103.057 104.5 25.08 + vertex 103.778 105.75 24.0867 + vertex 103.778 105.75 25.08 + endloop + endfacet + facet normal 0.866026 -0.5 0 + outer loop + vertex 103.778 105.75 24.0867 + vertex 103.057 104.5 25.08 + vertex 103.057 104.5 24.0867 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 103.778 105.75 24.0867 + vertex 105.222 105.75 25.08 + vertex 103.778 105.75 25.08 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 105.222 105.75 25.08 + vertex 103.778 105.75 24.0867 + vertex 105.222 105.75 24.0867 + endloop + endfacet + facet normal -0.866026 0.5 0 + outer loop + vertex 105.222 103.25 24.0867 + vertex 105.943 104.5 25.08 + vertex 105.943 104.5 24.0867 + endloop + endfacet + facet normal -0.866026 0.5 0 + outer loop + vertex 105.943 104.5 25.08 + vertex 105.222 103.25 24.0867 + vertex 105.222 103.25 25.08 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.222 105.75 24.0867 + vertex 105.222 103.25 24.0867 + vertex 105.943 104.5 24.0867 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 103.778 105.75 24.0867 + vertex 105.222 103.25 24.0867 + vertex 105.222 105.75 24.0867 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.778 105.75 24.0867 + vertex 103.778 103.25 24.0867 + vertex 105.222 103.25 24.0867 + endloop + endfacet + facet normal 0 -0 1 + outer loop + vertex 103.778 103.25 24.0867 + vertex 103.778 105.75 24.0867 + vertex 103.057 104.5 24.0867 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 105.222 103.25 24.0867 + vertex 103.778 103.25 25.08 + vertex 105.222 103.25 25.08 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 103.778 103.25 25.08 + vertex 105.222 103.25 24.0867 + vertex 103.778 103.25 24.0867 + endloop + endfacet + facet normal 0.866026 0.5 0 + outer loop + vertex 103.778 103.25 25.08 + vertex 103.057 104.5 24.0867 + vertex 103.057 104.5 25.08 + endloop + endfacet + facet normal 0.866026 0.5 0 + outer loop + vertex 103.057 104.5 24.0867 + vertex 103.778 103.25 25.08 + vertex 103.778 103.25 24.0867 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.981 -82 20.5 + vertex -106.981 -82 19.1223 + vertex -107 -82 20.5 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.981 -82 22.13 + vertex -106.981 -82 22.1 + vertex -107 -82 22.13 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -96.3536 -82 26.7428 + vertex -96.4718 -82 27.0143 + vertex -96 -82 26.88 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.8364 -82 26.7428 + vertex -96.4718 -82 27.0143 + vertex -96.3536 -82 26.7428 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.4718 -82 27.0143 + vertex -96.8364 -82 26.7428 + vertex -96.9603 -82 26.969 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -95.9185 -82 26.5333 + vertex -96 -82 26.88 + vertex -95.6084 -82 26.5844 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96 -82 26.88 + vertex -95.9185 -82 26.5333 + vertex -96.3536 -82 26.7428 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.6175 -82 26.1557 + vertex -95.6084 -82 26.5844 + vertex -95.3502 -82 26.1673 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.6084 -82 26.5844 + vertex -95.6175 -82 26.1557 + vertex -95.9185 -82 26.5333 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.51 -82 25.685 + vertex -95.3502 -82 26.1673 + vertex -95.26 -82 25.685 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.3502 -82 26.1673 + vertex -95.51 -82 25.685 + vertex -95.6175 -82 26.1557 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -95.3502 -82 25.2027 + vertex -95.51 -82 25.685 + vertex -95.26 -82 25.685 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.51 -82 25.685 + vertex -95.3502 -82 25.2027 + vertex -95.6175 -82 25.2143 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -95.6084 -82 24.7856 + vertex -95.6175 -82 25.2143 + vertex -95.3502 -82 25.2027 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.6175 -82 25.2143 + vertex -95.6084 -82 24.7856 + vertex -95.9185 -82 24.8367 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96 -82 24.49 + vertex -95.9185 -82 24.8367 + vertex -95.6084 -82 24.7856 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.4718 -82 24.3557 + vertex -96.3536 -82 24.6272 + vertex -96 -82 24.49 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.9185 -82 24.8367 + vertex -96 -82 24.49 + vertex -96.3536 -82 24.6272 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.2715 -82 26.5333 + vertex -96.9603 -82 26.969 + vertex -96.8364 -82 26.7428 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.9603 -82 26.969 + vertex -97.2715 -82 26.5333 + vertex -97.3995 -82 26.7503 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.2715 -82 26.5333 + vertex -97.73 -82 26.3878 + vertex -97.3995 -82 26.7503 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -97.5725 -82 26.1557 + vertex -97.73 -82 26.3878 + vertex -97.2715 -82 26.5333 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5725 -82 26.1557 + vertex -97.9073 -82 25.9303 + vertex -97.73 -82 26.3878 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -97.68 -82 25.685 + vertex -97.9073 -82 25.9303 + vertex -97.5725 -82 26.1557 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.68 -82 25.685 + vertex -97.9073 -82 25.4397 + vertex -97.9073 -82 25.9303 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5725 -82 25.2143 + vertex -97.9073 -82 25.4397 + vertex -97.68 -82 25.685 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5725 -82 25.2143 + vertex -97.73 -82 24.9822 + vertex -97.9073 -82 25.4397 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -97.5295 -82 24.7623 + vertex -97.5725 -82 25.2143 + vertex -97.2715 -82 24.8367 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5725 -82 25.2143 + vertex -97.5295 -82 24.7623 + vertex -97.73 -82 24.9822 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -96.9798 -82 24.4107 + vertex -97.2715 -82 24.8367 + vertex -96.8755 -82 24.646 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.523 -82 25.9943 + vertex -106.139 -82 26.2927 + vertex -106.146 -82 26.04 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5295 -82 24.7623 + vertex -106.146 -82 26.04 + vertex -106.139 -82 26.2927 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.2715 -82 24.8367 + vertex -96.9798 -82 24.4107 + vertex -97.5295 -82 24.7623 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.8872 -82 24.3942 + vertex -96.8755 -82 24.646 + vertex -96.7696 -82 24.6272 + endloop + endfacet + facet normal -0 1 0 + outer loop + vertex -96.605 -82 24.368 + vertex -96.3536 -82 24.6272 + vertex -96.4718 -82 24.3557 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5295 -82 24.7623 + vertex -96.9798 -82 24.4107 + vertex -106.146 -82 26.04 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.8755 -82 24.646 + vertex -96.8872 -82 24.3942 + vertex -96.9798 -82 24.4107 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.9798 -82 24.4107 + vertex -96.8872 -82 24.3942 + vertex -96.9603 -82 24.401 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.7696 -82 24.6272 + vertex -96.605 -82 24.368 + vertex -96.8872 -82 24.3942 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.3536 -82 24.6272 + vertex -96.605 -82 24.368 + vertex -96.7696 -82 24.6272 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.139 -82 26.2927 + vertex -106.523 -82 25.9943 + vertex -106.615 -82 26.235 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.523 -82 25.9943 + vertex -107.009 -82 25.9631 + vertex -106.615 -82 26.235 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -106.816 -82 25.7924 + vertex -107.009 -82 25.9631 + vertex -106.523 -82 25.9943 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.816 -82 25.7924 + vertex -107.231 -82 25.5393 + vertex -107.009 -82 25.9631 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -106.981 -82 25.4777 + vertex -107.231 -82 25.5393 + vertex -106.816 -82 25.7924 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -107 -82 24.13 + vertex -106.981 -82 25.4777 + vertex -106.981 -82 24.13 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.981 -82 25.4777 + vertex -107 -82 24.13 + vertex -107.231 -82 25.5393 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -107 -82 22.13 + vertex -107.231 -82 25.5393 + vertex -107 -82 24.13 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -107 -82 22.1 + vertex -107 -82 22.13 + vertex -106.981 -82 22.1 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -107 -82 22.1 + vertex -107.231 -82 25.5393 + vertex -107 -82 22.13 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -107.231 -82 19.0607 + vertex -107 -82 22.1 + vertex -107 -82 20.5 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -107.231 -82 19.0607 + vertex -107 -82 20.5 + vertex -106.981 -82 19.1223 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -107 -82 22.1 + vertex -107.231 -82 19.0607 + vertex -107.231 -82 25.5393 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.816 -82 18.8076 + vertex -107.231 -82 19.0607 + vertex -106.981 -82 19.1223 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.816 -82 18.8076 + vertex -107.009 -82 18.6369 + vertex -107.231 -82 19.0607 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.523 -82 18.6057 + vertex -107.009 -82 18.6369 + vertex -106.816 -82 18.8076 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.139 -82 18.3073 + vertex -106.523 -82 18.6057 + vertex -106.146 -82 18.56 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.523 -82 18.6057 + vertex -106.615 -82 18.365 + vertex -107.009 -82 18.6369 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.8872 -82 24.3942 + vertex -96.605 -82 24.368 + vertex -96.605 -82 24.344 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.9798 -82 20.1893 + vertex -97.2715 -82 19.7633 + vertex -97.5295 -82 19.8377 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5725 -82 19.3857 + vertex -97.5295 -82 19.8377 + vertex -97.2715 -82 19.7633 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5295 -82 19.8377 + vertex -97.5725 -82 19.3857 + vertex -97.73 -82 19.6178 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5725 -82 19.3857 + vertex -97.9073 -82 19.1603 + vertex -97.73 -82 19.6178 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -97.68 -82 18.915 + vertex -97.9073 -82 19.1603 + vertex -97.5725 -82 19.3857 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.68 -82 18.915 + vertex -97.9073 -82 18.6697 + vertex -97.9073 -82 19.1603 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5725 -82 18.4443 + vertex -97.9073 -82 18.6697 + vertex -97.68 -82 18.915 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5725 -82 18.4443 + vertex -97.73 -82 18.2122 + vertex -97.9073 -82 18.6697 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.2715 -82 18.0667 + vertex -97.73 -82 18.2122 + vertex -97.5725 -82 18.4443 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -96.9603 -82 17.631 + vertex -97.2715 -82 18.0667 + vertex -96.8364 -82 17.8572 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.2715 -82 18.0667 + vertex -97.3995 -82 17.8497 + vertex -97.73 -82 18.2122 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -95.9185 -82 19.7633 + vertex -96 -82 20.11 + vertex -95.6084 -82 19.8144 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96 -82 20.11 + vertex -95.9185 -82 19.7633 + vertex -96.3536 -82 19.9728 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.6175 -82 19.3857 + vertex -95.6084 -82 19.8144 + vertex -95.3502 -82 19.3973 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.6084 -82 19.8144 + vertex -95.6175 -82 19.3857 + vertex -95.9185 -82 19.7633 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.51 -82 18.915 + vertex -95.3502 -82 19.3973 + vertex -95.26 -82 18.915 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.3502 -82 19.3973 + vertex -95.51 -82 18.915 + vertex -95.6175 -82 19.3857 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -95.3502 -82 18.4327 + vertex -95.51 -82 18.915 + vertex -95.26 -82 18.915 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.51 -82 18.915 + vertex -95.3502 -82 18.4327 + vertex -95.6175 -82 18.4443 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -95.6084 -82 18.0156 + vertex -95.6175 -82 18.4443 + vertex -95.3502 -82 18.4327 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.6175 -82 18.4443 + vertex -95.6084 -82 18.0156 + vertex -95.9185 -82 18.0667 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96 -82 17.72 + vertex -95.9185 -82 18.0667 + vertex -95.6084 -82 18.0156 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -96.4718 -82 17.5857 + vertex -96.8364 -82 17.8572 + vertex -96.3536 -82 17.8572 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.9185 -82 18.0667 + vertex -96 -82 17.72 + vertex -96.3536 -82 17.8572 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.4718 -82 17.5857 + vertex -96.3536 -82 17.8572 + vertex -96 -82 17.72 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.2715 -82 18.0667 + vertex -96.9603 -82 17.631 + vertex -97.3995 -82 17.8497 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.8364 -82 17.8572 + vertex -96.4718 -82 17.5857 + vertex -96.9603 -82 17.631 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.8872 -82 20.2058 + vertex -96.9798 -82 20.1893 + vertex -96.9603 -82 20.199 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -96.7696 -82 19.9728 + vertex -96.8872 -82 20.2058 + vertex -96.605 -82 20.232 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.3536 -82 19.9728 + vertex -96.605 -82 20.232 + vertex -96.4718 -82 20.2443 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -96.3536 -82 19.9728 + vertex -96.4718 -82 20.2443 + vertex -96 -82 20.11 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.605 -82 20.232 + vertex -96.3536 -82 19.9728 + vertex -96.7696 -82 19.9728 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -96.8755 -82 19.954 + vertex -96.8872 -82 20.2058 + vertex -96.7696 -82 19.9728 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.8872 -82 20.2058 + vertex -96.8755 -82 19.954 + vertex -96.9798 -82 20.1893 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.2715 -82 19.7633 + vertex -96.9798 -82 20.1893 + vertex -96.8755 -82 19.954 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -97.5295 -82 19.8377 + vertex -106.146 -82 18.56 + vertex -96.9798 -82 20.1893 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -106.139 -82 18.3073 + vertex -106.146 -82 18.56 + vertex -97.5295 -82 19.8377 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.523 -82 18.6057 + vertex -106.139 -82 18.3073 + vertex -106.615 -82 18.365 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.605 -82 20.256 + vertex -96.605 -82 20.232 + vertex -96.8872 -82 20.2058 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -96.605 -101 20.256 + vertex -96.8872 -101 20.2058 + vertex -96.605 -101 20.232 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.981 -101 20.5 + vertex 106.981 -101 19.1223 + vertex 107 -101 20.5 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.8872 -101 24.3942 + vertex -96.605 -101 24.344 + vertex -96.605 -101 24.368 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -106.139 -101 26.2927 + vertex -106.523 -101 25.9943 + vertex -106.146 -101 26.04 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107.009 -101 25.9631 + vertex -106.523 -101 25.9943 + vertex -106.615 -101 26.235 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107.009 -101 25.9631 + vertex -106.816 -101 25.7924 + vertex -106.523 -101 25.9943 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107.231 -101 25.5393 + vertex -106.816 -101 25.7924 + vertex -107.009 -101 25.9631 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107.231 -101 25.5393 + vertex -106.981 -101 25.4777 + vertex -106.816 -101 25.7924 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107.231 -101 25.5393 + vertex -106.981 -101 24.13 + vertex -106.981 -101 25.4777 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -106.981 -101 24.13 + vertex -106.981 -101 22.13 + vertex 106.981 -101 24.13 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107 -101 22.1 + vertex -106.981 -101 24.13 + vertex -107.231 -101 25.5393 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -106.981 -101 24.13 + vertex -107 -101 22.1 + vertex -106.981 -101 22.13 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107.231 -101 19.0607 + vertex -107 -101 22.1 + vertex -107.231 -101 25.5393 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107 -101 20.5 + vertex -106.981 -101 19.1223 + vertex -106.981 -101 20.5 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -107 -101 22.1 + vertex -107.231 -101 19.0607 + vertex -107 -101 20.5 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -107 -101 20.5 + vertex -107.231 -101 19.0607 + vertex -106.981 -101 19.1223 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107.231 -101 19.0607 + vertex -106.816 -101 18.8076 + vertex -106.981 -101 19.1223 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107.009 -101 18.6369 + vertex -106.816 -101 18.8076 + vertex -107.231 -101 19.0607 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107.009 -101 18.6369 + vertex -106.523 -101 18.6057 + vertex -106.816 -101 18.8076 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -106.615 -101 18.365 + vertex -106.523 -101 18.6057 + vertex -107.009 -101 18.6369 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -106.139 -101 18.3073 + vertex -106.523 -101 18.6057 + vertex -106.615 -101 18.365 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -106.523 -101 25.9943 + vertex -106.139 -101 26.2927 + vertex -106.615 -101 26.235 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -106.146 -101 26.04 + vertex -97.5295 -101 24.7623 + vertex -106.139 -101 26.2927 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.9798 -101 24.4107 + vertex -97.5295 -101 24.7623 + vertex -106.146 -101 26.04 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.5295 -101 24.7623 + vertex -96.9798 -101 24.4107 + vertex -96.8755 -101 24.646 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.605 -101 24.368 + vertex -96.3536 -101 24.6272 + vertex -96.7696 -101 24.6272 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.8872 -101 24.3942 + vertex -96.8755 -101 24.646 + vertex -96.9798 -101 24.4107 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -96.8755 -101 24.646 + vertex -96.8872 -101 24.3942 + vertex -96.7696 -101 24.6272 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.8872 -101 24.3942 + vertex -96.9798 -101 24.4107 + vertex -96.9603 -101 24.401 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.605 -101 24.368 + vertex -96.7696 -101 24.6272 + vertex -96.8872 -101 24.3942 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.3536 -101 24.6272 + vertex -96.605 -101 24.368 + vertex -96.4718 -101 24.3557 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -96.3536 -101 24.6272 + vertex -96.4718 -101 24.3557 + vertex -96 -101 24.49 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -96.9603 -101 26.969 + vertex -97.2715 -101 26.5333 + vertex -96.8364 -101 26.7428 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.73 -101 26.3878 + vertex -97.2715 -101 26.5333 + vertex -97.3995 -101 26.7503 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.73 -101 26.3878 + vertex -97.5725 -101 26.1557 + vertex -97.2715 -101 26.5333 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.9073 -101 25.9303 + vertex -97.5725 -101 26.1557 + vertex -97.73 -101 26.3878 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.9073 -101 25.9303 + vertex -97.68 -101 25.685 + vertex -97.5725 -101 26.1557 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.9073 -101 25.4397 + vertex -97.68 -101 25.685 + vertex -97.9073 -101 25.9303 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.9073 -101 25.4397 + vertex -97.5725 -101 25.2143 + vertex -97.68 -101 25.685 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.73 -101 24.9822 + vertex -97.5725 -101 25.2143 + vertex -97.9073 -101 25.4397 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.5295 -101 24.7623 + vertex -97.5725 -101 25.2143 + vertex -97.73 -101 24.9822 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.5725 -101 25.2143 + vertex -97.5295 -101 24.7623 + vertex -97.2715 -101 24.8367 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -97.2715 -101 24.8367 + vertex -97.5295 -101 24.7623 + vertex -96.8755 -101 24.646 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.8364 -101 26.7428 + vertex -96.4718 -101 27.0143 + vertex -96.9603 -101 26.969 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.2715 -101 26.5333 + vertex -96.9603 -101 26.969 + vertex -97.3995 -101 26.7503 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -96.4718 -101 27.0143 + vertex -96.8364 -101 26.7428 + vertex -96.3536 -101 26.7428 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.4718 -101 27.0143 + vertex -96.3536 -101 26.7428 + vertex -96 -101 26.88 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.9185 -101 26.5333 + vertex -96 -101 26.88 + vertex -96.3536 -101 26.7428 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96 -101 26.88 + vertex -95.9185 -101 26.5333 + vertex -95.6084 -101 26.5844 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.6175 -101 26.1557 + vertex -95.6084 -101 26.5844 + vertex -95.9185 -101 26.5333 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -95.6084 -101 26.5844 + vertex -95.6175 -101 26.1557 + vertex -95.3502 -101 26.1673 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.51 -101 25.685 + vertex -95.3502 -101 26.1673 + vertex -95.6175 -101 26.1557 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.51 -101 25.685 + vertex -95.26 -101 25.685 + vertex -95.3502 -101 26.1673 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.3502 -101 25.2027 + vertex -95.51 -101 25.685 + vertex -95.6175 -101 25.2143 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.51 -101 25.685 + vertex -95.3502 -101 25.2027 + vertex -95.26 -101 25.685 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.6084 -101 24.7856 + vertex -95.6175 -101 25.2143 + vertex -95.9185 -101 24.8367 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.6175 -101 25.2143 + vertex -95.6084 -101 24.7856 + vertex -95.3502 -101 25.2027 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96 -101 24.49 + vertex -95.9185 -101 24.8367 + vertex -96.3536 -101 24.6272 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -95.9185 -101 24.8367 + vertex -96 -101 24.49 + vertex -95.6084 -101 24.7856 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.3536 -101 26.7428 + vertex 96.4718 -101 27.0143 + vertex 96 -101 26.88 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.8364 -101 26.7428 + vertex 96.4718 -101 27.0143 + vertex 96.3536 -101 26.7428 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.4718 -101 27.0143 + vertex 96.8364 -101 26.7428 + vertex 96.9603 -101 26.969 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.9185 -101 26.5333 + vertex 96 -101 26.88 + vertex 95.6084 -101 26.5844 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 96 -101 26.88 + vertex 95.9185 -101 26.5333 + vertex 96.3536 -101 26.7428 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.6175 -101 26.1557 + vertex 95.6084 -101 26.5844 + vertex 95.3502 -101 26.1673 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.6084 -101 26.5844 + vertex 95.6175 -101 26.1557 + vertex 95.9185 -101 26.5333 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.51 -101 25.685 + vertex 95.3502 -101 26.1673 + vertex 95.26 -101 25.685 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.3502 -101 26.1673 + vertex 95.51 -101 25.685 + vertex 95.6175 -101 26.1557 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.3502 -101 25.2027 + vertex 95.51 -101 25.685 + vertex 95.26 -101 25.685 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 95.51 -101 25.685 + vertex 95.3502 -101 25.2027 + vertex 95.6175 -101 25.2143 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.6084 -101 24.7856 + vertex 95.6175 -101 25.2143 + vertex 95.3502 -101 25.2027 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 95.6175 -101 25.2143 + vertex 95.6084 -101 24.7856 + vertex 95.9185 -101 24.8367 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96 -101 24.49 + vertex 95.9185 -101 24.8367 + vertex 95.6084 -101 24.7856 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.4718 -101 24.3557 + vertex 96.3536 -101 24.6272 + vertex 96 -101 24.49 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.9185 -101 24.8367 + vertex 96 -101 24.49 + vertex 96.3536 -101 24.6272 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.2715 -101 26.5333 + vertex 96.9603 -101 26.969 + vertex 96.8364 -101 26.7428 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.9603 -101 26.969 + vertex 97.2715 -101 26.5333 + vertex 97.3995 -101 26.7503 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.2715 -101 26.5333 + vertex 97.73 -101 26.3878 + vertex 97.3995 -101 26.7503 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5725 -101 26.1557 + vertex 97.73 -101 26.3878 + vertex 97.2715 -101 26.5333 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5725 -101 26.1557 + vertex 97.9073 -101 25.9303 + vertex 97.73 -101 26.3878 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.68 -101 25.685 + vertex 97.9073 -101 25.9303 + vertex 97.5725 -101 26.1557 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.68 -101 25.685 + vertex 97.9073 -101 25.4397 + vertex 97.9073 -101 25.9303 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5725 -101 25.2143 + vertex 97.9073 -101 25.4397 + vertex 97.68 -101 25.685 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5725 -101 25.2143 + vertex 97.73 -101 24.9822 + vertex 97.9073 -101 25.4397 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5295 -101 24.7623 + vertex 97.5725 -101 25.2143 + vertex 97.2715 -101 24.8367 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 97.5725 -101 25.2143 + vertex 97.5295 -101 24.7623 + vertex 97.73 -101 24.9822 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.9798 -101 24.4107 + vertex 97.2715 -101 24.8367 + vertex 96.8755 -101 24.646 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.523 -101 25.9943 + vertex 106.139 -101 26.2927 + vertex 106.146 -101 26.04 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5295 -101 24.7623 + vertex 106.146 -101 26.04 + vertex 106.139 -101 26.2927 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 97.2715 -101 24.8367 + vertex 96.9798 -101 24.4107 + vertex 97.5295 -101 24.7623 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.8872 -101 24.3942 + vertex 96.8755 -101 24.646 + vertex 96.7696 -101 24.6272 + endloop + endfacet + facet normal -0 -1 0 + outer loop + vertex 96.605 -101 24.368 + vertex 96.3536 -101 24.6272 + vertex 96.4718 -101 24.3557 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 97.5295 -101 24.7623 + vertex 96.9798 -101 24.4107 + vertex 106.146 -101 26.04 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.8755 -101 24.646 + vertex 96.8872 -101 24.3942 + vertex 96.9798 -101 24.4107 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.9798 -101 24.4107 + vertex 96.8872 -101 24.3942 + vertex 96.9603 -101 24.401 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 96.7696 -101 24.6272 + vertex 96.605 -101 24.368 + vertex 96.8872 -101 24.3942 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.3536 -101 24.6272 + vertex 96.605 -101 24.368 + vertex 96.7696 -101 24.6272 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.139 -101 26.2927 + vertex 106.523 -101 25.9943 + vertex 106.615 -101 26.235 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.523 -101 25.9943 + vertex 107.009 -101 25.9631 + vertex 106.615 -101 26.235 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.816 -101 25.7924 + vertex 107.009 -101 25.9631 + vertex 106.523 -101 25.9943 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.816 -101 25.7924 + vertex 107.231 -101 25.5393 + vertex 107.009 -101 25.9631 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.981 -101 25.4777 + vertex 107.231 -101 25.5393 + vertex 106.816 -101 25.7924 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.981 -101 24.13 + vertex 107.231 -101 25.5393 + vertex 106.981 -101 25.4777 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.981 -101 22.13 + vertex 106.981 -101 24.13 + vertex -106.981 -101 22.13 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 107 -101 22.1 + vertex 106.981 -101 24.13 + vertex 106.981 -101 22.13 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 107 -101 22.1 + vertex 106.981 -101 22.13 + vertex 106.981 -101 22.1 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.981 -101 24.13 + vertex 107 -101 22.1 + vertex 107.231 -101 25.5393 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 107.231 -101 19.0607 + vertex 107 -101 22.1 + vertex 107 -101 20.5 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 107.231 -101 19.0607 + vertex 107 -101 20.5 + vertex 106.981 -101 19.1223 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 107 -101 22.1 + vertex 107.231 -101 19.0607 + vertex 107.231 -101 25.5393 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.816 -101 18.8076 + vertex 107.231 -101 19.0607 + vertex 106.981 -101 19.1223 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.816 -101 18.8076 + vertex 107.009 -101 18.6369 + vertex 107.231 -101 19.0607 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.523 -101 18.6057 + vertex 107.009 -101 18.6369 + vertex 106.816 -101 18.8076 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.139 -101 18.3073 + vertex 106.523 -101 18.6057 + vertex 106.146 -101 18.56 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.523 -101 18.6057 + vertex 106.615 -101 18.365 + vertex 107.009 -101 18.6369 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.8872 -101 24.3942 + vertex 96.605 -101 24.368 + vertex 96.605 -101 24.344 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -106.981 -101 22.13 + vertex -107 -101 22.1 + vertex -106.981 -101 22.1 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.9798 -101 20.1893 + vertex -96.8872 -101 20.2058 + vertex -96.9603 -101 20.199 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.8755 -101 19.954 + vertex -96.8872 -101 20.2058 + vertex -96.9798 -101 20.1893 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.8872 -101 20.2058 + vertex -96.7696 -101 19.9728 + vertex -96.605 -101 20.232 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.3536 -101 19.9728 + vertex -96.605 -101 20.232 + vertex -96.7696 -101 19.9728 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.605 -101 20.232 + vertex -96.3536 -101 19.9728 + vertex -96.4718 -101 20.2443 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.8872 -101 20.2058 + vertex -96.8755 -101 19.954 + vertex -96.7696 -101 19.9728 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.2715 -101 19.7633 + vertex -96.9798 -101 20.1893 + vertex -97.5295 -101 19.8377 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -106.146 -101 18.56 + vertex -97.5295 -101 19.8377 + vertex -96.9798 -101 20.1893 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -106.523 -101 18.6057 + vertex -106.139 -101 18.3073 + vertex -106.146 -101 18.56 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -106.146 -101 18.56 + vertex -106.139 -101 18.3073 + vertex -97.5295 -101 19.8377 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.4718 -101 20.2443 + vertex -96.3536 -101 19.9728 + vertex -96 -101 20.11 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.9185 -101 19.7633 + vertex -96 -101 20.11 + vertex -96.3536 -101 19.9728 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96 -101 20.11 + vertex -95.9185 -101 19.7633 + vertex -95.6084 -101 19.8144 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.6175 -101 19.3857 + vertex -95.6084 -101 19.8144 + vertex -95.9185 -101 19.7633 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -95.6084 -101 19.8144 + vertex -95.6175 -101 19.3857 + vertex -95.3502 -101 19.3973 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.51 -101 18.915 + vertex -95.3502 -101 19.3973 + vertex -95.6175 -101 19.3857 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.51 -101 18.915 + vertex -95.26 -101 18.915 + vertex -95.3502 -101 19.3973 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.3502 -101 18.4327 + vertex -95.51 -101 18.915 + vertex -95.6175 -101 18.4443 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.51 -101 18.915 + vertex -95.3502 -101 18.4327 + vertex -95.26 -101 18.915 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.6084 -101 18.0156 + vertex -95.6175 -101 18.4443 + vertex -95.9185 -101 18.0667 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.6175 -101 18.4443 + vertex -95.6084 -101 18.0156 + vertex -95.3502 -101 18.4327 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96 -101 17.72 + vertex -95.9185 -101 18.0667 + vertex -96.3536 -101 17.8572 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -95.9185 -101 18.0667 + vertex -96 -101 17.72 + vertex -95.6084 -101 18.0156 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.8364 -101 17.8572 + vertex -96 -101 17.72 + vertex -96.3536 -101 17.8572 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.4718 -101 17.5857 + vertex -96.8364 -101 17.8572 + vertex -96.9603 -101 17.631 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.8364 -101 17.8572 + vertex -96.4718 -101 17.5857 + vertex -96 -101 17.72 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -96.9798 -101 20.1893 + vertex -97.2715 -101 19.7633 + vertex -96.8755 -101 19.954 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.5725 -101 19.3857 + vertex -97.5295 -101 19.8377 + vertex -97.73 -101 19.6178 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -97.5295 -101 19.8377 + vertex -97.5725 -101 19.3857 + vertex -97.2715 -101 19.7633 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.9073 -101 19.1603 + vertex -97.5725 -101 19.3857 + vertex -97.73 -101 19.6178 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.9073 -101 19.1603 + vertex -97.68 -101 18.915 + vertex -97.5725 -101 19.3857 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.9073 -101 18.6697 + vertex -97.68 -101 18.915 + vertex -97.9073 -101 19.1603 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.9073 -101 18.6697 + vertex -97.5725 -101 18.4443 + vertex -97.68 -101 18.915 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.73 -101 18.2122 + vertex -97.5725 -101 18.4443 + vertex -97.9073 -101 18.6697 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.73 -101 18.2122 + vertex -97.2715 -101 18.0667 + vertex -97.5725 -101 18.4443 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.3995 -101 17.8497 + vertex -97.2715 -101 18.0667 + vertex -97.73 -101 18.2122 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.2715 -101 18.0667 + vertex -96.9603 -101 17.631 + vertex -96.8364 -101 17.8572 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.9603 -101 17.631 + vertex -97.2715 -101 18.0667 + vertex -97.3995 -101 17.8497 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.9798 -101 20.1893 + vertex 97.2715 -101 19.7633 + vertex 97.5295 -101 19.8377 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5725 -101 19.3857 + vertex 97.5295 -101 19.8377 + vertex 97.2715 -101 19.7633 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5295 -101 19.8377 + vertex 97.5725 -101 19.3857 + vertex 97.73 -101 19.6178 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5725 -101 19.3857 + vertex 97.9073 -101 19.1603 + vertex 97.73 -101 19.6178 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.68 -101 18.915 + vertex 97.9073 -101 19.1603 + vertex 97.5725 -101 19.3857 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.68 -101 18.915 + vertex 97.9073 -101 18.6697 + vertex 97.9073 -101 19.1603 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5725 -101 18.4443 + vertex 97.9073 -101 18.6697 + vertex 97.68 -101 18.915 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5725 -101 18.4443 + vertex 97.73 -101 18.2122 + vertex 97.9073 -101 18.6697 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.2715 -101 18.0667 + vertex 97.73 -101 18.2122 + vertex 97.5725 -101 18.4443 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.9603 -101 17.631 + vertex 97.2715 -101 18.0667 + vertex 96.8364 -101 17.8572 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.2715 -101 18.0667 + vertex 97.3995 -101 17.8497 + vertex 97.73 -101 18.2122 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.9185 -101 19.7633 + vertex 96 -101 20.11 + vertex 95.6084 -101 19.8144 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 96 -101 20.11 + vertex 95.9185 -101 19.7633 + vertex 96.3536 -101 19.9728 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.6175 -101 19.3857 + vertex 95.6084 -101 19.8144 + vertex 95.3502 -101 19.3973 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.6084 -101 19.8144 + vertex 95.6175 -101 19.3857 + vertex 95.9185 -101 19.7633 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.51 -101 18.915 + vertex 95.3502 -101 19.3973 + vertex 95.26 -101 18.915 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.3502 -101 19.3973 + vertex 95.51 -101 18.915 + vertex 95.6175 -101 19.3857 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.3502 -101 18.4327 + vertex 95.51 -101 18.915 + vertex 95.26 -101 18.915 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 95.51 -101 18.915 + vertex 95.3502 -101 18.4327 + vertex 95.6175 -101 18.4443 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.6084 -101 18.0156 + vertex 95.6175 -101 18.4443 + vertex 95.3502 -101 18.4327 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 95.6175 -101 18.4443 + vertex 95.6084 -101 18.0156 + vertex 95.9185 -101 18.0667 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96 -101 17.72 + vertex 95.9185 -101 18.0667 + vertex 95.6084 -101 18.0156 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.4718 -101 17.5857 + vertex 96.8364 -101 17.8572 + vertex 96.3536 -101 17.8572 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.9185 -101 18.0667 + vertex 96 -101 17.72 + vertex 96.3536 -101 17.8572 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.4718 -101 17.5857 + vertex 96.3536 -101 17.8572 + vertex 96 -101 17.72 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 97.2715 -101 18.0667 + vertex 96.9603 -101 17.631 + vertex 97.3995 -101 17.8497 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 96.8364 -101 17.8572 + vertex 96.4718 -101 17.5857 + vertex 96.9603 -101 17.631 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.8872 -101 20.2058 + vertex 96.9798 -101 20.1893 + vertex 96.9603 -101 20.199 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.7696 -101 19.9728 + vertex 96.8872 -101 20.2058 + vertex 96.605 -101 20.232 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.3536 -101 19.9728 + vertex 96.605 -101 20.232 + vertex 96.4718 -101 20.2443 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.3536 -101 19.9728 + vertex 96.4718 -101 20.2443 + vertex 96 -101 20.11 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 96.605 -101 20.232 + vertex 96.3536 -101 19.9728 + vertex 96.7696 -101 19.9728 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.8755 -101 19.954 + vertex 96.8872 -101 20.2058 + vertex 96.7696 -101 19.9728 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 96.8872 -101 20.2058 + vertex 96.8755 -101 19.954 + vertex 96.9798 -101 20.1893 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.2715 -101 19.7633 + vertex 96.9798 -101 20.1893 + vertex 96.8755 -101 19.954 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5295 -101 19.8377 + vertex 106.146 -101 18.56 + vertex 96.9798 -101 20.1893 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.139 -101 18.3073 + vertex 106.146 -101 18.56 + vertex 97.5295 -101 19.8377 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 106.523 -101 18.6057 + vertex 106.139 -101 18.3073 + vertex 106.615 -101 18.365 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.605 -101 20.256 + vertex 96.605 -101 20.232 + vertex 96.8872 -101 20.2058 + endloop + endfacet + facet normal 0.175007 0 0.984567 + outer loop + vertex -106.139 -82 26.2927 + vertex -97.5295 -101 24.7623 + vertex -97.5295 -82 24.7623 + endloop + endfacet + facet normal 0.175007 0 0.984567 + outer loop + vertex -97.5295 -101 24.7623 + vertex -106.139 -82 26.2927 + vertex -106.139 -101 26.2927 + endloop + endfacet + facet normal 0.175 0 0.984568 + outer loop + vertex -96.8755 -82 24.646 + vertex -96.7696 -101 24.6272 + vertex -96.7696 -82 24.6272 + endloop + endfacet + facet normal 0.175 0 0.984568 + outer loop + vertex -96.7696 -101 24.6272 + vertex -96.8755 -82 24.646 + vertex -96.8755 -101 24.646 + endloop + endfacet + facet normal -0.120538 0 0.992709 + outer loop + vertex -106.615 -82 26.235 + vertex -106.139 -101 26.2927 + vertex -106.139 -82 26.2927 + endloop + endfacet + facet normal -0.120538 0 0.992709 + outer loop + vertex -106.139 -101 26.2927 + vertex -106.615 -82 26.235 + vertex -106.615 -101 26.235 + endloop + endfacet + facet normal -0.568069 0 0.822981 + outer loop + vertex -107.009 -82 25.9631 + vertex -106.615 -101 26.235 + vertex -106.615 -82 26.235 + endloop + endfacet + facet normal -0.568069 0 0.822981 + outer loop + vertex -106.615 -101 26.235 + vertex -107.009 -82 25.9631 + vertex -107.009 -101 25.9631 + endloop + endfacet + facet normal -0.885462 0 0.464712 + outer loop + vertex -107.231 -101 25.5393 + vertex -107.009 -82 25.9631 + vertex -107.231 -82 25.5393 + endloop + endfacet + facet normal -0.885462 0 0.464712 + outer loop + vertex -107.009 -82 25.9631 + vertex -107.231 -101 25.5393 + vertex -107.009 -101 25.9631 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -107.231 -101 19.0607 + vertex -107.231 -82 25.5393 + vertex -107.231 -82 19.0607 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex -107.231 -82 25.5393 + vertex -107.231 -101 19.0607 + vertex -107.231 -101 25.5393 + endloop + endfacet + facet normal -0.885462 0 -0.464712 + outer loop + vertex -107.009 -101 18.6369 + vertex -107.231 -82 19.0607 + vertex -107.009 -82 18.6369 + endloop + endfacet + facet normal -0.885462 -0 -0.464712 + outer loop + vertex -107.231 -82 19.0607 + vertex -107.009 -101 18.6369 + vertex -107.231 -101 19.0607 + endloop + endfacet + facet normal -0.568069 0 -0.822981 + outer loop + vertex -107.009 -101 18.6369 + vertex -106.615 -82 18.365 + vertex -106.615 -101 18.365 + endloop + endfacet + facet normal -0.568069 0 -0.822981 + outer loop + vertex -106.615 -82 18.365 + vertex -107.009 -101 18.6369 + vertex -107.009 -82 18.6369 + endloop + endfacet + facet normal -0.120538 0 -0.992709 + outer loop + vertex -106.615 -101 18.365 + vertex -106.139 -82 18.3073 + vertex -106.139 -101 18.3073 + endloop + endfacet + facet normal -0.120538 0 -0.992709 + outer loop + vertex -106.139 -82 18.3073 + vertex -106.615 -101 18.365 + vertex -106.615 -82 18.365 + endloop + endfacet + facet normal 0.175008 0 -0.984567 + outer loop + vertex -106.139 -101 18.3073 + vertex -97.5295 -82 19.8377 + vertex -97.5295 -101 19.8377 + endloop + endfacet + facet normal 0.175008 0 -0.984567 + outer loop + vertex -97.5295 -82 19.8377 + vertex -106.139 -101 18.3073 + vertex -106.139 -82 18.3073 + endloop + endfacet + facet normal 0.175 0 -0.984568 + outer loop + vertex -96.8755 -101 19.954 + vertex -96.7696 -82 19.9728 + vertex -96.7696 -101 19.9728 + endloop + endfacet + facet normal 0.175 0 -0.984568 + outer loop + vertex -96.7696 -82 19.9728 + vertex -96.8755 -101 19.954 + vertex -96.8755 -82 19.954 + endloop + endfacet + facet normal 0.568073 0 0.822978 + outer loop + vertex -106.816 -82 18.8076 + vertex -106.523 -101 18.6057 + vertex -106.523 -82 18.6057 + endloop + endfacet + facet normal 0.568073 0 0.822978 + outer loop + vertex -106.523 -101 18.6057 + vertex -106.816 -82 18.8076 + vertex -106.816 -101 18.8076 + endloop + endfacet + facet normal 0.88547 -0 0.464697 + outer loop + vertex -106.981 -101 19.1223 + vertex -106.816 -82 18.8076 + vertex -106.981 -82 19.1223 + endloop + endfacet + facet normal 0.88547 0 0.464697 + outer loop + vertex -106.816 -82 18.8076 + vertex -106.981 -101 19.1223 + vertex -106.816 -101 18.8076 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex -106.981 -101 25.4777 + vertex -106.981 -82 24.13 + vertex -106.981 -82 25.4777 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex -106.981 -82 24.13 + vertex -106.981 -101 25.4777 + vertex -106.981 -101 24.13 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex -106.981 -101 20.5 + vertex -106.981 -82 19.1223 + vertex -106.981 -82 20.5 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex -106.981 -82 19.1223 + vertex -106.981 -101 20.5 + vertex -106.981 -101 19.1223 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex -106.981 -101 22.13 + vertex -106.981 -82 22.1 + vertex -106.981 -82 22.13 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex -106.981 -82 22.1 + vertex -106.981 -101 22.13 + vertex -106.981 -101 22.1 + endloop + endfacet + facet normal 0.88547 0 -0.464697 + outer loop + vertex -106.816 -101 25.7924 + vertex -106.981 -82 25.4777 + vertex -106.816 -82 25.7924 + endloop + endfacet + facet normal 0.88547 0 -0.464697 + outer loop + vertex -106.981 -82 25.4777 + vertex -106.816 -101 25.7924 + vertex -106.981 -101 25.4777 + endloop + endfacet + facet normal 0.568073 0 -0.822978 + outer loop + vertex -106.816 -101 25.7924 + vertex -106.523 -82 25.9943 + vertex -106.523 -101 25.9943 + endloop + endfacet + facet normal 0.568073 0 -0.822978 + outer loop + vertex -106.523 -82 25.9943 + vertex -106.816 -101 25.7924 + vertex -106.816 -82 25.7924 + endloop + endfacet + facet normal 0.120522 0 -0.992711 + outer loop + vertex -106.523 -101 25.9943 + vertex -106.146 -82 26.04 + vertex -106.146 -101 26.04 + endloop + endfacet + facet normal 0.120522 0 -0.992711 + outer loop + vertex -106.146 -82 26.04 + vertex -106.523 -101 25.9943 + vertex -106.523 -82 25.9943 + endloop + endfacet + facet normal -0.175007 0 -0.984567 + outer loop + vertex -106.146 -101 26.04 + vertex -96.9798 -82 24.4107 + vertex -96.9798 -101 24.4107 + endloop + endfacet + facet normal -0.175007 0 -0.984567 + outer loop + vertex -96.9798 -82 24.4107 + vertex -106.146 -101 26.04 + vertex -106.146 -82 26.04 + endloop + endfacet + facet normal -0.175007 0 -0.984567 + outer loop + vertex -96.8872 -101 24.3942 + vertex -96.605 -82 24.344 + vertex -96.605 -101 24.344 + endloop + endfacet + facet normal -0.175007 0 -0.984567 + outer loop + vertex -96.605 -82 24.344 + vertex -96.8872 -101 24.3942 + vertex -96.8872 -82 24.3942 + endloop + endfacet + facet normal -0.175007 0 0.984567 + outer loop + vertex -106.146 -82 18.56 + vertex -96.9798 -101 20.1893 + vertex -96.9798 -82 20.1893 + endloop + endfacet + facet normal -0.175007 0 0.984567 + outer loop + vertex -96.9798 -101 20.1893 + vertex -106.146 -82 18.56 + vertex -106.146 -101 18.56 + endloop + endfacet + facet normal -0.175007 0 0.984567 + outer loop + vertex -96.8872 -82 20.2058 + vertex -96.605 -101 20.256 + vertex -96.605 -82 20.256 + endloop + endfacet + facet normal -0.175007 0 0.984567 + outer loop + vertex -96.605 -101 20.256 + vertex -96.8872 -82 20.2058 + vertex -96.8872 -101 20.2058 + endloop + endfacet + facet normal 0.120522 0 0.992711 + outer loop + vertex -106.523 -82 18.6057 + vertex -106.146 -101 18.56 + vertex -106.146 -82 18.56 + endloop + endfacet + facet normal 0.120522 0 0.992711 + outer loop + vertex -106.146 -101 18.56 + vertex -106.523 -82 18.6057 + vertex -106.523 -101 18.6057 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex -96.605 -101 24.368 + vertex -96.605 -82 24.344 + vertex -96.605 -82 24.368 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex -96.605 -82 24.344 + vertex -96.605 -101 24.368 + vertex -96.605 -101 24.344 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex -96.605 -101 20.256 + vertex -96.605 -82 20.232 + vertex -96.605 -82 20.256 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex -96.605 -82 20.232 + vertex -96.605 -101 20.256 + vertex -96.605 -101 20.232 + endloop + endfacet + facet normal 0.602619 0 -0.798029 + outer loop + vertex -96 -101 17.72 + vertex -95.6084 -82 18.0156 + vertex -95.6084 -101 18.0156 + endloop + endfacet + facet normal 0.602619 0 -0.798029 + outer loop + vertex -95.6084 -82 18.0156 + vertex -96 -101 17.72 + vertex -96 -82 17.72 + endloop + endfacet + facet normal 0.850222 0 -0.526424 + outer loop + vertex -95.3502 -101 18.4327 + vertex -95.6084 -82 18.0156 + vertex -95.3502 -82 18.4327 + endloop + endfacet + facet normal 0.850222 0 -0.526424 + outer loop + vertex -95.6084 -82 18.0156 + vertex -95.3502 -101 18.4327 + vertex -95.6084 -101 18.0156 + endloop + endfacet + facet normal 0.982973 0 -0.18375 + outer loop + vertex -95.26 -101 18.915 + vertex -95.3502 -82 18.4327 + vertex -95.26 -82 18.915 + endloop + endfacet + facet normal 0.982973 0 -0.18375 + outer loop + vertex -95.3502 -82 18.4327 + vertex -95.26 -101 18.915 + vertex -95.3502 -101 18.4327 + endloop + endfacet + facet normal 0.982973 -0 0.18375 + outer loop + vertex -95.3502 -101 19.3973 + vertex -95.26 -82 18.915 + vertex -95.3502 -82 19.3973 + endloop + endfacet + facet normal 0.982973 0 0.18375 + outer loop + vertex -95.26 -82 18.915 + vertex -95.3502 -101 19.3973 + vertex -95.26 -101 18.915 + endloop + endfacet + facet normal 0.850222 -0 0.526424 + outer loop + vertex -95.6084 -101 19.8144 + vertex -95.3502 -82 19.3973 + vertex -95.6084 -82 19.8144 + endloop + endfacet + facet normal 0.850222 0 0.526424 + outer loop + vertex -95.3502 -82 19.3973 + vertex -95.6084 -101 19.8144 + vertex -95.3502 -101 19.3973 + endloop + endfacet + facet normal 0.602619 0 0.798029 + outer loop + vertex -96 -82 20.11 + vertex -95.6084 -101 19.8144 + vertex -95.6084 -82 19.8144 + endloop + endfacet + facet normal 0.602619 0 0.798029 + outer loop + vertex -95.6084 -101 19.8144 + vertex -96 -82 20.11 + vertex -96 -101 20.11 + endloop + endfacet + facet normal 0.273665 0 0.961825 + outer loop + vertex -96.4718 -82 20.2443 + vertex -96 -101 20.11 + vertex -96 -82 20.11 + endloop + endfacet + facet normal 0.273665 0 0.961825 + outer loop + vertex -96 -101 20.11 + vertex -96.4718 -82 20.2443 + vertex -96.4718 -101 20.2443 + endloop + endfacet + facet normal -0.0922792 0 0.995733 + outer loop + vertex -96.9603 -82 20.199 + vertex -96.8872 -101 20.2058 + vertex -96.8872 -82 20.2058 + endloop + endfacet + facet normal -0.0922792 0 0.995733 + outer loop + vertex -96.8872 -101 20.2058 + vertex -96.9603 -82 20.199 + vertex -96.9603 -101 20.199 + endloop + endfacet + facet normal -0.0922857 0 0.995733 + outer loop + vertex -96.605 -82 20.232 + vertex -96.4718 -101 20.2443 + vertex -96.4718 -82 20.2443 + endloop + endfacet + facet normal -0.0922857 0 0.995733 + outer loop + vertex -96.4718 -101 20.2443 + vertex -96.605 -82 20.232 + vertex -96.605 -101 20.232 + endloop + endfacet + facet normal -0.445737 0 0.895164 + outer loop + vertex -96.9798 -82 20.1893 + vertex -96.9603 -101 20.199 + vertex -96.9603 -82 20.199 + endloop + endfacet + facet normal -0.445737 0 0.895164 + outer loop + vertex -96.9603 -101 20.199 + vertex -96.9798 -82 20.1893 + vertex -96.9798 -101 20.1893 + endloop + endfacet + facet normal -0.739002 0 0.673704 + outer loop + vertex -97.73 -101 19.6178 + vertex -97.5295 -82 19.8377 + vertex -97.73 -82 19.6178 + endloop + endfacet + facet normal -0.739002 0 0.673704 + outer loop + vertex -97.5295 -82 19.8377 + vertex -97.73 -101 19.6178 + vertex -97.5295 -101 19.8377 + endloop + endfacet + facet normal -0.932469 0 0.36125 + outer loop + vertex -97.9073 -101 19.1603 + vertex -97.73 -82 19.6178 + vertex -97.9073 -82 19.1603 + endloop + endfacet + facet normal -0.932469 0 0.36125 + outer loop + vertex -97.73 -82 19.6178 + vertex -97.9073 -101 19.1603 + vertex -97.73 -101 19.6178 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -97.9073 -101 18.6697 + vertex -97.9073 -82 19.1603 + vertex -97.9073 -82 18.6697 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex -97.9073 -82 19.1603 + vertex -97.9073 -101 18.6697 + vertex -97.9073 -101 19.1603 + endloop + endfacet + facet normal -0.932469 0 -0.36125 + outer loop + vertex -97.73 -101 18.2122 + vertex -97.9073 -82 18.6697 + vertex -97.73 -82 18.2122 + endloop + endfacet + facet normal -0.932469 -0 -0.36125 + outer loop + vertex -97.9073 -82 18.6697 + vertex -97.73 -101 18.2122 + vertex -97.9073 -101 18.6697 + endloop + endfacet + facet normal -0.739009 0 -0.673695 + outer loop + vertex -97.3995 -101 17.8497 + vertex -97.73 -82 18.2122 + vertex -97.3995 -82 17.8497 + endloop + endfacet + facet normal -0.739009 -0 -0.673695 + outer loop + vertex -97.73 -82 18.2122 + vertex -97.3995 -101 17.8497 + vertex -97.73 -101 18.2122 + endloop + endfacet + facet normal -0.445745 0 -0.89516 + outer loop + vertex -97.3995 -101 17.8497 + vertex -96.9603 -82 17.631 + vertex -96.9603 -101 17.631 + endloop + endfacet + facet normal -0.445745 0 -0.89516 + outer loop + vertex -96.9603 -82 17.631 + vertex -97.3995 -101 17.8497 + vertex -97.3995 -82 17.8497 + endloop + endfacet + facet normal -0.0922827 0 -0.995733 + outer loop + vertex -96.9603 -101 17.631 + vertex -96.4718 -82 17.5857 + vertex -96.4718 -101 17.5857 + endloop + endfacet + facet normal -0.0922827 0 -0.995733 + outer loop + vertex -96.4718 -82 17.5857 + vertex -96.9603 -101 17.631 + vertex -96.9603 -82 17.631 + endloop + endfacet + facet normal 0.273665 0 -0.961825 + outer loop + vertex -96.4718 -101 17.5857 + vertex -96 -82 17.72 + vertex -96 -101 17.72 + endloop + endfacet + facet normal 0.273665 0 -0.961825 + outer loop + vertex -96 -82 17.72 + vertex -96.4718 -101 17.5857 + vertex -96.4718 -82 17.5857 + endloop + endfacet + facet normal 0.433867 0 0.900977 + outer loop + vertex -97.2715 -82 18.0667 + vertex -96.8364 -101 17.8572 + vertex -96.8364 -82 17.8572 + endloop + endfacet + facet normal 0.433867 0 0.900977 + outer loop + vertex -96.8364 -101 17.8572 + vertex -97.2715 -82 18.0667 + vertex -97.2715 -101 18.0667 + endloop + endfacet + facet normal 0.781848 -0 0.623469 + outer loop + vertex -97.5725 -101 18.4443 + vertex -97.2715 -82 18.0667 + vertex -97.5725 -82 18.4443 + endloop + endfacet + facet normal 0.781848 0 0.623469 + outer loop + vertex -97.2715 -82 18.0667 + vertex -97.5725 -101 18.4443 + vertex -97.2715 -101 18.0667 + endloop + endfacet + facet normal 0.974925 -0 0.222535 + outer loop + vertex -97.68 -101 18.915 + vertex -97.5725 -82 18.4443 + vertex -97.68 -82 18.915 + endloop + endfacet + facet normal 0.974925 0 0.222535 + outer loop + vertex -97.5725 -82 18.4443 + vertex -97.68 -101 18.915 + vertex -97.5725 -101 18.4443 + endloop + endfacet + facet normal 0.974925 0 -0.222535 + outer loop + vertex -97.5725 -101 19.3857 + vertex -97.68 -82 18.915 + vertex -97.5725 -82 19.3857 + endloop + endfacet + facet normal 0.974925 0 -0.222535 + outer loop + vertex -97.68 -82 18.915 + vertex -97.5725 -101 19.3857 + vertex -97.68 -101 18.915 + endloop + endfacet + facet normal 0.781848 0 -0.623469 + outer loop + vertex -97.2715 -101 19.7633 + vertex -97.5725 -82 19.3857 + vertex -97.2715 -82 19.7633 + endloop + endfacet + facet normal 0.781848 0 -0.623469 + outer loop + vertex -97.5725 -82 19.3857 + vertex -97.2715 -101 19.7633 + vertex -97.5725 -101 19.3857 + endloop + endfacet + facet normal 0.433867 0 -0.900977 + outer loop + vertex -97.2715 -101 19.7633 + vertex -96.8755 -82 19.954 + vertex -96.8755 -101 19.954 + endloop + endfacet + facet normal 0.433867 0 -0.900977 + outer loop + vertex -96.8755 -82 19.954 + vertex -97.2715 -101 19.7633 + vertex -97.2715 -82 19.7633 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -96.7696 -101 19.9728 + vertex -96.3536 -82 19.9728 + vertex -96.3536 -101 19.9728 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -96.3536 -82 19.9728 + vertex -96.7696 -101 19.9728 + vertex -96.7696 -82 19.9728 + endloop + endfacet + facet normal -0.433867 0 -0.900977 + outer loop + vertex -96.3536 -101 19.9728 + vertex -95.9185 -82 19.7633 + vertex -95.9185 -101 19.7633 + endloop + endfacet + facet normal -0.433867 0 -0.900977 + outer loop + vertex -95.9185 -82 19.7633 + vertex -96.3536 -101 19.9728 + vertex -96.3536 -82 19.9728 + endloop + endfacet + facet normal -0.781848 0 -0.623469 + outer loop + vertex -95.6175 -101 19.3857 + vertex -95.9185 -82 19.7633 + vertex -95.6175 -82 19.3857 + endloop + endfacet + facet normal -0.781848 -0 -0.623469 + outer loop + vertex -95.9185 -82 19.7633 + vertex -95.6175 -101 19.3857 + vertex -95.9185 -101 19.7633 + endloop + endfacet + facet normal -0.974925 0 -0.222535 + outer loop + vertex -95.51 -101 18.915 + vertex -95.6175 -82 19.3857 + vertex -95.51 -82 18.915 + endloop + endfacet + facet normal -0.974925 -0 -0.222535 + outer loop + vertex -95.6175 -82 19.3857 + vertex -95.51 -101 18.915 + vertex -95.6175 -101 19.3857 + endloop + endfacet + facet normal -0.974925 0 0.222535 + outer loop + vertex -95.6175 -101 18.4443 + vertex -95.51 -82 18.915 + vertex -95.6175 -82 18.4443 + endloop + endfacet + facet normal -0.974925 0 0.222535 + outer loop + vertex -95.51 -82 18.915 + vertex -95.6175 -101 18.4443 + vertex -95.51 -101 18.915 + endloop + endfacet + facet normal -0.781848 0 0.623469 + outer loop + vertex -95.9185 -101 18.0667 + vertex -95.6175 -82 18.4443 + vertex -95.9185 -82 18.0667 + endloop + endfacet + facet normal -0.781848 0 0.623469 + outer loop + vertex -95.6175 -82 18.4443 + vertex -95.9185 -101 18.0667 + vertex -95.6175 -101 18.4443 + endloop + endfacet + facet normal -0.433867 0 0.900977 + outer loop + vertex -96.3536 -82 17.8572 + vertex -95.9185 -101 18.0667 + vertex -95.9185 -82 18.0667 + endloop + endfacet + facet normal -0.433867 0 0.900977 + outer loop + vertex -95.9185 -101 18.0667 + vertex -96.3536 -82 17.8572 + vertex -96.3536 -101 17.8572 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -96.8364 -82 17.8572 + vertex -96.3536 -101 17.8572 + vertex -96.3536 -82 17.8572 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -96.3536 -101 17.8572 + vertex -96.8364 -82 17.8572 + vertex -96.8364 -101 17.8572 + endloop + endfacet + facet normal 0.602619 0 -0.798029 + outer loop + vertex -96 -101 24.49 + vertex -95.6084 -82 24.7856 + vertex -95.6084 -101 24.7856 + endloop + endfacet + facet normal 0.602619 0 -0.798029 + outer loop + vertex -95.6084 -82 24.7856 + vertex -96 -101 24.49 + vertex -96 -82 24.49 + endloop + endfacet + facet normal 0.850222 0 -0.526424 + outer loop + vertex -95.3502 -101 25.2027 + vertex -95.6084 -82 24.7856 + vertex -95.3502 -82 25.2027 + endloop + endfacet + facet normal 0.850222 0 -0.526424 + outer loop + vertex -95.6084 -82 24.7856 + vertex -95.3502 -101 25.2027 + vertex -95.6084 -101 24.7856 + endloop + endfacet + facet normal 0.982973 0 -0.18375 + outer loop + vertex -95.26 -101 25.685 + vertex -95.3502 -82 25.2027 + vertex -95.26 -82 25.685 + endloop + endfacet + facet normal 0.982973 0 -0.18375 + outer loop + vertex -95.3502 -82 25.2027 + vertex -95.26 -101 25.685 + vertex -95.3502 -101 25.2027 + endloop + endfacet + facet normal 0.982973 -0 0.18375 + outer loop + vertex -95.3502 -101 26.1673 + vertex -95.26 -82 25.685 + vertex -95.3502 -82 26.1673 + endloop + endfacet + facet normal 0.982973 0 0.18375 + outer loop + vertex -95.26 -82 25.685 + vertex -95.3502 -101 26.1673 + vertex -95.26 -101 25.685 + endloop + endfacet + facet normal 0.850222 -0 0.526424 + outer loop + vertex -95.6084 -101 26.5844 + vertex -95.3502 -82 26.1673 + vertex -95.6084 -82 26.5844 + endloop + endfacet + facet normal 0.850222 0 0.526424 + outer loop + vertex -95.3502 -82 26.1673 + vertex -95.6084 -101 26.5844 + vertex -95.3502 -101 26.1673 + endloop + endfacet + facet normal 0.602619 0 0.798029 + outer loop + vertex -96 -82 26.88 + vertex -95.6084 -101 26.5844 + vertex -95.6084 -82 26.5844 + endloop + endfacet + facet normal 0.602619 0 0.798029 + outer loop + vertex -95.6084 -101 26.5844 + vertex -96 -82 26.88 + vertex -96 -101 26.88 + endloop + endfacet + facet normal 0.273665 0 0.961825 + outer loop + vertex -96.4718 -82 27.0143 + vertex -96 -101 26.88 + vertex -96 -82 26.88 + endloop + endfacet + facet normal 0.273665 0 0.961825 + outer loop + vertex -96 -101 26.88 + vertex -96.4718 -82 27.0143 + vertex -96.4718 -101 27.0143 + endloop + endfacet + facet normal -0.0922827 0 0.995733 + outer loop + vertex -96.9603 -82 26.969 + vertex -96.4718 -101 27.0143 + vertex -96.4718 -82 27.0143 + endloop + endfacet + facet normal -0.0922827 0 0.995733 + outer loop + vertex -96.4718 -101 27.0143 + vertex -96.9603 -82 26.969 + vertex -96.9603 -101 26.969 + endloop + endfacet + facet normal -0.445745 0 0.89516 + outer loop + vertex -97.3995 -82 26.7503 + vertex -96.9603 -101 26.969 + vertex -96.9603 -82 26.969 + endloop + endfacet + facet normal -0.445745 0 0.89516 + outer loop + vertex -96.9603 -101 26.969 + vertex -97.3995 -82 26.7503 + vertex -97.3995 -101 26.7503 + endloop + endfacet + facet normal -0.739009 0 0.673695 + outer loop + vertex -97.73 -101 26.3878 + vertex -97.3995 -82 26.7503 + vertex -97.73 -82 26.3878 + endloop + endfacet + facet normal -0.739009 0 0.673695 + outer loop + vertex -97.3995 -82 26.7503 + vertex -97.73 -101 26.3878 + vertex -97.3995 -101 26.7503 + endloop + endfacet + facet normal -0.932469 0 0.36125 + outer loop + vertex -97.9073 -101 25.9303 + vertex -97.73 -82 26.3878 + vertex -97.9073 -82 25.9303 + endloop + endfacet + facet normal -0.932469 0 0.36125 + outer loop + vertex -97.73 -82 26.3878 + vertex -97.9073 -101 25.9303 + vertex -97.73 -101 26.3878 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -97.9073 -101 25.4397 + vertex -97.9073 -82 25.9303 + vertex -97.9073 -82 25.4397 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex -97.9073 -82 25.9303 + vertex -97.9073 -101 25.4397 + vertex -97.9073 -101 25.9303 + endloop + endfacet + facet normal -0.932469 0 -0.36125 + outer loop + vertex -97.73 -101 24.9822 + vertex -97.9073 -82 25.4397 + vertex -97.73 -82 24.9822 + endloop + endfacet + facet normal -0.932469 -0 -0.36125 + outer loop + vertex -97.9073 -82 25.4397 + vertex -97.73 -101 24.9822 + vertex -97.9073 -101 25.4397 + endloop + endfacet + facet normal -0.739002 0 -0.673704 + outer loop + vertex -97.5295 -101 24.7623 + vertex -97.73 -82 24.9822 + vertex -97.5295 -82 24.7623 + endloop + endfacet + facet normal -0.739002 -0 -0.673704 + outer loop + vertex -97.73 -82 24.9822 + vertex -97.5295 -101 24.7623 + vertex -97.73 -101 24.9822 + endloop + endfacet + facet normal -0.445737 0 -0.895164 + outer loop + vertex -96.9798 -101 24.4107 + vertex -96.9603 -82 24.401 + vertex -96.9603 -101 24.401 + endloop + endfacet + facet normal -0.445737 0 -0.895164 + outer loop + vertex -96.9603 -82 24.401 + vertex -96.9798 -101 24.4107 + vertex -96.9798 -82 24.4107 + endloop + endfacet + facet normal -0.0922857 0 -0.995733 + outer loop + vertex -96.605 -101 24.368 + vertex -96.4718 -82 24.3557 + vertex -96.4718 -101 24.3557 + endloop + endfacet + facet normal -0.0922857 0 -0.995733 + outer loop + vertex -96.4718 -82 24.3557 + vertex -96.605 -101 24.368 + vertex -96.605 -82 24.368 + endloop + endfacet + facet normal -0.0922792 0 -0.995733 + outer loop + vertex -96.9603 -101 24.401 + vertex -96.8872 -82 24.3942 + vertex -96.8872 -101 24.3942 + endloop + endfacet + facet normal -0.0922792 0 -0.995733 + outer loop + vertex -96.8872 -82 24.3942 + vertex -96.9603 -101 24.401 + vertex -96.9603 -82 24.401 + endloop + endfacet + facet normal 0.273665 0 -0.961825 + outer loop + vertex -96.4718 -101 24.3557 + vertex -96 -82 24.49 + vertex -96 -101 24.49 + endloop + endfacet + facet normal 0.273665 0 -0.961825 + outer loop + vertex -96 -82 24.49 + vertex -96.4718 -101 24.3557 + vertex -96.4718 -82 24.3557 + endloop + endfacet + facet normal 0.433867 0 0.900977 + outer loop + vertex -97.2715 -82 24.8367 + vertex -96.8755 -101 24.646 + vertex -96.8755 -82 24.646 + endloop + endfacet + facet normal 0.433867 0 0.900977 + outer loop + vertex -96.8755 -101 24.646 + vertex -97.2715 -82 24.8367 + vertex -97.2715 -101 24.8367 + endloop + endfacet + facet normal 0.781848 -0 0.623469 + outer loop + vertex -97.5725 -101 25.2143 + vertex -97.2715 -82 24.8367 + vertex -97.5725 -82 25.2143 + endloop + endfacet + facet normal 0.781848 0 0.623469 + outer loop + vertex -97.2715 -82 24.8367 + vertex -97.5725 -101 25.2143 + vertex -97.2715 -101 24.8367 + endloop + endfacet + facet normal 0.974925 -0 0.222535 + outer loop + vertex -97.68 -101 25.685 + vertex -97.5725 -82 25.2143 + vertex -97.68 -82 25.685 + endloop + endfacet + facet normal 0.974925 0 0.222535 + outer loop + vertex -97.5725 -82 25.2143 + vertex -97.68 -101 25.685 + vertex -97.5725 -101 25.2143 + endloop + endfacet + facet normal 0.974925 0 -0.222535 + outer loop + vertex -97.5725 -101 26.1557 + vertex -97.68 -82 25.685 + vertex -97.5725 -82 26.1557 + endloop + endfacet + facet normal 0.974925 0 -0.222535 + outer loop + vertex -97.68 -82 25.685 + vertex -97.5725 -101 26.1557 + vertex -97.68 -101 25.685 + endloop + endfacet + facet normal 0.781848 0 -0.623469 + outer loop + vertex -97.2715 -101 26.5333 + vertex -97.5725 -82 26.1557 + vertex -97.2715 -82 26.5333 + endloop + endfacet + facet normal 0.781848 0 -0.623469 + outer loop + vertex -97.5725 -82 26.1557 + vertex -97.2715 -101 26.5333 + vertex -97.5725 -101 26.1557 + endloop + endfacet + facet normal 0.433867 0 -0.900977 + outer loop + vertex -97.2715 -101 26.5333 + vertex -96.8364 -82 26.7428 + vertex -96.8364 -101 26.7428 + endloop + endfacet + facet normal 0.433867 0 -0.900977 + outer loop + vertex -96.8364 -82 26.7428 + vertex -97.2715 -101 26.5333 + vertex -97.2715 -82 26.5333 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -96.8364 -101 26.7428 + vertex -96.3536 -82 26.7428 + vertex -96.3536 -101 26.7428 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -96.3536 -82 26.7428 + vertex -96.8364 -101 26.7428 + vertex -96.8364 -82 26.7428 + endloop + endfacet + facet normal -0.433867 0 -0.900977 + outer loop + vertex -96.3536 -101 26.7428 + vertex -95.9185 -82 26.5333 + vertex -95.9185 -101 26.5333 + endloop + endfacet + facet normal -0.433867 0 -0.900977 + outer loop + vertex -95.9185 -82 26.5333 + vertex -96.3536 -101 26.7428 + vertex -96.3536 -82 26.7428 + endloop + endfacet + facet normal -0.781848 0 -0.623469 + outer loop + vertex -95.6175 -101 26.1557 + vertex -95.9185 -82 26.5333 + vertex -95.6175 -82 26.1557 + endloop + endfacet + facet normal -0.781848 -0 -0.623469 + outer loop + vertex -95.9185 -82 26.5333 + vertex -95.6175 -101 26.1557 + vertex -95.9185 -101 26.5333 + endloop + endfacet + facet normal -0.974925 0 -0.222535 + outer loop + vertex -95.51 -101 25.685 + vertex -95.6175 -82 26.1557 + vertex -95.51 -82 25.685 + endloop + endfacet + facet normal -0.974925 -0 -0.222535 + outer loop + vertex -95.6175 -82 26.1557 + vertex -95.51 -101 25.685 + vertex -95.6175 -101 26.1557 + endloop + endfacet + facet normal -0.974925 0 0.222535 + outer loop + vertex -95.6175 -101 25.2143 + vertex -95.51 -82 25.685 + vertex -95.6175 -82 25.2143 + endloop + endfacet + facet normal -0.974925 0 0.222535 + outer loop + vertex -95.51 -82 25.685 + vertex -95.6175 -101 25.2143 + vertex -95.51 -101 25.685 + endloop + endfacet + facet normal -0.781848 0 0.623469 + outer loop + vertex -95.9185 -101 24.8367 + vertex -95.6175 -82 25.2143 + vertex -95.9185 -82 24.8367 + endloop + endfacet + facet normal -0.781848 0 0.623469 + outer loop + vertex -95.6175 -82 25.2143 + vertex -95.9185 -101 24.8367 + vertex -95.6175 -101 25.2143 + endloop + endfacet + facet normal -0.433867 0 0.900977 + outer loop + vertex -96.3536 -82 24.6272 + vertex -95.9185 -101 24.8367 + vertex -95.9185 -82 24.8367 + endloop + endfacet + facet normal -0.433867 0 0.900977 + outer loop + vertex -95.9185 -101 24.8367 + vertex -96.3536 -82 24.6272 + vertex -96.3536 -101 24.6272 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -96.7696 -82 24.6272 + vertex -96.3536 -101 24.6272 + vertex -96.3536 -82 24.6272 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -96.3536 -101 24.6272 + vertex -96.7696 -82 24.6272 + vertex -96.7696 -101 24.6272 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.605 101 20.256 + vertex 96.8872 101 20.2058 + vertex 96.605 101 20.232 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.981 101 20.5 + vertex -106.981 101 19.1223 + vertex -107 101 20.5 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.8872 101 24.3942 + vertex 96.605 101 24.344 + vertex 96.605 101 24.368 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 106.139 101 26.2927 + vertex 106.523 101 25.9943 + vertex 106.146 101 26.04 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107.009 101 25.9631 + vertex 106.523 101 25.9943 + vertex 106.615 101 26.235 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107.009 101 25.9631 + vertex 106.816 101 25.7924 + vertex 106.523 101 25.9943 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107.231 101 25.5393 + vertex 106.816 101 25.7924 + vertex 107.009 101 25.9631 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107.231 101 25.5393 + vertex 106.981 101 25.4777 + vertex 106.816 101 25.7924 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107.231 101 25.5393 + vertex 106.981 101 24.13 + vertex 106.981 101 25.4777 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 106.981 101 24.13 + vertex 106.981 101 22.13 + vertex -106.981 101 24.13 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 107 101 22.1 + vertex 106.981 101 24.13 + vertex 107.231 101 25.5393 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 106.981 101 24.13 + vertex 107 101 22.1 + vertex 106.981 101 22.13 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 107.231 101 19.0607 + vertex 107 101 22.1 + vertex 107.231 101 25.5393 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107 101 20.5 + vertex 106.981 101 19.1223 + vertex 106.981 101 20.5 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107 101 22.1 + vertex 107.231 101 19.0607 + vertex 107 101 20.5 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107 101 20.5 + vertex 107.231 101 19.0607 + vertex 106.981 101 19.1223 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107.231 101 19.0607 + vertex 106.816 101 18.8076 + vertex 106.981 101 19.1223 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 107.009 101 18.6369 + vertex 106.816 101 18.8076 + vertex 107.231 101 19.0607 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107.009 101 18.6369 + vertex 106.523 101 18.6057 + vertex 106.816 101 18.8076 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 106.615 101 18.365 + vertex 106.523 101 18.6057 + vertex 107.009 101 18.6369 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 106.139 101 18.3073 + vertex 106.523 101 18.6057 + vertex 106.615 101 18.365 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 106.523 101 25.9943 + vertex 106.139 101 26.2927 + vertex 106.615 101 26.235 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 106.146 101 26.04 + vertex 97.5295 101 24.7623 + vertex 106.139 101 26.2927 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.9798 101 24.4107 + vertex 97.5295 101 24.7623 + vertex 106.146 101 26.04 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.5295 101 24.7623 + vertex 96.9798 101 24.4107 + vertex 96.8755 101 24.646 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 96.605 101 24.368 + vertex 96.3536 101 24.6272 + vertex 96.7696 101 24.6272 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 96.8872 101 24.3942 + vertex 96.8755 101 24.646 + vertex 96.9798 101 24.4107 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.8755 101 24.646 + vertex 96.8872 101 24.3942 + vertex 96.7696 101 24.6272 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.8872 101 24.3942 + vertex 96.9798 101 24.4107 + vertex 96.9603 101 24.401 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.605 101 24.368 + vertex 96.7696 101 24.6272 + vertex 96.8872 101 24.3942 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.3536 101 24.6272 + vertex 96.605 101 24.368 + vertex 96.4718 101 24.3557 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.3536 101 24.6272 + vertex 96.4718 101 24.3557 + vertex 96 101 24.49 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.9603 101 26.969 + vertex 97.2715 101 26.5333 + vertex 96.8364 101 26.7428 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.73 101 26.3878 + vertex 97.2715 101 26.5333 + vertex 97.3995 101 26.7503 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.73 101 26.3878 + vertex 97.5725 101 26.1557 + vertex 97.2715 101 26.5333 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.9073 101 25.9303 + vertex 97.5725 101 26.1557 + vertex 97.73 101 26.3878 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.9073 101 25.9303 + vertex 97.68 101 25.685 + vertex 97.5725 101 26.1557 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 97.9073 101 25.4397 + vertex 97.68 101 25.685 + vertex 97.9073 101 25.9303 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.9073 101 25.4397 + vertex 97.5725 101 25.2143 + vertex 97.68 101 25.685 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 97.73 101 24.9822 + vertex 97.5725 101 25.2143 + vertex 97.9073 101 25.4397 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.5295 101 24.7623 + vertex 97.5725 101 25.2143 + vertex 97.73 101 24.9822 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.5725 101 25.2143 + vertex 97.5295 101 24.7623 + vertex 97.2715 101 24.8367 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.2715 101 24.8367 + vertex 97.5295 101 24.7623 + vertex 96.8755 101 24.646 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 96.8364 101 26.7428 + vertex 96.4718 101 27.0143 + vertex 96.9603 101 26.969 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 97.2715 101 26.5333 + vertex 96.9603 101 26.969 + vertex 97.3995 101 26.7503 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.4718 101 27.0143 + vertex 96.8364 101 26.7428 + vertex 96.3536 101 26.7428 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.4718 101 27.0143 + vertex 96.3536 101 26.7428 + vertex 96 101 26.88 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.9185 101 26.5333 + vertex 96 101 26.88 + vertex 96.3536 101 26.7428 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96 101 26.88 + vertex 95.9185 101 26.5333 + vertex 95.6084 101 26.5844 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 95.6175 101 26.1557 + vertex 95.6084 101 26.5844 + vertex 95.9185 101 26.5333 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.6084 101 26.5844 + vertex 95.6175 101 26.1557 + vertex 95.3502 101 26.1673 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 95.51 101 25.685 + vertex 95.3502 101 26.1673 + vertex 95.6175 101 26.1557 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.51 101 25.685 + vertex 95.26 101 25.685 + vertex 95.3502 101 26.1673 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.3502 101 25.2027 + vertex 95.51 101 25.685 + vertex 95.6175 101 25.2143 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.51 101 25.685 + vertex 95.3502 101 25.2027 + vertex 95.26 101 25.685 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.6084 101 24.7856 + vertex 95.6175 101 25.2143 + vertex 95.9185 101 24.8367 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.6175 101 25.2143 + vertex 95.6084 101 24.7856 + vertex 95.3502 101 25.2027 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 96 101 24.49 + vertex 95.9185 101 24.8367 + vertex 96.3536 101 24.6272 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.9185 101 24.8367 + vertex 96 101 24.49 + vertex 95.6084 101 24.7856 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -96.3536 101 26.7428 + vertex -96.4718 101 27.0143 + vertex -96 101 26.88 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.8364 101 26.7428 + vertex -96.4718 101 27.0143 + vertex -96.3536 101 26.7428 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.4718 101 27.0143 + vertex -96.8364 101 26.7428 + vertex -96.9603 101 26.969 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -95.9185 101 26.5333 + vertex -96 101 26.88 + vertex -95.6084 101 26.5844 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96 101 26.88 + vertex -95.9185 101 26.5333 + vertex -96.3536 101 26.7428 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.6175 101 26.1557 + vertex -95.6084 101 26.5844 + vertex -95.3502 101 26.1673 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.6084 101 26.5844 + vertex -95.6175 101 26.1557 + vertex -95.9185 101 26.5333 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.51 101 25.685 + vertex -95.3502 101 26.1673 + vertex -95.26 101 25.685 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.3502 101 26.1673 + vertex -95.51 101 25.685 + vertex -95.6175 101 26.1557 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -95.3502 101 25.2027 + vertex -95.51 101 25.685 + vertex -95.26 101 25.685 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.51 101 25.685 + vertex -95.3502 101 25.2027 + vertex -95.6175 101 25.2143 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -95.6084 101 24.7856 + vertex -95.6175 101 25.2143 + vertex -95.3502 101 25.2027 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.6175 101 25.2143 + vertex -95.6084 101 24.7856 + vertex -95.9185 101 24.8367 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96 101 24.49 + vertex -95.9185 101 24.8367 + vertex -95.6084 101 24.7856 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.4718 101 24.3557 + vertex -96.3536 101 24.6272 + vertex -96 101 24.49 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.9185 101 24.8367 + vertex -96 101 24.49 + vertex -96.3536 101 24.6272 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.2715 101 26.5333 + vertex -96.9603 101 26.969 + vertex -96.8364 101 26.7428 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.9603 101 26.969 + vertex -97.2715 101 26.5333 + vertex -97.3995 101 26.7503 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.2715 101 26.5333 + vertex -97.73 101 26.3878 + vertex -97.3995 101 26.7503 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -97.5725 101 26.1557 + vertex -97.73 101 26.3878 + vertex -97.2715 101 26.5333 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5725 101 26.1557 + vertex -97.9073 101 25.9303 + vertex -97.73 101 26.3878 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -97.68 101 25.685 + vertex -97.9073 101 25.9303 + vertex -97.5725 101 26.1557 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.68 101 25.685 + vertex -97.9073 101 25.4397 + vertex -97.9073 101 25.9303 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5725 101 25.2143 + vertex -97.9073 101 25.4397 + vertex -97.68 101 25.685 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5725 101 25.2143 + vertex -97.73 101 24.9822 + vertex -97.9073 101 25.4397 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -97.5295 101 24.7623 + vertex -97.5725 101 25.2143 + vertex -97.2715 101 24.8367 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5725 101 25.2143 + vertex -97.5295 101 24.7623 + vertex -97.73 101 24.9822 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -96.9798 101 24.4107 + vertex -97.2715 101 24.8367 + vertex -96.8755 101 24.646 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.523 101 25.9943 + vertex -106.139 101 26.2927 + vertex -106.146 101 26.04 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5295 101 24.7623 + vertex -106.146 101 26.04 + vertex -106.139 101 26.2927 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.2715 101 24.8367 + vertex -96.9798 101 24.4107 + vertex -97.5295 101 24.7623 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.8872 101 24.3942 + vertex -96.8755 101 24.646 + vertex -96.7696 101 24.6272 + endloop + endfacet + facet normal -0 1 0 + outer loop + vertex -96.605 101 24.368 + vertex -96.3536 101 24.6272 + vertex -96.4718 101 24.3557 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5295 101 24.7623 + vertex -96.9798 101 24.4107 + vertex -106.146 101 26.04 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.8755 101 24.646 + vertex -96.8872 101 24.3942 + vertex -96.9798 101 24.4107 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.9798 101 24.4107 + vertex -96.8872 101 24.3942 + vertex -96.9603 101 24.401 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.7696 101 24.6272 + vertex -96.605 101 24.368 + vertex -96.8872 101 24.3942 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.3536 101 24.6272 + vertex -96.605 101 24.368 + vertex -96.7696 101 24.6272 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.139 101 26.2927 + vertex -106.523 101 25.9943 + vertex -106.615 101 26.235 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.523 101 25.9943 + vertex -107.009 101 25.9631 + vertex -106.615 101 26.235 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -106.816 101 25.7924 + vertex -107.009 101 25.9631 + vertex -106.523 101 25.9943 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.816 101 25.7924 + vertex -107.231 101 25.5393 + vertex -107.009 101 25.9631 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -106.981 101 25.4777 + vertex -107.231 101 25.5393 + vertex -106.816 101 25.7924 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -106.981 101 24.13 + vertex -107.231 101 25.5393 + vertex -106.981 101 25.4777 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.981 101 22.13 + vertex -106.981 101 24.13 + vertex 106.981 101 22.13 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -107 101 22.1 + vertex -106.981 101 24.13 + vertex -106.981 101 22.13 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -107 101 22.1 + vertex -106.981 101 22.13 + vertex -106.981 101 22.1 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.981 101 24.13 + vertex -107 101 22.1 + vertex -107.231 101 25.5393 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -107.231 101 19.0607 + vertex -107 101 22.1 + vertex -107 101 20.5 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -107.231 101 19.0607 + vertex -107 101 20.5 + vertex -106.981 101 19.1223 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -107 101 22.1 + vertex -107.231 101 19.0607 + vertex -107.231 101 25.5393 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.816 101 18.8076 + vertex -107.231 101 19.0607 + vertex -106.981 101 19.1223 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.816 101 18.8076 + vertex -107.009 101 18.6369 + vertex -107.231 101 19.0607 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.523 101 18.6057 + vertex -107.009 101 18.6369 + vertex -106.816 101 18.8076 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.139 101 18.3073 + vertex -106.523 101 18.6057 + vertex -106.146 101 18.56 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.523 101 18.6057 + vertex -106.615 101 18.365 + vertex -107.009 101 18.6369 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.8872 101 24.3942 + vertex -96.605 101 24.368 + vertex -96.605 101 24.344 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 106.981 101 22.13 + vertex 107 101 22.1 + vertex 106.981 101 22.1 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.9798 101 20.1893 + vertex 96.8872 101 20.2058 + vertex 96.9603 101 20.199 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.8755 101 19.954 + vertex 96.8872 101 20.2058 + vertex 96.9798 101 20.1893 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.8872 101 20.2058 + vertex 96.7696 101 19.9728 + vertex 96.605 101 20.232 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.3536 101 19.9728 + vertex 96.605 101 20.232 + vertex 96.7696 101 19.9728 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.605 101 20.232 + vertex 96.3536 101 19.9728 + vertex 96.4718 101 20.2443 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.8872 101 20.2058 + vertex 96.8755 101 19.954 + vertex 96.7696 101 19.9728 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 97.2715 101 19.7633 + vertex 96.9798 101 20.1893 + vertex 97.5295 101 19.8377 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 106.146 101 18.56 + vertex 97.5295 101 19.8377 + vertex 96.9798 101 20.1893 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 106.523 101 18.6057 + vertex 106.139 101 18.3073 + vertex 106.146 101 18.56 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 106.146 101 18.56 + vertex 106.139 101 18.3073 + vertex 97.5295 101 19.8377 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.4718 101 20.2443 + vertex 96.3536 101 19.9728 + vertex 96 101 20.11 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.9185 101 19.7633 + vertex 96 101 20.11 + vertex 96.3536 101 19.9728 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96 101 20.11 + vertex 95.9185 101 19.7633 + vertex 95.6084 101 19.8144 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 95.6175 101 19.3857 + vertex 95.6084 101 19.8144 + vertex 95.9185 101 19.7633 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.6084 101 19.8144 + vertex 95.6175 101 19.3857 + vertex 95.3502 101 19.3973 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 95.51 101 18.915 + vertex 95.3502 101 19.3973 + vertex 95.6175 101 19.3857 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.51 101 18.915 + vertex 95.26 101 18.915 + vertex 95.3502 101 19.3973 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.3502 101 18.4327 + vertex 95.51 101 18.915 + vertex 95.6175 101 18.4443 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.51 101 18.915 + vertex 95.3502 101 18.4327 + vertex 95.26 101 18.915 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.6084 101 18.0156 + vertex 95.6175 101 18.4443 + vertex 95.9185 101 18.0667 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.6175 101 18.4443 + vertex 95.6084 101 18.0156 + vertex 95.3502 101 18.4327 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 96 101 17.72 + vertex 95.9185 101 18.0667 + vertex 96.3536 101 17.8572 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.9185 101 18.0667 + vertex 96 101 17.72 + vertex 95.6084 101 18.0156 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.8364 101 17.8572 + vertex 96 101 17.72 + vertex 96.3536 101 17.8572 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.4718 101 17.5857 + vertex 96.8364 101 17.8572 + vertex 96.9603 101 17.631 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.8364 101 17.8572 + vertex 96.4718 101 17.5857 + vertex 96 101 17.72 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.9798 101 20.1893 + vertex 97.2715 101 19.7633 + vertex 96.8755 101 19.954 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 97.5725 101 19.3857 + vertex 97.5295 101 19.8377 + vertex 97.73 101 19.6178 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.5295 101 19.8377 + vertex 97.5725 101 19.3857 + vertex 97.2715 101 19.7633 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.9073 101 19.1603 + vertex 97.5725 101 19.3857 + vertex 97.73 101 19.6178 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.9073 101 19.1603 + vertex 97.68 101 18.915 + vertex 97.5725 101 19.3857 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 97.9073 101 18.6697 + vertex 97.68 101 18.915 + vertex 97.9073 101 19.1603 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.9073 101 18.6697 + vertex 97.5725 101 18.4443 + vertex 97.68 101 18.915 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 97.73 101 18.2122 + vertex 97.5725 101 18.4443 + vertex 97.9073 101 18.6697 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.73 101 18.2122 + vertex 97.2715 101 18.0667 + vertex 97.5725 101 18.4443 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 97.3995 101 17.8497 + vertex 97.2715 101 18.0667 + vertex 97.73 101 18.2122 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.2715 101 18.0667 + vertex 96.9603 101 17.631 + vertex 96.8364 101 17.8572 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.9603 101 17.631 + vertex 97.2715 101 18.0667 + vertex 97.3995 101 17.8497 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.9798 101 20.1893 + vertex -97.2715 101 19.7633 + vertex -97.5295 101 19.8377 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5725 101 19.3857 + vertex -97.5295 101 19.8377 + vertex -97.2715 101 19.7633 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5295 101 19.8377 + vertex -97.5725 101 19.3857 + vertex -97.73 101 19.6178 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5725 101 19.3857 + vertex -97.9073 101 19.1603 + vertex -97.73 101 19.6178 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -97.68 101 18.915 + vertex -97.9073 101 19.1603 + vertex -97.5725 101 19.3857 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.68 101 18.915 + vertex -97.9073 101 18.6697 + vertex -97.9073 101 19.1603 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5725 101 18.4443 + vertex -97.9073 101 18.6697 + vertex -97.68 101 18.915 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.5725 101 18.4443 + vertex -97.73 101 18.2122 + vertex -97.9073 101 18.6697 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.2715 101 18.0667 + vertex -97.73 101 18.2122 + vertex -97.5725 101 18.4443 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -96.9603 101 17.631 + vertex -97.2715 101 18.0667 + vertex -96.8364 101 17.8572 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.2715 101 18.0667 + vertex -97.3995 101 17.8497 + vertex -97.73 101 18.2122 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -95.9185 101 19.7633 + vertex -96 101 20.11 + vertex -95.6084 101 19.8144 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96 101 20.11 + vertex -95.9185 101 19.7633 + vertex -96.3536 101 19.9728 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.6175 101 19.3857 + vertex -95.6084 101 19.8144 + vertex -95.3502 101 19.3973 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.6084 101 19.8144 + vertex -95.6175 101 19.3857 + vertex -95.9185 101 19.7633 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.51 101 18.915 + vertex -95.3502 101 19.3973 + vertex -95.26 101 18.915 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.3502 101 19.3973 + vertex -95.51 101 18.915 + vertex -95.6175 101 19.3857 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -95.3502 101 18.4327 + vertex -95.51 101 18.915 + vertex -95.26 101 18.915 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.51 101 18.915 + vertex -95.3502 101 18.4327 + vertex -95.6175 101 18.4443 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -95.6084 101 18.0156 + vertex -95.6175 101 18.4443 + vertex -95.3502 101 18.4327 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.6175 101 18.4443 + vertex -95.6084 101 18.0156 + vertex -95.9185 101 18.0667 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96 101 17.72 + vertex -95.9185 101 18.0667 + vertex -95.6084 101 18.0156 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -96.4718 101 17.5857 + vertex -96.8364 101 17.8572 + vertex -96.3536 101 17.8572 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -95.9185 101 18.0667 + vertex -96 101 17.72 + vertex -96.3536 101 17.8572 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.4718 101 17.5857 + vertex -96.3536 101 17.8572 + vertex -96 101 17.72 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.2715 101 18.0667 + vertex -96.9603 101 17.631 + vertex -97.3995 101 17.8497 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.8364 101 17.8572 + vertex -96.4718 101 17.5857 + vertex -96.9603 101 17.631 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.8872 101 20.2058 + vertex -96.9798 101 20.1893 + vertex -96.9603 101 20.199 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -96.7696 101 19.9728 + vertex -96.8872 101 20.2058 + vertex -96.605 101 20.232 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.3536 101 19.9728 + vertex -96.605 101 20.232 + vertex -96.4718 101 20.2443 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -96.3536 101 19.9728 + vertex -96.4718 101 20.2443 + vertex -96 101 20.11 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.605 101 20.232 + vertex -96.3536 101 19.9728 + vertex -96.7696 101 19.9728 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -96.8755 101 19.954 + vertex -96.8872 101 20.2058 + vertex -96.7696 101 19.9728 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.8872 101 20.2058 + vertex -96.8755 101 19.954 + vertex -96.9798 101 20.1893 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -97.2715 101 19.7633 + vertex -96.9798 101 20.1893 + vertex -96.8755 101 19.954 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -97.5295 101 19.8377 + vertex -106.146 101 18.56 + vertex -96.9798 101 20.1893 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex -106.139 101 18.3073 + vertex -106.146 101 18.56 + vertex -97.5295 101 19.8377 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -106.523 101 18.6057 + vertex -106.139 101 18.3073 + vertex -106.615 101 18.365 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -96.605 101 20.256 + vertex -96.605 101 20.232 + vertex -96.8872 101 20.2058 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.8872 82 24.3942 + vertex -96.605 82 24.344 + vertex -96.605 82 24.368 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -106.139 82 26.2927 + vertex -106.523 82 25.9943 + vertex -106.146 82 26.04 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107.009 82 25.9631 + vertex -106.523 82 25.9943 + vertex -106.615 82 26.235 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107.009 82 25.9631 + vertex -106.816 82 25.7924 + vertex -106.523 82 25.9943 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107.231 82 25.5393 + vertex -106.816 82 25.7924 + vertex -107.009 82 25.9631 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107.231 82 25.5393 + vertex -106.981 82 25.4777 + vertex -106.816 82 25.7924 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107.231 82 25.5393 + vertex -107 82 24.13 + vertex -106.981 82 25.4777 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107.231 82 25.5393 + vertex -107 82 22.13 + vertex -107 82 24.13 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107 82 22.13 + vertex -107 82 22.1 + vertex -106.981 82 22.13 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107.231 82 25.5393 + vertex -107 82 22.1 + vertex -107 82 22.13 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107.231 82 19.0607 + vertex -107 82 22.1 + vertex -107.231 82 25.5393 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107 82 20.5 + vertex -106.981 82 19.1223 + vertex -106.981 82 20.5 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -107 82 22.1 + vertex -107.231 82 19.0607 + vertex -107 82 20.5 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -107 82 20.5 + vertex -107.231 82 19.0607 + vertex -106.981 82 19.1223 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107.231 82 19.0607 + vertex -106.816 82 18.8076 + vertex -106.981 82 19.1223 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107.009 82 18.6369 + vertex -106.816 82 18.8076 + vertex -107.231 82 19.0607 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107.009 82 18.6369 + vertex -106.523 82 18.6057 + vertex -106.816 82 18.8076 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -106.615 82 18.365 + vertex -106.523 82 18.6057 + vertex -107.009 82 18.6369 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -106.139 82 18.3073 + vertex -106.523 82 18.6057 + vertex -106.615 82 18.365 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -106.523 82 25.9943 + vertex -106.139 82 26.2927 + vertex -106.615 82 26.235 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -106.146 82 26.04 + vertex -97.5295 82 24.7623 + vertex -106.139 82 26.2927 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.9798 82 24.4107 + vertex -97.5295 82 24.7623 + vertex -106.146 82 26.04 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.5295 82 24.7623 + vertex -96.9798 82 24.4107 + vertex -96.8755 82 24.646 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.605 82 24.368 + vertex -96.3536 82 24.6272 + vertex -96.7696 82 24.6272 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.8872 82 24.3942 + vertex -96.8755 82 24.646 + vertex -96.9798 82 24.4107 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -96.8755 82 24.646 + vertex -96.8872 82 24.3942 + vertex -96.7696 82 24.6272 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.8872 82 24.3942 + vertex -96.9798 82 24.4107 + vertex -96.9603 82 24.401 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.605 82 24.368 + vertex -96.7696 82 24.6272 + vertex -96.8872 82 24.3942 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.3536 82 24.6272 + vertex -96.605 82 24.368 + vertex -96.4718 82 24.3557 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -96.3536 82 24.6272 + vertex -96.4718 82 24.3557 + vertex -96 82 24.49 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -96.9603 82 26.969 + vertex -97.2715 82 26.5333 + vertex -96.8364 82 26.7428 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.73 82 26.3878 + vertex -97.2715 82 26.5333 + vertex -97.3995 82 26.7503 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.73 82 26.3878 + vertex -97.5725 82 26.1557 + vertex -97.2715 82 26.5333 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.9073 82 25.9303 + vertex -97.5725 82 26.1557 + vertex -97.73 82 26.3878 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.9073 82 25.9303 + vertex -97.68 82 25.685 + vertex -97.5725 82 26.1557 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.9073 82 25.4397 + vertex -97.68 82 25.685 + vertex -97.9073 82 25.9303 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.9073 82 25.4397 + vertex -97.5725 82 25.2143 + vertex -97.68 82 25.685 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.73 82 24.9822 + vertex -97.5725 82 25.2143 + vertex -97.9073 82 25.4397 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.5295 82 24.7623 + vertex -97.5725 82 25.2143 + vertex -97.73 82 24.9822 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.5725 82 25.2143 + vertex -97.5295 82 24.7623 + vertex -97.2715 82 24.8367 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -97.2715 82 24.8367 + vertex -97.5295 82 24.7623 + vertex -96.8755 82 24.646 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.8364 82 26.7428 + vertex -96.4718 82 27.0143 + vertex -96.9603 82 26.969 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.2715 82 26.5333 + vertex -96.9603 82 26.969 + vertex -97.3995 82 26.7503 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -96.4718 82 27.0143 + vertex -96.8364 82 26.7428 + vertex -96.3536 82 26.7428 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.4718 82 27.0143 + vertex -96.3536 82 26.7428 + vertex -96 82 26.88 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.9185 82 26.5333 + vertex -96 82 26.88 + vertex -96.3536 82 26.7428 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96 82 26.88 + vertex -95.9185 82 26.5333 + vertex -95.6084 82 26.5844 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.6175 82 26.1557 + vertex -95.6084 82 26.5844 + vertex -95.9185 82 26.5333 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -95.6084 82 26.5844 + vertex -95.6175 82 26.1557 + vertex -95.3502 82 26.1673 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.51 82 25.685 + vertex -95.3502 82 26.1673 + vertex -95.6175 82 26.1557 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.51 82 25.685 + vertex -95.26 82 25.685 + vertex -95.3502 82 26.1673 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.3502 82 25.2027 + vertex -95.51 82 25.685 + vertex -95.6175 82 25.2143 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.51 82 25.685 + vertex -95.3502 82 25.2027 + vertex -95.26 82 25.685 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.6084 82 24.7856 + vertex -95.6175 82 25.2143 + vertex -95.9185 82 24.8367 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.6175 82 25.2143 + vertex -95.6084 82 24.7856 + vertex -95.3502 82 25.2027 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96 82 24.49 + vertex -95.9185 82 24.8367 + vertex -96.3536 82 24.6272 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -95.9185 82 24.8367 + vertex -96 82 24.49 + vertex -95.6084 82 24.7856 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -106.981 82 25.4777 + vertex -107 82 24.13 + vertex -106.981 82 24.13 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -106.981 82 22.13 + vertex -107 82 22.1 + vertex -106.981 82 22.1 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -96.605 82 20.256 + vertex -96.8872 82 20.2058 + vertex -96.605 82 20.232 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.9798 82 20.1893 + vertex -96.8872 82 20.2058 + vertex -96.9603 82 20.199 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.8755 82 19.954 + vertex -96.8872 82 20.2058 + vertex -96.9798 82 20.1893 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.8872 82 20.2058 + vertex -96.7696 82 19.9728 + vertex -96.605 82 20.232 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.3536 82 19.9728 + vertex -96.605 82 20.232 + vertex -96.7696 82 19.9728 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.605 82 20.232 + vertex -96.3536 82 19.9728 + vertex -96.4718 82 20.2443 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.8872 82 20.2058 + vertex -96.8755 82 19.954 + vertex -96.7696 82 19.9728 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.2715 82 19.7633 + vertex -96.9798 82 20.1893 + vertex -97.5295 82 19.8377 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -106.146 82 18.56 + vertex -97.5295 82 19.8377 + vertex -96.9798 82 20.1893 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -106.523 82 18.6057 + vertex -106.139 82 18.3073 + vertex -106.146 82 18.56 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -106.146 82 18.56 + vertex -106.139 82 18.3073 + vertex -97.5295 82 19.8377 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.4718 82 20.2443 + vertex -96.3536 82 19.9728 + vertex -96 82 20.11 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.9185 82 19.7633 + vertex -96 82 20.11 + vertex -96.3536 82 19.9728 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96 82 20.11 + vertex -95.9185 82 19.7633 + vertex -95.6084 82 19.8144 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.6175 82 19.3857 + vertex -95.6084 82 19.8144 + vertex -95.9185 82 19.7633 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -95.6084 82 19.8144 + vertex -95.6175 82 19.3857 + vertex -95.3502 82 19.3973 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.51 82 18.915 + vertex -95.3502 82 19.3973 + vertex -95.6175 82 19.3857 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.51 82 18.915 + vertex -95.26 82 18.915 + vertex -95.3502 82 19.3973 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.3502 82 18.4327 + vertex -95.51 82 18.915 + vertex -95.6175 82 18.4443 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.51 82 18.915 + vertex -95.3502 82 18.4327 + vertex -95.26 82 18.915 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.6084 82 18.0156 + vertex -95.6175 82 18.4443 + vertex -95.9185 82 18.0667 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -95.6175 82 18.4443 + vertex -95.6084 82 18.0156 + vertex -95.3502 82 18.4327 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96 82 17.72 + vertex -95.9185 82 18.0667 + vertex -96.3536 82 17.8572 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -95.9185 82 18.0667 + vertex -96 82 17.72 + vertex -95.6084 82 18.0156 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.8364 82 17.8572 + vertex -96 82 17.72 + vertex -96.3536 82 17.8572 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.4718 82 17.5857 + vertex -96.8364 82 17.8572 + vertex -96.9603 82 17.631 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.8364 82 17.8572 + vertex -96.4718 82 17.5857 + vertex -96 82 17.72 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -96.9798 82 20.1893 + vertex -97.2715 82 19.7633 + vertex -96.8755 82 19.954 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.5725 82 19.3857 + vertex -97.5295 82 19.8377 + vertex -97.73 82 19.6178 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex -97.5295 82 19.8377 + vertex -97.5725 82 19.3857 + vertex -97.2715 82 19.7633 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.9073 82 19.1603 + vertex -97.5725 82 19.3857 + vertex -97.73 82 19.6178 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.9073 82 19.1603 + vertex -97.68 82 18.915 + vertex -97.5725 82 19.3857 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.9073 82 18.6697 + vertex -97.68 82 18.915 + vertex -97.9073 82 19.1603 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.9073 82 18.6697 + vertex -97.5725 82 18.4443 + vertex -97.68 82 18.915 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.73 82 18.2122 + vertex -97.5725 82 18.4443 + vertex -97.9073 82 18.6697 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.73 82 18.2122 + vertex -97.2715 82 18.0667 + vertex -97.5725 82 18.4443 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.3995 82 17.8497 + vertex -97.2715 82 18.0667 + vertex -97.73 82 18.2122 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -97.2715 82 18.0667 + vertex -96.9603 82 17.631 + vertex -96.8364 82 17.8572 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -96.9603 82 17.631 + vertex -97.2715 82 18.0667 + vertex -97.3995 82 17.8497 + endloop + endfacet + facet normal 0.175007 0 0.984567 + outer loop + vertex -106.139 101 26.2927 + vertex -97.5295 82 24.7623 + vertex -97.5295 101 24.7623 + endloop + endfacet + facet normal 0.175007 0 0.984567 + outer loop + vertex -97.5295 82 24.7623 + vertex -106.139 101 26.2927 + vertex -106.139 82 26.2927 + endloop + endfacet + facet normal 0.175 0 0.984568 + outer loop + vertex -96.8755 101 24.646 + vertex -96.7696 82 24.6272 + vertex -96.7696 101 24.6272 + endloop + endfacet + facet normal 0.175 0 0.984568 + outer loop + vertex -96.7696 82 24.6272 + vertex -96.8755 101 24.646 + vertex -96.8755 82 24.646 + endloop + endfacet + facet normal -0.120538 0 0.992709 + outer loop + vertex -106.615 101 26.235 + vertex -106.139 82 26.2927 + vertex -106.139 101 26.2927 + endloop + endfacet + facet normal -0.120538 0 0.992709 + outer loop + vertex -106.139 82 26.2927 + vertex -106.615 101 26.235 + vertex -106.615 82 26.235 + endloop + endfacet + facet normal -0.568069 0 0.822981 + outer loop + vertex -107.009 101 25.9631 + vertex -106.615 82 26.235 + vertex -106.615 101 26.235 + endloop + endfacet + facet normal -0.568069 0 0.822981 + outer loop + vertex -106.615 82 26.235 + vertex -107.009 101 25.9631 + vertex -107.009 82 25.9631 + endloop + endfacet + facet normal -0.885462 0 0.464712 + outer loop + vertex -107.231 82 25.5393 + vertex -107.009 101 25.9631 + vertex -107.231 101 25.5393 + endloop + endfacet + facet normal -0.885462 0 0.464712 + outer loop + vertex -107.009 101 25.9631 + vertex -107.231 82 25.5393 + vertex -107.009 82 25.9631 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -107.231 82 19.0607 + vertex -107.231 101 25.5393 + vertex -107.231 101 19.0607 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex -107.231 101 25.5393 + vertex -107.231 82 19.0607 + vertex -107.231 82 25.5393 + endloop + endfacet + facet normal -0.885462 0 -0.464712 + outer loop + vertex -107.009 82 18.6369 + vertex -107.231 101 19.0607 + vertex -107.009 101 18.6369 + endloop + endfacet + facet normal -0.885462 -0 -0.464712 + outer loop + vertex -107.231 101 19.0607 + vertex -107.009 82 18.6369 + vertex -107.231 82 19.0607 + endloop + endfacet + facet normal -0.568069 0 -0.822981 + outer loop + vertex -107.009 82 18.6369 + vertex -106.615 101 18.365 + vertex -106.615 82 18.365 + endloop + endfacet + facet normal -0.568069 0 -0.822981 + outer loop + vertex -106.615 101 18.365 + vertex -107.009 82 18.6369 + vertex -107.009 101 18.6369 + endloop + endfacet + facet normal -0.120538 0 -0.992709 + outer loop + vertex -106.615 82 18.365 + vertex -106.139 101 18.3073 + vertex -106.139 82 18.3073 + endloop + endfacet + facet normal -0.120538 0 -0.992709 + outer loop + vertex -106.139 101 18.3073 + vertex -106.615 82 18.365 + vertex -106.615 101 18.365 + endloop + endfacet + facet normal 0.175008 0 -0.984567 + outer loop + vertex -106.139 82 18.3073 + vertex -97.5295 101 19.8377 + vertex -97.5295 82 19.8377 + endloop + endfacet + facet normal 0.175008 0 -0.984567 + outer loop + vertex -97.5295 101 19.8377 + vertex -106.139 82 18.3073 + vertex -106.139 101 18.3073 + endloop + endfacet + facet normal 0.175 0 -0.984568 + outer loop + vertex -96.8755 82 19.954 + vertex -96.7696 101 19.9728 + vertex -96.7696 82 19.9728 + endloop + endfacet + facet normal 0.175 0 -0.984568 + outer loop + vertex -96.7696 101 19.9728 + vertex -96.8755 82 19.954 + vertex -96.8755 101 19.954 + endloop + endfacet + facet normal 0.568073 0 0.822978 + outer loop + vertex -106.816 101 18.8076 + vertex -106.523 82 18.6057 + vertex -106.523 101 18.6057 + endloop + endfacet + facet normal 0.568073 0 0.822978 + outer loop + vertex -106.523 82 18.6057 + vertex -106.816 101 18.8076 + vertex -106.816 82 18.8076 + endloop + endfacet + facet normal 0.88547 -0 0.464697 + outer loop + vertex -106.981 82 19.1223 + vertex -106.816 101 18.8076 + vertex -106.981 101 19.1223 + endloop + endfacet + facet normal 0.88547 0 0.464697 + outer loop + vertex -106.816 101 18.8076 + vertex -106.981 82 19.1223 + vertex -106.816 82 18.8076 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex -106.981 82 25.4777 + vertex -106.981 101 24.13 + vertex -106.981 101 25.4777 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex -106.981 101 24.13 + vertex -106.981 82 25.4777 + vertex -106.981 82 24.13 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex -106.981 82 20.5 + vertex -106.981 101 19.1223 + vertex -106.981 101 20.5 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex -106.981 101 19.1223 + vertex -106.981 82 20.5 + vertex -106.981 82 19.1223 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex -106.981 82 22.13 + vertex -106.981 101 22.1 + vertex -106.981 101 22.13 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex -106.981 101 22.1 + vertex -106.981 82 22.13 + vertex -106.981 82 22.1 + endloop + endfacet + facet normal 0.88547 0 -0.464697 + outer loop + vertex -106.816 82 25.7924 + vertex -106.981 101 25.4777 + vertex -106.816 101 25.7924 + endloop + endfacet + facet normal 0.88547 0 -0.464697 + outer loop + vertex -106.981 101 25.4777 + vertex -106.816 82 25.7924 + vertex -106.981 82 25.4777 + endloop + endfacet + facet normal 0.568073 0 -0.822978 + outer loop + vertex -106.816 82 25.7924 + vertex -106.523 101 25.9943 + vertex -106.523 82 25.9943 + endloop + endfacet + facet normal 0.568073 0 -0.822978 + outer loop + vertex -106.523 101 25.9943 + vertex -106.816 82 25.7924 + vertex -106.816 101 25.7924 + endloop + endfacet + facet normal 0.120522 0 -0.992711 + outer loop + vertex -106.523 82 25.9943 + vertex -106.146 101 26.04 + vertex -106.146 82 26.04 + endloop + endfacet + facet normal 0.120522 0 -0.992711 + outer loop + vertex -106.146 101 26.04 + vertex -106.523 82 25.9943 + vertex -106.523 101 25.9943 + endloop + endfacet + facet normal -0.175007 0 -0.984567 + outer loop + vertex -106.146 82 26.04 + vertex -96.9798 101 24.4107 + vertex -96.9798 82 24.4107 + endloop + endfacet + facet normal -0.175007 0 -0.984567 + outer loop + vertex -96.9798 101 24.4107 + vertex -106.146 82 26.04 + vertex -106.146 101 26.04 + endloop + endfacet + facet normal -0.175007 0 -0.984567 + outer loop + vertex -96.8872 82 24.3942 + vertex -96.605 101 24.344 + vertex -96.605 82 24.344 + endloop + endfacet + facet normal -0.175007 0 -0.984567 + outer loop + vertex -96.605 101 24.344 + vertex -96.8872 82 24.3942 + vertex -96.8872 101 24.3942 + endloop + endfacet + facet normal -0.175007 0 0.984567 + outer loop + vertex -106.146 101 18.56 + vertex -96.9798 82 20.1893 + vertex -96.9798 101 20.1893 + endloop + endfacet + facet normal -0.175007 0 0.984567 + outer loop + vertex -96.9798 82 20.1893 + vertex -106.146 101 18.56 + vertex -106.146 82 18.56 + endloop + endfacet + facet normal -0.175007 0 0.984567 + outer loop + vertex -96.8872 101 20.2058 + vertex -96.605 82 20.256 + vertex -96.605 101 20.256 + endloop + endfacet + facet normal -0.175007 0 0.984567 + outer loop + vertex -96.605 82 20.256 + vertex -96.8872 101 20.2058 + vertex -96.8872 82 20.2058 + endloop + endfacet + facet normal 0.120522 0 0.992711 + outer loop + vertex -106.523 101 18.6057 + vertex -106.146 82 18.56 + vertex -106.146 101 18.56 + endloop + endfacet + facet normal 0.120522 0 0.992711 + outer loop + vertex -106.146 82 18.56 + vertex -106.523 101 18.6057 + vertex -106.523 82 18.6057 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex -96.605 82 24.368 + vertex -96.605 101 24.344 + vertex -96.605 101 24.368 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex -96.605 101 24.344 + vertex -96.605 82 24.368 + vertex -96.605 82 24.344 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex -96.605 82 20.256 + vertex -96.605 101 20.232 + vertex -96.605 101 20.256 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex -96.605 101 20.232 + vertex -96.605 82 20.256 + vertex -96.605 82 20.232 + endloop + endfacet + facet normal 0.602619 0 -0.798029 + outer loop + vertex -96 82 17.72 + vertex -95.6084 101 18.0156 + vertex -95.6084 82 18.0156 + endloop + endfacet + facet normal 0.602619 0 -0.798029 + outer loop + vertex -95.6084 101 18.0156 + vertex -96 82 17.72 + vertex -96 101 17.72 + endloop + endfacet + facet normal 0.850222 0 -0.526424 + outer loop + vertex -95.3502 82 18.4327 + vertex -95.6084 101 18.0156 + vertex -95.3502 101 18.4327 + endloop + endfacet + facet normal 0.850222 0 -0.526424 + outer loop + vertex -95.6084 101 18.0156 + vertex -95.3502 82 18.4327 + vertex -95.6084 82 18.0156 + endloop + endfacet + facet normal 0.982973 0 -0.18375 + outer loop + vertex -95.26 82 18.915 + vertex -95.3502 101 18.4327 + vertex -95.26 101 18.915 + endloop + endfacet + facet normal 0.982973 0 -0.18375 + outer loop + vertex -95.3502 101 18.4327 + vertex -95.26 82 18.915 + vertex -95.3502 82 18.4327 + endloop + endfacet + facet normal 0.982973 -0 0.18375 + outer loop + vertex -95.3502 82 19.3973 + vertex -95.26 101 18.915 + vertex -95.3502 101 19.3973 + endloop + endfacet + facet normal 0.982973 0 0.18375 + outer loop + vertex -95.26 101 18.915 + vertex -95.3502 82 19.3973 + vertex -95.26 82 18.915 + endloop + endfacet + facet normal 0.850222 -0 0.526424 + outer loop + vertex -95.6084 82 19.8144 + vertex -95.3502 101 19.3973 + vertex -95.6084 101 19.8144 + endloop + endfacet + facet normal 0.850222 0 0.526424 + outer loop + vertex -95.3502 101 19.3973 + vertex -95.6084 82 19.8144 + vertex -95.3502 82 19.3973 + endloop + endfacet + facet normal 0.602619 0 0.798029 + outer loop + vertex -96 101 20.11 + vertex -95.6084 82 19.8144 + vertex -95.6084 101 19.8144 + endloop + endfacet + facet normal 0.602619 0 0.798029 + outer loop + vertex -95.6084 82 19.8144 + vertex -96 101 20.11 + vertex -96 82 20.11 + endloop + endfacet + facet normal 0.273665 0 0.961825 + outer loop + vertex -96.4718 101 20.2443 + vertex -96 82 20.11 + vertex -96 101 20.11 + endloop + endfacet + facet normal 0.273665 0 0.961825 + outer loop + vertex -96 82 20.11 + vertex -96.4718 101 20.2443 + vertex -96.4718 82 20.2443 + endloop + endfacet + facet normal -0.0922792 0 0.995733 + outer loop + vertex -96.9603 101 20.199 + vertex -96.8872 82 20.2058 + vertex -96.8872 101 20.2058 + endloop + endfacet + facet normal -0.0922792 0 0.995733 + outer loop + vertex -96.8872 82 20.2058 + vertex -96.9603 101 20.199 + vertex -96.9603 82 20.199 + endloop + endfacet + facet normal -0.0922857 0 0.995733 + outer loop + vertex -96.605 101 20.232 + vertex -96.4718 82 20.2443 + vertex -96.4718 101 20.2443 + endloop + endfacet + facet normal -0.0922857 0 0.995733 + outer loop + vertex -96.4718 82 20.2443 + vertex -96.605 101 20.232 + vertex -96.605 82 20.232 + endloop + endfacet + facet normal -0.445737 0 0.895164 + outer loop + vertex -96.9798 101 20.1893 + vertex -96.9603 82 20.199 + vertex -96.9603 101 20.199 + endloop + endfacet + facet normal -0.445737 0 0.895164 + outer loop + vertex -96.9603 82 20.199 + vertex -96.9798 101 20.1893 + vertex -96.9798 82 20.1893 + endloop + endfacet + facet normal -0.739002 0 0.673704 + outer loop + vertex -97.73 82 19.6178 + vertex -97.5295 101 19.8377 + vertex -97.73 101 19.6178 + endloop + endfacet + facet normal -0.739002 0 0.673704 + outer loop + vertex -97.5295 101 19.8377 + vertex -97.73 82 19.6178 + vertex -97.5295 82 19.8377 + endloop + endfacet + facet normal -0.932469 0 0.36125 + outer loop + vertex -97.9073 82 19.1603 + vertex -97.73 101 19.6178 + vertex -97.9073 101 19.1603 + endloop + endfacet + facet normal -0.932469 0 0.36125 + outer loop + vertex -97.73 101 19.6178 + vertex -97.9073 82 19.1603 + vertex -97.73 82 19.6178 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -97.9073 82 18.6697 + vertex -97.9073 101 19.1603 + vertex -97.9073 101 18.6697 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex -97.9073 101 19.1603 + vertex -97.9073 82 18.6697 + vertex -97.9073 82 19.1603 + endloop + endfacet + facet normal -0.932469 0 -0.36125 + outer loop + vertex -97.73 82 18.2122 + vertex -97.9073 101 18.6697 + vertex -97.73 101 18.2122 + endloop + endfacet + facet normal -0.932469 -0 -0.36125 + outer loop + vertex -97.9073 101 18.6697 + vertex -97.73 82 18.2122 + vertex -97.9073 82 18.6697 + endloop + endfacet + facet normal -0.739009 0 -0.673695 + outer loop + vertex -97.3995 82 17.8497 + vertex -97.73 101 18.2122 + vertex -97.3995 101 17.8497 + endloop + endfacet + facet normal -0.739009 -0 -0.673695 + outer loop + vertex -97.73 101 18.2122 + vertex -97.3995 82 17.8497 + vertex -97.73 82 18.2122 + endloop + endfacet + facet normal -0.445745 0 -0.89516 + outer loop + vertex -97.3995 82 17.8497 + vertex -96.9603 101 17.631 + vertex -96.9603 82 17.631 + endloop + endfacet + facet normal -0.445745 0 -0.89516 + outer loop + vertex -96.9603 101 17.631 + vertex -97.3995 82 17.8497 + vertex -97.3995 101 17.8497 + endloop + endfacet + facet normal -0.0922827 0 -0.995733 + outer loop + vertex -96.9603 82 17.631 + vertex -96.4718 101 17.5857 + vertex -96.4718 82 17.5857 + endloop + endfacet + facet normal -0.0922827 0 -0.995733 + outer loop + vertex -96.4718 101 17.5857 + vertex -96.9603 82 17.631 + vertex -96.9603 101 17.631 + endloop + endfacet + facet normal 0.273665 0 -0.961825 + outer loop + vertex -96.4718 82 17.5857 + vertex -96 101 17.72 + vertex -96 82 17.72 + endloop + endfacet + facet normal 0.273665 0 -0.961825 + outer loop + vertex -96 101 17.72 + vertex -96.4718 82 17.5857 + vertex -96.4718 101 17.5857 + endloop + endfacet + facet normal 0.433867 0 0.900977 + outer loop + vertex -97.2715 101 18.0667 + vertex -96.8364 82 17.8572 + vertex -96.8364 101 17.8572 + endloop + endfacet + facet normal 0.433867 0 0.900977 + outer loop + vertex -96.8364 82 17.8572 + vertex -97.2715 101 18.0667 + vertex -97.2715 82 18.0667 + endloop + endfacet + facet normal 0.781848 -0 0.623469 + outer loop + vertex -97.5725 82 18.4443 + vertex -97.2715 101 18.0667 + vertex -97.5725 101 18.4443 + endloop + endfacet + facet normal 0.781848 0 0.623469 + outer loop + vertex -97.2715 101 18.0667 + vertex -97.5725 82 18.4443 + vertex -97.2715 82 18.0667 + endloop + endfacet + facet normal 0.974925 -0 0.222535 + outer loop + vertex -97.68 82 18.915 + vertex -97.5725 101 18.4443 + vertex -97.68 101 18.915 + endloop + endfacet + facet normal 0.974925 0 0.222535 + outer loop + vertex -97.5725 101 18.4443 + vertex -97.68 82 18.915 + vertex -97.5725 82 18.4443 + endloop + endfacet + facet normal 0.974925 0 -0.222535 + outer loop + vertex -97.5725 82 19.3857 + vertex -97.68 101 18.915 + vertex -97.5725 101 19.3857 + endloop + endfacet + facet normal 0.974925 0 -0.222535 + outer loop + vertex -97.68 101 18.915 + vertex -97.5725 82 19.3857 + vertex -97.68 82 18.915 + endloop + endfacet + facet normal 0.781848 0 -0.623469 + outer loop + vertex -97.2715 82 19.7633 + vertex -97.5725 101 19.3857 + vertex -97.2715 101 19.7633 + endloop + endfacet + facet normal 0.781848 0 -0.623469 + outer loop + vertex -97.5725 101 19.3857 + vertex -97.2715 82 19.7633 + vertex -97.5725 82 19.3857 + endloop + endfacet + facet normal 0.433867 0 -0.900977 + outer loop + vertex -97.2715 82 19.7633 + vertex -96.8755 101 19.954 + vertex -96.8755 82 19.954 + endloop + endfacet + facet normal 0.433867 0 -0.900977 + outer loop + vertex -96.8755 101 19.954 + vertex -97.2715 82 19.7633 + vertex -97.2715 101 19.7633 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -96.7696 82 19.9728 + vertex -96.3536 101 19.9728 + vertex -96.3536 82 19.9728 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -96.3536 101 19.9728 + vertex -96.7696 82 19.9728 + vertex -96.7696 101 19.9728 + endloop + endfacet + facet normal -0.433867 0 -0.900977 + outer loop + vertex -96.3536 82 19.9728 + vertex -95.9185 101 19.7633 + vertex -95.9185 82 19.7633 + endloop + endfacet + facet normal -0.433867 0 -0.900977 + outer loop + vertex -95.9185 101 19.7633 + vertex -96.3536 82 19.9728 + vertex -96.3536 101 19.9728 + endloop + endfacet + facet normal -0.781848 0 -0.623469 + outer loop + vertex -95.6175 82 19.3857 + vertex -95.9185 101 19.7633 + vertex -95.6175 101 19.3857 + endloop + endfacet + facet normal -0.781848 -0 -0.623469 + outer loop + vertex -95.9185 101 19.7633 + vertex -95.6175 82 19.3857 + vertex -95.9185 82 19.7633 + endloop + endfacet + facet normal -0.974925 0 -0.222535 + outer loop + vertex -95.51 82 18.915 + vertex -95.6175 101 19.3857 + vertex -95.51 101 18.915 + endloop + endfacet + facet normal -0.974925 -0 -0.222535 + outer loop + vertex -95.6175 101 19.3857 + vertex -95.51 82 18.915 + vertex -95.6175 82 19.3857 + endloop + endfacet + facet normal -0.974925 0 0.222535 + outer loop + vertex -95.6175 82 18.4443 + vertex -95.51 101 18.915 + vertex -95.6175 101 18.4443 + endloop + endfacet + facet normal -0.974925 0 0.222535 + outer loop + vertex -95.51 101 18.915 + vertex -95.6175 82 18.4443 + vertex -95.51 82 18.915 + endloop + endfacet + facet normal -0.781848 0 0.623469 + outer loop + vertex -95.9185 82 18.0667 + vertex -95.6175 101 18.4443 + vertex -95.9185 101 18.0667 + endloop + endfacet + facet normal -0.781848 0 0.623469 + outer loop + vertex -95.6175 101 18.4443 + vertex -95.9185 82 18.0667 + vertex -95.6175 82 18.4443 + endloop + endfacet + facet normal -0.433867 0 0.900977 + outer loop + vertex -96.3536 101 17.8572 + vertex -95.9185 82 18.0667 + vertex -95.9185 101 18.0667 + endloop + endfacet + facet normal -0.433867 0 0.900977 + outer loop + vertex -95.9185 82 18.0667 + vertex -96.3536 101 17.8572 + vertex -96.3536 82 17.8572 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -96.8364 101 17.8572 + vertex -96.3536 82 17.8572 + vertex -96.3536 101 17.8572 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -96.3536 82 17.8572 + vertex -96.8364 101 17.8572 + vertex -96.8364 82 17.8572 + endloop + endfacet + facet normal 0.602619 0 -0.798029 + outer loop + vertex -96 82 24.49 + vertex -95.6084 101 24.7856 + vertex -95.6084 82 24.7856 + endloop + endfacet + facet normal 0.602619 0 -0.798029 + outer loop + vertex -95.6084 101 24.7856 + vertex -96 82 24.49 + vertex -96 101 24.49 + endloop + endfacet + facet normal 0.850222 0 -0.526424 + outer loop + vertex -95.3502 82 25.2027 + vertex -95.6084 101 24.7856 + vertex -95.3502 101 25.2027 + endloop + endfacet + facet normal 0.850222 0 -0.526424 + outer loop + vertex -95.6084 101 24.7856 + vertex -95.3502 82 25.2027 + vertex -95.6084 82 24.7856 + endloop + endfacet + facet normal 0.982973 0 -0.18375 + outer loop + vertex -95.26 82 25.685 + vertex -95.3502 101 25.2027 + vertex -95.26 101 25.685 + endloop + endfacet + facet normal 0.982973 0 -0.18375 + outer loop + vertex -95.3502 101 25.2027 + vertex -95.26 82 25.685 + vertex -95.3502 82 25.2027 + endloop + endfacet + facet normal 0.982973 -0 0.18375 + outer loop + vertex -95.3502 82 26.1673 + vertex -95.26 101 25.685 + vertex -95.3502 101 26.1673 + endloop + endfacet + facet normal 0.982973 0 0.18375 + outer loop + vertex -95.26 101 25.685 + vertex -95.3502 82 26.1673 + vertex -95.26 82 25.685 + endloop + endfacet + facet normal 0.850222 -0 0.526424 + outer loop + vertex -95.6084 82 26.5844 + vertex -95.3502 101 26.1673 + vertex -95.6084 101 26.5844 + endloop + endfacet + facet normal 0.850222 0 0.526424 + outer loop + vertex -95.3502 101 26.1673 + vertex -95.6084 82 26.5844 + vertex -95.3502 82 26.1673 + endloop + endfacet + facet normal 0.602619 0 0.798029 + outer loop + vertex -96 101 26.88 + vertex -95.6084 82 26.5844 + vertex -95.6084 101 26.5844 + endloop + endfacet + facet normal 0.602619 0 0.798029 + outer loop + vertex -95.6084 82 26.5844 + vertex -96 101 26.88 + vertex -96 82 26.88 + endloop + endfacet + facet normal 0.273665 0 0.961825 + outer loop + vertex -96.4718 101 27.0143 + vertex -96 82 26.88 + vertex -96 101 26.88 + endloop + endfacet + facet normal 0.273665 0 0.961825 + outer loop + vertex -96 82 26.88 + vertex -96.4718 101 27.0143 + vertex -96.4718 82 27.0143 + endloop + endfacet + facet normal -0.0922827 0 0.995733 + outer loop + vertex -96.9603 101 26.969 + vertex -96.4718 82 27.0143 + vertex -96.4718 101 27.0143 + endloop + endfacet + facet normal -0.0922827 0 0.995733 + outer loop + vertex -96.4718 82 27.0143 + vertex -96.9603 101 26.969 + vertex -96.9603 82 26.969 + endloop + endfacet + facet normal -0.445745 0 0.89516 + outer loop + vertex -97.3995 101 26.7503 + vertex -96.9603 82 26.969 + vertex -96.9603 101 26.969 + endloop + endfacet + facet normal -0.445745 0 0.89516 + outer loop + vertex -96.9603 82 26.969 + vertex -97.3995 101 26.7503 + vertex -97.3995 82 26.7503 + endloop + endfacet + facet normal -0.739009 0 0.673695 + outer loop + vertex -97.73 82 26.3878 + vertex -97.3995 101 26.7503 + vertex -97.73 101 26.3878 + endloop + endfacet + facet normal -0.739009 0 0.673695 + outer loop + vertex -97.3995 101 26.7503 + vertex -97.73 82 26.3878 + vertex -97.3995 82 26.7503 + endloop + endfacet + facet normal -0.932469 0 0.36125 + outer loop + vertex -97.9073 82 25.9303 + vertex -97.73 101 26.3878 + vertex -97.9073 101 25.9303 + endloop + endfacet + facet normal -0.932469 0 0.36125 + outer loop + vertex -97.73 101 26.3878 + vertex -97.9073 82 25.9303 + vertex -97.73 82 26.3878 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -97.9073 82 25.4397 + vertex -97.9073 101 25.9303 + vertex -97.9073 101 25.4397 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex -97.9073 101 25.9303 + vertex -97.9073 82 25.4397 + vertex -97.9073 82 25.9303 + endloop + endfacet + facet normal -0.932469 0 -0.36125 + outer loop + vertex -97.73 82 24.9822 + vertex -97.9073 101 25.4397 + vertex -97.73 101 24.9822 + endloop + endfacet + facet normal -0.932469 -0 -0.36125 + outer loop + vertex -97.9073 101 25.4397 + vertex -97.73 82 24.9822 + vertex -97.9073 82 25.4397 + endloop + endfacet + facet normal -0.739002 0 -0.673704 + outer loop + vertex -97.5295 82 24.7623 + vertex -97.73 101 24.9822 + vertex -97.5295 101 24.7623 + endloop + endfacet + facet normal -0.739002 -0 -0.673704 + outer loop + vertex -97.73 101 24.9822 + vertex -97.5295 82 24.7623 + vertex -97.73 82 24.9822 + endloop + endfacet + facet normal -0.445737 0 -0.895164 + outer loop + vertex -96.9798 82 24.4107 + vertex -96.9603 101 24.401 + vertex -96.9603 82 24.401 + endloop + endfacet + facet normal -0.445737 0 -0.895164 + outer loop + vertex -96.9603 101 24.401 + vertex -96.9798 82 24.4107 + vertex -96.9798 101 24.4107 + endloop + endfacet + facet normal -0.0922857 0 -0.995733 + outer loop + vertex -96.605 82 24.368 + vertex -96.4718 101 24.3557 + vertex -96.4718 82 24.3557 + endloop + endfacet + facet normal -0.0922857 0 -0.995733 + outer loop + vertex -96.4718 101 24.3557 + vertex -96.605 82 24.368 + vertex -96.605 101 24.368 + endloop + endfacet + facet normal -0.0922792 0 -0.995733 + outer loop + vertex -96.9603 82 24.401 + vertex -96.8872 101 24.3942 + vertex -96.8872 82 24.3942 + endloop + endfacet + facet normal -0.0922792 0 -0.995733 + outer loop + vertex -96.8872 101 24.3942 + vertex -96.9603 82 24.401 + vertex -96.9603 101 24.401 + endloop + endfacet + facet normal 0.273665 0 -0.961825 + outer loop + vertex -96.4718 82 24.3557 + vertex -96 101 24.49 + vertex -96 82 24.49 + endloop + endfacet + facet normal 0.273665 0 -0.961825 + outer loop + vertex -96 101 24.49 + vertex -96.4718 82 24.3557 + vertex -96.4718 101 24.3557 + endloop + endfacet + facet normal 0.433867 0 0.900977 + outer loop + vertex -97.2715 101 24.8367 + vertex -96.8755 82 24.646 + vertex -96.8755 101 24.646 + endloop + endfacet + facet normal 0.433867 0 0.900977 + outer loop + vertex -96.8755 82 24.646 + vertex -97.2715 101 24.8367 + vertex -97.2715 82 24.8367 + endloop + endfacet + facet normal 0.781848 -0 0.623469 + outer loop + vertex -97.5725 82 25.2143 + vertex -97.2715 101 24.8367 + vertex -97.5725 101 25.2143 + endloop + endfacet + facet normal 0.781848 0 0.623469 + outer loop + vertex -97.2715 101 24.8367 + vertex -97.5725 82 25.2143 + vertex -97.2715 82 24.8367 + endloop + endfacet + facet normal 0.974925 -0 0.222535 + outer loop + vertex -97.68 82 25.685 + vertex -97.5725 101 25.2143 + vertex -97.68 101 25.685 + endloop + endfacet + facet normal 0.974925 0 0.222535 + outer loop + vertex -97.5725 101 25.2143 + vertex -97.68 82 25.685 + vertex -97.5725 82 25.2143 + endloop + endfacet + facet normal 0.974925 0 -0.222535 + outer loop + vertex -97.5725 82 26.1557 + vertex -97.68 101 25.685 + vertex -97.5725 101 26.1557 + endloop + endfacet + facet normal 0.974925 0 -0.222535 + outer loop + vertex -97.68 101 25.685 + vertex -97.5725 82 26.1557 + vertex -97.68 82 25.685 + endloop + endfacet + facet normal 0.781848 0 -0.623469 + outer loop + vertex -97.2715 82 26.5333 + vertex -97.5725 101 26.1557 + vertex -97.2715 101 26.5333 + endloop + endfacet + facet normal 0.781848 0 -0.623469 + outer loop + vertex -97.5725 101 26.1557 + vertex -97.2715 82 26.5333 + vertex -97.5725 82 26.1557 + endloop + endfacet + facet normal 0.433867 0 -0.900977 + outer loop + vertex -97.2715 82 26.5333 + vertex -96.8364 101 26.7428 + vertex -96.8364 82 26.7428 + endloop + endfacet + facet normal 0.433867 0 -0.900977 + outer loop + vertex -96.8364 101 26.7428 + vertex -97.2715 82 26.5333 + vertex -97.2715 101 26.5333 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -96.8364 82 26.7428 + vertex -96.3536 101 26.7428 + vertex -96.3536 82 26.7428 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -96.3536 101 26.7428 + vertex -96.8364 82 26.7428 + vertex -96.8364 101 26.7428 + endloop + endfacet + facet normal -0.433867 0 -0.900977 + outer loop + vertex -96.3536 82 26.7428 + vertex -95.9185 101 26.5333 + vertex -95.9185 82 26.5333 + endloop + endfacet + facet normal -0.433867 0 -0.900977 + outer loop + vertex -95.9185 101 26.5333 + vertex -96.3536 82 26.7428 + vertex -96.3536 101 26.7428 + endloop + endfacet + facet normal -0.781848 0 -0.623469 + outer loop + vertex -95.6175 82 26.1557 + vertex -95.9185 101 26.5333 + vertex -95.6175 101 26.1557 + endloop + endfacet + facet normal -0.781848 -0 -0.623469 + outer loop + vertex -95.9185 101 26.5333 + vertex -95.6175 82 26.1557 + vertex -95.9185 82 26.5333 + endloop + endfacet + facet normal -0.974925 0 -0.222535 + outer loop + vertex -95.51 82 25.685 + vertex -95.6175 101 26.1557 + vertex -95.51 101 25.685 + endloop + endfacet + facet normal -0.974925 -0 -0.222535 + outer loop + vertex -95.6175 101 26.1557 + vertex -95.51 82 25.685 + vertex -95.6175 82 26.1557 + endloop + endfacet + facet normal -0.974925 0 0.222535 + outer loop + vertex -95.6175 82 25.2143 + vertex -95.51 101 25.685 + vertex -95.6175 101 25.2143 + endloop + endfacet + facet normal -0.974925 0 0.222535 + outer loop + vertex -95.51 101 25.685 + vertex -95.6175 82 25.2143 + vertex -95.51 82 25.685 + endloop + endfacet + facet normal -0.781848 0 0.623469 + outer loop + vertex -95.9185 82 24.8367 + vertex -95.6175 101 25.2143 + vertex -95.9185 101 24.8367 + endloop + endfacet + facet normal -0.781848 0 0.623469 + outer loop + vertex -95.6175 101 25.2143 + vertex -95.9185 82 24.8367 + vertex -95.6175 82 25.2143 + endloop + endfacet + facet normal -0.433867 0 0.900977 + outer loop + vertex -96.3536 101 24.6272 + vertex -95.9185 82 24.8367 + vertex -95.9185 101 24.8367 + endloop + endfacet + facet normal -0.433867 0 0.900977 + outer loop + vertex -95.9185 82 24.8367 + vertex -96.3536 101 24.6272 + vertex -96.3536 82 24.6272 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -96.7696 101 24.6272 + vertex -96.3536 82 24.6272 + vertex -96.3536 101 24.6272 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -96.3536 82 24.6272 + vertex -96.7696 101 24.6272 + vertex -96.7696 82 24.6272 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.8872 -82 24.3942 + vertex 96.605 -82 24.344 + vertex 96.605 -82 24.368 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 106.139 -82 26.2927 + vertex 106.523 -82 25.9943 + vertex 106.146 -82 26.04 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107.009 -82 25.9631 + vertex 106.523 -82 25.9943 + vertex 106.615 -82 26.235 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107.009 -82 25.9631 + vertex 106.816 -82 25.7924 + vertex 106.523 -82 25.9943 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107.231 -82 25.5393 + vertex 106.816 -82 25.7924 + vertex 107.009 -82 25.9631 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107.231 -82 25.5393 + vertex 106.981 -82 25.4777 + vertex 106.816 -82 25.7924 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107.231 -82 25.5393 + vertex 107 -82 24.13 + vertex 106.981 -82 25.4777 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107.231 -82 25.5393 + vertex 107 -82 22.13 + vertex 107 -82 24.13 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107 -82 22.13 + vertex 107 -82 22.1 + vertex 106.981 -82 22.13 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107.231 -82 25.5393 + vertex 107 -82 22.1 + vertex 107 -82 22.13 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 107.231 -82 19.0607 + vertex 107 -82 22.1 + vertex 107.231 -82 25.5393 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107 -82 20.5 + vertex 106.981 -82 19.1223 + vertex 106.981 -82 20.5 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107 -82 22.1 + vertex 107.231 -82 19.0607 + vertex 107 -82 20.5 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107 -82 20.5 + vertex 107.231 -82 19.0607 + vertex 106.981 -82 19.1223 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107.231 -82 19.0607 + vertex 106.816 -82 18.8076 + vertex 106.981 -82 19.1223 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 107.009 -82 18.6369 + vertex 106.816 -82 18.8076 + vertex 107.231 -82 19.0607 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 107.009 -82 18.6369 + vertex 106.523 -82 18.6057 + vertex 106.816 -82 18.8076 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 106.615 -82 18.365 + vertex 106.523 -82 18.6057 + vertex 107.009 -82 18.6369 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 106.139 -82 18.3073 + vertex 106.523 -82 18.6057 + vertex 106.615 -82 18.365 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 106.523 -82 25.9943 + vertex 106.139 -82 26.2927 + vertex 106.615 -82 26.235 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 106.146 -82 26.04 + vertex 97.5295 -82 24.7623 + vertex 106.139 -82 26.2927 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.9798 -82 24.4107 + vertex 97.5295 -82 24.7623 + vertex 106.146 -82 26.04 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.5295 -82 24.7623 + vertex 96.9798 -82 24.4107 + vertex 96.8755 -82 24.646 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 96.605 -82 24.368 + vertex 96.3536 -82 24.6272 + vertex 96.7696 -82 24.6272 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 96.8872 -82 24.3942 + vertex 96.8755 -82 24.646 + vertex 96.9798 -82 24.4107 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.8755 -82 24.646 + vertex 96.8872 -82 24.3942 + vertex 96.7696 -82 24.6272 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.8872 -82 24.3942 + vertex 96.9798 -82 24.4107 + vertex 96.9603 -82 24.401 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.605 -82 24.368 + vertex 96.7696 -82 24.6272 + vertex 96.8872 -82 24.3942 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.3536 -82 24.6272 + vertex 96.605 -82 24.368 + vertex 96.4718 -82 24.3557 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.3536 -82 24.6272 + vertex 96.4718 -82 24.3557 + vertex 96 -82 24.49 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.9603 -82 26.969 + vertex 97.2715 -82 26.5333 + vertex 96.8364 -82 26.7428 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.73 -82 26.3878 + vertex 97.2715 -82 26.5333 + vertex 97.3995 -82 26.7503 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.73 -82 26.3878 + vertex 97.5725 -82 26.1557 + vertex 97.2715 -82 26.5333 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.9073 -82 25.9303 + vertex 97.5725 -82 26.1557 + vertex 97.73 -82 26.3878 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.9073 -82 25.9303 + vertex 97.68 -82 25.685 + vertex 97.5725 -82 26.1557 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 97.9073 -82 25.4397 + vertex 97.68 -82 25.685 + vertex 97.9073 -82 25.9303 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.9073 -82 25.4397 + vertex 97.5725 -82 25.2143 + vertex 97.68 -82 25.685 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 97.73 -82 24.9822 + vertex 97.5725 -82 25.2143 + vertex 97.9073 -82 25.4397 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.5295 -82 24.7623 + vertex 97.5725 -82 25.2143 + vertex 97.73 -82 24.9822 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.5725 -82 25.2143 + vertex 97.5295 -82 24.7623 + vertex 97.2715 -82 24.8367 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.2715 -82 24.8367 + vertex 97.5295 -82 24.7623 + vertex 96.8755 -82 24.646 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 96.8364 -82 26.7428 + vertex 96.4718 -82 27.0143 + vertex 96.9603 -82 26.969 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 97.2715 -82 26.5333 + vertex 96.9603 -82 26.969 + vertex 97.3995 -82 26.7503 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.4718 -82 27.0143 + vertex 96.8364 -82 26.7428 + vertex 96.3536 -82 26.7428 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.4718 -82 27.0143 + vertex 96.3536 -82 26.7428 + vertex 96 -82 26.88 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.9185 -82 26.5333 + vertex 96 -82 26.88 + vertex 96.3536 -82 26.7428 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96 -82 26.88 + vertex 95.9185 -82 26.5333 + vertex 95.6084 -82 26.5844 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 95.6175 -82 26.1557 + vertex 95.6084 -82 26.5844 + vertex 95.9185 -82 26.5333 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.6084 -82 26.5844 + vertex 95.6175 -82 26.1557 + vertex 95.3502 -82 26.1673 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 95.51 -82 25.685 + vertex 95.3502 -82 26.1673 + vertex 95.6175 -82 26.1557 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.51 -82 25.685 + vertex 95.26 -82 25.685 + vertex 95.3502 -82 26.1673 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.3502 -82 25.2027 + vertex 95.51 -82 25.685 + vertex 95.6175 -82 25.2143 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.51 -82 25.685 + vertex 95.3502 -82 25.2027 + vertex 95.26 -82 25.685 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.6084 -82 24.7856 + vertex 95.6175 -82 25.2143 + vertex 95.9185 -82 24.8367 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.6175 -82 25.2143 + vertex 95.6084 -82 24.7856 + vertex 95.3502 -82 25.2027 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 96 -82 24.49 + vertex 95.9185 -82 24.8367 + vertex 96.3536 -82 24.6272 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.9185 -82 24.8367 + vertex 96 -82 24.49 + vertex 95.6084 -82 24.7856 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 106.981 -82 25.4777 + vertex 107 -82 24.13 + vertex 106.981 -82 24.13 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 106.981 -82 22.13 + vertex 107 -82 22.1 + vertex 106.981 -82 22.1 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.605 -82 20.256 + vertex 96.8872 -82 20.2058 + vertex 96.605 -82 20.232 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.9798 -82 20.1893 + vertex 96.8872 -82 20.2058 + vertex 96.9603 -82 20.199 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.8755 -82 19.954 + vertex 96.8872 -82 20.2058 + vertex 96.9798 -82 20.1893 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.8872 -82 20.2058 + vertex 96.7696 -82 19.9728 + vertex 96.605 -82 20.232 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.3536 -82 19.9728 + vertex 96.605 -82 20.232 + vertex 96.7696 -82 19.9728 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.605 -82 20.232 + vertex 96.3536 -82 19.9728 + vertex 96.4718 -82 20.2443 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.8872 -82 20.2058 + vertex 96.8755 -82 19.954 + vertex 96.7696 -82 19.9728 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 97.2715 -82 19.7633 + vertex 96.9798 -82 20.1893 + vertex 97.5295 -82 19.8377 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 106.146 -82 18.56 + vertex 97.5295 -82 19.8377 + vertex 96.9798 -82 20.1893 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 106.523 -82 18.6057 + vertex 106.139 -82 18.3073 + vertex 106.146 -82 18.56 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 106.146 -82 18.56 + vertex 106.139 -82 18.3073 + vertex 97.5295 -82 19.8377 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.4718 -82 20.2443 + vertex 96.3536 -82 19.9728 + vertex 96 -82 20.11 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.9185 -82 19.7633 + vertex 96 -82 20.11 + vertex 96.3536 -82 19.9728 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96 -82 20.11 + vertex 95.9185 -82 19.7633 + vertex 95.6084 -82 19.8144 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 95.6175 -82 19.3857 + vertex 95.6084 -82 19.8144 + vertex 95.9185 -82 19.7633 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.6084 -82 19.8144 + vertex 95.6175 -82 19.3857 + vertex 95.3502 -82 19.3973 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 95.51 -82 18.915 + vertex 95.3502 -82 19.3973 + vertex 95.6175 -82 19.3857 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.51 -82 18.915 + vertex 95.26 -82 18.915 + vertex 95.3502 -82 19.3973 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.3502 -82 18.4327 + vertex 95.51 -82 18.915 + vertex 95.6175 -82 18.4443 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.51 -82 18.915 + vertex 95.3502 -82 18.4327 + vertex 95.26 -82 18.915 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.6084 -82 18.0156 + vertex 95.6175 -82 18.4443 + vertex 95.9185 -82 18.0667 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.6175 -82 18.4443 + vertex 95.6084 -82 18.0156 + vertex 95.3502 -82 18.4327 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 96 -82 17.72 + vertex 95.9185 -82 18.0667 + vertex 96.3536 -82 17.8572 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 95.9185 -82 18.0667 + vertex 96 -82 17.72 + vertex 95.6084 -82 18.0156 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.8364 -82 17.8572 + vertex 96 -82 17.72 + vertex 96.3536 -82 17.8572 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.4718 -82 17.5857 + vertex 96.8364 -82 17.8572 + vertex 96.9603 -82 17.631 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.8364 -82 17.8572 + vertex 96.4718 -82 17.5857 + vertex 96 -82 17.72 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.9798 -82 20.1893 + vertex 97.2715 -82 19.7633 + vertex 96.8755 -82 19.954 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 97.5725 -82 19.3857 + vertex 97.5295 -82 19.8377 + vertex 97.73 -82 19.6178 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.5295 -82 19.8377 + vertex 97.5725 -82 19.3857 + vertex 97.2715 -82 19.7633 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.9073 -82 19.1603 + vertex 97.5725 -82 19.3857 + vertex 97.73 -82 19.6178 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.9073 -82 19.1603 + vertex 97.68 -82 18.915 + vertex 97.5725 -82 19.3857 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 97.9073 -82 18.6697 + vertex 97.68 -82 18.915 + vertex 97.9073 -82 19.1603 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.9073 -82 18.6697 + vertex 97.5725 -82 18.4443 + vertex 97.68 -82 18.915 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 97.73 -82 18.2122 + vertex 97.5725 -82 18.4443 + vertex 97.9073 -82 18.6697 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.73 -82 18.2122 + vertex 97.2715 -82 18.0667 + vertex 97.5725 -82 18.4443 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 97.3995 -82 17.8497 + vertex 97.2715 -82 18.0667 + vertex 97.73 -82 18.2122 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 97.2715 -82 18.0667 + vertex 96.9603 -82 17.631 + vertex 96.8364 -82 17.8572 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 96.9603 -82 17.631 + vertex 97.2715 -82 18.0667 + vertex 97.3995 -82 17.8497 + endloop + endfacet + facet normal -0.175007 0 0.984567 + outer loop + vertex 97.5295 -82 24.7623 + vertex 106.139 -101 26.2927 + vertex 106.139 -82 26.2927 + endloop + endfacet + facet normal -0.175007 0 0.984567 + outer loop + vertex 106.139 -101 26.2927 + vertex 97.5295 -82 24.7623 + vertex 97.5295 -101 24.7623 + endloop + endfacet + facet normal -0.175 0 0.984568 + outer loop + vertex 96.7696 -82 24.6272 + vertex 96.8755 -101 24.646 + vertex 96.8755 -82 24.646 + endloop + endfacet + facet normal -0.175 0 0.984568 + outer loop + vertex 96.8755 -101 24.646 + vertex 96.7696 -82 24.6272 + vertex 96.7696 -101 24.6272 + endloop + endfacet + facet normal 0.120538 0 0.992709 + outer loop + vertex 106.139 -82 26.2927 + vertex 106.615 -101 26.235 + vertex 106.615 -82 26.235 + endloop + endfacet + facet normal 0.120538 0 0.992709 + outer loop + vertex 106.615 -101 26.235 + vertex 106.139 -82 26.2927 + vertex 106.139 -101 26.2927 + endloop + endfacet + facet normal 0.568069 0 0.822981 + outer loop + vertex 106.615 -82 26.235 + vertex 107.009 -101 25.9631 + vertex 107.009 -82 25.9631 + endloop + endfacet + facet normal 0.568069 0 0.822981 + outer loop + vertex 107.009 -101 25.9631 + vertex 106.615 -82 26.235 + vertex 106.615 -101 26.235 + endloop + endfacet + facet normal 0.885462 -0 0.464712 + outer loop + vertex 107.009 -101 25.9631 + vertex 107.231 -82 25.5393 + vertex 107.009 -82 25.9631 + endloop + endfacet + facet normal 0.885462 0 0.464712 + outer loop + vertex 107.231 -82 25.5393 + vertex 107.009 -101 25.9631 + vertex 107.231 -101 25.5393 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex 107.231 -101 25.5393 + vertex 107.231 -82 19.0607 + vertex 107.231 -82 25.5393 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 107.231 -82 19.0607 + vertex 107.231 -101 25.5393 + vertex 107.231 -101 19.0607 + endloop + endfacet + facet normal 0.885462 0 -0.464712 + outer loop + vertex 107.231 -101 19.0607 + vertex 107.009 -82 18.6369 + vertex 107.231 -82 19.0607 + endloop + endfacet + facet normal 0.885462 0 -0.464712 + outer loop + vertex 107.009 -82 18.6369 + vertex 107.231 -101 19.0607 + vertex 107.009 -101 18.6369 + endloop + endfacet + facet normal 0.568069 0 -0.822981 + outer loop + vertex 106.615 -101 18.365 + vertex 107.009 -82 18.6369 + vertex 107.009 -101 18.6369 + endloop + endfacet + facet normal 0.568069 0 -0.822981 + outer loop + vertex 107.009 -82 18.6369 + vertex 106.615 -101 18.365 + vertex 106.615 -82 18.365 + endloop + endfacet + facet normal 0.120538 0 -0.992709 + outer loop + vertex 106.139 -101 18.3073 + vertex 106.615 -82 18.365 + vertex 106.615 -101 18.365 + endloop + endfacet + facet normal 0.120538 0 -0.992709 + outer loop + vertex 106.615 -82 18.365 + vertex 106.139 -101 18.3073 + vertex 106.139 -82 18.3073 + endloop + endfacet + facet normal -0.175008 0 -0.984567 + outer loop + vertex 97.5295 -101 19.8377 + vertex 106.139 -82 18.3073 + vertex 106.139 -101 18.3073 + endloop + endfacet + facet normal -0.175008 0 -0.984567 + outer loop + vertex 106.139 -82 18.3073 + vertex 97.5295 -101 19.8377 + vertex 97.5295 -82 19.8377 + endloop + endfacet + facet normal -0.175 0 -0.984568 + outer loop + vertex 96.7696 -101 19.9728 + vertex 96.8755 -82 19.954 + vertex 96.8755 -101 19.954 + endloop + endfacet + facet normal -0.175 0 -0.984568 + outer loop + vertex 96.8755 -82 19.954 + vertex 96.7696 -101 19.9728 + vertex 96.7696 -82 19.9728 + endloop + endfacet + facet normal -0.568073 0 0.822978 + outer loop + vertex 106.523 -82 18.6057 + vertex 106.816 -101 18.8076 + vertex 106.816 -82 18.8076 + endloop + endfacet + facet normal -0.568073 0 0.822978 + outer loop + vertex 106.816 -101 18.8076 + vertex 106.523 -82 18.6057 + vertex 106.523 -101 18.6057 + endloop + endfacet + facet normal -0.88547 0 0.464697 + outer loop + vertex 106.816 -101 18.8076 + vertex 106.981 -82 19.1223 + vertex 106.816 -82 18.8076 + endloop + endfacet + facet normal -0.88547 0 0.464697 + outer loop + vertex 106.981 -82 19.1223 + vertex 106.816 -101 18.8076 + vertex 106.981 -101 19.1223 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex 106.981 -101 24.13 + vertex 106.981 -82 25.4777 + vertex 106.981 -82 24.13 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex 106.981 -82 25.4777 + vertex 106.981 -101 24.13 + vertex 106.981 -101 25.4777 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex 106.981 -101 19.1223 + vertex 106.981 -82 20.5 + vertex 106.981 -82 19.1223 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex 106.981 -82 20.5 + vertex 106.981 -101 19.1223 + vertex 106.981 -101 20.5 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex 106.981 -101 22.1 + vertex 106.981 -82 22.13 + vertex 106.981 -82 22.1 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex 106.981 -82 22.13 + vertex 106.981 -101 22.1 + vertex 106.981 -101 22.13 + endloop + endfacet + facet normal -0.88547 0 -0.464697 + outer loop + vertex 106.981 -101 25.4777 + vertex 106.816 -82 25.7924 + vertex 106.981 -82 25.4777 + endloop + endfacet + facet normal -0.88547 -0 -0.464697 + outer loop + vertex 106.816 -82 25.7924 + vertex 106.981 -101 25.4777 + vertex 106.816 -101 25.7924 + endloop + endfacet + facet normal -0.568073 0 -0.822978 + outer loop + vertex 106.523 -101 25.9943 + vertex 106.816 -82 25.7924 + vertex 106.816 -101 25.7924 + endloop + endfacet + facet normal -0.568073 0 -0.822978 + outer loop + vertex 106.816 -82 25.7924 + vertex 106.523 -101 25.9943 + vertex 106.523 -82 25.9943 + endloop + endfacet + facet normal -0.120522 0 -0.992711 + outer loop + vertex 106.146 -101 26.04 + vertex 106.523 -82 25.9943 + vertex 106.523 -101 25.9943 + endloop + endfacet + facet normal -0.120522 0 -0.992711 + outer loop + vertex 106.523 -82 25.9943 + vertex 106.146 -101 26.04 + vertex 106.146 -82 26.04 + endloop + endfacet + facet normal 0.175007 0 -0.984567 + outer loop + vertex 96.9798 -101 24.4107 + vertex 106.146 -82 26.04 + vertex 106.146 -101 26.04 + endloop + endfacet + facet normal 0.175007 0 -0.984567 + outer loop + vertex 106.146 -82 26.04 + vertex 96.9798 -101 24.4107 + vertex 96.9798 -82 24.4107 + endloop + endfacet + facet normal 0.175007 0 -0.984567 + outer loop + vertex 96.605 -101 24.344 + vertex 96.8872 -82 24.3942 + vertex 96.8872 -101 24.3942 + endloop + endfacet + facet normal 0.175007 0 -0.984567 + outer loop + vertex 96.8872 -82 24.3942 + vertex 96.605 -101 24.344 + vertex 96.605 -82 24.344 + endloop + endfacet + facet normal 0.175007 0 0.984567 + outer loop + vertex 96.9798 -82 20.1893 + vertex 106.146 -101 18.56 + vertex 106.146 -82 18.56 + endloop + endfacet + facet normal 0.175007 0 0.984567 + outer loop + vertex 106.146 -101 18.56 + vertex 96.9798 -82 20.1893 + vertex 96.9798 -101 20.1893 + endloop + endfacet + facet normal 0.175007 0 0.984567 + outer loop + vertex 96.605 -82 20.256 + vertex 96.8872 -101 20.2058 + vertex 96.8872 -82 20.2058 + endloop + endfacet + facet normal 0.175007 0 0.984567 + outer loop + vertex 96.8872 -101 20.2058 + vertex 96.605 -82 20.256 + vertex 96.605 -101 20.256 + endloop + endfacet + facet normal -0.120522 0 0.992711 + outer loop + vertex 106.146 -82 18.56 + vertex 106.523 -101 18.6057 + vertex 106.523 -82 18.6057 + endloop + endfacet + facet normal -0.120522 0 0.992711 + outer loop + vertex 106.523 -101 18.6057 + vertex 106.146 -82 18.56 + vertex 106.146 -101 18.56 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex 96.605 -101 24.344 + vertex 96.605 -82 24.368 + vertex 96.605 -82 24.344 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex 96.605 -82 24.368 + vertex 96.605 -101 24.344 + vertex 96.605 -101 24.368 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex 96.605 -101 20.232 + vertex 96.605 -82 20.256 + vertex 96.605 -82 20.232 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex 96.605 -82 20.256 + vertex 96.605 -101 20.232 + vertex 96.605 -101 20.256 + endloop + endfacet + facet normal -0.602619 0 -0.798029 + outer loop + vertex 95.6084 -101 18.0156 + vertex 96 -82 17.72 + vertex 96 -101 17.72 + endloop + endfacet + facet normal -0.602619 0 -0.798029 + outer loop + vertex 96 -82 17.72 + vertex 95.6084 -101 18.0156 + vertex 95.6084 -82 18.0156 + endloop + endfacet + facet normal -0.850222 0 -0.526424 + outer loop + vertex 95.6084 -101 18.0156 + vertex 95.3502 -82 18.4327 + vertex 95.6084 -82 18.0156 + endloop + endfacet + facet normal -0.850222 -0 -0.526424 + outer loop + vertex 95.3502 -82 18.4327 + vertex 95.6084 -101 18.0156 + vertex 95.3502 -101 18.4327 + endloop + endfacet + facet normal -0.982973 0 -0.18375 + outer loop + vertex 95.3502 -101 18.4327 + vertex 95.26 -82 18.915 + vertex 95.3502 -82 18.4327 + endloop + endfacet + facet normal -0.982973 -0 -0.18375 + outer loop + vertex 95.26 -82 18.915 + vertex 95.3502 -101 18.4327 + vertex 95.26 -101 18.915 + endloop + endfacet + facet normal -0.982973 0 0.18375 + outer loop + vertex 95.26 -101 18.915 + vertex 95.3502 -82 19.3973 + vertex 95.26 -82 18.915 + endloop + endfacet + facet normal -0.982973 0 0.18375 + outer loop + vertex 95.3502 -82 19.3973 + vertex 95.26 -101 18.915 + vertex 95.3502 -101 19.3973 + endloop + endfacet + facet normal -0.850222 0 0.526424 + outer loop + vertex 95.3502 -101 19.3973 + vertex 95.6084 -82 19.8144 + vertex 95.3502 -82 19.3973 + endloop + endfacet + facet normal -0.850222 0 0.526424 + outer loop + vertex 95.6084 -82 19.8144 + vertex 95.3502 -101 19.3973 + vertex 95.6084 -101 19.8144 + endloop + endfacet + facet normal -0.602619 0 0.798029 + outer loop + vertex 95.6084 -82 19.8144 + vertex 96 -101 20.11 + vertex 96 -82 20.11 + endloop + endfacet + facet normal -0.602619 0 0.798029 + outer loop + vertex 96 -101 20.11 + vertex 95.6084 -82 19.8144 + vertex 95.6084 -101 19.8144 + endloop + endfacet + facet normal -0.273665 0 0.961825 + outer loop + vertex 96 -82 20.11 + vertex 96.4718 -101 20.2443 + vertex 96.4718 -82 20.2443 + endloop + endfacet + facet normal -0.273665 0 0.961825 + outer loop + vertex 96.4718 -101 20.2443 + vertex 96 -82 20.11 + vertex 96 -101 20.11 + endloop + endfacet + facet normal 0.0922792 0 0.995733 + outer loop + vertex 96.8872 -82 20.2058 + vertex 96.9603 -101 20.199 + vertex 96.9603 -82 20.199 + endloop + endfacet + facet normal 0.0922792 0 0.995733 + outer loop + vertex 96.9603 -101 20.199 + vertex 96.8872 -82 20.2058 + vertex 96.8872 -101 20.2058 + endloop + endfacet + facet normal 0.0922857 0 0.995733 + outer loop + vertex 96.4718 -82 20.2443 + vertex 96.605 -101 20.232 + vertex 96.605 -82 20.232 + endloop + endfacet + facet normal 0.0922857 0 0.995733 + outer loop + vertex 96.605 -101 20.232 + vertex 96.4718 -82 20.2443 + vertex 96.4718 -101 20.2443 + endloop + endfacet + facet normal 0.445737 0 0.895164 + outer loop + vertex 96.9603 -82 20.199 + vertex 96.9798 -101 20.1893 + vertex 96.9798 -82 20.1893 + endloop + endfacet + facet normal 0.445737 0 0.895164 + outer loop + vertex 96.9798 -101 20.1893 + vertex 96.9603 -82 20.199 + vertex 96.9603 -101 20.199 + endloop + endfacet + facet normal 0.739002 -0 0.673704 + outer loop + vertex 97.5295 -101 19.8377 + vertex 97.73 -82 19.6178 + vertex 97.5295 -82 19.8377 + endloop + endfacet + facet normal 0.739002 0 0.673704 + outer loop + vertex 97.73 -82 19.6178 + vertex 97.5295 -101 19.8377 + vertex 97.73 -101 19.6178 + endloop + endfacet + facet normal 0.932469 -0 0.36125 + outer loop + vertex 97.73 -101 19.6178 + vertex 97.9073 -82 19.1603 + vertex 97.73 -82 19.6178 + endloop + endfacet + facet normal 0.932469 0 0.36125 + outer loop + vertex 97.9073 -82 19.1603 + vertex 97.73 -101 19.6178 + vertex 97.9073 -101 19.1603 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex 97.9073 -101 19.1603 + vertex 97.9073 -82 18.6697 + vertex 97.9073 -82 19.1603 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 97.9073 -82 18.6697 + vertex 97.9073 -101 19.1603 + vertex 97.9073 -101 18.6697 + endloop + endfacet + facet normal 0.932469 0 -0.36125 + outer loop + vertex 97.9073 -101 18.6697 + vertex 97.73 -82 18.2122 + vertex 97.9073 -82 18.6697 + endloop + endfacet + facet normal 0.932469 0 -0.36125 + outer loop + vertex 97.73 -82 18.2122 + vertex 97.9073 -101 18.6697 + vertex 97.73 -101 18.2122 + endloop + endfacet + facet normal 0.739009 0 -0.673695 + outer loop + vertex 97.73 -101 18.2122 + vertex 97.3995 -82 17.8497 + vertex 97.73 -82 18.2122 + endloop + endfacet + facet normal 0.739009 0 -0.673695 + outer loop + vertex 97.3995 -82 17.8497 + vertex 97.73 -101 18.2122 + vertex 97.3995 -101 17.8497 + endloop + endfacet + facet normal 0.445745 0 -0.89516 + outer loop + vertex 96.9603 -101 17.631 + vertex 97.3995 -82 17.8497 + vertex 97.3995 -101 17.8497 + endloop + endfacet + facet normal 0.445745 0 -0.89516 + outer loop + vertex 97.3995 -82 17.8497 + vertex 96.9603 -101 17.631 + vertex 96.9603 -82 17.631 + endloop + endfacet + facet normal 0.0922827 0 -0.995733 + outer loop + vertex 96.4718 -101 17.5857 + vertex 96.9603 -82 17.631 + vertex 96.9603 -101 17.631 + endloop + endfacet + facet normal 0.0922827 0 -0.995733 + outer loop + vertex 96.9603 -82 17.631 + vertex 96.4718 -101 17.5857 + vertex 96.4718 -82 17.5857 + endloop + endfacet + facet normal -0.273665 0 -0.961825 + outer loop + vertex 96 -101 17.72 + vertex 96.4718 -82 17.5857 + vertex 96.4718 -101 17.5857 + endloop + endfacet + facet normal -0.273665 0 -0.961825 + outer loop + vertex 96.4718 -82 17.5857 + vertex 96 -101 17.72 + vertex 96 -82 17.72 + endloop + endfacet + facet normal -0.433867 0 0.900977 + outer loop + vertex 96.8364 -82 17.8572 + vertex 97.2715 -101 18.0667 + vertex 97.2715 -82 18.0667 + endloop + endfacet + facet normal -0.433867 0 0.900977 + outer loop + vertex 97.2715 -101 18.0667 + vertex 96.8364 -82 17.8572 + vertex 96.8364 -101 17.8572 + endloop + endfacet + facet normal -0.781848 0 0.623469 + outer loop + vertex 97.2715 -101 18.0667 + vertex 97.5725 -82 18.4443 + vertex 97.2715 -82 18.0667 + endloop + endfacet + facet normal -0.781848 0 0.623469 + outer loop + vertex 97.5725 -82 18.4443 + vertex 97.2715 -101 18.0667 + vertex 97.5725 -101 18.4443 + endloop + endfacet + facet normal -0.974925 0 0.222535 + outer loop + vertex 97.5725 -101 18.4443 + vertex 97.68 -82 18.915 + vertex 97.5725 -82 18.4443 + endloop + endfacet + facet normal -0.974925 0 0.222535 + outer loop + vertex 97.68 -82 18.915 + vertex 97.5725 -101 18.4443 + vertex 97.68 -101 18.915 + endloop + endfacet + facet normal -0.974925 0 -0.222535 + outer loop + vertex 97.68 -101 18.915 + vertex 97.5725 -82 19.3857 + vertex 97.68 -82 18.915 + endloop + endfacet + facet normal -0.974925 -0 -0.222535 + outer loop + vertex 97.5725 -82 19.3857 + vertex 97.68 -101 18.915 + vertex 97.5725 -101 19.3857 + endloop + endfacet + facet normal -0.781848 0 -0.623469 + outer loop + vertex 97.5725 -101 19.3857 + vertex 97.2715 -82 19.7633 + vertex 97.5725 -82 19.3857 + endloop + endfacet + facet normal -0.781848 -0 -0.623469 + outer loop + vertex 97.2715 -82 19.7633 + vertex 97.5725 -101 19.3857 + vertex 97.2715 -101 19.7633 + endloop + endfacet + facet normal -0.433867 0 -0.900977 + outer loop + vertex 96.8755 -101 19.954 + vertex 97.2715 -82 19.7633 + vertex 97.2715 -101 19.7633 + endloop + endfacet + facet normal -0.433867 0 -0.900977 + outer loop + vertex 97.2715 -82 19.7633 + vertex 96.8755 -101 19.954 + vertex 96.8755 -82 19.954 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 96.3536 -101 19.9728 + vertex 96.7696 -82 19.9728 + vertex 96.7696 -101 19.9728 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 96.7696 -82 19.9728 + vertex 96.3536 -101 19.9728 + vertex 96.3536 -82 19.9728 + endloop + endfacet + facet normal 0.433867 0 -0.900977 + outer loop + vertex 95.9185 -101 19.7633 + vertex 96.3536 -82 19.9728 + vertex 96.3536 -101 19.9728 + endloop + endfacet + facet normal 0.433867 0 -0.900977 + outer loop + vertex 96.3536 -82 19.9728 + vertex 95.9185 -101 19.7633 + vertex 95.9185 -82 19.7633 + endloop + endfacet + facet normal 0.781848 0 -0.623469 + outer loop + vertex 95.9185 -101 19.7633 + vertex 95.6175 -82 19.3857 + vertex 95.9185 -82 19.7633 + endloop + endfacet + facet normal 0.781848 0 -0.623469 + outer loop + vertex 95.6175 -82 19.3857 + vertex 95.9185 -101 19.7633 + vertex 95.6175 -101 19.3857 + endloop + endfacet + facet normal 0.974925 0 -0.222535 + outer loop + vertex 95.6175 -101 19.3857 + vertex 95.51 -82 18.915 + vertex 95.6175 -82 19.3857 + endloop + endfacet + facet normal 0.974925 0 -0.222535 + outer loop + vertex 95.51 -82 18.915 + vertex 95.6175 -101 19.3857 + vertex 95.51 -101 18.915 + endloop + endfacet + facet normal 0.974925 -0 0.222535 + outer loop + vertex 95.51 -101 18.915 + vertex 95.6175 -82 18.4443 + vertex 95.51 -82 18.915 + endloop + endfacet + facet normal 0.974925 0 0.222535 + outer loop + vertex 95.6175 -82 18.4443 + vertex 95.51 -101 18.915 + vertex 95.6175 -101 18.4443 + endloop + endfacet + facet normal 0.781848 -0 0.623469 + outer loop + vertex 95.6175 -101 18.4443 + vertex 95.9185 -82 18.0667 + vertex 95.6175 -82 18.4443 + endloop + endfacet + facet normal 0.781848 0 0.623469 + outer loop + vertex 95.9185 -82 18.0667 + vertex 95.6175 -101 18.4443 + vertex 95.9185 -101 18.0667 + endloop + endfacet + facet normal 0.433867 0 0.900977 + outer loop + vertex 95.9185 -82 18.0667 + vertex 96.3536 -101 17.8572 + vertex 96.3536 -82 17.8572 + endloop + endfacet + facet normal 0.433867 0 0.900977 + outer loop + vertex 96.3536 -101 17.8572 + vertex 95.9185 -82 18.0667 + vertex 95.9185 -101 18.0667 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 96.3536 -82 17.8572 + vertex 96.8364 -101 17.8572 + vertex 96.8364 -82 17.8572 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 96.8364 -101 17.8572 + vertex 96.3536 -82 17.8572 + vertex 96.3536 -101 17.8572 + endloop + endfacet + facet normal -0.602619 0 -0.798029 + outer loop + vertex 95.6084 -101 24.7856 + vertex 96 -82 24.49 + vertex 96 -101 24.49 + endloop + endfacet + facet normal -0.602619 0 -0.798029 + outer loop + vertex 96 -82 24.49 + vertex 95.6084 -101 24.7856 + vertex 95.6084 -82 24.7856 + endloop + endfacet + facet normal -0.850222 0 -0.526424 + outer loop + vertex 95.6084 -101 24.7856 + vertex 95.3502 -82 25.2027 + vertex 95.6084 -82 24.7856 + endloop + endfacet + facet normal -0.850222 -0 -0.526424 + outer loop + vertex 95.3502 -82 25.2027 + vertex 95.6084 -101 24.7856 + vertex 95.3502 -101 25.2027 + endloop + endfacet + facet normal -0.982973 0 -0.18375 + outer loop + vertex 95.3502 -101 25.2027 + vertex 95.26 -82 25.685 + vertex 95.3502 -82 25.2027 + endloop + endfacet + facet normal -0.982973 -0 -0.18375 + outer loop + vertex 95.26 -82 25.685 + vertex 95.3502 -101 25.2027 + vertex 95.26 -101 25.685 + endloop + endfacet + facet normal -0.982973 0 0.18375 + outer loop + vertex 95.26 -101 25.685 + vertex 95.3502 -82 26.1673 + vertex 95.26 -82 25.685 + endloop + endfacet + facet normal -0.982973 0 0.18375 + outer loop + vertex 95.3502 -82 26.1673 + vertex 95.26 -101 25.685 + vertex 95.3502 -101 26.1673 + endloop + endfacet + facet normal -0.850222 0 0.526424 + outer loop + vertex 95.3502 -101 26.1673 + vertex 95.6084 -82 26.5844 + vertex 95.3502 -82 26.1673 + endloop + endfacet + facet normal -0.850222 0 0.526424 + outer loop + vertex 95.6084 -82 26.5844 + vertex 95.3502 -101 26.1673 + vertex 95.6084 -101 26.5844 + endloop + endfacet + facet normal -0.602619 0 0.798029 + outer loop + vertex 95.6084 -82 26.5844 + vertex 96 -101 26.88 + vertex 96 -82 26.88 + endloop + endfacet + facet normal -0.602619 0 0.798029 + outer loop + vertex 96 -101 26.88 + vertex 95.6084 -82 26.5844 + vertex 95.6084 -101 26.5844 + endloop + endfacet + facet normal -0.273665 0 0.961825 + outer loop + vertex 96 -82 26.88 + vertex 96.4718 -101 27.0143 + vertex 96.4718 -82 27.0143 + endloop + endfacet + facet normal -0.273665 0 0.961825 + outer loop + vertex 96.4718 -101 27.0143 + vertex 96 -82 26.88 + vertex 96 -101 26.88 + endloop + endfacet + facet normal 0.0922827 0 0.995733 + outer loop + vertex 96.4718 -82 27.0143 + vertex 96.9603 -101 26.969 + vertex 96.9603 -82 26.969 + endloop + endfacet + facet normal 0.0922827 0 0.995733 + outer loop + vertex 96.9603 -101 26.969 + vertex 96.4718 -82 27.0143 + vertex 96.4718 -101 27.0143 + endloop + endfacet + facet normal 0.445745 0 0.89516 + outer loop + vertex 96.9603 -82 26.969 + vertex 97.3995 -101 26.7503 + vertex 97.3995 -82 26.7503 + endloop + endfacet + facet normal 0.445745 0 0.89516 + outer loop + vertex 97.3995 -101 26.7503 + vertex 96.9603 -82 26.969 + vertex 96.9603 -101 26.969 + endloop + endfacet + facet normal 0.739009 -0 0.673695 + outer loop + vertex 97.3995 -101 26.7503 + vertex 97.73 -82 26.3878 + vertex 97.3995 -82 26.7503 + endloop + endfacet + facet normal 0.739009 0 0.673695 + outer loop + vertex 97.73 -82 26.3878 + vertex 97.3995 -101 26.7503 + vertex 97.73 -101 26.3878 + endloop + endfacet + facet normal 0.932469 -0 0.36125 + outer loop + vertex 97.73 -101 26.3878 + vertex 97.9073 -82 25.9303 + vertex 97.73 -82 26.3878 + endloop + endfacet + facet normal 0.932469 0 0.36125 + outer loop + vertex 97.9073 -82 25.9303 + vertex 97.73 -101 26.3878 + vertex 97.9073 -101 25.9303 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex 97.9073 -101 25.9303 + vertex 97.9073 -82 25.4397 + vertex 97.9073 -82 25.9303 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 97.9073 -82 25.4397 + vertex 97.9073 -101 25.9303 + vertex 97.9073 -101 25.4397 + endloop + endfacet + facet normal 0.932469 0 -0.36125 + outer loop + vertex 97.9073 -101 25.4397 + vertex 97.73 -82 24.9822 + vertex 97.9073 -82 25.4397 + endloop + endfacet + facet normal 0.932469 0 -0.36125 + outer loop + vertex 97.73 -82 24.9822 + vertex 97.9073 -101 25.4397 + vertex 97.73 -101 24.9822 + endloop + endfacet + facet normal 0.739002 0 -0.673704 + outer loop + vertex 97.73 -101 24.9822 + vertex 97.5295 -82 24.7623 + vertex 97.73 -82 24.9822 + endloop + endfacet + facet normal 0.739002 0 -0.673704 + outer loop + vertex 97.5295 -82 24.7623 + vertex 97.73 -101 24.9822 + vertex 97.5295 -101 24.7623 + endloop + endfacet + facet normal 0.445737 0 -0.895164 + outer loop + vertex 96.9603 -101 24.401 + vertex 96.9798 -82 24.4107 + vertex 96.9798 -101 24.4107 + endloop + endfacet + facet normal 0.445737 0 -0.895164 + outer loop + vertex 96.9798 -82 24.4107 + vertex 96.9603 -101 24.401 + vertex 96.9603 -82 24.401 + endloop + endfacet + facet normal 0.0922857 0 -0.995733 + outer loop + vertex 96.4718 -101 24.3557 + vertex 96.605 -82 24.368 + vertex 96.605 -101 24.368 + endloop + endfacet + facet normal 0.0922857 0 -0.995733 + outer loop + vertex 96.605 -82 24.368 + vertex 96.4718 -101 24.3557 + vertex 96.4718 -82 24.3557 + endloop + endfacet + facet normal 0.0922792 0 -0.995733 + outer loop + vertex 96.8872 -101 24.3942 + vertex 96.9603 -82 24.401 + vertex 96.9603 -101 24.401 + endloop + endfacet + facet normal 0.0922792 0 -0.995733 + outer loop + vertex 96.9603 -82 24.401 + vertex 96.8872 -101 24.3942 + vertex 96.8872 -82 24.3942 + endloop + endfacet + facet normal -0.273665 0 -0.961825 + outer loop + vertex 96 -101 24.49 + vertex 96.4718 -82 24.3557 + vertex 96.4718 -101 24.3557 + endloop + endfacet + facet normal -0.273665 0 -0.961825 + outer loop + vertex 96.4718 -82 24.3557 + vertex 96 -101 24.49 + vertex 96 -82 24.49 + endloop + endfacet + facet normal -0.433867 0 0.900977 + outer loop + vertex 96.8755 -82 24.646 + vertex 97.2715 -101 24.8367 + vertex 97.2715 -82 24.8367 + endloop + endfacet + facet normal -0.433867 0 0.900977 + outer loop + vertex 97.2715 -101 24.8367 + vertex 96.8755 -82 24.646 + vertex 96.8755 -101 24.646 + endloop + endfacet + facet normal -0.781848 0 0.623469 + outer loop + vertex 97.2715 -101 24.8367 + vertex 97.5725 -82 25.2143 + vertex 97.2715 -82 24.8367 + endloop + endfacet + facet normal -0.781848 0 0.623469 + outer loop + vertex 97.5725 -82 25.2143 + vertex 97.2715 -101 24.8367 + vertex 97.5725 -101 25.2143 + endloop + endfacet + facet normal -0.974925 0 0.222535 + outer loop + vertex 97.5725 -101 25.2143 + vertex 97.68 -82 25.685 + vertex 97.5725 -82 25.2143 + endloop + endfacet + facet normal -0.974925 0 0.222535 + outer loop + vertex 97.68 -82 25.685 + vertex 97.5725 -101 25.2143 + vertex 97.68 -101 25.685 + endloop + endfacet + facet normal -0.974925 0 -0.222535 + outer loop + vertex 97.68 -101 25.685 + vertex 97.5725 -82 26.1557 + vertex 97.68 -82 25.685 + endloop + endfacet + facet normal -0.974925 -0 -0.222535 + outer loop + vertex 97.5725 -82 26.1557 + vertex 97.68 -101 25.685 + vertex 97.5725 -101 26.1557 + endloop + endfacet + facet normal -0.781848 0 -0.623469 + outer loop + vertex 97.5725 -101 26.1557 + vertex 97.2715 -82 26.5333 + vertex 97.5725 -82 26.1557 + endloop + endfacet + facet normal -0.781848 -0 -0.623469 + outer loop + vertex 97.2715 -82 26.5333 + vertex 97.5725 -101 26.1557 + vertex 97.2715 -101 26.5333 + endloop + endfacet + facet normal -0.433867 0 -0.900977 + outer loop + vertex 96.8364 -101 26.7428 + vertex 97.2715 -82 26.5333 + vertex 97.2715 -101 26.5333 + endloop + endfacet + facet normal -0.433867 0 -0.900977 + outer loop + vertex 97.2715 -82 26.5333 + vertex 96.8364 -101 26.7428 + vertex 96.8364 -82 26.7428 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 96.3536 -101 26.7428 + vertex 96.8364 -82 26.7428 + vertex 96.8364 -101 26.7428 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 96.8364 -82 26.7428 + vertex 96.3536 -101 26.7428 + vertex 96.3536 -82 26.7428 + endloop + endfacet + facet normal 0.433867 0 -0.900977 + outer loop + vertex 95.9185 -101 26.5333 + vertex 96.3536 -82 26.7428 + vertex 96.3536 -101 26.7428 + endloop + endfacet + facet normal 0.433867 0 -0.900977 + outer loop + vertex 96.3536 -82 26.7428 + vertex 95.9185 -101 26.5333 + vertex 95.9185 -82 26.5333 + endloop + endfacet + facet normal 0.781848 0 -0.623469 + outer loop + vertex 95.9185 -101 26.5333 + vertex 95.6175 -82 26.1557 + vertex 95.9185 -82 26.5333 + endloop + endfacet + facet normal 0.781848 0 -0.623469 + outer loop + vertex 95.6175 -82 26.1557 + vertex 95.9185 -101 26.5333 + vertex 95.6175 -101 26.1557 + endloop + endfacet + facet normal 0.974925 0 -0.222535 + outer loop + vertex 95.6175 -101 26.1557 + vertex 95.51 -82 25.685 + vertex 95.6175 -82 26.1557 + endloop + endfacet + facet normal 0.974925 0 -0.222535 + outer loop + vertex 95.51 -82 25.685 + vertex 95.6175 -101 26.1557 + vertex 95.51 -101 25.685 + endloop + endfacet + facet normal 0.974925 -0 0.222535 + outer loop + vertex 95.51 -101 25.685 + vertex 95.6175 -82 25.2143 + vertex 95.51 -82 25.685 + endloop + endfacet + facet normal 0.974925 0 0.222535 + outer loop + vertex 95.6175 -82 25.2143 + vertex 95.51 -101 25.685 + vertex 95.6175 -101 25.2143 + endloop + endfacet + facet normal 0.781848 -0 0.623469 + outer loop + vertex 95.6175 -101 25.2143 + vertex 95.9185 -82 24.8367 + vertex 95.6175 -82 25.2143 + endloop + endfacet + facet normal 0.781848 0 0.623469 + outer loop + vertex 95.9185 -82 24.8367 + vertex 95.6175 -101 25.2143 + vertex 95.9185 -101 24.8367 + endloop + endfacet + facet normal 0.433867 0 0.900977 + outer loop + vertex 95.9185 -82 24.8367 + vertex 96.3536 -101 24.6272 + vertex 96.3536 -82 24.6272 + endloop + endfacet + facet normal 0.433867 0 0.900977 + outer loop + vertex 96.3536 -101 24.6272 + vertex 95.9185 -82 24.8367 + vertex 95.9185 -101 24.8367 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 96.3536 -82 24.6272 + vertex 96.7696 -101 24.6272 + vertex 96.7696 -82 24.6272 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 96.7696 -101 24.6272 + vertex 96.3536 -82 24.6272 + vertex 96.3536 -101 24.6272 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.981 82 20.5 + vertex 106.981 82 19.1223 + vertex 107 82 20.5 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.981 82 22.13 + vertex 106.981 82 22.1 + vertex 107 82 22.13 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.3536 82 26.7428 + vertex 96.4718 82 27.0143 + vertex 96 82 26.88 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.8364 82 26.7428 + vertex 96.4718 82 27.0143 + vertex 96.3536 82 26.7428 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.4718 82 27.0143 + vertex 96.8364 82 26.7428 + vertex 96.9603 82 26.969 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.9185 82 26.5333 + vertex 96 82 26.88 + vertex 95.6084 82 26.5844 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 96 82 26.88 + vertex 95.9185 82 26.5333 + vertex 96.3536 82 26.7428 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.6175 82 26.1557 + vertex 95.6084 82 26.5844 + vertex 95.3502 82 26.1673 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.6084 82 26.5844 + vertex 95.6175 82 26.1557 + vertex 95.9185 82 26.5333 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.51 82 25.685 + vertex 95.3502 82 26.1673 + vertex 95.26 82 25.685 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.3502 82 26.1673 + vertex 95.51 82 25.685 + vertex 95.6175 82 26.1557 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.3502 82 25.2027 + vertex 95.51 82 25.685 + vertex 95.26 82 25.685 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 95.51 82 25.685 + vertex 95.3502 82 25.2027 + vertex 95.6175 82 25.2143 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.6084 82 24.7856 + vertex 95.6175 82 25.2143 + vertex 95.3502 82 25.2027 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 95.6175 82 25.2143 + vertex 95.6084 82 24.7856 + vertex 95.9185 82 24.8367 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96 82 24.49 + vertex 95.9185 82 24.8367 + vertex 95.6084 82 24.7856 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.4718 82 24.3557 + vertex 96.3536 82 24.6272 + vertex 96 82 24.49 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.9185 82 24.8367 + vertex 96 82 24.49 + vertex 96.3536 82 24.6272 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.2715 82 26.5333 + vertex 96.9603 82 26.969 + vertex 96.8364 82 26.7428 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.9603 82 26.969 + vertex 97.2715 82 26.5333 + vertex 97.3995 82 26.7503 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.2715 82 26.5333 + vertex 97.73 82 26.3878 + vertex 97.3995 82 26.7503 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5725 82 26.1557 + vertex 97.73 82 26.3878 + vertex 97.2715 82 26.5333 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5725 82 26.1557 + vertex 97.9073 82 25.9303 + vertex 97.73 82 26.3878 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.68 82 25.685 + vertex 97.9073 82 25.9303 + vertex 97.5725 82 26.1557 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.68 82 25.685 + vertex 97.9073 82 25.4397 + vertex 97.9073 82 25.9303 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5725 82 25.2143 + vertex 97.9073 82 25.4397 + vertex 97.68 82 25.685 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5725 82 25.2143 + vertex 97.73 82 24.9822 + vertex 97.9073 82 25.4397 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5295 82 24.7623 + vertex 97.5725 82 25.2143 + vertex 97.2715 82 24.8367 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 97.5725 82 25.2143 + vertex 97.5295 82 24.7623 + vertex 97.73 82 24.9822 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.9798 82 24.4107 + vertex 97.2715 82 24.8367 + vertex 96.8755 82 24.646 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.523 82 25.9943 + vertex 106.139 82 26.2927 + vertex 106.146 82 26.04 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5295 82 24.7623 + vertex 106.146 82 26.04 + vertex 106.139 82 26.2927 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 97.2715 82 24.8367 + vertex 96.9798 82 24.4107 + vertex 97.5295 82 24.7623 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.8872 82 24.3942 + vertex 96.8755 82 24.646 + vertex 96.7696 82 24.6272 + endloop + endfacet + facet normal -0 -1 0 + outer loop + vertex 96.605 82 24.368 + vertex 96.3536 82 24.6272 + vertex 96.4718 82 24.3557 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 97.5295 82 24.7623 + vertex 96.9798 82 24.4107 + vertex 106.146 82 26.04 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.8755 82 24.646 + vertex 96.8872 82 24.3942 + vertex 96.9798 82 24.4107 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.9798 82 24.4107 + vertex 96.8872 82 24.3942 + vertex 96.9603 82 24.401 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 96.7696 82 24.6272 + vertex 96.605 82 24.368 + vertex 96.8872 82 24.3942 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.3536 82 24.6272 + vertex 96.605 82 24.368 + vertex 96.7696 82 24.6272 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.139 82 26.2927 + vertex 106.523 82 25.9943 + vertex 106.615 82 26.235 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.523 82 25.9943 + vertex 107.009 82 25.9631 + vertex 106.615 82 26.235 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.816 82 25.7924 + vertex 107.009 82 25.9631 + vertex 106.523 82 25.9943 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.816 82 25.7924 + vertex 107.231 82 25.5393 + vertex 107.009 82 25.9631 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.981 82 25.4777 + vertex 107.231 82 25.5393 + vertex 106.816 82 25.7924 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 107 82 24.13 + vertex 106.981 82 25.4777 + vertex 106.981 82 24.13 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.981 82 25.4777 + vertex 107 82 24.13 + vertex 107.231 82 25.5393 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 107 82 22.13 + vertex 107.231 82 25.5393 + vertex 107 82 24.13 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 107 82 22.1 + vertex 107 82 22.13 + vertex 106.981 82 22.1 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 107 82 22.1 + vertex 107.231 82 25.5393 + vertex 107 82 22.13 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 107.231 82 19.0607 + vertex 107 82 22.1 + vertex 107 82 20.5 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 107.231 82 19.0607 + vertex 107 82 20.5 + vertex 106.981 82 19.1223 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 107 82 22.1 + vertex 107.231 82 19.0607 + vertex 107.231 82 25.5393 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.816 82 18.8076 + vertex 107.231 82 19.0607 + vertex 106.981 82 19.1223 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.816 82 18.8076 + vertex 107.009 82 18.6369 + vertex 107.231 82 19.0607 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.523 82 18.6057 + vertex 107.009 82 18.6369 + vertex 106.816 82 18.8076 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.139 82 18.3073 + vertex 106.523 82 18.6057 + vertex 106.146 82 18.56 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.523 82 18.6057 + vertex 106.615 82 18.365 + vertex 107.009 82 18.6369 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.8872 82 24.3942 + vertex 96.605 82 24.368 + vertex 96.605 82 24.344 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.9798 82 20.1893 + vertex 97.2715 82 19.7633 + vertex 97.5295 82 19.8377 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5725 82 19.3857 + vertex 97.5295 82 19.8377 + vertex 97.2715 82 19.7633 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5295 82 19.8377 + vertex 97.5725 82 19.3857 + vertex 97.73 82 19.6178 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5725 82 19.3857 + vertex 97.9073 82 19.1603 + vertex 97.73 82 19.6178 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.68 82 18.915 + vertex 97.9073 82 19.1603 + vertex 97.5725 82 19.3857 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.68 82 18.915 + vertex 97.9073 82 18.6697 + vertex 97.9073 82 19.1603 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5725 82 18.4443 + vertex 97.9073 82 18.6697 + vertex 97.68 82 18.915 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5725 82 18.4443 + vertex 97.73 82 18.2122 + vertex 97.9073 82 18.6697 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.2715 82 18.0667 + vertex 97.73 82 18.2122 + vertex 97.5725 82 18.4443 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.9603 82 17.631 + vertex 97.2715 82 18.0667 + vertex 96.8364 82 17.8572 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.2715 82 18.0667 + vertex 97.3995 82 17.8497 + vertex 97.73 82 18.2122 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.9185 82 19.7633 + vertex 96 82 20.11 + vertex 95.6084 82 19.8144 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 96 82 20.11 + vertex 95.9185 82 19.7633 + vertex 96.3536 82 19.9728 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.6175 82 19.3857 + vertex 95.6084 82 19.8144 + vertex 95.3502 82 19.3973 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.6084 82 19.8144 + vertex 95.6175 82 19.3857 + vertex 95.9185 82 19.7633 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.51 82 18.915 + vertex 95.3502 82 19.3973 + vertex 95.26 82 18.915 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.3502 82 19.3973 + vertex 95.51 82 18.915 + vertex 95.6175 82 19.3857 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.3502 82 18.4327 + vertex 95.51 82 18.915 + vertex 95.26 82 18.915 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 95.51 82 18.915 + vertex 95.3502 82 18.4327 + vertex 95.6175 82 18.4443 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.6084 82 18.0156 + vertex 95.6175 82 18.4443 + vertex 95.3502 82 18.4327 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 95.6175 82 18.4443 + vertex 95.6084 82 18.0156 + vertex 95.9185 82 18.0667 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96 82 17.72 + vertex 95.9185 82 18.0667 + vertex 95.6084 82 18.0156 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.4718 82 17.5857 + vertex 96.8364 82 17.8572 + vertex 96.3536 82 17.8572 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 95.9185 82 18.0667 + vertex 96 82 17.72 + vertex 96.3536 82 17.8572 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.4718 82 17.5857 + vertex 96.3536 82 17.8572 + vertex 96 82 17.72 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 97.2715 82 18.0667 + vertex 96.9603 82 17.631 + vertex 97.3995 82 17.8497 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 96.8364 82 17.8572 + vertex 96.4718 82 17.5857 + vertex 96.9603 82 17.631 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.8872 82 20.2058 + vertex 96.9798 82 20.1893 + vertex 96.9603 82 20.199 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.7696 82 19.9728 + vertex 96.8872 82 20.2058 + vertex 96.605 82 20.232 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.3536 82 19.9728 + vertex 96.605 82 20.232 + vertex 96.4718 82 20.2443 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.3536 82 19.9728 + vertex 96.4718 82 20.2443 + vertex 96 82 20.11 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 96.605 82 20.232 + vertex 96.3536 82 19.9728 + vertex 96.7696 82 19.9728 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.8755 82 19.954 + vertex 96.8872 82 20.2058 + vertex 96.7696 82 19.9728 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 96.8872 82 20.2058 + vertex 96.8755 82 19.954 + vertex 96.9798 82 20.1893 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.2715 82 19.7633 + vertex 96.9798 82 20.1893 + vertex 96.8755 82 19.954 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 97.5295 82 19.8377 + vertex 106.146 82 18.56 + vertex 96.9798 82 20.1893 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 106.139 82 18.3073 + vertex 106.146 82 18.56 + vertex 97.5295 82 19.8377 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 106.523 82 18.6057 + vertex 106.139 82 18.3073 + vertex 106.615 82 18.365 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 96.605 82 20.256 + vertex 96.605 82 20.232 + vertex 96.8872 82 20.2058 + endloop + endfacet + facet normal -0.175007 0 0.984567 + outer loop + vertex 97.5295 101 24.7623 + vertex 106.139 82 26.2927 + vertex 106.139 101 26.2927 + endloop + endfacet + facet normal -0.175007 0 0.984567 + outer loop + vertex 106.139 82 26.2927 + vertex 97.5295 101 24.7623 + vertex 97.5295 82 24.7623 + endloop + endfacet + facet normal -0.175 0 0.984568 + outer loop + vertex 96.7696 101 24.6272 + vertex 96.8755 82 24.646 + vertex 96.8755 101 24.646 + endloop + endfacet + facet normal -0.175 0 0.984568 + outer loop + vertex 96.8755 82 24.646 + vertex 96.7696 101 24.6272 + vertex 96.7696 82 24.6272 + endloop + endfacet + facet normal 0.120538 0 0.992709 + outer loop + vertex 106.139 101 26.2927 + vertex 106.615 82 26.235 + vertex 106.615 101 26.235 + endloop + endfacet + facet normal 0.120538 0 0.992709 + outer loop + vertex 106.615 82 26.235 + vertex 106.139 101 26.2927 + vertex 106.139 82 26.2927 + endloop + endfacet + facet normal 0.568069 0 0.822981 + outer loop + vertex 106.615 101 26.235 + vertex 107.009 82 25.9631 + vertex 107.009 101 25.9631 + endloop + endfacet + facet normal 0.568069 0 0.822981 + outer loop + vertex 107.009 82 25.9631 + vertex 106.615 101 26.235 + vertex 106.615 82 26.235 + endloop + endfacet + facet normal 0.885462 -0 0.464712 + outer loop + vertex 107.009 82 25.9631 + vertex 107.231 101 25.5393 + vertex 107.009 101 25.9631 + endloop + endfacet + facet normal 0.885462 0 0.464712 + outer loop + vertex 107.231 101 25.5393 + vertex 107.009 82 25.9631 + vertex 107.231 82 25.5393 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex 107.231 82 25.5393 + vertex 107.231 101 19.0607 + vertex 107.231 101 25.5393 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 107.231 101 19.0607 + vertex 107.231 82 25.5393 + vertex 107.231 82 19.0607 + endloop + endfacet + facet normal 0.885462 0 -0.464712 + outer loop + vertex 107.231 82 19.0607 + vertex 107.009 101 18.6369 + vertex 107.231 101 19.0607 + endloop + endfacet + facet normal 0.885462 0 -0.464712 + outer loop + vertex 107.009 101 18.6369 + vertex 107.231 82 19.0607 + vertex 107.009 82 18.6369 + endloop + endfacet + facet normal 0.568069 0 -0.822981 + outer loop + vertex 106.615 82 18.365 + vertex 107.009 101 18.6369 + vertex 107.009 82 18.6369 + endloop + endfacet + facet normal 0.568069 0 -0.822981 + outer loop + vertex 107.009 101 18.6369 + vertex 106.615 82 18.365 + vertex 106.615 101 18.365 + endloop + endfacet + facet normal 0.120538 0 -0.992709 + outer loop + vertex 106.139 82 18.3073 + vertex 106.615 101 18.365 + vertex 106.615 82 18.365 + endloop + endfacet + facet normal 0.120538 0 -0.992709 + outer loop + vertex 106.615 101 18.365 + vertex 106.139 82 18.3073 + vertex 106.139 101 18.3073 + endloop + endfacet + facet normal -0.175008 0 -0.984567 + outer loop + vertex 97.5295 82 19.8377 + vertex 106.139 101 18.3073 + vertex 106.139 82 18.3073 + endloop + endfacet + facet normal -0.175008 0 -0.984567 + outer loop + vertex 106.139 101 18.3073 + vertex 97.5295 82 19.8377 + vertex 97.5295 101 19.8377 + endloop + endfacet + facet normal -0.175 0 -0.984568 + outer loop + vertex 96.7696 82 19.9728 + vertex 96.8755 101 19.954 + vertex 96.8755 82 19.954 + endloop + endfacet + facet normal -0.175 0 -0.984568 + outer loop + vertex 96.8755 101 19.954 + vertex 96.7696 82 19.9728 + vertex 96.7696 101 19.9728 + endloop + endfacet + facet normal -0.568073 0 0.822978 + outer loop + vertex 106.523 101 18.6057 + vertex 106.816 82 18.8076 + vertex 106.816 101 18.8076 + endloop + endfacet + facet normal -0.568073 0 0.822978 + outer loop + vertex 106.816 82 18.8076 + vertex 106.523 101 18.6057 + vertex 106.523 82 18.6057 + endloop + endfacet + facet normal -0.88547 0 0.464697 + outer loop + vertex 106.816 82 18.8076 + vertex 106.981 101 19.1223 + vertex 106.816 101 18.8076 + endloop + endfacet + facet normal -0.88547 0 0.464697 + outer loop + vertex 106.981 101 19.1223 + vertex 106.816 82 18.8076 + vertex 106.981 82 19.1223 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex 106.981 82 24.13 + vertex 106.981 101 25.4777 + vertex 106.981 101 24.13 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex 106.981 101 25.4777 + vertex 106.981 82 24.13 + vertex 106.981 82 25.4777 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex 106.981 82 19.1223 + vertex 106.981 101 20.5 + vertex 106.981 101 19.1223 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex 106.981 101 20.5 + vertex 106.981 82 19.1223 + vertex 106.981 82 20.5 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex 106.981 82 22.1 + vertex 106.981 101 22.13 + vertex 106.981 101 22.1 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex 106.981 101 22.13 + vertex 106.981 82 22.1 + vertex 106.981 82 22.13 + endloop + endfacet + facet normal -0.88547 0 -0.464697 + outer loop + vertex 106.981 82 25.4777 + vertex 106.816 101 25.7924 + vertex 106.981 101 25.4777 + endloop + endfacet + facet normal -0.88547 -0 -0.464697 + outer loop + vertex 106.816 101 25.7924 + vertex 106.981 82 25.4777 + vertex 106.816 82 25.7924 + endloop + endfacet + facet normal -0.568073 0 -0.822978 + outer loop + vertex 106.523 82 25.9943 + vertex 106.816 101 25.7924 + vertex 106.816 82 25.7924 + endloop + endfacet + facet normal -0.568073 0 -0.822978 + outer loop + vertex 106.816 101 25.7924 + vertex 106.523 82 25.9943 + vertex 106.523 101 25.9943 + endloop + endfacet + facet normal -0.120522 0 -0.992711 + outer loop + vertex 106.146 82 26.04 + vertex 106.523 101 25.9943 + vertex 106.523 82 25.9943 + endloop + endfacet + facet normal -0.120522 0 -0.992711 + outer loop + vertex 106.523 101 25.9943 + vertex 106.146 82 26.04 + vertex 106.146 101 26.04 + endloop + endfacet + facet normal 0.175007 0 -0.984567 + outer loop + vertex 96.9798 82 24.4107 + vertex 106.146 101 26.04 + vertex 106.146 82 26.04 + endloop + endfacet + facet normal 0.175007 0 -0.984567 + outer loop + vertex 106.146 101 26.04 + vertex 96.9798 82 24.4107 + vertex 96.9798 101 24.4107 + endloop + endfacet + facet normal 0.175007 0 -0.984567 + outer loop + vertex 96.605 82 24.344 + vertex 96.8872 101 24.3942 + vertex 96.8872 82 24.3942 + endloop + endfacet + facet normal 0.175007 0 -0.984567 + outer loop + vertex 96.8872 101 24.3942 + vertex 96.605 82 24.344 + vertex 96.605 101 24.344 + endloop + endfacet + facet normal 0.175007 0 0.984567 + outer loop + vertex 96.9798 101 20.1893 + vertex 106.146 82 18.56 + vertex 106.146 101 18.56 + endloop + endfacet + facet normal 0.175007 0 0.984567 + outer loop + vertex 106.146 82 18.56 + vertex 96.9798 101 20.1893 + vertex 96.9798 82 20.1893 + endloop + endfacet + facet normal 0.175007 0 0.984567 + outer loop + vertex 96.605 101 20.256 + vertex 96.8872 82 20.2058 + vertex 96.8872 101 20.2058 + endloop + endfacet + facet normal 0.175007 0 0.984567 + outer loop + vertex 96.8872 82 20.2058 + vertex 96.605 101 20.256 + vertex 96.605 82 20.256 + endloop + endfacet + facet normal -0.120522 0 0.992711 + outer loop + vertex 106.146 101 18.56 + vertex 106.523 82 18.6057 + vertex 106.523 101 18.6057 + endloop + endfacet + facet normal -0.120522 0 0.992711 + outer loop + vertex 106.523 82 18.6057 + vertex 106.146 101 18.56 + vertex 106.146 82 18.56 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex 96.605 82 24.344 + vertex 96.605 101 24.368 + vertex 96.605 101 24.344 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex 96.605 101 24.368 + vertex 96.605 82 24.344 + vertex 96.605 82 24.368 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex 96.605 82 20.232 + vertex 96.605 101 20.256 + vertex 96.605 101 20.232 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex 96.605 101 20.256 + vertex 96.605 82 20.232 + vertex 96.605 82 20.256 + endloop + endfacet + facet normal -0.602619 0 -0.798029 + outer loop + vertex 95.6084 82 18.0156 + vertex 96 101 17.72 + vertex 96 82 17.72 + endloop + endfacet + facet normal -0.602619 0 -0.798029 + outer loop + vertex 96 101 17.72 + vertex 95.6084 82 18.0156 + vertex 95.6084 101 18.0156 + endloop + endfacet + facet normal -0.850222 0 -0.526424 + outer loop + vertex 95.6084 82 18.0156 + vertex 95.3502 101 18.4327 + vertex 95.6084 101 18.0156 + endloop + endfacet + facet normal -0.850222 -0 -0.526424 + outer loop + vertex 95.3502 101 18.4327 + vertex 95.6084 82 18.0156 + vertex 95.3502 82 18.4327 + endloop + endfacet + facet normal -0.982973 0 -0.18375 + outer loop + vertex 95.3502 82 18.4327 + vertex 95.26 101 18.915 + vertex 95.3502 101 18.4327 + endloop + endfacet + facet normal -0.982973 -0 -0.18375 + outer loop + vertex 95.26 101 18.915 + vertex 95.3502 82 18.4327 + vertex 95.26 82 18.915 + endloop + endfacet + facet normal -0.982973 0 0.18375 + outer loop + vertex 95.26 82 18.915 + vertex 95.3502 101 19.3973 + vertex 95.26 101 18.915 + endloop + endfacet + facet normal -0.982973 0 0.18375 + outer loop + vertex 95.3502 101 19.3973 + vertex 95.26 82 18.915 + vertex 95.3502 82 19.3973 + endloop + endfacet + facet normal -0.850222 0 0.526424 + outer loop + vertex 95.3502 82 19.3973 + vertex 95.6084 101 19.8144 + vertex 95.3502 101 19.3973 + endloop + endfacet + facet normal -0.850222 0 0.526424 + outer loop + vertex 95.6084 101 19.8144 + vertex 95.3502 82 19.3973 + vertex 95.6084 82 19.8144 + endloop + endfacet + facet normal -0.602619 0 0.798029 + outer loop + vertex 95.6084 101 19.8144 + vertex 96 82 20.11 + vertex 96 101 20.11 + endloop + endfacet + facet normal -0.602619 0 0.798029 + outer loop + vertex 96 82 20.11 + vertex 95.6084 101 19.8144 + vertex 95.6084 82 19.8144 + endloop + endfacet + facet normal -0.273665 0 0.961825 + outer loop + vertex 96 101 20.11 + vertex 96.4718 82 20.2443 + vertex 96.4718 101 20.2443 + endloop + endfacet + facet normal -0.273665 0 0.961825 + outer loop + vertex 96.4718 82 20.2443 + vertex 96 101 20.11 + vertex 96 82 20.11 + endloop + endfacet + facet normal 0.0922792 0 0.995733 + outer loop + vertex 96.8872 101 20.2058 + vertex 96.9603 82 20.199 + vertex 96.9603 101 20.199 + endloop + endfacet + facet normal 0.0922792 0 0.995733 + outer loop + vertex 96.9603 82 20.199 + vertex 96.8872 101 20.2058 + vertex 96.8872 82 20.2058 + endloop + endfacet + facet normal 0.0922857 0 0.995733 + outer loop + vertex 96.4718 101 20.2443 + vertex 96.605 82 20.232 + vertex 96.605 101 20.232 + endloop + endfacet + facet normal 0.0922857 0 0.995733 + outer loop + vertex 96.605 82 20.232 + vertex 96.4718 101 20.2443 + vertex 96.4718 82 20.2443 + endloop + endfacet + facet normal 0.445737 0 0.895164 + outer loop + vertex 96.9603 101 20.199 + vertex 96.9798 82 20.1893 + vertex 96.9798 101 20.1893 + endloop + endfacet + facet normal 0.445737 0 0.895164 + outer loop + vertex 96.9798 82 20.1893 + vertex 96.9603 101 20.199 + vertex 96.9603 82 20.199 + endloop + endfacet + facet normal 0.739002 -0 0.673704 + outer loop + vertex 97.5295 82 19.8377 + vertex 97.73 101 19.6178 + vertex 97.5295 101 19.8377 + endloop + endfacet + facet normal 0.739002 0 0.673704 + outer loop + vertex 97.73 101 19.6178 + vertex 97.5295 82 19.8377 + vertex 97.73 82 19.6178 + endloop + endfacet + facet normal 0.932469 -0 0.36125 + outer loop + vertex 97.73 82 19.6178 + vertex 97.9073 101 19.1603 + vertex 97.73 101 19.6178 + endloop + endfacet + facet normal 0.932469 0 0.36125 + outer loop + vertex 97.9073 101 19.1603 + vertex 97.73 82 19.6178 + vertex 97.9073 82 19.1603 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex 97.9073 82 19.1603 + vertex 97.9073 101 18.6697 + vertex 97.9073 101 19.1603 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 97.9073 101 18.6697 + vertex 97.9073 82 19.1603 + vertex 97.9073 82 18.6697 + endloop + endfacet + facet normal 0.932469 0 -0.36125 + outer loop + vertex 97.9073 82 18.6697 + vertex 97.73 101 18.2122 + vertex 97.9073 101 18.6697 + endloop + endfacet + facet normal 0.932469 0 -0.36125 + outer loop + vertex 97.73 101 18.2122 + vertex 97.9073 82 18.6697 + vertex 97.73 82 18.2122 + endloop + endfacet + facet normal 0.739009 0 -0.673695 + outer loop + vertex 97.73 82 18.2122 + vertex 97.3995 101 17.8497 + vertex 97.73 101 18.2122 + endloop + endfacet + facet normal 0.739009 0 -0.673695 + outer loop + vertex 97.3995 101 17.8497 + vertex 97.73 82 18.2122 + vertex 97.3995 82 17.8497 + endloop + endfacet + facet normal 0.445745 0 -0.89516 + outer loop + vertex 96.9603 82 17.631 + vertex 97.3995 101 17.8497 + vertex 97.3995 82 17.8497 + endloop + endfacet + facet normal 0.445745 0 -0.89516 + outer loop + vertex 97.3995 101 17.8497 + vertex 96.9603 82 17.631 + vertex 96.9603 101 17.631 + endloop + endfacet + facet normal 0.0922827 0 -0.995733 + outer loop + vertex 96.4718 82 17.5857 + vertex 96.9603 101 17.631 + vertex 96.9603 82 17.631 + endloop + endfacet + facet normal 0.0922827 0 -0.995733 + outer loop + vertex 96.9603 101 17.631 + vertex 96.4718 82 17.5857 + vertex 96.4718 101 17.5857 + endloop + endfacet + facet normal -0.273665 0 -0.961825 + outer loop + vertex 96 82 17.72 + vertex 96.4718 101 17.5857 + vertex 96.4718 82 17.5857 + endloop + endfacet + facet normal -0.273665 0 -0.961825 + outer loop + vertex 96.4718 101 17.5857 + vertex 96 82 17.72 + vertex 96 101 17.72 + endloop + endfacet + facet normal -0.433867 0 0.900977 + outer loop + vertex 96.8364 101 17.8572 + vertex 97.2715 82 18.0667 + vertex 97.2715 101 18.0667 + endloop + endfacet + facet normal -0.433867 0 0.900977 + outer loop + vertex 97.2715 82 18.0667 + vertex 96.8364 101 17.8572 + vertex 96.8364 82 17.8572 + endloop + endfacet + facet normal -0.781848 0 0.623469 + outer loop + vertex 97.2715 82 18.0667 + vertex 97.5725 101 18.4443 + vertex 97.2715 101 18.0667 + endloop + endfacet + facet normal -0.781848 0 0.623469 + outer loop + vertex 97.5725 101 18.4443 + vertex 97.2715 82 18.0667 + vertex 97.5725 82 18.4443 + endloop + endfacet + facet normal -0.974925 0 0.222535 + outer loop + vertex 97.5725 82 18.4443 + vertex 97.68 101 18.915 + vertex 97.5725 101 18.4443 + endloop + endfacet + facet normal -0.974925 0 0.222535 + outer loop + vertex 97.68 101 18.915 + vertex 97.5725 82 18.4443 + vertex 97.68 82 18.915 + endloop + endfacet + facet normal -0.974925 0 -0.222535 + outer loop + vertex 97.68 82 18.915 + vertex 97.5725 101 19.3857 + vertex 97.68 101 18.915 + endloop + endfacet + facet normal -0.974925 -0 -0.222535 + outer loop + vertex 97.5725 101 19.3857 + vertex 97.68 82 18.915 + vertex 97.5725 82 19.3857 + endloop + endfacet + facet normal -0.781848 0 -0.623469 + outer loop + vertex 97.5725 82 19.3857 + vertex 97.2715 101 19.7633 + vertex 97.5725 101 19.3857 + endloop + endfacet + facet normal -0.781848 -0 -0.623469 + outer loop + vertex 97.2715 101 19.7633 + vertex 97.5725 82 19.3857 + vertex 97.2715 82 19.7633 + endloop + endfacet + facet normal -0.433867 0 -0.900977 + outer loop + vertex 96.8755 82 19.954 + vertex 97.2715 101 19.7633 + vertex 97.2715 82 19.7633 + endloop + endfacet + facet normal -0.433867 0 -0.900977 + outer loop + vertex 97.2715 101 19.7633 + vertex 96.8755 82 19.954 + vertex 96.8755 101 19.954 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 96.3536 82 19.9728 + vertex 96.7696 101 19.9728 + vertex 96.7696 82 19.9728 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 96.7696 101 19.9728 + vertex 96.3536 82 19.9728 + vertex 96.3536 101 19.9728 + endloop + endfacet + facet normal 0.433867 0 -0.900977 + outer loop + vertex 95.9185 82 19.7633 + vertex 96.3536 101 19.9728 + vertex 96.3536 82 19.9728 + endloop + endfacet + facet normal 0.433867 0 -0.900977 + outer loop + vertex 96.3536 101 19.9728 + vertex 95.9185 82 19.7633 + vertex 95.9185 101 19.7633 + endloop + endfacet + facet normal 0.781848 0 -0.623469 + outer loop + vertex 95.9185 82 19.7633 + vertex 95.6175 101 19.3857 + vertex 95.9185 101 19.7633 + endloop + endfacet + facet normal 0.781848 0 -0.623469 + outer loop + vertex 95.6175 101 19.3857 + vertex 95.9185 82 19.7633 + vertex 95.6175 82 19.3857 + endloop + endfacet + facet normal 0.974925 0 -0.222535 + outer loop + vertex 95.6175 82 19.3857 + vertex 95.51 101 18.915 + vertex 95.6175 101 19.3857 + endloop + endfacet + facet normal 0.974925 0 -0.222535 + outer loop + vertex 95.51 101 18.915 + vertex 95.6175 82 19.3857 + vertex 95.51 82 18.915 + endloop + endfacet + facet normal 0.974925 -0 0.222535 + outer loop + vertex 95.51 82 18.915 + vertex 95.6175 101 18.4443 + vertex 95.51 101 18.915 + endloop + endfacet + facet normal 0.974925 0 0.222535 + outer loop + vertex 95.6175 101 18.4443 + vertex 95.51 82 18.915 + vertex 95.6175 82 18.4443 + endloop + endfacet + facet normal 0.781848 -0 0.623469 + outer loop + vertex 95.6175 82 18.4443 + vertex 95.9185 101 18.0667 + vertex 95.6175 101 18.4443 + endloop + endfacet + facet normal 0.781848 0 0.623469 + outer loop + vertex 95.9185 101 18.0667 + vertex 95.6175 82 18.4443 + vertex 95.9185 82 18.0667 + endloop + endfacet + facet normal 0.433867 0 0.900977 + outer loop + vertex 95.9185 101 18.0667 + vertex 96.3536 82 17.8572 + vertex 96.3536 101 17.8572 + endloop + endfacet + facet normal 0.433867 0 0.900977 + outer loop + vertex 96.3536 82 17.8572 + vertex 95.9185 101 18.0667 + vertex 95.9185 82 18.0667 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 96.3536 101 17.8572 + vertex 96.8364 82 17.8572 + vertex 96.8364 101 17.8572 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 96.8364 82 17.8572 + vertex 96.3536 101 17.8572 + vertex 96.3536 82 17.8572 + endloop + endfacet + facet normal -0.602619 0 -0.798029 + outer loop + vertex 95.6084 82 24.7856 + vertex 96 101 24.49 + vertex 96 82 24.49 + endloop + endfacet + facet normal -0.602619 0 -0.798029 + outer loop + vertex 96 101 24.49 + vertex 95.6084 82 24.7856 + vertex 95.6084 101 24.7856 + endloop + endfacet + facet normal -0.850222 0 -0.526424 + outer loop + vertex 95.6084 82 24.7856 + vertex 95.3502 101 25.2027 + vertex 95.6084 101 24.7856 + endloop + endfacet + facet normal -0.850222 -0 -0.526424 + outer loop + vertex 95.3502 101 25.2027 + vertex 95.6084 82 24.7856 + vertex 95.3502 82 25.2027 + endloop + endfacet + facet normal -0.982973 0 -0.18375 + outer loop + vertex 95.3502 82 25.2027 + vertex 95.26 101 25.685 + vertex 95.3502 101 25.2027 + endloop + endfacet + facet normal -0.982973 -0 -0.18375 + outer loop + vertex 95.26 101 25.685 + vertex 95.3502 82 25.2027 + vertex 95.26 82 25.685 + endloop + endfacet + facet normal -0.982973 0 0.18375 + outer loop + vertex 95.26 82 25.685 + vertex 95.3502 101 26.1673 + vertex 95.26 101 25.685 + endloop + endfacet + facet normal -0.982973 0 0.18375 + outer loop + vertex 95.3502 101 26.1673 + vertex 95.26 82 25.685 + vertex 95.3502 82 26.1673 + endloop + endfacet + facet normal -0.850222 0 0.526424 + outer loop + vertex 95.3502 82 26.1673 + vertex 95.6084 101 26.5844 + vertex 95.3502 101 26.1673 + endloop + endfacet + facet normal -0.850222 0 0.526424 + outer loop + vertex 95.6084 101 26.5844 + vertex 95.3502 82 26.1673 + vertex 95.6084 82 26.5844 + endloop + endfacet + facet normal -0.602619 0 0.798029 + outer loop + vertex 95.6084 101 26.5844 + vertex 96 82 26.88 + vertex 96 101 26.88 + endloop + endfacet + facet normal -0.602619 0 0.798029 + outer loop + vertex 96 82 26.88 + vertex 95.6084 101 26.5844 + vertex 95.6084 82 26.5844 + endloop + endfacet + facet normal -0.273665 0 0.961825 + outer loop + vertex 96 101 26.88 + vertex 96.4718 82 27.0143 + vertex 96.4718 101 27.0143 + endloop + endfacet + facet normal -0.273665 0 0.961825 + outer loop + vertex 96.4718 82 27.0143 + vertex 96 101 26.88 + vertex 96 82 26.88 + endloop + endfacet + facet normal 0.0922827 0 0.995733 + outer loop + vertex 96.4718 101 27.0143 + vertex 96.9603 82 26.969 + vertex 96.9603 101 26.969 + endloop + endfacet + facet normal 0.0922827 0 0.995733 + outer loop + vertex 96.9603 82 26.969 + vertex 96.4718 101 27.0143 + vertex 96.4718 82 27.0143 + endloop + endfacet + facet normal 0.445745 0 0.89516 + outer loop + vertex 96.9603 101 26.969 + vertex 97.3995 82 26.7503 + vertex 97.3995 101 26.7503 + endloop + endfacet + facet normal 0.445745 0 0.89516 + outer loop + vertex 97.3995 82 26.7503 + vertex 96.9603 101 26.969 + vertex 96.9603 82 26.969 + endloop + endfacet + facet normal 0.739009 -0 0.673695 + outer loop + vertex 97.3995 82 26.7503 + vertex 97.73 101 26.3878 + vertex 97.3995 101 26.7503 + endloop + endfacet + facet normal 0.739009 0 0.673695 + outer loop + vertex 97.73 101 26.3878 + vertex 97.3995 82 26.7503 + vertex 97.73 82 26.3878 + endloop + endfacet + facet normal 0.932469 -0 0.36125 + outer loop + vertex 97.73 82 26.3878 + vertex 97.9073 101 25.9303 + vertex 97.73 101 26.3878 + endloop + endfacet + facet normal 0.932469 0 0.36125 + outer loop + vertex 97.9073 101 25.9303 + vertex 97.73 82 26.3878 + vertex 97.9073 82 25.9303 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex 97.9073 82 25.9303 + vertex 97.9073 101 25.4397 + vertex 97.9073 101 25.9303 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 97.9073 101 25.4397 + vertex 97.9073 82 25.9303 + vertex 97.9073 82 25.4397 + endloop + endfacet + facet normal 0.932469 0 -0.36125 + outer loop + vertex 97.9073 82 25.4397 + vertex 97.73 101 24.9822 + vertex 97.9073 101 25.4397 + endloop + endfacet + facet normal 0.932469 0 -0.36125 + outer loop + vertex 97.73 101 24.9822 + vertex 97.9073 82 25.4397 + vertex 97.73 82 24.9822 + endloop + endfacet + facet normal 0.739002 0 -0.673704 + outer loop + vertex 97.73 82 24.9822 + vertex 97.5295 101 24.7623 + vertex 97.73 101 24.9822 + endloop + endfacet + facet normal 0.739002 0 -0.673704 + outer loop + vertex 97.5295 101 24.7623 + vertex 97.73 82 24.9822 + vertex 97.5295 82 24.7623 + endloop + endfacet + facet normal 0.445737 0 -0.895164 + outer loop + vertex 96.9603 82 24.401 + vertex 96.9798 101 24.4107 + vertex 96.9798 82 24.4107 + endloop + endfacet + facet normal 0.445737 0 -0.895164 + outer loop + vertex 96.9798 101 24.4107 + vertex 96.9603 82 24.401 + vertex 96.9603 101 24.401 + endloop + endfacet + facet normal 0.0922857 0 -0.995733 + outer loop + vertex 96.4718 82 24.3557 + vertex 96.605 101 24.368 + vertex 96.605 82 24.368 + endloop + endfacet + facet normal 0.0922857 0 -0.995733 + outer loop + vertex 96.605 101 24.368 + vertex 96.4718 82 24.3557 + vertex 96.4718 101 24.3557 + endloop + endfacet + facet normal 0.0922792 0 -0.995733 + outer loop + vertex 96.8872 82 24.3942 + vertex 96.9603 101 24.401 + vertex 96.9603 82 24.401 + endloop + endfacet + facet normal 0.0922792 0 -0.995733 + outer loop + vertex 96.9603 101 24.401 + vertex 96.8872 82 24.3942 + vertex 96.8872 101 24.3942 + endloop + endfacet + facet normal -0.273665 0 -0.961825 + outer loop + vertex 96 82 24.49 + vertex 96.4718 101 24.3557 + vertex 96.4718 82 24.3557 + endloop + endfacet + facet normal -0.273665 0 -0.961825 + outer loop + vertex 96.4718 101 24.3557 + vertex 96 82 24.49 + vertex 96 101 24.49 + endloop + endfacet + facet normal -0.433867 0 0.900977 + outer loop + vertex 96.8755 101 24.646 + vertex 97.2715 82 24.8367 + vertex 97.2715 101 24.8367 + endloop + endfacet + facet normal -0.433867 0 0.900977 + outer loop + vertex 97.2715 82 24.8367 + vertex 96.8755 101 24.646 + vertex 96.8755 82 24.646 + endloop + endfacet + facet normal -0.781848 0 0.623469 + outer loop + vertex 97.2715 82 24.8367 + vertex 97.5725 101 25.2143 + vertex 97.2715 101 24.8367 + endloop + endfacet + facet normal -0.781848 0 0.623469 + outer loop + vertex 97.5725 101 25.2143 + vertex 97.2715 82 24.8367 + vertex 97.5725 82 25.2143 + endloop + endfacet + facet normal -0.974925 0 0.222535 + outer loop + vertex 97.5725 82 25.2143 + vertex 97.68 101 25.685 + vertex 97.5725 101 25.2143 + endloop + endfacet + facet normal -0.974925 0 0.222535 + outer loop + vertex 97.68 101 25.685 + vertex 97.5725 82 25.2143 + vertex 97.68 82 25.685 + endloop + endfacet + facet normal -0.974925 0 -0.222535 + outer loop + vertex 97.68 82 25.685 + vertex 97.5725 101 26.1557 + vertex 97.68 101 25.685 + endloop + endfacet + facet normal -0.974925 -0 -0.222535 + outer loop + vertex 97.5725 101 26.1557 + vertex 97.68 82 25.685 + vertex 97.5725 82 26.1557 + endloop + endfacet + facet normal -0.781848 0 -0.623469 + outer loop + vertex 97.5725 82 26.1557 + vertex 97.2715 101 26.5333 + vertex 97.5725 101 26.1557 + endloop + endfacet + facet normal -0.781848 -0 -0.623469 + outer loop + vertex 97.2715 101 26.5333 + vertex 97.5725 82 26.1557 + vertex 97.2715 82 26.5333 + endloop + endfacet + facet normal -0.433867 0 -0.900977 + outer loop + vertex 96.8364 82 26.7428 + vertex 97.2715 101 26.5333 + vertex 97.2715 82 26.5333 + endloop + endfacet + facet normal -0.433867 0 -0.900977 + outer loop + vertex 97.2715 101 26.5333 + vertex 96.8364 82 26.7428 + vertex 96.8364 101 26.7428 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 96.3536 82 26.7428 + vertex 96.8364 101 26.7428 + vertex 96.8364 82 26.7428 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 96.8364 101 26.7428 + vertex 96.3536 82 26.7428 + vertex 96.3536 101 26.7428 + endloop + endfacet + facet normal 0.433867 0 -0.900977 + outer loop + vertex 95.9185 82 26.5333 + vertex 96.3536 101 26.7428 + vertex 96.3536 82 26.7428 + endloop + endfacet + facet normal 0.433867 0 -0.900977 + outer loop + vertex 96.3536 101 26.7428 + vertex 95.9185 82 26.5333 + vertex 95.9185 101 26.5333 + endloop + endfacet + facet normal 0.781848 0 -0.623469 + outer loop + vertex 95.9185 82 26.5333 + vertex 95.6175 101 26.1557 + vertex 95.9185 101 26.5333 + endloop + endfacet + facet normal 0.781848 0 -0.623469 + outer loop + vertex 95.6175 101 26.1557 + vertex 95.9185 82 26.5333 + vertex 95.6175 82 26.1557 + endloop + endfacet + facet normal 0.974925 0 -0.222535 + outer loop + vertex 95.6175 82 26.1557 + vertex 95.51 101 25.685 + vertex 95.6175 101 26.1557 + endloop + endfacet + facet normal 0.974925 0 -0.222535 + outer loop + vertex 95.51 101 25.685 + vertex 95.6175 82 26.1557 + vertex 95.51 82 25.685 + endloop + endfacet + facet normal 0.974925 -0 0.222535 + outer loop + vertex 95.51 82 25.685 + vertex 95.6175 101 25.2143 + vertex 95.51 101 25.685 + endloop + endfacet + facet normal 0.974925 0 0.222535 + outer loop + vertex 95.6175 101 25.2143 + vertex 95.51 82 25.685 + vertex 95.6175 82 25.2143 + endloop + endfacet + facet normal 0.781848 -0 0.623469 + outer loop + vertex 95.6175 82 25.2143 + vertex 95.9185 101 24.8367 + vertex 95.6175 101 25.2143 + endloop + endfacet + facet normal 0.781848 0 0.623469 + outer loop + vertex 95.9185 101 24.8367 + vertex 95.6175 82 25.2143 + vertex 95.9185 82 24.8367 + endloop + endfacet + facet normal 0.433867 0 0.900977 + outer loop + vertex 95.9185 101 24.8367 + vertex 96.3536 82 24.6272 + vertex 96.3536 101 24.6272 + endloop + endfacet + facet normal 0.433867 0 0.900977 + outer loop + vertex 96.3536 82 24.6272 + vertex 95.9185 101 24.8367 + vertex 95.9185 82 24.8367 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 96.3536 101 24.6272 + vertex 96.7696 82 24.6272 + vertex 96.7696 101 24.6272 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 96.7696 82 24.6272 + vertex 96.3536 101 24.6272 + vertex 96.3536 82 24.6272 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -107 -104.067 20.5 + vertex -107 -101 22.1 + vertex -107 -101 20.5 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -107 -107 22.1 + vertex -107 -104.067 20.5 + vertex -107 -104.933 20.5 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -107 -107 22.1 + vertex -107 -104.933 20.5 + vertex -107 -107 20.5 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -107 -104.067 20.5 + vertex -107 -107 22.1 + vertex -107 -101 22.1 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -107 104.933 20.5 + vertex -107 107 22.1 + vertex -107 107 20.5 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -107 104.067 20.5 + vertex -107 107 22.1 + vertex -107 104.933 20.5 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -107 101 22.1 + vertex -107 104.067 20.5 + vertex -107 101 20.5 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -107 104.067 20.5 + vertex -107 101 22.1 + vertex -107 107 22.1 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -107 -82 20.5 + vertex -107 82 22.1 + vertex -107 82 20.5 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex -107 82 22.1 + vertex -107 -82 20.5 + vertex -107 -82 22.1 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -107 82 22.1 + vertex -106.981 -82 22.1 + vertex -106.981 82 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -106.981 -82 22.1 + vertex -107 82 22.1 + vertex -107 -82 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.981 82 22.1 + vertex -106.981 82 22.1 + vertex 106.981 -82 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.981 -82 22.1 + vertex -103.091 -104.016 22.1 + vertex -103.01 -104.5 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -106.981 82 22.1 + vertex -103.091 104.016 22.1 + vertex -103.324 103.585 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -106.981 -82 22.1 + vertex 106.981 -82 22.1 + vertex -106.981 82 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -106.981 82 22.1 + vertex -103.324 103.585 22.1 + vertex -103.685 103.253 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.981 -82 22.1 + vertex -106.981 -82 22.1 + vertex -103.091 -104.016 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -106.981 101 22.1 + vertex -103.685 103.253 22.1 + vertex -104.134 103.056 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.091 -104.016 22.1 + vertex -106.981 -82 22.1 + vertex -103.324 -103.585 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -106.981 101 22.1 + vertex -104.134 103.056 22.1 + vertex -104.623 103.015 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.324 -103.585 22.1 + vertex -106.981 -82 22.1 + vertex -103.685 -103.253 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -106.981 101 22.1 + vertex -104.623 103.015 22.1 + vertex -105.099 103.135 22.1 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -106.981 -101 22.1 + vertex -103.685 -103.253 22.1 + vertex -106.981 -82 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -106.981 101 22.1 + vertex -105.099 103.135 22.1 + vertex -105.509 103.404 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.685 -103.253 22.1 + vertex -106.981 -101 22.1 + vertex -104.134 -103.056 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -106.981 101 22.1 + vertex -105.509 103.404 22.1 + vertex -105.81 103.791 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.134 -103.056 22.1 + vertex -106.981 -101 22.1 + vertex -104.623 -103.015 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -107 101 22.1 + vertex -105.81 103.791 22.1 + vertex -105.97 104.255 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.623 -103.015 22.1 + vertex -106.981 -101 22.1 + vertex -105.099 -103.135 22.1 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 104.866 103.056 22.1 + vertex 106.981 101 22.1 + vertex 105.315 103.253 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.981 -82 22.1 + vertex 105.909 -104.016 22.1 + vertex 105.99 -104.5 22.1 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 104.377 103.015 22.1 + vertex 106.981 101 22.1 + vertex 104.866 103.056 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.981 -82 22.1 + vertex 105.676 -103.585 22.1 + vertex 105.909 -104.016 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.901 103.135 22.1 + vertex 106.981 101 22.1 + vertex 104.377 103.015 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.981 -82 22.1 + vertex 105.315 -103.253 22.1 + vertex 105.676 -103.585 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.981 101 22.1 + vertex 103.901 103.135 22.1 + vertex 106.981 82 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.981 -82 22.1 + vertex 104.866 -103.056 22.1 + vertex 105.315 -103.253 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.491 103.404 22.1 + vertex 106.981 82 22.1 + vertex 103.901 103.135 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.981 -82 22.1 + vertex 104.377 -103.015 22.1 + vertex 104.866 -103.056 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.19 103.791 22.1 + vertex 106.981 82 22.1 + vertex 103.491 103.404 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.981 -82 22.1 + vertex 103.901 -103.135 22.1 + vertex 104.377 -103.015 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.03 104.255 22.1 + vertex -103.091 104.016 22.1 + vertex 106.981 82 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.981 -82 22.1 + vertex 103.491 -103.404 22.1 + vertex 103.901 -103.135 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.03 104.255 22.1 + vertex 106.981 82 22.1 + vertex 103.19 103.791 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -106.981 82 22.1 + vertex 106.981 82 22.1 + vertex -103.091 104.016 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.091 104.016 22.1 + vertex 103.03 104.255 22.1 + vertex -103.01 104.5 22.1 + endloop + endfacet + facet normal 0 -0 1 + outer loop + vertex 103.03 -104.255 22.1 + vertex 106.981 -82 22.1 + vertex -103.01 -104.5 22.1 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 105.99 104.5 22.1 + vertex 107 101 22.1 + vertex 107 107 22.1 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 105.676 103.585 22.1 + vertex 107 101 22.1 + vertex 105.909 104.016 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 107 101 22.1 + vertex 105.676 103.585 22.1 + vertex 106.981 101 22.1 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 105.315 103.253 22.1 + vertex 106.981 101 22.1 + vertex 105.676 103.585 22.1 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 105.909 104.016 22.1 + vertex 107 101 22.1 + vertex 105.99 104.5 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 107 107 22.1 + vertex 105.909 104.984 22.1 + vertex 105.99 104.5 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 107 107 22.1 + vertex 105.676 105.415 22.1 + vertex 105.909 104.984 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 107 107 22.1 + vertex 105.315 105.747 22.1 + vertex 105.676 105.415 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 107 107 22.1 + vertex 104.866 105.944 22.1 + vertex 105.315 105.747 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 107 107 22.1 + vertex 104.377 105.985 22.1 + vertex 104.866 105.944 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 107 107 22.1 + vertex 103.901 105.865 22.1 + vertex 104.377 105.985 22.1 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -103.01 104.5 22.1 + vertex 103.03 104.255 22.1 + vertex 103.03 104.745 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.981 -82 22.1 + vertex 103.19 -103.791 22.1 + vertex 103.491 -103.404 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.981 -82 22.1 + vertex 103.03 -104.255 22.1 + vertex 103.19 -103.791 22.1 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -103.091 104.984 22.1 + vertex 103.03 104.745 22.1 + vertex 103.19 105.209 22.1 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -103.324 105.415 22.1 + vertex 103.19 105.209 22.1 + vertex 103.491 105.596 22.1 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -103.685 105.747 22.1 + vertex 103.491 105.596 22.1 + vertex 103.901 105.865 22.1 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -104.134 105.944 22.1 + vertex 103.901 105.865 22.1 + vertex 107 107 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.03 104.745 22.1 + vertex -103.091 104.984 22.1 + vertex -103.01 104.5 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.19 105.209 22.1 + vertex -103.324 105.415 22.1 + vertex -103.091 104.984 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.491 105.596 22.1 + vertex -103.685 105.747 22.1 + vertex -103.324 105.415 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.901 105.865 22.1 + vertex -104.134 105.944 22.1 + vertex -103.685 105.747 22.1 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -107 107 22.1 + vertex -104.134 105.944 22.1 + vertex 107 107 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -107 107 22.1 + vertex -105.97 104.255 22.1 + vertex -105.97 104.745 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.099 -103.135 22.1 + vertex -106.981 -101 22.1 + vertex -105.509 -103.404 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.685 103.253 22.1 + vertex -106.981 101 22.1 + vertex -106.981 82 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.134 105.944 22.1 + vertex -107 107 22.1 + vertex -104.623 105.985 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -107 107 22.1 + vertex -105.099 105.865 22.1 + vertex -104.623 105.985 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -107 107 22.1 + vertex -105.509 105.596 22.1 + vertex -105.099 105.865 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -107 107 22.1 + vertex -105.81 105.209 22.1 + vertex -105.509 105.596 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -107 107 22.1 + vertex -105.97 104.745 22.1 + vertex -105.81 105.209 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.97 104.255 22.1 + vertex -107 107 22.1 + vertex -107 101 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.81 103.791 22.1 + vertex -107 101 22.1 + vertex -106.981 101 22.1 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 106.981 82 22.1 + vertex 107 -82 22.1 + vertex 107 82 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 107 -82 22.1 + vertex 106.981 82 22.1 + vertex 106.981 -82 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 105.99 -104.5 22.1 + vertex 107 -101 22.1 + vertex 106.981 -101 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.981 -82 22.1 + vertex 105.99 -104.5 22.1 + vertex 106.981 -101 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 107 -101 22.1 + vertex 105.99 -104.5 22.1 + vertex 107 -107 22.1 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 105.909 -104.984 22.1 + vertex 107 -107 22.1 + vertex 105.99 -104.5 22.1 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 105.676 -105.415 22.1 + vertex 107 -107 22.1 + vertex 105.909 -104.984 22.1 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 105.315 -105.747 22.1 + vertex 107 -107 22.1 + vertex 105.676 -105.415 22.1 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 104.866 -105.944 22.1 + vertex 107 -107 22.1 + vertex 105.315 -105.747 22.1 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 104.377 -105.985 22.1 + vertex 107 -107 22.1 + vertex 104.866 -105.944 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.901 -105.865 22.1 + vertex 107 -107 22.1 + vertex 104.377 -105.985 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.03 -104.255 22.1 + vertex -103.01 -104.5 22.1 + vertex 103.03 -104.745 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.091 -104.984 22.1 + vertex 103.03 -104.745 22.1 + vertex -103.01 -104.5 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.03 -104.745 22.1 + vertex -103.091 -104.984 22.1 + vertex 103.19 -105.209 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.324 -105.415 22.1 + vertex 103.19 -105.209 22.1 + vertex -103.091 -104.984 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.19 -105.209 22.1 + vertex -103.324 -105.415 22.1 + vertex 103.491 -105.596 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -103.685 -105.747 22.1 + vertex 103.491 -105.596 22.1 + vertex -103.324 -105.415 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.491 -105.596 22.1 + vertex -103.685 -105.747 22.1 + vertex 103.901 -105.865 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.134 -105.944 22.1 + vertex 103.901 -105.865 22.1 + vertex -103.685 -105.747 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 103.901 -105.865 22.1 + vertex -104.134 -105.944 22.1 + vertex 107 -107 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -107 -107 22.1 + vertex -104.134 -105.944 22.1 + vertex -104.623 -105.985 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.509 -103.404 22.1 + vertex -106.981 -101 22.1 + vertex -105.81 -103.791 22.1 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -107 -101 22.1 + vertex -105.81 -103.791 22.1 + vertex -106.981 -101 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.81 -103.791 22.1 + vertex -107 -101 22.1 + vertex -105.97 -104.255 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -107 -107 22.1 + vertex -105.97 -104.255 22.1 + vertex -107 -101 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -104.134 -105.944 22.1 + vertex -107 -107 22.1 + vertex 107 -107 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.099 -105.865 22.1 + vertex -107 -107 22.1 + vertex -104.623 -105.985 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.509 -105.596 22.1 + vertex -107 -107 22.1 + vertex -105.099 -105.865 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.81 -105.209 22.1 + vertex -107 -107 22.1 + vertex -105.509 -105.596 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.97 -104.745 22.1 + vertex -107 -107 22.1 + vertex -105.81 -105.209 22.1 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -105.97 -104.255 22.1 + vertex -107 -107 22.1 + vertex -105.97 -104.745 22.1 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 107 -101 22.1 + vertex 107 -104.067 20.5 + vertex 107 -101 20.5 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex 107 -107 22.1 + vertex 107 -104.067 20.5 + vertex 107 -101 22.1 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 107 -104.067 20.5 + vertex 107 -107 22.1 + vertex 107 -104.933 20.5 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 107 -104.933 20.5 + vertex 107 -107 22.1 + vertex 107 -107 20.5 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 107 107 22.1 + vertex 107 104.933 20.5 + vertex 107 107 20.5 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 107 107 22.1 + vertex 107 104.067 20.5 + vertex 107 104.933 20.5 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex 107 101 22.1 + vertex 107 104.067 20.5 + vertex 107 107 22.1 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 107 104.067 20.5 + vertex 107 101 22.1 + vertex 107 101 20.5 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex 107 -82 22.1 + vertex 107 82 20.5 + vertex 107 82 22.1 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 107 82 20.5 + vertex 107 -82 22.1 + vertex 107 -82 20.5 + endloop + endfacet + facet normal 0 1 -0 + outer loop + vertex 107 107 20.5 + vertex -107 107 22.1 + vertex 107 107 22.1 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -107 107 22.1 + vertex 107 107 20.5 + vertex -107 107 20.5 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -107 -107 20.5 + vertex 107 -107 22.1 + vertex -107 -107 22.1 + endloop + endfacet + facet normal 0 -1 -0 + outer loop + vertex 107 -107 22.1 + vertex -107 -107 20.5 + vertex 107 -107 20.5 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -107 -82 22.13 + vertex -106.981 82 22.13 + vertex -106.981 -82 22.13 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -106.981 82 22.13 + vertex -107 -82 22.13 + vertex -107 82 22.13 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -106.981 -82 22.13 + vertex 106.981 -82 22.13 + vertex 106.981 -101 22.13 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 106.981 -82 22.13 + vertex -106.981 -82 22.13 + vertex 106.981 82 22.13 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -106.981 -82 22.13 + vertex 106.981 -101 22.13 + vertex -106.981 -101 22.13 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -106.981 82 22.13 + vertex 106.981 82 22.13 + vertex -106.981 -82 22.13 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 106.981 82 22.13 + vertex -106.981 82 22.13 + vertex 106.981 101 22.13 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 106.981 101 22.13 + vertex -106.981 82 22.13 + vertex -106.981 101 22.13 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 106.981 -82 22.13 + vertex 107 82 22.13 + vertex 107 -82 22.13 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 107 82 22.13 + vertex 106.981 -82 22.13 + vertex 106.981 82 22.13 + endloop + endfacet + facet normal 1 -0 0 + outer loop + vertex 107 -82 24.13 + vertex 107 82 22.13 + vertex 107 82 24.13 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 107 82 22.13 + vertex 107 -82 24.13 + vertex 107 -82 22.13 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -107 -82 22.13 + vertex -107 82 24.13 + vertex -107 82 22.13 + endloop + endfacet + facet normal -1 -0 0 + outer loop + vertex -107 82 24.13 + vertex -107 -82 22.13 + vertex -107 -82 24.13 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -107 82 24.13 + vertex -106.981 -82 24.13 + vertex -106.981 82 24.13 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -106.981 -82 24.13 + vertex -107 82 24.13 + vertex -107 -82 24.13 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -106.981 82 24.13 + vertex 106.981 82 24.13 + vertex 106.981 101 24.13 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.981 82 24.13 + vertex -106.981 82 24.13 + vertex 106.981 -82 24.13 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -106.981 82 24.13 + vertex 106.981 101 24.13 + vertex -106.981 101 24.13 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -106.981 -82 24.13 + vertex 106.981 -82 24.13 + vertex -106.981 82 24.13 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.981 -82 24.13 + vertex -106.981 -82 24.13 + vertex 106.981 -101 24.13 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 106.981 -101 24.13 + vertex -106.981 -82 24.13 + vertex -106.981 -101 24.13 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex 106.981 82 24.13 + vertex 107 -82 24.13 + vertex 107 82 24.13 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 107 -82 24.13 + vertex 106.981 82 24.13 + vertex 106.981 -82 24.13 + endloop + endfacet +endsolid OpenSCAD_Model From a5424fa2070e3ac39da99fb7b04c86369d6c787c Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 16 Jun 2016 15:08:05 +0200 Subject: [PATCH 701/705] Revert "Fix filtering of variants and materials by definition instead of by machine" This reverts commit 623b8f276e8c74023aad1592fc16bf98d50da1d5. --- cura/ExtruderManager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 5d0ad612cf..c83f8d9af7 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -140,7 +140,7 @@ class ExtruderManager(QObject): variant = container_registry.getEmptyInstanceContainer() if machine_definition.getMetaDataEntry("has_variants"): #First add any variant. Later, overwrite with preference if the preference is valid. - variants = container_registry.findInstanceContainers(definition = machine_id, type = "variant") + variants = container_registry.findInstanceContainers(machine = machine_id, type = "variant") if len(variants) >= 1: variant = variants[0] preferred_variant_id = machine_definition.getMetaDataEntry("preferred_variant") @@ -158,9 +158,9 @@ class ExtruderManager(QObject): if machine_definition.getMetaDataEntry("has_materials"): #First add any material. Later, overwrite with preference if the preference is valid. if machine_definition.getMetaDataEntry("has_variant_materials", default = "False") == "True": - materials = container_registry.findInstanceContainers(type = "material", definition = machine_id, variant = variant.getId()) + materials = container_registry.findInstanceContainers(type = "material", machine = machine_id, variant = variant.getId()) else: - materials = container_registry.findInstanceContainers(type = "material", definition = machine_id) + materials = container_registry.findInstanceContainers(type = "material", machine = machine_id) if len(materials) >= 1: material = materials[0] preferred_material_id = machine_definition.getMetaDataEntry("preferred_material") From 666b1a0263e5e8ef03a97f4b6767a27133b92162 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 16 Jun 2016 15:08:20 +0200 Subject: [PATCH 702/705] Revert "Fix check for has_variants & has_materials" This reverts commit 7f093be75a1a31f07eba79ec89ab08ebc2d9622d. --- cura/ExtruderManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index c83f8d9af7..f9079c6328 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -138,7 +138,7 @@ class ExtruderManager(QObject): #Find the variant to use for this extruder. variant = container_registry.getEmptyInstanceContainer() - if machine_definition.getMetaDataEntry("has_variants"): + if machine_definition.getMetaDataEntry("has_variants", default = "False") == "True": #First add any variant. Later, overwrite with preference if the preference is valid. variants = container_registry.findInstanceContainers(machine = machine_id, type = "variant") if len(variants) >= 1: @@ -155,7 +155,7 @@ class ExtruderManager(QObject): #Find a material to use for this variant. material = container_registry.getEmptyInstanceContainer() - if machine_definition.getMetaDataEntry("has_materials"): + if machine_definition.getMetaDataEntry("has_materials", default = "False") == "True": #First add any material. Later, overwrite with preference if the preference is valid. if machine_definition.getMetaDataEntry("has_variant_materials", default = "False") == "True": materials = container_registry.findInstanceContainers(type = "material", machine = machine_id, variant = variant.getId()) From 0893e4b2cc3057ceab57408cdcbe8f8bb7995180 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 16 Jun 2016 15:08:45 +0200 Subject: [PATCH 703/705] Revert "Fix variant vs nozzle" This reverts commit cb05f75f6ab754f1f095e1cabd19f7259ed917bf. --- cura/ExtruderManager.py | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index f9079c6328..b6739740f5 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -111,7 +111,7 @@ class ExtruderManager(QObject): ## Creates a container stack for an extruder train. # # The container stack has an extruder definition at the bottom, which is - # linked to a machine definition. Then it has a variant profile, a material + # linked to a machine definition. Then it has a nozzle profile, a material # profile, a quality profile and a user profile, in that order. # # The resulting container stack is added to the registry. @@ -136,29 +136,29 @@ class ExtruderManager(QObject): container_stack.addMetaDataEntry("position", position) container_stack.addContainer(extruder_definition) - #Find the variant to use for this extruder. - variant = container_registry.getEmptyInstanceContainer() - if machine_definition.getMetaDataEntry("has_variants", default = "False") == "True": - #First add any variant. Later, overwrite with preference if the preference is valid. - variants = container_registry.findInstanceContainers(machine = machine_id, type = "variant") - if len(variants) >= 1: - variant = variants[0] - preferred_variant_id = machine_definition.getMetaDataEntry("preferred_variant") - if preferred_variant_id: - preferred_variants = container_registry.findInstanceContainers(id = preferred_variant_id, type = "variant") - if len(preferred_variants) >= 1: - variant = preferred_variants[0] + #Find the nozzle to use for this extruder. + nozzle = container_registry.getEmptyInstanceContainer() + if machine_definition.getMetaDataEntry("has_nozzles", default = "False") == "True": + #First add any nozzle. Later, overwrite with preference if the preference is valid. + nozzles = container_registry.findInstanceContainers(machine = machine_id, type = "nozzle") + if len(nozzles) >= 1: + nozzle = nozzles[0] + preferred_nozzle_id = machine_definition.getMetaDataEntry("preferred_nozzle") + if preferred_nozzle_id: + preferred_nozzles = container_registry.findInstanceContainers(id = preferred_nozzle_id, type = "nozzle") + if len(preferred_nozzles) >= 1: + nozzle = preferred_nozzles[0] else: - UM.Logger.log("w", "The preferred variant \"%s\" of machine %s doesn't exist or is not a variant profile.", preferred_variant_id, machine_id) - #And leave it at the default variant. - container_stack.addContainer(variant) + UM.Logger.log("w", "The preferred nozzle \"%s\" of machine %s doesn't exist or is not a nozzle profile.", preferred_nozzle_id, machine_id) + #And leave it at the default nozzle. + container_stack.addContainer(nozzle) - #Find a material to use for this variant. + #Find a material to use for this nozzle. material = container_registry.getEmptyInstanceContainer() if machine_definition.getMetaDataEntry("has_materials", default = "False") == "True": #First add any material. Later, overwrite with preference if the preference is valid. - if machine_definition.getMetaDataEntry("has_variant_materials", default = "False") == "True": - materials = container_registry.findInstanceContainers(type = "material", machine = machine_id, variant = variant.getId()) + if machine_definition.getMetaDataEntry("has_nozzle_materials", default = "False") == "True": + materials = container_registry.findInstanceContainers(type = "material", machine = machine_id, nozzle = nozzle.getId()) else: materials = container_registry.findInstanceContainers(type = "material", machine = machine_id) if len(materials) >= 1: @@ -175,7 +175,7 @@ class ExtruderManager(QObject): #Find a quality to use for this extruder. quality = container_registry.getEmptyInstanceContainer() - + #First add any quality. Later, overwrite with preference if the preference is valid. qualities = container_registry.findInstanceContainers(type = "quality") if len(qualities) >= 1: From 2e9ee9f668cc2ef66f132ef369498e58a0213738 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Fri, 17 Jun 2016 11:36:50 +0200 Subject: [PATCH 704/705] JSON lil fix: default didn't coicide with default inherited state --- 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 c5acbd49bb..433517504d 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1726,7 +1726,7 @@ "description": "The distance between the nozzle and already printed parts when avoiding during travel moves.", "unit": "mm", "type": "float", - "default_value": 1.5, + "default_value": 0.625, "value": "machine_nozzle_tip_outer_diameter / 2 * 1.25", "minimum_value": "0", "maximum_value_warning": "machine_nozzle_tip_outer_diameter * 5", From f139e91f8805818c93127cc557aae3b8f0f3b984 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 15 Jun 2016 14:20:07 +0200 Subject: [PATCH 705/705] Remove minimum and maximum of _extruder_nr settings This way the validation won't get an error any more. There is no validation. It's an enum anyway. Contributes to issue CURA-1716. --- resources/definitions/fdmprinter.def.json | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 433517504d..ac40eed0ae 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -2724,9 +2724,7 @@ "label": "Platform Adhesion Extruder", "description": "The extruder train to use for printing the skirt/brim/raft. This is used in multi-extrusion.", "type": "extruder", - "default_value": 0, - "minimum_value": "0", - "maximum_value": "machine_extruder_count - 1", + "default_value": "0", "settable_per_mesh": false, "settable_per_extruder": false }, @@ -2735,9 +2733,7 @@ "label": "Support Extruder", "description": "The extruder train to use for printing the support. This is used in multi-extrusion.", "type": "extruder", - "default_value": 0, - "minimum_value": "0", - "maximum_value": "machine_extruder_count - 1", + "default_value": "0", "enabled": "support_enable", "settable_per_mesh": false, "settable_per_extruder": false, @@ -2747,10 +2743,8 @@ "label": "Support Infill Extruder", "description": "The extruder train to use for printing the infill of the support. This is used in multi-extrusion.", "type": "extruder", - "default_value": 0, + "default_value": "0", "value": "support_extruder_nr", - "minimum_value": "0", - "maximum_value": "machine_extruder_count - 1", "enabled": "support_enable", "settable_per_mesh": false, "settable_per_extruder": false @@ -2760,10 +2754,8 @@ "label": "First Layer Support Extruder", "description": "The extruder train to use for printing the first layer of support infill. This is used in multi-extrusion.", "type": "extruder", - "default_value": 0, + "default_value": "0", "value": "support_extruder_nr", - "minimum_value": "0", - "maximum_value": "machine_extruder_count - 1", "enabled": "support_enable", "settable_per_mesh": false, "settable_per_extruder": false @@ -2773,10 +2765,8 @@ "label": "Support Roof Extruder", "description": "The extruder train to use for printing the roof of the support. This is used in multi-extrusion.", "type": "extruder", - "default_value": 0, + "default_value": "0", "value": "support_extruder_nr", - "minimum_value": "0", - "maximum_value": "machine_extruder_count - 1", "enabled": "support_enable", "settable_per_mesh": false, "settable_per_extruder": false