diff --git a/resources/profiles/Elegoo.idx b/resources/profiles/Elegoo.idx index cf0da371b1..6fcdedd3f8 100644 --- a/resources/profiles/Elegoo.idx +++ b/resources/profiles/Elegoo.idx @@ -1,2 +1,3 @@ -min_slic3r_version = 2.5.0-alpha3 -1.0.0 Initial version +min_slic3r_version = 2.5.0-alpha3 +1.0.1 Decreased bed size to 220x220. +1.0.0 Initial version diff --git a/resources/profiles/Elegoo.ini b/resources/profiles/Elegoo.ini index a39d33f3f5..d9053e5a24 100644 --- a/resources/profiles/Elegoo.ini +++ b/resources/profiles/Elegoo.ini @@ -1,510 +1,510 @@ -# PrusaSlicer print profiles for the Elegoo printers. -# By Andrew Suzuki (andrewsuzuki.com), adapted from Creality.ini - -[vendor] -# Vendor name will be shown by the Config Wizard. -name = Elegoo -# Configuration version of this file. Config file will only be installed, if the config_version differs. -# This means, the server may force the PrusaSlicer configuration to be downgraded. -config_version = 1.0.0 -config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Elegoo/ - -# The printer models will be shown by the Configuration Wizard in this order, -# also the first model installed & the first nozzle installed will be activated after install. -# Printer model name will be shown by the installation wizard. - -[printer_model:NEPTUNE1] -name = Elegoo Neptune-1 -variants = 0.4 -technology = FFF -family = NEPTUNE -bed_model = -bed_texture = -default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO - -[printer_model:NEPTUNE2] -name = Elegoo Neptune-2 -variants = 0.4 -technology = FFF -family = NEPTUNE -bed_model = -bed_texture = -default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO - -[printer_model:NEPTUNE2D] -name = Elegoo Neptune-2D -variants = 0.4 -technology = FFF -family = NEPTUNE -bed_model = -bed_texture = -default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO - -[printer_model:NEPTUNE2S] -name = Elegoo Neptune-2S -variants = 0.4 -technology = FFF -family = NEPTUNE -bed_model = -bed_texture = -default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO - -[printer_model:NEPTUNE3] -name = Elegoo Neptune-3 -variants = 0.4 -technology = FFF -family = NEPTUNE -bed_model = -bed_texture = -default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO - -[printer_model:NEPTUNEX] -name = Elegoo Neptune-X -variants = 0.4 -technology = FFF -family = NEPTUNE -bed_model = -bed_texture = -default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO - -# All presets starting with asterisk, for example *common*, are intermediate and they will -# not make it into the user interface. - -# Common print preset -[print:*common*] -avoid_crossing_perimeters = 0 -bridge_angle = 0 -bridge_flow_ratio = 0.95 -bridge_speed = 25 -brim_width = 0 -clip_multipart_objects = 1 -compatible_printers = -complete_objects = 0 -dont_support_bridges = 1 -elefant_foot_compensation = 0.1 -ensure_vertical_shell_thickness = 1 -external_fill_pattern = rectilinear -external_perimeters_first = 0 -external_perimeter_extrusion_width = 0.45 -external_perimeter_speed = 25 -extra_perimeters = 0 -extruder_clearance_height = 25 -extruder_clearance_radius = 45 -extrusion_width = 0.45 -fill_angle = 45 -fill_density = 20% -fill_pattern = grid -first_layer_extrusion_width = 0.42 -first_layer_height = 0.2 -first_layer_speed = 20 -gap_fill_speed = 30 -gcode_comments = 0 -infill_every_layers = 1 -infill_extruder = 1 -infill_extrusion_width = 0.45 -infill_first = 0 -infill_only_where_needed = 0 -infill_overlap = 25% -infill_speed = 50 -interface_shells = 0 -max_print_speed = 100 -max_volumetric_extrusion_rate_slope_negative = 0 -max_volumetric_extrusion_rate_slope_positive = 0 -max_volumetric_speed = 0 -min_skirt_length = 4 -notes = -overhangs = 0 -only_retract_when_crossing_perimeters = 0 -ooze_prevention = 0 -output_filename_format = {input_filename_base}_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode -perimeters = 2 -perimeter_extruder = 1 -perimeter_extrusion_width = 0.45 -perimeter_speed = 40 -post_process = -print_settings_id = -raft_layers = 0 -resolution = 0 -seam_position = nearest -single_extruder_multi_material_priming = 0 -skirts = 1 -skirt_distance = 2 -skirt_height = 2 -small_perimeter_speed = 25 -solid_infill_below_area = 0 -solid_infill_every_layers = 0 -solid_infill_extruder = 1 -solid_infill_extrusion_width = 0.45 -solid_infill_speed = 40 -spiral_vase = 0 -standby_temperature_delta = -5 -support_material = 0 -support_material_extruder = 0 -support_material_extrusion_width = 0.38 -support_material_interface_extruder = 0 -support_material_angle = 0 -support_material_buildplate_only = 0 -support_material_enforce_layers = 0 -support_material_contact_distance = 0.15 -support_material_interface_contact_loops = 0 -support_material_interface_layers = 2 -support_material_interface_spacing = 0.2 -support_material_interface_speed = 100% -support_material_pattern = rectilinear -support_material_spacing = 2 -support_material_speed = 40 -support_material_synchronize_layers = 0 -support_material_threshold = 45 -support_material_with_sheath = 0 -support_material_xy_spacing = 60% -thin_walls = 0 -top_infill_extrusion_width = 0.4 -top_solid_infill_speed = 30 -travel_speed = 150 -wipe_tower = 0 -wipe_tower_bridging = 10 -wipe_tower_rotation_angle = 0 -wipe_tower_width = 60 -wipe_tower_x = 170 -wipe_tower_y = 140 -xy_size_compensation = 0 - -[print:*0.08mm*] -inherits = *common* -layer_height = 0.08 -perimeters = 3 -bottom_solid_layers = 9 -top_solid_layers = 11 - -[print:*0.10mm*] -inherits = *common* -layer_height = 0.1 -perimeters = 3 -bottom_solid_layers = 7 -top_solid_layers = 9 - -[print:*0.12mm*] -inherits = *common* -layer_height = 0.12 -perimeters = 3 -bottom_solid_layers = 6 -top_solid_layers = 7 - -[print:*0.16mm*] -inherits = *common* -layer_height = 0.16 -bottom_solid_layers = 5 -top_solid_layers = 7 - -[print:*0.20mm*] -inherits = *common* -layer_height = 0.20 -bottom_solid_layers = 4 -top_solid_layers = 5 - -[print:*0.24mm*] -inherits = *common* -layer_height = 0.24 -top_infill_extrusion_width = 0.45 -bottom_solid_layers = 3 -top_solid_layers = 4 - -[print:*0.28mm*] -inherits = *common* -layer_height = 0.28 -top_infill_extrusion_width = 0.45 -bottom_solid_layers = 3 -top_solid_layers = 4 - -[print:0.08mm SUPERDETAIL @ELEGOO] -inherits = *0.08mm* -compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 - -[print:0.10mm HIGHDETAIL @ELEGOO] -inherits = *0.10mm* -compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 - -[print:0.12mm DETAIL @ELEGOO] -inherits = *0.12mm* -compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 - -[print:0.16mm OPTIMAL @ELEGOO] -inherits = *0.16mm* -compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 - -[print:0.20mm NORMAL @ELEGOO] -inherits = *0.20mm* -compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 - -[print:0.24mm DRAFT @ELEGOO] -inherits = *0.24mm* -compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 - -[print:0.28mm SUPERDRAFT @ELEGOO] -inherits = *0.28mm* -compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 - -# When submitting new filaments please print the following temperature tower at 0.1mm layer height: -# https://www.thingiverse.com/thing:2615842 -# Pay particular attention to bridging, overhangs and retractions. -# Also print the following bed adhesion test at 0.1 layer height as well: -# https://www.prusaprinters.org/prints/4634-bed-adhesion-warp-test -# At least for PLA, please keep bed temp at 60, as many Elegoo printers do not have any ABL -# So having some leeway to get good bed adhesion is not a luxury for many users - -[filament:*common*] -cooling = 0 -compatible_printers = -extrusion_multiplier = 1 -filament_cost = 0 -filament_density = 0 -filament_diameter = 1.75 -filament_notes = "" -filament_settings_id = "" -filament_soluble = 0 -min_print_speed = 15 -slowdown_below_layer_time = 20 -compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_ELEGOO.*/ - -[filament:*PLA*] -inherits = *common* -bed_temperature = 60 -fan_below_layer_time = 100 -filament_colour = #DDDDDD -filament_max_volumetric_speed = 15 -filament_type = PLA -filament_density = 1.24 -filament_cost = 20 -first_layer_bed_temperature = 60 -first_layer_temperature = 210 -fan_always_on = 1 -cooling = 1 -max_fan_speed = 100 -min_fan_speed = 100 -bridge_fan_speed = 100 -disable_fan_first_layers = 1 -temperature = 205 - -[filament:*PET*] -inherits = *common* -bed_temperature = 70 -cooling = 1 -disable_fan_first_layers = 3 -fan_below_layer_time = 20 -filament_colour = #DDDDDD -filament_max_volumetric_speed = 8 -filament_type = PETG -filament_density = 1.27 -filament_cost = 20 -first_layer_bed_temperature = 70 -first_layer_temperature = 240 -fan_always_on = 1 -max_fan_speed = 50 -min_fan_speed = 20 -bridge_fan_speed = 100 -temperature = 240 - -[filament:*ABS*] -inherits = *common* -bed_temperature = 100 -cooling = 0 -disable_fan_first_layers = 3 -fan_below_layer_time = 20 -filament_colour = #DDDDDD -filament_max_volumetric_speed = 11 -filament_type = ABS -filament_density = 1.04 -filament_cost = 20 -first_layer_bed_temperature = 100 -first_layer_temperature = 245 -fan_always_on = 0 -max_fan_speed = 0 -min_fan_speed = 0 -bridge_fan_speed = 30 -top_fan_speed = 0 -temperature = 245 - -[filament:Generic PLA @ELEGOO] -inherits = *PLA* -filament_vendor = Generic - -[filament:Generic PETG @ELEGOO] -inherits = *PET* -filament_vendor = Generic - -[filament:Generic ABS @ELEGOO] -inherits = *ABS* -first_layer_bed_temperature = 90 -bed_temperature = 90 -filament_vendor = Generic - -# Common printer preset -[printer:*common*] -printer_technology = FFF -before_layer_gcode = ;BEFORE_LAYER_CHANGE\nG92 E0\n;[layer_z]\n\n -bed_shape = 0x0,235x0,235x235,0x235 -between_objects_gcode = -pause_print_gcode = -deretract_speed = 0 -extruder_colour = #FCE94F -extruder_offset = 0x0 -gcode_flavor = marlin -silent_mode = 0 -remaining_times = 0 -machine_max_acceleration_e = 5000 -machine_max_acceleration_extruding = 500 -machine_max_acceleration_retracting = 1000 -machine_max_acceleration_x = 500 -machine_max_acceleration_y = 500 -machine_max_acceleration_z = 100 -machine_max_feedrate_e = 60 -machine_max_feedrate_x = 500 -machine_max_feedrate_y = 500 -machine_max_feedrate_z = 10 -machine_max_jerk_e = 5 -machine_max_jerk_x = 8 -machine_max_jerk_y = 8 -machine_max_jerk_z = 0.4 -machine_min_extruding_rate = 0 -machine_min_travel_rate = 0 -layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] -max_layer_height = 0.3 -min_layer_height = 0.07 -max_print_height = 250 -nozzle_diameter = 0.4 -printer_notes = -printer_settings_id = -retract_before_travel = 1 -retract_before_wipe = 0% -retract_layer_change = 1 -retract_length = 1 -retract_length_toolchange = 1 -retract_lift = 0 -retract_lift_above = 0 -retract_lift_below = 0 -retract_restart_extra = 0 -retract_restart_extra_toolchange = 0 -retract_speed = 35 -single_extruder_multi_material = 0 -thumbnails = 16x16,220x124 -toolchange_gcode = -use_firmware_retraction = 0 -use_relative_e_distances = 1 -use_volumetric_e = 0 -variable_layer_height = 1 -wipe = 1 -z_offset = 0 -printer_model = -default_print_profile = 0.16mm OPTIMAL @ELEGOO -default_filament_profile = Generic PLA @ELEGOO - -[printer:Elegoo Neptune-2] -inherits = *common* -printer_model = NEPTUNE2 -printer_variant = 0.4 -max_layer_height = 0.28 -min_layer_height = 0.08 -printer_notes = Do not remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_ELEGOO\nPRINTER_MODEL_NEPTUNE2\nPRINTER_HAS_BOWDEN -max_print_height = 250 -machine_max_acceleration_e = 5000 -machine_max_acceleration_extruding = 500 -machine_max_acceleration_retracting = 1000 -machine_max_acceleration_x = 500 -machine_max_acceleration_y = 500 -machine_max_acceleration_z = 100 -machine_max_feedrate_e = 60 -machine_max_feedrate_x = 500 -machine_max_feedrate_y = 500 -machine_max_feedrate_z = 10 -machine_max_jerk_e = 5 -machine_max_jerk_x = 8 -machine_max_jerk_y = 8 -machine_max_jerk_z = 0.4 -machine_min_extruding_rate = 0 -machine_min_travel_rate = 0 -nozzle_diameter = 0.4 -retract_before_travel = 2 -retract_length = 5 -retract_speed = 60 -deretract_speed = 40 -retract_before_wipe = 70% -start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nM140 S[first_layer_bed_temperature] ; set final bed temp\nG4 S10 ; allow partial nozzle warmup\nG28 ; home all axis\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set final nozzle temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp to stabilize\nM109 S[first_layer_temperature] ; wait for nozzle temp to stabilize\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 -end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2, max_print_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\n{if max_layer_z < max_print_height-10}G1 Z{z_offset+min(max_layer_z+70, max_print_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{max_print_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors - - -# Intended for printers with a smaller bed -# [printer:*fastabl*] -# start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nM140 S[first_layer_bed_temperature] ; set final bed temp\nG4 S10 ; allow partial nozzle warmup\nG28 ; home all axis\nG29 ; auto bed levelling\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set final nozzle temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp to stabilize\nM109 S[first_layer_temperature] ; wait for nozzle temp to stabilize\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 - -# Intended for printers with a larger bed -# [printer:*slowabl*] -# start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nM140 S[first_layer_bed_temperature] ; set final bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp to stabilize\nG28 ; home all axis\nG29 ; auto bed levelling\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set final nozzle temp\nM109 S[first_layer_temperature] ; wait for nozzle temp to stabilize\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 - -# Intended for printers with vendor official firmware verified to support M25 -# [printer:*pauseprint*] -# pause_print_gcode = M25 ; pause print - -# Intended for printers where the Z-axis lowers the print bed during printing -# [printer:*invertedz*] -# end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2, max_print_height)} F600{endif} ; Move print bed down\nG1 X50 Y50 F{travel_speed*60} ; present print\n{if max_layer_z < max_print_height-10}G1 Z{z_offset+max_print_height-10} F600{endif} ; Move print bed down further down\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors - -# Intended for printers with dual extruders and a single hotend/nozzle -[printer:*dualextruder*] -single_extruder_multi_material = 1 -cooling_tube_length = 23 -cooling_tube_retraction = 35 -extra_loading_move = -2 -parking_pos_retraction = 80 -deretract_speed = 40,40 -extruder_colour = #0080C0;#FFFF9F -extruder_offset = 0x0,0x0 -max_layer_height = 0.28,0.28 -min_layer_height = 0.08,0.08 -nozzle_diameter = 0.4,0.4 -retract_before_travel = 2,2 -retract_before_wipe = 70%,70% -retract_layer_change = 1,1 -retract_length = 5,5 -retract_length_toolchange = 1,1 -retract_lift = 0,0 -retract_lift_above = 0,0 -retract_lift_below = 0,0 -retract_restart_extra = 0,0 -retract_restart_extra_toolchange = 0,0 -retract_speed = 60,60 -wipe = 1,1 -start_gcode = T[initial_tool] ; set active extruder\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM140 S{first_layer_bed_temperature[0]} ; set final bed temp\nM104 S150 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nG4 S10 ; allow partial nozzle warmup\nG28 ; home all axis\n;G29 ; auto bed levelling - remove ; at beginning of line to enable\n;M420 S1 ; enable mesh - remove ; at beginning of line to enable\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S{first_layer_temperature[0]} ; set final nozzle temp\nM190 S{first_layer_bed_temperature[0]} ; wait for bed temp to stabilize\nM109 S{first_layer_temperature[0]} ; wait for nozzle temp to stabilize\nG1 Z0.28 F240 ; move down to prime nozzle\nG92 E0 ; reset extruder\nG1 E90 ; load filament\nG92 E0 ; reset extruder\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000 ; move over for second prime line\nG92 E0 ; reset extruder\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 ; reset extruder -end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2, max_print_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\nG1 E-80 F2000 ; unload filament\n{if max_layer_z < max_print_height-10}G1 Z{z_offset+min(max_layer_z+70, max_print_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{max_print_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors - -# Copy of Creality CR-X config for the Neptune 2D (dual extruder, single hotend) - -[printer:Elegoo Neptune-2D] -inherits = Elegoo Neptune-2; *dualextruder* -retract_length = 6,6 -printer_model = NEPTUNE2D -printer_notes = Do not remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_ELEGOO\nPRINTER_MODEL_NEPTUNE2D\nPRINTER_HAS_BOWDEN - -[printer:Elegoo Neptune-2S] -inherits = Elegoo Neptune-2 -printer_model = NEPTUNE2S -printer_notes = Do not remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_ELEGOO\nPRINTER_MODEL_NEPTUNE2D\nPRINTER_HAS_BOWDEN - -[printer:Elegoo Neptune-X] -inherits = Elegoo Neptune-2 -max_print_height = 300 -printer_model = NEPTUNEX -printer_notes = Do not remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_ELEGOO\nPRINTER_MODEL_NEPTUNE2D\nPRINTER_HAS_BOWDEN - -[printer:Elegoo Neptune-3] -inherits = Elegoo Neptune-2 -max_print_height = 280 -start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nM140 S[first_layer_bed_temperature] ; set final bed temp\nG4 S10 ; allow partial nozzle warmup\nG28 ; home all axis\nG29 ; run abl mesh\nM420 S1 ; load mesh\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set final nozzle temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp to stabilize\nM109 S[first_layer_temperature] ; wait for nozzle temp to stabilize\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 -printer_model = NEPTUNE3 -printer_notes = Do not remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_ELEGOO\nPRINTER_MODEL_NEPTUNE2D\nPRINTER_HAS_BOWDEN - -[printer:Elegoo Neptune-1] -inherits = Elegoo Neptune-2 -bed_shape = 0x0,210x0,210x210,0x210 -max_print_height = 200 -printer_model = NEPTUNE1 -printer_notes = Do not remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_ELEGOO\nPRINTER_MODEL_NEPTUNE2D\nPRINTER_HAS_BOWDEN +# PrusaSlicer print profiles for the Elegoo printers. +# By Andrew Suzuki (andrewsuzuki.com), adapted from Creality.ini + +[vendor] +# Vendor name will be shown by the Config Wizard. +name = Elegoo +# Configuration version of this file. Config file will only be installed, if the config_version differs. +# This means, the server may force the PrusaSlicer configuration to be downgraded. +config_version = 1.0.1 +config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Elegoo/ + +# The printer models will be shown by the Configuration Wizard in this order, +# also the first model installed & the first nozzle installed will be activated after install. +# Printer model name will be shown by the installation wizard. + +[printer_model:NEPTUNE1] +name = Elegoo Neptune-1 +variants = 0.4 +technology = FFF +family = NEPTUNE +bed_model = +bed_texture = +default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO + +[printer_model:NEPTUNE2] +name = Elegoo Neptune-2 +variants = 0.4 +technology = FFF +family = NEPTUNE +bed_model = +bed_texture = +default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO + +[printer_model:NEPTUNE2D] +name = Elegoo Neptune-2D +variants = 0.4 +technology = FFF +family = NEPTUNE +bed_model = +bed_texture = +default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO + +[printer_model:NEPTUNE2S] +name = Elegoo Neptune-2S +variants = 0.4 +technology = FFF +family = NEPTUNE +bed_model = +bed_texture = +default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO + +[printer_model:NEPTUNE3] +name = Elegoo Neptune-3 +variants = 0.4 +technology = FFF +family = NEPTUNE +bed_model = +bed_texture = +default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO + +[printer_model:NEPTUNEX] +name = Elegoo Neptune-X +variants = 0.4 +technology = FFF +family = NEPTUNE +bed_model = +bed_texture = +default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO + +# All presets starting with asterisk, for example *common*, are intermediate and they will +# not make it into the user interface. + +# Common print preset +[print:*common*] +avoid_crossing_perimeters = 0 +bridge_angle = 0 +bridge_flow_ratio = 0.95 +bridge_speed = 25 +brim_width = 0 +clip_multipart_objects = 1 +compatible_printers = +complete_objects = 0 +dont_support_bridges = 1 +elefant_foot_compensation = 0.1 +ensure_vertical_shell_thickness = 1 +external_fill_pattern = rectilinear +external_perimeters_first = 0 +external_perimeter_extrusion_width = 0.45 +external_perimeter_speed = 25 +extra_perimeters = 0 +extruder_clearance_height = 25 +extruder_clearance_radius = 45 +extrusion_width = 0.45 +fill_angle = 45 +fill_density = 20% +fill_pattern = grid +first_layer_extrusion_width = 0.42 +first_layer_height = 0.2 +first_layer_speed = 20 +gap_fill_speed = 30 +gcode_comments = 0 +infill_every_layers = 1 +infill_extruder = 1 +infill_extrusion_width = 0.45 +infill_first = 0 +infill_only_where_needed = 0 +infill_overlap = 25% +infill_speed = 50 +interface_shells = 0 +max_print_speed = 100 +max_volumetric_extrusion_rate_slope_negative = 0 +max_volumetric_extrusion_rate_slope_positive = 0 +max_volumetric_speed = 0 +min_skirt_length = 4 +notes = +overhangs = 0 +only_retract_when_crossing_perimeters = 0 +ooze_prevention = 0 +output_filename_format = {input_filename_base}_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode +perimeters = 2 +perimeter_extruder = 1 +perimeter_extrusion_width = 0.45 +perimeter_speed = 40 +post_process = +print_settings_id = +raft_layers = 0 +resolution = 0 +seam_position = nearest +single_extruder_multi_material_priming = 0 +skirts = 1 +skirt_distance = 2 +skirt_height = 2 +small_perimeter_speed = 25 +solid_infill_below_area = 0 +solid_infill_every_layers = 0 +solid_infill_extruder = 1 +solid_infill_extrusion_width = 0.45 +solid_infill_speed = 40 +spiral_vase = 0 +standby_temperature_delta = -5 +support_material = 0 +support_material_extruder = 0 +support_material_extrusion_width = 0.38 +support_material_interface_extruder = 0 +support_material_angle = 0 +support_material_buildplate_only = 0 +support_material_enforce_layers = 0 +support_material_contact_distance = 0.15 +support_material_interface_contact_loops = 0 +support_material_interface_layers = 2 +support_material_interface_spacing = 0.2 +support_material_interface_speed = 100% +support_material_pattern = rectilinear +support_material_spacing = 2 +support_material_speed = 40 +support_material_synchronize_layers = 0 +support_material_threshold = 45 +support_material_with_sheath = 0 +support_material_xy_spacing = 60% +thin_walls = 0 +top_infill_extrusion_width = 0.4 +top_solid_infill_speed = 30 +travel_speed = 150 +wipe_tower = 0 +wipe_tower_bridging = 10 +wipe_tower_rotation_angle = 0 +wipe_tower_width = 60 +wipe_tower_x = 170 +wipe_tower_y = 140 +xy_size_compensation = 0 + +[print:*0.08mm*] +inherits = *common* +layer_height = 0.08 +perimeters = 3 +bottom_solid_layers = 9 +top_solid_layers = 11 + +[print:*0.10mm*] +inherits = *common* +layer_height = 0.1 +perimeters = 3 +bottom_solid_layers = 7 +top_solid_layers = 9 + +[print:*0.12mm*] +inherits = *common* +layer_height = 0.12 +perimeters = 3 +bottom_solid_layers = 6 +top_solid_layers = 7 + +[print:*0.16mm*] +inherits = *common* +layer_height = 0.16 +bottom_solid_layers = 5 +top_solid_layers = 7 + +[print:*0.20mm*] +inherits = *common* +layer_height = 0.20 +bottom_solid_layers = 4 +top_solid_layers = 5 + +[print:*0.24mm*] +inherits = *common* +layer_height = 0.24 +top_infill_extrusion_width = 0.45 +bottom_solid_layers = 3 +top_solid_layers = 4 + +[print:*0.28mm*] +inherits = *common* +layer_height = 0.28 +top_infill_extrusion_width = 0.45 +bottom_solid_layers = 3 +top_solid_layers = 4 + +[print:0.08mm SUPERDETAIL @ELEGOO] +inherits = *0.08mm* +compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 + +[print:0.10mm HIGHDETAIL @ELEGOO] +inherits = *0.10mm* +compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 + +[print:0.12mm DETAIL @ELEGOO] +inherits = *0.12mm* +compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 + +[print:0.16mm OPTIMAL @ELEGOO] +inherits = *0.16mm* +compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 + +[print:0.20mm NORMAL @ELEGOO] +inherits = *0.20mm* +compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 + +[print:0.24mm DRAFT @ELEGOO] +inherits = *0.24mm* +compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 + +[print:0.28mm SUPERDRAFT @ELEGOO] +inherits = *0.28mm* +compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 + +# When submitting new filaments please print the following temperature tower at 0.1mm layer height: +# https://www.thingiverse.com/thing:2615842 +# Pay particular attention to bridging, overhangs and retractions. +# Also print the following bed adhesion test at 0.1 layer height as well: +# https://www.prusaprinters.org/prints/4634-bed-adhesion-warp-test +# At least for PLA, please keep bed temp at 60, as many Elegoo printers do not have any ABL +# So having some leeway to get good bed adhesion is not a luxury for many users + +[filament:*common*] +cooling = 0 +compatible_printers = +extrusion_multiplier = 1 +filament_cost = 0 +filament_density = 0 +filament_diameter = 1.75 +filament_notes = "" +filament_settings_id = "" +filament_soluble = 0 +min_print_speed = 15 +slowdown_below_layer_time = 20 +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_ELEGOO.*/ + +[filament:*PLA*] +inherits = *common* +bed_temperature = 60 +fan_below_layer_time = 100 +filament_colour = #DDDDDD +filament_max_volumetric_speed = 15 +filament_type = PLA +filament_density = 1.24 +filament_cost = 20 +first_layer_bed_temperature = 60 +first_layer_temperature = 210 +fan_always_on = 1 +cooling = 1 +max_fan_speed = 100 +min_fan_speed = 100 +bridge_fan_speed = 100 +disable_fan_first_layers = 1 +temperature = 205 + +[filament:*PET*] +inherits = *common* +bed_temperature = 70 +cooling = 1 +disable_fan_first_layers = 3 +fan_below_layer_time = 20 +filament_colour = #DDDDDD +filament_max_volumetric_speed = 8 +filament_type = PETG +filament_density = 1.27 +filament_cost = 20 +first_layer_bed_temperature = 70 +first_layer_temperature = 240 +fan_always_on = 1 +max_fan_speed = 50 +min_fan_speed = 20 +bridge_fan_speed = 100 +temperature = 240 + +[filament:*ABS*] +inherits = *common* +bed_temperature = 100 +cooling = 0 +disable_fan_first_layers = 3 +fan_below_layer_time = 20 +filament_colour = #DDDDDD +filament_max_volumetric_speed = 11 +filament_type = ABS +filament_density = 1.04 +filament_cost = 20 +first_layer_bed_temperature = 100 +first_layer_temperature = 245 +fan_always_on = 0 +max_fan_speed = 0 +min_fan_speed = 0 +bridge_fan_speed = 30 +top_fan_speed = 0 +temperature = 245 + +[filament:Generic PLA @ELEGOO] +inherits = *PLA* +filament_vendor = Generic + +[filament:Generic PETG @ELEGOO] +inherits = *PET* +filament_vendor = Generic + +[filament:Generic ABS @ELEGOO] +inherits = *ABS* +first_layer_bed_temperature = 90 +bed_temperature = 90 +filament_vendor = Generic + +# Common printer preset +[printer:*common*] +printer_technology = FFF +before_layer_gcode = ;BEFORE_LAYER_CHANGE\nG92 E0\n;[layer_z]\n\n +bed_shape = 0x0,220x0,220x220,0x220 +between_objects_gcode = +pause_print_gcode = +deretract_speed = 0 +extruder_colour = #FCE94F +extruder_offset = 0x0 +gcode_flavor = marlin +silent_mode = 0 +remaining_times = 0 +machine_max_acceleration_e = 5000 +machine_max_acceleration_extruding = 500 +machine_max_acceleration_retracting = 1000 +machine_max_acceleration_x = 500 +machine_max_acceleration_y = 500 +machine_max_acceleration_z = 100 +machine_max_feedrate_e = 60 +machine_max_feedrate_x = 500 +machine_max_feedrate_y = 500 +machine_max_feedrate_z = 10 +machine_max_jerk_e = 5 +machine_max_jerk_x = 8 +machine_max_jerk_y = 8 +machine_max_jerk_z = 0.4 +machine_min_extruding_rate = 0 +machine_min_travel_rate = 0 +layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] +max_layer_height = 0.3 +min_layer_height = 0.07 +max_print_height = 250 +nozzle_diameter = 0.4 +printer_notes = +printer_settings_id = +retract_before_travel = 1 +retract_before_wipe = 0% +retract_layer_change = 1 +retract_length = 1 +retract_length_toolchange = 1 +retract_lift = 0 +retract_lift_above = 0 +retract_lift_below = 0 +retract_restart_extra = 0 +retract_restart_extra_toolchange = 0 +retract_speed = 35 +single_extruder_multi_material = 0 +thumbnails = 16x16,220x124 +toolchange_gcode = +use_firmware_retraction = 0 +use_relative_e_distances = 1 +use_volumetric_e = 0 +variable_layer_height = 1 +wipe = 1 +z_offset = 0 +printer_model = +default_print_profile = 0.16mm OPTIMAL @ELEGOO +default_filament_profile = Generic PLA @ELEGOO + +[printer:Elegoo Neptune-2] +inherits = *common* +printer_model = NEPTUNE2 +printer_variant = 0.4 +max_layer_height = 0.28 +min_layer_height = 0.08 +printer_notes = Do not remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_ELEGOO\nPRINTER_MODEL_NEPTUNE2\nPRINTER_HAS_BOWDEN +max_print_height = 250 +machine_max_acceleration_e = 5000 +machine_max_acceleration_extruding = 500 +machine_max_acceleration_retracting = 1000 +machine_max_acceleration_x = 500 +machine_max_acceleration_y = 500 +machine_max_acceleration_z = 100 +machine_max_feedrate_e = 60 +machine_max_feedrate_x = 500 +machine_max_feedrate_y = 500 +machine_max_feedrate_z = 10 +machine_max_jerk_e = 5 +machine_max_jerk_x = 8 +machine_max_jerk_y = 8 +machine_max_jerk_z = 0.4 +machine_min_extruding_rate = 0 +machine_min_travel_rate = 0 +nozzle_diameter = 0.4 +retract_before_travel = 2 +retract_length = 5 +retract_speed = 60 +deretract_speed = 40 +retract_before_wipe = 70% +start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nM140 S[first_layer_bed_temperature] ; set final bed temp\nG4 S10 ; allow partial nozzle warmup\nG28 ; home all axis\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set final nozzle temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp to stabilize\nM109 S[first_layer_temperature] ; wait for nozzle temp to stabilize\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 +end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2, max_print_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\n{if max_layer_z < max_print_height-10}G1 Z{z_offset+min(max_layer_z+70, max_print_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{max_print_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors + + +# Intended for printers with a smaller bed +# [printer:*fastabl*] +# start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nM140 S[first_layer_bed_temperature] ; set final bed temp\nG4 S10 ; allow partial nozzle warmup\nG28 ; home all axis\nG29 ; auto bed levelling\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set final nozzle temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp to stabilize\nM109 S[first_layer_temperature] ; wait for nozzle temp to stabilize\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 + +# Intended for printers with a larger bed +# [printer:*slowabl*] +# start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nM140 S[first_layer_bed_temperature] ; set final bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp to stabilize\nG28 ; home all axis\nG29 ; auto bed levelling\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set final nozzle temp\nM109 S[first_layer_temperature] ; wait for nozzle temp to stabilize\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 + +# Intended for printers with vendor official firmware verified to support M25 +# [printer:*pauseprint*] +# pause_print_gcode = M25 ; pause print + +# Intended for printers where the Z-axis lowers the print bed during printing +# [printer:*invertedz*] +# end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2, max_print_height)} F600{endif} ; Move print bed down\nG1 X50 Y50 F{travel_speed*60} ; present print\n{if max_layer_z < max_print_height-10}G1 Z{z_offset+max_print_height-10} F600{endif} ; Move print bed down further down\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors + +# Intended for printers with dual extruders and a single hotend/nozzle +[printer:*dualextruder*] +single_extruder_multi_material = 1 +cooling_tube_length = 23 +cooling_tube_retraction = 35 +extra_loading_move = -2 +parking_pos_retraction = 80 +deretract_speed = 40,40 +extruder_colour = #0080C0;#FFFF9F +extruder_offset = 0x0,0x0 +max_layer_height = 0.28,0.28 +min_layer_height = 0.08,0.08 +nozzle_diameter = 0.4,0.4 +retract_before_travel = 2,2 +retract_before_wipe = 70%,70% +retract_layer_change = 1,1 +retract_length = 5,5 +retract_length_toolchange = 1,1 +retract_lift = 0,0 +retract_lift_above = 0,0 +retract_lift_below = 0,0 +retract_restart_extra = 0,0 +retract_restart_extra_toolchange = 0,0 +retract_speed = 60,60 +wipe = 1,1 +start_gcode = T[initial_tool] ; set active extruder\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM140 S{first_layer_bed_temperature[0]} ; set final bed temp\nM104 S150 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nG4 S10 ; allow partial nozzle warmup\nG28 ; home all axis\n;G29 ; auto bed levelling - remove ; at beginning of line to enable\n;M420 S1 ; enable mesh - remove ; at beginning of line to enable\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S{first_layer_temperature[0]} ; set final nozzle temp\nM190 S{first_layer_bed_temperature[0]} ; wait for bed temp to stabilize\nM109 S{first_layer_temperature[0]} ; wait for nozzle temp to stabilize\nG1 Z0.28 F240 ; move down to prime nozzle\nG92 E0 ; reset extruder\nG1 E90 ; load filament\nG92 E0 ; reset extruder\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000 ; move over for second prime line\nG92 E0 ; reset extruder\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 ; reset extruder +end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2, max_print_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\nG1 E-80 F2000 ; unload filament\n{if max_layer_z < max_print_height-10}G1 Z{z_offset+min(max_layer_z+70, max_print_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{max_print_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors + +# Copy of Creality CR-X config for the Neptune 2D (dual extruder, single hotend) + +[printer:Elegoo Neptune-2D] +inherits = Elegoo Neptune-2; *dualextruder* +retract_length = 6,6 +printer_model = NEPTUNE2D +printer_notes = Do not remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_ELEGOO\nPRINTER_MODEL_NEPTUNE2D\nPRINTER_HAS_BOWDEN + +[printer:Elegoo Neptune-2S] +inherits = Elegoo Neptune-2 +printer_model = NEPTUNE2S +printer_notes = Do not remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_ELEGOO\nPRINTER_MODEL_NEPTUNE2D\nPRINTER_HAS_BOWDEN + +[printer:Elegoo Neptune-X] +inherits = Elegoo Neptune-2 +max_print_height = 300 +printer_model = NEPTUNEX +printer_notes = Do not remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_ELEGOO\nPRINTER_MODEL_NEPTUNE2D\nPRINTER_HAS_BOWDEN + +[printer:Elegoo Neptune-3] +inherits = Elegoo Neptune-2 +max_print_height = 280 +start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nM140 S[first_layer_bed_temperature] ; set final bed temp\nG4 S10 ; allow partial nozzle warmup\nG28 ; home all axis\nG29 ; run abl mesh\nM420 S1 ; load mesh\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set final nozzle temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp to stabilize\nM109 S[first_layer_temperature] ; wait for nozzle temp to stabilize\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 +printer_model = NEPTUNE3 +printer_notes = Do not remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_ELEGOO\nPRINTER_MODEL_NEPTUNE2D\nPRINTER_HAS_BOWDEN + +[printer:Elegoo Neptune-1] +inherits = Elegoo Neptune-2 +bed_shape = 0x0,210x0,210x210,0x210 +max_print_height = 200 +printer_model = NEPTUNE1 +printer_notes = Do not remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_ELEGOO\nPRINTER_MODEL_NEPTUNE2D\nPRINTER_HAS_BOWDEN diff --git a/resources/profiles/LulzBot.idx b/resources/profiles/LulzBot.idx index 8638bdbbeb..e182c33dbb 100644 --- a/resources/profiles/LulzBot.idx +++ b/resources/profiles/LulzBot.idx @@ -1,4 +1,5 @@ -min_slic3r_version = 2.3.0-beta2 -0.0.2 Removed obsolete host keys -min_slic3r_version = 2.2.0-alpha3 -0.0.1 Initial version +min_slic3r_version = 2.3.0-beta2 +0.1.0 General rework. Added new print and filament profiles. +0.0.2 Removed obsolete host keys +min_slic3r_version = 2.2.0-alpha3 +0.0.1 Initial version diff --git a/resources/profiles/LulzBot.ini b/resources/profiles/LulzBot.ini index 2338beaee0..3ab6999227 100644 --- a/resources/profiles/LulzBot.ini +++ b/resources/profiles/LulzBot.ini @@ -1,9 +1,10 @@ -# generated by PrusaSlicer 2.1.1+win64 on 2020-02-25 at 01:51:21 UTC +# LulzBot profiles +# Based on community profiles and original profiles from Cura LulzBot Edition. [vendor] # Vendor name will be shown by the Config Wizard. name = LulzBot -config_version = 0.0.2 +config_version = 0.1.0 config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/LulzBot/ [printer_model:MINI_AERO] @@ -12,18 +13,26 @@ variants = 0.5 technology = FFF #bed_model = mini_bed.stl #bed_texture = mini.svg -default_materials = ColorFabb PLA-PHA @lulzbot;PrintedSolid Jesse PLA @lulzbot +default_materials = Generic PLA @lulzbot; Generic PETG @lulzbot; Jessie PLA @lulzbot [printer_model:TAZ6_AERO] name = Taz6 Aero variants = 0.5 technology = FFF -default_materials = ColorFabb PLA-PHA @lulzbot;PrintedSolid Jesse PLA @lulzbot +default_materials = Generic PLA @lulzbot; Generic PETG @lulzbot; Jessie PLA @lulzbot -[print:0.3mm @lulzbot] +# [printer_model:TAZ_WORKHORSE] +# name = Taz Workhorse +# variants = 0.5 +# technology = FFF +# default_materials = Generic PLA @lulzbot; Generic PETG @lulzbot; Jessie PLA @lulzbot + +[print:*common*] avoid_crossing_perimeters = 0 -bottom_fill_pattern = rectilinear +bottom_fill_pattern = monotonic +top_fill_pattern = monotonic bottom_solid_layers = 3 +top_solid_layers = 4 bridge_acceleration = 500 bridge_angle = 0 bridge_flow_ratio = 1 @@ -34,26 +43,24 @@ compatible_printers = compatible_printers_condition = complete_objects = 0 default_acceleration = 500 -dont_support_bridges = 1 +dont_support_bridges = 0 elefant_foot_compensation = 0 -ensure_vertical_shell_thickness = 0 +ensure_vertical_shell_thickness = 1 +extra_perimeters = 0 external_perimeter_extrusion_width = 0.56 -external_perimeter_speed = 50% +external_perimeter_speed = 35 external_perimeters_first = 0 -extra_perimeters = 1 -extruder_clearance_height = 20 -extruder_clearance_radius = 20 extrusion_width = 0.56 fill_angle = 45 fill_density = 20% -fill_pattern = gyroid +fill_pattern = grid first_layer_acceleration = 500 first_layer_extrusion_width = 0.6 -first_layer_height = 100% -first_layer_speed = 40% +first_layer_height = 0.3 +first_layer_speed = 15 gap_fill_speed = 20 -gcode_comments = 0 -gcode_label_objects = 0 +infill_anchor = 1 +infill_anchor_max = 20 infill_acceleration = 500 infill_every_layers = 1 infill_extruder = 1 @@ -62,33 +69,31 @@ infill_first = 0 infill_only_where_needed = 0 infill_overlap = 25% infill_speed = 60 -inherits = -interface_shells = 0 -layer_height = 0.3 +layer_height = 0.25 max_print_speed = 80 max_volumetric_speed = 0 min_skirt_length = 0 -notes = -only_retract_when_crossing_perimeters = 1 +only_retract_when_crossing_perimeters = 0 ooze_prevention = 0 output_filename_format = [printer_settings_id]_[input_filename_base]_[layer_height]_[filament_type]_[print_time].gcode overhangs = 1 perimeter_acceleration = 500 perimeter_extruder = 1 perimeter_extrusion_width = 0.56 -perimeter_speed = 60 +perimeter_speed = 45 perimeters = 3 post_process = raft_layers = 0 +raft_first_layer_density = 70 resolution = 0 -seam_position = nearest +seam_position = aligned single_extruder_multi_material_priming = 1 skirt_distance = 3 skirt_height = 1 skirts = 3 slice_closing_radius = 0.049 -small_perimeter_speed = 15 -solid_infill_below_area = 70 +small_perimeter_speed = 22 +solid_infill_below_area = 0 solid_infill_every_layers = 0 solid_infill_extruder = 1 solid_infill_extrusion_width = 0.56 @@ -96,7 +101,7 @@ solid_infill_speed = 60 spiral_vase = 0 standby_temperature_delta = -5 support_material = 0 -support_material_angle = 0 +support_material_angle = 45 support_material_auto = 1 support_material_buildplate_only = 0 support_material_contact_distance = 0.2 @@ -110,17 +115,14 @@ support_material_interface_spacing = 0 support_material_interface_speed = 100% support_material_pattern = rectilinear support_material_spacing = 2.5 -support_material_speed = 60 +support_material_speed = 50 support_material_synchronize_layers = 0 support_material_threshold = 0 support_material_with_sheath = 1 -support_material_xy_spacing = 50% +support_material_xy_spacing = 60% thin_walls = 1 -threads = 12 -top_fill_pattern = rectilinear top_infill_extrusion_width = 0.52 top_solid_infill_speed = 40 -top_solid_layers = 3 travel_speed = 175 wipe_tower = 0 wipe_tower_bridging = 10 @@ -130,121 +132,116 @@ wipe_tower_x = 180 wipe_tower_y = 140 xy_size_compensation = 0 +[print:0.14mm DETAIL @lulzbot] +inherits = *common* +layer_height = 0.14 +bottom_solid_layers = 8 +top_solid_layers = 8 +infill_speed = 40 +solid_infill_speed = 50 +perimeter_speed = 35 +external_perimeter_speed = 30 +top_solid_infill_speed = 40 + +[print:0.25mm STANDARD @lulzbot] +inherits = *common* + +[print:0.30mm SPEED @lulzbot] +inherits = *common* +renamed_from = "0.3mm @lulzbot" +layer_height = 0.3 +seam_position = nearest +top_solid_layers = 3 +infill_speed = 45 +perimeter_speed = 40 +external_perimeter_speed = 35 + [filament:ColorFabb PLA-PHA @lulzbot] filament_vendor = ColorFabb bed_temperature = 60 bridge_fan_speed = 100 -compatible_printers = -compatible_printers_condition = -compatible_prints = -compatible_prints_condition = cooling = 1 disable_fan_first_layers = 3 end_filament_gcode = "; Filament-specific end gcode \n;END gcode for filament\n" extrusion_multiplier = 1 -fan_always_on = 0 +fan_always_on = 1 fan_below_layer_time = 60 filament_colour = #29B2B2 -filament_cooling_final_speed = 3.4 -filament_cooling_initial_speed = 2.2 -filament_cooling_moves = 4 filament_cost = 0 filament_density = 1.25 -filament_deretract_speed = nil filament_diameter = 2.85 -filament_load_time = 0 -filament_loading_speed = 28 -filament_loading_speed_start = 3 -filament_max_volumetric_speed = 0 -filament_minimal_purge_on_wipe_tower = 15 -filament_notes = "" -filament_ramming_parameters = "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" -filament_retract_before_travel = nil -filament_retract_before_wipe = nil -filament_retract_layer_change = nil -filament_retract_length = nil -filament_retract_lift = nil -filament_retract_lift_above = nil -filament_retract_lift_below = nil -filament_retract_restart_extra = nil -filament_retract_speed = nil filament_soluble = 0 -filament_toolchange_delay = 0 filament_type = PLA -filament_unload_time = 0 -filament_unloading_speed = 90 -filament_unloading_speed_start = 100 -filament_wipe = nil first_layer_bed_temperature = 60 first_layer_temperature = 200 -inherits = max_fan_speed = 100 min_fan_speed = 35 min_print_speed = 10 -slowdown_below_layer_time = 5 +slowdown_below_layer_time = 10 start_filament_gcode = "; Filament gcode\n" temperature = 200 -[filament:PrintedSolid Jesse PLA @lulzbot] -filament_vendor = PrintedSolid +[filament:Jessie PLA @lulzbot] +filament_vendor = Printed Solid +renamed_from = "PrintedSolid Jesse PLA @lulzbot" bed_temperature = 60 bridge_fan_speed = 100 -compatible_printers = -compatible_printers_condition = -compatible_prints = -compatible_prints_condition = cooling = 1 disable_fan_first_layers = 3 end_filament_gcode = "; Filament-specific end gcode \n;END gcode for filament\n" extrusion_multiplier = 1 -fan_always_on = 0 +fan_always_on = 1 fan_below_layer_time = 60 filament_colour = #29B2B2 -filament_cooling_final_speed = 3.4 -filament_cooling_initial_speed = 2.2 -filament_cooling_moves = 4 filament_cost = 27 -filament_density = 1.25 -filament_deretract_speed = nil +filament_density = 1.24 filament_diameter = 2.85 -filament_load_time = 0 -filament_loading_speed = 28 -filament_loading_speed_start = 3 -filament_max_volumetric_speed = 0 -filament_minimal_purge_on_wipe_tower = 15 -filament_notes = "" -filament_ramming_parameters = "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" -filament_retract_before_travel = nil -filament_retract_before_wipe = nil -filament_retract_layer_change = nil -filament_retract_length = nil -filament_retract_lift = nil -filament_retract_lift_above = nil -filament_retract_lift_below = nil -filament_retract_restart_extra = nil -filament_retract_speed = nil -filament_soluble = 0 -filament_toolchange_delay = 0 filament_type = PLA -filament_unload_time = 0 -filament_unloading_speed = 90 -filament_unloading_speed_start = 100 -filament_wipe = nil first_layer_bed_temperature = 60 first_layer_temperature = 220 -inherits = max_fan_speed = 100 -min_fan_speed = 35 +min_fan_speed = 80 min_print_speed = 10 -slowdown_below_layer_time = 5 +slowdown_below_layer_time = 10 start_filament_gcode = "; Filament gcode\n" temperature = 220 +[filament:Generic PLA @lulzbot] +inherits = Jessie PLA @lulzbot +filament_vendor = Generic + +[filament:Generic PETG @lulzbot] +filament_vendor = Generic +bed_temperature = 60 +first_layer_bed_temperature = 65 +first_layer_temperature = 235 +temperature = 230 +bridge_fan_speed = 100 +cooling = 1 +disable_fan_first_layers = 3 +end_filament_gcode = "; Filament-specific end gcode \n;END gcode for filament\n" +extrusion_multiplier = 1 +fan_always_on = 1 +fan_below_layer_time = 60 +filament_colour = #29B2B2 +filament_cost = 27 +filament_density = 1.27 +filament_diameter = 2.85 +filament_notes = "Use glue stick." +filament_soluble = 0 +filament_toolchange_delay = 0 +filament_type = PETG +max_fan_speed = 80 +min_fan_speed = 40 +min_print_speed = 10 +slowdown_below_layer_time = 10 +start_filament_gcode = "; Filament gcode\n" + [printer:Mini Aero 0.5mm] printer_model = MINI_AERO printer_variant = 0.5 -default_print_profile = 0.3mm @lulzbot -default_filament_profile = PrintedSolid Jesse PLA @lulzbot +default_print_profile = 0.25mm STANDARD @lulzbot +default_filament_profile = Jessie PLA @lulzbot bed_shape = 0x0,154x0,154x154,0x154 before_layer_gcode = between_objects_gcode = @@ -259,22 +256,23 @@ gcode_flavor = marlin high_current_on_filament_swap = 0 inherits = layer_gcode = -machine_max_acceleration_e = 10000,5000 -machine_max_acceleration_extruding = 1500,1250 -machine_max_acceleration_retracting = 1500,1250 -machine_max_acceleration_x = 9000,1000 -machine_max_acceleration_y = 9000,1000 -machine_max_acceleration_z = 100,200 -machine_max_feedrate_e = 40,120 -machine_max_feedrate_x = 800,200 -machine_max_feedrate_y = 800,200 -machine_max_feedrate_z = 8,12 -machine_max_jerk_e = 2.5,2.5 -machine_max_jerk_x = 20,10 -machine_max_jerk_y = 20,10 -machine_max_jerk_z = 0.2,0.4 -machine_min_extruding_rate = 0,0 -machine_min_travel_rate = 0,0 +machine_max_acceleration_e = 10000 +machine_max_acceleration_extruding = 1500 +machine_max_acceleration_retracting = 1500 +machine_max_acceleration_x = 9000 +machine_max_acceleration_y = 9000 +machine_max_acceleration_z = 100 +machine_max_feedrate_e = 40 +machine_max_feedrate_x = 300 +machine_max_feedrate_y = 300 +machine_max_feedrate_z = 8 +machine_max_jerk_e = 2.5 +machine_max_jerk_x = 20 +machine_max_jerk_y = 20 +machine_max_jerk_z = 0.2 +machine_min_extruding_rate = 0 +machine_min_travel_rate = 0 +machine_limits_usage = time_estimate_only max_layer_height = 0 max_print_height = 158 min_layer_height = 0.07 @@ -292,7 +290,7 @@ retract_lift_above = 0 retract_lift_below = 0 retract_restart_extra = 0 retract_restart_extra_toolchange = 0 -retract_speed = 40 +retract_speed = 30 silent_mode = 0 single_extruder_multi_material = 0 start_gcode = ;This G-Code has been generated specifically for the LulzBot Mini with Aerosturder\nM73 P0 ; clear GLCD progress bar\nM75 ; start GLCD timer\nG26 ; clear potential 'probe fail' condition\nM107 ; disable fans\nM420 S0 ; disable leveling matrix\nG90 ; absolute positioning\nM82 ; set extruder to absolute mode\nG92 E0 ; set extruder position to 0\nM140 S{first_layer_bed_temperature[0]} ; start bed heating up\nG28; home all axes\nG0 X0 Y187 Z156 F200 ; move away from endstops\nM109 R{first_layer_temperature[0] - 60} ; soften filament before retraction\n;G1 E-15 F75 ; retract filament (LulzBot Cura is apparently trying to cold pull, might be a contributing factor to hob gear filling with filament)\nM109 R{first_layer_temperature[0] - 60} ; wait for extruder to reach wiping temp\nG1 X45 Y173 F11520 ; move above wiper pad\nG1 Z0 F1200 ; push nozzle into wiper\nG1 X42 Y173 Z-.5 F4000 ; wiping\nG1 X52 Y171 Z-.5 F4000 ; wiping\nG1 X42 Y173 Z0 F4000 ; wiping\nG1 X52 Y171 F4000 ; wiping\nG1 X42 Y173 F4000 ; wiping\nG1 X52 Y171 F4000 ; wiping\nG1 X42 Y173 F4000 ; wiping\nG1 X52 Y171 F4000 ; wiping\nG1 X57 Y173 F4000 ; wiping\nG1 X77 Y171 F4000 ; wiping\nG1 X57 Y173 F4000 ; wiping\nG1 X77 Y171 F4000 ; wiping\nG1 X57 Y173 F4000 ; wiping\nG1 X87 Y171 F4000 ; wiping\nG1 X77 Y173 F4000 ; wiping\nG1 X97 Y171 F4000 ; wiping\nG1 X77 Y173 F4000 ; wiping\nG1 X97 Y171 F4000 ; wiping\nG1 X77 Y173 F4000 ; wiping\nG1 X97 Y171 F4000 ; wiping\nG1 X107 Y173 F4000 ; wiping\nG1 X97 Y171 F4000 ; wiping\nG1 X107 Y173 F4000 ; wiping\nG1 X97 Y171 F4000 ; wiping\nG1 X107 Y173 F4000 ; wiping\nG1 X112 Y171 Z-0.5 F1000 ; wiping\nG1 Z10 ; raise extruder\nG28 X0 Y0 ; home X and Y\nG0 X0 Y187 F200 ; move away from endstops\nM109 R{first_layer_temperature[0] - 60} ; wait for extruder to reach probe temp\nM204 S300 ; set probing acceleration\nG29 ; start auto-leveling sequence\nM420 S1 ; enable leveling matrix\nM425 Z ; use measured Z backlash for compensation\nM425 Z F0 ; turn off measured Z backlash compensation. (if activated in the quality settings, this command will automatically be ignored)\nM204 S2000 ; restore standard acceleration\nG28 X0 Y0 ; re-home to account for build variance of earlier mini builds\nG0 X0 Y187 F200 ; move away from endstops\nG0 Y152 F4000 ; move in front of wiper pad\nG4 S1 ; pause\nM400 ; wait for moves to finish\nM117 Heating... ; progress indicator message on LCD\nM109 R{first_layer_temperature[0]} ; wait for extruder to reach printing temp\nM190 R{first_layer_bed_temperature[0]} ; wait for bed to reach printing temp\nG1 Z2 E0 F75 ; prime tiny bit of filament into the nozzle\nM117 Mini Printing... ; progress indicator message on LCD\nM221 S74 ; Printer specific extrusion modifier. @@ -308,8 +306,8 @@ z_offset = 0 [printer:Taz6 Aero 0.5mm] printer_model = TAZ6_AERO printer_variant = 0.5 -default_print_profile = 0.3mm @lulzbot -default_filament_profile = PrintedSolid Jesse PLA @lulzbot +default_print_profile = 0.25mm STANDARD @lulzbot +default_filament_profile = Jessie PLA @lulzbot bed_shape = 0x0,280x0,280x280,0x280 before_layer_gcode = between_objects_gcode = @@ -324,22 +322,23 @@ gcode_flavor = marlin high_current_on_filament_swap = 0 inherits = layer_gcode = -machine_max_acceleration_e = 1000,5000 -machine_max_acceleration_extruding = 1000,1250 -machine_max_acceleration_retracting = 1000,1250 -machine_max_acceleration_x = 9000,1000 -machine_max_acceleration_y = 9000,1000 -machine_max_acceleration_z = 100,200 -machine_max_feedrate_e = 40,120 -machine_max_feedrate_x = 800,200 -machine_max_feedrate_y = 800,200 -machine_max_feedrate_z = 3,12 -machine_max_jerk_e = 2.5,2.5 -machine_max_jerk_x = 12,10 -machine_max_jerk_y = 12,10 -machine_max_jerk_z = 0.2,0.4 -machine_min_extruding_rate = 0,0 -machine_min_travel_rate = 0,0 +machine_max_acceleration_e = 1000 +machine_max_acceleration_extruding = 500 +machine_max_acceleration_retracting = 1000 +machine_max_acceleration_x = 9000 +machine_max_acceleration_y = 9000 +machine_max_acceleration_z = 100 +machine_max_feedrate_e = 40 +machine_max_feedrate_x = 300 +machine_max_feedrate_y = 300 +machine_max_feedrate_z = 3 +machine_max_jerk_e = 10 +machine_max_jerk_x = 8 +machine_max_jerk_y = 8 +machine_max_jerk_z = 0.4 +machine_min_extruding_rate = 0 +machine_min_travel_rate = 0 +machine_limits_usage = time_estimate_only max_layer_height = 0 max_print_height = 250 min_layer_height = 0.07 @@ -358,7 +357,7 @@ retract_lift_above = 0 retract_lift_below = 0 retract_restart_extra = 0 retract_restart_extra_toolchange = 0 -retract_speed = 40 +retract_speed = 30 silent_mode = 0 single_extruder_multi_material = 0 start_gcode = ;This G-Code has been generated specifically for the LulzBot TAZ 6 with Aerosturder\nM73 P0 ; clear GLCD progress bar\nM75 ; start GLCD timer\nG26 ; clear potential 'probe fail' condition\nM107 ; disable fans\nM420 S0 ; disable leveling matrix\nG90 ; absolute positioning\nM82 ; set extruder to absolute mode\nG92 E0 ; set extruder position to 0\nM140 S{first_layer_bed_temperature[0]} ; start bed heating up\nG28 XY ; home X and Y\nG1 X-19 Y258 F1000 ; move to safe homing position\nM109 R{first_layer_temperature[0] - 60} ; soften filament before homing Z\nG28 Z ; home Z\nG1 E-15 F100 ; retract filament\nM109 R{first_layer_temperature[0] - 60} ; wait for extruder to reach wiping temp\nG1 X-15 Y100 F3000 ; move above wiper pad\nG1 Z1 ; push nozzle into wiper\nG1 X-17 Y95 F1000 ; slow wipe\nG1 X-17 Y90 F1000 ; slow wipe\nG1 X-17 Y85 F1000 ; slow wipe\nG1 X-15 Y90 F1000 ; slow wipe\nG1 X-17 Y80 F1000 ; slow wipe\nG1 X-15 Y95 F1000 ; slow wipe\nG1 X-17 Y75 F2000 ; fast wipe\nG1 X-15 Y65 F2000 ; fast wipe\nG1 X-17 Y70 F2000 ; fast wipe\nG1 X-15 Y60 F2000 ; fast wipe\nG1 X-17 Y55 F2000 ; fast wipe\nG1 X-15 Y50 F2000 ; fast wipe\nG1 X-17 Y40 F2000 ; fast wipe\nG1 X-15 Y45 F2000 ; fast wipe\nG1 X-17 Y35 F2000 ; fast wipe\nG1 X-15 Y40 F2000 ; fast wipe\nG1 X-17 Y70 F2000 ; fast wipe\nG1 X-15 Y30 Z2 F2000 ; fast wipe\nG1 X-17 Y35 F2000 ; fast wipe\nG1 X-15 Y25 F2000 ; fast wipe\nG1 X-17 Y30 F2000 ; fast wipe\nG1 X-15 Y25 Z1.5 F1000 ; slow wipe\nG1 X-17 Y23 F1000 ; slow wipe\nG1 Z10 ; raise extruder\nM109 R{first_layer_temperature[0] - 60} ; wait for extruder to reach probe temp\nG1 X-9 Y-9 ; move above first probe point\nM204 S100 ; set probing acceleration\nG29 ; start auto-leveling sequence\nM420 S1 ; enable leveling matrix\nM425 Z ; use measured Z backlash for compensation\nM425 Z F0 ; turn off measured Z backlash compensation. (if activated in the quality settings, this command will automatically be ignored)\nM204 S500 ; restore standard acceleration\nG1 X0 Y0 Z15 F5000 ; move up off last probe point\nG4 S1 ; pause\nM400 ; wait for moves to finish\nM117 Heating... ; progress indicator message on LCD\nM109 R{first_layer_temperature[0]} ; wait for extruder to reach printing temp\nM190 R{first_layer_bed_temperature[0]} ; wait for bed to reach printing temp\nG1 Z2 E0 F75 ; prime tiny bit of filament into the nozzle\nM117 TAZ 6 Printing... ; progress indicator message on LCD\n @@ -370,3 +369,55 @@ use_volumetric_e = 0 variable_layer_height = 1 wipe = 1 z_offset = 0 + +# [printer:Taz Workhorse 0.5mm] +# printer_model = TAZ_WORKHORSE +# printer_variant = 0.5 +# printer_technology = FFF +# default_print_profile = 0.25mm STANDARD @lulzbot +# default_filament_profile = Jessie PLA @lulzbot +# bed_shape = 0x0,280x0,280x280,0x280 +# deretract_speed = 20 +# end_gcode = M400 ; wait for moves to finish\nM140 S40 ; start bed cooling\nM104 S0 ; disable hotend\nM107 ; disable fans\nG91 ; relative positioning\nG1 E-1 F300 ; filament retraction to release pressure\nG1 Z20 E-5 X-20 Y-20 F3000 ; lift up and retract even more filament\nG1 E6 ; re-prime extruder\nM117 Cooling please wait ; progress indicator message on LCD\nG90 ; absolute positioning\nG1 Y0 F3000 ; move to cooling position\nM190 R40 ; wait for bed to cool down to removal temp\nG1 Y280 F3000 ; present finished print\nM140 S0; cool downs\nM77 ; stop GLCD timer\nM84 ; disable steppers\nG90 ; absolute positioning\nM117 Print Complete. ; print complete message\n +# extra_loading_move = -2 +# extruder_colour = "" +# extruder_offset = 0x0 +# gcode_flavor = marlin +# high_current_on_filament_swap = 0 +# machine_max_acceleration_e = 3000 +# machine_max_acceleration_extruding = 500 +# machine_max_acceleration_retracting = 2000 +# machine_max_acceleration_x = 9000 +# machine_max_acceleration_y = 9000 +# machine_max_acceleration_z = 100 +# machine_max_feedrate_e = 40 +# machine_max_feedrate_x = 300 +# machine_max_feedrate_y = 300 +# machine_max_feedrate_z = 25 +# machine_max_jerk_e = 10 +# machine_max_jerk_x = 8 +# machine_max_jerk_y = 8 +# machine_max_jerk_z = 0.4 +# machine_min_extruding_rate = 0 +# machine_min_travel_rate = 0 +# machine_limits_usage = time_estimate_only +# max_layer_height = 0 +# max_print_height = 285 +# min_layer_height = 0.07 +# nozzle_diameter = 0.5 +# remaining_times = 0 +# retract_before_travel = 2 +# retract_before_wipe = 0% +# retract_layer_change = 0 +# retract_length = 2 +# retract_length_toolchange = 10 +# retract_lift = 0 +# retract_speed = 40 +# silent_mode = 0 +# single_extruder_multi_material = 0 +# start_gcode = ;This G-Code has been generated specifically for the LulzBot TAZ Workhorse with HE Tool Head\n;\n;The following lines can be uncommented for printer specific fine tuning\n;More information can be found at https://marlinfw.org/meta/gcode/\n;\n;M92 E420 ;Set Axis Steps-per-unit\n;M301 P21.0 I1.78 D61.93 ;Set Hotend PID\n;M906 E160 ;Digipot Motor Current ((875mA-750)/5+135) = 160\n;\nM73 P0 ; clear GLCD progress bar\nM75 ; start GLCD timer\nG26 ; clear potential 'probe fail' condition\nM107 ; disable fans\nM420 S0 ; disable previous leveling matrix\nG90 ; absolute positioning\nM82 ; set extruder to absolute mode\nG92 E0 ; set extruder position to 0\nM140 S{first_layer_bed_temperature[0]} ; start bed heating up\nM109 R{first_layer_temperature[0] - 60} ; soften filament before homing Z\nG28 ; Home all axis\nG1 E-15 F100 ; retract filament\nM109 R{first_layer_temperature[0] - 60} ; wait for extruder to reach wiping temp\n;M206 X0 Y0 Z0 ; uncomment to adjust wipe position (+X ~ nozzle moves left)(+Y ~ nozzle moves forward)(+Z ~ nozzle moves down)\nG12 ; wiping sequence\nM206 X0 Y0 Z0 ; reseting stock nozzle position ### CAUTION: changing this line can affect print quality ###\nM109 R{first_layer_temperature[0] - 60} ; wait for extruder to reach probe temp\nG1 X288 Y-10 F4000; move above first probe point\nM204 S100 ; set probing acceleration\nG29 ; start auto-leveling sequence\nM420 S1 ; activate bed level matrix\nM425 Z ; use measured Z backlash for compensation\nM425 Z F0 ; turn off measured Z backlash compensation. (if activated in the quality settings, this command will automatically be ignored)\nM204 S500 ; restore standard acceleration\nG1 X0 Y0 Z15 F5000 ; move up off last probe point\nG4 S1 ; pause\nM400 ; wait for moves to finish\nM117 Heating... ; progress indicator message on LCD\nM109 R{first_layer_temperature[0]} ; wait for extruder to reach printing temp\nM190 R{first_layer_bed_temperature[0]} ; wait for bed to reach printing temp\nG1 Z2 E0 F75 ; prime tiny bit of filament into the nozzle\nM117 TAZ Workhorse Printing... ; progress indicator message on LCD +# use_relative_e_distances = 0 +# use_volumetric_e = 0 +# variable_layer_height = 1 +# wipe = 1 +# z_offset = 0 diff --git a/resources/profiles/LulzBot/TAZ_WORKHORSE_thumbnail.png b/resources/profiles/LulzBot/TAZ_WORKHORSE_thumbnail.png new file mode 100644 index 0000000000..133858a6f2 Binary files /dev/null and b/resources/profiles/LulzBot/TAZ_WORKHORSE_thumbnail.png differ diff --git a/resources/profiles/Print4Taste.idx b/resources/profiles/Print4Taste.idx new file mode 100644 index 0000000000..b19d0f3e1a --- /dev/null +++ b/resources/profiles/Print4Taste.idx @@ -0,0 +1,2 @@ +min_slic3r_version = 2.6.0-alpha1 +0.0.1 Initial version \ No newline at end of file diff --git a/resources/profiles/Print4Taste.ini b/resources/profiles/Print4Taste.ini new file mode 100644 index 0000000000..05f76e1c33 --- /dev/null +++ b/resources/profiles/Print4Taste.ini @@ -0,0 +1,131 @@ +# Print profiles for Print4Taste printers (mycusini and procusini brands) +# Created from scratch from default FFF + +[vendor] +# Vendor name will be shown by the Config Wizard. +name = Print4Taste +# Configuration version of this file. Config file will only be installed, if the config_version differs. +# This means, the server may force the PrusaSlicer configuration to be downgraded. +config_version = 0.0.1 +# Where to get the updates from? +config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Print4Taste/ + +# The printer models will be shown by the Configuration Wizard in this order, +# also the first model installed & the first nozzle installed will be activated after install. +# Printer model name will be shown by the installation wizard. + + +[printer_model:MC2.0] +name = mycusini 2.0 +variants = 1.0 +technology = FFF +family = mycusini +bed_model = MC2.0_bed.stl +bed_texture = MC2.0_texture.svg +default_materials = mycusini 3D Choco @MC2.0 + +[print:*common_MC2.0*] +bottom_solid_layers = 2 +bridge_speed = 30 +brim_type = no_brim +compatible_printers_condition = printer_notes=~/.*PRINT4TASTE.*/ and printer_notes=~/.*MYCUSINI2.0.*/ +elefant_foot_compensation = 0.1 +ensure_vertical_shell_thickness = 1 +external_perimeter_extrusion_width = 1.15 +external_perimeter_speed = 100% +extra_perimeters = 0 +extruder_clearance_height = 45 +extruder_clearance_radius = 40 +extrusion_width = 1.15 +fill_density = 20% +fill_pattern = grid +first_layer_extrusion_width = 1.15 +first_layer_height = 0.5 +first_layer_speed = 100% +gap_fill_speed = 30 +infill_anchor = 250% +infill_extrusion_width = 1 +infill_overlap = 5% +infill_speed = 30 +layer_height = 0.5 +max_print_speed = 80 +max_volumetric_extrusion_rate_slope_negative = 2 +max_volumetric_extrusion_rate_slope_positive = 2 +max_volumetric_speed = 8 +notes = Extruder clearances:\nHeight: 45 Radius: 40\nHeight: 8 Radius: 12\n\nDon't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRINT4TASTE\nPRINTER_MODEL_MYCUSINI2.0 +output_filename_format = [input_filename_base].gco +perimeter_extrusion_width = 1.15 +perimeter_speed = 30 +perimeters = 1 +slice_closing_radius = 0.49 +small_perimeter_speed = 100% +solid_infill_below_area = 10 +solid_infill_extrusion_width = 1.15 +solid_infill_speed = 100% +thin_walls = 0 +top_infill_extrusion_width = 1.15 +top_solid_infill_speed = 100% +top_solid_layers = 3 +travel_speed = 80 +skirts = 0 + +[print:0.50mm SOLID @MC2.0] +inherits = *common_MC2.0* + +[print:0.50mm FILLABLE @MC2.0] +inherits = 0.50mm SOLID @MC2.0 +top_solid_layers = 0 +fill_density = 0% +spiral_vase = 1 + +[print:0.50mm OUTLINES @MC2.0] +inherits = 0.50mm FILLABLE @MC2.0 +bottom_solid_layers = 0 + +[filament:mycusini 3D Choco @MC2.0] +filament_vendor = Print4Taste +bed_temperature = 0 +bridge_fan_speed = 0 +compatible_printers_condition = printer_notes=~/.*PRINT4TASTE.*/ and printer_notes=~/.*MYCUSINI2.0.*/ +cooling = 1 +disable_fan_first_layers = 0 +end_filament_gcode = "" +extrusion_multiplier = 0.95 +fan_always_on = 0 +fan_below_layer_time = 60 +filament_colour = #F4A6FF +filament_density = 1.26 +filament_diameter = 18 +filament_max_volumetric_speed = 8 +filament_notes = "Full cartridge: 18 x 100 mm, 32g\nDensity: 1.26 g/cm3\nCut cartrige size: 18 x ~50 mm, 16g\nMycusini 2.0 does not require temperature control in gcode\n\n\nDon't remove the following keywords! These keywords are used in the \"compatible printer\" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRINT4TASTE\nPRINTER_MODEL_MYCUSINI2.0" +ilament_retract_before_wipe = 30% +filament_retract_layer_change = 1 +filament_retract_length = 0.3 +filament_retract_lift = 1 +filament_type = GLAZE +filament_wipe = 1 +first_layer_bed_temperature = 0 +first_layer_temperature = 0 +max_fan_speed = 0 +min_fan_speed = 0 +min_print_speed = 9 +slowdown_below_layer_time = 15 +start_filament_gcode = "" +temperature = 0 + +[printer:mycusini 2.0] +printer_model = MC2.0 +printer_variant = 1.0 +bed_shape = 5x2.5,105x2.5,105x112.5,5x112.5 +color_change_gcode = +end_gcode = M83 ;Relative mode to retract\nG1 F2400 E-0.1 ;Retract\nM84 ;Back to absolute mode after retract\nG0 F2400 X90 Y55 Z45 ;Park +max_layer_height = 0.75 +max_print_height = 45 +min_layer_height = 0.3 +nozzle_diameter = 1 +pause_print_gcode = +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRINT4TASTE\nPRINTER_MODEL_MYCUSINI2.0 +retract_length = 0.1 +start_gcode = G1 F2400 E-0.3 ;Retract\nG0 F2400 X100 Y55 Z20.7 ;Full coordinates to prevent ramming down\nG0 F2400 X100 Y40 Z0.5 ;Start purge line\nG0 F570 X100 Y10 Z0.5 E0.025 ;Purge slightly more, should make a line only a few mm long +default_print_profile = 0.50mm SOLID @MC2.0 +default_filament_profile = mycusini 3D Choco @MC2.0 \ No newline at end of file diff --git a/resources/profiles/Print4Taste/MC2.0_bed.stl b/resources/profiles/Print4Taste/MC2.0_bed.stl new file mode 100644 index 0000000000..2db61908d8 Binary files /dev/null and b/resources/profiles/Print4Taste/MC2.0_bed.stl differ diff --git a/resources/profiles/Print4Taste/MC2.0_texture.svg b/resources/profiles/Print4Taste/MC2.0_texture.svg new file mode 100644 index 0000000000..b3cce084fc --- /dev/null +++ b/resources/profiles/Print4Taste/MC2.0_texture.svg @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/profiles/Print4Taste/MC2.0_thumbnail.png b/resources/profiles/Print4Taste/MC2.0_thumbnail.png new file mode 100644 index 0000000000..886dd34547 Binary files /dev/null and b/resources/profiles/Print4Taste/MC2.0_thumbnail.png differ diff --git a/resources/profiles/RatRig/VC3_300_thumbnail.png b/resources/profiles/RatRig/VC3_300_thumbnail.png index c9150d2b03..3e35aaf3e6 100644 Binary files a/resources/profiles/RatRig/VC3_300_thumbnail.png and b/resources/profiles/RatRig/VC3_300_thumbnail.png differ diff --git a/resources/profiles/RatRig/VC3_400_thumbnail.png b/resources/profiles/RatRig/VC3_400_thumbnail.png index c9150d2b03..3e35aaf3e6 100644 Binary files a/resources/profiles/RatRig/VC3_400_thumbnail.png and b/resources/profiles/RatRig/VC3_400_thumbnail.png differ diff --git a/resources/profiles/RatRig/VC3_500_thumbnail.png b/resources/profiles/RatRig/VC3_500_thumbnail.png index c9150d2b03..3e35aaf3e6 100644 Binary files a/resources/profiles/RatRig/VC3_500_thumbnail.png and b/resources/profiles/RatRig/VC3_500_thumbnail.png differ diff --git a/resources/profiles/RatRig/VMINION_thumbnail.png b/resources/profiles/RatRig/VMINION_thumbnail.png index 1cd82fe8c3..c4d95c4cb8 100644 Binary files a/resources/profiles/RatRig/VMINION_thumbnail.png and b/resources/profiles/RatRig/VMINION_thumbnail.png differ diff --git a/resources/profiles/TriLAB.idx b/resources/profiles/TriLAB.idx index 75819e135a..9ba40c9fc6 100644 --- a/resources/profiles/TriLAB.idx +++ b/resources/profiles/TriLAB.idx @@ -1,3 +1,5 @@ +min_slic3r_version = 2.5.0-alpha0 +1.0.2 Added home to start gcode before heating bed, added DeltiQ 2 material PLA Prusament, fixed gcode for pause print, improved output filename template(added printhead code, added filament used length, truncated timestamp) min_slic3r_version = 2.4.1-rc1 1.0.1 Fix missing AzteQ Industrial ABS material for 0.6, 0.8 nozzle, enabled elefant foot compensation 1.0.0 Added AzteQ Industrial profiles for 0.8 nozzle, updated spool weight and filament cost, some minor setting improvements diff --git a/resources/profiles/TriLAB.ini b/resources/profiles/TriLAB.ini index b5c31d1832..62ddd94a23 100644 --- a/resources/profiles/TriLAB.ini +++ b/resources/profiles/TriLAB.ini @@ -6,7 +6,7 @@ name = TriLAB # Configuration version of this file. Config file will only be installed, if the config_version differs. # This means, the server may force the PrusaSlicer configuration to be downgraded. -config_version = 1.0.1 +config_version = 1.0.2 # Where to get the updates from? config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/TriLAB/ # changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1% @@ -22,7 +22,7 @@ technology = FFF family = AzteQ bed_model = aq_bed.stl bed_texture = aq_bed_texture.svg -default_materials = AzteQ Industrial (Door Opened) - PLA - ExtraFill (Fillamentum);AzteQ Industrial (Door Opened) - PLA - Generic;AzteQ Industrial (PLA Printhead) - PLA - ExtraFill (Fillamentum);AzteQ Industrial - ABS - ExtraFill (Fillamentum);AzteQ Industrial - ABS - Generic;AzteQ Industrial - ASA - ExtraFill (Fillamentum);AzteQ Industrial - ASA - Generic;AzteQ Industrial - ASA - Prusament (Prusa);AzteQ Industrial - PA - Nylon PA12 (Fiberlogy);AzteQ Industrial - PC Blend - Prusament (Prusa);AzteQ Industrial - PC - PolyMax (Polymaker);AzteQ Industrial - PC - PolyMax (Polymaker) @0.6 nozzle;AzteQ Industrial - PC/ABS - (Fillamentum);AzteQ Industrial - PC/ABS - (Fillamentum) @0.6 nozzle;AzteQ Industrial - PA - Nylon FX256 (Fillamentum);AzteQ Industrial - PA - Nylon FX256 (Fillamentum) @0.6 nozzle;AzteQ Industrial - ABS - Generic @0.8 nozzle;AzteQ Industrial - ABS - ExtraFill (Fillamentum) @0.8 nozzle;AzteQ Industrial - ASA - ExtraFill (Fillamentum) @0.8 nozzle;AzteQ Industrial - ASA - Prusament (Prusa) @0.8 nozzle;AzteQ Industrial - PC Blend - Prusament (Prusa) @0.8 nozzle +default_materials = AzteQ Industrial (Door Opened) - PLA - ExtraFill (Fillamentum);AzteQ Industrial (Door Opened) - PLA - Generic;AzteQ Industrial (PLA Printhead) - PLA - ExtraFill (Fillamentum);AzteQ Industrial - ABS - ExtraFill (Fillamentum);AzteQ Industrial - ABS - Generic;AzteQ Industrial - ASA - ExtraFill (Fillamentum);AzteQ Industrial - ASA - Generic;AzteQ Industrial - ASA - Prusament (Prusa Polymers);AzteQ Industrial - PA - Nylon PA12 (Fiberlogy);AzteQ Industrial - PC Blend - Prusament (Prusa Polymers);AzteQ Industrial - PC - PolyMax (Polymaker);AzteQ Industrial - PC - PolyMax (Polymaker) @0.6 nozzle;AzteQ Industrial - PC/ABS - (Fillamentum);AzteQ Industrial - PC/ABS - (Fillamentum) @0.6 nozzle;AzteQ Industrial - PA - Nylon FX256 (Fillamentum);AzteQ Industrial - PA - Nylon FX256 (Fillamentum) @0.6 nozzle;AzteQ Industrial - ABS - Generic @0.8 nozzle;AzteQ Industrial - ABS - ExtraFill (Fillamentum) @0.8 nozzle;AzteQ Industrial - ASA - ExtraFill (Fillamentum) @0.8 nozzle;AzteQ Industrial - ASA - Prusament (Prusa Polymers) @0.8 nozzle;AzteQ Industrial - PC Blend - Prusament (Prusa Polymers) @0.8 nozzle [printer_model:DQ2] name = DeltiQ 2 @@ -31,7 +31,7 @@ technology = FFF family = DeltiQ 2 bed_model = dq2_bed.stl bed_texture = dq2_bed_texture.svg -default_materials = DeltiQ - PLA - Generic;DeltiQ - PLA - ExtraFill (Fillamentum);DeltiQ - PETG - Generic;DeltiQ - PETG (Devil Design);DeltiQ - ABS - Generic;DeltiQ - ABS - ExtraFill (Fillamentum);DeltiQ - ASA - ExtraFill (Fillamentum);DeltiQ - ASA - ASA 275 (Spectrum);DeltiQ - CPE - HG100 (Fillamentum);DeltiQ - PLA - ExtraFill (Fillamentum) @0.25 nozzle;DeltiQ - PETG (Devil Design) @0.25 nozzle;DeltiQ - PLA - ExtraFill (Fillamentum) @0.6 nozzle;DeltiQ - PETG (Devil Design) @0.6 nozzle;DeltiQ - ABS - ExtraFill (Fillamentum) @0.6 nozzle;DeltiQ - ASA - ExtraFill (Fillamentum) @0.6 nozzle;DeltiQ - ASA - ASA 275 (Spectrum) @0.6 nozzle;DeltiQ - CPE - HG100 (Fillamentum) @0.6 nozzle;DeltiQ - PLA - ExtraFill (Fillamentum) @0.8 nozzle;DeltiQ - PETG (Devil Design) @0.8 nozzle;DeltiQ - PA - Nylon PA12 (Fiberlogy);DeltiQ - PA - Nylon CF15 Carbon (Fillamentum);DeltiQ - MoldLay (Wax-Alike) +default_materials = DeltiQ - PLA - Generic;DeltiQ - PLA - Prusament (Prusa Polymers); DeltiQ - PLA - ExtraFill (Fillamentum);DeltiQ - PETG - Generic;DeltiQ - PETG (Devil Design);DeltiQ - ABS - Generic;DeltiQ - ABS - ExtraFill (Fillamentum);DeltiQ - ASA - ExtraFill (Fillamentum);DeltiQ - ASA - ASA 275 (Spectrum);DeltiQ - CPE - HG100 (Fillamentum);DeltiQ - PLA - ExtraFill (Fillamentum) @0.25 nozzle;DeltiQ - PETG (Devil Design) @0.25 nozzle;DeltiQ - PLA - Prusament (Prusa Polymers) @0.6 nozzle;DeltiQ - PLA - ExtraFill (Fillamentum) @0.6 nozzle;DeltiQ - PETG (Devil Design) @0.6 nozzle;DeltiQ - ABS - ExtraFill (Fillamentum) @0.6 nozzle;DeltiQ - ASA - ExtraFill (Fillamentum) @0.6 nozzle;DeltiQ - ASA - ASA 275 (Spectrum) @0.6 nozzle;DeltiQ - CPE - HG100 (Fillamentum) @0.6 nozzle;DeltiQ - PLA - Prusament (Prusa Polymers) @0.8 nozzle;DeltiQ - PLA - ExtraFill (Fillamentum) @0.8 nozzle;DeltiQ - PETG (Devil Design) @0.8 nozzle;DeltiQ - PA - Nylon PA12 (Fiberlogy);DeltiQ - PA - Nylon CF15 Carbon (Fillamentum);DeltiQ - MoldLay (Wax-Alike) [printer_model:DQ2P] name = DeltiQ 2 Plus @@ -40,7 +40,7 @@ technology = FFF family = DeltiQ 2 bed_model = dq2_bed.stl bed_texture = dq2_bed_texture.svg -default_materials = DeltiQ - PLA - Generic;DeltiQ - PLA - ExtraFill (Fillamentum);DeltiQ - PETG - Generic;DeltiQ - PETG (Devil Design);DeltiQ - ABS - Generic;DeltiQ - ABS - ExtraFill (Fillamentum);DeltiQ - ASA - ExtraFill (Fillamentum);DeltiQ - ASA - ASA 275 (Spectrum);DeltiQ - CPE - HG100 (Fillamentum);DeltiQ - PLA - ExtraFill (Fillamentum) @0.25 nozzle;DeltiQ - PETG (Devil Design) @0.25 nozzle;DeltiQ - PLA - ExtraFill (Fillamentum) @0.6 nozzle;DeltiQ - PETG (Devil Design) @0.6 nozzle;DeltiQ - ABS - ExtraFill (Fillamentum) @0.6 nozzle;DeltiQ - ASA - ExtraFill (Fillamentum) @0.6 nozzle;DeltiQ - ASA - ASA 275 (Spectrum) @0.6 nozzle;DeltiQ - CPE - HG100 (Fillamentum) @0.6 nozzle;DeltiQ - PLA - ExtraFill (Fillamentum) @0.8 nozzle;DeltiQ - PETG (Devil Design) @0.8 nozzle;DeltiQ - PA - Nylon PA12 (Fiberlogy);DeltiQ - PA - Nylon CF15 Carbon (Fillamentum);DeltiQ - MoldLay (Wax-Alike) +default_materials = DeltiQ - PLA - Generic;DeltiQ - PLA - Prusament (Prusa Polymers); DeltiQ - PLA - ExtraFill (Fillamentum);DeltiQ - PETG - Generic;DeltiQ - PETG (Devil Design);DeltiQ - ABS - Generic;DeltiQ - ABS - ExtraFill (Fillamentum);DeltiQ - ASA - ExtraFill (Fillamentum);DeltiQ - ASA - ASA 275 (Spectrum);DeltiQ - CPE - HG100 (Fillamentum);DeltiQ - PLA - ExtraFill (Fillamentum) @0.25 nozzle;DeltiQ - PETG (Devil Design) @0.25 nozzle;DeltiQ - PLA - Prusament (Prusa Polymers) @0.6 nozzle;DeltiQ - PLA - ExtraFill (Fillamentum) @0.6 nozzle;DeltiQ - PETG (Devil Design) @0.6 nozzle;DeltiQ - ABS - ExtraFill (Fillamentum) @0.6 nozzle;DeltiQ - ASA - ExtraFill (Fillamentum) @0.6 nozzle;DeltiQ - ASA - ASA 275 (Spectrum) @0.6 nozzle;DeltiQ - CPE - HG100 (Fillamentum) @0.6 nozzle;DeltiQ - PLA - Prusament (Prusa Polymers) @0.8 nozzle;DeltiQ - PLA - ExtraFill (Fillamentum) @0.8 nozzle;DeltiQ - PETG (Devil Design) @0.8 nozzle;DeltiQ - PA - Nylon PA12 (Fiberlogy);DeltiQ - PA - Nylon CF15 Carbon (Fillamentum);DeltiQ - MoldLay (Wax-Alike) [printer_model:DQ2+FP2] name = DeltiQ 2 + FlexPrint 2 @@ -49,7 +49,7 @@ technology = FFF family = DeltiQ 2 bed_model = dq2_bed.stl bed_texture = dq2_bed_texture.svg -default_materials = DeltiQ FP2 - PLA - Generic;DeltiQ FP2 - PLA - ExtraFill (Fillamentum);DeltiQ FP2 - PETG - Generic;DeltiQ FP2 - PETG (Devil Design);DeltiQ FP2 - ABS - Generic;DeltiQ FP2 - ABS - ExtraFill (Fillamentum);DeltiQ FP2 - ASA - ExtraFill (Fillamentum);DeltiQ FP2 - CPE - HG100 (Fillamentum);DeltiQ FP2 - FLEX - Generic;DeltiQ FP2 - TPU 92A - FlexFill (Fillamentum);DeltiQ FP2 - TPU 98A - FlexFill (Fillamentum);DeltiQ FP2 - TPU 93A (SMARTFIL);DeltiQ FP2 - PEBA 90A - FlexFill (Fillamentum) +default_materials = DeltiQ FP2 - PLA - Generic;DeltiQ FP2 - PLA - Prusament (Prusa Polymers);DeltiQ FP2 - PLA - ExtraFill (Fillamentum);DeltiQ FP2 - PETG - Generic;DeltiQ FP2 - PETG (Devil Design);DeltiQ FP2 - ABS - Generic;DeltiQ FP2 - ABS - ExtraFill (Fillamentum);DeltiQ FP2 - ASA - ExtraFill (Fillamentum);DeltiQ FP2 - CPE - HG100 (Fillamentum);DeltiQ FP2 - FLEX - Generic;DeltiQ FP2 - TPU 92A - FlexFill (Fillamentum);DeltiQ FP2 - TPU 98A - FlexFill (Fillamentum);DeltiQ FP2 - TPU 93A (SMARTFIL);DeltiQ FP2 - PEBA 90A - FlexFill (Fillamentum) [printer_model:DQ2P+FP2] name = DeltiQ 2 Plus + FlexPrint 2 @@ -58,7 +58,7 @@ technology = FFF family = DeltiQ 2 bed_model = dq2_bed.stl bed_texture = dq2_bed_texture.svg -default_materials = DeltiQ FP2 - PLA - Generic;DeltiQ FP2 - PLA - ExtraFill (Fillamentum);DeltiQ FP2 - PETG - Generic;DeltiQ FP2 - PETG (Devil Design);DeltiQ FP2 - ABS - Generic;DeltiQ FP2 - ABS - ExtraFill (Fillamentum);DeltiQ FP2 - ASA - ExtraFill (Fillamentum);DeltiQ FP2 - CPE - HG100 (Fillamentum);DeltiQ FP2 - FLEX - Generic;DeltiQ FP2 - TPU 92A - FlexFill (Fillamentum);DeltiQ FP2 - TPU 98A - FlexFill (Fillamentum);DeltiQ FP2 - TPU 93A (SMARTFIL);DeltiQ FP2 - PEBA 90A - FlexFill (Fillamentum) +default_materials = DeltiQ FP2 - PLA - Generic;DeltiQ FP2 - PLA - Prusament (Prusa Polymers);DeltiQ FP2 - PLA - ExtraFill (Fillamentum);DeltiQ FP2 - PETG - Generic;DeltiQ FP2 - PETG (Devil Design);DeltiQ FP2 - ABS - Generic;DeltiQ FP2 - ABS - ExtraFill (Fillamentum);DeltiQ FP2 - ASA - ExtraFill (Fillamentum);DeltiQ FP2 - CPE - HG100 (Fillamentum);DeltiQ FP2 - FLEX - Generic;DeltiQ FP2 - TPU 92A - FlexFill (Fillamentum);DeltiQ FP2 - TPU 98A - FlexFill (Fillamentum);DeltiQ FP2 - TPU 93A (SMARTFIL);DeltiQ FP2 - PEBA 90A - FlexFill (Fillamentum) [printer_model:DQ2+FP] name = DeltiQ 2 + FlexPrint @@ -67,7 +67,7 @@ technology = FFF family = DeltiQ 2 bed_model = dq2_bed.stl bed_texture = dq2_bed_texture.svg -default_materials = DeltiQ FP - PLA - Generic;DeltiQ FP - PLA - ExtraFill (Fillamentum);DeltiQ FP - PETG - Generic;DeltiQ FP - PETG (Devil Design);DeltiQ FP - ABS - Generic;DeltiQ FP - ABS - ExtraFill (Fillamentum);DeltiQ FP - ASA - ExtraFill (Fillamentum);DeltiQ FP - CPE - HG100 (Fillamentum);DeltiQ FP - FLEX - Generic +default_materials = DeltiQ FP - PLA - Generic;DeltiQ FP - PLA - Prusament (Prusa Polymers);DeltiQ FP - PLA - ExtraFill (Fillamentum);DeltiQ FP - PETG - Generic;DeltiQ FP - PETG (Devil Design);DeltiQ FP - ABS - Generic;DeltiQ FP - ABS - ExtraFill (Fillamentum);DeltiQ FP - ASA - ExtraFill (Fillamentum);DeltiQ FP - CPE - HG100 (Fillamentum);DeltiQ FP - FLEX - Generic [printer_model:DQ2P+FP] name = DeltiQ 2 Plus + FlexPrint @@ -76,7 +76,7 @@ technology = FFF family = DeltiQ 2 bed_model = dq2_bed.stl bed_texture = dq2_bed_texture.svg -default_materials = DeltiQ FP - PLA - Generic;DeltiQ FP - PLA - ExtraFill (Fillamentum);DeltiQ FP - PETG - Generic;DeltiQ FP - PETG (Devil Design);DeltiQ FP - ABS - Generic;DeltiQ FP - ABS - ExtraFill (Fillamentum);DeltiQ FP - ASA - ExtraFill (Fillamentum);DeltiQ FP - CPE - HG100 (Fillamentum);DeltiQ FP - FLEX - Generic +default_materials = DeltiQ FP - PLA - Generic;DeltiQ FP - PLA - Prusament (Prusa Polymers);DeltiQ FP - PLA - ExtraFill (Fillamentum);DeltiQ FP - PETG - Generic;DeltiQ FP - PETG (Devil Design);DeltiQ FP - ABS - Generic;DeltiQ FP - ABS - ExtraFill (Fillamentum);DeltiQ FP - ASA - ExtraFill (Fillamentum);DeltiQ FP - CPE - HG100 (Fillamentum);DeltiQ FP - FLEX - Generic [printer_model:DQM] name = DeltiQ M @@ -158,7 +158,7 @@ min_skirt_length = 4 notes = only_retract_when_crossing_perimeters = 0 ooze_prevention = 0 -output_filename_format = {input_filename_base}_{printer_model}_{filament_type[0]}_{layer_height}mm_{print_time}_{timestamp}.gcode +output_filename_format = {input_filename_base}_{printer_model}_{filament_notes[0]}_{filament_type[0]}_{print_time}_{round(used_filament)}m_{year}{zdigits(month, 2)}{zdigits(day, 2)}-{hour}{minute}.gcode overhangs = 1 perimeter_acceleration = 1500 perimeter_extruder = 1 @@ -459,7 +459,7 @@ min_skirt_length = 4 notes = only_retract_when_crossing_perimeters = 0 ooze_prevention = 0 -output_filename_format = {input_filename_base}_{printer_model}_{filament_type[0]}_{layer_height}mm_{print_time}_{timestamp}.gcode +output_filename_format = {input_filename_base}_{printer_model}_{filament_notes[0]}_{filament_type[0]}_{print_time}_{round(used_filament)}m_{year}{zdigits(month, 2)}{zdigits(day, 2)}-{hour}{minute}.gcode overhangs = 1 perimeter_acceleration = 1500 perimeter_extruder = 1 @@ -681,7 +681,6 @@ extrusion_multiplier = 1 filament_colour = #FF0000 filament_diameter = 1.75 filament_minimal_purge_on_wipe_tower = 15 -filament_notes = "" filament_ramming_parameters = "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" filament_settings_id = "" filament_soluble = 0 @@ -691,6 +690,7 @@ end_filament_gcode = "; FILAMENT_END_GCODE" filament_cost = 0 filament_spool_weight = 250 filament_vendor = Generic +filament_notes = "LP-CU" # DeltiQ PLA filaments # @@ -719,6 +719,59 @@ min_print_speed = 10 slowdown_below_layer_time = 4 temperature = 215 +[filament:DeltiQ - PLA - Prusament (Prusa Polymers)] +inherits = DeltiQ - PLA - Generic +bed_temperature = 55 +bridge_fan_speed = 100 +cooling = 1 +extrusion_multiplier = 1 +fan_always_on = 1 +fan_below_layer_time = 100 +filament_cost = 550 +filament_density = 1.24 +filament_deretract_speed = nil +filament_max_volumetric_speed = 8 +filament_retract_before_travel = 2 +filament_retract_before_wipe = 90% +filament_retract_layer_change = 1 +filament_retract_length = 4 +filament_retract_lift = 0.2 +filament_retract_lift_above = nil +filament_retract_lift_below = nil +filament_retract_restart_extra = nil +filament_retract_speed = 30 +filament_spool_weight = 201 +filament_vendor = Prusa Polymers +filament_wipe = 1 +first_layer_bed_temperature = 55 +first_layer_temperature = 215 +full_fan_speed_layer = 0 +max_fan_speed = 100 +min_fan_speed = 100 +min_print_speed = 10 +slowdown_below_layer_time = 4 +temperature = 215 + +[filament:DeltiQ - PLA - Prusament (Prusa Polymers) @0.6 nozzle] +inherits = DeltiQ - PLA - Prusament (Prusa Polymers) +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_DQ.*/ and !(printer_notes=~/.*FLEXPRINT.*/) and nozzle_diameter[0]==0.6 +filament_max_volumetric_speed = 15 +filament_notes = "BN" + +[filament:DeltiQ - PLA - Prusament (Prusa Polymers) @0.8 nozzle] +inherits = DeltiQ - PLA - Prusament (Prusa Polymers) +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_FAMILY_DQ.*/ and !(printer_notes=~/.*FLEXPRINT.*/) and nozzle_diameter[0]==0.8 +disable_fan_first_layers = 1 +filament_max_volumetric_speed = 40 +first_layer_temperature = 230 +slowdown_below_layer_time = 8 +temperature = 230 +filament_retract_layer_change = 0 +filament_retract_length = 4.1 +filament_retract_speed = 45 +filament_deretract_speed = 25 +filament_notes = "ZL" + [filament:DeltiQ - PLA - ExtraFill (Fillamentum)] inherits = DeltiQ - PLA - Generic filament_cost = 24.27 @@ -729,11 +782,13 @@ filament_vendor = Fillamentum [filament:DeltiQ - PLA - ExtraFill (Fillamentum) @0.25 nozzle] inherits = DeltiQ - PLA - ExtraFill (Fillamentum) compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_FAMILY_DQ.*/ and !(printer_notes=~/.*FLEXPRINT.*/) and nozzle_diameter[0]==0.25 +filament_notes = "BN" [filament:DeltiQ - PLA - ExtraFill (Fillamentum) @0.6 nozzle] inherits = DeltiQ - PLA - ExtraFill (Fillamentum) compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_DQ.*/ and !(printer_notes=~/.*FLEXPRINT.*/) and nozzle_diameter[0]==0.6 filament_max_volumetric_speed = 15 +filament_notes = "BN" [filament:DeltiQ - PLA - ExtraFill (Fillamentum) @0.8 nozzle] inherits = DeltiQ - PLA - ExtraFill (Fillamentum) @@ -747,6 +802,7 @@ filament_retract_layer_change = 0 filament_retract_length = 4.1 filament_retract_speed = 45 filament_deretract_speed = 25 +filament_notes = "ZL" [filament:DeltiQ FP - PLA - Generic] inherits = DeltiQ - PLA - Generic @@ -767,6 +823,39 @@ compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and p filament_retract_length = 1.2 filament_retract_speed = 28 +[filament:DeltiQ FP2 - PLA - Prusament (Prusa Polymers)] +inherits = DeltiQ FP2 - PLA - Generic +bed_temperature = 55 +bridge_fan_speed = 100 +cooling = 1 +extrusion_multiplier = 1 +fan_always_on = 1 +fan_below_layer_time = 100 +filament_cost = 550 +filament_density = 1.24 +filament_deretract_speed = nil +filament_max_volumetric_speed = 8 +filament_retract_before_travel = 2 +filament_retract_before_wipe = 90% +filament_retract_layer_change = 1 +filament_retract_length = 1.2 +filament_retract_lift = 0.2 +filament_retract_lift_above = nil +filament_retract_lift_below = nil +filament_retract_restart_extra = nil +filament_retract_speed = 28 +filament_spool_weight = 201 +filament_vendor = Prusa Polymers +filament_wipe = 1 +first_layer_bed_temperature = 55 +first_layer_temperature = 215 +full_fan_speed_layer = 0 +max_fan_speed = 100 +min_fan_speed = 100 +min_print_speed = 10 +slowdown_below_layer_time = 4 +temperature = 215 + [filament:DeltiQ FP2 - PLA - ExtraFill (Fillamentum)] inherits = DeltiQ FP2 - PLA - Generic filament_cost = 24.27 @@ -817,11 +906,13 @@ temperature = 220 max_fan_speed = 65 min_fan_speed = 40 bridge_fan_speed = 100 +filament_notes = "JW" [filament:DeltiQ - PETG (Devil Design) @0.6 nozzle] inherits = DeltiQ - PETG (Devil Design) compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_DQ.*/ and !(printer_notes=~/.*FLEXPRINT.*/) and nozzle_diameter[0]==0.6 filament_max_volumetric_speed = 15 +filament_notes = "BN" [filament:DeltiQ - PETG (Devil Design) @0.8 nozzle] inherits = DeltiQ - PETG (Devil Design) @@ -836,6 +927,7 @@ filament_retract_speed = 45 filament_deretract_speed = 25 filament_retract_before_wipe = 80% filament_wipe = 1 +filament_notes = "ZL" [filament:DeltiQ FP - PETG - Generic] inherits = DeltiQ - PETG - Generic @@ -902,6 +994,7 @@ filament_vendor = Fillamentum inherits = DeltiQ - ABS - ExtraFill (Fillamentum) compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_DQ.*/ and !(printer_notes=~/.*FLEXPRINT.*/) and nozzle_diameter[0]==0.6 filament_max_volumetric_speed = 15 +filament_notes = "BN" [filament:DeltiQ FP - ABS - Generic] inherits = DeltiQ - ABS - Generic @@ -946,6 +1039,7 @@ temperature = 265 inherits = DeltiQ - ASA - ExtraFill (Fillamentum) compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_DQ.*/ and !(printer_notes=~/.*FLEXPRINT.*/) and nozzle_diameter[0]==0.6 filament_max_volumetric_speed = 15 +filament_notes = "BN" [filament:DeltiQ FP - ASA - ExtraFill (Fillamentum)] inherits = DeltiQ - ASA - ExtraFill (Fillamentum) @@ -989,7 +1083,7 @@ temperature = 230 inherits = DeltiQ - ASA - ASA 275 (Spectrum) compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_DQ.*/ and !(printer_notes=~/.*FLEXPRINT.*/) and nozzle_diameter[0]==0.6 filament_max_volumetric_speed = 15 - +filament_notes = "BN" # DeltiQ CPE filaments # @@ -1026,6 +1120,7 @@ temperature = 260 inherits = DeltiQ - CPE - HG100 (Fillamentum) compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_DQ.*/ and !(printer_notes=~/.*FLEXPRINT.*/) and nozzle_diameter[0]==0.6 filament_max_volumetric_speed = 15 +filament_notes = "BN" [filament:DeltiQ FP - CPE - HG100 (Fillamentum)] inherits = DeltiQ - CPE - HG100 (Fillamentum) @@ -1250,6 +1345,7 @@ filament_vendor = Wax-Alike [filament:*AzteQ common*] inherits = *DeltiQ common* compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_AQI.*/ and nozzle_diameter[0]==0.4 +filament_notes = "CU" # AzteQ Industrial filaments # @@ -1294,6 +1390,7 @@ temperature = 210 inherits = AzteQ Industrial (Door Opened) - PLA - Generic compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_AQI.*/ and nozzle_diameter[0]==0.6 filament_max_volumetric_speed = 15 +filament_notes = "BN" [filament:AzteQ Industrial (Door Opened) - PLA - ExtraFill (Fillamentum)] inherits = AzteQ Industrial (Door Opened) - PLA - Generic @@ -1306,6 +1403,7 @@ filament_spool_weight = 229 inherits = AzteQ Industrial (Door Opened) - PLA - ExtraFill (Fillamentum) compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_AQI.*/ and nozzle_diameter[0]==0.6 filament_max_volumetric_speed = 15 +filament_notes = "BN" [filament:AzteQ Industrial (PLA Printhead) - PLA - ExtraFill (Fillamentum)] inherits = *AzteQ common* @@ -1349,6 +1447,7 @@ temperature = 215 inherits = AzteQ Industrial (PLA Printhead) - PLA - ExtraFill (Fillamentum) compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_AQI.*/ and nozzle_diameter[0]==0.6 filament_max_volumetric_speed = 15 +filament_notes = "BN" [filament:AzteQ Industrial - ABS - Generic] inherits = *AzteQ common* @@ -1392,6 +1491,7 @@ temperature = 255 inherits = AzteQ Industrial - ABS - Generic compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_AQI.*/ and nozzle_diameter[0]==0.6 filament_max_volumetric_speed = 15 +filament_notes = "BN" [filament:AzteQ Industrial - ABS - Generic @0.8 nozzle] inherits = AzteQ Industrial - ABS - Generic @@ -1405,6 +1505,7 @@ min_fan_speed = 50 filament_retract_length = 6.1 filament_max_volumetric_speed = 0 start_filament_gcode = "; FILAMENT_START_GCODE\nM191 S75 ; Set and wait - chamber temperature" +filament_notes = "ZL" [filament:AzteQ Industrial - ABS - ExtraFill (Fillamentum)] inherits = AzteQ Industrial - ABS - Generic @@ -1416,11 +1517,13 @@ filament_spool_weight = 229 [filament:AzteQ Industrial - ABS - ExtraFill (Fillamentum) @0.6 nozzle] inherits = AzteQ Industrial - ABS - ExtraFill (Fillamentum) compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_AQI.*/ and nozzle_diameter[0]==0.6 +filament_notes = "BN" [filament:AzteQ Industrial - ABS - ExtraFill (Fillamentum) @0.8 nozzle] inherits = AzteQ Industrial - ABS - ExtraFill (Fillamentum) compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_AQI.*/ and nozzle_diameter[0]==0.8 extrusion_multiplier = 0.95 +filament_notes = "ZL" [filament:AzteQ Industrial - PC/ABS - (Fillamentum)] inherits = AzteQ Industrial - ABS - Generic @@ -1443,6 +1546,7 @@ filament_notes = "S180 ; Probing temperature" inherits = AzteQ Industrial - PC/ABS - (Fillamentum) compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_AQI.*/ and nozzle_diameter[0]==0.6 filament_max_volumetric_speed = 15 +filament_notes = "BN" [filament:AzteQ Industrial - PC - PolyMax (Polymaker)] inherits = AzteQ Industrial - ABS - Generic @@ -1464,6 +1568,7 @@ filament_notes = "S180 ; Probing temperature" inherits = AzteQ Industrial - PC - PolyMax (Polymaker) compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_AQI.*/ and nozzle_diameter[0]==0.6 filament_max_volumetric_speed = 15 +filament_notes = "BN" [filament:AzteQ Industrial - ASA - Generic] inherits = *AzteQ common* @@ -1504,6 +1609,7 @@ temperature = 265 inherits = AzteQ Industrial - ASA - Generic compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_AQI.*/ and nozzle_diameter[0]==0.6 filament_max_volumetric_speed = 15 +filament_notes = "BN" [filament:AzteQ Industrial - ASA - ExtraFill (Fillamentum)] inherits = AzteQ Industrial - ASA - Generic @@ -1520,6 +1626,7 @@ filament_density = 1.07 inherits = AzteQ Industrial - ASA - ExtraFill (Fillamentum) compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_AQI.*/ and nozzle_diameter[0]==0.6 filament_max_volumetric_speed = 15 +filament_notes = "BN" [filament:AzteQ Industrial - ASA - ExtraFill (Fillamentum) @0.8 nozzle] inherits = AzteQ Industrial - ASA - ExtraFill (Fillamentum) @@ -1533,27 +1640,29 @@ max_fan_speed = 100 min_fan_speed = 80 filament_retract_length = 6.1 filament_max_volumetric_speed = 0 +filament_notes = "ZL" -[filament:AzteQ Industrial - ASA - Prusament (Prusa)] +[filament:AzteQ Industrial - ASA - Prusament (Prusa Polymers)] inherits = AzteQ Industrial - ASA - Generic filament_cost = 29.16 filament_density = 1.07 filament_spool_weight = 201 -filament_vendor = Prusa +filament_vendor = Prusa Polymers first_layer_temperature = 260 max_fan_speed = 70 min_fan_speed = 70 start_filament_gcode = "; FILAMENT_START_GCODE\nM191 S50 ; Set and wait - chamber temperature" temperature = 260 -[filament:AzteQ Industrial - ASA - Prusament (Prusa) @0.6 nozzle] -inherits = AzteQ Industrial - ASA - Prusament (Prusa) +[filament:AzteQ Industrial - ASA - Prusament (Prusa Polymers) @0.6 nozzle] +inherits = AzteQ Industrial - ASA - Prusament (Prusa Polymers) compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_AQI.*/ and nozzle_diameter[0]==0.6 filament_max_volumetric_speed = 15 +filament_notes = "BN" -[filament:AzteQ Industrial - ASA - Prusament (Prusa) @0.8 nozzle] -inherits = AzteQ Industrial - ASA - Prusament (Prusa) +[filament:AzteQ Industrial - ASA - Prusament (Prusa Polymers) @0.8 nozzle] +inherits = AzteQ Industrial - ASA - Prusament (Prusa Polymers) compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_AQI.*/ and nozzle_diameter[0]==0.8 first_layer_bed_temperature = 100 bed_temperature = 100 @@ -1564,6 +1673,7 @@ max_fan_speed = 80 min_fan_speed = 50 filament_retract_length = 4.1 filament_max_volumetric_speed = 0 +filament_notes = "ZL" [filament:AzteQ Industrial - PA - Nylon PA12 (Fiberlogy)] @@ -1611,6 +1721,7 @@ temperature = 255 inherits = AzteQ Industrial - PA - Nylon PA12 (Fiberlogy) compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_AQI.*/ and nozzle_diameter[0]==0.6 filament_max_volumetric_speed = 15 +filament_notes = "BN" [filament:AzteQ Industrial - PA - Nylon FX256 (Fillamentum)] inherits = *AzteQ common* @@ -1657,8 +1768,9 @@ temperature = 255 inherits = AzteQ Industrial - PA - Nylon FX256 (Fillamentum) compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_AQI.*/ and nozzle_diameter[0]==0.6 filament_max_volumetric_speed = 15 +filament_notes = "BN" -[filament:AzteQ Industrial - PC Blend - Prusament (Prusa)] +[filament:AzteQ Industrial - PC Blend - Prusament (Prusa Polymers)] inherits = *AzteQ common* bed_temperature = 100 bridge_fan_speed = 75 @@ -1683,7 +1795,7 @@ filament_retract_restart_extra = nil filament_retract_speed = 25 filament_soluble = 0 filament_type = PC -filament_vendor = Prusa +filament_vendor = Prusa Polymers filament_wipe = 1 first_layer_bed_temperature = 100 first_layer_temperature = 270 @@ -1696,13 +1808,14 @@ start_filament_gcode = "; FILAMENT_START_GCODE\nM191 S75 ; Set and wait - chambe temperature = 270 filament_notes = "S180 ; Probing temperature" -[filament:AzteQ Industrial - PC Blend - Prusament (Prusa) @0.6 nozzle] -inherits = AzteQ Industrial - PC Blend - Prusament (Prusa) +[filament:AzteQ Industrial - PC Blend - Prusament (Prusa Polymers) @0.6 nozzle] +inherits = AzteQ Industrial - PC Blend - Prusament (Prusa Polymers) compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_AQI.*/ and nozzle_diameter[0]==0.6 filament_max_volumetric_speed = 15 +filament_notes = "BN" -[filament:AzteQ Industrial - PC Blend - Prusament (Prusa) @0.8 nozzle] -inherits = AzteQ Industrial - PC Blend - Prusament (Prusa) +[filament:AzteQ Industrial - PC Blend - Prusament (Prusa Polymers) @0.8 nozzle] +inherits = AzteQ Industrial - PC Blend - Prusament (Prusa Polymers) compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_MODEL_AQI.*/ and nozzle_diameter[0]==0.8 first_layer_bed_temperature = 100 bed_temperature = 100 @@ -1713,6 +1826,7 @@ max_fan_speed = 60 min_fan_speed = 60 filament_retract_length = 7.1 filament_max_volumetric_speed = 0 +filament_notes = "ZL" # DeltiQ Printer # @@ -1796,12 +1910,14 @@ retract_speed = 35 [printer:*DeltiQ 2*] inherits = *DeltiQ* +default_filament_profile = "DeltiQ - PLA - Prusament (Prusa Polymers)" +default_print_profile = DeltiQ 0.20mm Normal before_layer_gcode = ; BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n end_gcode = ; END_GCODE\n\nM140 S0 ; Turn off bed\n\nG28 ; Home\n\nM104 S0 ; Turn off extruder\nM107 ; Turn off fan\n\nG90 ; Absolute positioning\nM220 S100 ; Feedmultiply back to 100percent\n\nM84 S5; Disable motors gcode_flavor = reprapfirmware layer_gcode = ; AFTER_LAYER_CHANGE\n;[layer_z] -pause_print_gcode = M0 -start_gcode = ; START_GCODE\n\nM220 S100 ; Set feedmultiply back to 100percent\n\nT0 ; Select Titan extruder\n\nG90 ; Absolute positioning\nM83; Relative Extruder\n\nM190 S[first_layer_bed_temperature] ; Set and wait - bed temperature\nM104 S[first_layer_temperature]\n\nG28 ; Home all axes\nG32 ; Probe Z and calculate Z plane\n\nG29 ; Mesh bed probe\n\nG1009 ; Go ARC to purge end\n\nG92 E0 ; Zero extruder +pause_print_gcode = M25 +start_gcode = ; START_GCODE\n\nM220 S100 ; Set feedmultiply back to 100percent\n\nT0 ; Select Titan extruder\n\nG90 ; Absolute positioning\nM83; Relative Extruder\n\nG28 ; Home all axes\n\nM190 S[first_layer_bed_temperature] ; Set and wait - bed temperature\nM104 S[first_layer_temperature]\n\nG28 ; Home all axes\nG32 ; Probe Z and calculate Z plane\n\nG29 ; Mesh bed probe\n\nG1009 ; Go ARC to purge end\n\nG92 E0 ; Zero extruder printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_TRILAB\nPRINTER_FAMILY_DQ\nPRINTER_MODEL_DQ2 [printer:DeltiQ 2] @@ -1825,7 +1941,7 @@ printer_variant = 0.6 max_layer_height = 0.4 min_layer_height = 0.2 nozzle_diameter = 0.6 -default_filament_profile = "DeltiQ - PLA - ExtraFill (Fillamentum) @0.6 nozzle" +default_filament_profile = "DeltiQ - PLA - Prusament (Prusa Polymers) @0.6 nozzle" default_print_profile = DeltiQ 0.30mm Normal @0.6 nozzle [printer:DeltiQ 2 - 0.8 nozzle] @@ -1834,7 +1950,7 @@ printer_variant = 0.8 max_layer_height = 0.6 min_layer_height = 0.3 nozzle_diameter = 0.8 -default_filament_profile = "DeltiQ - PLA - ExtraFill (Fillamentum) @0.8 nozzle" +default_filament_profile = "DeltiQ - PLA - Prusament (Prusa Polymers) @0.8 nozzle" default_print_profile = DeltiQ 0.40mm Normal @0.8 nozzle [printer:DeltiQ 2 Plus] @@ -1858,7 +1974,7 @@ printer_variant = 0.6 max_layer_height = 0.4 min_layer_height = 0.2 nozzle_diameter = 0.6 -default_filament_profile = "DeltiQ - PLA - ExtraFill (Fillamentum) @0.6 nozzle" +default_filament_profile = "DeltiQ - PLA - Prusament (Prusa Polymers) @0.6 nozzle" default_print_profile = DeltiQ 0.30mm Normal @0.6 nozzle [printer:DeltiQ 2 Plus - 0.8 nozzle] @@ -1867,12 +1983,12 @@ printer_variant = 0.8 max_layer_height = 0.6 min_layer_height = 0.3 nozzle_diameter = 0.8 -default_filament_profile = "DeltiQ - PLA - ExtraFill (Fillamentum) @0.8 nozzle" +default_filament_profile = "DeltiQ - PLA - Prusament (Prusa Polymers) @0.8 nozzle" default_print_profile = DeltiQ 0.40mm Normal @0.8 nozzle [printer:*DeltiQ 2 FlexPrint*] inherits = *DeltiQ 2* -start_gcode = ; START_GCODE\n\nM220 S100 ; Set feedmultiply back to 100percent\n\nT1 ; Select FlexPrint extruder\n\nG90 ; Absolute positioning\nM83; Relative Extruder\n\nM190 S[first_layer_bed_temperature] ; Set and wait - bed temperature\nM104 S[first_layer_temperature]\n\nG28 ; Home all axes\nG32 ; Probe Z and calculate Z plane\n\nG29 ; Mesh bed probe\n\nG1009 ; Go ARC to purge end\n\nG92 E0 ; Zero extruder +start_gcode = ; START_GCODE\n\nM220 S100 ; Set feedmultiply back to 100percent\n\nT1 ; Select FlexPrint extruder\n\nG90 ; Absolute positioning\nM83; Relative Extruder\n\nG28 ; Home all axes\n\nM190 S[first_layer_bed_temperature] ; Set and wait - bed temperature\nM104 S[first_layer_temperature]\n\nG28 ; Home all axes\nG32 ; Probe Z and calculate Z plane\n\nG29 ; Mesh bed probe\n\nG1009 ; Go ARC to purge end\n\nG92 E0 ; Zero extruder default_print_profile = DeltiQ 0.20mm FLEX default_filament_profile = "DeltiQ FP2 - FLEX - Generic" retract_length = 0.7 @@ -1929,7 +2045,7 @@ retract_lift_below = 0 retract_restart_extra = 0 retract_restart_extra_toolchange = 0 retract_speed = 30 -start_gcode = ; START_GCODE\nT0\nM220 S100 ; Set feedmultiply back to 100 percent\nG90 ; Absolute positioning for motion\nM83 ; Relative extruder\nM107 ; Layer fan off\n\nM140 S[first_layer_bed_temperature] ; Set and continue - bed temperature\nM104 S150 ; Set and continue - hotend probing temperature\n[start_filament_gcode]\nM190 S[first_layer_bed_temperature] ; Set and wait - bed temperature\nM109 [filament_notes] ; Set and wait for material specific hotend probing temperature\n\nG28 ; Home all axes\nG32 ; Probe Z and calculate Z plane\nG29 ; Mesh bed probe\n\nM104 S[first_layer_temperature] ; Set and continue - printing temperature\n\nG1009 ; Purge hotend\nG92 E0 ; Zero extruder +start_gcode = ; START_GCODE\nT0\nM220 S100 ; Set feedmultiply back to 100 percent\nG90 ; Absolute positioning for motion\nM83 ; Relative extruder\nM107 ; Layer fan off\n\nG28 ; Home all axes\n\nM140 S[first_layer_bed_temperature] ; Set and continue - bed temperature\nM104 S150 ; Set and continue - hotend probing temperature\n[start_filament_gcode]\nM190 S[first_layer_bed_temperature] ; Set and wait - bed temperature\nM109 [filament_notes] ; Set and wait for material specific hotend probing temperature\n\nG28 ; Home all axes\nG32 ; Probe Z and calculate Z plane\nG29 ; Mesh bed probe\n\nM104 S[first_layer_temperature] ; Set and continue - printing temperature\n\nG1009 ; Purge hotend\nG92 E0 ; Zero extruder wipe = 1 [printer:AzteQ Industrial] @@ -1937,7 +2053,7 @@ inherits = *AzteQ* printer_model = AQI printer_variant = 0.4 max_print_height = 400 -default_filament_profile = "AzteQ Industrial - ABS - ExtraFill (Fillamentum)" +default_filament_profile = "AzteQ Industrial - ASA - Prusament (Prusa Polymers)" default_print_profile = AzteQ Industrial 0.30mm Normal [printer:AzteQ Industrial - 0.6 nozzle] @@ -1946,7 +2062,7 @@ printer_variant = 0.6 max_layer_height = 0.4 min_layer_height = 0.2 nozzle_diameter = 0.6 -default_filament_profile = "AzteQ Industrial - ABS - ExtraFill (Fillamentum) @0.6 nozzle" +default_filament_profile = "AzteQ Industrial - ASA - Prusament (Prusa Polymers) @0.6 nozzle" default_print_profile = AzteQ Industrial 0.30mm Normal @0.6 nozzle [printer:AzteQ Industrial - 0.8 nozzle] @@ -1955,10 +2071,10 @@ printer_variant = 0.8 max_layer_height = 0.6 min_layer_height = 0.2 nozzle_diameter = 0.8 -default_filament_profile = "AzteQ Industrial - ABS - ExtraFill (Fillamentum) @0.8 nozzle" +default_filament_profile = "AzteQ Industrial - ASA - Prusament (Prusa Polymers) @0.8 nozzle" default_print_profile = AzteQ Industrial 0.40mm Normal @0.8 nozzle [presets] print = DeltiQ 0.20mm Normal printer = DeltiQ 2 -filament = DeltiQ - PLA - Generic \ No newline at end of file +filament = DeltiQ - PLA - Prusament (Prusa Polymers) \ No newline at end of file diff --git a/src/libslic3r/AABBTreeIndirect.hpp b/src/libslic3r/AABBTreeIndirect.hpp index 3db74b8b91..b4b74ef138 100644 --- a/src/libslic3r/AABBTreeIndirect.hpp +++ b/src/libslic3r/AABBTreeIndirect.hpp @@ -519,7 +519,7 @@ namespace detail { const VectorType origin; inline VectorType closest_point_to_origin(size_t primitive_index, - ScalarType& squared_distance){ + ScalarType& squared_distance) const { const auto &triangle = this->faces[primitive_index]; VectorType closest_point = closest_point_to_triangle(origin, this->vertices[triangle(0)].template cast(), @@ -613,6 +613,37 @@ namespace detail { return up_sqr_d; } + template + static inline void indexed_primitives_within_distance_squared_recurisve(const IndexedPrimitivesDistancerType &distancer, + size_t node_idx, + Scalar squared_distance_limit, + std::vector &found_primitives_indices) + { + const auto &node = distancer.tree.node(node_idx); + assert(node.is_valid()); + if (node.is_leaf()) { + Scalar sqr_dist; + distancer.closest_point_to_origin(node.idx, sqr_dist); + if (sqr_dist < squared_distance_limit) { found_primitives_indices.push_back(node.idx); } + } else { + size_t left_node_idx = node_idx * 2 + 1; + size_t right_node_idx = left_node_idx + 1; + const auto &node_left = distancer.tree.node(left_node_idx); + const auto &node_right = distancer.tree.node(right_node_idx); + assert(node_left.is_valid()); + assert(node_right.is_valid()); + + if (node_left.bbox.squaredExteriorDistance(distancer.origin) < squared_distance_limit) { + indexed_primitives_within_distance_squared_recurisve(distancer, left_node_idx, squared_distance_limit, + found_primitives_indices); + } + if (node_right.bbox.squaredExteriorDistance(distancer.origin) < squared_distance_limit) { + indexed_primitives_within_distance_squared_recurisve(distancer, right_node_idx, squared_distance_limit, + found_primitives_indices); + } + } + } + } // namespace detail // Build a balanced AABB Tree over an indexed triangles set, balancing the tree @@ -799,6 +830,33 @@ inline bool is_any_triangle_in_radius( return hit_point.allFinite(); } +// Returns all triangles within the given radius limit +template +inline std::vector all_triangles_in_radius( + // Indexed triangle set - 3D vertices. + const std::vector &vertices, + // Indexed triangle set - triangular faces, references to vertices. + const std::vector &faces, + // AABBTreeIndirect::Tree over vertices & faces, bounding boxes built with the accuracy of vertices. + const TreeType &tree, + // Point to which the distances on the indexed triangle set is searched for. + const VectorType &point, + //Square of maximum distance in which triangles are searched for + typename VectorType::Scalar max_distance_squared) +{ + auto distancer = detail::IndexedTriangleSetDistancer + { vertices, faces, tree, point }; + + if(tree.empty()) + { + return {}; + } + + std::vector found_triangles{}; + detail::indexed_primitives_within_distance_squared_recurisve(distancer, size_t(0), max_distance_squared, found_triangles); + return found_triangles; +} + // Traverse the tree and return the index of an entity whose bounding box // contains a given point. Returns size_t(-1) when the point is outside. diff --git a/src/libslic3r/AABBTreeLines.hpp b/src/libslic3r/AABBTreeLines.hpp index 39f828b558..8432feda74 100644 --- a/src/libslic3r/AABBTreeLines.hpp +++ b/src/libslic3r/AABBTreeLines.hpp @@ -1,8 +1,12 @@ #ifndef SRC_LIBSLIC3R_AABBTREELINES_HPP_ #define SRC_LIBSLIC3R_AABBTREELINES_HPP_ +#include "Utils.hpp" +#include "libslic3r.h" #include "libslic3r/AABBTreeIndirect.hpp" #include "libslic3r/Line.hpp" +#include +#include namespace Slic3r { @@ -23,17 +27,17 @@ struct IndexedLinesDistancer { const VectorType origin; inline VectorType closest_point_to_origin(size_t primitive_index, - ScalarType &squared_distance) { - VectorType nearest_point; + ScalarType &squared_distance) const { + Vec nearest_point; const LineType &line = lines[primitive_index]; - squared_distance = line_alg::distance_to_squared(line, origin, &nearest_point); - return nearest_point; + squared_distance = line_alg::distance_to_squared(line, origin.template cast(), &nearest_point); + return nearest_point.template cast(); } }; } -// Build a balanced AABB Tree over a vector of float lines, balancing the tree +// Build a balanced AABB Tree over a vector of lines, balancing the tree // on centroids of the lines. // Epsilon is applied to the bounding boxes of the AABB Tree to cope with numeric inaccuracies // during tree traversal. @@ -41,7 +45,7 @@ template inline AABBTreeIndirect::Tree<2, typename LineType::Scalar> build_aabb_tree_over_indexed_lines( const std::vector &lines, //FIXME do we want to apply an epsilon? - const float eps = 0) + const double eps = 0) { using TreeType = AABBTreeIndirect::Tree<2, typename LineType::Scalar>; // using CoordType = typename TreeType::CoordType; @@ -87,24 +91,99 @@ inline AABBTreeIndirect::Tree<2, typename LineType::Scalar> build_aabb_tree_over // Finding a closest line, its closest point and squared distance to the closest point // Returns squared distance to the closest point or -1 if the input is empty. template -inline typename VectorType::Scalar squared_distance_to_indexed_lines( - const std::vector &lines, - const TreeType &tree, - const VectorType &point, - size_t &hit_idx_out, - Eigen::PlainObjectBase &hit_point_out) - { - using Scalar = typename VectorType::Scalar; - auto distancer = detail::IndexedLinesDistancer - { lines, tree, point }; +inline typename VectorType::Scalar squared_distance_to_indexed_lines(const std::vector &lines, + const TreeType &tree, + const VectorType &point, + size_t &hit_idx_out, + Eigen::PlainObjectBase &hit_point_out) +{ + using Scalar = typename VectorType::Scalar; + auto distancer = detail::IndexedLinesDistancer{lines, tree, point}; return tree.empty() ? - Scalar(-1) : - AABBTreeIndirect::detail::squared_distance_to_indexed_primitives_recursive(distancer, size_t(0), Scalar(0), - std::numeric_limits::infinity(), hit_idx_out, hit_point_out); + Scalar(-1) : + AABBTreeIndirect::detail::squared_distance_to_indexed_primitives_recursive(distancer, size_t(0), Scalar(0), + std::numeric_limits::infinity(), + hit_idx_out, hit_point_out); } +// Returns all lines within the given radius limit +template +inline std::vector all_lines_in_radius(const std::vector &lines, + const TreeType &tree, + const VectorType &point, + typename VectorType::Scalar max_distance_squared) +{ + auto distancer = detail::IndexedLinesDistancer{lines, tree, point}; + + if (tree.empty()) { return {}; } + + std::vector found_lines{}; + AABBTreeIndirect::detail::indexed_primitives_within_distance_squared_recurisve(distancer, size_t(0), max_distance_squared, found_lines); + return found_lines; } -} +template class LinesDistancer +{ +private: + std::vector lines; + using Scalar = typename LineType::Scalar; + using Floating = typename std::conditional::value, Scalar, double>::type; + AABBTreeIndirect::Tree<2, Scalar> tree; + +public: + explicit LinesDistancer(const std::vector &lines) : lines(lines) + { + tree = AABBTreeLines::build_aabb_tree_over_indexed_lines(this->lines); + } + + // negative sign means inside + std::tuple> signed_distance_from_lines_extra(const Vec<2, Scalar> &point) const + { + size_t nearest_line_index_out = size_t(-1); + Vec<2, Floating> nearest_point_out = Vec<2, Floating>::Zero(); + Vec<2, Floating> p = point.template cast(); + auto distance = AABBTreeLines::squared_distance_to_indexed_lines(lines, tree, p, nearest_line_index_out, nearest_point_out); + + if (distance < 0) { return {std::numeric_limits::infinity(), nearest_line_index_out, nearest_point_out}; } + distance = sqrt(distance); + const LineType &line = lines[nearest_line_index_out]; + Vec<2, Floating> v1 = (line.b - line.a).template cast(); + Vec<2, Floating> v2 = (point - line.a).template cast(); + auto d1 = (v1.x() * v2.y()) - (v1.y() * v2.x()); + + LineType second_line = line; + if ((line.a.template cast() - nearest_point_out).squaredNorm() < SCALED_EPSILON) { + second_line = lines[prev_idx_modulo(nearest_line_index_out, lines.size())]; + } else { + second_line = lines[next_idx_modulo(nearest_line_index_out, lines.size())]; + } + v1 = (second_line.b - second_line.a).template cast(); + v2 = (point - second_line.a).template cast(); + auto d2 = (v1.x() * v2.y()) - (v1.y() * v2.x()); + + auto d = abs(d1) > abs(d2) ? d1 : d2; + + if (d > 0.0) { distance *= -1.0; } + + return {distance, nearest_line_index_out, nearest_point_out}; + } + + Floating signed_distance_from_lines(const Vec<2, typename LineType::Scalar> &point) const + { + auto [dist, idx, np] = signed_distance_from_lines_extra(point); + return dist; + } + + std::vector all_lines_in_radius(const Vec<2, typename LineType::Scalar> &point, Floating radius) + { + return all_lines_in_radius(this->lines, this->tree, point, radius * radius); + } + + const LineType &get_line(size_t line_idx) const { return lines[line_idx]; } + + const std::vector &get_lines() const { return lines; } +}; + +}} // namespace Slic3r::AABBTreeLines #endif /* SRC_LIBSLIC3R_AABBTREELINES_HPP_ */ diff --git a/src/libslic3r/Brim.cpp b/src/libslic3r/Brim.cpp index 9ed56bea46..62d8867851 100644 --- a/src/libslic3r/Brim.cpp +++ b/src/libslic3r/Brim.cpp @@ -39,7 +39,7 @@ static void append_and_translate(Polygons &dst, const Polygons &src, const Print dst[dst_idx].translate(instance.shift.x(), instance.shift.y()); } -static float max_brim_width(const ConstPrintObjectPtrsAdaptor &objects) +static float max_brim_width(const SpanOfConstPtrs &objects) { assert(!objects.empty()); return float(std::accumulate(objects.begin(), objects.end(), 0., @@ -564,7 +564,7 @@ ExtrusionEntityCollection make_brim(const Print &print, PrintTryCancel try_cance } #endif // BRIM_DEBUG_TO_SVG - const bool could_brim_intersects_skirt = std::any_of(print.objects().begin(), print.objects().end(), [&print](PrintObject *object) { + const bool could_brim_intersects_skirt = std::any_of(print.objects().begin(), print.objects().end(), [&print](const PrintObject *object) { const BrimType &bt = object->config().brim_type; return (bt == btOuterOnly || bt == btOuterAndInner) && print.config().skirt_distance.value < object->config().brim_width; }); diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index f77bbaee83..a118f6ef39 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -268,7 +268,6 @@ set(SLIC3R_SOURCES TriangleMeshSlicer.hpp MeshSplitImpl.hpp TriangulateWall.hpp - TriangulateWall.cpp utils.cpp Utils.hpp Time.cpp diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index 151043a04f..a8d0473b7b 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -1786,6 +1786,17 @@ public: // Initialized by ConfigOptionEnum::get_enum_values() const t_config_enum_values *enum_keys_map = nullptr; + void set_enum_values(std::initializer_list> il) { + enum_values.clear(); + enum_values.reserve(il.size()); + enum_labels.clear(); + enum_labels.reserve(il.size()); + for (const std::pair p : il) { + enum_values.emplace_back(p.first); + enum_labels.emplace_back(p.second); + } + } + bool has_enum_value(const std::string &value) const { for (const std::string &v : enum_values) if (v == value) diff --git a/src/libslic3r/ExPolygon.hpp b/src/libslic3r/ExPolygon.hpp index d13056f952..4ea5b95962 100644 --- a/src/libslic3r/ExPolygon.hpp +++ b/src/libslic3r/ExPolygon.hpp @@ -1,6 +1,7 @@ #ifndef slic3r_ExPolygon_hpp_ #define slic3r_ExPolygon_hpp_ +#include "Point.hpp" #include "libslic3r.h" #include "Polygon.hpp" #include "Polyline.hpp" @@ -125,6 +126,33 @@ inline Lines to_lines(const ExPolygons &src) return lines; } +inline std::vector to_unscaled_linesf(const ExPolygons &src) +{ + size_t n_lines = 0; + for (ExPolygons::const_iterator it_expoly = src.begin(); it_expoly != src.end(); ++ it_expoly) { + n_lines += it_expoly->contour.points.size(); + for (size_t i = 0; i < it_expoly->holes.size(); ++ i) + n_lines += it_expoly->holes[i].points.size(); + } + std::vector lines; + lines.reserve(n_lines); + for (ExPolygons::const_iterator it_expoly = src.begin(); it_expoly != src.end(); ++ it_expoly) { + for (size_t i = 0; i <= it_expoly->holes.size(); ++ i) { + const Points &points = ((i == 0) ? it_expoly->contour : it_expoly->holes[i - 1]).points; + Vec2d unscaled_a = unscaled(points.front()); + Vec2d unscaled_b = unscaled_a; + for (Points::const_iterator it = points.begin()+1; it != points.end(); ++it){ + unscaled_b = unscaled(*(it)); + lines.push_back(Linef(unscaled_a, unscaled_b)); + unscaled_a = unscaled_b; + } + lines.push_back(Linef(unscaled_a, unscaled(points.front()))); + } + } + return lines; +} + + inline Polylines to_polylines(const ExPolygon &src) { Polylines polylines; diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index ce4a505fc6..4592402e37 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -32,7 +32,6 @@ class GCode; namespace { struct Item; } struct PrintInstance; -class ConstPrintObjectPtrsAdaptor; class OozePrevention { public: diff --git a/src/libslic3r/GCode/SeamPlacer.cpp b/src/libslic3r/GCode/SeamPlacer.cpp index 926538ec9c..1d7fd5b3c6 100644 --- a/src/libslic3r/GCode/SeamPlacer.cpp +++ b/src/libslic3r/GCode/SeamPlacer.cpp @@ -1,6 +1,7 @@ #include "SeamPlacer.hpp" #include "Color.hpp" +#include "Polygon.hpp" #include "PrintConfig.hpp" #include "tbb/parallel_for.h" #include "tbb/blocked_range.h" @@ -995,49 +996,6 @@ void pick_random_seam_point(const std::vector &perimeter_points, perimeter.finalized = true; } -class PerimeterDistancer { - std::vector lines; - AABBTreeIndirect::Tree<2, double> tree; - -public: - PerimeterDistancer(const Layer *layer) { - ExPolygons layer_outline = layer->lslices; - for (const ExPolygon &island : layer_outline) { - assert(island.contour.is_counter_clockwise()); - for (const auto &line : island.contour.lines()) { - lines.emplace_back(unscale(line.a), unscale(line.b)); - } - for (const Polygon &hole : island.holes) { - assert(hole.is_clockwise()); - for (const auto &line : hole.lines()) { - lines.emplace_back(unscale(line.a), unscale(line.b)); - } - } - } - tree = AABBTreeLines::build_aabb_tree_over_indexed_lines(lines); - } - - float distance_from_perimeter(const Vec2f &point) const { - Vec2d p = point.cast(); - size_t hit_idx_out { }; - Vec2d hit_point_out = Vec2d::Zero(); - auto distance = AABBTreeLines::squared_distance_to_indexed_lines(lines, tree, p, hit_idx_out, hit_point_out); - if (distance < 0) { - return std::numeric_limits::max(); - } - - distance = sqrt(distance); - const Linef &line = lines[hit_idx_out]; - Vec2d v1 = line.b - line.a; - Vec2d v2 = p - line.a; - if ((v1.x() * v2.y()) - (v1.y() * v2.x()) > 0.0) { - distance *= -1; - } - return distance; - } -} -; - } // namespace SeamPlacerImpl // Parallel process and extract each perimeter polygon of the given print object. @@ -1089,13 +1047,14 @@ void SeamPlacer::calculate_candidates_visibility(const PrintObject *po, void SeamPlacer::calculate_overhangs_and_layer_embedding(const PrintObject *po) { using namespace SeamPlacerImpl; + using PerimeterDistancer = AABBTreeLines::LinesDistancer; std::vector &layers = m_seam_per_object[po].layers; tbb::parallel_for(tbb::blocked_range(0, layers.size()), [po, &layers](tbb::blocked_range r) { std::unique_ptr prev_layer_distancer; if (r.begin() > 0) { // previous layer exists - prev_layer_distancer = std::make_unique(po->layers()[r.begin() - 1]); + prev_layer_distancer = std::make_unique(to_unscaled_linesf(po->layers()[r.begin() - 1]->lslices)); } for (size_t layer_idx = r.begin(); layer_idx < r.end(); ++layer_idx) { @@ -1106,12 +1065,13 @@ void SeamPlacer::calculate_overhangs_and_layer_embedding(const PrintObject *po) } }; bool should_compute_layer_embedding = regions_with_perimeter > 1; - std::unique_ptr current_layer_distancer = std::make_unique(po->layers()[layer_idx]); + std::unique_ptr current_layer_distancer = std::make_unique( + to_unscaled_linesf(po->layers()[layer_idx]->lslices)); for (SeamCandidate &perimeter_point : layers[layer_idx].points) { Vec2f point = Vec2f { perimeter_point.position.head<2>() }; if (prev_layer_distancer.get() != nullptr) { - perimeter_point.overhang = prev_layer_distancer->distance_from_perimeter(point) + perimeter_point.overhang = prev_layer_distancer->signed_distance_from_lines(point.cast()) + 0.6f * perimeter_point.perimeter.flow_width - tan(SeamPlacer::overhang_angle_threshold) * po->layers()[layer_idx]->height; @@ -1120,7 +1080,7 @@ void SeamPlacer::calculate_overhangs_and_layer_embedding(const PrintObject *po) } if (should_compute_layer_embedding) { // search for embedded perimeter points (points hidden inside the print ,e.g. multimaterial join, best position for seam) - perimeter_point.embedded_distance = current_layer_distancer->distance_from_perimeter(point) + perimeter_point.embedded_distance = current_layer_distancer->signed_distance_from_lines(point.cast()) + 0.6f * perimeter_point.perimeter.flow_width; } } diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index 870096bb9b..c5554c2fa1 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -658,7 +658,7 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int return std::max(0.f, volume_to_wipe); // Soluble filament cannot be wiped in a random infill, neither the filament after it // we will sort objects so that dedicated for wiping are at the beginning: - ConstPrintObjectPtrs object_list = print.objects().vector(); + ConstPrintObjectPtrs object_list(print.objects().begin(), print.objects().end()); std::sort(object_list.begin(), object_list.end(), [](const PrintObject* a, const PrintObject* b) { return a->config().wipe_into_objects; }); // We will now iterate through diff --git a/src/libslic3r/MultiMaterialSegmentation.cpp b/src/libslic3r/MultiMaterialSegmentation.cpp index 9560096bed..21b53c40dd 100644 --- a/src/libslic3r/MultiMaterialSegmentation.cpp +++ b/src/libslic3r/MultiMaterialSegmentation.cpp @@ -1305,7 +1305,7 @@ static inline std::vector> mmu_segmentation_top_and_bott { const size_t num_extruders = print_object.print()->config().nozzle_diameter.size() + 1; const size_t num_layers = input_expolygons.size(); - const ConstLayerPtrsAdaptor layers = print_object.layers(); + const SpanOfConstPtrs layers = print_object.layers(); // Maximum number of top / bottom layers accounts for maximum overlap of one thread group into a neighbor thread group. int max_top_layers = 0; @@ -1685,7 +1685,7 @@ std::vector> multi_material_segmentation_by_painting(con std::vector> painted_lines(num_layers); std::array painted_lines_mutex; std::vector edge_grids(num_layers); - const ConstLayerPtrsAdaptor layers = print_object.layers(); + const SpanOfConstPtrs layers = print_object.layers(); std::vector input_expolygons(num_layers); throw_on_cancel_callback(); diff --git a/src/libslic3r/Point.hpp b/src/libslic3r/Point.hpp index da558e4388..949ddbad1f 100644 --- a/src/libslic3r/Point.hpp +++ b/src/libslic3r/Point.hpp @@ -111,11 +111,17 @@ inline double angle(const Eigen::MatrixBase &v1, const Eigen::MatrixBas return atan2(cross2(v1d, v2d), v1d.dot(v2d)); } -template -Eigen::Matrix to_2d(const Eigen::MatrixBase> &ptN) { return { ptN.x(), ptN.y() }; } +template +Eigen::Matrix to_2d(const Eigen::MatrixBase &ptN) { + static_assert(Derived::IsVectorAtCompileTime && int(Derived::SizeAtCompileTime) >= 3, "to_2d(): first parameter is not a 3D or higher dimensional vector"); + return { ptN.x(), ptN.y() }; +} -template -Eigen::Matrix to_3d(const Eigen::MatrixBase> & pt, const T z) { return { pt.x(), pt.y(), z }; } +template +inline Eigen::Matrix to_3d(const Eigen::MatrixBase &pt, const typename Derived::Scalar z) { + static_assert(Derived::IsVectorAtCompileTime && int(Derived::SizeAtCompileTime) == 2, "to_3d(): first parameter is not a 2D vector"); + return { pt.x(), pt.y(), z }; +} inline Vec2d unscale(coord_t x, coord_t y) { return Vec2d(unscale(x), unscale(y)); } inline Vec2d unscale(const Vec2crd &pt) { return Vec2d(unscale(pt.x()), unscale(pt.y())); } diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index c2777083d8..9e21111ce1 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -21,6 +21,7 @@ #include #include +#include namespace Slic3r { @@ -117,38 +118,12 @@ private: inline bool operator==(const PrintRegion &lhs, const PrintRegion &rhs) { return lhs.config_hash() == rhs.config_hash() && lhs.config() == rhs.config(); } inline bool operator!=(const PrintRegion &lhs, const PrintRegion &rhs) { return ! (lhs == rhs); } -template -class ConstVectorOfPtrsAdaptor { -public: - // Returning a non-const pointer to const pointers to T. - T * const * begin() const { return m_data->data(); } - T * const * end() const { return m_data->data() + m_data->size(); } - const T* front() const { return m_data->front(); } - const T* back() const { return m_data->back(); } - size_t size() const { return m_data->size(); } - bool empty() const { return m_data->empty(); } - const T* operator[](size_t i) const { return (*m_data)[i]; } - const T* at(size_t i) const { return m_data->at(i); } - std::vector vector() const { return std::vector(this->begin(), this->end()); } -protected: - ConstVectorOfPtrsAdaptor(const std::vector *data) : m_data(data) {} -private: - const std::vector *m_data; -}; +// For const correctness: Wrapping a vector of non-const pointers as a span of const pointers. +template +using SpanOfConstPtrs = tcb::span; -typedef std::vector LayerPtrs; -typedef std::vector ConstLayerPtrs; -class ConstLayerPtrsAdaptor : public ConstVectorOfPtrsAdaptor { - friend PrintObject; - ConstLayerPtrsAdaptor(const LayerPtrs *data) : ConstVectorOfPtrsAdaptor(data) {} -}; - -typedef std::vector SupportLayerPtrs; -typedef std::vector ConstSupportLayerPtrs; -class ConstSupportLayerPtrsAdaptor : public ConstVectorOfPtrsAdaptor { - friend PrintObject; - ConstSupportLayerPtrsAdaptor(const SupportLayerPtrs *data) : ConstVectorOfPtrsAdaptor(data) {} -}; +using LayerPtrs = std::vector; +using SupportLayerPtrs = std::vector; class BoundingBoxf3; // TODO: for temporary constructor parameter @@ -256,8 +231,8 @@ public: // Size of an object: XYZ in scaled coordinates. The size might not be quite snug in XY plane. const Vec3crd& size() const { return m_size; } const PrintObjectConfig& config() const { return m_config; } - ConstLayerPtrsAdaptor layers() const { return ConstLayerPtrsAdaptor(&m_layers); } - ConstSupportLayerPtrsAdaptor support_layers() const { return ConstSupportLayerPtrsAdaptor(&m_support_layers); } + auto layers() const { return SpanOfConstPtrs(const_cast(m_layers.data()), m_layers.size()); } + auto support_layers() const { return SpanOfConstPtrs(const_cast(m_support_layers.data()), m_support_layers.size()); } const Transform3d& trafo() const { return m_trafo; } // Trafo with the center_offset() applied after the transformation, to center the object in XY before slicing. Transform3d trafo_centered() const @@ -498,21 +473,10 @@ struct PrintStatistics } }; -typedef std::vector PrintObjectPtrs; -typedef std::vector ConstPrintObjectPtrs; -class ConstPrintObjectPtrsAdaptor : public ConstVectorOfPtrsAdaptor { - friend Print; - ConstPrintObjectPtrsAdaptor(const PrintObjectPtrs *data) : ConstVectorOfPtrsAdaptor(data) {} -}; +using PrintObjectPtrs = std::vector; +using ConstPrintObjectPtrs = std::vector; -typedef std::vector PrintRegionPtrs; -/* -typedef std::vector ConstPrintRegionPtrs; -class ConstPrintRegionPtrsAdaptor : public ConstVectorOfPtrsAdaptor { - friend Print; - ConstPrintRegionPtrsAdaptor(const PrintRegionPtrs *data) : ConstVectorOfPtrsAdaptor(data) {} -}; -*/ +using PrintRegionPtrs = std::vector; // The complete print tray with possibly multiple objects. class Print : public PrintBaseWithState @@ -575,7 +539,7 @@ public: const PrintConfig& config() const { return m_config; } const PrintObjectConfig& default_object_config() const { return m_default_object_config; } const PrintRegionConfig& default_region_config() const { return m_default_region_config; } - ConstPrintObjectPtrsAdaptor objects() const { return ConstPrintObjectPtrsAdaptor(&m_objects); } + SpanOfConstPtrs objects() const { return SpanOfConstPtrs(const_cast(m_objects.data()), m_objects.size()); } PrintObject* get_object(size_t idx) { return const_cast(m_objects[idx]); } const PrintObject* get_object(size_t idx) const { return m_objects[idx]; } // PrintObject by its ObjectID, to be used to uniquely bind slicing warnings to their source PrintObjects diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 9a3bc3ce6f..841bee5b9f 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -138,7 +138,8 @@ CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(SupportMaterialPattern) static const t_config_enum_values s_keys_map_SupportMaterialStyle { { "grid", smsGrid }, { "snug", smsSnug }, - { "tree", smsTree } + { "tree", smsTree }, + { "organic", smsOrganic } }; CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(SupportMaterialStyle) @@ -2782,12 +2783,12 @@ void PrintConfigDef::init_fff_params() "will create more stable supports, while snug support towers will save material and reduce " "object scarring."); def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); - def->enum_values.push_back("grid"); - def->enum_values.push_back("snug"); - def->enum_values.push_back("tree"); - def->enum_labels.push_back(L("Grid")); - def->enum_labels.push_back(L("Snug")); - def->enum_labels.push_back(L("Tree")); + def->set_enum_values({ + { "grid", L("Grid") }, + { "snug", L("Snug") }, + { "tree", L("Tree") }, + { "organic", L("Organic") } + }); def->mode = comAdvanced; def->set_default_value(new ConfigOptionEnum(smsGrid)); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 48493aa0bd..0a6daf2d28 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -85,7 +85,7 @@ enum SupportMaterialPattern { }; enum SupportMaterialStyle { - smsGrid, smsSnug, smsTree, + smsGrid, smsSnug, smsTree, smsOrganic, }; enum SupportMaterialInterfacePattern { diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 7ea55a3a4e..bdcb034abf 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -2197,7 +2197,7 @@ void PrintObject::combine_infill() void PrintObject::_generate_support_material() { - if (m_config.support_material_style == smsTree) { + if (m_config.support_material_style == smsTree || m_config.support_material_style == smsOrganic) { fff_tree_support_generate(*this, std::function([this](){ this->throw_if_canceled(); })); } else { PrintObjectSupportMaterial support_material(this, m_slicing_params); @@ -2205,7 +2205,7 @@ void PrintObject::_generate_support_material() } } -static void project_triangles_to_slabs(ConstLayerPtrsAdaptor layers, const indexed_triangle_set &custom_facets, const Transform3f &tr, bool seam, std::vector &out) +static void project_triangles_to_slabs(SpanOfConstPtrs layers, const indexed_triangle_set &custom_facets, const Transform3f &tr, bool seam, std::vector &out) { if (custom_facets.indices.empty()) return; diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp index 4910168873..c4a4efbf24 100644 --- a/src/libslic3r/SupportMaterial.cpp +++ b/src/libslic3r/SupportMaterial.cpp @@ -800,6 +800,7 @@ public: { switch (m_style) { case smsTree: + case smsOrganic: assert(false); [[fallthrough]]; case smsGrid: @@ -3237,6 +3238,20 @@ static inline void fill_expolygons_generate_paths( fill_expolygons_generate_paths(dst, std::move(expolygons), filler, fill_params, density, role, flow); } +static Polylines draw_perimeters(const ExPolygon &expoly, double clip_length) +{ + // Draw the perimeters. + Polylines polylines; + polylines.reserve(expoly.holes.size() + 1); + for (size_t i = 0; i <= expoly.holes.size(); ++ i) { + Polyline pl(i == 0 ? expoly.contour.points : expoly.holes[i - 1].points); + pl.points.emplace_back(pl.points.front()); + pl.clip_end(clip_length); + polylines.emplace_back(std::move(pl)); + } + return polylines; +} + static inline void tree_supports_generate_paths( ExtrusionEntitiesPtr &dst, const Polygons &polygons, @@ -3335,7 +3350,20 @@ static inline void tree_supports_generate_paths( const double clip_length = spacing * 0.15; const double anchor_length = spacing * 6.; ClipperLib_Z::Paths anchor_candidates; - for (ExPolygon &expoly : closing_ex(polygons, float(SCALED_EPSILON), float(SCALED_EPSILON + 0.5*flow.scaled_width()))) { + for (ExPolygon& expoly : closing_ex(polygons, float(SCALED_EPSILON), float(SCALED_EPSILON + 0.5 * flow.scaled_width()))) { + double area = expoly.area(); + if (area > sqr(scaled(5.))) { + // Make the tree branch stable by adding another perimeter. + ExPolygons level2 = offset2_ex({ expoly }, -1.5 * flow.scaled_width(), 0.5 * flow.scaled_width()); + if (level2.size() == 1) { + Polylines polylines; + extrusion_entities_append_paths(dst, draw_perimeters(expoly, clip_length), erSupportMaterial, flow.mm3_per_mm(), flow.width(), flow.height(), + // Disable reversal of the path, always start with the anchor, always print CCW. + false); + expoly = level2.front(); + } + } + // Try to produce one more perimeter to place the seam anchor. // First genrate a 2nd perimeter loop as a source for anchor candidates. // The anchor candidate points are annotated with an index of the source contour or with -1 if on intersection. @@ -3465,9 +3493,9 @@ static inline void fill_expolygons_with_sheath_generate_paths( fill_params.density = density; fill_params.dont_adjust = true; - double spacing = flow.scaled_spacing(); + const double spacing = flow.scaled_spacing(); // Clip the sheath path to avoid the extruder to get exactly on the first point of the loop. - double clip_length = spacing * 0.15; + const double clip_length = spacing * 0.15; for (ExPolygon &expoly : closing_ex(polygons, float(SCALED_EPSILON), float(SCALED_EPSILON + 0.5*flow.scaled_width()))) { // Don't reorder the skirt and its infills. @@ -3477,16 +3505,7 @@ static inline void fill_expolygons_with_sheath_generate_paths( eec->no_sort = true; } ExtrusionEntitiesPtr &out = no_sort ? eec->entities : dst; - // Draw the perimeters. - Polylines polylines; - polylines.reserve(expoly.holes.size() + 1); - for (size_t i = 0; i <= expoly.holes.size(); ++ i) { - Polyline pl(i == 0 ? expoly.contour.points : expoly.holes[i - 1].points); - pl.points.emplace_back(pl.points.front()); - pl.clip_end(clip_length); - polylines.emplace_back(std::move(pl)); - } - extrusion_entities_append_paths(out, polylines, erSupportMaterial, flow.mm3_per_mm(), flow.width(), flow.height()); + extrusion_entities_append_paths(out, draw_perimeters(expoly, clip_length), erSupportMaterial, flow.mm3_per_mm(), flow.width(), flow.height()); // Fill in the rest. fill_expolygons_generate_paths(out, offset_ex(expoly, float(-0.4 * spacing)), filler, fill_params, density, role, flow); if (no_sort && ! eec->empty()) diff --git a/src/libslic3r/SupportSpotsGenerator.cpp b/src/libslic3r/SupportSpotsGenerator.cpp index 697518bd08..09b2bc5aea 100644 --- a/src/libslic3r/SupportSpotsGenerator.cpp +++ b/src/libslic3r/SupportSpotsGenerator.cpp @@ -1,6 +1,9 @@ #include "SupportSpotsGenerator.hpp" +#include "ExPolygon.hpp" #include "ExtrusionEntity.hpp" +#include "Line.hpp" +#include "Polygon.hpp" #include "tbb/parallel_for.h" #include "tbb/blocked_range.h" #include "tbb/blocked_range2d.h" @@ -70,46 +73,10 @@ SupportPoint::SupportPoint(const Vec3f &position, float force, float spot_radius position(position), force(force), spot_radius(spot_radius), direction(direction) { } -class LinesDistancer { -private: - std::vector lines; - AABBTreeIndirect::Tree<2, float> tree; - -public: - explicit LinesDistancer(const std::vector &lines) : - lines(lines) { - tree = AABBTreeLines::build_aabb_tree_over_indexed_lines(this->lines); - } - - // negative sign means inside - float signed_distance_from_lines(const Vec2f &point, size_t &nearest_line_index_out, - Vec2f &nearest_point_out) const { - auto distance = AABBTreeLines::squared_distance_to_indexed_lines(lines, tree, point, nearest_line_index_out, - nearest_point_out); - if (distance < 0) - return std::numeric_limits::infinity(); - - distance = sqrt(distance); - const ExtrusionLine &line = lines[nearest_line_index_out]; - Vec2f v1 = line.b - line.a; - Vec2f v2 = point - line.a; - if ((v1.x() * v2.y()) - (v1.y() * v2.x()) > 0.0) { - distance *= -1; - } - return distance; - } - - const ExtrusionLine& get_line(size_t line_idx) const { - return lines[line_idx]; - } - - const std::vector& get_lines() const { - return lines; - } -}; - static const size_t NULL_ISLAND = std::numeric_limits::max(); +using LD = AABBTreeLines::LinesDistancer; + class PixelGrid { Vec2f pixel_size; Vec2f origin; @@ -387,7 +354,7 @@ void check_extrusion_entity_stability(const ExtrusionEntity *entity, std::vector &checked_lines_out, float layer_z, const LayerRegion *layer_region, - const LinesDistancer &prev_layer_lines, + const LD &prev_layer_lines, Issues &issues, const Params ¶ms) { @@ -429,11 +396,7 @@ void check_extrusion_entity_stability(const ExtrusionEntity *entity, // malformation in concave angles does not happen malformation_acc.add_angle(std::max(0.0f, curr_angle)); - size_t nearest_line_idx; - Vec2f nearest_point; - float dist_from_prev_layer = prev_layer_lines.signed_distance_from_lines(current_line.b, nearest_line_idx, - nearest_point); - + auto [dist_from_prev_layer, nearest_line_idx, nearest_point] = prev_layer_lines.signed_distance_from_lines_extra(current_line.b); if (fabs(dist_from_prev_layer) < overhang_dist) { bridging_acc.reset(); } else { @@ -491,53 +454,18 @@ std::tuple reckon_islands( } } - std::vector islands; // these search trees will be used to determine to which island does the extrusion belong. - std::vector> island_extrusions; //final assigment of each extrusion to an island. - // initliaze the search from external perimeters - at the beginning, there is island candidate for each external perimeter. - // some of them will disappear (e.g. holes) - for (size_t e = 0; e < extrusions.size(); ++e) { - if (layer_lines[extrusions[e].first].origin_entity->is_loop() && - layer_lines[extrusions[e].first].is_external_perimeter()) { - std::vector copy(extrusions[e].second - extrusions[e].first); - for (size_t ex_line_idx = extrusions[e].first; ex_line_idx < extrusions[e].second; ++ex_line_idx) { - copy[ex_line_idx - extrusions[e].first] = layer_lines[ex_line_idx]; - } - islands.emplace_back(copy); - island_extrusions.push_back( { e }); - } + std::vector> islands; // these search trees will be used to determine to which island does the extrusion belong. + for (const ExPolygon& island : layer->lslices) { + islands.emplace_back(to_lines(island)); } - // backup code if islands not found - // If that happens, just make the first extrusion into island - it may be wrong, but it won't crash. - if (islands.empty() && !extrusions.empty()) { - std::vector copy(extrusions[0].second - extrusions[0].first); - for (size_t ex_line_idx = extrusions[0].first; ex_line_idx < extrusions[0].second; ++ex_line_idx) { - copy[ex_line_idx - extrusions[0].first] = layer_lines[ex_line_idx]; - } - islands.emplace_back(copy); - island_extrusions.push_back( { 0 }); - } - - // assign non external extrusions to islands - for (size_t e = 0; e < extrusions.size(); ++e) { - if (!layer_lines[extrusions[e].first].origin_entity->is_loop() || - !layer_lines[extrusions[e].first].is_external_perimeter()) { - bool island_assigned = false; - for (size_t i = 0; i < islands.size(); ++i) { - if (island_extrusions[i].empty()) { - continue; - } - size_t idx = 0; - Vec2f pt = Vec2f::Zero(); - if (islands[i].signed_distance_from_lines(layer_lines[extrusions[e].first].a, idx, pt) < 0) { - island_extrusions[i].push_back(e); - island_assigned = true; - break; - } - } - if (!island_assigned) { // If extrusion is not assigned for some reason, push it into the first island. As with the previous backup code, - // it may be wrong, but it won't crash - island_extrusions[0].push_back(e); + std::vector> island_extrusions(islands.size(), + std::vector{}); // final assigment of each extrusion to an island. + for (size_t extrusion_idx = 0; extrusion_idx < extrusions.size(); extrusion_idx++) { + Point second_point = Point::new_scale(layer_lines[extrusions[extrusion_idx].first].b); + for (size_t island_idx = 0; island_idx < islands.size(); island_idx++) { + if (islands[island_idx].signed_distance_from_lines(second_point) <= 0.0) { + island_extrusions[island_idx].push_back(extrusion_idx); } } } @@ -553,10 +481,14 @@ std::tuple reckon_islands( } Island island { }; - island.external_lines.insert(island.external_lines.end(), - layer_lines.begin() + extrusions[island_ex[0]].first, - layer_lines.begin() + extrusions[island_ex[0]].second); for (size_t extrusion_idx : island_ex) { + + if (layer_lines[extrusions[extrusion_idx].first].is_external_perimeter()) { + island.external_lines.insert(island.external_lines.end(), + layer_lines.begin() + extrusions[extrusion_idx].first, + layer_lines.begin() + extrusions[extrusion_idx].second); + } + for (size_t lidx = extrusions[extrusion_idx].first; lidx < extrusions[extrusion_idx].second; ++lidx) { line_to_island_mapping[lidx] = result.islands.size(); const ExtrusionLine &line = layer_lines[lidx]; @@ -1050,7 +982,7 @@ Issues check_global_stability(SupportGridFilter supports_presence_grid, #ifdef DETAILED_DEBUG_LOGS weakest_conn.print_info("weakest connection info: "); #endif - LinesDistancer island_lines_dist(island.external_lines); + LD island_lines_dist(island.external_lines); float unchecked_dist = params.min_distance_between_support_points + 1.0f; for (const ExtrusionLine &line : island.external_lines) { @@ -1059,12 +991,9 @@ Issues check_global_stability(SupportGridFilter supports_presence_grid, unchecked_dist += line.len; } else { unchecked_dist = line.len; - Vec2f target_point; - size_t idx; Vec3f pivot_site_search_point = to_3d(Vec2f(line.b + (line.b - line.a).normalized() * 300.0f), layer_z); - island_lines_dist.signed_distance_from_lines(pivot_site_search_point.head<2>(), idx, - target_point); + auto [dist, nidx, target_point] = island_lines_dist.signed_distance_from_lines_extra(pivot_site_search_point.head<2>()); Vec3f support_point = to_3d(target_point, layer_z); auto force = part.is_stable_while_extruding(weakest_conn, line, support_point, layer_z, params); if (force > 0) { @@ -1147,7 +1076,7 @@ std::tuple> check_extrusions_and_build_graph(c } } #endif - LinesDistancer external_lines(layer_lines); + LD external_lines(layer_lines); layer_lines.clear(); prev_layer_grid = layer_grid; @@ -1199,7 +1128,7 @@ std::tuple> check_extrusions_and_build_graph(c } } #endif - external_lines = LinesDistancer(layer_lines); + external_lines = LD(layer_lines); layer_lines.clear(); prev_layer_grid = layer_grid; } diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index ad23b4cbe1..695c58abeb 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -39,8 +39,6 @@ //==================== #define ENABLE_2_5_0_ALPHA1 1 -// Enable removal of wipe tower magic object_id equal to 1000 -#define ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL (1 && ENABLE_2_5_0_ALPHA1) // Enable removal of legacy OpenGL calls #define ENABLE_LEGACY_OPENGL_REMOVAL (1 && ENABLE_2_5_0_ALPHA1) // Enable OpenGL ES diff --git a/src/libslic3r/TreeModelVolumes.cpp b/src/libslic3r/TreeModelVolumes.cpp index ad27e78712..e098636fd4 100644 --- a/src/libslic3r/TreeModelVolumes.cpp +++ b/src/libslic3r/TreeModelVolumes.cpp @@ -39,7 +39,7 @@ TreeSupportMeshGroupSettings::TreeSupportMeshGroupSettings(const PrintObject &pr // Support must be enabled and set to Tree style. assert(config.support_material); - assert(config.support_material_style == smsTree); + assert(config.support_material_style == smsTree || config.support_material_style == smsOrganic); // Calculate maximum external perimeter width over all printing regions, taking into account the default layer height. coordf_t external_perimeter_width = 0.; @@ -666,7 +666,13 @@ void TreeModelVolumes::calculatePlaceables(const coord_t radius, const LayerInde tbb::parallel_for(tbb::blocked_range(std::max(1, start_layer), max_required_layer + 1), [this, &data, radius, start_layer](const tbb::blocked_range& range) { for (LayerIndex layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) - data[layer_idx - start_layer] = offset(union_ex(getPlaceableAreas(0, layer_idx)), - radius, jtMiter, 1.2); + data[layer_idx - start_layer] = offset( + union_ex(getPlaceableAreas(0, layer_idx)), + // As a placeable area is calculated by (collision of the layer below) - (collision of the current layer) and the collision is offset by xy_distance, + // it can happen that a small line is considered a flat area to place something onto, even though it is mostly + // xy_distance that cant support it. Making the area smaller by xy_distance fixes this. + - (radius + m_current_min_xy_dist + m_current_min_xy_dist_delta), + jtMiter, 1.2); }); #ifdef SLIC3R_TREESUPPORTS_PROGRESS { diff --git a/src/libslic3r/TreeSupport.cpp b/src/libslic3r/TreeSupport.cpp index c408b2f85b..b60744e327 100644 --- a/src/libslic3r/TreeSupport.cpp +++ b/src/libslic3r/TreeSupport.cpp @@ -19,6 +19,9 @@ #include "Polyline.hpp" #include "MutablePolygon.hpp" #include "SupportMaterial.hpp" +#include "TriangleMeshSlicer.hpp" +#include "OpenVDBUtils.hpp" +#include #include #include @@ -26,6 +29,7 @@ #include #include #include +#include #ifdef _WIN32 #include //todo Remove! ONLY FOR PUBLIC BETA!! #endif // _WIN32 @@ -97,6 +101,20 @@ static inline void validate_range(const LineInformations &lines) validate_range(l); } +static inline void check_self_intersections(const Polygons &polygons, const std::string_view message) +{ +#ifdef _WIN32 + if (!intersecting_edges(polygons).empty()) + ::MessageBoxA(nullptr, (std::string("TreeSupport infill self intersections: ") + std::string(message)).c_str(), "Bug detected!", MB_OK | MB_SYSTEMMODAL | MB_SETFOREGROUND | MB_ICONWARNING); +#endif // _WIN32 +} +static inline void check_self_intersections(const ExPolygon &expoly, const std::string_view message) +{ +#ifdef _WIN32 + check_self_intersections(to_polygons(expoly), message); +#endif // _WIN32 +} + static inline void clip_for_diff(const Polygon &src, const BoundingBox &bbox, Polygon &out) { out.clear(); @@ -193,7 +211,7 @@ static std::vector>> group_me #endif // NDEBUG // Support must be enabled and set to Tree style. assert(object_config.support_material); - assert(object_config.support_material_style == smsTree); + assert(object_config.support_material_style == smsTree || object_config.support_material_style == smsOrganic); bool found_existing_group = false; TreeSupportSettings next_settings{ TreeSupportMeshGroupSettings{ print_object } }; @@ -312,17 +330,39 @@ void tree_supports_show_error(std::string message, bool critical) if (! (enforced_layer || blockers_layers.empty() || blockers_layers[layer_id].empty())) overhangs = diff(overhangs, blockers_layers[layer_id], ApplySafetyOffset::Yes); } - if (! enforcers_layers.empty() && ! enforcers_layers[layer_id].empty()) + //check_self_intersections(overhangs, "generate_overhangs1"); + if (! enforcers_layers.empty() && ! enforcers_layers[layer_id].empty()) { // Has some support enforcers at this layer, apply them to the overhangs, don't apply the support threshold angle. - if (Polygons enforced_overhangs = intersection(raw_overhangs_calculated ? raw_overhangs : diff(current_layer.lslices, lower_layer.lslices), enforcers_layers[layer_id]); + //enforcers_layers[layer_id] = union_(enforcers_layers[layer_id]); + //check_self_intersections(enforcers_layers[layer_id], "generate_overhangs - enforcers"); + //check_self_intersections(to_polygons(lower_layer.lslices), "generate_overhangs - lowerlayers"); + if (Polygons enforced_overhangs = intersection(raw_overhangs_calculated ? raw_overhangs : diff(current_layer.lslices, lower_layer.lslices), enforcers_layers[layer_id] /*, ApplySafetyOffset::Yes */); ! enforced_overhangs.empty()) { //FIXME this is a hack to make enforcers work on steep overhangs. - enforced_overhangs = diff(offset(enforced_overhangs, + //check_self_intersections(enforced_overhangs, "generate_overhangs - enforced overhangs1"); + //Polygons enforced_overhangs_prev = enforced_overhangs; + //check_self_intersections(to_polygons(union_ex(enforced_overhangs)), "generate_overhangs - enforced overhangs11"); + //check_self_intersections(offset(union_ex(enforced_overhangs), + //FIXME this is a fudge constant! + // scaled(0.4)), "generate_overhangs - enforced overhangs12"); + enforced_overhangs = diff(offset(union_ex(enforced_overhangs), //FIXME this is a fudge constant! scaled(0.4)), lower_layer.lslices); +#ifdef TREESUPPORT_DEBUG_SVG + if (! intersecting_edges(enforced_overhangs).empty()) { + static int irun = 0; + SVG::export_expolygons(debug_out_path("treesupport-self-intersections-%d.svg", ++irun), + { { { union_ex(enforced_overhangs_prev) }, { "prev", "yellow", 0.5f } }, + { { lower_layer.lslices }, { "lower_layer.lslices", "gray", 0.5f } }, + { { union_ex(enforced_overhangs) }, { "enforced_overhangs", "red", "black", "", scaled(0.1f), 0.5f } } }); + } +#endif // TREESUPPORT_DEBUG_SVG + //check_self_intersections(enforced_overhangs, "generate_overhangs - enforced overhangs2"); overhangs = overhangs.empty() ? std::move(enforced_overhangs) : union_(overhangs, enforced_overhangs); + //check_self_intersections(overhangs, "generate_overhangs - enforcers"); } + } out[layer_id] = std::move(overhangs); } }); @@ -675,7 +715,10 @@ static std::optional> polyline_sample_next_point_at_dis return lines; #else #ifdef _WIN32 - if (! BoundingBox(Point::new_scale(-170., -170.), Point::new_scale(170., 170.)).contains(get_extents(polygon))) + // Max dimensions for MK3 +// if (! BoundingBox(Point::new_scale(-170., -170.), Point::new_scale(170., 170.)).contains(get_extents(polygon))) + // Max dimensions for XL + if (! BoundingBox(Point::new_scale(-250., -250.), Point::new_scale(250., 250.)).contains(get_extents(polygon))) ::MessageBoxA(nullptr, "TreeSupport infill kravsky", "Bug detected!", MB_OK | MB_SYSTEMMODAL | MB_SETFOREGROUND | MB_ICONWARNING); #endif // _WIN32 @@ -702,10 +745,7 @@ static std::optional> polyline_sample_next_point_at_dis ::MessageBoxA(nullptr, "TreeSupport infill negative area", "Bug detected!", MB_OK | MB_SYSTEMMODAL | MB_SETFOREGROUND | MB_ICONWARNING); #endif // _WIN32 assert(intersecting_edges(to_polygons(expoly)).empty()); -#ifdef _WIN32 - if (! intersecting_edges(to_polygons(expoly)).empty()) - ::MessageBoxA(nullptr, "TreeSupport infill self intersections", "Bug detected!", MB_OK | MB_SYSTEMMODAL | MB_SETFOREGROUND | MB_ICONWARNING); -#endif // _WIN32 + check_self_intersections(expoly, "generate_support_infill_lines"); Surface surface(stInternal, std::move(expoly)); try { Polylines pl = filler->fill_surface(&surface, fill_params); @@ -831,6 +871,11 @@ static std::optional> polyline_sample_next_point_at_dis return union_(ret); } +static double layer_z(const SlicingParameters &slicing_params, const size_t layer_idx) +{ + return slicing_params.object_print_z_min + slicing_params.first_object_layer_height + layer_idx * slicing_params.layer_height; +} + static inline SupportGeneratorLayer& layer_initialize( SupportGeneratorLayer &layer_new, const SupporLayerType layer_type, @@ -838,7 +883,7 @@ static inline SupportGeneratorLayer& layer_initialize( const size_t layer_idx) { layer_new.layer_type = layer_type; - layer_new.print_z = slicing_params.object_print_z_min + slicing_params.first_object_layer_height + layer_idx * slicing_params.layer_height; + layer_new.print_z = layer_z(slicing_params, layer_idx); layer_new.height = layer_idx == 0 ? slicing_params.first_object_layer_height : slicing_params.layer_height; layer_new.bottom_z = layer_idx == 0 ? slicing_params.object_print_z_min : layer_new.print_z - layer_new.height; return layer_new; @@ -1082,6 +1127,8 @@ static void generate_initial_areas( overhang_regular = mesh_group_settings.support_offset == 0 ? overhang_raw : safe_offset_inc(overhang_raw, mesh_group_settings.support_offset, relevant_forbidden, mesh_config.min_radius * 1.75 + mesh_config.xy_min_distance, 0, 1); + //check_self_intersections(overhang_regular, "overhang_regular1"); + // offset ensures that areas that could be supported by a part of a support line, are not considered unsupported overhang Polygons remaining_overhang = intersection( diff(mesh_group_settings.support_offset == 0 ? @@ -1108,6 +1155,7 @@ static void generate_initial_areas( remaining_overhang = diff(remaining_overhang, safe_offset_inc(overhang_regular, 1.5 * extra_total_offset_acc, raw_collision, offset_step, 0, 1)); // Extending the overhangs by the inflated remaining overhangs. overhang_regular = union_(overhang_regular, diff(safe_offset_inc(remaining_overhang, extra_total_offset_acc, raw_collision, offset_step, 0, 1), relevant_forbidden)); + //check_self_intersections(overhang_regular, "overhang_regular2"); } // If the xy distance overrides the z distance, some support needs to be inserted further down. //=> Analyze which support points do not fit on this layer and check if they will fit a few layers down (while adding them an infinite amount of layers down would technically be closer the the setting description, it would not produce reasonable results. ) @@ -1159,6 +1207,7 @@ static void generate_initial_areas( if (mesh_group_settings.minimum_support_area > 0) remove_small(overhang_roofs, mesh_group_settings.minimum_roof_area); overhang_regular = diff(overhang_regular, overhang_roofs, ApplySafetyOffset::Yes); + //check_self_intersections(overhang_regular, "overhang_regular3"); for (ExPolygon &roof_part : union_ex(overhang_roofs)) overhang_processing.emplace_back(std::move(roof_part), true); } @@ -2369,6 +2418,8 @@ static void set_points_on_areas(const SupportElement &elem, SupportElements *lay next_elem.state.result_on_layer = move_inside_if_outside(next_elem.influence_area, elem.state.result_on_layer); // do not call recursive because then amount of layers would be restricted by the stack size } + // Mark the parent element as accessed from a valid child element. + next_elem.state.marked = true; } } @@ -2487,15 +2538,23 @@ static void create_nodes_from_area( { // Initialize points on layer 0, with a "random" point in the influence area. // Point is chosen based on an inaccurate estimate where the branches will split into two, but every point inside the influence area would produce a valid result. - for (SupportElement &init : move_bounds.front()) { - init.state.result_on_layer = move_inside_if_outside(init.influence_area, init.state.next_position); - // Also set the parent nodes, as these will be required for the first iteration of the loop below. - set_points_on_areas(init, move_bounds.size() > 1 ? &move_bounds[1] : nullptr); + { + SupportElements *layer_above = move_bounds.size() > 1 ? &move_bounds[1] : nullptr; + for (SupportElement &elem : *layer_above) + elem.state.marked = false; + for (SupportElement &init : move_bounds.front()) { + init.state.result_on_layer = move_inside_if_outside(init.influence_area, init.state.next_position); + // Also set the parent nodes, as these will be required for the first iteration of the loop below and mark the parent nodes. + set_points_on_areas(init, layer_above); + } } for (LayerIndex layer_idx = 1; layer_idx < LayerIndex(move_bounds.size()); ++ layer_idx) { auto &layer = move_bounds[layer_idx]; auto *layer_above = layer_idx + 1 < move_bounds.size() ? &move_bounds[layer_idx + 1] : nullptr; + if (layer_above) + for (SupportElement &elem : *layer_above) + elem.state.marked = false; for (SupportElement &elem : layer) { assert(! elem.state.deleted); assert(elem.state.layer_idx == layer_idx); @@ -2509,11 +2568,6 @@ static void create_nodes_from_area( } // we dont need to remove yet the parents as they will have a lower dtt and also no result_on_layer set elem.state.deleted = true; - for (int32_t parent_idx : elem.parents) - // When the roof was not able to generate downwards enough, the top elements may have not moved, and have result_on_layer already set. - // As this branch needs to be removed => all parents result_on_layer have to be invalidated. - (*layer_above)[parent_idx].state.result_on_layer_reset(); - continue; } else { // set the point where the branch will be placed on the model if (elem.state.to_model_gracious) @@ -2522,13 +2576,67 @@ static void create_nodes_from_area( set_to_model_contact_simple(elem); } } - if (! elem.state.deleted) - // element is valid now setting points in the layer above + if (! elem.state.deleted && ! elem.state.marked && elem.state.target_height == layer_idx) + // Just a tip surface with no supporting element. + elem.state.deleted = true; + if (elem.state.deleted) { + for (int32_t parent_idx : elem.parents) + // When the roof was not able to generate downwards enough, the top elements may have not moved, and have result_on_layer already set. + // As this branch needs to be removed => all parents result_on_layer have to be invalidated. + (*layer_above)[parent_idx].state.result_on_layer_reset(); + } + if (! elem.state.deleted) { + // Element is valid now setting points in the layer above and mark the parent nodes. set_points_on_areas(elem, layer_above); + } } } +#ifndef NDEBUG + // Verify the tree connectivity including the branch slopes. + for (LayerIndex layer_idx = 0; layer_idx + 1 < LayerIndex(move_bounds.size()); ++ layer_idx) { + auto &layer = move_bounds[layer_idx]; + auto &above = move_bounds[layer_idx + 1]; + for (SupportElement &elem : layer) + if (! elem.state.deleted) { + for (int32_t iparent : elem.parents) { + SupportElement &parent = above[iparent]; + assert(! parent.state.deleted); + assert(elem.state.result_on_layer_is_set() == parent.state.result_on_layer_is_set()); + if (elem.state.result_on_layer_is_set()) { + double radius_increase = config.getRadius(elem.state) - config.getRadius(parent.state); + assert(radius_increase >= 0); + double shift = (elem.state.result_on_layer - parent.state.result_on_layer).cast().norm(); + assert(shift < radius_increase + 2. * config.maximum_move_distance_slow); + } + } + } + } +#endif // NDEBUG + remove_deleted_elements(move_bounds); + +#ifndef NDEBUG + // Verify the tree connectivity including the branch slopes. + for (LayerIndex layer_idx = 0; layer_idx + 1 < LayerIndex(move_bounds.size()); ++ layer_idx) { + auto &layer = move_bounds[layer_idx]; + auto &above = move_bounds[layer_idx + 1]; + for (SupportElement &elem : layer) { + assert(! elem.state.deleted); + for (int32_t iparent : elem.parents) { + SupportElement &parent = above[iparent]; + assert(! parent.state.deleted); + assert(elem.state.result_on_layer_is_set() == parent.state.result_on_layer_is_set()); + if (elem.state.result_on_layer_is_set()) { + double radius_increase = config.getRadius(elem.state) - config.getRadius(parent.state); + assert(radius_increase >= 0); + double shift = (elem.state.result_on_layer - parent.state.result_on_layer).cast().norm(); + assert(shift < radius_increase + 2. * config.maximum_move_distance_slow); + } + } + } + } +#endif // NDEBUG } // For producing circular / elliptical areas from SupportElements (one DrawArea per one SupportElement) @@ -2649,7 +2757,8 @@ static void generate_branch_areas(const TreeModelVolumes &volumes, const TreeSup polygons_with_correct_center.emplace_back(std::move(part)); } // Increase the area again, to ensure the nozzle path when calculated later is very similar to the one assumed above. - polygons = diff_clipped(offset(polygons_with_correct_center, config.support_line_width / 2, jtMiter, 1.2), + assert(contains(polygons, draw_area.element->state.result_on_layer)); + polygons = diff_clipped(offset(polygons_with_correct_center, config.support_line_width / 2, jtMiter, 1.2), //FIXME Vojtech: Clipping may split the region into multiple pieces again, reversing the fixing effort. collision); } @@ -2695,10 +2804,12 @@ static void smooth_branch_areas( [&](const tbb::blocked_range &range) { for (size_t processing_idx = range.begin(); processing_idx < range.end(); ++ processing_idx) { DrawArea &draw_area = linear_data[processing_base + processing_idx]; + assert(draw_area.element->state.layer_idx == layer_idx); double max_outer_wall_distance = 0; bool do_something = false; for (int32_t parent_idx : draw_area.element->parents) { const SupportElement &parent = layer_above[parent_idx]; + assert(parent.state.layer_idx == layer_idx + 1); if (config.getRadius(parent.state) != config.getCollisionRadius(parent.state)) { do_something = true; max_outer_wall_distance = std::max(max_outer_wall_distance, (draw_area.element->state.result_on_layer - parent.state.result_on_layer).cast().norm() - (config.getRadius(*draw_area.element) - config.getRadius(parent))); @@ -2706,14 +2817,35 @@ static void smooth_branch_areas( } max_outer_wall_distance += max_radius_change_per_layer; // As this change is a bit larger than what usually appears, lost radius can be slowly reclaimed over the layers. if (do_something) { + assert(contains(draw_area.polygons, draw_area.element->state.result_on_layer)); Polygons max_allowed_area = offset(draw_area.polygons, float(max_outer_wall_distance), jtMiter, 1.2); for (int32_t parent_idx : draw_area.element->parents) { const SupportElement &parent = layer_above[parent_idx]; +#ifndef NDEBUG + assert(parent.state.layer_idx == layer_idx + 1); + assert(contains(linear_data[processing_base_above + parent_idx].polygons, parent.state.result_on_layer)); + double radius_increase = config.getRadius(draw_area.element->state) - config.getRadius(parent.state); + assert(radius_increase >= 0); + double shift = (draw_area.element->state.result_on_layer - parent.state.result_on_layer).cast().norm(); + assert(shift < radius_increase + 2. * config.maximum_move_distance_slow); +#endif // NDEBUG if (config.getRadius(parent.state) != config.getCollisionRadius(parent.state)) { // No other element on this layer than the current one may be connected to &parent, // thus it is safe to update parent's DrawArea directly. Polygons &dst = linear_data[processing_base_above + parent_idx].polygons; - dst = intersection(dst, max_allowed_area); +// Polygons orig = dst; + if (! dst.empty()) { + dst = intersection(dst, max_allowed_area); +#if 0 + if (dst.empty()) { + static int irun = 0; + SVG::export_expolygons(debug_out_path("treesupport-extrude_areas-smooth-error-%d.svg", irun ++), + { { { union_ex(max_allowed_area) }, { "max_allowed_area", "yellow", 0.5f } }, + { { union_ex(orig) }, { "orig", "red", "black", "", scaled(0.1f), 0.5f } } }); + ::MessageBoxA(nullptr, "TreeSupport smoothing bug", "Bug detected!", MB_OK | MB_SYSTEMMODAL | MB_SETFOREGROUND | MB_ICONWARNING); + } +#endif + } } } } @@ -2982,9 +3114,7 @@ static void draw_areas( // Only one link points to a node above from below. assert(! (++ it != map_downwards_old.end() && it->first == &elem)); } - if ((! child && elem.state.target_height == layer_idx) || (child && !child->state.result_on_layer_is_set())) - // We either come from nowhere at the final layer or we had invalid parents 2. should never happen but just to be sure - continue; + assert(child ? child->state.result_on_layer_is_set() : elem.state.target_height > layer_idx); } for (int32_t parent_idx : elem.parents) { SupportElement &parent = (*layer_above)[parent_idx]; @@ -2998,12 +3128,66 @@ static void draw_areas( linear_data_layers.emplace_back(linear_data.size()); } +#ifndef NDEBUG + for (size_t i = 0; i < move_bounds.size(); ++ i) { + size_t begin = linear_data_layers[i]; + size_t end = linear_data_layers[i + 1]; + for (size_t j = begin; j < end; ++ j) + assert(linear_data[j].element == &move_bounds[i][j - begin]); + } +#endif // NDEBUG + auto t_start = std::chrono::high_resolution_clock::now(); // Generate the circles that will be the branches. generate_branch_areas(volumes, config, move_bounds, linear_data); + +#if 0 + assert(linear_data_layers.size() == move_bounds.size() + 1); + for (const auto &draw_area : linear_data) + assert(contains(draw_area.polygons, draw_area.element->state.result_on_layer)); + for (size_t i = 0; i < move_bounds.size(); ++ i) { + size_t begin = linear_data_layers[i]; + size_t end = linear_data_layers[i + 1]; + for (size_t j = begin; j < end; ++ j) { + const auto &draw_area = linear_data[j]; + assert(draw_area.element == &move_bounds[i][j - begin]); + assert(contains(draw_area.polygons, draw_area.element->state.result_on_layer)); + } + } +#endif + +#if 0 + for (size_t area_layer_idx = 0; area_layer_idx + 1 < linear_data_layers.size(); ++ area_layer_idx) { + size_t begin = linear_data_layers[area_layer_idx]; + size_t end = linear_data_layers[area_layer_idx + 1]; + Polygons polygons; + for (size_t area_idx = begin; area_idx < end; ++ area_idx) { + DrawArea &area = linear_data[area_idx]; + append(polygons, area.polygons); + } + SVG::export_expolygons(debug_out_path("treesupport-extrude_areas-raw-%d.svg", area_layer_idx), + { { { union_ex(polygons) }, { "parent", "red", "black", "", scaled(0.1f), 0.5f } } }); + } +#endif + auto t_generate = std::chrono::high_resolution_clock::now(); // In some edgecases a branch may go though a hole, where the regular radius does not fit. This can result in an apparent jump in branch radius. As such this cases need to be caught and smoothed out. smooth_branch_areas(config, move_bounds, linear_data, linear_data_layers); + +#if 0 + for (size_t area_layer_idx = 0; area_layer_idx + 1 < linear_data_layers.size(); ++area_layer_idx) { + size_t begin = linear_data_layers[area_layer_idx]; + size_t end = linear_data_layers[area_layer_idx + 1]; + Polygons polygons; + for (size_t area_idx = begin; area_idx < end; ++area_idx) { + DrawArea& area = linear_data[area_idx]; + append(polygons, area.polygons); + } + SVG::export_expolygons(debug_out_path("treesupport-extrude_areas-smooth-%d.svg", area_layer_idx), + { { { union_ex(polygons) }, { "parent", "red", "black", "", scaled(0.1f), 0.5f } } }); + } +#endif + auto t_smooth = std::chrono::high_resolution_clock::now(); // drop down all trees that connect non gracefully with the model drop_non_gracious_areas(volumes, linear_data, support_layer_storage); @@ -3044,6 +3228,491 @@ static void draw_areas( "finalize_interface_and_support_areas " << dur_finalize << " ms"; } +#if 1 +// Test whether two circles, each on its own plane in 3D intersect. +// Circles are considered intersecting, if the lowest point on one circle is below the other circle's plane. +// Assumption: The two planes are oriented the same way. +static bool circles_intersect( + const Vec3d &p1, const Vec3d &n1, const double r1, + const Vec3d &p2, const Vec3d &n2, const double r2) +{ + assert(n1.dot(n2) >= 0); + + const Vec3d z = n1.cross(n2); + const Vec3d dir1 = z.cross(n1); + const Vec3d lowest_point1 = p1 + dir1 * (r1 / dir1.norm()); + assert(n2.dot(p1) >= n2.dot(lowest_point1)); + if (n2.dot(lowest_point1) <= 0) + return true; + const Vec3d dir2 = z.cross(n2); + const Vec3d lowest_point2 = p2 + dir2 * (r2 / dir2.norm()); + assert(n1.dot(p2) >= n1.dot(lowest_point2)); + return n1.dot(lowest_point2) <= 0; +} + +template +void triangulate_fan(indexed_triangle_set &its, int ifan, int ibegin, int iend) +{ + // at least 3 vertices, increasing order. + assert(ibegin + 3 <= iend); + assert(ibegin >= 0 && iend <= its.vertices.size()); + assert(ifan >= 0 && ifan < its.vertices.size()); + int num_faces = iend - ibegin; + its.indices.reserve(its.indices.size() + num_faces * 3); + for (int v = ibegin, u = iend - 1; v < iend; u = v ++) { + if (flip_normals) + its.indices.push_back({ ifan, u, v }); + else + its.indices.push_back({ ifan, v, u }); + } +} + +static void triangulate_strip(indexed_triangle_set &its, int ibegin1, int iend1, int ibegin2, int iend2) +{ + // at least 3 vertices, increasing order. + assert(ibegin1 + 3 <= iend1); + assert(ibegin1 >= 0 && iend1 <= its.vertices.size()); + assert(ibegin2 + 3 <= iend2); + assert(ibegin2 >= 0 && iend2 <= its.vertices.size()); + int n1 = iend1 - ibegin1; + int n2 = iend2 - ibegin2; + its.indices.reserve(its.indices.size() + (n1 + n2) * 3); + + // For the first vertex of 1st strip, find the closest vertex on the 2nd strip. + int istart2 = ibegin2; + { + const Vec3f &p1 = its.vertices[ibegin1]; + auto d2min = std::numeric_limits::max(); + for (int i = ibegin2; i < iend2; ++ i) { + const Vec3f &p2 = its.vertices[i]; + const float d2 = (p2 - p1).squaredNorm(); + if (d2 < d2min) { + d2min = d2; + istart2 = i; + } + } + } + + // Now triangulate the strip zig-zag fashion taking always the shortest connection if possible. + for (int u = ibegin1, v = istart2; n1 > 0 || n2 > 0;) { + bool take_first; + int u2, v2; + auto update_u2 = [&u2, u, ibegin1, iend1]() { + u2 = u; + if (++ u2 == iend1) + u2 = ibegin1; + }; + auto update_v2 = [&v2, v, ibegin2, iend2]() { + v2 = v; + if (++ v2 == iend2) + v2 = ibegin2; + }; + if (n1 == 0) { + take_first = false; + update_v2(); + } else if (n2 == 0) { + take_first = true; + update_u2(); + } else { + update_u2(); + update_v2(); + float l1 = (its.vertices[u2] - its.vertices[v]).squaredNorm(); + float l2 = (its.vertices[v2] - its.vertices[u]).squaredNorm(); + take_first = l1 < l2; + } + if (take_first) { + its.indices.push_back({ u, u2, v }); + -- n1; + u = u2; + } else { + its.indices.push_back({ u, v2, v }); + -- n2; + v = v2; + } + } +} + +// Discretize 3D circle, append to output vector, return ranges of indices of the points added. +static std::pair discretize_circle(const Vec3f ¢er, const Vec3f &normal, const float radius, const float eps, std::vector &pts) +{ + // Calculate discretization step and number of steps. + float angle_step = 2. * acos(1. - eps / radius); + auto nsteps = int(ceil(2 * M_PI / angle_step)); + angle_step = 2 * M_PI / nsteps; + + // Prepare coordinate system for the circle plane. + Vec3f x = normal.cross(Vec3f(0.f, -1.f, 0.f)).normalized(); + Vec3f y = normal.cross(x).normalized(); + assert(std::abs(x.cross(y).dot(normal) - 1.f) < EPSILON); + + // Discretize the circle. + int begin = int(pts.size()); + pts.reserve(pts.size() + nsteps); + float angle = 0; + x *= radius; + y *= radius; + for (int i = 0; i < nsteps; ++ i) { + pts.emplace_back(center + x * cos(angle) + y * sin(angle)); + angle += angle_step; + } + return { begin, int(pts.size()) }; +} + +static void extrude_branch( + const std::vector &path, + const TreeSupportSettings &config, + const SlicingParameters &slicing_params, + const std::vector &move_bounds, + indexed_triangle_set &result) +{ + Vec3d p1, p2, p3; + Vec3d v1, v2; + Vec3d nprev; + Vec3d ncurrent; + assert(path.size() >= 2); + static constexpr const float eps = 0.015f; + std::pair prev_strip; + +// char fname[2048]; +// static int irun = 0; + + for (size_t ipath = 1; ipath < path.size(); ++ ipath) { + const SupportElement &prev = *path[ipath - 1]; + const SupportElement ¤t = *path[ipath]; + assert(prev.state.layer_idx + 1 == current.state.layer_idx); + p1 = to_3d(unscaled(prev .state.result_on_layer), layer_z(slicing_params, prev .state.layer_idx)); + p2 = to_3d(unscaled(current.state.result_on_layer), layer_z(slicing_params, current.state.layer_idx)); + v1 = (p2 - p1).normalized(); + if (ipath == 1) { + nprev = v1; + // Extrude the bottom half sphere. + float radius = unscaled(config.getRadius(prev.state)); + float angle_step = 2. * acos(1. - eps / radius); + auto nsteps = int(ceil(M_PI / (2. * angle_step))); + angle_step = M_PI / (2. * nsteps); + int ifan = int(result.vertices.size()); + result.vertices.emplace_back((p1 - nprev * radius).cast()); + float angle = angle_step; + for (int i = 1; i < nsteps; ++ i, angle += angle_step) { + std::pair strip = discretize_circle((p1 - nprev * radius * cos(angle)).cast(), nprev.cast(), radius * sin(angle), eps, result.vertices); + if (i == 1) + triangulate_fan(result, ifan, strip.first, strip.second); + else + triangulate_strip(result, prev_strip.first, prev_strip.second, strip.first, strip.second); +// sprintf(fname, "d:\\temp\\meshes\\tree-partial-%d.obj", ++ irun); +// its_write_obj(result, fname); + prev_strip = strip; + } + } + if (ipath + 1 == path.size()) { + // End of the tube. + ncurrent = v1; + // Extrude the top half sphere. + float radius = unscaled(config.getRadius(current.state)); + float angle_step = 2. * acos(1. - eps / radius); + auto nsteps = int(ceil(M_PI / (2. * angle_step))); + angle_step = M_PI / (2. * nsteps); + auto angle = float(M_PI / 2.); + for (int i = 0; i < nsteps; ++ i, angle -= angle_step) { + std::pair strip = discretize_circle((p2 + ncurrent * radius * cos(angle)).cast(), ncurrent.cast(), radius * sin(angle), eps, result.vertices); + triangulate_strip(result, prev_strip.first, prev_strip.second, strip.first, strip.second); +// sprintf(fname, "d:\\temp\\meshes\\tree-partial-%d.obj", ++ irun); +// its_write_obj(result, fname); + prev_strip = strip; + } + int ifan = int(result.vertices.size()); + result.vertices.emplace_back((p2 + ncurrent * radius).cast()); + triangulate_fan(result, ifan, prev_strip.first, prev_strip.second); +// sprintf(fname, "d:\\temp\\meshes\\tree-partial-%d.obj", ++ irun); +// its_write_obj(result, fname); + } else { + const SupportElement &next = *path[ipath + 1]; + assert(current.state.layer_idx + 1 == next.state.layer_idx); + p3 = to_3d(unscaled(next.state.result_on_layer), layer_z(slicing_params, next.state.layer_idx)); + v2 = (p3 - p2).normalized(); + ncurrent = (v1 + v2).normalized(); + float radius = unscaled(config.getRadius(current.state)); + std::pair strip = discretize_circle(p2.cast(), ncurrent.cast(), radius, eps, result.vertices); + triangulate_strip(result, prev_strip.first, prev_strip.second, strip.first, strip.second); + prev_strip = strip; +// sprintf(fname, "d:\\temp\\meshes\\tree-partial-%d.obj", ++irun); +// its_write_obj(result, fname); + } +#if 0 + if (circles_intersect(p1, nprev, settings.getRadius(prev), p2, ncurrent, settings.getRadius(current))) { + // Cannot connect previous and current slice using a simple zig-zag triangulation, + // because the two circles intersect. + + } else { + // Continue with chaining. + + } +#endif + } +} +#endif + +static void draw_branches( + PrintObject &print_object, + const TreeModelVolumes &volumes, + const TreeSupportSettings &config, + const std::vector &overhangs, + std::vector &move_bounds, + + SupportGeneratorLayersPtr &bottom_contacts, + SupportGeneratorLayersPtr &top_contacts, + SupportGeneratorLayersPtr &intermediate_layers, + SupportGeneratorLayerStorage &layer_storage) +{ + static int irun = 0; + + const SlicingParameters& slicing_params = print_object.slicing_parameters(); + + // All SupportElements are put into a layer independent storage to improve parallelization. + std::vector> elements_with_link_down; + std::vector linear_data_layers; + { + std::vector> map_downwards_old; + std::vector> map_downwards_new; + linear_data_layers.emplace_back(0); + for (LayerIndex layer_idx = 0; layer_idx < LayerIndex(move_bounds.size()); ++ layer_idx) { + SupportElements *layer_above = layer_idx + 1 < move_bounds.size() ? &move_bounds[layer_idx + 1] : nullptr; + map_downwards_new.clear(); + std::sort(map_downwards_old.begin(), map_downwards_old.end(), [](auto& l, auto& r) { return l.first < r.first; }); + SupportElements &layer = move_bounds[layer_idx]; + for (size_t elem_idx = 0; elem_idx < layer.size(); ++ elem_idx) { + SupportElement &elem = layer[elem_idx]; + int child = -1; + if (layer_idx > 0) { + auto it = std::lower_bound(map_downwards_old.begin(), map_downwards_old.end(), &elem, [](auto& l, const SupportElement* r) { return l.first < r; }); + if (it != map_downwards_old.end() && it->first == &elem) { + child = it->second; + // Only one link points to a node above from below. + assert(!(++it != map_downwards_old.end() && it->first == &elem)); + } + const SupportElement *pchild = child == -1 ? nullptr : &move_bounds[layer_idx - 1][child]; + assert(pchild ? pchild->state.result_on_layer_is_set() : elem.state.target_height > layer_idx); + } + for (int32_t parent_idx : elem.parents) { + SupportElement &parent = (*layer_above)[parent_idx]; + if (parent.state.result_on_layer_is_set()) + map_downwards_new.emplace_back(&parent, elem_idx); + } + + elements_with_link_down.push_back({ &elem, int(child) }); + } + std::swap(map_downwards_old, map_downwards_new); + linear_data_layers.emplace_back(elements_with_link_down.size()); + } + } + + std::unique_ptr> closest_surface_point; + { + TriangleMesh mesh = print_object.model_object()->raw_mesh(); + mesh.transform(print_object.trafo_centered()); + double scale = 10.; + openvdb::FloatGrid::Ptr grid = mesh_to_grid(mesh.its, {}, scale, 0., 0.); + closest_surface_point = openvdb::tools::ClosestSurfacePoint::create(*grid); + std::vector pts, prev, projections; + std::vector distances; + for (const std::pair &element : elements_with_link_down) { + Vec3d pt = to_3d(unscaled(element.first->state.result_on_layer), layer_z(slicing_params, element.first->state.layer_idx)) * scale; + pts.push_back({ pt.x(), pt.y(), pt.z() }); + } + + const double collision_extra_gap = 1. * scale; + const double max_nudge_collision_avoidance = 2. * scale; + const double max_nudge_smoothing = 1. * scale; + + static constexpr const size_t num_iter = 100; // 1000; + for (size_t iter = 0; iter < num_iter; ++ iter) { + prev = pts; + projections = pts; + distances.assign(pts.size(), std::numeric_limits::max()); + closest_surface_point->searchAndReplace(projections, distances); + size_t num_moved = 0; + for (size_t i = 0; i < projections.size(); ++ i) { + const SupportElement &element = *elements_with_link_down[i].first; + const int below = elements_with_link_down[i].second; + const bool locked = below == -1 && element.state.layer_idx > 0; + if (! locked && pts[i] != projections[i]) { + // Nudge the circle center away from the collision. + Vec3d v{ projections[i].x() - pts[i].x(), projections[i].y() - pts[i].y(), projections[i].z() - pts[i].z() }; + double depth = v.norm(); + assert(std::abs(distances[i] - depth) < EPSILON); + double radius = unscaled(config.getRadius(element.state)) * scale; + if (depth < radius) { + // Collision detected to be removed. + ++ num_moved; + double dxy = sqrt(sqr(radius) - sqr(v.z())); + double nudge_dist_max = dxy - std::hypot(v.x(), v.y()) + //FIXME 1mm gap + + collision_extra_gap; + // Shift by maximum 2mm. + double nudge_dist = std::min(std::max(0., nudge_dist_max), max_nudge_collision_avoidance); + Vec2d nudge_v = to_2d(v).normalized() * (- nudge_dist); + pts[i].x() += nudge_v.x(); + pts[i].y() += nudge_v.y(); + } + } + // Laplacian smoothing + if (! locked && ! element.parents.empty()) { + Vec2d avg{ 0, 0 }; + const SupportElements &above = move_bounds[element.state.layer_idx + 1]; + const size_t offset_above = linear_data_layers[element.state.layer_idx + 1]; + double weight = 0.; + for (auto iparent : element.parents) { + double w = config.getRadius(above[iparent].state); + avg.x() += w * prev[offset_above + iparent].x(); + avg.y() += w * prev[offset_above + iparent].y(); + weight += w; + } + size_t cnt = element.parents.size(); + if (below != -1) { + const size_t offset_below = linear_data_layers[element.state.layer_idx - 1]; + const double w = weight; // config.getRadius(move_bounds[element.state.layer_idx - 1][below].state); + avg.x() += w * prev[offset_below + below].x(); + avg.y() += w * prev[offset_below + below].y(); + ++ cnt; + weight += w; + } + //avg /= double(cnt); + avg /= weight; + static constexpr const double smoothing_factor = 0.5; + Vec2d old_pos{ pts[i].x(), pts[i].y() }; + Vec2d new_pos = (1. - smoothing_factor) * old_pos + smoothing_factor * avg; + Vec2d shift = new_pos - old_pos; + double nudge_dist_max = shift.norm(); + // Shift by maximum 1mm, less than the collision avoidance factor. + double nudge_dist = std::min(std::max(0., nudge_dist_max), max_nudge_smoothing); + Vec2d nudge_v = shift.normalized() * nudge_dist; + pts[i].x() += nudge_v.x(); + pts[i].y() += nudge_v.y(); + } + } + printf("iteration: %d, moved: %d\n", int(iter), int(num_moved)); + if (num_moved == 0) + break; + } + +#if 1 + for (size_t i = 0; i < projections.size(); ++ i) { + elements_with_link_down[i].first->state.result_on_layer.x() = scaled(pts[i].x()) / scale; + elements_with_link_down[i].first->state.result_on_layer.y() = scaled(pts[i].y()) / scale; + } +#endif + } + + std::vector support_layer_storage(move_bounds.size()); + std::vector support_roof_storage(move_bounds.size()); + + // Unmark all nodes. + for (SupportElements &elements : move_bounds) + for (SupportElement &element : elements) + element.state.marked = false; + + // Traverse all nodes, generate tubes. + // Traversal stack with nodes and thier current parent + std::vector path; + indexed_triangle_set cummulative_mesh; + indexed_triangle_set partial_mesh; + indexed_triangle_set temp_mesh; + for (LayerIndex layer_idx = 0; layer_idx + 1 < LayerIndex(move_bounds.size()); ++ layer_idx) { + SupportElements &layer = move_bounds[layer_idx]; + SupportElements &layer_above = move_bounds[layer_idx + 1]; + + for (SupportElement &start_element : layer) + if (! start_element.state.marked && ! start_element.parents.empty()) { + // Collect elements up to a bifurcation above. + start_element.state.marked = true; + for (size_t parent_idx = 0; parent_idx < start_element.parents.size(); ++ parent_idx) { + path.clear(); + path.emplace_back(&start_element); + // Traverse each branch until it branches again. + SupportElement &first_parent = layer_above[start_element.parents[parent_idx]]; + assert(path.back()->state.layer_idx + 1 == first_parent.state.layer_idx); + path.emplace_back(&first_parent); + if (first_parent.parents.size() < 2) + first_parent.state.marked = true; + if (first_parent.parents.size() == 1) { + for (SupportElement *parent = &first_parent;;) { + SupportElement &next_parent = move_bounds[parent->state.layer_idx + 1][parent->parents.front()]; + assert(path.back()->state.layer_idx + 1 == next_parent.state.layer_idx); + path.emplace_back(&next_parent); + if (next_parent.parents.size() > 1) + break; + next_parent.state.marked = true; + if (next_parent.parents.size() == 0) + break; + parent = &next_parent; + } + } + // Triangulate the tube. + partial_mesh.clear(); + extrude_branch(path, config, slicing_params, move_bounds, partial_mesh); +#if 0 + char fname[2048]; + sprintf(fname, "d:\\temp\\meshes\\tree-raw-%d.obj", ++ irun); + its_write_obj(partial_mesh, fname); +#if 0 + temp_mesh.clear(); + cut_mesh(partial_mesh, layer_z(slicing_params, path.back()->state.layer_idx) + EPSILON, nullptr, &temp_mesh, false); + sprintf(fname, "d:\\temp\\meshes\\tree-trimmed1-%d.obj", irun); + its_write_obj(temp_mesh, fname); + partial_mesh.clear(); + cut_mesh(temp_mesh, layer_z(slicing_params, path.front()->state.layer_idx) - EPSILON, &partial_mesh, nullptr, false); + sprintf(fname, "d:\\temp\\meshes\\tree-trimmed2-%d.obj", irun); +#endif + its_write_obj(partial_mesh, fname); +#endif + its_merge(cummulative_mesh, partial_mesh); + } + } + } + + std::vector slice_z; + for (size_t layer_idx = 0; layer_idx < move_bounds.size(); ++ layer_idx) { + double print_z = slicing_params.object_print_z_min + slicing_params.first_object_layer_height + layer_idx * slicing_params.layer_height; + double layer_height = layer_idx == 0 ? slicing_params.first_object_layer_height : slicing_params.layer_height; + slice_z.emplace_back(float(print_z - layer_height * 0.5)); + } + // Remove the trailing slices. + while (! slice_z.empty()) + if (move_bounds[slice_z.size() - 1].empty()) + slice_z.pop_back(); + else + break; + +#if 0 + its_write_obj(cummulative_mesh, "d:\\temp\\meshes\\tree.obj"); +#endif + + MeshSlicingParamsEx params; + params.closing_radius = float(print_object.config().slice_closing_radius.value); + params.mode = MeshSlicingParams::SlicingMode::Positive; + std::vector slices = slice_mesh_ex(cummulative_mesh, slice_z, params); + for (size_t layer_idx = 0; layer_idx < slice_z.size(); ++ layer_idx) + if (! slices[layer_idx].empty()) { + SupportGeneratorLayer *&l = intermediate_layers[layer_idx]; + if (l == nullptr) + l = &layer_allocate(layer_storage, SupporLayerType::Base, slicing_params, layer_idx); + append(l->polygons, to_polygons(std::move(slices[layer_idx]))); + } + + // Trim the slices. + tbb::parallel_for(tbb::blocked_range(0, intermediate_layers.size()), + [&](const tbb::blocked_range &range) { + for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) + if (SupportGeneratorLayer *layer = intermediate_layers[layer_idx]; layer) { + Polygons &poly = intermediate_layers[layer_idx]->polygons; + poly = diff_clipped(poly, volumes.getCollision(0, layer_idx, true)); + } + }); + + finalize_interface_and_support_areas(print_object, volumes, config, overhangs, support_layer_storage, support_roof_storage, + bottom_contacts, top_contacts, intermediate_layers, layer_storage); +} + /*! * \brief Create the areas that need support. * @@ -3147,8 +3816,15 @@ static void generate_support_areas(Print &print, const BuildVolume &build_volume auto t_place = std::chrono::high_resolution_clock::now(); // ### draw these points as circles - draw_areas(*print.get_object(processing.second.front()), volumes, config, overhangs, move_bounds, - bottom_contacts, top_contacts, intermediate_layers, layer_storage); + + if (print_object.config().support_material_style == smsTree) + draw_areas(*print.get_object(processing.second.front()), volumes, config, overhangs, move_bounds, + bottom_contacts, top_contacts, intermediate_layers, layer_storage); + else { + assert(print_object.config().support_material_style == smsOrganic); + draw_branches(*print.get_object(processing.second.front()), volumes, config, overhangs, move_bounds, + bottom_contacts, top_contacts, intermediate_layers, layer_storage); + } auto t_draw = std::chrono::high_resolution_clock::now(); auto dur_pre_gen = 0.001 * std::chrono::duration_cast(t_precalc - t_start).count(); @@ -3232,7 +3908,7 @@ static void generate_support_areas(Print &print, const BuildVolume &build_volume void fff_tree_support_generate(PrintObject &print_object, std::function throw_on_cancel) { size_t idx = 0; - for (PrintObject* po : print_object.print()->objects()) { + for (const PrintObject *po : print_object.print()->objects()) { if (po == &print_object) break; ++idx; diff --git a/src/libslic3r/TriangulateWall.cpp b/src/libslic3r/TriangulateWall.cpp deleted file mode 100644 index eb710d9a57..0000000000 --- a/src/libslic3r/TriangulateWall.cpp +++ /dev/null @@ -1,159 +0,0 @@ -#include "TriangulateWall.hpp" -#include "MTUtils.hpp" - -namespace Slic3r { - -//class Ring { -// size_t idx = 0, nextidx = 1, startidx = 0, begin = 0, end = 0; - -//public: -// explicit Ring(size_t from, size_t to) : begin(from), end(to) { init(begin); } - -// size_t size() const { return end - begin; } -// std::pair pos() const { return {idx, nextidx}; } -// bool is_lower() const { return idx < size(); } - -// void inc() -// { -// if (nextidx != startidx) nextidx++; -// if (nextidx == end) nextidx = begin; -// idx ++; -// if (idx == end) idx = begin; -// } - -// void init(size_t pos) -// { -// startidx = begin + (pos - begin) % size(); -// idx = startidx; -// nextidx = begin + (idx + 1 - begin) % size(); -// } - -// bool is_finished() const { return nextidx == idx; } -//}; - -//template -//static Sc sq_dst(const Vec<3, Sc> &v1, const Vec<3, Sc>& v2) -//{ -// Vec<3, Sc> v = v1 - v2; -// return v.x() * v.x() + v.y() * v.y() /*+ v.z() * v.z()*/; -//} - -//template -//static Sc trscore(const Ring & onring, -// const Ring & offring, -// const std::vector> &pts) -//{ -// Sc a = sq_dst(pts[onring.pos().first], pts[offring.pos().first]); -// Sc b = sq_dst(pts[onring.pos().second], pts[offring.pos().first]); -// return (std::abs(a) + std::abs(b)) / 2.; -//} - -//template -//class Triangulator { -// const std::vector> *pts; -// Ring *onring, *offring; - -// double calc_score() const -// { -// return trscore(*onring, *offring, *pts); -// } - -// void synchronize_rings() -// { -// Ring lring = *offring; -// auto minsc = trscore(*onring, lring, *pts); -// size_t imin = lring.pos().first; - -// lring.inc(); - -// while(!lring.is_finished()) { -// double score = trscore(*onring, lring, *pts); -// if (score < minsc) { minsc = score; imin = lring.pos().first; } -// lring.inc(); -// } - -// offring->init(imin); -// } - -// void emplace_indices(std::vector &indices) -// { -// Vec3i tr{int(onring->pos().first), int(onring->pos().second), -// int(offring->pos().first)}; -// if (onring->is_lower()) std::swap(tr(0), tr(1)); -// indices.emplace_back(tr); -// } - -//public: -// void run(std::vector &indices) -// { -// synchronize_rings(); - -// double score = 0, prev_score = 0; -// while (!onring->is_finished() || !offring->is_finished()) { -// prev_score = score; -// if (onring->is_finished() || (score = calc_score()) > prev_score) { -// std::swap(onring, offring); -// } else { -// emplace_indices(indices); -// onring->inc(); -// } -// } -// } - -// explicit Triangulator(const std::vector> *points, -// Ring & lower, -// Ring & upper) -// : pts{points}, onring{&upper}, offring{&lower} -// {} -//}; - -//template -//void triangulate_wall(std::vector> &pts, -// std::vector> & ind, -// const Polygon & lower, -// const Polygon & upper, -// double lower_z_mm, -// double upper_z_mm) -//{ -// if (upper.points.size() < 3 || lower.points.size() < 3) return; - -// pts.reserve(lower.points.size() + upper.points.size()); -// for (auto &p : lower.points) -// pts.emplace_back(unscaled(p.x()), unscaled(p.y()), lower_z_mm); -// for (auto &p : upper.points) -// pts.emplace_back(unscaled(p.x()), unscaled(p.y()), upper_z_mm); - -// ind.reserve(2 * (lower.size() + upper.size())); - -// Ring lring{0, lower.points.size()}, uring{lower.points.size(), pts.size()}; -// Triangulator t{&pts, lring, uring}; -// t.run(ind); -//} - -//Wall triangulate_wall(const Polygon &lower, -// const Polygon &upper, -// double lower_z_mm, -// double upper_z_mm) -//{ -// if (upper.points.size() < 3 || lower.points.size() < 3) return {}; - -// Wall wall; -// auto &pts = wall.first; -// auto &ind = wall.second; - -// pts.reserve(lower.points.size() + upper.points.size()); -// for (auto &p : lower.points) -// wall.first.emplace_back(unscaled(p.x()), unscaled(p.y()), lower_z_mm); -// for (auto &p : upper.points) -// wall.first.emplace_back(unscaled(p.x()), unscaled(p.y()), upper_z_mm); - -// ind.reserve(2 * (lower.size() + upper.size())); - -// Ring lring{0, lower.points.size()}, uring{lower.points.size(), pts.size()}; -// Triangulator t{&pts, lring, uring}; -// t.run(ind); - -// return wall; -//} - -} // namespace Slic3r diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 9945b40471..cedc7ef2a6 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -912,7 +912,6 @@ void GLVolumeCollection::load_object_auxiliary( } #if ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL #if ENABLE_OPENGL_ES int GLVolumeCollection::load_wipe_tower_preview( float pos_x, float pos_y, float width, float depth, float height, @@ -923,26 +922,9 @@ int GLVolumeCollection::load_wipe_tower_preview( float rotation_angle, bool size_unknown, float brim_width) #endif // ENABLE_OPENGL_ES #else -#if ENABLE_OPENGL_ES -int GLVolumeCollection::load_wipe_tower_preview( - int obj_idx, float pos_x, float pos_y, float width, float depth, float height, - float rotation_angle, bool size_unknown, float brim_width, TriangleMesh* out_mesh) -#else -int GLVolumeCollection::load_wipe_tower_preview( - int obj_idx, float pos_x, float pos_y, float width, float depth, float height, - float rotation_angle, bool size_unknown, float brim_width) -#endif // ENABLE_OPENGL_ES -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL -#else -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL int GLVolumeCollection::load_wipe_tower_preview( float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized) -#else -int GLVolumeCollection::load_wipe_tower_preview( - int obj_idx, float pos_x, float pos_y, float width, float depth, float height, - float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized) -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL #endif // ENABLE_LEGACY_OPENGL_REMOVAL { if (depth < 0.01f) @@ -1210,11 +1192,7 @@ int GLVolumeCollection::load_wipe_tower_preview( #endif // !ENABLE_LEGACY_OPENGL_REMOVAL v.set_volume_offset(Vec3d(pos_x, pos_y, 0.0)); v.set_volume_rotation(Vec3d(0., 0., (M_PI / 180.) * rotation_angle)); -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL - v.composite_id = GLVolume::CompositeID(INT_MAX, 0, 0); -#else - v.composite_id = GLVolume::CompositeID(obj_idx, 0, 0); -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL + v.composite_id = GLVolume::CompositeID(INT_MAX, 0, 0); v.geometry_id.first = 0; v.geometry_id.second = wipe_tower_instance_id().id; v.is_wipe_tower = true; diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index b48ad90a82..1e8897c4e0 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -668,7 +668,6 @@ public: // Timestamp of the last change of the milestone size_t timestamp); -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL #if ENABLE_OPENGL_ES int load_wipe_tower_preview( float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, TriangleMesh* out_mesh = nullptr); @@ -676,15 +675,6 @@ public: int load_wipe_tower_preview( float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width); #endif // ENABLE_OPENGL_ES -#else -#if ENABLE_OPENGL_ES - int load_wipe_tower_preview( - int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, TriangleMesh* out_mesh = nullptr); -#else - int load_wipe_tower_preview( - int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width); -#endif // ENABLE_OPENGL_ES -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL #else std::vector load_object( const ModelObject *model_object, @@ -710,13 +700,8 @@ public: size_t timestamp, bool opengl_initialized); -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL int load_wipe_tower_preview( float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized); -#else - int load_wipe_tower_preview( - int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized); -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL #endif // ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_LEGACY_OPENGL_REMOVAL diff --git a/src/slic3r/GUI/ConfigWizard_private.hpp b/src/slic3r/GUI/ConfigWizard_private.hpp index aa074f9253..d757eed634 100644 --- a/src/slic3r/GUI/ConfigWizard_private.hpp +++ b/src/slic3r/GUI/ConfigWizard_private.hpp @@ -75,7 +75,7 @@ struct Bundle const std::string& vendor_id() const { return vendor_profile->id; } }; -struct BundleMap : std::unordered_map +struct BundleMap : std::map { static BundleMap load(); diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index 717af39ba8..31b2c5c90e 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -2123,13 +2123,13 @@ void Control::show_cog_icon_context_menu() GUI::wxGetApp().plater()->PopupMenu(&menu); } -bool check_color_change(PrintObject* object, size_t frst_layer_id, size_t layers_cnt, bool check_overhangs, std::function break_condition) +bool check_color_change(const PrintObject* object, size_t frst_layer_id, size_t layers_cnt, bool check_overhangs, std::function break_condition) { double prev_area = area(object->get_layer(frst_layer_id)->lslices); bool detected = false; for (size_t i = frst_layer_id+1; i < layers_cnt; i++) { - Layer* layer = object->get_layer(i); + const Layer* layer = object->get_layer(i); double cur_area = area(layer->lslices); // check for overhangs @@ -2169,7 +2169,7 @@ void Control::auto_color_change() if (object->layer_count() < 2) continue; - check_color_change(object, 1, object->layers().size(), false, [this, extruders_cnt](Layer* layer) + check_color_change(object, 1, object->layers().size(), false, [this, extruders_cnt](const Layer* layer) { int tick = get_tick_from_value(layer->print_z); if (tick >= 0 && !m_ticks.has_tick(tick)) { diff --git a/src/slic3r/GUI/DoubleSlider.hpp b/src/slic3r/GUI/DoubleSlider.hpp index e4654d6047..3a862c2868 100644 --- a/src/slic3r/GUI/DoubleSlider.hpp +++ b/src/slic3r/GUI/DoubleSlider.hpp @@ -31,10 +31,10 @@ constexpr double epsilon() { return 0.0011; } bool equivalent_areas(const double& bottom_area, const double& top_area); // return true if color change was detected -bool check_color_change(PrintObject* object, size_t frst_layer_id, size_t layers_cnt, bool check_overhangs, +bool check_color_change(const PrintObject* object, size_t frst_layer_id, size_t layers_cnt, bool check_overhangs, // what to do with detected color change // and return true when detection have to be desturbed - std::function break_condition); + std::function break_condition); // custom message the slider sends to its parent to notify a tick-change: wxDECLARE_EVENT(wxCUSTOMEVT_TICKSCHANGED, wxEvent); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index be232c178b..562c67cebc 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -2349,21 +2349,11 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) const float brim_width = print.wipe_tower_data(extruders_count).brim_width; #if ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL m_shells.volumes.load_wipe_tower_preview(config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle, !print.is_step_done(psWipeTower), brim_width); #else - m_shells.volumes.load_wipe_tower_preview(1000, config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle, - !print.is_step_done(psWipeTower), brim_width); -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL -#else -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL m_shells.volumes.load_wipe_tower_preview(config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle, !print.is_step_done(psWipeTower), brim_width, initialized); -#else - m_shells.volumes.load_wipe_tower_preview(1000, config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle, - !print.is_step_done(psWipeTower), brim_width, initialized); -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL #endif // ENABLE_LEGACY_OPENGL_REMOVAL } } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c83e3f9703..25ac882955 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1341,18 +1341,12 @@ ModelInstanceEPrintVolumeState GLCanvas3D::check_volumes_outside_state() const void GLCanvas3D::toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo, int instance_idx) { -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL if (current_printer_technology() != ptSLA) return; -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL m_render_sla_auxiliaries = visible; for (GLVolume* vol : m_volumes.volumes) { -#if !ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL - if (vol->composite_id.object_id == 1000) - continue; // the wipe tower -#endif // !ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL if ((mo == nullptr || m_model->objects[vol->composite_id.object_id] == mo) && (instance_idx == -1 || vol->composite_id.instance_id == instance_idx) && vol->composite_id.volume_id < 0) @@ -1362,15 +1356,12 @@ void GLCanvas3D::toggle_sla_auxiliaries_visibility(bool visible, const ModelObje void GLCanvas3D::toggle_model_objects_visibility(bool visible, const ModelObject* mo, int instance_idx, const ModelVolume* mv) { +#if ENABLE_RAYCAST_PICKING + std::vector>* raycasters = get_raycasters_for_picking(SceneRaycaster::EType::Volume); +#endif // ENABLE_RAYCAST_PICKING for (GLVolume* vol : m_volumes.volumes) { -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL if (vol->is_wipe_tower) vol->is_active = (visible && mo == nullptr); -#else - if (vol->composite_id.object_id == 1000) { // wipe tower - vol->is_active = (visible && mo == nullptr); - } -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL else { if ((mo == nullptr || m_model->objects[vol->composite_id.object_id] == mo) && (instance_idx == -1 || vol->composite_id.instance_id == instance_idx) @@ -1400,6 +1391,11 @@ void GLCanvas3D::toggle_model_objects_visibility(bool visible, const ModelObject } } } +#if ENABLE_RAYCAST_PICKING + auto it = std::find_if(raycasters->begin(), raycasters->end(), [vol](std::shared_ptr item) { return item->get_raycaster() == vol->mesh_raycaster.get(); }); + if (it != raycasters->end()) + (*it)->set_active(vol->is_active); +#endif // ENABLE_RAYCAST_PICKING } if (visible && !mo) @@ -2354,7 +2350,6 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re float brim_width = print->wipe_tower_data(extruders_count).brim_width; #if ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL #if ENABLE_OPENGL_ES int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview( x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower), @@ -2365,26 +2360,9 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re brim_width); #endif // ENABLE_OPENGL_ES #else -#if ENABLE_OPENGL_ES - int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview( - 1000, x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower), - brim_width, &m_wipe_tower_mesh); -#else - int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview( - 1000, x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower), - brim_width); -#endif // ENABLE_OPENGL_ES -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL -#else -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview( x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower), brim_width, m_initialized); -#else - int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview( - 1000, x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower), - brim_width, m_initialized); -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL #endif // ENABLE_LEGACY_OPENGL_REMOVAL if (volume_idx_wipe_tower_old != -1) map_glvolume_old_to_new[volume_idx_wipe_tower_old] = volume_idx_wipe_tower_new; @@ -3868,15 +3846,9 @@ void GLCanvas3D::do_move(const std::string& snapshot_type) model_object->invalidate_bounding_box(); } } -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL else if (v->is_wipe_tower) // Move a wipe tower proxy. wipe_tower_origin = v->get_volume_offset(); -#else - else if (object_idx == 1000) - // Move a wipe tower proxy. - wipe_tower_origin = v->get_volume_offset(); -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL } // Fixes flying instances @@ -3937,18 +3909,11 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type) Selection::EMode selection_mode = m_selection.get_mode(); for (const GLVolume* v : m_volumes.volumes) { -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL if (v->is_wipe_tower) { -#else - int object_idx = v->object_idx(); - if (object_idx == 1000) { // the wipe tower -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL const Vec3d offset = v->get_volume_offset(); post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset.x(), offset.y(), v->get_volume_rotation().z()))); } -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL - int object_idx = v->object_idx(); -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL + const int object_idx = v->object_idx(); if (object_idx < 0 || (int)m_model->objects.size() <= object_idx) continue; diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 4c83e1f0d2..8c7b1db75d 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1989,15 +1989,9 @@ void ObjectList::del_layers_from_object(const int obj_idx) bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, const int type) { assert(idx >= 0); -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL if (m_objects->empty() || int(m_objects->size()) <= obj_idx) // Cannot delete a wipe tower return false; -#else - if (obj_idx == 1000 || idx<0) - // Cannot delete a wipe tower or volume with negative id - return false; -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL ModelObject* object = (*m_objects)[obj_idx]; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 7989c3cdce..93cbca3c4f 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -574,7 +574,7 @@ void Preview::update_layers_slider(const std::vector& layers_z, bool kee if (i < min_solid_height) continue; - if (DoubleSlider::check_color_change(object, i, num_layers, true, [this, object](Layer*) { + if (DoubleSlider::check_color_change(object, i, num_layers, true, [this, object](const Layer*) { NotificationManager* notif_mngr = wxGetApp().plater()->get_notification_manager(); notif_mngr->push_notification( NotificationType::SignDetected, NotificationManager::NotificationLevel::PrintInfoNotificationLevel, diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 802cd3006e..7e3b709d62 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -9,6 +9,7 @@ #include "slic3r/GUI/GUI_App.hpp" #include "slic3r/GUI/Plater.hpp" #include "slic3r/GUI/GUI_ObjectManipulation.hpp" +#include "slic3r/GUI/format.hpp" #include "slic3r/Utils/UndoRedo.hpp" #include "libslic3r/AppConfig.hpp" #include "libslic3r/TriangleMeshSlicer.hpp" diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 2fd0fb7c72..579cbbe675 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -78,14 +78,14 @@ void GLGizmoSlaSupports::data_changed() if (mo) { if (mo->sla_points_status == sla::PointsStatus::Generating) get_data_from_backend(); - } #if ENABLE_RAYCAST_PICKING - if (m_raycasters.empty()) - on_register_raycasters_for_picking(); - else - update_raycasters_for_picking_transform(); + if (m_raycasters.empty()) + on_register_raycasters_for_picking(); + else + update_raycasters_for_picking_transform(); #endif // ENABLE_RAYCAST_PICKING + } } diff --git a/src/slic3r/GUI/MeshUtils.cpp b/src/slic3r/GUI/MeshUtils.cpp index 5ec066f441..e33d29ba16 100644 --- a/src/slic3r/GUI/MeshUtils.cpp +++ b/src/slic3r/GUI/MeshUtils.cpp @@ -252,7 +252,7 @@ void MeshClipper::recalculate_triangles() // it so it lies on our line. This will be the figure to subtract // from the cut. The coordinates must not overflow after the transform, // make the rectangle a bit smaller. - const coord_t size = (std::numeric_limits::max()/2 - scale_(std::max(std::abs(e*a), std::abs(e*b)))) / 4; + const coord_t size = (std::numeric_limits::max()/2 - scale_(std::max(std::abs(e * a), std::abs(e * b)))) / 4; Polygons ep {Polygon({Point(-size, 0), Point(size, 0), Point(size, 2*size), Point(-size, 2*size)})}; ep.front().rotate(angle); ep.front().translate(scale_(-e * a), scale_(-e * b)); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d3bd704d21..22c819ab47 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1254,11 +1254,7 @@ void Sidebar::show_info_sizer() ModelObjectPtrs objects = p->plater->model().objects; int obj_idx = selection.get_object_idx(); -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL if (m_mode < comExpert || objects.empty() || obj_idx < 0 || int(objects.size()) <= obj_idx || -#else - if (m_mode < comExpert || objects.empty() || obj_idx < 0 || obj_idx == 1000 || -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL objects[obj_idx]->volumes.empty() || // hack to avoid crash when deleting the last object on the bed (selection.is_single_full_object() && objects[obj_idx]->instances.size()> 1) || !(selection.is_single_full_instance() || selection.is_single_volume())) { @@ -2193,6 +2189,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) format(_L("Successfully unmounted. The device %s(%s) can now be safely removed from the computer."), evt.data.first.name, evt.data.first.path) ); } else { + notification_manager->close_notification_of_type(NotificationType::ExportFinished); notification_manager->push_notification(NotificationType::CustomNotification, NotificationManager::NotificationLevel::ErrorNotificationLevel, format(_L("Ejecting of device %s(%s) has failed."), evt.data.first.name, evt.data.first.path) @@ -2933,23 +2930,15 @@ Selection& Plater::priv::get_selection() int Plater::priv::get_selected_object_idx() const { - int idx = get_selection().get_object_idx(); -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL + const int idx = get_selection().get_object_idx(); return (0 <= idx && idx < int(model.objects.size())) ? idx : -1; -#else - return ((0 <= idx) && (idx < 1000)) ? idx : -1; -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL } int Plater::priv::get_selected_volume_idx() const { auto& selection = get_selection(); - int idx = selection.get_object_idx(); -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL + const int idx = selection.get_object_idx(); if (idx < 0 || int(model.objects.size()) <= idx) -#else - if ((0 > idx) || (idx > 1000)) -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL return-1; const GLVolume* v = selection.get_first_volume(); if (model.objects[idx]->volumes.size() > 1) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 5fb8b01321..2189f2ad91 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -10,9 +10,9 @@ #include #include #include - #include - +#include +#include #else // unix, linux & OSX includes #include @@ -72,6 +72,192 @@ std::vector RemovableDriveManager::search_for_removable_drives() cons return current_drives; } +namespace { +// returns the device instance handle of a storage volume or 0 on error +// called from eject_inner, based on https://stackoverflow.com/a/58848961 +DEVINST get_dev_inst_by_device_number(long device_number, UINT drive_type, WCHAR* dos_device_name) +{ + bool is_floppy = (wcsstr(dos_device_name, L"\\Floppy") != NULL); // TODO: could be tested better? + GUID* guid; + switch (drive_type) { + case DRIVE_REMOVABLE: + if (is_floppy) { + // we are interested only in SD cards or USB sticks + BOOST_LOG_TRIVIAL(debug) << "get_dev_inst_by_device_number failed: Drive is floppy disk."; + return 0; + //guid = (GUID*)&GUID_DEVINTERFACE_FLOPPY; + } else { + guid = (GUID*)&GUID_DEVINTERFACE_DISK; + } + break; + case DRIVE_FIXED: + // we are interested only in SD cards or USB sticks + BOOST_LOG_TRIVIAL(debug) << "get_dev_inst_by_device_number failed: Drive is harddisk."; + return 0; + //guid = (GUID*)&GUID_DEVINTERFACE_DISK; + //break; + case DRIVE_CDROM: + BOOST_LOG_TRIVIAL(debug) << "get_dev_inst_by_device_number failed: Drive is cd-rom."; + // we are interested only in SD cards or USB sticks + return 0; + //guid = (GUID*)&GUID_DEVINTERFACE_CDROM; + //break; + default: + return 0; + } + + // Get device interface info set handle for all devices attached to system + HDEVINFO h_dev_info = SetupDiGetClassDevs(guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); + + if (h_dev_info == INVALID_HANDLE_VALUE) { + BOOST_LOG_TRIVIAL(debug) << "get_dev_inst_by_device_number failed: Invalid dev info handle."; + return 0; + } + + // Retrieve a context structure for a device interface of a device information set + BYTE buf[1024]; + PSP_DEVICE_INTERFACE_DETAIL_DATA pspdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)buf; + SP_DEVICE_INTERFACE_DATA spdid; + SP_DEVINFO_DATA spdd; + DWORD size; + + spdid.cbSize = sizeof(spdid); + + // Loop through devices and compare device numbers + for (DWORD index = 0; SetupDiEnumDeviceInterfaces(h_dev_info, NULL, guid, index, &spdid); ++index) { + SetupDiGetDeviceInterfaceDetail(h_dev_info, &spdid, NULL, 0, &size, NULL); + // check the buffer size + if (size == 0 || size > sizeof(buf)) { + continue; + } + // prepare structures + pspdidd->cbSize = sizeof(*pspdidd); + ZeroMemory(&spdd, sizeof(spdd)); + spdd.cbSize = sizeof(spdd); + // fill structures + long res = SetupDiGetDeviceInterfaceDetail(h_dev_info, &spdid, pspdidd, size, &size, &spdd); + if (!res) { + continue; + } + // open the drive with pspdidd->DevicePath to compare device numbers + HANDLE drive_handle = CreateFile(pspdidd->DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if (drive_handle == INVALID_HANDLE_VALUE) { + continue; + } + // get its device number + STORAGE_DEVICE_NUMBER sdn; + DWORD bytes_returned = 0; + res = DeviceIoControl(drive_handle, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn), &bytes_returned, NULL); + CloseHandle(drive_handle); + if (!res) { + continue; + } + //compare + if (device_number != (long)sdn.DeviceNumber) { + continue; + } + // this is the drive, return the device instance + SetupDiDestroyDeviceInfoList(h_dev_info); + return spdd.DevInst; + } + + SetupDiDestroyDeviceInfoList(h_dev_info); + BOOST_LOG_TRIVIAL(debug) << "get_dev_inst_by_device_number failed: Enmurating couldn't find the drive."; + return 0; +} + +// Perform eject using CM_Request_Device_EjectW. +// Returns 0 if success. +int eject_inner(const std::string& path) +{ + // Following implementation is based on https://stackoverflow.com/a/58848961 + assert(path.size() > 0); + std::wstring wpath = std::wstring(); + wpath += boost::nowide::widen(path)[0]; // drive letter wide + wpath[0] &= ~0x20; // make sure drive letter is uppercase + assert(wpath[0] >= 'A' && wpath[0] <= 'Z'); + std::wstring root_path = wpath + L":\\"; // for GetDriveType + std::wstring device_path = wpath + L":"; //for QueryDosDevice + std::wstring volume_access_path = L"\\\\.\\" + wpath + L":"; // for CreateFile + long device_number = -1; + + // open the storage volume + HANDLE volume_handle = CreateFileW(volume_access_path.c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL); + if (volume_handle == INVALID_HANDLE_VALUE) { + BOOST_LOG_TRIVIAL(error) << GUI::format("Ejecting of %1% has failed: Invalid value of file handle.", path); + return 1; + } + + // get the volume's device number + STORAGE_DEVICE_NUMBER sdn; + DWORD bytes_returned = 0; + long res = DeviceIoControl(volume_handle, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn), &bytes_returned, NULL); + if (res) { + device_number = sdn.DeviceNumber; + } + CloseHandle(volume_handle); + + if (device_number == -1) { + BOOST_LOG_TRIVIAL(error) << GUI::format("Ejecting of %1% has failed: Invalid device number.", path); + return 1; + } + + // get the drive type which is required to match the device numbers correctely + UINT drive_type = GetDriveTypeW(root_path.c_str()); + + // get the dos device name (like \device\floppy0) to decide if it's a floppy or not + WCHAR dos_device_name[MAX_PATH]; + res = QueryDosDeviceW(device_path.c_str(), dos_device_name, MAX_PATH); + if (!res) { + BOOST_LOG_TRIVIAL(error) << GUI::format("Ejecting of %1% has failed: Invalid dos device name.", path); + return 1; + } + + // get the device instance handle of the storage volume by means of a SetupDi enum and matching the device number + DEVINST dev_inst = get_dev_inst_by_device_number(device_number, drive_type, dos_device_name); + + if (dev_inst == 0) { + BOOST_LOG_TRIVIAL(error) << GUI::format("Ejecting of %1% has failed: Invalid device instance handle.", path); + return 1; + } + + PNP_VETO_TYPE veto_type = PNP_VetoTypeUnknown; + WCHAR veto_name[MAX_PATH]; + veto_name[0] = 0; + + // get drives's parent, e.g. the USB bridge, the SATA port, an IDE channel with two drives! + DEVINST dev_inst_parent = 0; + res = CM_Get_Parent(&dev_inst_parent, dev_inst, 0); + +#if 0 + // loop with several tries and sleep (this is running on main UI thread) + for (int i = 0; i < 3; ++i) { + veto_name[0] = 0; + // CM_Query_And_Remove_SubTree doesn't work for restricted users + //res = CM_Query_And_Remove_SubTreeW(DevInstParent, &VetoType, VetoNameW, MAX_PATH, CM_REMOVE_NO_RESTART); // CM_Query_And_Remove_SubTreeA is not implemented under W2K! + //res = CM_Query_And_Remove_SubTreeW(DevInstParent, NULL, NULL, 0, CM_REMOVE_NO_RESTART); // with messagebox (W2K, Vista) or balloon (XP) + res = CM_Request_Device_EjectW(dev_inst_parent, &veto_type, veto_name, MAX_PATH, 0); + //res = CM_Request_Device_EjectW(DevInstParent, NULL, NULL, 0, 0); // with messagebox (W2K, Vista) or balloon (XP) + if (res == CR_SUCCESS && veto_type == PNP_VetoTypeUnknown) { + return 0; + } + // Wait for next try. + // This is main thread! + Sleep(500); + } +#endif // 0 + + // perform eject + res = CM_Request_Device_EjectW(dev_inst_parent, &veto_type, veto_name, MAX_PATH, 0); + if (res == CR_SUCCESS && veto_type == PNP_VetoTypeUnknown) { + return 0; + } + + BOOST_LOG_TRIVIAL(error) << GUI::format("Ejecting of %1% has failed: Request to eject device has failed.", path); + return 1; +} + +} // Called from UI therefore it blocks the UI thread. // It also blocks updates at the worker thread. // Win32 implementation. @@ -86,6 +272,28 @@ void RemovableDriveManager::eject_drive() BOOST_LOG_TRIVIAL(info) << "Ejecting started"; std::scoped_lock lock(m_drives_mutex); auto it_drive_data = this->find_last_save_path_drive_data(); + if (it_drive_data != m_current_drives.end()) { + if (!eject_inner(m_last_save_path)) { + // success + assert(m_callback_evt_handler); + if (m_callback_evt_handler) + wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair< DriveData, bool >(std::move(*it_drive_data), true))); + } else { + // failed to eject + // this should not happen, throwing exception might be the way here + assert(m_callback_evt_handler); + if (m_callback_evt_handler) + wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair(*it_drive_data, false))); + } + } else { + // drive not found in m_current_drives + assert(m_callback_evt_handler); + if (m_callback_evt_handler) + wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair({"",""}, false))); + } +#if 0 + // Implementation used until 2.5.x version + // Some usb drives does not eject properly (still visible in file explorer). Some even does not write all content and eject. if (it_drive_data != m_current_drives.end()) { // get handle to device std::string mpath = "\\\\.\\" + m_last_save_path; @@ -102,16 +310,16 @@ void RemovableDriveManager::eject_drive() //these 3 commands should eject device safely but they dont, the device does disappear from file explorer but the "device was safely remove" notification doesnt trigger. //sd cards does trigger WM_DEVICECHANGE messege, usb drives dont BOOL e1 = DeviceIoControl(handle, FSCTL_LOCK_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); - BOOST_LOG_TRIVIAL(debug) << "FSCTL_LOCK_VOLUME " << e1 << " ; " << deviceControlRetVal << " ; " << GetLastError(); + BOOST_LOG_TRIVIAL(error) << "FSCTL_LOCK_VOLUME " << e1 << " ; " << deviceControlRetVal << " ; " << GetLastError(); BOOL e2 = DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); - BOOST_LOG_TRIVIAL(debug) << "FSCTL_DISMOUNT_VOLUME " << e2 << " ; " << deviceControlRetVal << " ; " << GetLastError(); - // some implemenatations also calls IOCTL_STORAGE_MEDIA_REMOVAL here but it returns error to me + BOOST_LOG_TRIVIAL(error) << "FSCTL_DISMOUNT_VOLUME " << e2 << " ; " << deviceControlRetVal << " ; " << GetLastError(); + // some implemenatations also calls IOCTL_STORAGE_MEDIA_REMOVAL here with FALSE as third parameter, which should set PreventMediaRemoval BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); if (error == 0) { CloseHandle(handle); BOOST_LOG_TRIVIAL(error) << "Ejecting " << mpath << " failed (IOCTL_STORAGE_EJECT_MEDIA)" << deviceControlRetVal << " " << GetLastError(); assert(m_callback_evt_handler); - if (m_callback_evt_handler) + if (m_callback_evt_handler) wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair(*it_drive_data, false))); return; } @@ -122,6 +330,7 @@ void RemovableDriveManager::eject_drive() wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair< DriveData, bool >(std::move(*it_drive_data), true))); m_current_drives.erase(it_drive_data); } +#endif // 0 } std::string RemovableDriveManager::get_removable_drive_path(const std::string &path) diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index a3828f53df..9a4169b318 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -566,11 +566,7 @@ bool Selection::is_single_full_instance() const bool Selection::is_from_single_object() const { const int idx = get_object_idx(); -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL return 0 <= idx && idx < int(m_model->objects.size()); -#else - return 0 <= idx && idx < 1000; -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL } bool Selection::is_sla_compliant() const @@ -1426,16 +1422,10 @@ void Selection::translate(unsigned int object_idx, const Vec3d& displacement) if (done.size() == m_volumes->size()) break; -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL if ((*m_volumes)[i]->is_wipe_tower) continue; int object_idx = (*m_volumes)[i]->object_idx(); -#else - int object_idx = (*m_volumes)[i]->object_idx(); - if (object_idx >= 1000) - continue; -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL // Process unselected volumes of the object. for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) { @@ -1480,16 +1470,10 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co if (done.size() == m_volumes->size()) break; -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL if ((*m_volumes)[i]->is_wipe_tower) continue; - int object_idx = (*m_volumes)[i]->object_idx(); -#else - int object_idx = (*m_volumes)[i]->object_idx(); - if (object_idx >= 1000) - continue; -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL + const int object_idx = (*m_volumes)[i]->object_idx(); // Process unselected volumes of the object. for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) { @@ -2987,17 +2971,10 @@ void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_ break; const GLVolume* volume_i = (*m_volumes)[i]; -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL if (volume_i->is_wipe_tower) continue; const int object_idx = volume_i->object_idx(); -#else - const int object_idx = volume_i->object_idx(); - if (object_idx >= 1000) - continue; -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL - const int instance_idx = volume_i->instance_idx(); #if ENABLE_WORLD_COORDINATE const Geometry::Transformation& curr_inst_trafo_i = volume_i->get_instance_transformation(); @@ -3095,17 +3072,10 @@ void Selection::synchronize_unselected_volumes() { for (unsigned int i : m_list) { const GLVolume* volume = (*m_volumes)[i]; -#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL if (volume->is_wipe_tower) continue; const int object_idx = volume->object_idx(); -#else - const int object_idx = volume->object_idx(); - if (object_idx >= 1000) - continue; -#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL - const int volume_idx = volume->volume_idx(); #if ENABLE_WORLD_COORDINATE const Geometry::Transformation& trafo = volume->get_volume_transformation(); diff --git a/src/tcbspan/README.md b/src/tcbspan/README.md new file mode 100644 index 0000000000..6e2fba84cf --- /dev/null +++ b/src/tcbspan/README.md @@ -0,0 +1,124 @@ +Bundled with PrusaSlicer: +https://github.com/tcbrindle/span +commit 836dc6a0efd9849cb194e88e4aa2387436bb079b +This is not the full distribution, it only contains README and span.hpp +Original README follows: + + +[![Standard](https://img.shields.io/badge/c%2B%2B-11/14/17/20-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization) +[![License](https://img.shields.io/badge/license-BSL-blue.svg)](http://www.boost.org/LICENSE_1_0.txt) +[![Build Status](https://travis-ci.org/tcbrindle/span.svg?branch=master)](https://travis-ci.org/tcbrindle/span) +[![Build status](https://ci.appveyor.com/api/projects/status/ow7cj56s108fs439/branch/master?svg=true)](https://ci.appveyor.com/project/tcbrindle/span/branch/master) +[![Try it on godbolt online](https://img.shields.io/badge/on-godbolt-blue.svg)](https://godbolt.org/z/-vlZZR) + +`std::span` implementation for C++11 and later +============================================== + +This repository contains a single-header implementation of C++20's `std::span`, +conforming to the C++20 committee draft. +It is compatible with C++11, but will use newer language features if they +are available. + +It differs from the implementation in the [Microsoft GSL](https://github.com/Microsoft/GSL/) +in that it is single-header and does not depend on any other GSL facilities. It +also works with C++11, while the GSL version requires C++14. + +Usage +----- + +The recommended way to use the implementation simply copy the file `span.hpp` +from `include/tcb/` into your own sources and `#include` it like +any other header. By default, it lives in namespace `tcb`, but this can be +customised by setting the macro `TCB_SPAN_NAMESPACE_NAME` to an appropriate string +before `#include`-ing the header -- or simply edit the source code. + +The rest of the repository contains testing machinery, and is not required for +use. + +Compatibility +------------- + +This implementation requires a conforming C++11 (or later) compiler, and is tested as far +back as GCC 5, Clang 3.5 and MSVC 2015 Update 3. Older compilers may work, but this is not guaranteed. + +Documentation +------------- + +Documentation for `std::span` is available [on cppreference](https://en.cppreference.com/w/cpp/container/span). + +Implementation Notes +-------------------- + +### Bounds Checking ### + +This implementation of `span` includes optional bounds checking, which is handled +either by throwing an exception or by calling `std::terminate()`. + +The default behaviour with C++14 and later is to check the macro `NDEBUG`: +if this is set, bounds checking is disabled. Otherwise, `std::terminate()` will +be called if there is a precondition violation (i.e. the same behaviour as +`assert()`). If you wish to terminate on errors even if `NDEBUG` is set, define +the symbol `TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION` before `#include`-ing the +header. + +Alternatively, if you want to throw on a contract violation, define +`TCB_SPAN_THROW_ON_CONTRACT_VIOLATION`. This will throw an exception of an +implementation-defined type (deriving from `std::logic_error`), allowing +cleanup to happen. Note that defining this symbol will cause the checks to be +run even if `NDEBUG` is set. + +Lastly, if you wish to disable contract checking even in debug builds, +`#define TCB_SPAN_NO_CONTRACT_CHECKING`. + +Under C++11, due to the restrictions on `constexpr` functions, contract checking +is disabled by default even if `NDEBUG` is not set. You can change this by +defining either of the above symbols, but this will result in most of `span`'s +interface becoming non-`constexpr`. + +### `constexpr` ### + +This implementation is fully `constexpr` under C++17 and later. Under earlier +versions, it is "as `constexpr` as possible". + +Note that even in C++17, it is generally not possible to declare a `span` +as non-default constructed `constexpr` variable, for the same reason that you +cannot form a `constexpr` pointer to a value: it involves taking the address of +a compile-time variable in a way that would be visible at run-time. +You can however use a `span` freely in a `constexpr` function. For example: + +```cpp +// Okay, even in C++11 +constexpr std::ptrdiff_t get_span_size(span span) +{ + return span.size(); +} + +constexpr int arr[] = {1, 2, 3}; +constexpr auto size = get_span_size(arr); // Okay +constexpr span span{arr}; // ERROR -- not a constant expression +constexpr const int* p = arr; // ERROR -- same +``` + +Constructor deduction guides are provided if the compiler supports them. For +older compilers, a set of `make_span()` functions are provided as an extension +which use the same logic, for example: + + ```cpp + constexpr int c_array[] = {1, 2, 3}; + std::array std_array{1, 2, 3}; + const std::vector vec{1, 2, 3}; + + auto s1 = make_span(c_array); // returns span + auto s2 = make_span(std_array); // returns span + auto s3 = make_span(vec); // returns span + ``` + +Alternatives +------------ + +* [Microsoft/GSL](https://github.com/Microsoft/GSL): The original `span` reference + implementation from which `std::span` was born. + +* [martinmoene/span_lite](https://github.com/martinmoene/span-lite): An + alternative implementation which offers C++98 compatibility. + diff --git a/src/tcbspan/span.hpp b/src/tcbspan/span.hpp new file mode 100644 index 0000000000..fdc3a988a4 --- /dev/null +++ b/src/tcbspan/span.hpp @@ -0,0 +1,618 @@ + +/* +This is an implementation of C++20's std::span +http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/n4820.pdf +*/ + +// Copyright Tristan Brindle 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file ../../LICENSE_1_0.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +#ifndef TCB_SPAN_HPP_INCLUDED +#define TCB_SPAN_HPP_INCLUDED + +#include +#include +#include +#include + +#ifndef TCB_SPAN_NO_EXCEPTIONS +// Attempt to discover whether we're being compiled with exception support +#if !(defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) +#define TCB_SPAN_NO_EXCEPTIONS +#endif +#endif + +#ifndef TCB_SPAN_NO_EXCEPTIONS +#include +#include +#endif + +// Various feature test macros + +#ifndef TCB_SPAN_NAMESPACE_NAME +#define TCB_SPAN_NAMESPACE_NAME tcb +#endif + +#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +#define TCB_SPAN_HAVE_CPP17 +#endif + +#if __cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) +#define TCB_SPAN_HAVE_CPP14 +#endif + +namespace TCB_SPAN_NAMESPACE_NAME { + +// Establish default contract checking behavior +#if !defined(TCB_SPAN_THROW_ON_CONTRACT_VIOLATION) && \ + !defined(TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION) && \ + !defined(TCB_SPAN_NO_CONTRACT_CHECKING) +#if defined(NDEBUG) || !defined(TCB_SPAN_HAVE_CPP14) +#define TCB_SPAN_NO_CONTRACT_CHECKING +#else +#define TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION +#endif +#endif + +#if defined(TCB_SPAN_THROW_ON_CONTRACT_VIOLATION) +struct contract_violation_error : std::logic_error { + explicit contract_violation_error(const char* msg) : std::logic_error(msg) + {} +}; + +inline void contract_violation(const char* msg) +{ + throw contract_violation_error(msg); +} + +#elif defined(TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION) +[[noreturn]] inline void contract_violation(const char* /*unused*/) +{ + std::terminate(); +} +#endif + +#if !defined(TCB_SPAN_NO_CONTRACT_CHECKING) +#define TCB_SPAN_STRINGIFY(cond) #cond +#define TCB_SPAN_EXPECT(cond) \ + cond ? (void) 0 : contract_violation("Expected " TCB_SPAN_STRINGIFY(cond)) +#else +#define TCB_SPAN_EXPECT(cond) +#endif + +#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_inline_variables) +#define TCB_SPAN_INLINE_VAR inline +#else +#define TCB_SPAN_INLINE_VAR +#endif + +#if defined(TCB_SPAN_HAVE_CPP14) || \ + (defined(__cpp_constexpr) && __cpp_constexpr >= 201304) +#define TCB_SPAN_HAVE_CPP14_CONSTEXPR +#endif + +#if defined(TCB_SPAN_HAVE_CPP14_CONSTEXPR) +#define TCB_SPAN_CONSTEXPR14 constexpr +#else +#define TCB_SPAN_CONSTEXPR14 +#endif + +#if defined(TCB_SPAN_HAVE_CPP14_CONSTEXPR) && \ + (!defined(_MSC_VER) || _MSC_VER > 1900) +#define TCB_SPAN_CONSTEXPR_ASSIGN constexpr +#else +#define TCB_SPAN_CONSTEXPR_ASSIGN +#endif + +#if defined(TCB_SPAN_NO_CONTRACT_CHECKING) +#define TCB_SPAN_CONSTEXPR11 constexpr +#else +#define TCB_SPAN_CONSTEXPR11 TCB_SPAN_CONSTEXPR14 +#endif + +#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_deduction_guides) +#define TCB_SPAN_HAVE_DEDUCTION_GUIDES +#endif + +#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_byte) +#define TCB_SPAN_HAVE_STD_BYTE +#endif + +#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_array_constexpr) +#define TCB_SPAN_HAVE_CONSTEXPR_STD_ARRAY_ETC +#endif + +#if defined(TCB_SPAN_HAVE_CONSTEXPR_STD_ARRAY_ETC) +#define TCB_SPAN_ARRAY_CONSTEXPR constexpr +#else +#define TCB_SPAN_ARRAY_CONSTEXPR +#endif + +#ifdef TCB_SPAN_HAVE_STD_BYTE +using byte = std::byte; +#else +using byte = unsigned char; +#endif + +#if defined(TCB_SPAN_HAVE_CPP17) +#define TCB_SPAN_NODISCARD [[nodiscard]] +#else +#define TCB_SPAN_NODISCARD +#endif + +TCB_SPAN_INLINE_VAR constexpr std::size_t dynamic_extent = SIZE_MAX; + +template +class span; + +namespace detail { + +template +struct span_storage { + constexpr span_storage() noexcept = default; + + constexpr span_storage(E* p_ptr, std::size_t /*unused*/) noexcept + : ptr(p_ptr) + {} + + E* ptr = nullptr; + static constexpr std::size_t size = S; +}; + +template +struct span_storage { + constexpr span_storage() noexcept = default; + + constexpr span_storage(E* p_ptr, std::size_t p_size) noexcept + : ptr(p_ptr), size(p_size) + {} + + E* ptr = nullptr; + std::size_t size = 0; +}; + +// Reimplementation of C++17 std::size() and std::data() +#if defined(TCB_SPAN_HAVE_CPP17) || \ + defined(__cpp_lib_nonmember_container_access) +using std::data; +using std::size; +#else +template +constexpr auto size(const C& c) -> decltype(c.size()) +{ + return c.size(); +} + +template +constexpr std::size_t size(const T (&)[N]) noexcept +{ + return N; +} + +template +constexpr auto data(C& c) -> decltype(c.data()) +{ + return c.data(); +} + +template +constexpr auto data(const C& c) -> decltype(c.data()) +{ + return c.data(); +} + +template +constexpr T* data(T (&array)[N]) noexcept +{ + return array; +} + +template +constexpr const E* data(std::initializer_list il) noexcept +{ + return il.begin(); +} +#endif // TCB_SPAN_HAVE_CPP17 + +#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_void_t) +using std::void_t; +#else +template +using void_t = void; +#endif + +template +using uncvref_t = + typename std::remove_cv::type>::type; + +template +struct is_span : std::false_type {}; + +template +struct is_span> : std::true_type {}; + +template +struct is_std_array : std::false_type {}; + +template +struct is_std_array> : std::true_type {}; + +template +struct has_size_and_data : std::false_type {}; + +template +struct has_size_and_data())), + decltype(detail::data(std::declval()))>> + : std::true_type {}; + +template > +struct is_container { + static constexpr bool value = + !is_span::value && !is_std_array::value && + !std::is_array::value && has_size_and_data::value; +}; + +template +using remove_pointer_t = typename std::remove_pointer::type; + +template +struct is_container_element_type_compatible : std::false_type {}; + +template +struct is_container_element_type_compatible< + T, E, + typename std::enable_if< + !std::is_same< + typename std::remove_cv()))>::type, + void>::value && + std::is_convertible< + remove_pointer_t()))> (*)[], + E (*)[]>::value + >::type> + : std::true_type {}; + +template +struct is_complete : std::false_type {}; + +template +struct is_complete : std::true_type {}; + +} // namespace detail + +template +class span { + static_assert(std::is_object::value, + "A span's ElementType must be an object type (not a " + "reference type or void)"); + static_assert(detail::is_complete::value, + "A span's ElementType must be a complete type (not a forward " + "declaration)"); + static_assert(!std::is_abstract::value, + "A span's ElementType cannot be an abstract class type"); + + using storage_type = detail::span_storage; + +public: + // constants and types + using element_type = ElementType; + using value_type = typename std::remove_cv::type; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + using pointer = element_type*; + using const_pointer = const element_type*; + using reference = element_type&; + using const_reference = const element_type&; + using iterator = pointer; + using reverse_iterator = std::reverse_iterator; + + static constexpr size_type extent = Extent; + + // [span.cons], span constructors, copy, assignment, and destructor + template < + std::size_t E = Extent, + typename std::enable_if<(E == dynamic_extent || E <= 0), int>::type = 0> + constexpr span() noexcept + {} + + TCB_SPAN_CONSTEXPR11 span(pointer ptr, size_type count) + : storage_(ptr, count) + { + TCB_SPAN_EXPECT(extent == dynamic_extent || count == extent); + } + + TCB_SPAN_CONSTEXPR11 span(pointer first_elem, pointer last_elem) + : storage_(first_elem, last_elem - first_elem) + { + TCB_SPAN_EXPECT(extent == dynamic_extent || + last_elem - first_elem == + static_cast(extent)); + } + + template ::value, + int>::type = 0> + constexpr span(element_type (&arr)[N]) noexcept : storage_(arr, N) + {} + + template &, ElementType>::value, + int>::type = 0> + TCB_SPAN_ARRAY_CONSTEXPR span(std::array& arr) noexcept + : storage_(arr.data(), N) + {} + + template &, ElementType>::value, + int>::type = 0> + TCB_SPAN_ARRAY_CONSTEXPR span(const std::array& arr) noexcept + : storage_(arr.data(), N) + {} + + template < + typename Container, std::size_t E = Extent, + typename std::enable_if< + E == dynamic_extent && detail::is_container::value && + detail::is_container_element_type_compatible< + Container&, ElementType>::value, + int>::type = 0> + constexpr span(Container& cont) + : storage_(detail::data(cont), detail::size(cont)) + {} + + template < + typename Container, std::size_t E = Extent, + typename std::enable_if< + E == dynamic_extent && detail::is_container::value && + detail::is_container_element_type_compatible< + const Container&, ElementType>::value, + int>::type = 0> + constexpr span(const Container& cont) + : storage_(detail::data(cont), detail::size(cont)) + {} + + constexpr span(const span& other) noexcept = default; + + template ::value, + int>::type = 0> + constexpr span(const span& other) noexcept + : storage_(other.data(), other.size()) + {} + + ~span() noexcept = default; + + TCB_SPAN_CONSTEXPR_ASSIGN span& + operator=(const span& other) noexcept = default; + + // [span.sub], span subviews + template + TCB_SPAN_CONSTEXPR11 span first() const + { + TCB_SPAN_EXPECT(Count <= size()); + return {data(), Count}; + } + + template + TCB_SPAN_CONSTEXPR11 span last() const + { + TCB_SPAN_EXPECT(Count <= size()); + return {data() + (size() - Count), Count}; + } + + template + using subspan_return_t = + span; + + template + TCB_SPAN_CONSTEXPR11 subspan_return_t subspan() const + { + TCB_SPAN_EXPECT(Offset <= size() && + (Count == dynamic_extent || Offset + Count <= size())); + return {data() + Offset, + Count != dynamic_extent ? Count : size() - Offset}; + } + + TCB_SPAN_CONSTEXPR11 span + first(size_type count) const + { + TCB_SPAN_EXPECT(count <= size()); + return {data(), count}; + } + + TCB_SPAN_CONSTEXPR11 span + last(size_type count) const + { + TCB_SPAN_EXPECT(count <= size()); + return {data() + (size() - count), count}; + } + + TCB_SPAN_CONSTEXPR11 span + subspan(size_type offset, size_type count = dynamic_extent) const + { + TCB_SPAN_EXPECT(offset <= size() && + (count == dynamic_extent || offset + count <= size())); + return {data() + offset, + count == dynamic_extent ? size() - offset : count}; + } + + // [span.obs], span observers + constexpr size_type size() const noexcept { return storage_.size; } + + constexpr size_type size_bytes() const noexcept + { + return size() * sizeof(element_type); + } + + TCB_SPAN_NODISCARD constexpr bool empty() const noexcept + { + return size() == 0; + } + + // [span.elem], span element access + TCB_SPAN_CONSTEXPR11 reference operator[](size_type idx) const + { + TCB_SPAN_EXPECT(idx < size()); + return *(data() + idx); + } + + TCB_SPAN_CONSTEXPR11 reference front() const + { + TCB_SPAN_EXPECT(!empty()); + return *data(); + } + + TCB_SPAN_CONSTEXPR11 reference back() const + { + TCB_SPAN_EXPECT(!empty()); + return *(data() + (size() - 1)); + } + + constexpr pointer data() const noexcept { return storage_.ptr; } + + // [span.iterators], span iterator support + constexpr iterator begin() const noexcept { return data(); } + + constexpr iterator end() const noexcept { return data() + size(); } + + TCB_SPAN_ARRAY_CONSTEXPR reverse_iterator rbegin() const noexcept + { + return reverse_iterator(end()); + } + + TCB_SPAN_ARRAY_CONSTEXPR reverse_iterator rend() const noexcept + { + return reverse_iterator(begin()); + } + +private: + storage_type storage_{}; +}; + +#ifdef TCB_SPAN_HAVE_DEDUCTION_GUIDES + +/* Deduction Guides */ +template +span(T (&)[N])->span; + +template +span(std::array&)->span; + +template +span(const std::array&)->span; + +template +span(Container&)->span()))>::type>; + +template +span(const Container&)->span; + +#endif // TCB_HAVE_DEDUCTION_GUIDES + +template +constexpr span +make_span(span s) noexcept +{ + return s; +} + +template +constexpr span make_span(T (&arr)[N]) noexcept +{ + return {arr}; +} + +template +TCB_SPAN_ARRAY_CONSTEXPR span make_span(std::array& arr) noexcept +{ + return {arr}; +} + +template +TCB_SPAN_ARRAY_CONSTEXPR span +make_span(const std::array& arr) noexcept +{ + return {arr}; +} + +template +constexpr span()))>::type> +make_span(Container& cont) +{ + return {cont}; +} + +template +constexpr span +make_span(const Container& cont) +{ + return {cont}; +} + +template +span +as_bytes(span s) noexcept +{ + return {reinterpret_cast(s.data()), s.size_bytes()}; +} + +template < + class ElementType, size_t Extent, + typename std::enable_if::value, int>::type = 0> +span +as_writable_bytes(span s) noexcept +{ + return {reinterpret_cast(s.data()), s.size_bytes()}; +} + +template +constexpr auto get(span s) -> decltype(s[N]) +{ + return s[N]; +} + +} // namespace TCB_SPAN_NAMESPACE_NAME + +namespace std { + +template +class tuple_size> + : public integral_constant {}; + +template +class tuple_size>; // not defined + +template +class tuple_element> { +public: + static_assert(Extent != TCB_SPAN_NAMESPACE_NAME::dynamic_extent && + I < Extent, + ""); + using type = ElementType; +}; + +} // end namespace std + +#endif // TCB_SPAN_HPP_INCLUDED diff --git a/tests/fff_print/test_print.cpp b/tests/fff_print/test_print.cpp index 395f758410..d8ab5a3faa 100644 --- a/tests/fff_print/test_print.cpp +++ b/tests/fff_print/test_print.cpp @@ -62,7 +62,7 @@ SCENARIO("Print: Changing number of solid surfaces does not cause all surfaces t // Precondition: Ensure that the model has 2 solid top layers (39, 38) // and one solid bottom layer (0). auto test_is_solid_infill = [&print](size_t obj_id, size_t layer_id) { - const Layer &layer = *(print.objects().at(obj_id)->get_layer((int)layer_id)); + const Layer &layer = *print.objects()[obj_id]->get_layer((int)layer_id); // iterate over all of the regions in the layer for (const LayerRegion *region : layer.regions()) { // for each region, iterate over the fill surfaces diff --git a/tests/fff_print/test_printobject.cpp b/tests/fff_print/test_printobject.cpp index 8d322f58fe..cbc47345c7 100644 --- a/tests/fff_print/test_printobject.cpp +++ b/tests/fff_print/test_printobject.cpp @@ -18,7 +18,7 @@ SCENARIO("PrintObject: object layer heights", "[PrintObject]") { { "layer_height", 2 }, { "nozzle_diameter", 3 } }); - ConstLayerPtrsAdaptor layers = print.objects().front()->layers(); + SpanOfConstPtrs layers = print.objects().front()->layers(); THEN("The output vector has 10 entries") { REQUIRE(layers.size() == 10); } @@ -37,7 +37,7 @@ SCENARIO("PrintObject: object layer heights", "[PrintObject]") { { "layer_height", 10 }, { "nozzle_diameter", 11 } }); - ConstLayerPtrsAdaptor layers = print.objects().front()->layers(); + SpanOfConstPtrs layers = print.objects().front()->layers(); THEN("The output vector has 3 entries") { REQUIRE(layers.size() == 3); } @@ -55,7 +55,7 @@ SCENARIO("PrintObject: object layer heights", "[PrintObject]") { { "layer_height", 15 }, { "nozzle_diameter", 16 } }); - ConstLayerPtrsAdaptor layers = print.objects().front()->layers(); + SpanOfConstPtrs layers = print.objects().front()->layers(); THEN("The output vector has 2 entries") { REQUIRE(layers.size() == 2); } diff --git a/tests/fff_print/test_support_material.cpp b/tests/fff_print/test_support_material.cpp index c5087263c3..0720b270cb 100644 --- a/tests/fff_print/test_support_material.cpp +++ b/tests/fff_print/test_support_material.cpp @@ -27,7 +27,7 @@ SCENARIO("SupportMaterial: support_layers_z and contact_distance", "[SupportMate auto check = [](Slic3r::Print &print, bool &first_support_layer_height_ok, bool &layer_height_minimum_ok, bool &layer_height_maximum_ok, bool &top_spacing_ok) { - ConstSupportLayerPtrsAdaptor support_layers = print.objects().front()->support_layers(); + SpanOfConstPtrs support_layers = print.objects().front()->support_layers(); first_support_layer_height_ok = support_layers.front()->print_z == print.config().first_layer_height.value; diff --git a/tests/libslic3r/test_aabbindirect.cpp b/tests/libslic3r/test_aabbindirect.cpp index 87cf80943a..def349042e 100644 --- a/tests/libslic3r/test_aabbindirect.cpp +++ b/tests/libslic3r/test_aabbindirect.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -87,6 +88,25 @@ TEST_CASE("Creating a several 2d lines, testing closest point query", "[AABBIndi REQUIRE(hit_point_out.y() == Approx(0.5)); } +TEST_CASE("Creating a several 2d lines, testing all lines in radius query", "[AABBIndirect]") +{ + std::vector lines { }; + lines.push_back(Linef(Vec2d(0.0, 0.0), Vec2d(10.0, 0.0))); + lines.push_back(Linef(Vec2d(-10.0, 10.0), Vec2d(10.0, -10.0))); + lines.push_back(Linef(Vec2d(-2.0, -1.0), Vec2d(-2.0, 1.0))); + lines.push_back(Linef(Vec2d(-1.0, -1.0), Vec2d(-1.0, -1.0))); + lines.push_back(Linef(Vec2d(1.0, 1.0), Vec2d(1.0, 1.0))); + + auto tree = AABBTreeLines::build_aabb_tree_over_indexed_lines(lines); + + auto indices = AABBTreeLines::all_lines_in_radius(lines, tree, Vec2d{1.0,1.0}, 4.0); + + REQUIRE(std::find(indices.begin(),indices.end(), 0) != indices.end()); + REQUIRE(std::find(indices.begin(),indices.end(), 1) != indices.end()); + REQUIRE(std::find(indices.begin(),indices.end(), 4) != indices.end()); + REQUIRE(indices.size() == 3); +} + #if 0 #include "libslic3r/EdgeGrid.hpp" #include