Merge remote-tracking branch 'PRIVATE/master' into ys_cut

This commit is contained in:
YuSanka 2022-10-25 16:07:46 +02:00
commit bba6d8b94d
58 changed files with 3185 additions and 1299 deletions

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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

Binary file not shown.

After

(image error) Size: 39 KiB

View file

@ -0,0 +1,2 @@
min_slic3r_version = 2.6.0-alpha1
0.0.1 Initial version

View file

@ -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

Binary file not shown.

View file

@ -0,0 +1,165 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="100mm"
height="110mm"
viewBox="0 0 100 110"
version="1.1"
id="svg5"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
sodipodi:docname="mycusini2.0_printbed.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="true"
inkscape:document-units="mm"
showgrid="false"
inkscape:snap-to-guides="false"
inkscape:snap-grids="false"
inkscape:snap-global="true"
inkscape:zoom="8.7988368"
inkscape:cx="285.77641"
inkscape:cy="344.70465"
inkscape:window-width="3840"
inkscape:window-height="2080"
inkscape:window-x="-11"
inkscape:window-y="-11"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow1Lstart"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Lstart"
inkscape:isstock="true">
<path
transform="scale(0.8) translate(12.5,0)"
style="fill-rule:evenodd;fill:context-stroke;stroke:context-stroke;stroke-width:1.0pt"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path2735" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-17.350515,-57.494846)">
<rect
style="display:inline;fill:#ffffff;fill-opacity:0.5;stroke:none;stroke-width:2.83606;stroke-linejoin:round;stroke-dasharray:none"
id="rect6619"
width="100"
height="110"
x="17.350515"
y="57.494846" />
<path
id="rect1815"
style="display:inline;fill:#323232;fill-opacity:1;stroke:none;stroke-width:3.58768;stroke-linejoin:round;stroke-dasharray:none"
d="M 17.350515,57.494846 V 167.49485 H 117.35061 V 57.494846 Z m 4.88859,2.999817 h 90.222405 c 1.04636,0 1.88877,0.842404 1.88877,1.888773 V 162.60626 c 0,1.04637 -0.84241,1.88877 -1.88877,1.88877 H 22.239105 c -1.046369,0 -1.888773,-0.8424 -1.888773,-1.88877 V 62.383436 c 0,-1.046369 0.842404,-1.888773 1.888773,-1.888773 z" />
<rect
style="display:inline;fill:#323232;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.025227"
id="rect31"
width="100"
height="1"
x="17.350515"
y="-112.99484"
transform="scale(1,-1)" />
<rect
style="fill:#323232;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.0264583"
id="rect31-1"
width="1"
height="110"
x="66.850517"
y="-167.49484"
transform="scale(1,-1)" />
<rect
style="fill:#323232;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.0229831"
id="rect31-1-6"
width="1"
height="83"
x="91.850517"
y="-140.49481"
transform="scale(1,-1)" />
<rect
style="fill:#323232;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.0264583"
id="rect31-1-4"
width="1"
height="110"
x="41.850513"
y="-167.49484"
transform="scale(1,-1)" />
<rect
style="fill:#323232;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.025227"
id="rect31-5"
width="100"
height="1"
x="17.350515"
y="-140.49484"
transform="scale(1,-1)" />
<rect
style="fill:#323232;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.025227"
id="rect31-8"
width="100"
height="1"
x="17.350515"
y="-85.494843"
transform="scale(1,-1)" />
<g
transform="matrix(0.01004114,0,0,-0.01004115,77.288332,160.09414)"
fill="#000000"
stroke="none"
id="g1873"
style="fill:#323232;fill-opacity:1">
<path
d="m 1593,1049 c -25,-6 -58,-24 -78,-43 -21,-20 -50,-36 -71,-39 -83,-14 -127,-72 -121,-160 3,-46 9,-63 32,-87 16,-17 44,-35 61,-42 30,-11 33,-16 36,-57 3,-51 29,-68 53,-34 12,16 29,18 143,18 113,0 133,-2 151,-19 30,-28 53,-6 49,47 -3,37 -1,41 26,48 34,9 72,43 92,81 44,85 -22,203 -119,212 -23,2 -49,13 -65,28 -51,48 -115,64 -189,47 z m 128,-65 c 33,-17 57,-53 67,-101 6,-29 13,-39 31,-41 22,-3 23,-1 19,37 -2,29 0,41 10,41 25,0 61,-32 72,-65 21,-63 -22,-118 -100,-127 -21,-3 -25,-9 -28,-40 -3,-36 -3,-37 -40,-30 -48,9 -166,9 -214,0 -38,-7 -38,-7 -38,28 0,29 -3,34 -25,34 -58,0 -105,47 -105,104 0,29 41,81 69,89 18,4 20,0 18,-32 -2,-32 1,-36 23,-36 20,0 26,6 30,35 8,47 24,75 57,98 48,34 96,36 154,6 z"
id="path1855"
style="fill:#323232;fill-opacity:1" />
<path
d="M 107,536 C 24,506 9,474 7,317 5,197 5,195 28,192 c 12,-2 22,0 22,5 4,210 6,229 23,255 37,54 123,60 168,12 22,-23 24,-37 29,-147 4,-109 7,-122 24,-125 30,-6 36,16 36,134 0,110 0,110 31,140 42,40 106,41 146,1 27,-26 28,-32 33,-150 4,-109 7,-122 24,-125 29,-6 36,16 36,113 0,116 -11,155 -59,198 -63,57 -155,58 -216,1 l -27,-25 -27,26 c -26,24 -79,46 -111,45 -8,-1 -32,-7 -53,-14 z"
id="path1857"
style="fill:#323232;fill-opacity:1" />
<path
d="m 674,536 c -3,-8 -4,-67 -2,-130 3,-123 11,-145 70,-189 39,-29 114,-33 161,-9 l 37,20 V 173 C 940,124 936,114 906,84 865,43 809,37 766,71 737,94 707,90 712,64 718,30 766,7 828,7 c 64,0 104,18 137,61 18,25 20,45 23,246 2,120 -1,223 -6,228 -5,5 -16,6 -25,2 -15,-5 -17,-23 -17,-121 V 308 l -34,-34 c -27,-27 -42,-34 -73,-34 -83,0 -106,40 -113,190 -4,99 -7,115 -23,118 -9,2 -20,-3 -23,-12 z"
id="path1859"
style="fill:#323232;fill-opacity:1" />
<path
d="m 1177,535 c -76,-27 -117,-84 -117,-165 0,-102 59,-170 155,-178 30,-2 65,-2 79,2 35,9 86,54 86,77 0,24 -32,25 -51,2 -23,-26 -78,-45 -112,-37 -46,10 -73,31 -91,69 -32,66 -12,139 47,175 49,30 99,26 142,-11 57,-50 93,-16 38,36 -47,43 -110,54 -176,30 z"
id="path1861"
style="fill:#323232;fill-opacity:1" />
<path
d="m 1994,540 c -31,-12 -64,-59 -64,-90 0,-46 34,-78 110,-101 78,-23 95,-38 86,-73 -12,-47 -99,-53 -162,-11 -23,15 -28,15 -41,2 -49,-48 130,-102 207,-62 36,19 50,43 50,90 0,47 -31,75 -107,99 -88,28 -112,56 -75,89 23,21 72,22 119,2 31,-13 39,-13 51,-2 38,39 -104,85 -174,57 z"
id="path1863"
style="fill:#323232;fill-opacity:1" />
<path
d="m 2321,541 c -8,-5 -11,-55 -9,-177 3,-161 4,-169 23,-169 19,0 20,8 23,171 2,138 0,173 -11,177 -8,3 -19,2 -26,-2 z"
id="path1865"
style="fill:#323232;fill-opacity:1" />
<path
d="m 2590,528 c -77,-40 -85,-60 -85,-206 0,-120 1,-127 20,-127 19,0 20,8 25,115 3,66 10,125 18,137 15,26 61,53 92,53 31,0 77,-27 92,-53 8,-12 15,-71 18,-137 5,-107 6,-115 25,-115 19,0 20,8 23,121 2,111 1,123 -20,155 -25,37 -98,79 -138,79 -14,0 -46,-10 -70,-22 z"
id="path1867"
style="fill:#323232;fill-opacity:1" />
<path
d="m 1490,417 c 0,-112 2,-127 23,-157 64,-95 200,-93 271,3 19,25 21,42 21,150 0,119 -1,122 -22,125 -23,3 -23,1 -23,-98 0,-110 -13,-157 -51,-184 -46,-32 -134,-14 -155,32 -5,9 -11,69 -14,132 -5,110 -6,115 -27,118 -23,3 -23,2 -23,-121 z"
id="path1869"
style="fill:#323232;fill-opacity:1" />
<path
d="m 2952,368 c 3,-163 4,-173 22,-173 19,0 20,9 20,170 0,168 -1,170 -22,173 l -22,3 z"
id="path1871"
style="fill:#323232;fill-opacity:1" />
</g>
</g>
</svg>

After

(image error) Size: 7.7 KiB

Binary file not shown.

After

(image error) Size: 44 KiB

Binary file not shown.

Before

(image error) Size: 37 KiB

After

(image error) Size: 34 KiB

Binary file not shown.

Before

(image error) Size: 37 KiB

After

(image error) Size: 34 KiB

Binary file not shown.

Before

(image error) Size: 37 KiB

After

(image error) Size: 34 KiB

Binary file not shown.

Before

(image error) Size: 31 KiB

After

(image error) Size: 29 KiB

View file

@ -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

View file

@ -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
filament = DeltiQ - PLA - Prusament (Prusa Polymers)

View file

@ -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<VectorType>(origin,
this->vertices[triangle(0)].template cast<ScalarType>(),
@ -613,6 +613,37 @@ namespace detail {
return up_sqr_d;
}
template<typename IndexedPrimitivesDistancerType, typename Scalar>
static inline void indexed_primitives_within_distance_squared_recurisve(const IndexedPrimitivesDistancerType &distancer,
size_t node_idx,
Scalar squared_distance_limit,
std::vector<size_t> &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<typename VertexType, typename IndexedFaceType, typename TreeType, typename VectorType>
inline std::vector<size_t> all_triangles_in_radius(
// Indexed triangle set - 3D vertices.
const std::vector<VertexType> &vertices,
// Indexed triangle set - triangular faces, references to vertices.
const std::vector<IndexedFaceType> &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<VertexType, IndexedFaceType, TreeType, VectorType>
{ vertices, faces, tree, point };
if(tree.empty())
{
return {};
}
std::vector<size_t> 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.

View file

@ -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 <type_traits>
#include <vector>
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<LineType::Dim, typename LineType::Scalar> 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<typename LineType::Scalar>(), &nearest_point);
return nearest_point.template cast<ScalarType>();
}
};
}
// 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<typename LineType>
inline AABBTreeIndirect::Tree<2, typename LineType::Scalar> build_aabb_tree_over_indexed_lines(
const std::vector<LineType> &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<typename LineType, typename TreeType, typename VectorType>
inline typename VectorType::Scalar squared_distance_to_indexed_lines(
const std::vector<LineType> &lines,
const TreeType &tree,
const VectorType &point,
size_t &hit_idx_out,
Eigen::PlainObjectBase<VectorType> &hit_point_out)
{
using Scalar = typename VectorType::Scalar;
auto distancer = detail::IndexedLinesDistancer<LineType, TreeType, VectorType>
{ lines, tree, point };
inline typename VectorType::Scalar squared_distance_to_indexed_lines(const std::vector<LineType> &lines,
const TreeType &tree,
const VectorType &point,
size_t &hit_idx_out,
Eigen::PlainObjectBase<VectorType> &hit_point_out)
{
using Scalar = typename VectorType::Scalar;
auto distancer = detail::IndexedLinesDistancer<LineType, TreeType, VectorType>{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<Scalar>::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<Scalar>::infinity(),
hit_idx_out, hit_point_out);
}
// Returns all lines within the given radius limit
template<typename LineType, typename TreeType, typename VectorType>
inline std::vector<size_t> all_lines_in_radius(const std::vector<LineType> &lines,
const TreeType &tree,
const VectorType &point,
typename VectorType::Scalar max_distance_squared)
{
auto distancer = detail::IndexedLinesDistancer<LineType, TreeType, VectorType>{lines, tree, point};
if (tree.empty()) { return {}; }
std::vector<size_t> found_lines{};
AABBTreeIndirect::detail::indexed_primitives_within_distance_squared_recurisve(distancer, size_t(0), max_distance_squared, found_lines);
return found_lines;
}
}
template<typename LineType> class LinesDistancer
{
private:
std::vector<LineType> lines;
using Scalar = typename LineType::Scalar;
using Floating = typename std::conditional<std::is_floating_point<Scalar>::value, Scalar, double>::type;
AABBTreeIndirect::Tree<2, Scalar> tree;
public:
explicit LinesDistancer(const std::vector<LineType> &lines) : lines(lines)
{
tree = AABBTreeLines::build_aabb_tree_over_indexed_lines(this->lines);
}
// negative sign means inside
std::tuple<Floating, size_t, Vec<2, Floating>> 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<Floating>();
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<Floating>::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<Floating>();
Vec<2, Floating> v2 = (point - line.a).template cast<Floating>();
auto d1 = (v1.x() * v2.y()) - (v1.y() * v2.x());
LineType second_line = line;
if ((line.a.template cast<Floating>() - 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<Floating>();
v2 = (point - second_line.a).template cast<Floating>();
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<size_t> 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<LineType> &get_lines() const { return lines; }
};
}} // namespace Slic3r::AABBTreeLines
#endif /* SRC_LIBSLIC3R_AABBTREELINES_HPP_ */

View file

@ -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<PrintObject> &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;
});

View file

@ -268,7 +268,6 @@ set(SLIC3R_SOURCES
TriangleMeshSlicer.hpp
MeshSplitImpl.hpp
TriangulateWall.hpp
TriangulateWall.cpp
utils.cpp
Utils.hpp
Time.cpp

View file

@ -1786,6 +1786,17 @@ public:
// Initialized by ConfigOptionEnum<xxx>::get_enum_values()
const t_config_enum_values *enum_keys_map = nullptr;
void set_enum_values(std::initializer_list<std::pair<std::string_view, std::string_view>> il) {
enum_values.clear();
enum_values.reserve(il.size());
enum_labels.clear();
enum_labels.reserve(il.size());
for (const std::pair<std::string_view, std::string_view> 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)

View file

@ -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<Linef> 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<Linef> 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;

View file

@ -32,7 +32,6 @@ class GCode;
namespace { struct Item; }
struct PrintInstance;
class ConstPrintObjectPtrsAdaptor;
class OozePrevention {
public:

View file

@ -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<SeamCandidate> &perimeter_points,
perimeter.finalized = true;
}
class PerimeterDistancer {
std::vector<Linef> 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<double>();
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<float>::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<Linef>;
std::vector<PrintObjectSeamData::LayerSeams> &layers = m_seam_per_object[po].layers;
tbb::parallel_for(tbb::blocked_range<size_t>(0, layers.size()),
[po, &layers](tbb::blocked_range<size_t> r) {
std::unique_ptr<PerimeterDistancer> prev_layer_distancer;
if (r.begin() > 0) { // previous layer exists
prev_layer_distancer = std::make_unique<PerimeterDistancer>(po->layers()[r.begin() - 1]);
prev_layer_distancer = std::make_unique<PerimeterDistancer>(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<PerimeterDistancer> current_layer_distancer = std::make_unique<PerimeterDistancer>(po->layers()[layer_idx]);
std::unique_ptr<PerimeterDistancer> current_layer_distancer = std::make_unique<PerimeterDistancer>(
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<double>())
+ 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<double>())
+ 0.6f * perimeter_point.perimeter.flow_width;
}
}

View file

@ -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

View file

@ -1305,7 +1305,7 @@ static inline std::vector<std::vector<ExPolygons>> 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<Layer> 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<std::vector<ExPolygons>> multi_material_segmentation_by_painting(con
std::vector<std::vector<PaintedLine>> painted_lines(num_layers);
std::array<std::mutex, 64> painted_lines_mutex;
std::vector<EdgeGrid::Grid> edge_grids(num_layers);
const ConstLayerPtrsAdaptor layers = print_object.layers();
const SpanOfConstPtrs<Layer> layers = print_object.layers();
std::vector<ExPolygons> input_expolygons(num_layers);
throw_on_cancel_callback();

View file

@ -111,11 +111,17 @@ inline double angle(const Eigen::MatrixBase<Derived> &v1, const Eigen::MatrixBas
return atan2(cross2(v1d, v2d), v1d.dot(v2d));
}
template<class T, int N, int Options>
Eigen::Matrix<T, 2, 1, Eigen::DontAlign> to_2d(const Eigen::MatrixBase<Eigen::Matrix<T, N, 1, Options>> &ptN) { return { ptN.x(), ptN.y() }; }
template<typename Derived>
Eigen::Matrix<typename Derived::Scalar, 2, 1, Eigen::DontAlign> to_2d(const Eigen::MatrixBase<Derived> &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<class T, int Options>
Eigen::Matrix<T, 3, 1, Eigen::DontAlign> to_3d(const Eigen::MatrixBase<Eigen::Matrix<T, 2, 1, Options>> & pt, const T z) { return { pt.x(), pt.y(), z }; }
template<typename Derived>
inline Eigen::Matrix<typename Derived::Scalar, 3, 1, Eigen::DontAlign> to_3d(const Eigen::MatrixBase<Derived> &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<double>(x), unscale<double>(y)); }
inline Vec2d unscale(const Vec2crd &pt) { return Vec2d(unscale<double>(pt.x()), unscale<double>(pt.y())); }

View file

@ -21,6 +21,7 @@
#include <functional>
#include <set>
#include <tcbspan/span.hpp>
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<typename T>
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<const T*> vector() const { return std::vector<const T*>(this->begin(), this->end()); }
protected:
ConstVectorOfPtrsAdaptor(const std::vector<T*> *data) : m_data(data) {}
private:
const std::vector<T*> *m_data;
};
// For const correctness: Wrapping a vector of non-const pointers as a span of const pointers.
template<class T>
using SpanOfConstPtrs = tcb::span<const T* const>;
typedef std::vector<Layer*> LayerPtrs;
typedef std::vector<const Layer*> ConstLayerPtrs;
class ConstLayerPtrsAdaptor : public ConstVectorOfPtrsAdaptor<Layer> {
friend PrintObject;
ConstLayerPtrsAdaptor(const LayerPtrs *data) : ConstVectorOfPtrsAdaptor<Layer>(data) {}
};
typedef std::vector<SupportLayer*> SupportLayerPtrs;
typedef std::vector<const SupportLayer*> ConstSupportLayerPtrs;
class ConstSupportLayerPtrsAdaptor : public ConstVectorOfPtrsAdaptor<SupportLayer> {
friend PrintObject;
ConstSupportLayerPtrsAdaptor(const SupportLayerPtrs *data) : ConstVectorOfPtrsAdaptor<SupportLayer>(data) {}
};
using LayerPtrs = std::vector<Layer*>;
using SupportLayerPtrs = std::vector<SupportLayer*>;
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<Layer>(const_cast<const Layer* const* const>(m_layers.data()), m_layers.size()); }
auto support_layers() const { return SpanOfConstPtrs<SupportLayer>(const_cast<const SupportLayer* const* const>(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<PrintObject*> PrintObjectPtrs;
typedef std::vector<const PrintObject*> ConstPrintObjectPtrs;
class ConstPrintObjectPtrsAdaptor : public ConstVectorOfPtrsAdaptor<PrintObject> {
friend Print;
ConstPrintObjectPtrsAdaptor(const PrintObjectPtrs *data) : ConstVectorOfPtrsAdaptor<PrintObject>(data) {}
};
using PrintObjectPtrs = std::vector<PrintObject*>;
using ConstPrintObjectPtrs = std::vector<const PrintObject*>;
typedef std::vector<PrintRegion*> PrintRegionPtrs;
/*
typedef std::vector<const PrintRegion*> ConstPrintRegionPtrs;
class ConstPrintRegionPtrsAdaptor : public ConstVectorOfPtrsAdaptor<PrintRegion> {
friend Print;
ConstPrintRegionPtrsAdaptor(const PrintRegionPtrs *data) : ConstVectorOfPtrsAdaptor<PrintRegion>(data) {}
};
*/
using PrintRegionPtrs = std::vector<PrintRegion*>;
// The complete print tray with possibly multiple objects.
class Print : public PrintBaseWithState<PrintStep, psCount>
@ -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<PrintObject> objects() const { return SpanOfConstPtrs<PrintObject>(const_cast<const PrintObject* const* const>(m_objects.data()), m_objects.size()); }
PrintObject* get_object(size_t idx) { return const_cast<PrintObject*>(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

View file

@ -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<SupportMaterialStyle>::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<SupportMaterialStyle>(smsGrid));

View file

@ -85,7 +85,7 @@ enum SupportMaterialPattern {
};
enum SupportMaterialStyle {
smsGrid, smsSnug, smsTree,
smsGrid, smsSnug, smsTree, smsOrganic,
};
enum SupportMaterialInterfacePattern {

View file

@ -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<void()>([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<Polygons> &out)
static void project_triangles_to_slabs(SpanOfConstPtrs<Layer> layers, const indexed_triangle_set &custom_facets, const Transform3f &tr, bool seam, std::vector<Polygons> &out)
{
if (custom_facets.indices.empty())
return;

View file

@ -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<double>(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())

View file

@ -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<ExtrusionLine> lines;
AABBTreeIndirect::Tree<2, float> tree;
public:
explicit LinesDistancer(const std::vector<ExtrusionLine> &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<float>::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<ExtrusionLine>& get_lines() const {
return lines;
}
};
static const size_t NULL_ISLAND = std::numeric_limits<size_t>::max();
using LD = AABBTreeLines::LinesDistancer<ExtrusionLine>;
class PixelGrid {
Vec2f pixel_size;
Vec2f origin;
@ -387,7 +354,7 @@ void check_extrusion_entity_stability(const ExtrusionEntity *entity,
std::vector<ExtrusionLine> &checked_lines_out,
float layer_z,
const LayerRegion *layer_region,
const LinesDistancer &prev_layer_lines,
const LD &prev_layer_lines,
Issues &issues,
const Params &params) {
@ -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<LayerIslands, PixelGrid> reckon_islands(
}
}
std::vector<LinesDistancer> islands; // these search trees will be used to determine to which island does the extrusion belong.
std::vector<std::vector<size_t>> 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<ExtrusionLine> 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<AABBTreeLines::LinesDistancer<Line>> 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<ExtrusionLine> 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<std::vector<size_t>> island_extrusions(islands.size(),
std::vector<size_t>{}); // 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<LayerIslands, PixelGrid> 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<Issues, std::vector<LayerIslands>> 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<Issues, std::vector<LayerIslands>> 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;
}

View file

@ -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

View file

@ -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<LayerIndex>(std::max(1, start_layer), max_required_layer + 1),
[this, &data, radius, start_layer](const tbb::blocked_range<LayerIndex>& 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
{

View file

@ -19,6 +19,9 @@
#include "Polyline.hpp"
#include "MutablePolygon.hpp"
#include "SupportMaterial.hpp"
#include "TriangleMeshSlicer.hpp"
#include "OpenVDBUtils.hpp"
#include <openvdb/tools/VolumeToSpheres.h>
#include <cassert>
#include <chrono>
@ -26,6 +29,7 @@
#include <optional>
#include <stdio.h>
#include <string>
#include <string_view>
#ifdef _WIN32
#include <windows.h> //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<std::pair<TreeSupportSettings, std::vector<size_t>>> 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<float>(0.4)), "generate_overhangs - enforced overhangs12");
enforced_overhangs = diff(offset(union_ex(enforced_overhangs),
//FIXME this is a fudge constant!
scaled<float>(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<coord_t>(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<std::pair<Point, size_t>> 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<std::pair<Point, size_t>> 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<std::pair<Point, size_t>> 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<double>().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<double>().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<size_t> &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<double>().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<double>().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<coord_t>(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<coord_t>(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<coord_t>(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<bool flip_normals>
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<float>::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<int, int> discretize_circle(const Vec3f &center, const Vec3f &normal, const float radius, const float eps, std::vector<Vec3f> &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<SupportElement*> &path,
const TreeSupportSettings &config,
const SlicingParameters &slicing_params,
const std::vector<SupportElements> &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<int, int> 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 &current = *path[ipath];
assert(prev.state.layer_idx + 1 == current.state.layer_idx);
p1 = to_3d(unscaled<double>(prev .state.result_on_layer), layer_z(slicing_params, prev .state.layer_idx));
p2 = to_3d(unscaled<double>(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<float>(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>());
float angle = angle_step;
for (int i = 1; i < nsteps; ++ i, angle += angle_step) {
std::pair<int, int> strip = discretize_circle((p1 - nprev * radius * cos(angle)).cast<float>(), nprev.cast<float>(), radius * sin(angle), eps, result.vertices);
if (i == 1)
triangulate_fan<false>(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<float>(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<int, int> strip = discretize_circle((p2 + ncurrent * radius * cos(angle)).cast<float>(), ncurrent.cast<float>(), 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<float>());
triangulate_fan<true>(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<double>(next.state.result_on_layer), layer_z(slicing_params, next.state.layer_idx));
v2 = (p3 - p2).normalized();
ncurrent = (v1 + v2).normalized();
float radius = unscaled<float>(config.getRadius(current.state));
std::pair<int, int> strip = discretize_circle(p2.cast<float>(), ncurrent.cast<float>(), 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<Polygons> &overhangs,
std::vector<SupportElements> &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<std::pair<SupportElement*, int>> elements_with_link_down;
std::vector<size_t> linear_data_layers;
{
std::vector<std::pair<SupportElement*, int>> map_downwards_old;
std::vector<std::pair<SupportElement*, int>> 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<openvdb::tools::ClosestSurfacePoint<openvdb::FloatGrid>> 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<openvdb::FloatGrid>::create(*grid);
std::vector<openvdb::Vec3R> pts, prev, projections;
std::vector<float> distances;
for (const std::pair<SupportElement*, int> &element : elements_with_link_down) {
Vec3d pt = to_3d(unscaled<double>(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<float>::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<double>(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<coord_t>(pts[i].x()) / scale;
elements_with_link_down[i].first->state.result_on_layer.y() = scaled<coord_t>(pts[i].y()) / scale;
}
#endif
}
std::vector<Polygons> support_layer_storage(move_bounds.size());
std::vector<Polygons> 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<SupportElement*> 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<float> 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<ExPolygons> 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<size_t>(0, intermediate_layers.size()),
[&](const tbb::blocked_range<size_t> &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<std::chrono::microseconds>(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<void()> 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;

View file

@ -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<size_t, size_t> 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<class Sc>
//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<class Sc>
//static Sc trscore(const Ring & onring,
// const Ring & offring,
// const std::vector<Vec<3, Sc>> &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 Sc>
//class Triangulator {
// const std::vector<Vec<3, Sc>> *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<Vec3i> &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<Vec3i> &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<Vec<3, Sc>> *points,
// Ring & lower,
// Ring & upper)
// : pts{points}, onring{&upper}, offring{&lower}
// {}
//};
//template<class Sc, class I>
//void triangulate_wall(std::vector<Vec<3, Sc>> &pts,
// std::vector<Vec<3, I>> & 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

View file

@ -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;

View file

@ -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<int> 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

View file

@ -75,7 +75,7 @@ struct Bundle
const std::string& vendor_id() const { return vendor_profile->id; }
};
struct BundleMap : std::unordered_map<std::string /* = vendor ID */, Bundle>
struct BundleMap : std::map<std::string /* = vendor ID */, Bundle>
{
static BundleMap load();

View file

@ -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<bool(Layer*)> break_condition)
bool check_color_change(const PrintObject* object, size_t frst_layer_id, size_t layers_cnt, bool check_overhangs, std::function<bool(const Layer*)> 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)) {

View file

@ -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<bool(Layer*)> break_condition);
std::function<bool(const Layer*)> break_condition);
// custom message the slider sends to its parent to notify a tick-change:
wxDECLARE_EVENT(wxCUSTOMEVT_TICKSCHANGED, wxEvent);

View file

@ -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
}
}

View file

@ -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<std::shared_ptr<SceneRaycasterItem>>* 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<SceneRaycasterItem> 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;

View file

@ -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];

View file

@ -574,7 +574,7 @@ void Preview::update_layers_slider(const std::vector<double>& 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,

View file

@ -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"

View file

@ -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
}
}

View file

@ -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<coord_t>::max()/2 - scale_(std::max(std::abs(e*a), std::abs(e*b)))) / 4;
const coord_t size = (std::numeric_limits<coord_t>::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));

View file

@ -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)

View file

@ -10,9 +10,9 @@
#include <tchar.h>
#include <winioctl.h>
#include <shlwapi.h>
#include <Dbt.h>
#include <Setupapi.h>
#include <cfgmgr32.h>
#else
// unix, linux & OSX includes
#include <errno.h>
@ -72,6 +72,192 @@ std::vector<DriveData> 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<std::mutex> 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<DriveData, bool>(*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<DriveData, bool>({"",""}, 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<DriveData, bool>(*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)

View file

@ -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();

124
src/tcbspan/README.md Normal file
View file

@ -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<const int> span)
{
return span.size();
}
constexpr int arr[] = {1, 2, 3};
constexpr auto size = get_span_size(arr); // Okay
constexpr span<const int> 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<int, 3> std_array{1, 2, 3};
const std::vector<int> vec{1, 2, 3};
auto s1 = make_span(c_array); // returns span<const int, 3>
auto s2 = make_span(std_array); // returns span<int, 3>
auto s3 = make_span(vec); // returns span<const int, dynamic_extent>
```
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.

618
src/tcbspan/span.hpp Normal file
View file

@ -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 <array>
#include <cstddef>
#include <cstdint>
#include <type_traits>
#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 <cstdio>
#include <stdexcept>
#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 <typename ElementType, std::size_t Extent = dynamic_extent>
class span;
namespace detail {
template <typename E, std::size_t S>
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 <typename E>
struct span_storage<E, dynamic_extent> {
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 <class C>
constexpr auto size(const C& c) -> decltype(c.size())
{
return c.size();
}
template <class T, std::size_t N>
constexpr std::size_t size(const T (&)[N]) noexcept
{
return N;
}
template <class C>
constexpr auto data(C& c) -> decltype(c.data())
{
return c.data();
}
template <class C>
constexpr auto data(const C& c) -> decltype(c.data())
{
return c.data();
}
template <class T, std::size_t N>
constexpr T* data(T (&array)[N]) noexcept
{
return array;
}
template <class E>
constexpr const E* data(std::initializer_list<E> 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 <typename...>
using void_t = void;
#endif
template <typename T>
using uncvref_t =
typename std::remove_cv<typename std::remove_reference<T>::type>::type;
template <typename>
struct is_span : std::false_type {};
template <typename T, std::size_t S>
struct is_span<span<T, S>> : std::true_type {};
template <typename>
struct is_std_array : std::false_type {};
template <typename T, std::size_t N>
struct is_std_array<std::array<T, N>> : std::true_type {};
template <typename, typename = void>
struct has_size_and_data : std::false_type {};
template <typename T>
struct has_size_and_data<T, void_t<decltype(detail::size(std::declval<T>())),
decltype(detail::data(std::declval<T>()))>>
: std::true_type {};
template <typename C, typename U = uncvref_t<C>>
struct is_container {
static constexpr bool value =
!is_span<U>::value && !is_std_array<U>::value &&
!std::is_array<U>::value && has_size_and_data<C>::value;
};
template <typename T>
using remove_pointer_t = typename std::remove_pointer<T>::type;
template <typename, typename, typename = void>
struct is_container_element_type_compatible : std::false_type {};
template <typename T, typename E>
struct is_container_element_type_compatible<
T, E,
typename std::enable_if<
!std::is_same<
typename std::remove_cv<decltype(detail::data(std::declval<T>()))>::type,
void>::value &&
std::is_convertible<
remove_pointer_t<decltype(detail::data(std::declval<T>()))> (*)[],
E (*)[]>::value
>::type>
: std::true_type {};
template <typename, typename = size_t>
struct is_complete : std::false_type {};
template <typename T>
struct is_complete<T, decltype(sizeof(T))> : std::true_type {};
} // namespace detail
template <typename ElementType, std::size_t Extent>
class span {
static_assert(std::is_object<ElementType>::value,
"A span's ElementType must be an object type (not a "
"reference type or void)");
static_assert(detail::is_complete<ElementType>::value,
"A span's ElementType must be a complete type (not a forward "
"declaration)");
static_assert(!std::is_abstract<ElementType>::value,
"A span's ElementType cannot be an abstract class type");
using storage_type = detail::span_storage<ElementType, Extent>;
public:
// constants and types
using element_type = ElementType;
using value_type = typename std::remove_cv<ElementType>::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<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<std::ptrdiff_t>(extent));
}
template <std::size_t N, std::size_t E = Extent,
typename std::enable_if<
(E == dynamic_extent || N == E) &&
detail::is_container_element_type_compatible<
element_type (&)[N], ElementType>::value,
int>::type = 0>
constexpr span(element_type (&arr)[N]) noexcept : storage_(arr, N)
{}
template <typename T, std::size_t N, std::size_t E = Extent,
typename std::enable_if<
(E == dynamic_extent || N == E) &&
detail::is_container_element_type_compatible<
std::array<T, N>&, ElementType>::value,
int>::type = 0>
TCB_SPAN_ARRAY_CONSTEXPR span(std::array<T, N>& arr) noexcept
: storage_(arr.data(), N)
{}
template <typename T, std::size_t N, std::size_t E = Extent,
typename std::enable_if<
(E == dynamic_extent || N == E) &&
detail::is_container_element_type_compatible<
const std::array<T, N>&, ElementType>::value,
int>::type = 0>
TCB_SPAN_ARRAY_CONSTEXPR span(const std::array<T, N>& arr) noexcept
: storage_(arr.data(), N)
{}
template <
typename Container, std::size_t E = Extent,
typename std::enable_if<
E == dynamic_extent && detail::is_container<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<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 <typename OtherElementType, std::size_t OtherExtent,
typename std::enable_if<
(Extent == dynamic_extent || OtherExtent == dynamic_extent ||
Extent == OtherExtent) &&
std::is_convertible<OtherElementType (*)[],
ElementType (*)[]>::value,
int>::type = 0>
constexpr span(const span<OtherElementType, OtherExtent>& 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 <std::size_t Count>
TCB_SPAN_CONSTEXPR11 span<element_type, Count> first() const
{
TCB_SPAN_EXPECT(Count <= size());
return {data(), Count};
}
template <std::size_t Count>
TCB_SPAN_CONSTEXPR11 span<element_type, Count> last() const
{
TCB_SPAN_EXPECT(Count <= size());
return {data() + (size() - Count), Count};
}
template <std::size_t Offset, std::size_t Count = dynamic_extent>
using subspan_return_t =
span<ElementType, Count != dynamic_extent
? Count
: (Extent != dynamic_extent ? Extent - Offset
: dynamic_extent)>;
template <std::size_t Offset, std::size_t Count = dynamic_extent>
TCB_SPAN_CONSTEXPR11 subspan_return_t<Offset, Count> 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<element_type, dynamic_extent>
first(size_type count) const
{
TCB_SPAN_EXPECT(count <= size());
return {data(), count};
}
TCB_SPAN_CONSTEXPR11 span<element_type, dynamic_extent>
last(size_type count) const
{
TCB_SPAN_EXPECT(count <= size());
return {data() + (size() - count), count};
}
TCB_SPAN_CONSTEXPR11 span<element_type, dynamic_extent>
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 <class T, size_t N>
span(T (&)[N])->span<T, N>;
template <class T, size_t N>
span(std::array<T, N>&)->span<T, N>;
template <class T, size_t N>
span(const std::array<T, N>&)->span<const T, N>;
template <class Container>
span(Container&)->span<typename std::remove_reference<
decltype(*detail::data(std::declval<Container&>()))>::type>;
template <class Container>
span(const Container&)->span<const typename Container::value_type>;
#endif // TCB_HAVE_DEDUCTION_GUIDES
template <typename ElementType, std::size_t Extent>
constexpr span<ElementType, Extent>
make_span(span<ElementType, Extent> s) noexcept
{
return s;
}
template <typename T, std::size_t N>
constexpr span<T, N> make_span(T (&arr)[N]) noexcept
{
return {arr};
}
template <typename T, std::size_t N>
TCB_SPAN_ARRAY_CONSTEXPR span<T, N> make_span(std::array<T, N>& arr) noexcept
{
return {arr};
}
template <typename T, std::size_t N>
TCB_SPAN_ARRAY_CONSTEXPR span<const T, N>
make_span(const std::array<T, N>& arr) noexcept
{
return {arr};
}
template <typename Container>
constexpr span<typename std::remove_reference<
decltype(*detail::data(std::declval<Container&>()))>::type>
make_span(Container& cont)
{
return {cont};
}
template <typename Container>
constexpr span<const typename Container::value_type>
make_span(const Container& cont)
{
return {cont};
}
template <typename ElementType, std::size_t Extent>
span<const byte, ((Extent == dynamic_extent) ? dynamic_extent
: sizeof(ElementType) * Extent)>
as_bytes(span<ElementType, Extent> s) noexcept
{
return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()};
}
template <
class ElementType, size_t Extent,
typename std::enable_if<!std::is_const<ElementType>::value, int>::type = 0>
span<byte, ((Extent == dynamic_extent) ? dynamic_extent
: sizeof(ElementType) * Extent)>
as_writable_bytes(span<ElementType, Extent> s) noexcept
{
return {reinterpret_cast<byte*>(s.data()), s.size_bytes()};
}
template <std::size_t N, typename E, std::size_t S>
constexpr auto get(span<E, S> s) -> decltype(s[N])
{
return s[N];
}
} // namespace TCB_SPAN_NAMESPACE_NAME
namespace std {
template <typename ElementType, size_t Extent>
class tuple_size<TCB_SPAN_NAMESPACE_NAME::span<ElementType, Extent>>
: public integral_constant<size_t, Extent> {};
template <typename ElementType>
class tuple_size<TCB_SPAN_NAMESPACE_NAME::span<
ElementType, TCB_SPAN_NAMESPACE_NAME::dynamic_extent>>; // not defined
template <size_t I, typename ElementType, size_t Extent>
class tuple_element<I, TCB_SPAN_NAMESPACE_NAME::span<ElementType, Extent>> {
public:
static_assert(Extent != TCB_SPAN_NAMESPACE_NAME::dynamic_extent &&
I < Extent,
"");
using type = ElementType;
};
} // end namespace std
#endif // TCB_SPAN_HPP_INCLUDED

View file

@ -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

View file

@ -18,7 +18,7 @@ SCENARIO("PrintObject: object layer heights", "[PrintObject]") {
{ "layer_height", 2 },
{ "nozzle_diameter", 3 }
});
ConstLayerPtrsAdaptor layers = print.objects().front()->layers();
SpanOfConstPtrs<Layer> 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<Layer> 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<Layer> layers = print.objects().front()->layers();
THEN("The output vector has 2 entries") {
REQUIRE(layers.size() == 2);
}

View file

@ -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<SupportLayer> support_layers = print.objects().front()->support_layers();
first_support_layer_height_ok = support_layers.front()->print_z == print.config().first_layer_height.value;

View file

@ -1,3 +1,4 @@
#include <algorithm>
#include <catch2/catch.hpp>
#include <test_utils.hpp>
@ -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<Linef> 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 <iostream>