Merge remote-tracking branch 'remotes/prusa/master'
note: new infill connect, maybe a good idea to get the previous one in case it's better (no useless lines) note2: fillline overextrude, tofix
BIN
PrusaSlicer.mo
Normal file
@ -78,7 +78,6 @@ src/libslic3r/ExtrusionEntity.cpp
|
||||
src/libslic3r/Flow.cpp
|
||||
src/libslic3r/Format/3mf.cpp
|
||||
src/libslic3r/Format/AMF.cpp
|
||||
src/libslic3r/GCode/PreviewData.cpp
|
||||
src/libslic3r/miniz_extension.cpp
|
||||
src/libslic3r/Preset.cpp
|
||||
src/libslic3r/Print.cpp
|
||||
|
@ -1,4 +1,6 @@
|
||||
min_slic3r_version = 2.3.0-alpha2
|
||||
0.0.4 Fixed predator output filaname format, infill overlap.
|
||||
0.0.3 Fixed infill_overlap, start_gcode, end_gcode for Anycubic Predator
|
||||
0.0.2 Added Anycubic Predator
|
||||
min_slic3r_version = 2.3.0-alpha0
|
||||
0.0.1 Initial Version
|
||||
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 33 KiB |
@ -1,5 +1,8 @@
|
||||
min_slic3r_version = 2.3.0-alpha2
|
||||
0.0.5 Superslicer adaptations
|
||||
0.1.7 Updated start g-code for Creality printers
|
||||
0.0.6 Added filament profiles, adjusted temperatures, updated start g-code for some models.
|
||||
0.0.5 Added 0.08mm SUPERDETAIL and 0.28mm SUPERDRAFT print profiles. Updated OPTIMAL print profile.
|
||||
0.1.5 Superslicer adaptations
|
||||
0.0.4 Added initial CR-10 profile, end g-code improvements.
|
||||
min_slic3r_version = 2.3.0-alpha0
|
||||
0.0.3 Added Ender-2, Ender-3 BLTouch, updated Ender-3 bed texture.
|
||||
|
@ -5,7 +5,7 @@
|
||||
name = Creality
|
||||
# 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.5
|
||||
config_version = 0.1.7
|
||||
# Where to get the updates from?
|
||||
config_update_url =
|
||||
# https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Creality/
|
||||
@ -339,6 +339,10 @@ inherits = *0.24mm*
|
||||
renamed_from = "0.24mm DRAFT @ENDER3"
|
||||
compatible_printers_condition = printer_model=~/(ENDER|CR).*/ and nozzle_diameter[0]==0.4
|
||||
|
||||
[print:0.28mm SUPERDRAFT @CREALITY]
|
||||
inherits = *0.28mm*
|
||||
compatible_printers_condition = printer_model=~/(ENDER|CR).*/ and nozzle_diameter[0]==0.4
|
||||
|
||||
# Common filament preset
|
||||
[filament:*common*]
|
||||
cooling = 0
|
||||
@ -358,20 +362,20 @@ compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_CREALITY.*/
|
||||
inherits = *common*
|
||||
bed_temperature = 60
|
||||
fan_below_layer_time = 100
|
||||
filament_colour = #FF3232
|
||||
filament_colour = #DDDDDD
|
||||
filament_max_volumetric_speed = 15
|
||||
filament_type = PLA
|
||||
filament_density = 1.24
|
||||
filament_cost = 20
|
||||
first_layer_bed_temperature = 60
|
||||
first_layer_temperature = 205
|
||||
first_layer_temperature = 210
|
||||
fan_always_on = 1
|
||||
cooling = 1
|
||||
max_fan_speed = 100
|
||||
min_fan_speed = 100
|
||||
bridge_fan_speed = 100
|
||||
disable_fan_first_layers = 1
|
||||
temperature = 200
|
||||
temperature = 205
|
||||
|
||||
[filament:*PET*]
|
||||
inherits = *common*
|
||||
@ -379,7 +383,7 @@ bed_temperature = 70
|
||||
cooling = 1
|
||||
disable_fan_first_layers = 3
|
||||
fan_below_layer_time = 20
|
||||
filament_colour = #FF8000
|
||||
filament_colour = #DDDDDD
|
||||
filament_max_volumetric_speed = 8
|
||||
filament_type = PETG
|
||||
filament_density = 1.27
|
||||
@ -398,7 +402,7 @@ bed_temperature = 100
|
||||
cooling = 0
|
||||
disable_fan_first_layers = 3
|
||||
fan_below_layer_time = 20
|
||||
filament_colour = #3A80CA
|
||||
filament_colour = #DDDDDD
|
||||
filament_max_volumetric_speed = 11
|
||||
filament_type = ABS
|
||||
filament_density = 1.04
|
||||
@ -433,10 +437,11 @@ filament_vendor = Generic
|
||||
inherits = *PLA*
|
||||
renamed_from = "Creality PLA @ENDER3"
|
||||
filament_vendor = Creality
|
||||
temperature = 205
|
||||
bed_temperature = 40
|
||||
first_layer_temperature = 210
|
||||
first_layer_bed_temperature = 40
|
||||
temperature = 200
|
||||
bed_temperature = 60
|
||||
first_layer_temperature = 205
|
||||
first_layer_bed_temperature = 60
|
||||
filament_colour = #42BDD8
|
||||
|
||||
[filament:Creality PETG @CREALITY]
|
||||
inherits = *PET*
|
||||
@ -448,6 +453,7 @@ first_layer_temperature = 240
|
||||
first_layer_bed_temperature = 70
|
||||
max_fan_speed = 40
|
||||
min_fan_speed = 20
|
||||
filament_colour = #42BDD8
|
||||
|
||||
[filament:Creality ABS @CREALITY]
|
||||
inherits = *ABS*
|
||||
@ -457,17 +463,19 @@ temperature = 240
|
||||
bed_temperature = 90
|
||||
first_layer_temperature = 240
|
||||
first_layer_bed_temperature = 90
|
||||
filament_colour = #42BDD8
|
||||
|
||||
[filament:Prusament PLA @CREALITY]
|
||||
inherits = *PLA*
|
||||
renamed_from = "Prusament PLA @ENDER3"
|
||||
filament_vendor = Prusa Polymers
|
||||
temperature = 210
|
||||
bed_temperature = 50
|
||||
bed_temperature = 60
|
||||
first_layer_temperature = 215
|
||||
first_layer_bed_temperature = 50
|
||||
first_layer_bed_temperature = 60
|
||||
filament_cost = 24.99
|
||||
filament_density = 1.24
|
||||
filament_colour = #F94D0C
|
||||
|
||||
[filament:Prusament PETG @CREALITY]
|
||||
inherits = *PET*
|
||||
@ -479,6 +487,18 @@ first_layer_temperature = 245
|
||||
first_layer_bed_temperature = 70
|
||||
filament_cost = 24.99
|
||||
filament_density = 1.27
|
||||
filament_colour = #F94D0C
|
||||
|
||||
[filament:AzureFilm PLA @CREALITY]
|
||||
inherits = *PLA*
|
||||
filament_vendor = AzureFilm
|
||||
temperature = 210
|
||||
bed_temperature = 60
|
||||
first_layer_temperature = 215
|
||||
first_layer_bed_temperature = 60
|
||||
filament_cost = 19.97
|
||||
filament_density = 1.24
|
||||
filament_colour = #006AA6
|
||||
|
||||
[filament:Devil Design PLA @CREALITY]
|
||||
inherits = *PLA*
|
||||
@ -489,6 +509,18 @@ first_layer_temperature = 215
|
||||
first_layer_bed_temperature = 60
|
||||
filament_cost = 19.00
|
||||
filament_density = 1.24
|
||||
filament_colour = #FF0000
|
||||
|
||||
[filament:Devil Design PLA (Galaxy) @CREALITY]
|
||||
inherits = *PLA*
|
||||
filament_vendor = Devil Design
|
||||
temperature = 225
|
||||
bed_temperature = 65
|
||||
first_layer_temperature = 225
|
||||
first_layer_bed_temperature = 65
|
||||
filament_cost = 19.00
|
||||
filament_density = 1.24
|
||||
filament_colour = #FF0000
|
||||
|
||||
[filament:Extrudr PLA NX2 @CREALITY]
|
||||
inherits = *PLA*
|
||||
@ -499,6 +531,7 @@ first_layer_temperature = 205
|
||||
first_layer_bed_temperature = 60
|
||||
filament_cost = 23.63
|
||||
filament_density = 1.3
|
||||
filament_colour = #3C4547
|
||||
|
||||
[filament:Real Filament PLA @CREALITY]
|
||||
inherits = *PLA*
|
||||
@ -509,6 +542,7 @@ first_layer_temperature = 200
|
||||
first_layer_bed_temperature = 60
|
||||
filament_cost = 24.99
|
||||
filament_density = 1.24
|
||||
filament_colour = #007ABF
|
||||
|
||||
[filament:Velleman PLA @CREALITY]
|
||||
inherits = *PLA*
|
||||
@ -519,6 +553,7 @@ first_layer_temperature = 205
|
||||
first_layer_bed_temperature = 60
|
||||
filament_cost = 27.99
|
||||
filament_density = 1.24
|
||||
filament_colour = #7EA60D
|
||||
|
||||
[filament:3DJAKE ecoPLA @CREALITY]
|
||||
inherits = *PLA*
|
||||
@ -529,6 +564,7 @@ first_layer_temperature = 205
|
||||
first_layer_bed_temperature = 60
|
||||
filament_cost = 21.99
|
||||
filament_density = 1.24
|
||||
filament_colour = #125467
|
||||
|
||||
[filament:123-3D Jupiter PLA @CREALITY]
|
||||
inherits = *PLA*
|
||||
@ -539,12 +575,14 @@ first_layer_temperature = 205
|
||||
first_layer_bed_temperature = 60
|
||||
filament_cost = 19.50
|
||||
filament_density = 1.24
|
||||
filament_colour = #FFE200
|
||||
|
||||
# Common printer preset
|
||||
[printer:*common*]
|
||||
printer_technology = FFF
|
||||
before_layer_gcode = ;BEFORE_LAYER_CHANGE\nG92 E0\n;[layer_z]\n\n
|
||||
between_objects_gcode =
|
||||
pause_print_gcode =
|
||||
deretract_speed = 0
|
||||
extruder_colour = #FFFF00
|
||||
extruder_offset = 0x0
|
||||
@ -625,7 +663,6 @@ deretract_speed = 40
|
||||
retract_before_wipe = 70%
|
||||
default_filament_profile = Creality PLA @CREALITY
|
||||
|
||||
|
||||
[printer:*0.2nozzle*]
|
||||
nozzle_diameter = 0.2
|
||||
max_layer_height = 0.16
|
||||
@ -705,16 +742,19 @@ inherits = *Creality Ender-3*; *0.5nozzle*
|
||||
[printer:Creality Ender-3 0.6mm]
|
||||
inherits = *Creality Ender-3*; *0.6nozzle*
|
||||
|
||||
[printer:*abl*]
|
||||
start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S150 ; set extruder temp for auto bed leveling\nM140 S[first_layer_bed_temperature] ; set bed temp\nG28 ; home all\nG29 ; auto bed levelling\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S{first_layer_temperature[initial_extruder]+extruder_temperature_offset[initial_extruder]} ; set extruder temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S{first_layer_temperature[initial_extruder]+extruder_temperature_offset[initial_extruder]} ; wait for extruder temp\nG1 Z0.28 F240\nG92 E0.0\nG1 Y190 E15.0 F1500.0 ; intro line\nG1 X2.3 F5000\nG1 Y10 E15.0 F1200.0 ; intro line\nG92 E0.0
|
||||
[printer:*fastabl*]
|
||||
start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S150 ; set extruder temp for auto bed leveling\nM140 S[first_layer_bed_temperature] ; set bed temp\nG28 ; home all\nG29 ; auto bed levelling\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S{first_layer_temperature[initial_extruder]+extruder_temperature_offset[initial_extruder]} ; set extruder temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S{first_layer_temperature[initial_extruder]+extruder_temperature_offset[initial_extruder]} ; wait for extruder temp\nG1 Z0.28 F240\nG92 E0\nG1 Y190 E15 F1500 ; intro line\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E15 F1200 ; intro line\nG92 E0
|
||||
|
||||
[printer:*slowabl*]
|
||||
start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S150 ; set extruder temp for auto bed leveling\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nG28 ; home all\nG29 ; auto bed levelling\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S{first_layer_temperature[initial_extruder]+extruder_temperature_offset[initial_extruder]} ; set extruder temp\nM109 S{first_layer_temperature[initial_extruder]+extruder_temperature_offset[initial_extruder]} ; wait for extruder temp\nG1 Z0.28 F240\nG92 E0\nG1 Y190 E15 F1500 ; intro line\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E15 F1200 ; intro line\nG92 E0
|
||||
|
||||
[printer:*invertedz*]
|
||||
end_gcode = M104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+5, max_print_height)} F600{endif} ; Move print bed down\nG1 X50 Y50 F3000 ; present print\n{if layer_z < max_print_height-10}G1 Z{z_offset+max_print_height-10} F600{endif} ; Move print bed down\nM84 X Y E ; disable motors
|
||||
|
||||
[printer:*Creality Ender-3 BLTouch*]
|
||||
inherits = *SmallBowden*; *abl*
|
||||
inherits = *SmallBowden*; *fastabl*
|
||||
renamed_from = "Creality ENDER-3 BLTouch"
|
||||
printer_model = ENDER3BLTOUCH
|
||||
|
||||
[printer:Creality Ender-3 BLTouch 0.4mm]
|
||||
inherits = *Creality Ender-3 BLTouch*; *0.4nozzle*
|
||||
renamed_from = "Creality ENDER-3 BLTouch"
|
||||
@ -749,7 +789,7 @@ inherits = *Creality Ender-5*; *0.5nozzle*
|
||||
inherits = *Creality Ender-5*; *0.6nozzle*
|
||||
|
||||
[printer:*Creality Ender-5 Plus*]
|
||||
inherits = *SmallBowden*; *abl*; *invertedz*
|
||||
inherits = *SmallBowden*; *slowabl*; *invertedz*
|
||||
retract_length = 6
|
||||
bed_shape = 5x5,355x5,355x355,5x355
|
||||
printer_model = ENDER5PLUS
|
||||
@ -774,7 +814,7 @@ bed_shape = 0x0,150x0,150x150,0x150
|
||||
printer_model = ENDER2
|
||||
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_CREALITY\nPRINTER_MODEL_ENDER2\nPRINTER_HAS_BOWDEN
|
||||
max_print_height = 200
|
||||
start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S{first_layer_temperature[initial_extruder]+extruder_temperature_offset[initial_extruder]} ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S{first_layer_temperature[initial_extruder]+extruder_temperature_offset[initial_extruder]} ; wait for extruder temp\nG28 ; home all\nG1 Z2 F240\nG1 X2 Y10 F3000\nG1 Z0.28 F240\nG92 E0.0\nG1 X15 Y135 E15.0 F1500.0 ; intro line\nG1 X2.3 F5000\nG1 Y10 E15.0 F1200.0 ; intro line\nG92 E0.0
|
||||
start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S{first_layer_temperature[initial_extruder]+extruder_temperature_offset[initial_extruder]} ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S{first_layer_temperature[initial_extruder]+extruder_temperature_offset[initial_extruder]} ; wait for extruder temp\nG28 ; home all\nG1 Z2 F240\nG1 X2 Y10 F3000\nG1 Z0.28 F240\nG92 E0\nG1 X15 Y135 E15 F1500 ; intro line\nG1 X2.3 F5000\nG1 Y10 E15 F1200 ; intro line\nG92 E0
|
||||
end_gcode = M104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+5, max_print_height)} F600{endif} ; Move print head up\nG1 X5 Y140 F3000 ; present print\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+30, max_print_height)} F600{endif} ; Move print head up\nM84 X Y E ; disable motors
|
||||
|
||||
[printer:Creality Ender-2 0.4mm]
|
||||
@ -879,7 +919,7 @@ inherits = *Creality CR-10 S*; *0.6nozzle*
|
||||
inherits = *Creality CR-10 S*; *0.8nozzle*
|
||||
|
||||
[printer:*Creality CR-10 S Pro*]
|
||||
inherits = *SmallBowden*; *abl*
|
||||
inherits = *SmallBowden*; *slowabl*
|
||||
retract_length = 6
|
||||
bed_shape = 0x0,300x0,300x300,0x300
|
||||
printer_model = CR10SPRO
|
||||
@ -896,7 +936,7 @@ inherits = *Creality CR-10 S Pro*; *0.6nozzle*
|
||||
inherits = *Creality CR-10 S Pro*; *0.8nozzle*
|
||||
|
||||
[printer:*Creality CR-10 S Pro V2*]
|
||||
inherits = *SmallBowden*; *abl*
|
||||
inherits = *SmallBowden*; *slowabl*
|
||||
retract_length = 6
|
||||
bed_shape = 5x5,305x5,305x305,5x305
|
||||
printer_model = CR10SPROV2
|
||||
@ -967,7 +1007,7 @@ inherits = *Creality CR-20*; *0.5nozzle*
|
||||
inherits = *Creality CR-20*; *0.6nozzle*
|
||||
|
||||
[printer:*Creality CR-20 Pro*]
|
||||
inherits = *SmallBowden*; *abl*
|
||||
inherits = *SmallBowden*; *fastabl*
|
||||
retract_length = 4
|
||||
printer_model = CR20PRO
|
||||
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_CREALITY\nPRINTER_MODEL_CR20PRO\nPRINTER_HAS_BOWDEN
|
||||
@ -983,3 +1023,4 @@ inherits = *Creality CR-20 Pro*; *0.5nozzle*
|
||||
|
||||
[printer:Creality CR-20 Pro 0.6mm]
|
||||
inherits = *Creality CR-20 Pro*; *0.6nozzle*
|
||||
|
||||
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 42 KiB |
@ -1,3 +1,5 @@
|
||||
min_slic3r_version = 2.3.0-alpha4
|
||||
1.2.0-alpha0 Added filament spool weights
|
||||
min_slic3r_version = 2.2.0-alpha3
|
||||
1.1.11 SuperSlicer version
|
||||
1.1.10 Updated firmware version.
|
||||
|
@ -1824,12 +1824,14 @@ inherits = *PLA*
|
||||
filament_vendor = Fillamentum
|
||||
filament_cost = 21.99
|
||||
filament_density = 1.24
|
||||
filament_spool_weight = 230
|
||||
|
||||
[filament:Fillamentum ABS]
|
||||
inherits = *ABSC*
|
||||
filament_vendor = Fillamentum
|
||||
filament_cost = 32.4
|
||||
filament_density = 1.04
|
||||
filament_spool_weight = 230
|
||||
first_layer_temperature = 240
|
||||
temperature = 240
|
||||
|
||||
@ -1838,6 +1840,7 @@ inherits = *ABS*
|
||||
filament_vendor = Fillamentum
|
||||
filament_cost = 38.7
|
||||
filament_density = 1.07
|
||||
filament_spool_weight = 230
|
||||
fan_always_on = 1
|
||||
cooling = 1
|
||||
min_fan_speed = 20
|
||||
@ -1853,6 +1856,7 @@ inherits = *ABS*
|
||||
filament_vendor = Prusa Polymers
|
||||
filament_cost = 35.28
|
||||
filament_density = 1.07
|
||||
filament_spool_weight = 201
|
||||
fan_always_on = 1
|
||||
first_layer_temperature = 260
|
||||
first_layer_bed_temperature = 105
|
||||
@ -1874,6 +1878,7 @@ inherits = *ABS*
|
||||
filament_vendor = Prusa Polymers
|
||||
filament_cost = 49.99
|
||||
filament_density = 1.22
|
||||
filament_spool_weight = 201
|
||||
fan_always_on = 0
|
||||
first_layer_temperature = 275
|
||||
first_layer_bed_temperature = 110
|
||||
@ -1900,6 +1905,7 @@ inherits = *ABS*
|
||||
filament_vendor = Prusa Polymers
|
||||
filament_cost = 49.99
|
||||
filament_density = 1.22
|
||||
filament_spool_weight = 201
|
||||
fan_always_on = 0
|
||||
first_layer_temperature = 275
|
||||
first_layer_bed_temperature = 105
|
||||
@ -1933,6 +1939,7 @@ inherits = *PET*
|
||||
filament_vendor = Fillamentum
|
||||
filament_cost = 34.99
|
||||
filament_density = 1.25
|
||||
filament_spool_weight = 230
|
||||
filament_type = CPE
|
||||
first_layer_bed_temperature = 90
|
||||
first_layer_temperature = 275
|
||||
@ -1948,6 +1955,7 @@ compatible_printers_condition = nozzle_diameter[0]>0.35 and ! (printer_notes=~/.
|
||||
extrusion_multiplier = 1.1
|
||||
filament_cost = 68
|
||||
filament_density = 1.15
|
||||
filament_spool_weight = 230
|
||||
filament_colour = #804040
|
||||
filament_max_volumetric_speed = 10
|
||||
first_layer_temperature = 190
|
||||
@ -1986,12 +1994,14 @@ inherits = *ABSC*
|
||||
filament_vendor = Hatchbox
|
||||
filament_cost = 27.82
|
||||
filament_density = 1.04
|
||||
filament_spool_weight = 225
|
||||
|
||||
[filament:Plasty Mladec ABS]
|
||||
inherits = *ABSC*
|
||||
filament_vendor = Plasty Mladec
|
||||
filament_cost = 27.82
|
||||
filament_density = 1.08
|
||||
filament_spool_weight = 230
|
||||
|
||||
[filament:Verbatim ABS]
|
||||
inherits = *ABSC*
|
||||
@ -2012,6 +2022,7 @@ inherits = *PET*
|
||||
filament_vendor = Plasty Mladec
|
||||
filament_cost = 27.82
|
||||
filament_density = 1.27
|
||||
filament_spool_weight = 230
|
||||
|
||||
[filament:Generic PLA]
|
||||
inherits = *PLA*
|
||||
@ -2056,6 +2067,7 @@ inherits = *FLEX*
|
||||
filament_vendor = Fillamentum
|
||||
filament_cost = 33.99
|
||||
filament_density = 1.20
|
||||
filament_spool_weight = 230
|
||||
filament_max_volumetric_speed = 1.2
|
||||
filament_retract_length = 0
|
||||
filament_retract_speed = nil
|
||||
@ -2153,6 +2165,7 @@ inherits = *ABSC*
|
||||
filament_vendor = Made for Prusa
|
||||
filament_cost = 22.99
|
||||
filament_density = 1.08
|
||||
filament_spool_weight = 230
|
||||
|
||||
[filament:*ABS MMU2*]
|
||||
inherits = Prusa ABS
|
||||
@ -2202,6 +2215,7 @@ inherits = *ABS MMU2*
|
||||
filament_vendor = Prusa Polymers
|
||||
filament_cost = 35.28
|
||||
filament_density = 1.07
|
||||
filament_spool_weight = 201
|
||||
fan_always_on = 1
|
||||
first_layer_temperature = 260
|
||||
first_layer_bed_temperature = 105
|
||||
@ -2226,6 +2240,7 @@ inherits = *ABS MMU2*
|
||||
filament_vendor = Prusa Polymers
|
||||
filament_cost = 49.99
|
||||
filament_density = 1.22
|
||||
filament_spool_weight = 201
|
||||
fan_always_on = 0
|
||||
fan_below_layer_time = 30
|
||||
first_layer_temperature = 265
|
||||
@ -2254,17 +2269,20 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and no
|
||||
inherits = *ABS MMU2*
|
||||
filament_vendor = Made for Prusa
|
||||
filament_cost = 22.99
|
||||
filament_spool_weight = 230
|
||||
|
||||
[filament:Plasty Mladec ABS @MMU2]
|
||||
inherits = *ABS MMU2*
|
||||
filament_vendor = Plasty Mladec
|
||||
filament_density = 1.08
|
||||
filament_spool_weight = 230
|
||||
|
||||
[filament:Prusa HIPS]
|
||||
inherits = *ABS*
|
||||
filament_vendor = Made for Prusa
|
||||
filament_cost = 27.3
|
||||
filament_density = 1.04
|
||||
filament_spool_weight = 230
|
||||
bridge_fan_speed = 50
|
||||
cooling = 1
|
||||
extrusion_multiplier = 1
|
||||
@ -2304,6 +2322,7 @@ renamed_from = "Prusa PET"
|
||||
filament_vendor = Made for Prusa
|
||||
filament_cost = 22.99
|
||||
filament_density = 1.27
|
||||
filament_spool_weight = 230
|
||||
compatible_printers_condition = nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and printer_model!="MINI" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
|
||||
|
||||
[filament:Verbatim PETG]
|
||||
@ -2327,6 +2346,7 @@ first_layer_temperature = 240
|
||||
temperature = 250
|
||||
filament_cost = 29.99
|
||||
filament_density = 1.27
|
||||
filament_spool_weight = 201
|
||||
filament_type = PETG
|
||||
compatible_printers_condition = nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and printer_model!="MINI" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
|
||||
|
||||
@ -2336,6 +2356,7 @@ renamed_from = "Prusa PET 0.6 nozzle"; "Prusa PETG 0.6 nozzle"
|
||||
filament_vendor = Made for Prusa
|
||||
filament_cost = 22.99
|
||||
filament_density = 1.27
|
||||
filament_spool_weight = 230
|
||||
|
||||
[filament:Prusament PETG @0.6 nozzle]
|
||||
inherits = *PET06*
|
||||
@ -2344,6 +2365,7 @@ first_layer_temperature = 240
|
||||
temperature = 250
|
||||
filament_cost = 29.99
|
||||
filament_density = 1.27
|
||||
filament_spool_weight = 201
|
||||
filament_type = PETG
|
||||
|
||||
[filament:Plasty Mladec PETG @0.6 nozzle]
|
||||
@ -2353,6 +2375,7 @@ first_layer_temperature = 230
|
||||
temperature = 240
|
||||
filament_cost = 27.92
|
||||
filament_density = 1.27
|
||||
filament_spool_weight = 230
|
||||
filament_type = PETG
|
||||
|
||||
[filament:Devil Design PETG @0.6 nozzle]
|
||||
@ -2415,12 +2438,14 @@ filament_vendor = Generic
|
||||
[filament:Plasty Mladec PETG @MMU2]
|
||||
inherits = *PET MMU2*
|
||||
filament_vendor = Plasty Mladec
|
||||
filament_spool_weight = 230
|
||||
|
||||
[filament:Prusa PETG @MMU2]
|
||||
inherits = *PET MMU2*
|
||||
renamed_from = "Prusa PET MMU2"; "Prusa PETG MMU2"
|
||||
filament_vendor = Made for Prusa
|
||||
filament_cost = 22.99
|
||||
filament_spool_weight = 230
|
||||
|
||||
[filament:Prusament PETG @MMU2]
|
||||
inherits = *PET MMU2*
|
||||
@ -2428,6 +2453,7 @@ filament_type = PETG
|
||||
filament_vendor = Prusa Polymers
|
||||
filament_cost = 29.99
|
||||
filament_density = 1.27
|
||||
filament_spool_weight = 201
|
||||
|
||||
[filament:Generic PETG @MMU2 0.6 nozzle]
|
||||
inherits = *PET MMU2 06*
|
||||
@ -2438,6 +2464,7 @@ filament_vendor = Generic
|
||||
inherits = *PET MMU2 06*
|
||||
renamed_from = "Prusa PET MMU2 0.6 nozzle"; "Prusa PETG MMU2 0.6 nozzle"
|
||||
filament_vendor = Made for Prusa
|
||||
filament_spool_weight = 230
|
||||
|
||||
[filament:Prusament PETG @MMU2 0.6 nozzle]
|
||||
inherits = *PET MMU2 06*
|
||||
@ -2445,17 +2472,20 @@ filament_type = PETG
|
||||
filament_vendor = Prusa Polymers
|
||||
filament_cost = 29.99
|
||||
filament_density = 1.27
|
||||
filament_spool_weight = 201
|
||||
|
||||
[filament:Plasty Mladec PETG @MMU2 0.6 nozzle]
|
||||
inherits = *PET MMU2 06*
|
||||
filament_type = PETG
|
||||
filament_vendor = Plasty Mladec
|
||||
filament_spool_weight = 230
|
||||
|
||||
[filament:Prusa PLA]
|
||||
inherits = *PLA*
|
||||
filament_vendor = Made for Prusa
|
||||
filament_cost = 20.99
|
||||
filament_density = 1.24
|
||||
filament_spool_weight = 230
|
||||
|
||||
[filament:Fiberlogy PLA]
|
||||
inherits = *PLA*
|
||||
@ -2468,6 +2498,7 @@ inherits = *PLA*
|
||||
filament_vendor = Plasty Mladec
|
||||
filament_cost = 25.4
|
||||
filament_density = 1.24
|
||||
filament_spool_weight = 230
|
||||
|
||||
[filament:AmazonBasics PLA]
|
||||
inherits = *PLA*
|
||||
@ -2480,6 +2511,7 @@ inherits = *PLA*
|
||||
filament_vendor = Hatchbox
|
||||
filament_cost = 25.4
|
||||
filament_density = 1.24
|
||||
filament_spool_weight = 225
|
||||
|
||||
[filament:Esun PLA]
|
||||
inherits = *PLA*
|
||||
@ -2511,6 +2543,7 @@ filament_vendor = Prusa Polymers
|
||||
temperature = 215
|
||||
filament_cost = 24.99
|
||||
filament_density = 1.24
|
||||
filament_spool_weight = 201
|
||||
filament_notes = "Affordable filament for everyday printing in premium quality manufactured in-house by Josef Prusa"
|
||||
|
||||
[filament:*PLA MMU2*]
|
||||
@ -2537,18 +2570,21 @@ filament_vendor = Generic
|
||||
inherits = *PLA MMU2*
|
||||
filament_vendor = Made for Prusa
|
||||
filament_cost = 20.99
|
||||
filament_spool_weight = 230
|
||||
|
||||
[filament:Prusament PLA @MMU2]
|
||||
inherits = *PLA MMU2*
|
||||
filament_vendor = Prusa Polymers
|
||||
filament_cost = 24.99
|
||||
filament_density = 1.24
|
||||
filament_spool_weight = 201
|
||||
|
||||
[filament:Fillamentum PLA @MMU2]
|
||||
inherits = *PLA MMU2*
|
||||
filament_vendor = Fillamentum
|
||||
filament_cost = 21.99
|
||||
filament_density = 1.24
|
||||
filament_spool_weight = 230
|
||||
|
||||
[filament:SemiFlex or Flexfill 98A]
|
||||
inherits = *FLEX*
|
||||
@ -2562,6 +2598,7 @@ inherits = *FLEX*
|
||||
filament_vendor = Fillamentum
|
||||
filament_cost = 33.99
|
||||
filament_density = 1.23
|
||||
filament_spool_weight = 230
|
||||
filament_max_volumetric_speed = 1.35
|
||||
fan_always_on = 1
|
||||
cooling = 0
|
||||
@ -2596,6 +2633,7 @@ inherits = *common*
|
||||
filament_vendor = Fillamentum
|
||||
filament_cost = 56.99
|
||||
filament_density = 1.01
|
||||
filament_spool_weight = 230
|
||||
bed_temperature = 90
|
||||
bridge_fan_speed = 30
|
||||
cooling = 1
|
||||
@ -2807,6 +2845,7 @@ inherits = *PETMMU1*
|
||||
filament_vendor = Fillamentum
|
||||
filament_cost = 34.99
|
||||
filament_density = 1.25
|
||||
filament_spool_weight = 230
|
||||
filament_type = CPE
|
||||
first_layer_bed_temperature = 90
|
||||
first_layer_temperature = 275
|
||||
@ -2836,6 +2875,7 @@ inherits = *PETMMU1*
|
||||
filament_vendor = Plasty Mladec
|
||||
filament_cost = 27.82
|
||||
filament_density = 1.27
|
||||
filament_spool_weight = 230
|
||||
|
||||
[filament:Verbatim PETG @MMU1]
|
||||
inherits = *PETMMU1*
|
||||
@ -2855,6 +2895,7 @@ renamed_from = "Prusa PET MMU1"; "Prusa PETG MMU1"
|
||||
filament_vendor = Made for Prusa
|
||||
filament_cost = 22.99
|
||||
filament_density = 1.27
|
||||
filament_spool_weight = 230
|
||||
|
||||
[filament:Prusament PETG @MMU1]
|
||||
inherits = *PETMMU1*
|
||||
@ -2863,6 +2904,7 @@ first_layer_temperature = 240
|
||||
temperature = 250
|
||||
filament_cost = 29.99
|
||||
filament_density = 1.27
|
||||
filament_spool_weight = 201
|
||||
filament_type = PETG
|
||||
|
||||
[filament:Taulman T-Glase @MMU1]
|
||||
@ -2927,6 +2969,7 @@ inherits = Generic PETG; *PETMINI*
|
||||
filament_vendor = Plasty Mladec
|
||||
filament_cost = 27.82
|
||||
filament_density = 1.27
|
||||
filament_spool_weight = 230
|
||||
compatible_printers_condition = printer_model=="MINI" and nozzle_diameter[0]!=0.6
|
||||
|
||||
[filament:Verbatim PETG @MINI]
|
||||
@ -2996,6 +3039,7 @@ inherits = Generic ABS; *ABSMINI*
|
||||
filament_vendor = Hatchbox
|
||||
filament_cost = 27.82
|
||||
filament_density = 1.08
|
||||
filament_spool_weight = 225
|
||||
fan_always_on = 0
|
||||
cooling = 1
|
||||
min_fan_speed = 15
|
||||
@ -3010,6 +3054,7 @@ inherits = Generic ABS; *ABSMINI*
|
||||
filament_vendor = Plasty Mladec
|
||||
filament_cost = 27.82
|
||||
filament_density = 1.08
|
||||
filament_spool_weight = 230
|
||||
fan_always_on = 0
|
||||
cooling = 1
|
||||
min_fan_speed = 15
|
||||
@ -3039,6 +3084,7 @@ filament_vendor = Prusa Polymers
|
||||
first_layer_temperature = 240
|
||||
temperature = 250
|
||||
filament_density = 1.27
|
||||
filament_spool_weight = 201
|
||||
filament_cost = 29.99
|
||||
compatible_printers_condition = printer_model=="MINI" and nozzle_diameter[0]!=0.6
|
||||
|
||||
@ -3061,6 +3107,7 @@ inherits = Prusament PETG; *PETMINI06*
|
||||
first_layer_temperature = 240
|
||||
temperature = 250
|
||||
filament_density = 1.27
|
||||
filament_spool_weight = 201
|
||||
filament_cost = 29.99
|
||||
|
||||
[filament:Generic PETG @0.6 nozzle MINI]
|
||||
@ -3080,6 +3127,7 @@ filament_density = 1.23
|
||||
[filament:Plasty Mladec PETG @0.6 nozzle MINI]
|
||||
inherits = Generic PETG; *PETMINI06*
|
||||
filament_vendor = Plasty Mladec
|
||||
filament_spool_weight = 230
|
||||
|
||||
[filament:Verbatim PETG @0.6 nozzle MINI]
|
||||
inherits = Generic PETG; *PETMINI06*
|
||||
@ -3107,6 +3155,7 @@ filament_type = ASA
|
||||
filament_colour = #FFF2EC
|
||||
filament_cost = 35.28
|
||||
filament_density = 1.07
|
||||
filament_spool_weight = 201
|
||||
|
||||
[filament:Fillamentum Flexfill 98A @MINI]
|
||||
inherits = SemiFlex or Flexfill 98A; *FLEXMINI*
|
||||
@ -3115,6 +3164,7 @@ first_layer_temperature = 240
|
||||
temperature = 240
|
||||
filament_max_volumetric_speed = 1.35
|
||||
filament_cost = 33.99
|
||||
filament_spool_weight = 230
|
||||
|
||||
[filament:Generic FLEX @MINI]
|
||||
inherits = SemiFlex or Flexfill 98A; *FLEXMINI*
|
||||
@ -3190,6 +3240,7 @@ filament_retract_lift = 0
|
||||
filament_retract_before_travel = 7
|
||||
filament_wipe = 0
|
||||
filament_density = 1.20
|
||||
filament_spool_weight = 230
|
||||
filament_cost = 33.95
|
||||
bridge_fan_speed = 70
|
||||
fan_always_on = 1
|
||||
@ -3210,6 +3261,7 @@ temperature = 265
|
||||
filament_type = CPE
|
||||
filament_cost = 34.99
|
||||
filament_density = 1.25
|
||||
filament_spool_weight = 230
|
||||
|
||||
[filament:ColorFabb nGen @MINI]
|
||||
inherits = ColorFabb nGen; *PETMINI*
|
||||
@ -3225,6 +3277,7 @@ filament_cost = 28.80
|
||||
inherits = Fillamentum ABS; *ABSMINI*
|
||||
filament_cost = 32.4
|
||||
filament_density = 1.04
|
||||
filament_spool_weight = 230
|
||||
fan_always_on = 0
|
||||
cooling = 1
|
||||
min_fan_speed = 15
|
||||
@ -3251,6 +3304,7 @@ filament_type = ASA
|
||||
filament_colour = #FFF2EC
|
||||
filament_cost = 38.7
|
||||
filament_density = 1.07
|
||||
filament_spool_weight = 230
|
||||
|
||||
[filament:Polymaker PC-Max @MINI]
|
||||
inherits = Polymaker PC-Max; *ABSMINI*
|
||||
@ -3270,6 +3324,7 @@ inherits = *ABSMINI*
|
||||
filament_vendor = Prusa Polymers
|
||||
filament_cost = 49.99
|
||||
filament_density = 1.22
|
||||
filament_spool_weight = 201
|
||||
fan_always_on = 0
|
||||
first_layer_temperature = 275
|
||||
first_layer_bed_temperature = 100
|
||||
@ -3298,6 +3353,7 @@ inherits = *ABSMINI*
|
||||
filament_vendor = Made for Prusa
|
||||
filament_cost = 22.99
|
||||
filament_density = 1.08
|
||||
filament_spool_weight = 230
|
||||
fan_always_on = 0
|
||||
cooling = 1
|
||||
min_fan_speed = 15
|
||||
@ -3391,6 +3447,7 @@ renamed_from = "Prusa PET MINI"; "Prusa PETG MINI"
|
||||
filament_vendor = Made for Prusa
|
||||
filament_cost = 22.99
|
||||
filament_density = 1.27
|
||||
filament_spool_weight = 230
|
||||
compatible_printers_condition = printer_model=="MINI" and nozzle_diameter[0]!=0.6
|
||||
|
||||
[filament:Prusa PETG @0.6 nozzle MINI]
|
||||
@ -3399,6 +3456,7 @@ renamed_from = "Prusa PET 0.6 nozzle MINI"; "Prusa PETG 0.6 nozzle MINI"
|
||||
filament_vendor = Made for Prusa
|
||||
filament_cost = 22.99
|
||||
filament_density = 1.27
|
||||
filament_spool_weight = 230
|
||||
|
||||
[sla_print:*common*]
|
||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_SL1.*/
|
||||
@ -3426,6 +3484,7 @@ support_pillar_diameter = 1
|
||||
support_pillar_connection_mode = zigzag
|
||||
support_pillar_widening_factor = 0
|
||||
supports_enable = 1
|
||||
support_small_pillar_diameter_percent = 60%
|
||||
|
||||
[sla_print:0.025 UltraDetail]
|
||||
inherits = *common*
|
||||
|
@ -1,3 +1,5 @@
|
||||
min_slic3r_version = 2.3.0-alpha3
|
||||
0.0.3 Added DeltiQ 2, DeltiQ 2 Plus printers, 0.10mm, 0.20mm FLEX print profiles, updated print materials, flexprint extension support
|
||||
min_slic3r_version = 2.3.0-alpha0
|
||||
0.0.2 Added 0.15mm print profile
|
||||
0.0.1 Initial TriLAB bundle
|
||||
|
@ -1,13 +1,12 @@
|
||||
# DeltiQ presets for PrusaSlicer
|
||||
# https://github.com/prusa3d/PrusaSlicer-settings/pull/100
|
||||
# based on https://github.com/trilab3d/Slicer-profiles/tree/deltiq/Slic3r_PE_1_41_3
|
||||
# Print profiles for the TriLAB printers
|
||||
# based on https://github.com/trilab3d/PrusaSlicer-settings/tree/master/live/TriLAB
|
||||
|
||||
[vendor]
|
||||
# Vendor name will be shown by the Config Wizard.
|
||||
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 = 0.0.2
|
||||
config_version = 0.0.3
|
||||
# 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%
|
||||
@ -16,215 +15,364 @@ config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/Prus
|
||||
# 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:DQM]
|
||||
name = TRILAB DeltiQ M
|
||||
[printer_model:DQ2]
|
||||
name = DeltiQ 2
|
||||
variants = 0.4
|
||||
technology = FFF
|
||||
bed_model =
|
||||
bed_texture =
|
||||
family = DeltiQ 2
|
||||
bed_model = dq2_bed.stl
|
||||
bed_texture = dq2_bed_texture.svg
|
||||
default_materials = DeltiQ PLA; DeltiQ ASA; DeltiQ PET; DeltiQ ABS; DeltiQ CPE
|
||||
|
||||
[printer_model:DQ2P]
|
||||
name = DeltiQ 2 Plus
|
||||
variants = 0.4
|
||||
technology = FFF
|
||||
family = DeltiQ 2
|
||||
bed_model = dq2_bed.stl
|
||||
bed_texture = dq2_bed_texture.svg
|
||||
default_materials = DeltiQ PLA; DeltiQ ASA; DeltiQ PET; DeltiQ ABS; DeltiQ CPE
|
||||
|
||||
[printer_model:DQ2+FP2]
|
||||
name = DeltiQ 2 + FlexPrint 2
|
||||
variants = 0.4
|
||||
technology = FFF
|
||||
family = DeltiQ 2
|
||||
bed_model = dq2_bed.stl
|
||||
bed_texture = dq2_bed_texture.svg
|
||||
default_materials = DeltiQ FlexPrint 2 FLEX; DeltiQ FlexPrint 2 FLEX Smartfil; DeltiQ FlexPrint 2 PLA; DeltiQ FlexPrint 2 ASA; DeltiQ FlexPrint 2 PET; DeltiQ FlexPrint 2 ABS; DeltiQ FlexPrint 2 CPE
|
||||
|
||||
[printer_model:DQ2P+FP2]
|
||||
name = DeltiQ 2 Plus + FlexPrint 2
|
||||
variants = 0.4
|
||||
technology = FFF
|
||||
family = DeltiQ 2
|
||||
bed_model = dq2_bed.stl
|
||||
bed_texture = dq2_bed_texture.svg
|
||||
default_materials = DeltiQ FlexPrint 2 FLEX; DeltiQ FlexPrint 2 FLEX Smartfil; DeltiQ FlexPrint 2 PLA; DeltiQ FlexPrint 2 ASA; DeltiQ FlexPrint 2 PET; DeltiQ FlexPrint 2 ABS; DeltiQ FlexPrint 2 CPE
|
||||
|
||||
[printer_model:DQ2+FP]
|
||||
name = DeltiQ 2 + FlexPrint
|
||||
variants = 0.4
|
||||
technology = FFF
|
||||
family = DeltiQ 2
|
||||
bed_model = dq2_bed.stl
|
||||
bed_texture = dq2_bed_texture.svg
|
||||
default_materials = DeltiQ FlexPrint FLEX; DeltiQ FlexPrint PLA; DeltiQ FlexPrint ASA; DeltiQ FlexPrint PET; DeltiQ FlexPrint ABS; DeltiQ FlexPrint CPE
|
||||
|
||||
[printer_model:DQ2P+FP]
|
||||
name = DeltiQ 2 Plus + FlexPrint
|
||||
variants = 0.4
|
||||
technology = FFF
|
||||
family = DeltiQ 2
|
||||
bed_model = dq2_bed.stl
|
||||
bed_texture = dq2_bed_texture.svg
|
||||
default_materials = DeltiQ FlexPrint FLEX; DeltiQ FlexPrint PLA; DeltiQ FlexPrint ASA; DeltiQ FlexPrint PET; DeltiQ FlexPrint ABS; DeltiQ FlexPrint CPE
|
||||
|
||||
[printer_model:DQM]
|
||||
name = DeltiQ M
|
||||
variants = 0.4
|
||||
technology = FFF
|
||||
family = DeltiQ
|
||||
default_materials = DeltiQ PLA; DeltiQ ASA; DeltiQ PET; DeltiQ ABS; DeltiQ CPE
|
||||
|
||||
[printer_model:DQL]
|
||||
name = TRILAB DeltiQ L
|
||||
name = DeltiQ L
|
||||
variants = 0.4
|
||||
technology = FFF
|
||||
bed_model =
|
||||
bed_texture =
|
||||
family = DeltiQ
|
||||
default_materials = DeltiQ PLA; DeltiQ ASA; DeltiQ PET; DeltiQ ABS; DeltiQ CPE
|
||||
|
||||
[printer_model:DQXL]
|
||||
name = TRILAB DeltiQ XL
|
||||
name = DeltiQ XL
|
||||
variants = 0.4
|
||||
technology = FFF
|
||||
bed_model =
|
||||
bed_texture =
|
||||
family = DeltiQ
|
||||
default_materials = DeltiQ PLA; DeltiQ ASA; DeltiQ PET; DeltiQ ABS; DeltiQ CPE
|
||||
|
||||
|
||||
# All presets starting with asterisk, for example *common*, are intermediate and they will
|
||||
# not make it into the user interface.
|
||||
[print:DeltiQ 0.15mm]
|
||||
inherits = DeltiQ 0.2mm
|
||||
layer_height = 0.15
|
||||
bottom_solid_layers = 5
|
||||
top_solid_layers = 6
|
||||
|
||||
[print:DeltiQ 0.2mm]
|
||||
[print:DeltiQ 0.20mm Normal]
|
||||
avoid_crossing_perimeters = 0
|
||||
bottom_fill_pattern = rectilinear
|
||||
bottom_solid_layers = 4
|
||||
bottom_solid_min_thickness = 0.7
|
||||
bridge_acceleration = 1000
|
||||
bridge_angle = 0
|
||||
bridge_flow_ratio = 0.95
|
||||
bridge_speed = 20
|
||||
bridge_speed = 30
|
||||
brim_width = 0
|
||||
clip_multipart_objects = 0
|
||||
compatible_printers_condition = printer_notes=~/.*TRILAB.*/
|
||||
clip_multipart_objects = 1
|
||||
compatible_printers =
|
||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/
|
||||
complete_objects = 0
|
||||
default_acceleration = 2000
|
||||
dont_support_bridges = 1
|
||||
elefant_foot_compensation = 0
|
||||
ensure_vertical_shell_thickness = 1
|
||||
external_fill_pattern = rectilinear
|
||||
external_perimeter_extrusion_width = 0.4
|
||||
dont_support_bridges = 0
|
||||
draft_shield = 0
|
||||
elefant_foot_compensation = 0.2
|
||||
ensure_vertical_shell_thickness = 0
|
||||
external_perimeter_extrusion_width = 0.45
|
||||
external_perimeter_speed = 30
|
||||
external_perimeters_first = 0
|
||||
extra_perimeters = 0
|
||||
extruder_clearance_height = 20
|
||||
extruder_clearance_radius = 20
|
||||
extrusion_width = 0.4
|
||||
extruder_clearance_height = 60
|
||||
extruder_clearance_radius = 45
|
||||
extrusion_width = 0.45
|
||||
fill_angle = 45
|
||||
fill_density = 15%
|
||||
fill_pattern = gyroid
|
||||
fill_density = 20%
|
||||
fill_pattern = grid
|
||||
first_layer_acceleration = 1000
|
||||
first_layer_extrusion_width = 0.4
|
||||
first_layer_height = 0.3
|
||||
first_layer_extrusion_width = 0.42
|
||||
first_layer_height = 0.2
|
||||
first_layer_speed = 20
|
||||
gap_fill_speed = 50
|
||||
gap_fill_speed = 40
|
||||
gcode_comments = 0
|
||||
gcode_label_objects = 0
|
||||
infill_acceleration = 2000
|
||||
infill_every_layers = 1
|
||||
infill_extruder = 1
|
||||
infill_extrusion_width = 0.55
|
||||
infill_extrusion_width = 0.45
|
||||
infill_first = 0
|
||||
infill_only_where_needed = 0
|
||||
infill_overlap = 25%
|
||||
infill_speed = 50
|
||||
inherits =
|
||||
infill_speed = 60
|
||||
interface_shells = 0
|
||||
ironing = 0
|
||||
ironing_flowrate = 15%
|
||||
ironing_spacing = 0.1
|
||||
ironing_speed = 15
|
||||
ironing_type = top
|
||||
layer_height = 0.2
|
||||
max_print_speed = 100
|
||||
max_volumetric_extrusion_rate_slope_negative = 0
|
||||
max_volumetric_extrusion_rate_slope_positive = 0
|
||||
max_volumetric_speed = 10
|
||||
max_print_speed = 60
|
||||
max_volumetric_speed = 0
|
||||
min_skirt_length = 4
|
||||
notes =
|
||||
only_retract_when_crossing_perimeters = 1
|
||||
ooze_prevention = 0
|
||||
output_filename_format = {input_filename_base}_{layer_height}mm_{filament_type[0]}_{printer_model}.gcode
|
||||
overhangs = 0
|
||||
output_filename_format = {input_filename_base}_{printer_model}_{filament_type[0]}_{layer_height}mm_{print_time}.gcode
|
||||
overhangs = 1
|
||||
perimeter_acceleration = 1500
|
||||
perimeter_extruder = 1
|
||||
perimeter_extrusion_width = 0.4
|
||||
perimeter_speed = 40
|
||||
perimeter_extrusion_width = 0.45
|
||||
perimeter_speed = 45
|
||||
perimeters = 2
|
||||
post_process =
|
||||
print_settings_id =
|
||||
raft_layers = 0
|
||||
resolution = 0
|
||||
seam_position = nearest
|
||||
single_extruder_multi_material_priming = 1
|
||||
skirt_distance = 2
|
||||
skirt_height = 1
|
||||
single_extruder_multi_material_priming = 0
|
||||
skirt_distance = 3
|
||||
skirt_height = 2
|
||||
skirts = 1
|
||||
slice_closing_radius = 0.049
|
||||
small_perimeter_speed = 20
|
||||
solid_infill_below_area = 15
|
||||
solid_infill_below_area = 70
|
||||
solid_infill_every_layers = 0
|
||||
solid_infill_extruder = 1
|
||||
solid_infill_extrusion_width = 0.4
|
||||
solid_infill_speed = 50
|
||||
solid_infill_extrusion_width = 0.45
|
||||
solid_infill_speed = 60
|
||||
spiral_vase = 0
|
||||
standby_temperature_delta = -5
|
||||
support_material = 0
|
||||
support_material_angle = 0
|
||||
support_material_angle = 40
|
||||
support_material_auto = 1
|
||||
support_material_buildplate_only = 0
|
||||
support_material_contact_distance = 0.15
|
||||
support_material_contact_distance = 0.1
|
||||
support_material_enforce_layers = 0
|
||||
support_material_extruder = 1
|
||||
support_material_extrusion_width = 0
|
||||
support_material_extruder = 0
|
||||
support_material_extrusion_width = 0.35
|
||||
support_material_interface_contact_loops = 0
|
||||
support_material_interface_extruder = 1
|
||||
support_material_interface_layers = 3
|
||||
support_material_interface_spacing = 0
|
||||
support_material_interface_extruder = 0
|
||||
support_material_interface_layers = 4
|
||||
support_material_interface_spacing = 0.4
|
||||
support_material_interface_speed = 100%
|
||||
support_material_pattern = rectilinear
|
||||
support_material_spacing = 2.5
|
||||
support_material_spacing = 2
|
||||
support_material_speed = 50
|
||||
support_material_synchronize_layers = 0
|
||||
support_material_threshold = 55
|
||||
support_material_with_sheath = 1
|
||||
support_material_xy_spacing = 100%
|
||||
support_material_with_sheath = 0
|
||||
support_material_xy_spacing = 0.6
|
||||
thin_walls = 0
|
||||
threads = 4
|
||||
threads = 12
|
||||
top_fill_pattern = monotonic
|
||||
top_infill_extrusion_width = 0.4
|
||||
top_solid_infill_speed = 30
|
||||
top_solid_infill_speed = 40
|
||||
top_solid_layers = 5
|
||||
top_solid_min_thickness = 0.7
|
||||
travel_speed = 150
|
||||
wipe_tower = 0
|
||||
wipe_tower_bridging = 10
|
||||
wipe_tower_no_sparse_layers = 0
|
||||
wipe_tower_rotation_angle = 0
|
||||
wipe_tower_width = 60
|
||||
wipe_tower_x = 180
|
||||
wipe_tower_y = 140
|
||||
xy_size_compensation = 0
|
||||
|
||||
[print:DeltiQ 0.10mm Normal]
|
||||
inherits = DeltiQ 0.20mm Normal
|
||||
bottom_solid_layers = 7
|
||||
bottom_solid_min_thickness = 0.7
|
||||
bridge_flow_ratio = 0.7
|
||||
bridge_speed = 30
|
||||
ensure_vertical_shell_thickness = 1
|
||||
layer_height = 0.1
|
||||
first_layer_height = 0.2
|
||||
top_solid_layers = 9
|
||||
top_solid_min_thickness = 0.7
|
||||
top_infill_extrusion_width = 0.4
|
||||
fill_pattern = grid
|
||||
fill_density = 20%
|
||||
|
||||
[print:DeltiQ 0.15mm Normal]
|
||||
inherits = DeltiQ 0.20mm Normal
|
||||
bottom_solid_layers = 5
|
||||
bottom_solid_min_thickness = 0.7
|
||||
bridge_flow_ratio = 0.7
|
||||
bridge_speed = 30
|
||||
ensure_vertical_shell_thickness = 1
|
||||
layer_height = 0.15
|
||||
first_layer_height = 0.2
|
||||
top_solid_layers = 7
|
||||
top_solid_min_thickness = 0.7
|
||||
fill_pattern = grid
|
||||
fill_density = 20%
|
||||
|
||||
[print:DeltiQ 0.20mm Vase]
|
||||
inherits = DeltiQ 0.20mm Normal
|
||||
perimeters = 1
|
||||
top_solid_layers = 0
|
||||
fill_density = 0
|
||||
support_material = 0
|
||||
spiral_vase = 1
|
||||
ensure_vertical_shell_thickness = 1
|
||||
thin_walls = 0
|
||||
|
||||
[print:DeltiQ 0.20mm FLEX]
|
||||
inherits = DeltiQ 0.20mm Normal
|
||||
avoid_crossing_perimeters = 0
|
||||
bridge_flow_ratio = 0.90
|
||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*FLEXPRINT.*/
|
||||
only_retract_when_crossing_perimeters = 1
|
||||
overhangs = 0
|
||||
seam_position = nearest
|
||||
thin_walls = 0
|
||||
bridge_speed = 20
|
||||
external_perimeter_speed = 20
|
||||
first_layer_speed = 20
|
||||
gap_fill_speed = 25
|
||||
infill_speed = 30
|
||||
perimeter_speed = 25
|
||||
small_perimeter_speed = 20
|
||||
solid_infill_speed = 30
|
||||
support_material_contact_distance = 0.3
|
||||
top_solid_infill_speed = 20
|
||||
top_fill_pattern = rectilinear
|
||||
fill_pattern = grid
|
||||
fill_density = 25%
|
||||
travel_speed = 200
|
||||
max_print_speed = 30
|
||||
complete_objects = 1
|
||||
|
||||
|
||||
[filament:*DeltiQ common*]
|
||||
bed_temperature = 90
|
||||
bridge_fan_speed = 50
|
||||
compatible_printers_condition = printer_notes=~/.*TRILAB.*/
|
||||
cooling = 1
|
||||
filament_vendor = Generic
|
||||
compatible_printers =
|
||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_FAMILY_DQ.*/ and !(printer_notes=~/.*FLEXPRINT.*/)
|
||||
disable_fan_first_layers = 3
|
||||
end_filament_gcode = ""
|
||||
extrusion_multiplier = 1
|
||||
fan_always_on = 1
|
||||
fan_below_layer_time = 60
|
||||
filament_colour = #FF3232
|
||||
filament_cooling_final_speed = 3.4
|
||||
filament_cooling_initial_speed = 2.2
|
||||
filament_cooling_moves = 4
|
||||
filament_cost = 0
|
||||
filament_density = 1.25
|
||||
filament_colour = #FF0000
|
||||
filament_diameter = 1.75
|
||||
filament_load_time = 0
|
||||
filament_loading_speed = 28
|
||||
filament_loading_speed_start = 3
|
||||
filament_max_volumetric_speed = 10
|
||||
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
|
||||
filament_toolchange_delay = 0
|
||||
start_filament_gcode = "; FILAMENT_START_GCODE"
|
||||
end_filament_gcode = "; FILAMENT_END_GCODE"
|
||||
|
||||
[filament:DeltiQ PET]
|
||||
inherits = *DeltiQ common*
|
||||
bed_temperature = 90
|
||||
bridge_fan_speed = 50
|
||||
cooling = 1
|
||||
fan_always_on = 1
|
||||
fan_below_layer_time = 20
|
||||
filament_vendor = DevilDesign
|
||||
filament_cost = 480
|
||||
filament_density = 1.27
|
||||
filament_deretract_speed = 25
|
||||
filament_max_volumetric_speed = 8
|
||||
filament_retract_before_travel = 2
|
||||
filament_retract_before_wipe = 70%
|
||||
filament_retract_layer_change = 1
|
||||
filament_retract_length = 4.1
|
||||
filament_retract_lift = 0.2
|
||||
filament_retract_speed = 45
|
||||
filament_type = PET
|
||||
filament_unload_time = 0
|
||||
filament_unloading_speed = 90
|
||||
filament_unloading_speed_start = 100
|
||||
filament_wipe = 1
|
||||
first_layer_bed_temperature = 90
|
||||
first_layer_temperature = 240
|
||||
max_fan_speed = 50
|
||||
min_fan_speed = 30
|
||||
min_print_speed = 10
|
||||
slowdown_below_layer_time = 5
|
||||
start_filament_gcode = ""
|
||||
temperature = 245
|
||||
|
||||
[filament:DeltiQ PET]
|
||||
inherits = *DeltiQ common*
|
||||
|
||||
[filament:DeltiQ PLA]
|
||||
inherits = *DeltiQ common*
|
||||
bed_temperature = 55
|
||||
bridge_fan_speed = 100
|
||||
disable_fan_first_layers = 1
|
||||
cooling = 1
|
||||
fan_always_on = 1
|
||||
fan_below_layer_time = 100
|
||||
filament_vendor = Fillamentum
|
||||
filament_cost = 767
|
||||
filament_density = 1.24
|
||||
filament_max_volumetric_speed = 8
|
||||
filament_retract_before_travel = 2
|
||||
filament_retract_before_wipe = 90%
|
||||
filament_retract_layer_change = 1
|
||||
filament_retract_length = 4.0
|
||||
filament_retract_lift = 0.2
|
||||
filament_retract_speed = 30
|
||||
filament_type = PLA
|
||||
filament_wipe = 1
|
||||
first_layer_bed_temperature = 55
|
||||
first_layer_temperature = 215
|
||||
first_layer_temperature = 220
|
||||
max_fan_speed = 100
|
||||
min_fan_speed = 85
|
||||
min_fan_speed = 100
|
||||
min_print_speed = 10
|
||||
slowdown_below_layer_time = 4
|
||||
temperature = 210
|
||||
temperature = 215
|
||||
|
||||
[filament:DeltiQ ABS]
|
||||
inherits = *DeltiQ common*
|
||||
bed_temperature = 100
|
||||
bridge_fan_speed = 20
|
||||
filament_density = 1.04
|
||||
bridge_fan_speed = 25
|
||||
cooling = 1
|
||||
fan_always_on = 1
|
||||
fan_below_layer_time = 20
|
||||
filament_vendor = Fillamentum
|
||||
filament_cost = 774
|
||||
filament_density = 1.08
|
||||
filament_max_volumetric_speed = 4
|
||||
filament_retract_before_travel = 3
|
||||
filament_retract_before_wipe = 70%
|
||||
filament_retract_layer_change = 1
|
||||
filament_retract_length = 4.1
|
||||
filament_retract_lift = 0.2
|
||||
filament_retract_speed = 25
|
||||
filament_type = ABS
|
||||
filament_wipe = 1
|
||||
first_layer_bed_temperature = 100
|
||||
first_layer_temperature = 255
|
||||
max_fan_speed = 20
|
||||
max_fan_speed = 15
|
||||
min_fan_speed = 5
|
||||
min_print_speed = 10
|
||||
slowdown_below_layer_time = 15
|
||||
temperature = 255
|
||||
|
||||
@ -237,11 +385,160 @@ temperature = 265
|
||||
|
||||
[filament:DeltiQ CPE]
|
||||
inherits = *DeltiQ common*
|
||||
bed_temperature = 85
|
||||
bed_temperature = 90
|
||||
bridge_fan_speed = 50
|
||||
cooling = 1
|
||||
fan_always_on = 1
|
||||
fan_below_layer_time = 20
|
||||
filament_vendor = Fillamentum
|
||||
filament_cost = 1214
|
||||
filament_density = 1.25
|
||||
filament_deretract_speed = 25
|
||||
filament_max_volumetric_speed = 8
|
||||
filament_retract_before_travel = 2
|
||||
filament_retract_before_wipe = 70%
|
||||
filament_retract_layer_change = 0
|
||||
filament_retract_length = 4.3
|
||||
filament_retract_lift = 0.2
|
||||
filament_retract_speed = 45
|
||||
filament_type = CPE
|
||||
first_layer_bed_temperature = 85
|
||||
first_layer_temperature = 260
|
||||
temperature = 265
|
||||
filament_wipe = 1
|
||||
first_layer_bed_temperature = 90
|
||||
first_layer_temperature = 265
|
||||
max_fan_speed = 50
|
||||
min_fan_speed = 30
|
||||
min_print_speed = 10
|
||||
slowdown_below_layer_time = 5
|
||||
temperature = 260
|
||||
|
||||
|
||||
[filament:DeltiQ FlexPrint 2 PET]
|
||||
inherits = DeltiQ PET
|
||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_FAMILY_DQ.*/ and printer_notes=~/.*FLEXPRINT2.*/
|
||||
filament_retract_length = 1.4
|
||||
filament_retract_speed = 35
|
||||
filament_retract_before_wipe = 0%
|
||||
|
||||
[filament:DeltiQ FlexPrint 2 PLA]
|
||||
inherits = DeltiQ PLA
|
||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_FAMILY_DQ.*/ and printer_notes=~/.*FLEXPRINT2.*/
|
||||
filament_retract_length = 1.2
|
||||
filament_retract_speed = 28
|
||||
|
||||
[filament:DeltiQ FlexPrint 2 ABS]
|
||||
inherits = DeltiQ ABS
|
||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_FAMILY_DQ.*/ and printer_notes=~/.*FLEXPRINT2.*/
|
||||
filament_retract_length = 0.8
|
||||
filament_retract_speed = 25
|
||||
|
||||
[filament:DeltiQ FlexPrint 2 ASA]
|
||||
inherits = DeltiQ ASA
|
||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_FAMILY_DQ.*/ and printer_notes=~/.*FLEXPRINT2.*/
|
||||
|
||||
[filament:DeltiQ FlexPrint 2 CPE]
|
||||
inherits = DeltiQ CPE
|
||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_FAMILY_DQ.*/ and printer_notes=~/.*FLEXPRINT2.*/
|
||||
filament_retract_length = 0.8
|
||||
filament_retract_speed = 35
|
||||
filament_deretract_speed = 0
|
||||
filament_retract_before_wipe = 0%
|
||||
|
||||
[filament:DeltiQ FlexPrint 2 FLEX]
|
||||
inherits = *DeltiQ common*
|
||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_FAMILY_DQ.*/ and printer_notes=~/.*FLEXPRINT2.*/
|
||||
bed_temperature = 50
|
||||
bridge_fan_speed = 80
|
||||
cooling = 1
|
||||
disable_fan_first_layers = 1
|
||||
extrusion_multiplier = 1.07
|
||||
fan_always_on = 1
|
||||
fan_below_layer_time = 20
|
||||
filament_vendor = Fillamentum
|
||||
filament_cost = 1870
|
||||
filament_density = 1.22
|
||||
filament_deretract_speed = 0
|
||||
filament_max_volumetric_speed = 2.9
|
||||
filament_retract_before_travel = 1
|
||||
filament_retract_before_wipe = 70%
|
||||
filament_retract_layer_change = 0
|
||||
filament_retract_length = 1.6
|
||||
filament_retract_lift = 0.2
|
||||
filament_retract_restart_extra = nil
|
||||
filament_retract_speed = 20
|
||||
filament_type = FLEX
|
||||
filament_wipe = 1
|
||||
first_layer_bed_temperature = 50
|
||||
first_layer_temperature = 225
|
||||
max_fan_speed = 50
|
||||
min_fan_speed = 30
|
||||
min_print_speed = 5
|
||||
slowdown_below_layer_time = 4
|
||||
temperature = 225
|
||||
|
||||
[filament:DeltiQ FlexPrint 2 FLEX Smartfil]
|
||||
inherits = *DeltiQ common*
|
||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_FAMILY_DQ.*/ and printer_notes=~/.*FLEXPRINT2.*/
|
||||
bed_temperature = 50
|
||||
bridge_fan_speed = 80
|
||||
cooling = 0
|
||||
disable_fan_first_layers = 3
|
||||
extrusion_multiplier = 1.07
|
||||
fan_always_on = 1
|
||||
fan_below_layer_time = 20
|
||||
filament_vendor = Smart Materials 3D
|
||||
filament_cost = 1209
|
||||
filament_density = 1.21
|
||||
filament_deretract_speed = 0
|
||||
filament_max_volumetric_speed = 2.5
|
||||
filament_retract_before_travel = 1
|
||||
filament_retract_before_wipe = nil
|
||||
filament_retract_layer_change = 0
|
||||
filament_retract_length = 1.2
|
||||
filament_retract_lift = 0.2
|
||||
filament_retract_restart_extra = nil
|
||||
filament_retract_speed = 20
|
||||
filament_type = FLEX
|
||||
filament_wipe = 0
|
||||
first_layer_bed_temperature = 50
|
||||
first_layer_temperature = 240
|
||||
max_fan_speed = 50
|
||||
min_fan_speed = 50
|
||||
min_print_speed = 10
|
||||
slowdown_below_layer_time = 4
|
||||
temperature = 240
|
||||
|
||||
|
||||
[filament:DeltiQ FlexPrint PET]
|
||||
inherits = DeltiQ PET
|
||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_FAMILY_DQ.*/ and printer_notes=~/.*FLEXPRINT1.*/
|
||||
filament_retract_length = 0.7
|
||||
filament_retract_speed = 25
|
||||
|
||||
[filament:DeltiQ FlexPrint PLA]
|
||||
inherits = DeltiQ PLA
|
||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_FAMILY_DQ.*/ and printer_notes=~/.*FLEXPRINT1.*/
|
||||
filament_retract_length = 0.7
|
||||
filament_retract_speed = 28
|
||||
|
||||
[filament:DeltiQ FlexPrint ABS]
|
||||
inherits = DeltiQ ABS
|
||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_FAMILY_DQ.*/ and printer_notes=~/.*FLEXPRINT1.*/
|
||||
filament_retract_length = 0.7
|
||||
filament_retract_speed = 25
|
||||
|
||||
[filament:DeltiQ FlexPrint ASA]
|
||||
inherits = DeltiQ ASA
|
||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_FAMILY_DQ.*/ and printer_notes=~/.*FLEXPRINT1.*/
|
||||
filament_retract_length = 0.7
|
||||
filament_retract_speed = 25
|
||||
|
||||
[filament:DeltiQ FlexPrint CPE]
|
||||
inherits = DeltiQ CPE
|
||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_FAMILY_DQ.*/ and printer_notes=~/.*FLEXPRINT1.*/
|
||||
filament_retract_length = 0.7
|
||||
filament_retract_speed = 25
|
||||
filament_deretract_speed = 0
|
||||
filament_retract_before_wipe = 0%
|
||||
|
||||
|
||||
[printer:*DeltiQ*]
|
||||
@ -251,63 +548,116 @@ before_layer_gcode = ;BEFORE_LAYER_CHANGE\nG92 E0\n;[layer_z]
|
||||
between_objects_gcode =
|
||||
cooling_tube_length = 5
|
||||
cooling_tube_retraction = 91.5
|
||||
default_filament_profile = ""
|
||||
default_print_profile =
|
||||
deretract_speed = 25
|
||||
default_filament_profile = "DeltiQ PLA"
|
||||
default_print_profile = DeltiQ 0.20mm Normal
|
||||
deretract_speed = 0
|
||||
end_gcode = ;END\nM104 S0 ; Turn extruder heater off\nM140 S0 ; Turn bed heater off\nG28 ; Home all axes\nM84 S5 ; Stop all axes and hold inidle for 5 seconds\nG90 ; Absolute positioning
|
||||
extra_loading_move = -2
|
||||
extruder_colour = ""
|
||||
extruder_colour = #FF0000
|
||||
extruder_offset = 0x0
|
||||
gcode_flavor = repetier
|
||||
host_type = octoprint
|
||||
layer_gcode = ;AFTER_LAYER_CHANGE\nM117 layer [layer_num] at [layer_z]mm\n;[layer_z]\n
|
||||
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 = 500,200
|
||||
machine_max_feedrate_e = 120,120
|
||||
machine_max_feedrate_x = 500,200
|
||||
machine_max_feedrate_y = 500,200
|
||||
machine_max_feedrate_z = 12,12
|
||||
machine_max_jerk_e = 2.5,2.5
|
||||
machine_max_jerk_x = 10,10
|
||||
machine_max_jerk_y = 10,10
|
||||
machine_max_jerk_z = 0.2,0.4
|
||||
machine_min_extruding_rate = 0,0
|
||||
machine_min_travel_rate = 0,0
|
||||
max_layer_height = 0.25
|
||||
max_print_height = 320
|
||||
min_layer_height = 0.15
|
||||
nozzle_diameter = 0.4
|
||||
parking_pos_retraction = 92
|
||||
print_host =
|
||||
printer_model =
|
||||
printer_notes = TRILAB
|
||||
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_DQL
|
||||
printer_settings_id =
|
||||
printer_variant =
|
||||
printer_vendor =
|
||||
printer_vendor = TriLAB Group s.r.o.
|
||||
printhost_apikey =
|
||||
printhost_cafile =
|
||||
remaining_times = 0
|
||||
retract_before_travel = 2
|
||||
retract_before_travel = 3
|
||||
retract_before_wipe = 100%
|
||||
retract_layer_change = 1
|
||||
retract_length = 4.1
|
||||
retract_length = 4.0
|
||||
retract_length_toolchange = 10
|
||||
retract_lift = 0.3
|
||||
retract_lift = 0.2
|
||||
retract_lift_above = 0
|
||||
retract_lift_below = 0
|
||||
retract_lift_below = 319
|
||||
retract_restart_extra = 0
|
||||
retract_restart_extra_toolchange = 0
|
||||
retract_speed = 33
|
||||
silent_mode = 1
|
||||
retract_speed = 30
|
||||
serial_port =
|
||||
serial_speed = 250000
|
||||
silent_mode = 0
|
||||
single_extruder_multi_material = 0
|
||||
start_gcode = ;START\nM220 S100 ; Set feedmultiply back to 100percent\nG90 ; Absolute positioning\nM83 ; Relative extruder\nM107 ; Layer fan OFF\nM190 S[first_layer_bed_temperature] ; Set bed temperature and wait\nM104 S[first_layer_temperature] ; Set extruder temperature\nG28 ; Home all axes\nG33 ; auto leveling rutine\nG1 X-62 Y-108 Z0.3 F6000 ; Go to purge position start\nG92 E0 ; Zero extruder\nM109 S[first_layer_temperature] ; Set and wait - hotend temperature\nG3 X62 Y-108 I62 J108 E10 F200 ; Go ARC to purge end\nG92 E0 ; Zero extruder
|
||||
thumbnails =
|
||||
toolchange_gcode =
|
||||
use_firmware_retraction = 0
|
||||
use_relative_e_distances = 1
|
||||
use_volumetric_e = 0
|
||||
variable_layer_height = 0
|
||||
wipe = 0
|
||||
wipe = 1
|
||||
z_offset = 0
|
||||
|
||||
[printer:*DeltiQ 2*]
|
||||
inherits = *DeltiQ*
|
||||
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 = reprap
|
||||
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
|
||||
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 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
|
||||
default_print_profile = DeltiQ 0.20mm FLEX
|
||||
default_filament_profile = "DeltiQ FlexPrint 2 FLEX"
|
||||
retract_length = 0.7
|
||||
retract_speed = 25
|
||||
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+FP\nFLEXPRINT1
|
||||
|
||||
[printer:*DeltiQ 2 FlexPrint 2*]
|
||||
inherits = *DeltiQ 2 FlexPrint*
|
||||
default_filament_profile = "DeltiQ FlexPrint 2 FLEX"
|
||||
retract_length = 0.8
|
||||
retract_speed = 25
|
||||
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+FP\nFLEXPRINT2
|
||||
|
||||
[printer:DeltiQ 2]
|
||||
inherits = *DeltiQ 2*
|
||||
printer_model = DQ2
|
||||
printer_variant = 0.4
|
||||
max_print_height = 320
|
||||
|
||||
[printer:DeltiQ 2 Plus]
|
||||
inherits = *DeltiQ 2*
|
||||
printer_model = DQ2P
|
||||
printer_variant = 0.4
|
||||
max_print_height = 500
|
||||
|
||||
[printer:DeltiQ 2 + FlexPrint 2]
|
||||
inherits = *DeltiQ 2 FlexPrint 2*
|
||||
printer_model = DQ2+FP2
|
||||
printer_variant = 0.4
|
||||
max_print_height = 320
|
||||
|
||||
[printer:DeltiQ 2 Plus + FlexPrint 2]
|
||||
inherits = *DeltiQ 2 FlexPrint 2*
|
||||
printer_model = DQ2P+FP2
|
||||
printer_variant = 0.4
|
||||
max_print_height = 500
|
||||
|
||||
[printer:DeltiQ 2 + FlexPrint]
|
||||
inherits = *DeltiQ 2 FlexPrint*
|
||||
printer_model = DQ2+FP
|
||||
printer_variant = 0.4
|
||||
max_print_height = 320
|
||||
|
||||
[printer:DeltiQ 2 Plus + FlexPrint]
|
||||
inherits = *DeltiQ 2 FlexPrint*
|
||||
printer_model = DQ2P+FP
|
||||
printer_variant = 0.4
|
||||
max_print_height = 500
|
||||
|
||||
[printer:DeltiQ L]
|
||||
inherits = *DeltiQ*
|
||||
@ -337,6 +687,6 @@ retract_length = 4.5
|
||||
retract_speed = 35
|
||||
|
||||
[presets]
|
||||
print = DeltiQ 0.2mm
|
||||
printer = DeltiQ L
|
||||
filament = DeltiQ PLA
|
||||
print = DeltiQ 0.20mm Normal
|
||||
printer = DeltiQ 2
|
||||
filament = DeltiQ PLA
|
BIN
resources/profiles/TriLAB/DQ2+FP2_thumbnail.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
resources/profiles/TriLAB/DQ2+FP_thumbnail.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
resources/profiles/TriLAB/DQ2P+FP2_thumbnail.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
resources/profiles/TriLAB/DQ2P+FP_thumbnail.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
resources/profiles/TriLAB/DQ2P_thumbnail.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
resources/profiles/TriLAB/DQ2_thumbnail.png
Normal file
After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 34 KiB |
BIN
resources/profiles/TriLAB/dq2_bed.stl
Normal file
@ -1,11 +1,22 @@
|
||||
#version 110
|
||||
|
||||
uniform bool use_fixed_screen_size;
|
||||
uniform float zoom;
|
||||
uniform float point_size;
|
||||
uniform float near_plane_height;
|
||||
|
||||
float fixed_screen_size()
|
||||
{
|
||||
return point_size;
|
||||
}
|
||||
|
||||
float fixed_world_size()
|
||||
{
|
||||
return (gl_Position.w == 1.0) ? zoom * near_plane_height * point_size : near_plane_height * point_size / gl_Position.w;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = ftransform();
|
||||
gl_PointSize = (gl_Position.w == 1.0) ? zoom * near_plane_height * point_size : near_plane_height * point_size / gl_Position.w;
|
||||
gl_PointSize = use_fixed_screen_size ? fixed_screen_size() : fixed_world_size();
|
||||
}
|
||||
|
@ -1,11 +1,22 @@
|
||||
#version 120
|
||||
|
||||
uniform bool use_fixed_screen_size;
|
||||
uniform float zoom;
|
||||
uniform float point_size;
|
||||
uniform float near_plane_height;
|
||||
|
||||
float fixed_screen_size()
|
||||
{
|
||||
return point_size;
|
||||
}
|
||||
|
||||
float fixed_world_size()
|
||||
{
|
||||
return (gl_Position.w == 1.0) ? zoom * near_plane_height * point_size : near_plane_height * point_size / gl_Position.w;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = ftransform();
|
||||
gl_PointSize = (gl_Position.w == 1.0) ? zoom * near_plane_height * point_size : near_plane_height * point_size / gl_Position.w;
|
||||
gl_PointSize = use_fixed_screen_size ? fixed_screen_size() : fixed_world_size();
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
|
||||
page:Filament:spool
|
||||
group:Filament
|
||||
group:filament_spool_weight_event:Filament
|
||||
setting:filament_colour
|
||||
setting:filament_diameter
|
||||
setting:extrusion_multiplier
|
||||
setting:filament_density
|
||||
setting:filament_cost
|
||||
setting:filament_spool_weight
|
||||
group:Temperature °C
|
||||
line:Extruder
|
||||
setting:first_layer_temperature
|
||||
|
@ -105,10 +105,11 @@ page:Infill:infill
|
||||
group:Infill
|
||||
line:Fill density
|
||||
setting:label_width$5:label$_:fill_density
|
||||
setting:width$19:label$_:infill_connection
|
||||
setting:infill_anchor
|
||||
end_line
|
||||
line:Pattern
|
||||
setting:label_width$5:label$_:fill_pattern
|
||||
setting:width$19:label$_:infill_connection
|
||||
end_line
|
||||
line:External patterns
|
||||
setting:label_width$5:top_fill_pattern
|
||||
|
@ -133,7 +133,6 @@ int CLI::run(int argc, char **argv)
|
||||
m_print_config.apply(config);
|
||||
}
|
||||
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
// are we starting as gcodeviewer ?
|
||||
for (auto it = m_actions.begin(); it != m_actions.end(); ++it) {
|
||||
if (*it == "gcodeviewer") {
|
||||
@ -143,10 +142,8 @@ int CLI::run(int argc, char **argv)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
|
||||
// Read input file(s) if any.
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
for (const std::string& file : m_input_files) {
|
||||
std::string ext = boost::filesystem::path(file).extension().string();
|
||||
if (ext == ".gcode" || ext == ".g") {
|
||||
@ -157,7 +154,6 @@ int CLI::run(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
if (!start_as_gcodeviewer) {
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
for (const std::string& file : m_input_files) {
|
||||
if (!boost::filesystem::exists(file)) {
|
||||
boost::nowide::cerr << "No such file: " << file << std::endl;
|
||||
@ -190,9 +186,7 @@ int CLI::run(int argc, char **argv)
|
||||
}
|
||||
m_models.push_back(model);
|
||||
}
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
}
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
|
||||
// Apply command line options to a more specific DynamicPrintConfig which provides normalize()
|
||||
// (command line options override --load files)
|
||||
@ -501,11 +495,7 @@ int CLI::run(int argc, char **argv)
|
||||
print->process();
|
||||
if (printer_technology == ptFFF) {
|
||||
// The outfile is processed by a PlaceholderParser.
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
outfile = fff_print.export_gcode(outfile, nullptr, nullptr);
|
||||
#else
|
||||
outfile = fff_print.export_gcode(outfile, nullptr);
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
outfile_final = fff_print.print_statistics().finalize_output_path(outfile);
|
||||
} else if (printer_technology == ptSLA) {
|
||||
outfile = sla_print.output_filepath(outfile);
|
||||
@ -556,11 +546,6 @@ int CLI::run(int argc, char **argv)
|
||||
<< " (" << print.total_extruded_volume()/1000 << "cm3)" << std::endl;
|
||||
*/
|
||||
}
|
||||
#if !ENABLE_GCODE_VIEWER
|
||||
} else if (opt_key == "gcodeviewer") {
|
||||
start_gui = true;
|
||||
start_as_gcodeviewer = true;
|
||||
#endif // !ENABLE_GCODE_VIEWER
|
||||
} else {
|
||||
boost::nowide::cerr << "error: option not supported yet: " << opt_key << std::endl;
|
||||
return 1;
|
||||
|
@ -8,4 +8,5 @@ Customized with the following commits:
|
||||
042880ba2df913916b2cc77f7bb677e07bfd2c58
|
||||
67c55c74901f1d337ef08f2090a87cfb4263bb0f
|
||||
a94c952b40d36b1505fb77b87c0dd739e1034659
|
||||
3ca3a544a87cc569b69351a77996c287763388a5
|
||||
3ca3a544a87cc569b69351a77996c287763388a5
|
||||
6586a46ea23e86d54d228c55c63ca55680d25d56
|
||||
|
@ -113,16 +113,16 @@ namespace ImGui
|
||||
const char PrinterSlaIconMarker = 0x6;
|
||||
const char FilamentIconMarker = 0x7;
|
||||
const char MaterialIconMarker = 0x8;
|
||||
const char CloseIconMarker = 0xB;
|
||||
const char CloseIconHoverMarker = 0xC;
|
||||
const char CloseNotifButton = 0xB;
|
||||
const char CloseNotifHoverButton = 0xC;
|
||||
// const char TimerDotMarker = 0xE;
|
||||
// const char TimerDotEmptyMarker = 0xF;
|
||||
const char MinimalizeMarker = 0xE;
|
||||
const char MinimalizeHoverMarker = 0xF;
|
||||
const char MinimalizeButton = 0xE;
|
||||
const char MinimalizeHoverButton = 0xF;
|
||||
const char WarningMarker = 0x10;
|
||||
const char ErrorMarker = 0x11;
|
||||
const char EjectMarker = 0x12;
|
||||
const char EjectHoverMarker = 0x13;
|
||||
const char EjectButton = 0x12;
|
||||
const char EjectHoverButton = 0x13;
|
||||
// void MyFunction(const char* name, const MyMatrix44& v);
|
||||
|
||||
}
|
||||
|
@ -38,9 +38,7 @@ void AppConfig::reset()
|
||||
// Override missing or keys with their defaults.
|
||||
void AppConfig::set_defaults()
|
||||
{
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
if (m_mode == EAppMode::Editor) {
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
// Reset the empty fields to defaults.
|
||||
if (get("autocenter").empty())
|
||||
set("autocenter", "0");
|
||||
@ -57,9 +55,15 @@ void AppConfig::set_defaults()
|
||||
if (get("show_incompatible_presets").empty())
|
||||
set("show_incompatible_presets", "0");
|
||||
|
||||
if (get("show_drop_project_dialog").empty())
|
||||
set("show_drop_project_dialog", "1");
|
||||
if (get("drop_project_action").empty())
|
||||
set("drop_project_action", "1");
|
||||
|
||||
if (get("freecad_path").empty())
|
||||
set("freecad_path", ".");
|
||||
|
||||
|
||||
if (get("version_check").empty())
|
||||
set("version_check", "1");
|
||||
if (get("preset_update").empty())
|
||||
@ -101,17 +105,6 @@ void AppConfig::set_defaults()
|
||||
if (get("auto_toolbar_size").empty())
|
||||
set("auto_toolbar_size", "100");
|
||||
|
||||
#if !ENABLE_GCODE_VIEWER
|
||||
if (get("use_perspective_camera").empty())
|
||||
set("use_perspective_camera", "1");
|
||||
|
||||
if (get("use_free_camera").empty())
|
||||
set("use_free_camera", "0");
|
||||
|
||||
if (get("reverse_mouse_wheel_zoom").empty())
|
||||
set("reverse_mouse_wheel_zoom", "0");
|
||||
#endif // !ENABLE_GCODE_VIEWER
|
||||
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
if (get("use_environment_map").empty())
|
||||
set("use_environment_map", "0");
|
||||
@ -119,7 +112,6 @@ void AppConfig::set_defaults()
|
||||
|
||||
if (get("use_inches").empty())
|
||||
set("use_inches", "0");
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
}
|
||||
|
||||
if (get("seq_top_layer_only").empty())
|
||||
@ -136,7 +128,6 @@ void AppConfig::set_defaults()
|
||||
|
||||
if (get("reverse_mouse_wheel_zoom").empty())
|
||||
set("reverse_mouse_wheel_zoom", "0");
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
|
||||
if (get("show_splash_screen").empty())
|
||||
set("show_splash_screen", "1");
|
||||
@ -253,14 +244,10 @@ void AppConfig::save()
|
||||
|
||||
boost::nowide::ofstream c;
|
||||
c.open(path_pid, std::ios::out | std::ios::trunc);
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
if (m_mode == EAppMode::Editor)
|
||||
c << "# " << Slic3r::header_slic3r_generated() << std::endl;
|
||||
else
|
||||
c << "# " << Slic3r::header_gcodeviewer_generated() << std::endl;
|
||||
#else
|
||||
c << "# " << Slic3r::header_slic3r_generated() << std::endl;
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
// Make sure the "no" category is written first.
|
||||
for (const std::pair<std::string, std::string> &kvp : m_storage[""])
|
||||
c << kvp.first << " = " << kvp.second << std::endl;
|
||||
@ -460,15 +447,11 @@ void AppConfig::reset_selections()
|
||||
|
||||
std::string AppConfig::config_path()
|
||||
{
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
std::string path = (m_mode == EAppMode::Editor) ?
|
||||
(boost::filesystem::path(Slic3r::data_dir()) / (SLIC3R_APP_KEY ".ini")).make_preferred().string() :
|
||||
(boost::filesystem::path(Slic3r::data_dir()) / (GCODEVIEWER_APP_KEY ".ini")).make_preferred().string();
|
||||
|
||||
return path;
|
||||
#else
|
||||
return (boost::filesystem::path(Slic3r::data_dir()) / (SLIC3R_APP_KEY ".ini")).make_preferred().string();
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
}
|
||||
|
||||
std::string AppConfig::version_check_url() const
|
||||
@ -479,11 +462,7 @@ std::string AppConfig::version_check_url() const
|
||||
|
||||
bool AppConfig::exists()
|
||||
{
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
return boost::filesystem::exists(config_path());
|
||||
#else
|
||||
return boost::filesystem::exists(AppConfig::config_path());
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
}
|
||||
|
||||
}; // namespace Slic3r
|
||||
|
@ -15,7 +15,6 @@ namespace Slic3r {
|
||||
class AppConfig
|
||||
{
|
||||
public:
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
enum class EAppMode : unsigned char
|
||||
{
|
||||
Editor,
|
||||
@ -23,14 +22,9 @@ public:
|
||||
};
|
||||
|
||||
explicit AppConfig(EAppMode mode) :
|
||||
#else
|
||||
AppConfig() :
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
m_dirty(false),
|
||||
m_orig_version(Semver::invalid()),
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
m_mode(mode),
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
m_legacy_datadir(false)
|
||||
{
|
||||
this->reset();
|
||||
@ -135,11 +129,7 @@ public:
|
||||
void reset_selections();
|
||||
|
||||
// Get the default config path from Slic3r::data_dir().
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
std::string config_path();
|
||||
#else
|
||||
static std::string config_path();
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
|
||||
// Returns true if the user's data directory comes from before Slic3r 1.40.0 (no updating)
|
||||
bool legacy_datadir() const { return m_legacy_datadir; }
|
||||
@ -154,11 +144,7 @@ public:
|
||||
Semver orig_version() const { return m_orig_version; }
|
||||
|
||||
// Does the config file exist?
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
bool exists();
|
||||
#else
|
||||
static bool exists();
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
|
||||
std::vector<std::string> get_recent_projects() const;
|
||||
void set_recent_projects(const std::vector<std::string>& recent_projects);
|
||||
@ -196,10 +182,8 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
// Type of application: Editor or GCodeViewer
|
||||
EAppMode m_mode { EAppMode::Editor };
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
|
||||
// Map of section, name -> value
|
||||
std::map<std::string, std::map<std::string, std::string>> m_storage;
|
||||
// Map of enabled vendors / models / variants
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <libnest2d/optimizers/nlopt/subplex.hpp>
|
||||
#include <libnest2d/placers/nfpplacer.hpp>
|
||||
#include <libnest2d/selections/firstfit.hpp>
|
||||
#include <libnest2d/utils/rotcalipers.hpp>
|
||||
|
||||
#include <numeric>
|
||||
#include <ClipperUtils.hpp>
|
||||
@ -83,7 +84,7 @@ const double BIG_ITEM_TRESHOLD = 0.02;
|
||||
// Fill in the placer algorithm configuration with values carefully chosen for
|
||||
// Slic3r.
|
||||
template<class PConf>
|
||||
void fill_config(PConf& pcfg) {
|
||||
void fill_config(PConf& pcfg, const ArrangeParams ¶ms) {
|
||||
|
||||
// Align the arranged pile into the center of the bin
|
||||
pcfg.alignment = PConf::Alignment::CENTER;
|
||||
@ -93,14 +94,17 @@ void fill_config(PConf& pcfg) {
|
||||
|
||||
// TODO cannot use rotations until multiple objects of same geometry can
|
||||
// handle different rotations.
|
||||
pcfg.rotations = { 0.0 };
|
||||
if (params.allow_rotations)
|
||||
pcfg.rotations = {0., PI / 2., PI, 3. * PI / 2. };
|
||||
else
|
||||
pcfg.rotations = {0.};
|
||||
|
||||
// The accuracy of optimization.
|
||||
// Goes from 0.0 to 1.0 and scales performance as well
|
||||
pcfg.accuracy = 0.65f;
|
||||
pcfg.accuracy = params.accuracy;
|
||||
|
||||
// Allow parallel execution.
|
||||
pcfg.parallel = true;
|
||||
pcfg.parallel = params.parallel;
|
||||
}
|
||||
|
||||
// Apply penalty to object function result. This is used only when alignment
|
||||
@ -277,10 +281,10 @@ protected:
|
||||
if (result.empty())
|
||||
score = 0.50 * dist + 0.50 * density;
|
||||
else
|
||||
score = R * 0.60 * dist +
|
||||
(1.0 - R) * 0.20 * density +
|
||||
0.20 * alignment_score;
|
||||
|
||||
// Let the density matter more when fewer objects remain
|
||||
score = 0.50 * dist + (1.0 - R) * 0.20 * density +
|
||||
0.30 * alignment_score;
|
||||
|
||||
break;
|
||||
}
|
||||
case LAST_BIG_ITEM: {
|
||||
@ -304,15 +308,15 @@ protected:
|
||||
|
||||
public:
|
||||
AutoArranger(const TBin & bin,
|
||||
Distance dist,
|
||||
const ArrangeParams ¶ms,
|
||||
std::function<void(unsigned)> progressind,
|
||||
std::function<bool(void)> stopcond)
|
||||
: m_pck(bin, dist)
|
||||
: m_pck(bin, params.min_obj_distance)
|
||||
, m_bin(bin)
|
||||
, m_bin_area(sl::area(bin))
|
||||
, m_norm(std::sqrt(m_bin_area))
|
||||
{
|
||||
fill_config(m_pconf);
|
||||
fill_config(m_pconf, params);
|
||||
|
||||
// Set up a callback that is called just before arranging starts
|
||||
// This functionality is provided by the Nester class (m_pack).
|
||||
@ -349,12 +353,6 @@ public:
|
||||
|
||||
m_pck.configure(m_pconf);
|
||||
}
|
||||
|
||||
AutoArranger(const TBin & bin,
|
||||
std::function<void(unsigned)> progressind,
|
||||
std::function<bool(void)> stopcond)
|
||||
: AutoArranger{bin, 0 /* no min distance */, progressind, stopcond}
|
||||
{}
|
||||
|
||||
template<class It> inline void operator()(It from, It to) {
|
||||
m_rtree.clear();
|
||||
@ -452,12 +450,18 @@ template<class Bin> void remove_large_items(std::vector<Item> &items, Bin &&bin)
|
||||
++it : it = items.erase(it);
|
||||
}
|
||||
|
||||
template<class S> Radians min_area_boundingbox_rotation(const S &sh)
|
||||
{
|
||||
return minAreaBoundingBox<S, TCompute<S>, boost::rational<LargeInt>>(sh)
|
||||
.angleToX();
|
||||
}
|
||||
|
||||
template<class BinT> // Arrange for arbitrary bin type
|
||||
void _arrange(
|
||||
std::vector<Item> & shapes,
|
||||
std::vector<Item> & excludes,
|
||||
const BinT & bin,
|
||||
const ArrangeParams & params,
|
||||
const ArrangeParams ¶ms,
|
||||
std::function<void(unsigned)> progressfn,
|
||||
std::function<bool()> stopfn)
|
||||
{
|
||||
@ -467,11 +471,10 @@ void _arrange(
|
||||
|
||||
auto corrected_bin = bin;
|
||||
sl::offset(corrected_bin, md);
|
||||
|
||||
AutoArranger<BinT> arranger{corrected_bin, progressfn, stopfn};
|
||||
|
||||
arranger.config().accuracy = params.accuracy;
|
||||
arranger.config().parallel = params.parallel;
|
||||
ArrangeParams mod_params = params;
|
||||
mod_params.min_obj_distance = 0;
|
||||
|
||||
AutoArranger<BinT> arranger{corrected_bin, mod_params, progressfn, stopfn};
|
||||
|
||||
auto infl = coord_t(std::ceil(params.min_obj_distance / 2.0));
|
||||
for (Item& itm : shapes) itm.inflate(infl);
|
||||
@ -487,6 +490,13 @@ void _arrange(
|
||||
for (auto &itm : shapes ) inp.emplace_back(itm);
|
||||
for (auto &itm : excludes) inp.emplace_back(itm);
|
||||
|
||||
// Use the minimum bounding box rotation as a starting point.
|
||||
// TODO: This only works for convex hull. If we ever switch to concave
|
||||
// polygon nesting, a convex hull needs to be calculated.
|
||||
if (params.allow_rotations)
|
||||
for (auto &itm : shapes)
|
||||
itm.rotation(min_area_boundingbox_rotation(itm.rawShape()));
|
||||
|
||||
arranger(inp.begin(), inp.end());
|
||||
for (Item &itm : inp) itm.inflate(-infl);
|
||||
}
|
||||
@ -556,28 +566,35 @@ static void process_arrangeable(const ArrangePolygon &arrpoly,
|
||||
outp.back().priority(arrpoly.priority);
|
||||
}
|
||||
|
||||
template<class Fn> auto call_with_bed(const Points &bed, Fn &&fn)
|
||||
{
|
||||
if (bed.empty())
|
||||
return fn(InfiniteBed{});
|
||||
else if (bed.size() == 1)
|
||||
return fn(InfiniteBed{bed.front()});
|
||||
else {
|
||||
auto bb = BoundingBox(bed);
|
||||
CircleBed circ = to_circle(bb.center(), bed);
|
||||
auto parea = poly_area(bed);
|
||||
|
||||
if ((1.0 - parea / area(bb)) < 1e-3)
|
||||
return fn(bb);
|
||||
else if (!std::isnan(circ.radius()))
|
||||
return fn(circ);
|
||||
else
|
||||
return fn(Polygon(bed));
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void arrange(ArrangePolygons & items,
|
||||
const ArrangePolygons &excludes,
|
||||
const Points & bed,
|
||||
const ArrangeParams & params)
|
||||
{
|
||||
if (bed.empty())
|
||||
arrange(items, excludes, InfiniteBed{}, params);
|
||||
else if (bed.size() == 1)
|
||||
arrange(items, excludes, InfiniteBed{bed.front()}, params);
|
||||
else {
|
||||
auto bb = BoundingBox(bed);
|
||||
CircleBed circ = to_circle(bb.center(), bed);
|
||||
auto parea = poly_area(bed);
|
||||
|
||||
if ((1.0 - parea / area(bb)) < 1e-3)
|
||||
arrange(items, excludes, bb, params);
|
||||
else if (!std::isnan(circ.radius()))
|
||||
arrange(items, excludes, circ, params);
|
||||
else
|
||||
arrange(items, excludes, Polygon(bed), params);
|
||||
}
|
||||
call_with_bed(bed, [&](const auto &bin) {
|
||||
arrange(items, excludes, bin, params);
|
||||
});
|
||||
}
|
||||
|
||||
template<class BedT>
|
||||
|
@ -78,6 +78,8 @@ struct ArrangeParams {
|
||||
|
||||
/// Allow parallel execution.
|
||||
bool parallel = true;
|
||||
|
||||
bool allow_rotations = false;
|
||||
|
||||
/// Progress indicator callback called when an object gets packed.
|
||||
/// The unsigned argument is the number of items remaining to pack.
|
||||
|
@ -47,6 +47,7 @@ public:
|
||||
void translate(coordf_t x, coordf_t y) { assert(this->defined); PointClass v(x, y); this->min += v; this->max += v; }
|
||||
void translate(const Vec2d &v) { this->min += v; this->max += v; }
|
||||
void offset(coordf_t delta);
|
||||
BoundingBoxBase<PointClass> inflated(coordf_t delta) const throw() { BoundingBoxBase<PointClass> out(*this); out.offset(delta); return out; }
|
||||
PointClass center() const;
|
||||
bool contains(const PointClass &point) const {
|
||||
return point(0) >= this->min(0) && point(0) <= this->max(0)
|
||||
@ -91,6 +92,7 @@ public:
|
||||
void translate(coordf_t x, coordf_t y, coordf_t z) { assert(this->defined); PointClass v(x, y, z); this->min += v; this->max += v; }
|
||||
void translate(const Vec3d &v) { this->min += v; this->max += v; }
|
||||
void offset(coordf_t delta);
|
||||
BoundingBoxBase<PointClass> inflated(coordf_t delta) const throw() { BoundingBoxBase<PointClass> out(*this); out.offset(delta); return out; }
|
||||
PointClass center() const;
|
||||
coordf_t max_size() const;
|
||||
|
||||
@ -159,6 +161,8 @@ public:
|
||||
BoundingBox(const Point &pmin, const Point &pmax) : BoundingBoxBase<Point>(pmin, pmax) {}
|
||||
BoundingBox(const Points &points) : BoundingBoxBase<Point>(points) {}
|
||||
|
||||
BoundingBox inflated(coordf_t delta) const throw() { BoundingBox out(*this); out.offset(delta); return out; }
|
||||
|
||||
friend BoundingBox get_extents_rotated(const Points &points, double angle);
|
||||
};
|
||||
|
||||
|
@ -58,10 +58,10 @@ add_library(libslic3r STATIC
|
||||
Fill/FillGyroid.hpp
|
||||
Fill/FillPlanePath.cpp
|
||||
Fill/FillPlanePath.hpp
|
||||
Fill/FillLine.cpp
|
||||
Fill/FillLine.hpp
|
||||
Fill/FillRectilinear.cpp
|
||||
Fill/FillRectilinear.hpp
|
||||
Fill/FillRectilinear2.cpp
|
||||
Fill/FillRectilinear2.hpp
|
||||
Fill/FillSmooth.cpp
|
||||
Fill/FillSmooth.hpp
|
||||
Flow.cpp
|
||||
@ -91,8 +91,6 @@ add_library(libslic3r STATIC
|
||||
GCode/PostProcessor.hpp
|
||||
# GCode/PressureEqualizer.cpp
|
||||
# GCode/PressureEqualizer.hpp
|
||||
GCode/PreviewData.cpp
|
||||
GCode/PreviewData.hpp
|
||||
GCode/PrintExtents.cpp
|
||||
GCode/PrintExtents.hpp
|
||||
GCode/SpiralVase.cpp
|
||||
|
@ -224,6 +224,23 @@ bool unescape_strings_cstyle(const std::string &str, std::vector<std::string> &o
|
||||
}
|
||||
}
|
||||
|
||||
std::string escape_ampersand(const std::string& str)
|
||||
{
|
||||
// Allocate a buffer 2 times the input string length,
|
||||
// so the output will fit even if all input characters get escaped.
|
||||
std::vector<char> out(str.size() * 6, 0);
|
||||
char* outptr = out.data();
|
||||
for (size_t i = 0; i < str.size(); ++i) {
|
||||
char c = str[i];
|
||||
if (c == '&') {
|
||||
(*outptr++) = '&';
|
||||
(*outptr++) = '&';
|
||||
} else
|
||||
(*outptr++) = c;
|
||||
}
|
||||
return std::string(out.data(), outptr - out.data());
|
||||
}
|
||||
|
||||
std::vector<std::string> ConfigOptionDef::cli_args(const std::string &key) const
|
||||
{
|
||||
std::vector<std::string> args;
|
||||
|
@ -34,6 +34,7 @@ extern std::string escape_strings_cstyle(const std::vector<std::string> &strs);
|
||||
extern bool unescape_string_cstyle(const std::string &str, std::string &out);
|
||||
extern bool unescape_strings_cstyle(const std::string &str, std::vector<std::string> &out);
|
||||
|
||||
extern std::string escape_ampersand(const std::string& str);
|
||||
|
||||
enum OptionCategory : int
|
||||
{
|
||||
|
@ -1,10 +1,6 @@
|
||||
#include "CustomGCode.hpp"
|
||||
#include "Config.hpp"
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
#include "GCode.hpp"
|
||||
#else
|
||||
#include "GCode/PreviewData.hpp"
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
#include "GCodeWriter.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
@ -21,11 +17,7 @@ extern void update_custom_gcode_per_print_z_from_config(Info& info, DynamicPrint
|
||||
return;
|
||||
if (info.gcodes.empty() && ! colorprint_heights->values.empty()) {
|
||||
// Convert the old colorprint_heighs only if there is no equivalent data in a new format.
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
const std::vector<std::string>& colors = ColorPrintColors::get();
|
||||
#else
|
||||
const std::vector<std::string>& colors = GCodePreviewData::ColorPrintColors();
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
const auto& colorprint_values = colorprint_heights->values;
|
||||
info.gcodes.clear();
|
||||
info.gcodes.reserve(colorprint_values.size());
|
||||
|
@ -55,6 +55,24 @@ void EdgeGrid::Grid::create(const Polygons &polygons, coord_t resolution)
|
||||
create_from_m_contours(resolution);
|
||||
}
|
||||
|
||||
void EdgeGrid::Grid::create(const std::vector<const Polygon*> &polygons, coord_t resolution)
|
||||
{
|
||||
// Count the contours.
|
||||
size_t ncontours = 0;
|
||||
for (size_t j = 0; j < polygons.size(); ++ j)
|
||||
if (! polygons[j]->points.empty())
|
||||
++ ncontours;
|
||||
|
||||
// Collect the contours.
|
||||
m_contours.assign(ncontours, nullptr);
|
||||
ncontours = 0;
|
||||
for (size_t j = 0; j < polygons.size(); ++ j)
|
||||
if (! polygons[j]->points.empty())
|
||||
m_contours[ncontours ++] = &polygons[j]->points;
|
||||
|
||||
create_from_m_contours(resolution);
|
||||
}
|
||||
|
||||
void EdgeGrid::Grid::create(const std::vector<Points> &polygons, coord_t resolution)
|
||||
{
|
||||
// Count the contours.
|
||||
@ -1150,7 +1168,7 @@ EdgeGrid::Grid::ClosestPointResult EdgeGrid::Grid::closest_point(const Point &pt
|
||||
if (result.contour_idx != size_t(-1) && d_min <= double(search_radius)) {
|
||||
result.distance = d_min * sign_min;
|
||||
result.t /= l2_seg_min;
|
||||
assert(result.t >= 0. && result.t < 1.);
|
||||
assert(result.t >= 0. && result.t <= 1.);
|
||||
#ifndef NDEBUG
|
||||
{
|
||||
const Slic3r::Points &pts = *m_contours[result.contour_idx];
|
||||
|
@ -21,6 +21,7 @@ public:
|
||||
void set_bbox(const BoundingBox &bbox) { m_bbox = bbox; }
|
||||
|
||||
void create(const Polygons &polygons, coord_t resolution);
|
||||
void create(const std::vector<const Polygon*> &polygons, coord_t resolution);
|
||||
void create(const std::vector<Points> &polygons, coord_t resolution);
|
||||
void create(const ExPolygon &expoly, coord_t resolution);
|
||||
void create(const ExPolygons &expolygons, coord_t resolution);
|
||||
@ -83,10 +84,14 @@ public:
|
||||
template<typename VISITOR> void visit_cells_intersecting_line(Slic3r::Point p1, Slic3r::Point p2, VISITOR &visitor) const
|
||||
{
|
||||
// End points of the line segment.
|
||||
p1(0) -= m_bbox.min(0);
|
||||
p1(1) -= m_bbox.min(1);
|
||||
p2(0) -= m_bbox.min(0);
|
||||
p2(1) -= m_bbox.min(1);
|
||||
assert(m_bbox.contains(p1));
|
||||
assert(m_bbox.contains(p2));
|
||||
p1 -= m_bbox.min;
|
||||
p2 -= m_bbox.min;
|
||||
assert(p1.x() >= 0 && p1.x() < m_cols * m_resolution);
|
||||
assert(p1.y() >= 0 && p1.y() < m_rows * m_resolution);
|
||||
assert(p2.x() >= 0 && p2.x() < m_cols * m_resolution);
|
||||
assert(p2.y() >= 0 && p2.y() < m_rows * m_resolution);
|
||||
// Get the cells of the end points.
|
||||
coord_t ix = p1(0) / m_resolution;
|
||||
coord_t iy = p1(1) / m_resolution;
|
||||
@ -114,18 +119,22 @@ public:
|
||||
ey -= ex;
|
||||
ex = int64_t(dy) * m_resolution;
|
||||
ix += 1;
|
||||
assert(ix <= ixb);
|
||||
}
|
||||
else if (ex == ey) {
|
||||
ex = int64_t(dy) * m_resolution;
|
||||
ey = int64_t(dx) * m_resolution;
|
||||
ix += 1;
|
||||
iy += 1;
|
||||
assert(ix <= ixb);
|
||||
assert(iy <= iyb);
|
||||
}
|
||||
else {
|
||||
assert(ex > ey);
|
||||
ex -= ey;
|
||||
ey = int64_t(dx) * m_resolution;
|
||||
iy += 1;
|
||||
assert(iy <= iyb);
|
||||
}
|
||||
if (! visitor(iy, ix))
|
||||
return;
|
||||
@ -140,11 +149,13 @@ public:
|
||||
ey -= ex;
|
||||
ex = int64_t(dy) * m_resolution;
|
||||
ix += 1;
|
||||
assert(ix <= ixb);
|
||||
}
|
||||
else {
|
||||
ex -= ey;
|
||||
ey = int64_t(dx) * m_resolution;
|
||||
iy -= 1;
|
||||
assert(iy >= iyb);
|
||||
}
|
||||
if (! visitor(iy, ix))
|
||||
return;
|
||||
@ -162,12 +173,14 @@ public:
|
||||
ey -= ex;
|
||||
ex = int64_t(dy) * m_resolution;
|
||||
ix -= 1;
|
||||
assert(ix >= ixb);
|
||||
}
|
||||
else {
|
||||
assert(ex >= ey);
|
||||
ex -= ey;
|
||||
ey = int64_t(dx) * m_resolution;
|
||||
iy += 1;
|
||||
assert(iy <= iyb);
|
||||
}
|
||||
if (! visitor(iy, ix))
|
||||
return;
|
||||
@ -182,6 +195,7 @@ public:
|
||||
ey -= ex;
|
||||
ex = int64_t(dy) * m_resolution;
|
||||
ix -= 1;
|
||||
assert(ix >= ixb);
|
||||
}
|
||||
else if (ex == ey) {
|
||||
// The lower edge of a grid cell belongs to the cell.
|
||||
@ -190,10 +204,12 @@ public:
|
||||
if (dx > 0) {
|
||||
ex = int64_t(dy) * m_resolution;
|
||||
ix -= 1;
|
||||
assert(ix >= ixb);
|
||||
}
|
||||
if (dy > 0) {
|
||||
ey = int64_t(dx) * m_resolution;
|
||||
iy -= 1;
|
||||
assert(iy >= iyb);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -201,6 +217,7 @@ public:
|
||||
ex -= ey;
|
||||
ey = int64_t(dx) * m_resolution;
|
||||
iy -= 1;
|
||||
assert(iy >= iyb);
|
||||
}
|
||||
if (! visitor(iy, ix))
|
||||
return;
|
||||
@ -230,6 +247,10 @@ public:
|
||||
|
||||
std::pair<std::vector<std::pair<size_t, size_t>>::const_iterator, std::vector<std::pair<size_t, size_t>>::const_iterator> cell_data_range(coord_t row, coord_t col) const
|
||||
{
|
||||
assert(row >= 0);
|
||||
assert(row < m_rows);
|
||||
assert(col >= 0);
|
||||
assert(col < m_cols);
|
||||
const EdgeGrid::Grid::Cell &cell = m_cells[row * m_cols + col];
|
||||
return std::make_pair(m_cell_data.begin() + cell.begin, m_cell_data.begin() + cell.end);
|
||||
}
|
||||
|
@ -17,9 +17,9 @@ typedef std::vector<ExPolygon> ExPolygons;
|
||||
class ExPolygon
|
||||
{
|
||||
public:
|
||||
ExPolygon() {}
|
||||
ExPolygon(const ExPolygon &other) : contour(other.contour), holes(other.holes) {}
|
||||
ExPolygon(ExPolygon &&other) noexcept : contour(std::move(other.contour)), holes(std::move(other.holes)) {}
|
||||
ExPolygon() = default;
|
||||
ExPolygon(const ExPolygon &other) = default;
|
||||
ExPolygon(ExPolygon &&other) = default;
|
||||
explicit ExPolygon(const Polygon &contour) : contour(contour) {}
|
||||
explicit ExPolygon(Polygon &&contour) : contour(std::move(contour)) {}
|
||||
explicit ExPolygon(const Points &contour) : contour(contour) {}
|
||||
@ -31,10 +31,10 @@ public:
|
||||
ExPolygon(std::initializer_list<Point> contour) : contour(contour) {}
|
||||
ExPolygon(std::initializer_list<Point> contour, std::initializer_list<Point> hole) : contour(contour), holes({ hole }) {}
|
||||
|
||||
ExPolygon& operator=(const ExPolygon &other) { contour = other.contour; holes = other.holes; return *this; }
|
||||
ExPolygon& operator=(ExPolygon &&other) noexcept { contour = std::move(other.contour); holes = std::move(other.holes); return *this; }
|
||||
ExPolygon& operator=(const ExPolygon &other) = default;
|
||||
ExPolygon& operator=(ExPolygon &&other) = default;
|
||||
|
||||
Polygon contour;
|
||||
Polygon contour;
|
||||
Polygons holes;
|
||||
|
||||
operator Points() const;
|
||||
|
@ -266,11 +266,7 @@ double ExtrusionLoop::min_mm3_per_mm() const
|
||||
std::string ExtrusionEntity::role_to_string(ExtrusionRole role)
|
||||
{
|
||||
switch (role) {
|
||||
#if ENABLE_GCODE_VIEWER
|
||||
case erNone : return L("Unknown");
|
||||
#else
|
||||
case erNone : return L("None");
|
||||
#endif // ENABLE_GCODE_VIEWER
|
||||
case erPerimeter : return L("Perimeter");
|
||||
case erExternalPerimeter : return L("External perimeter");
|
||||
case erOverhangPerimeter : return L("Overhang perimeter");
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "../Surface.hpp"
|
||||
|
||||
#include "FillBase.hpp"
|
||||
#include "FillRectilinear2.hpp"
|
||||
#include "FillRectilinear.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@ -54,7 +54,8 @@ struct SurfaceFillParams : FillParams
|
||||
RETURN_COMPARE_NON_EQUAL(monotonic);
|
||||
RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, connection);
|
||||
RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, dont_adjust);
|
||||
RETURN_COMPARE_NON_EQUAL(fill_exactly);
|
||||
|
||||
RETURN_COMPARE_NON_EQUAL(anchor_length); RETURN_COMPARE_NON_EQUAL(fill_exactly);
|
||||
RETURN_COMPARE_NON_EQUAL(flow.width);
|
||||
RETURN_COMPARE_NON_EQUAL(flow.height);
|
||||
RETURN_COMPARE_NON_EQUAL(flow.nozzle_diameter);
|
||||
@ -74,7 +75,8 @@ struct SurfaceFillParams : FillParams
|
||||
this->monotonic == rhs.monotonic &&
|
||||
this->connection == rhs.connection &&
|
||||
this->dont_adjust == rhs.dont_adjust &&
|
||||
this->fill_exactly == rhs.fill_exactly &&
|
||||
|
||||
this->anchor_length == rhs.anchor_length && this->fill_exactly == rhs.fill_exactly &&
|
||||
this->flow == rhs.flow &&
|
||||
this->role == rhs.role;
|
||||
}
|
||||
@ -105,25 +107,26 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
|
||||
if (surface.surface_type == (stPosInternal | stDensVoid)) {
|
||||
has_internal_voids = true;
|
||||
} else {
|
||||
const PrintRegionConfig ®ion_config = layerm.region()->config();
|
||||
FlowRole extrusion_role = surface.has_pos_top() ? frTopSolidInfill : (surface.has_fill_solid() ? frSolidInfill : frInfill);
|
||||
bool is_bridge = layer.id() > 0 && surface.has_mod_bridge();
|
||||
bool is_denser = false;
|
||||
params.extruder = layerm.region()->extruder(extrusion_role);
|
||||
params.pattern = layerm.region()->config().fill_pattern.value;
|
||||
params.density = float(layerm.region()->config().fill_density) / 100.f;
|
||||
params.pattern = region_config.fill_pattern.value;
|
||||
params.density = float(region_config.fill_density) / 100.f;
|
||||
params.dont_adjust = false;
|
||||
|
||||
if (surface.has_fill_solid()) {
|
||||
params.density = 1.f;
|
||||
params.pattern = ipRectilinear;
|
||||
if (surface.has_pos_external() && !is_bridge)
|
||||
params.pattern = surface.has_pos_top() ? layerm.region()->config().top_fill_pattern.value : layerm.region()->config().bottom_fill_pattern.value;
|
||||
params.pattern = surface.has_pos_top() ? region_config.top_fill_pattern.value : region_config.bottom_fill_pattern.value;
|
||||
else if (!is_bridge)
|
||||
params.pattern = layerm.region()->config().solid_fill_pattern.value;
|
||||
params.pattern = region_config.solid_fill_pattern.value;
|
||||
} else {
|
||||
|
||||
if (layerm.region()->config().infill_dense.getBool()
|
||||
&& layerm.region()->config().fill_density < 40
|
||||
if (region_config.infill_dense.getBool()
|
||||
&& region_config.fill_density < 40
|
||||
&& surface.maxNbSolidLayersOnTop == 1) {
|
||||
params.density = 0.42f;
|
||||
is_denser = true;
|
||||
@ -152,20 +155,20 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
|
||||
params.role = erSolidInfill;
|
||||
}
|
||||
}
|
||||
params.fill_exactly = layerm.region()->config().enforce_full_fill_volume.getBool();
|
||||
params.connection = layerm.region()->config().infill_connection.value;
|
||||
params.fill_exactly = region_config.enforce_full_fill_volume.getBool();
|
||||
params.connection = region_config.infill_connection.value;
|
||||
params.bridge_angle = float(surface.bridge_angle);
|
||||
if (is_denser) {
|
||||
params.angle = 0;
|
||||
} else {
|
||||
params.angle = float(Geometry::deg2rad(layerm.region()->config().fill_angle.value));
|
||||
params.angle += float(PI * (layerm.region()->config().fill_angle_increment.value * layerm.layer()->id()) / 180.f);
|
||||
params.angle = float(Geometry::deg2rad(region_config.fill_angle.value));
|
||||
params.angle += float(PI * (region_config.fill_angle_increment.value * layerm.layer()->id()) / 180.f);
|
||||
}
|
||||
|
||||
//adjust flow (to over-extrude when needed)
|
||||
params.flow_mult = 1;
|
||||
if (surface.has_pos_top())
|
||||
params.flow_mult *= float(layerm.region()->config().fill_top_flow_ratio.get_abs_value(1));
|
||||
params.flow_mult *= float(region_config.fill_top_flow_ratio.get_abs_value(1));
|
||||
|
||||
params.config = &layerm.region()->config();
|
||||
|
||||
@ -180,7 +183,11 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
|
||||
);
|
||||
|
||||
// Calculate flow spacing for infill pattern generation.
|
||||
if (! surface.has_fill_solid() && ! is_bridge) {
|
||||
if (surface.has_fill_solid() || is_bridge) {
|
||||
params.spacing = params.flow.spacing();
|
||||
// Don't limit anchor length for solid or bridging infill.
|
||||
params.anchor_length = 1000.f;
|
||||
} else {
|
||||
// it's internal infill, so we can calculate a generic flow spacing
|
||||
// for all layers, for avoiding the ugly effect of
|
||||
// misaligned infill on first layer because of different extrusion width and
|
||||
@ -193,8 +200,13 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
|
||||
-1, // auto width
|
||||
*layer.object()
|
||||
).spacing();
|
||||
} else
|
||||
params.spacing = params.flow.spacing();
|
||||
// Anchor a sparse infill to inner perimeters with the following anchor length:
|
||||
params.anchor_length = float(region_config.infill_anchor);
|
||||
if (region_config.infill_anchor.percent)
|
||||
params.anchor_length *= 0.01 * params.spacing;
|
||||
// Don't limit anchor length for solid or bridging infill.
|
||||
//FIXEME: totest params.anchor_length = 1000.f;
|
||||
}
|
||||
|
||||
auto it_params = set_surface_params.find(params);
|
||||
if (it_params == set_surface_params.end())
|
||||
@ -406,6 +418,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
||||
//FillParams params;
|
||||
//params.density = float(0.01 * surface_fill.params.density);
|
||||
//params.dont_adjust = surface_fill.params.dont_adjust; // false
|
||||
//params.anchor_length = surface_fill.params.anchor_length;
|
||||
|
||||
if (using_internal_flow) {
|
||||
// if we used the internal flow we're not doing a solid infill
|
||||
@ -561,14 +574,13 @@ void Layer::make_ironing()
|
||||
}
|
||||
std::sort(by_extruder.begin(), by_extruder.end());
|
||||
|
||||
FillRectilinear2 fill;
|
||||
FillRectilinear fill;
|
||||
FillParams fill_params;
|
||||
fill.set_bounding_box(this->object()->bounding_box());
|
||||
fill.layer_id = this->id();
|
||||
fill.z = this->print_z;
|
||||
fill.overlap = 0;
|
||||
fill_params.density = 1.;
|
||||
// fill_params.dont_connect = true;
|
||||
fill_params.connection = InfillConnection::icConnected;
|
||||
fill_params.monotonic = true;
|
||||
|
||||
|
@ -19,10 +19,10 @@ class LayerRegion;
|
||||
class Filler
|
||||
{
|
||||
public:
|
||||
Filler() : fill(NULL) {}
|
||||
Filler() : fill(nullptr) {}
|
||||
~Filler() {
|
||||
delete fill;
|
||||
fill = NULL;
|
||||
fill = nullptr;
|
||||
}
|
||||
Fill *fill;
|
||||
FillParams params;
|
||||
|
@ -138,7 +138,7 @@ void Fill3DHoneycomb::_fill_surface_single(
|
||||
const FillParams ¶ms,
|
||||
unsigned int thickness_layers,
|
||||
const std::pair<float, Point> &direction,
|
||||
ExPolygon &expolygon,
|
||||
ExPolygon expolygon,
|
||||
Polylines &polylines_out) const
|
||||
{
|
||||
// no rotation is supported for this infill pattern
|
||||
@ -164,15 +164,13 @@ void Fill3DHoneycomb::_fill_surface_single(
|
||||
pl.translate(bb.min);
|
||||
|
||||
// clip pattern to boundaries, chain the clipped polylines
|
||||
Polylines polylines_chained = chain_polylines(intersection_pl(polylines, to_polygons(expolygon)));
|
||||
polylines = intersection_pl(polylines, to_polygons(expolygon));
|
||||
|
||||
// connect lines if needed
|
||||
if (! polylines_chained.empty()) {
|
||||
if (params.connection == icNotConnected)
|
||||
append(polylines_out, std::move(polylines_chained));
|
||||
else
|
||||
this->connect_infill(std::move(polylines_chained), expolygon, polylines_out, this->get_spacing(), params);
|
||||
}
|
||||
}
|
||||
if (params.connection == icNotConnected || polylines.size() <= 1)
|
||||
append(polylines_out, chain_polylines(std::move(polylines)));
|
||||
else
|
||||
this->connect_infill(std::move(polylines), expolygon, polylines_out, this->get_spacing(), params);
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
@ -12,15 +12,15 @@ namespace Slic3r {
|
||||
class Fill3DHoneycomb : public Fill
|
||||
{
|
||||
public:
|
||||
virtual Fill* clone() const { return new Fill3DHoneycomb(*this); };
|
||||
virtual ~Fill3DHoneycomb() {}
|
||||
Fill* clone() const override { return new Fill3DHoneycomb(*this); };
|
||||
~Fill3DHoneycomb() override {}
|
||||
|
||||
protected:
|
||||
virtual void _fill_surface_single(
|
||||
void _fill_surface_single(
|
||||
const FillParams ¶ms,
|
||||
unsigned int thickness_layers,
|
||||
const std::pair<float, Point> &direction,
|
||||
ExPolygon &expolygon,
|
||||
ExPolygon expolygon,
|
||||
Polylines &polylines_out) const override;
|
||||
};
|
||||
|
||||
|
@ -14,11 +14,18 @@
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
|
||||
// Boost pool: Don't use mutexes to synchronize memory allocation.
|
||||
#define BOOST_POOL_NO_MT
|
||||
#include <boost/pool/object_pool.hpp>
|
||||
|
||||
#include <boost/geometry.hpp>
|
||||
#include <boost/geometry/geometries/point.hpp>
|
||||
#include <boost/geometry/geometries/segment.hpp>
|
||||
#include <boost/geometry/index/rtree.hpp>
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
namespace FillAdaptive {
|
||||
|
||||
@ -288,7 +295,7 @@ std::pair<double, double> adaptive_fill_line_spacing(const PrintObject &print_ob
|
||||
bool build_octree = false;
|
||||
const std::vector<double> &nozzle_diameters = print_object.print()->config().nozzle_diameter.values;
|
||||
double max_nozzle_diameter = *std::max_element(nozzle_diameters.begin(), nozzle_diameters.end());
|
||||
double default_infill_extrusion_width = Flow::auto_extrusion_width(FlowRole::frInfill, max_nozzle_diameter);
|
||||
double default_infill_extrusion_width = Flow::auto_extrusion_width(FlowRole::frInfill, float(max_nozzle_diameter));
|
||||
for (const PrintRegion *region : print_object.print()->regions()) {
|
||||
const PrintRegionConfig &config = region->config();
|
||||
bool nonempty = config.fill_density > 0;
|
||||
@ -475,7 +482,7 @@ static void generate_infill_lines_recursive(
|
||||
Line new_line(Point::new_scale(from), Point::new_scale(to));
|
||||
if (last_line.a.x() == std::numeric_limits<coord_t>::max()) {
|
||||
last_line.a = new_line.a;
|
||||
} else if ((new_line.a - last_line.b).cwiseAbs().maxCoeff() > 300) { // SCALED_EPSILON is 100 and it is not enough
|
||||
} else if ((new_line.a - last_line.b).cwiseAbs().maxCoeff() > 1000) { // SCALED_EPSILON is 100 and it is not enough
|
||||
context.output_lines.emplace_back(last_line);
|
||||
last_line.a = new_line.a;
|
||||
}
|
||||
@ -501,7 +508,7 @@ static void generate_infill_lines_recursive(
|
||||
#endif
|
||||
|
||||
#ifdef ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
static void export_infill_lines_to_svg(const ExPolygon &expoly, const Polylines &polylines, const std::string &path)
|
||||
static void export_infill_lines_to_svg(const ExPolygon &expoly, const Polylines &polylines, const std::string &path, const Points &pts = Points())
|
||||
{
|
||||
BoundingBox bbox = get_extents(expoly);
|
||||
bbox.offset(scale_(3.));
|
||||
@ -511,7 +518,8 @@ static void export_infill_lines_to_svg(const ExPolygon &expoly, const Polylines
|
||||
svg.draw_outline(expoly, "green");
|
||||
svg.draw(polylines, "red");
|
||||
static constexpr double trim_length = scale_(0.4);
|
||||
for (Polyline polyline : polylines) {
|
||||
for (Polyline polyline : polylines)
|
||||
if (! polyline.empty()) {
|
||||
Vec2d a = polyline.points.front().cast<double>();
|
||||
Vec2d d = polyline.points.back().cast<double>();
|
||||
if (polyline.size() == 2) {
|
||||
@ -543,15 +551,710 @@ static void export_infill_lines_to_svg(const ExPolygon &expoly, const Polylines
|
||||
}
|
||||
svg.draw(polyline, "black");
|
||||
}
|
||||
svg.draw(pts, "magenta");
|
||||
}
|
||||
#endif /* ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT */
|
||||
|
||||
// Representing a T-joint (in general case) between two infill lines
|
||||
// (between one end point of intersect_pl/intersect_line and
|
||||
struct Intersection
|
||||
{
|
||||
// Closest line to intersect_point.
|
||||
const Line *closest_line;
|
||||
|
||||
// The line for which is computed closest line from intersect_point to closest_line
|
||||
const Line *intersect_line;
|
||||
// Pointer to the polyline from which is computed closest_line
|
||||
Polyline *intersect_pl;
|
||||
// Point for which is computed closest line (closest_line)
|
||||
Point intersect_point;
|
||||
// Indicate if intersect_point is the first or the last point of intersect_pl
|
||||
bool front;
|
||||
// Signum of intersect_line_dir.cross(closest_line.dir()):
|
||||
bool left;
|
||||
|
||||
// Indication if this intersection has been proceed
|
||||
bool used = false;
|
||||
|
||||
bool fresh() const throw() { return ! used && ! intersect_pl->empty(); }
|
||||
|
||||
Intersection(const Line &closest_line, const Line &intersect_line, Polyline *intersect_pl, const Point &intersect_point, bool front) :
|
||||
closest_line(&closest_line), intersect_line(&intersect_line), intersect_pl(intersect_pl), intersect_point(intersect_point), front(front)
|
||||
{
|
||||
// Calculate side of this intersection line of the closest line.
|
||||
Vec2d v1((this->closest_line->b - this->closest_line->a).cast<double>());
|
||||
Vec2d v2(this->intersect_line_dir());
|
||||
#ifndef NDEBUG
|
||||
{
|
||||
Vec2d v1n = v1.normalized();
|
||||
Vec2d v2n = v2.normalized();
|
||||
double c = cross2(v1n, v2n);
|
||||
assert(std::abs(c) > sin(M_PI / 12.));
|
||||
}
|
||||
#endif // NDEBUG
|
||||
this->left = cross2(v1, v2) > 0.;
|
||||
}
|
||||
|
||||
std::optional<Line> other_hook() const {
|
||||
std::optional<Line> out;
|
||||
const Points &pts = intersect_pl->points;
|
||||
if (pts.size() >= 3)
|
||||
out = this->front ? Line(pts[1], pts[2]) : Line(pts[pts.size() - 2], pts[pts.size() - 3]);
|
||||
return out;
|
||||
}
|
||||
|
||||
bool other_hook_intersects(const Line &l, Point &pt) {
|
||||
std::optional<Line> h = other_hook();
|
||||
return h && h->intersection(l, &pt);
|
||||
}
|
||||
bool other_hook_intersects(const Line &l) { Point pt; return this->other_hook_intersects(l, pt); }
|
||||
|
||||
// Direction to intersect_point.
|
||||
Vec2d intersect_line_dir() const throw() {
|
||||
return (this->intersect_point == intersect_line->a ? intersect_line->b - intersect_line->a : intersect_line->a - intersect_line->b).cast<double>();
|
||||
}
|
||||
};
|
||||
|
||||
static inline Intersection* get_nearest_intersection(std::vector<std::pair<Intersection*, double>>& intersect_line, const size_t first_idx)
|
||||
{
|
||||
assert(intersect_line.size() >= 2);
|
||||
bool take_next = false;
|
||||
if (first_idx == 0)
|
||||
take_next = true;
|
||||
else if (first_idx + 1 == intersect_line.size())
|
||||
take_next = false;
|
||||
else {
|
||||
// Has both prev and next.
|
||||
const std::pair<Intersection*, double> &ithis = intersect_line[first_idx];
|
||||
const std::pair<Intersection*, double> &iprev = intersect_line[first_idx - 1];
|
||||
const std::pair<Intersection*, double> &inext = intersect_line[first_idx + 1];
|
||||
take_next = iprev.first->fresh() && inext.first->fresh() ?
|
||||
inext.second - ithis.second < ithis.second - iprev.second :
|
||||
inext.first->fresh();
|
||||
}
|
||||
return intersect_line[take_next ? first_idx + 1 : first_idx - 1].first;
|
||||
}
|
||||
|
||||
// Create a line representing the anchor aka hook extrusion based on line_to_offset
|
||||
// translated in the direction of the intersection line (intersection.intersect_line).
|
||||
static Line create_offset_line(Line offset_line, const Intersection &intersection, const double scaled_offset)
|
||||
{
|
||||
offset_line.translate((perp(intersection.closest_line->vector().cast<double>().normalized()) * (intersection.left ? scaled_offset : - scaled_offset)).cast<coord_t>());
|
||||
// Extend the line by a small value to guarantee a collision with adjacent lines
|
||||
offset_line.extend(coord_t(scaled_offset * 1.16)); // / cos(PI/6)
|
||||
return offset_line;
|
||||
}
|
||||
|
||||
namespace bg = boost::geometry;
|
||||
namespace bgm = boost::geometry::model;
|
||||
namespace bgi = boost::geometry::index;
|
||||
|
||||
// float is needed because for coord_t bgi::intersects throws "bad numeric conversion: positive overflow"
|
||||
using rtree_point_t = bgm::point<float, 2, boost::geometry::cs::cartesian>;
|
||||
using rtree_segment_t = bgm::segment<rtree_point_t>;
|
||||
using rtree_t = bgi::rtree<std::pair<rtree_segment_t, size_t>, bgi::rstar<16, 4>>;
|
||||
|
||||
static inline rtree_point_t mk_rtree_point(const Point &pt) {
|
||||
return rtree_point_t(float(pt.x()), float(pt.y()));
|
||||
}
|
||||
static inline rtree_segment_t mk_rtree_seg(const Point &a, const Point &b) {
|
||||
return { mk_rtree_point(a), mk_rtree_point(b) };
|
||||
}
|
||||
static inline rtree_segment_t mk_rtree_seg(const Line &l) {
|
||||
return mk_rtree_seg(l.a, l.b);
|
||||
}
|
||||
|
||||
// Create a hook based on hook_line and append it to the begin or end of the polyline in the intersection
|
||||
static void add_hook(
|
||||
const Intersection &intersection, const double scaled_offset,
|
||||
const int hook_length, double scaled_trim_distance,
|
||||
const rtree_t &rtree, const Lines &lines_src)
|
||||
{
|
||||
// Trim the hook start by the infill line it will connect to.
|
||||
Point hook_start;
|
||||
bool intersection_found = intersection.intersect_line->intersection(
|
||||
create_offset_line(*intersection.closest_line, intersection, scaled_offset),
|
||||
&hook_start);
|
||||
assert(intersection_found);
|
||||
|
||||
std::optional<Line> other_hook = intersection.other_hook();
|
||||
|
||||
Vec2d hook_vector_norm = intersection.closest_line->vector().cast<double>().normalized();
|
||||
// hook_vector is extended by the thickness of the infill line, so that a collision is found against
|
||||
// the infill centerline to be later trimmed by the thickened line.
|
||||
Vector hook_vector = ((hook_length + 1.16 * scaled_trim_distance) * hook_vector_norm).cast<coord_t>();
|
||||
Line hook_forward(hook_start, hook_start + hook_vector);
|
||||
|
||||
auto filter_itself = [&intersection, &lines_src](const auto &item) { return item.second != intersection.intersect_line - lines_src.data(); };
|
||||
|
||||
std::vector<std::pair<rtree_segment_t, size_t>> hook_intersections;
|
||||
rtree.query(bgi::intersects(mk_rtree_seg(hook_forward)) && bgi::satisfies(filter_itself), std::back_inserter(hook_intersections));
|
||||
Point self_intersection_point;
|
||||
bool self_intersection = other_hook && other_hook->intersection(hook_forward, &self_intersection_point);
|
||||
|
||||
// Find closest intersection of a line segment starting with pt pointing in dir
|
||||
// with any of the hook_intersections, returns Euclidian distance.
|
||||
// dir is normalized.
|
||||
auto max_hook_length = [hook_length, scaled_trim_distance, &lines_src](
|
||||
const Vec2d &pt, const Vec2d &dir,
|
||||
const std::vector<std::pair<rtree_segment_t, size_t>> &hook_intersections,
|
||||
bool self_intersection, const std::optional<Line> &self_intersection_line, const Point &self_intersection_point) {
|
||||
// No hook is longer than hook_length, there shouldn't be any intersection closer than that.
|
||||
auto max_length = double(hook_length);
|
||||
auto update_max_length = [&max_length](double d) {
|
||||
if (d < max_length)
|
||||
max_length = d;
|
||||
};
|
||||
// Shift the trimming point away from the colliding thick line.
|
||||
auto shift_from_thick_line = [&dir, scaled_trim_distance](const Vec2d& dir2) {
|
||||
return scaled_trim_distance * std::abs(cross2(dir, dir2.normalized()));
|
||||
};
|
||||
|
||||
for (const auto &hook_intersection : hook_intersections) {
|
||||
const rtree_segment_t &segment = hook_intersection.first;
|
||||
// Segment start and end points, segment vector.
|
||||
Vec2d pt2(bg::get<0, 0>(segment), bg::get<0, 1>(segment));
|
||||
Vec2d dir2 = Vec2d(bg::get<1, 0>(segment), bg::get<1, 1>(segment)) - pt2;
|
||||
// Find intersection of (pt, dir) with (pt2, dir2), where dir is normalized.
|
||||
double denom = cross2(dir, dir2);
|
||||
assert(std::abs(denom) > EPSILON);
|
||||
double t = cross2(pt2 - pt, dir2) / denom;
|
||||
if (hook_intersection.second < lines_src.size())
|
||||
// Trimming by another infill line. Reduce overlap.
|
||||
t -= shift_from_thick_line(dir2);
|
||||
update_max_length(t);
|
||||
}
|
||||
if (self_intersection) {
|
||||
double t = (self_intersection_point.cast<double>() - pt).dot(dir) - shift_from_thick_line((*self_intersection_line).vector().cast<double>());
|
||||
max_length = std::min(max_length, t);
|
||||
}
|
||||
return std::max(0., max_length);
|
||||
};
|
||||
|
||||
Vec2d hook_startf = hook_start.cast<double>();
|
||||
double hook_forward_max_length = max_hook_length(hook_startf, hook_vector_norm, hook_intersections, self_intersection, other_hook, self_intersection_point);
|
||||
double hook_backward_max_length = 0.;
|
||||
if (hook_forward_max_length < hook_length - SCALED_EPSILON) {
|
||||
// Try the other side.
|
||||
hook_intersections.clear();
|
||||
Line hook_backward(hook_start, hook_start - hook_vector);
|
||||
rtree.query(bgi::intersects(mk_rtree_seg(hook_backward)) && bgi::satisfies(filter_itself), std::back_inserter(hook_intersections));
|
||||
self_intersection = other_hook && other_hook->intersection(hook_backward, &self_intersection_point);
|
||||
hook_backward_max_length = max_hook_length(hook_startf, - hook_vector_norm, hook_intersections, self_intersection, other_hook, self_intersection_point);
|
||||
}
|
||||
|
||||
// Take the longer hook.
|
||||
Vec2d hook_dir = (hook_forward_max_length > hook_backward_max_length ? hook_forward_max_length : - hook_backward_max_length) * hook_vector_norm;
|
||||
Point hook_end = hook_start + hook_dir.cast<coord_t>();
|
||||
|
||||
Points &pl = intersection.intersect_pl->points;
|
||||
if (intersection.front) {
|
||||
pl.front() = hook_start;
|
||||
pl.emplace(pl.begin(), hook_end);
|
||||
} else {
|
||||
pl.back() = hook_start;
|
||||
pl.emplace_back(hook_end);
|
||||
}
|
||||
}
|
||||
|
||||
static Polylines connect_lines_using_hooks(Polylines &&lines, const ExPolygon &boundary, const double spacing, const int hook_length)
|
||||
{
|
||||
rtree_t rtree;
|
||||
size_t poly_idx = 0;
|
||||
|
||||
Lines lines_src;
|
||||
lines_src.reserve(lines.size());
|
||||
std::transform(lines.begin(), lines.end(), std::back_inserter(lines_src), [](const Line& l) { return Polyline{ l.a, l.b }; });
|
||||
|
||||
// 19% overlap, slightly lower than the allowed overlap in Fill::connect_infill()
|
||||
const float scaled_offset = float(scale_(spacing) * 0.81);
|
||||
// 25% overlap
|
||||
const float scaled_trim_distance = float(scale_(spacing) * 0.5 * 0.75);
|
||||
|
||||
// Keeping the vector of closest points outside the loop, so the vector does not need to be reallocated.
|
||||
std::vector<std::pair<rtree_segment_t, size_t>> closest;
|
||||
// Pairs of lines touching at one end point. The pair is sorted to make the end point connection test symmetric.
|
||||
std::vector<std::pair<const Polyline*, const Polyline*>> lines_touching_at_endpoints;
|
||||
{
|
||||
// Insert infill lines into rtree, merge close collinear segments split by the infill boundary,
|
||||
// collect lines_touching_at_endpoints.
|
||||
double r2_close = Slic3r::sqr(1200.);
|
||||
for (Polyline &poly : lines) {
|
||||
assert(poly.points.size() == 2);
|
||||
if (&poly != lines.data()) {
|
||||
// Join collinear segments separated by a tiny gap. These gaps were likely created by clipping the infill lines with a concave dent in an infill boundary.
|
||||
auto collinear_segment = [&rtree, &closest, &lines, &lines_touching_at_endpoints, r2_close](const Point& pt, const Point& pt_other, const Polyline* polyline) -> std::pair<Polyline*, bool> {
|
||||
closest.clear();
|
||||
rtree.query(bgi::nearest(mk_rtree_point(pt), 1), std::back_inserter(closest));
|
||||
const Polyline *other = &lines[closest.front().second];
|
||||
double dist2_front = (other->points.front() - pt).cast<double>().squaredNorm();
|
||||
double dist2_back = (other->points.back() - pt).cast<double>().squaredNorm();
|
||||
double dist2_min = std::min(dist2_front, dist2_back);
|
||||
if (dist2_min < r2_close) {
|
||||
// Don't connect the segments in an opposite direction.
|
||||
double dist2_min_other = std::min((other->points.front() - pt_other).cast<double>().squaredNorm(), (other->points.back() - pt_other).cast<double>().squaredNorm());
|
||||
if (dist2_min_other > dist2_min) {
|
||||
// End points of the two lines are very close, they should have been merged together if they are collinear.
|
||||
Vec2d v1 = (pt_other - pt).cast<double>();
|
||||
Vec2d v2 = (other->points.back() - other->points.front()).cast<double>();
|
||||
Vec2d v1n = v1.normalized();
|
||||
Vec2d v2n = v2.normalized();
|
||||
// The vectors must not be collinear.
|
||||
double d = v1n.dot(v2n);
|
||||
if (std::abs(d) > 0.99f) {
|
||||
// Lines are collinear, merge them.
|
||||
rtree.remove(closest.front());
|
||||
return std::make_pair(const_cast<Polyline*>(other), dist2_min == dist2_front);
|
||||
} else {
|
||||
if (polyline > other)
|
||||
std::swap(polyline, other);
|
||||
lines_touching_at_endpoints.emplace_back(polyline, other);
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::make_pair(static_cast<Polyline*>(nullptr), false);
|
||||
};
|
||||
auto collinear_front = collinear_segment(poly.points.front(), poly.points.back(), &poly);
|
||||
if (collinear_front.first) {
|
||||
Polyline &other = *collinear_front.first;
|
||||
poly.points.front() = collinear_front.second ? other.points.back() : other.points.front();
|
||||
other.points.clear();
|
||||
}
|
||||
auto collinear_back = collinear_segment(poly.points.back(), poly.points.front(), &poly);
|
||||
if (collinear_back.first) {
|
||||
Polyline &other = *collinear_front.first;
|
||||
poly.points.back() = collinear_front.second ? other.points.back() : other.points.front();
|
||||
other.points.clear();
|
||||
}
|
||||
}
|
||||
rtree.insert(std::make_pair(mk_rtree_seg(poly.points.front(), poly.points.back()), poly_idx++));
|
||||
}
|
||||
}
|
||||
|
||||
sort_remove_duplicates(lines_touching_at_endpoints);
|
||||
|
||||
std::vector<Intersection> intersections;
|
||||
{
|
||||
// Minimum lenght of an infill line to anchor. Very short lines cannot be trimmed from both sides,
|
||||
// it does not help to anchor extremely short infill lines, it consumes too much plastic while not adding
|
||||
// to the object rigidity.
|
||||
assert(scaled_offset > scaled_trim_distance);
|
||||
const double line_len_threshold_drop_both_sides = scaled_offset * (2. / cos(PI / 6.) + 0.5) + SCALED_EPSILON;
|
||||
const double line_len_threshold_anchor_both_sides = line_len_threshold_drop_both_sides + scaled_offset;
|
||||
const double line_len_threshold_drop_single_side = scaled_offset * (1. / cos(PI / 6.) + 1.5) + SCALED_EPSILON;
|
||||
const double line_len_threshold_anchor_single_side = line_len_threshold_drop_single_side + scaled_offset;
|
||||
for (size_t line_idx = 0; line_idx < lines.size(); ++ line_idx) {
|
||||
Polyline &line = lines[line_idx];
|
||||
if (line.points.empty())
|
||||
continue;
|
||||
|
||||
Point &front_point = line.points.front();
|
||||
Point &back_point = line.points.back();
|
||||
|
||||
// Find the nearest line from the start point of the line.
|
||||
std::optional<size_t> tjoint_front, tjoint_back;
|
||||
{
|
||||
auto has_tjoint = [&closest, line_idx, &rtree, &lines](const Point &pt) {
|
||||
auto filter_itself = [line_idx](const auto &item) { return item.second != line_idx; };
|
||||
closest.clear();
|
||||
rtree.query(bgi::nearest(mk_rtree_point(pt), 1) && bgi::satisfies(filter_itself), std::back_inserter(closest));
|
||||
const Polyline &pl = lines[closest.front().second];
|
||||
std::optional<size_t> out;
|
||||
if (pl.points.empty()) {
|
||||
// The closest infill line was already dropped as it was too short.
|
||||
// Such an infill line should not make a T-joint anyways.
|
||||
#if 0 // #ifndef NDEBUG
|
||||
const auto &seg = closest.front().first;
|
||||
struct Linef { Vec2d a; Vec2d b; };
|
||||
Linef l { { bg::get<0, 0>(seg), bg::get<0, 1>(seg) }, { bg::get<1, 0>(seg), bg::get<1, 1>(seg) } };
|
||||
assert(line_alg::distance_to_squared(l, Vec2d(pt.cast<double>())) > 1000 * 1000);
|
||||
#endif // NDEBUG
|
||||
} else if (((Line)pl).distance_to_squared(pt) <= 1000 * 1000)
|
||||
out = closest.front().second;
|
||||
return out;
|
||||
};
|
||||
// Refuse to create a T-joint if the infill lines touch at their ends.
|
||||
auto filter_end_point_connections = [&lines_touching_at_endpoints, &lines, &line](std::optional<size_t> in) {
|
||||
std::optional<size_t> out;
|
||||
if (in) {
|
||||
const Polyline *lo = &line;
|
||||
const Polyline *hi = &lines[*in];
|
||||
if (lo > hi)
|
||||
std::swap(lo, hi);
|
||||
if (! std::binary_search(lines_touching_at_endpoints.begin(), lines_touching_at_endpoints.end(), std::make_pair(lo, hi)))
|
||||
// Not an end-point connection, it is a valid T-joint.
|
||||
out = in;
|
||||
}
|
||||
return out;
|
||||
};
|
||||
tjoint_front = filter_end_point_connections(has_tjoint(front_point));
|
||||
tjoint_back = filter_end_point_connections(has_tjoint(back_point));
|
||||
}
|
||||
|
||||
int num_tjoints = int(tjoint_front.has_value()) + int(tjoint_back.has_value());
|
||||
if (num_tjoints > 0) {
|
||||
double line_len = line.length();
|
||||
bool drop = false;
|
||||
bool anchor = false;
|
||||
if (num_tjoints == 1) {
|
||||
// Connected to perimeters on a single side only, connected to another infill line on the other side.
|
||||
drop = line_len < line_len_threshold_drop_single_side;
|
||||
anchor = line_len > line_len_threshold_anchor_single_side;
|
||||
} else {
|
||||
// Not connected to perimeters at all, connected to two infill lines.
|
||||
assert(num_tjoints == 2);
|
||||
drop = line_len < line_len_threshold_drop_both_sides;
|
||||
anchor = line_len > line_len_threshold_anchor_both_sides;
|
||||
}
|
||||
if (drop) {
|
||||
// Drop a very short line if connected to another infill line.
|
||||
// Lines shorter than spacing are skipped because it is needed to shrink a line by the value of spacing.
|
||||
// A shorter line than spacing could produce a degenerate polyline.
|
||||
line.points.clear();
|
||||
} else if (anchor) {
|
||||
if (tjoint_front)
|
||||
// T-joint of line's front point with the 'closest' line.
|
||||
intersections.emplace_back(lines_src[*tjoint_front], lines_src[line_idx], &line, front_point, true);
|
||||
if (tjoint_back)
|
||||
// T-joint of line's back point with the 'closest' line.
|
||||
intersections.emplace_back(lines_src[*tjoint_back], lines_src[line_idx], &line, back_point, false);
|
||||
} else {
|
||||
if (tjoint_front)
|
||||
// T joint at the front at a 60 degree angle, the line is very short.
|
||||
// Trim the front side.
|
||||
front_point += ((scaled_trim_distance * 1.155) * (back_point - front_point).cast<double>().normalized()).cast<coord_t>();
|
||||
if (tjoint_back)
|
||||
// T joint at the front at a 60 degree angle, the line is very short.
|
||||
// Trim the front side.
|
||||
back_point += ((scaled_trim_distance * 1.155) * (front_point - back_point).cast<double>().normalized()).cast<coord_t>();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Remove those intersections, that point to a dropped line.
|
||||
for (auto it = intersections.begin(); it != intersections.end(); ) {
|
||||
assert(! lines[it->intersect_line - lines_src.data()].points.empty());
|
||||
if (lines[it->closest_line - lines_src.data()].points.empty()) {
|
||||
*it = intersections.back();
|
||||
intersections.pop_back();
|
||||
} else
|
||||
++ it;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
static int iRun = 0;
|
||||
int iStep = 0;
|
||||
{
|
||||
Points pts;
|
||||
for (const Intersection &i : intersections)
|
||||
pts.emplace_back(i.intersect_point);
|
||||
export_infill_lines_to_svg(boundary, lines, debug_out_path("FillAdaptive-Tjoints-%d.svg", iRun++), pts);
|
||||
}
|
||||
#endif /* ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT */
|
||||
|
||||
// Sort lexicographically by closest_line_idx and left/right orientation.
|
||||
std::sort(intersections.begin(), intersections.end(),
|
||||
[](const Intersection &i1, const Intersection &i2) {
|
||||
return (i1.closest_line == i2.closest_line) ?
|
||||
int(i1.left) < int(i2.left) :
|
||||
i1.closest_line < i2.closest_line;
|
||||
});
|
||||
|
||||
std::vector<size_t> merged_with(lines.size());
|
||||
std::iota(merged_with.begin(), merged_with.end(), 0);
|
||||
|
||||
// Appends the boundary polygon with all holes to rtree for detection to check whether hooks are not crossing the boundary
|
||||
{
|
||||
Point prev = boundary.contour.points.back();
|
||||
for (const Point &point : boundary.contour.points) {
|
||||
rtree.insert(std::make_pair(mk_rtree_seg(prev, point), poly_idx++));
|
||||
prev = point;
|
||||
}
|
||||
for (const Polygon &polygon : boundary.holes) {
|
||||
Point prev = polygon.points.back();
|
||||
for (const Point &point : polygon.points) {
|
||||
rtree.insert(std::make_pair(mk_rtree_seg(prev, point), poly_idx++));
|
||||
prev = point;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto update_merged_polyline_idx = [&merged_with](size_t pl_idx) {
|
||||
// Update the polyline index to index which is merged
|
||||
for (size_t last = pl_idx;;) {
|
||||
size_t lower = merged_with[last];
|
||||
if (lower == last) {
|
||||
merged_with[pl_idx] = lower;
|
||||
return lower;
|
||||
}
|
||||
last = lower;
|
||||
}
|
||||
assert(false);
|
||||
return size_t(0);
|
||||
};
|
||||
auto update_merged_polyline = [&lines, update_merged_polyline_idx](Intersection& intersection) {
|
||||
// Update the polyline index to index which is merged
|
||||
size_t intersect_pl_idx = update_merged_polyline_idx(intersection.intersect_pl - lines.data());
|
||||
intersection.intersect_pl = &lines[intersect_pl_idx];
|
||||
// After polylines are merged, it is necessary to update "forward" based on if intersect_point is the first or the last point of intersect_pl.
|
||||
if (intersection.fresh()) {
|
||||
assert(intersection.intersect_pl->points.front() == intersection.intersect_point ||
|
||||
intersection.intersect_pl->points.back() == intersection.intersect_point);
|
||||
intersection.front = intersection.intersect_pl->points.front() == intersection.intersect_point;
|
||||
}
|
||||
};
|
||||
|
||||
// Merge polylines touching at their ends. This should be a very rare case, but it happens surprisingly often.
|
||||
for (auto it = lines_touching_at_endpoints.rbegin(); it != lines_touching_at_endpoints.rend(); ++ it) {
|
||||
Polyline *pl1 = const_cast<Polyline*>(it->first);
|
||||
Polyline *pl2 = const_cast<Polyline*>(it->second);
|
||||
assert(pl1 < pl2);
|
||||
// pl1 was visited for the 1st time.
|
||||
// pl2 may have alread been merged with another polyline, even with this one.
|
||||
pl2 = &lines[update_merged_polyline_idx(pl2 - lines.data())];
|
||||
assert(pl1 <= pl2);
|
||||
// Avoid closing a loop, ignore dropped infill lines.
|
||||
if (pl1 != pl2 && ! pl1->points.empty() && ! pl2->points.empty()) {
|
||||
// Merge the polylines.
|
||||
assert(pl1 < pl2);
|
||||
assert(pl1->points.size() >= 2);
|
||||
assert(pl2->points.size() >= 2);
|
||||
double d11 = (pl1->points.front() - pl2->points.front()).cast<double>().squaredNorm();
|
||||
double d12 = (pl1->points.front() - pl2->points.back()) .cast<double>().squaredNorm();
|
||||
double d21 = (pl1->points.back() - pl2->points.front()).cast<double>().squaredNorm();
|
||||
double d22 = (pl1->points.back() - pl2->points.back()) .cast<double>().squaredNorm();
|
||||
double d1min = std::min(d11, d12);
|
||||
double d2min = std::min(d21, d22);
|
||||
if (d1min < d2min) {
|
||||
pl1->reverse();
|
||||
if (d12 == d1min)
|
||||
pl2->reverse();
|
||||
} else if (d22 == d2min)
|
||||
pl2->reverse();
|
||||
pl1->points.back() = (pl1->points.back() + pl2->points.front()) / 2;
|
||||
pl1->append(pl2->points.begin() + 1, pl2->points.end());
|
||||
pl2->points.clear();
|
||||
merged_with[pl2 - lines.data()] = pl1 - lines.data();
|
||||
}
|
||||
}
|
||||
|
||||
// Keep intersect_line outside the loop, so it does not get reallocated.
|
||||
std::vector<std::pair<Intersection*, double>> intersect_line;
|
||||
for (size_t min_idx = 0; min_idx < intersections.size();) {
|
||||
intersect_line.clear();
|
||||
// All the nearest points (T-joints) ending at the same line are projected onto this line. Because of it, it can easily find the nearest point.
|
||||
{
|
||||
const Vec2d line_dir = intersections[min_idx].closest_line->vector().cast<double>();
|
||||
size_t max_idx = min_idx;
|
||||
for (; max_idx < intersections.size() &&
|
||||
intersections[min_idx].closest_line == intersections[max_idx].closest_line &&
|
||||
intersections[min_idx].left == intersections[max_idx].left;
|
||||
++ max_idx)
|
||||
intersect_line.emplace_back(&intersections[max_idx], line_dir.dot(intersections[max_idx].intersect_point.cast<double>()));
|
||||
min_idx = max_idx;
|
||||
assert(intersect_line.size() > 0);
|
||||
// Sort the intersections along line_dir.
|
||||
std::sort(intersect_line.begin(), intersect_line.end(), [](const auto &i1, const auto &i2) { return i1.second < i2.second; });
|
||||
}
|
||||
|
||||
if (intersect_line.size() == 1) {
|
||||
// Simple case: The current intersection is the only one touching its adjacent line.
|
||||
Intersection &first_i = *intersect_line.front().first;
|
||||
update_merged_polyline(first_i);
|
||||
if (first_i.fresh()) {
|
||||
// Try to connect left or right. If not enough space for hook_length, take the longer side.
|
||||
#ifdef ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
export_infill_lines_to_svg(boundary, lines, debug_out_path("FillAdaptive-add_hook0-pre-%d-%d.svg", iRun, iStep), { first_i.intersect_point });
|
||||
#endif // ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
add_hook(first_i, scaled_offset, hook_length, scaled_trim_distance, rtree, lines_src);
|
||||
#ifdef ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
export_infill_lines_to_svg(boundary, lines, debug_out_path("FillAdaptive-add_hook0-pre-%d-%d.svg", iRun, iStep), { first_i.intersect_point });
|
||||
++ iStep;
|
||||
#endif // ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
first_i.used = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
for (size_t first_idx = 0; first_idx < intersect_line.size(); ++ first_idx) {
|
||||
Intersection &first_i = *intersect_line[first_idx].first;
|
||||
update_merged_polyline(first_i);
|
||||
if (! first_i.fresh())
|
||||
// The intersection has been processed, or the polyline has been merged to another polyline.
|
||||
continue;
|
||||
|
||||
// Get the previous or next intersection on the same line, pick the closer one.
|
||||
if (first_idx > 0)
|
||||
update_merged_polyline(*intersect_line[first_idx - 1].first);
|
||||
if (first_idx + 1 < intersect_line.size())
|
||||
update_merged_polyline(*intersect_line[first_idx + 1].first);
|
||||
Intersection &nearest_i = *get_nearest_intersection(intersect_line, first_idx);
|
||||
assert(first_i.closest_line == nearest_i.closest_line);
|
||||
assert(first_i.intersect_line != nearest_i.intersect_line);
|
||||
assert(first_i.intersect_line != first_i.closest_line);
|
||||
assert(nearest_i.intersect_line != first_i.closest_line);
|
||||
// A line between two intersections points
|
||||
Line offset_line = create_offset_line(Line(first_i.intersect_point, nearest_i.intersect_point), first_i, scaled_offset);
|
||||
// Check if both intersections lie on the offset_line and simultaneously get their points of intersecting.
|
||||
// These points are used as start and end of the hook
|
||||
Point first_i_point, nearest_i_point;
|
||||
bool could_connect = false;
|
||||
if (nearest_i.fresh()) {
|
||||
could_connect = first_i.intersect_line->intersection(offset_line, &first_i_point) &&
|
||||
nearest_i.intersect_line->intersection(offset_line, &nearest_i_point);
|
||||
assert(could_connect);
|
||||
}
|
||||
Points &first_points = first_i.intersect_pl->points;
|
||||
Points &second_points = nearest_i.intersect_pl->points;
|
||||
could_connect &= (nearest_i_point - first_i_point).cast<double>().squaredNorm() <= Slic3r::sqr(3. * hook_length);
|
||||
if (could_connect) {
|
||||
// Both intersections are so close that their polylines can be connected.
|
||||
// Verify that no other infill line intersects this anchor line.
|
||||
closest.clear();
|
||||
rtree.query(
|
||||
bgi::intersects(mk_rtree_seg(first_i_point, nearest_i_point)) &&
|
||||
bgi::satisfies([&first_i, &nearest_i, &lines_src](const auto &item)
|
||||
{ return item.second != first_i.intersect_line - lines_src.data() && item.second != nearest_i.intersect_line - lines_src.data(); }),
|
||||
std::back_inserter(closest));
|
||||
could_connect = closest.empty();
|
||||
#if 0
|
||||
// Avoid self intersections. Maybe it is better to trim the self intersection after the connection?
|
||||
if (could_connect && first_i.intersect_pl != nearest_i.intersect_pl) {
|
||||
Line l(first_i_point, nearest_i_point);
|
||||
could_connect = ! first_i.other_hook_intersects(l) && ! nearest_i.other_hook_intersects(l);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
bool connected = false;
|
||||
if (could_connect) {
|
||||
#ifdef ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
export_infill_lines_to_svg(boundary, lines, debug_out_path("FillAdaptive-connecting-pre-%d-%d.svg", iRun, iStep), { first_i.intersect_point, nearest_i.intersect_point });
|
||||
#endif // ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
// No other infill line intersects this anchor line. Extrude it as a whole.
|
||||
if (first_i.intersect_pl == nearest_i.intersect_pl) {
|
||||
// Both intersections are on the same polyline, that means a loop is being closed.
|
||||
assert(first_i.front != nearest_i.front);
|
||||
if (! first_i.front)
|
||||
std::swap(first_i_point, nearest_i_point);
|
||||
first_points.front() = first_i_point;
|
||||
first_points.back() = nearest_i_point;
|
||||
//FIXME trim the end of a closed loop a bit?
|
||||
first_points.emplace(first_points.begin(), nearest_i_point);
|
||||
} else {
|
||||
// Both intersections are on different polylines
|
||||
Line l(first_i_point, nearest_i_point);
|
||||
l.translate((perp(first_i.closest_line->vector().cast<double>().normalized()) * (first_i.left ? scaled_trim_distance : - scaled_trim_distance)).cast<coord_t>());
|
||||
Point pt_start, pt_end;
|
||||
bool trim_start = first_i .intersect_pl->points.size() == 3 && first_i .other_hook_intersects(l, pt_start);
|
||||
bool trim_end = nearest_i.intersect_pl->points.size() == 3 && nearest_i.other_hook_intersects(l, pt_end);
|
||||
first_points.reserve(first_points.size() + second_points.size());
|
||||
if (first_i.front)
|
||||
std::reverse(first_points.begin(), first_points.end());
|
||||
if (trim_start)
|
||||
first_points.front() = pt_start;
|
||||
first_points.back() = first_i_point;
|
||||
first_points.emplace_back(nearest_i_point);
|
||||
if (nearest_i.front)
|
||||
first_points.insert(first_points.end(), second_points.begin() + 1, second_points.end());
|
||||
else
|
||||
first_points.insert(first_points.end(), second_points.rbegin() + 1, second_points.rend());
|
||||
if (trim_end)
|
||||
first_points.back() = pt_end;
|
||||
// Keep the polyline at the lower index slot.
|
||||
if (first_i.intersect_pl < nearest_i.intersect_pl) {
|
||||
second_points.clear();
|
||||
merged_with[nearest_i.intersect_pl - lines.data()] = first_i.intersect_pl - lines.data();
|
||||
} else {
|
||||
second_points = std::move(first_points);
|
||||
first_points.clear();
|
||||
merged_with[first_i.intersect_pl - lines.data()] = nearest_i.intersect_pl - lines.data();
|
||||
}
|
||||
}
|
||||
nearest_i.used = true;
|
||||
connected = true;
|
||||
#ifdef ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
export_infill_lines_to_svg(boundary, lines, debug_out_path("FillAdaptive-connecting-post-%d-%d.svg", iRun, iStep), { first_i.intersect_point, nearest_i.intersect_point });
|
||||
#endif // ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
}
|
||||
if (! connected) {
|
||||
// Try to connect left or right. If not enough space for hook_length, take the longer side.
|
||||
#ifdef ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
export_infill_lines_to_svg(boundary, lines, debug_out_path("FillAdaptive-add_hook-pre-%d-%d.svg", iRun, iStep), { first_i.intersect_point });
|
||||
#endif // ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
add_hook(first_i, scaled_offset, hook_length, scaled_trim_distance, rtree, lines_src);
|
||||
#ifdef ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
export_infill_lines_to_svg(boundary, lines, debug_out_path("FillAdaptive-add_hook-post-%d-%d.svg", iRun, iStep), { first_i.intersect_point });
|
||||
#endif // ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
}
|
||||
#ifdef ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
++ iStep;
|
||||
#endif ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
first_i.used = true;
|
||||
}
|
||||
}
|
||||
|
||||
Polylines polylines_out;
|
||||
polylines_out.reserve(polylines_out.size() + std::count_if(lines.begin(), lines.end(), [](const Polyline &pl) { return !pl.empty(); }));
|
||||
for (Polyline &pl : lines)
|
||||
if (!pl.empty()) polylines_out.emplace_back(std::move(pl));
|
||||
return polylines_out;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool has_no_collinear_lines(const Polylines &polylines)
|
||||
{
|
||||
// Create line end point lookup.
|
||||
struct LineEnd {
|
||||
LineEnd(const Polyline *line, bool start) : line(line), start(start) {}
|
||||
const Polyline *line;
|
||||
// Is it the start or end point?
|
||||
bool start;
|
||||
const Point& point() const { return start ? line->points.front() : line->points.back(); }
|
||||
const Point& other_point() const { return start ? line->points.back() : line->points.front(); }
|
||||
LineEnd other_end() const { return LineEnd(line, !start); }
|
||||
Vec2d vec() const { return Vec2d((this->other_point() - this->point()).cast<double>()); }
|
||||
bool operator==(const LineEnd &rhs) const { return this->line == rhs.line && this->start == rhs.start; }
|
||||
};
|
||||
struct LineEndAccessor {
|
||||
const Point* operator()(const LineEnd &pt) const { return &pt.point(); }
|
||||
};
|
||||
typedef ClosestPointInRadiusLookup<LineEnd, LineEndAccessor> ClosestPointLookupType;
|
||||
ClosestPointLookupType closest_end_point_lookup(1001. * sqrt(2.));
|
||||
for (const Polyline& pl : polylines) {
|
||||
// assert(pl.points.size() == 2);
|
||||
auto line_start = LineEnd(&pl, true);
|
||||
auto line_end = LineEnd(&pl, false);
|
||||
|
||||
auto assert_not_collinear = [&closest_end_point_lookup](const LineEnd &line_start) {
|
||||
std::vector<std::pair<const LineEnd*, double>> hits = closest_end_point_lookup.find_all(line_start.point());
|
||||
for (const std::pair<const LineEnd*, double> &hit : hits)
|
||||
if ((line_start.point() - hit.first->point()).cwiseAbs().maxCoeff() <= 1000) {
|
||||
// End points of the two lines are very close, they should have been merged together if they are collinear.
|
||||
Vec2d v1 = line_start.vec();
|
||||
Vec2d v2 = hit.first->vec();
|
||||
Vec2d v1n = v1.normalized();
|
||||
Vec2d v2n = v2.normalized();
|
||||
// The vectors must not be collinear.
|
||||
assert(std::abs(v1n.dot(v2n)) < cos(M_PI / 12.));
|
||||
}
|
||||
};
|
||||
assert_not_collinear(line_start);
|
||||
assert_not_collinear(line_end);
|
||||
|
||||
closest_end_point_lookup.insert(line_start);
|
||||
closest_end_point_lookup.insert(line_end);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Filler::_fill_surface_single(
|
||||
const FillParams & params,
|
||||
unsigned int thickness_layers,
|
||||
const std::pair<float, Point> &direction,
|
||||
ExPolygon &expolygon,
|
||||
Polylines &polylines_out)
|
||||
ExPolygon expolygon,
|
||||
Polylines &polylines_out) const
|
||||
{
|
||||
assert (this->adapt_fill_octree);
|
||||
|
||||
@ -569,6 +1272,23 @@ void Filler::_fill_surface_single(
|
||||
generate_infill_lines_recursive(context, adapt_fill_octree->root_cube, 0, int(adapt_fill_octree->cubes_properties.size()) - 1);
|
||||
num_lines += context.output_lines.size() + context.temp_lines.size();
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Collect the lines, trim them by the expolygon.
|
||||
all_polylines.reserve(num_lines);
|
||||
auto boundary = to_polygons(expolygon);
|
||||
for (auto &context : contexts) {
|
||||
Polylines lines;
|
||||
lines.reserve(context.output_lines.size() + context.temp_lines.size());
|
||||
std::transform(context.output_lines.begin(), context.output_lines.end(), std::back_inserter(lines), [](const Line& l) { return Polyline{ l.a, l.b }; });
|
||||
for (const Line &l : context.temp_lines)
|
||||
if (l.a.x() != std::numeric_limits<coord_t>::max())
|
||||
lines.push_back({ l.a, l.b });
|
||||
// Crop all polylines
|
||||
append(all_polylines, intersection_pl(std::move(lines), boundary));
|
||||
}
|
||||
// assert(has_no_collinear_lines(all_polylines));
|
||||
#else
|
||||
// Collect the lines.
|
||||
std::vector<Line> lines;
|
||||
lines.reserve(num_lines);
|
||||
@ -578,18 +1298,21 @@ void Filler::_fill_surface_single(
|
||||
if (line.a.x() != std::numeric_limits<coord_t>::max())
|
||||
lines.emplace_back(line);
|
||||
}
|
||||
#if 0
|
||||
// Chain touching line segments, convert lines to polylines.
|
||||
//all_polylines = chain_lines(lines, 300.); // SCALED_EPSILON is 100 and it is not enough
|
||||
#else
|
||||
// Convert lines to polylines.
|
||||
all_polylines.reserve(lines.size());
|
||||
std::transform(lines.begin(), lines.end(), std::back_inserter(all_polylines), [](const Line& l) { return Polyline{ l.a, l.b }; });
|
||||
// Crop all polylines
|
||||
all_polylines = intersection_pl(std::move(all_polylines), to_polygons(expolygon));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Crop all polylines
|
||||
all_polylines = intersection_pl(std::move(all_polylines), to_polygons(expolygon));
|
||||
// After intersection_pl some polylines with only one line are split into more lines
|
||||
for (Polyline &polyline : all_polylines) {
|
||||
//FIXME assert that all the points are collinear and in between the start and end point.
|
||||
if (polyline.points.size() > 2)
|
||||
polyline.points.erase(polyline.points.begin() + 1, polyline.points.end() - 1);
|
||||
}
|
||||
// assert(has_no_collinear_lines(all_polylines));
|
||||
|
||||
#ifdef ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
{
|
||||
@ -598,10 +1321,21 @@ void Filler::_fill_surface_single(
|
||||
}
|
||||
#endif /* ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT */
|
||||
|
||||
if (params.connection == InfillConnection::icNotConnected || all_polylines.size() <= 1)
|
||||
append(polylines_out, std::move(all_polylines));
|
||||
const auto hook_length = coord_t(std::min(scale_(this->get_spacing() * 5), scale_(params.anchor_length)));
|
||||
|
||||
Polylines all_polylines_with_hooks = all_polylines.size() > 1 ? connect_lines_using_hooks(std::move(all_polylines), expolygon, this->get_spacing(), hook_length) : std::move(all_polylines);
|
||||
|
||||
#ifdef ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
{
|
||||
static int iRun = 0;
|
||||
export_infill_lines_to_svg(expolygon, all_polylines_with_hooks, debug_out_path("FillAdaptive-hooks-%d.svg", iRun++));
|
||||
}
|
||||
#endif /* ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT */
|
||||
|
||||
if (params.connection == InfillConnection::icNotConnected || all_polylines_with_hooks.size() <= 1)
|
||||
append(polylines_out, chain_polylines(std::move(all_polylines_with_hooks)));
|
||||
else
|
||||
connect_infill(chain_polylines(std::move(all_polylines)), expolygon, polylines_out, this->get_spacing(), params);
|
||||
connect_infill(std::move(all_polylines_with_hooks), expolygon, polylines_out, this->get_spacing(), params);
|
||||
|
||||
#ifdef ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
{
|
||||
|
@ -56,17 +56,17 @@ FillAdaptive::OctreePtr build_octree(
|
||||
class Filler : public Slic3r::Fill
|
||||
{
|
||||
public:
|
||||
virtual ~Filler() {}
|
||||
~Filler() override {}
|
||||
|
||||
protected:
|
||||
virtual Fill* clone() const { return new Filler(*this); };
|
||||
virtual void _fill_surface_single(
|
||||
Fill* clone() const override { return new Filler(*this); };
|
||||
void _fill_surface_single(
|
||||
const FillParams ¶ms,
|
||||
unsigned int thickness_layers,
|
||||
const std::pair<float, Point> &direction,
|
||||
ExPolygon &expolygon,
|
||||
Polylines &polylines_out);
|
||||
virtual bool no_sort() const { return true; }
|
||||
ExPolygon expolygon,
|
||||
Polylines &polylines_out) const override;
|
||||
bool no_sort() const override { return true; }
|
||||
};
|
||||
|
||||
}; // namespace FillAdaptive
|
||||
|
@ -37,6 +37,8 @@ public:
|
||||
struct FillParams
|
||||
{
|
||||
bool full_infill() const { return density > 0.9999f && density < 1.0001f; }
|
||||
// Don't connect the fill lines around the inner perimeter.
|
||||
bool dont_connect() const { return anchor_length < 0.05f || connection == InfillConnection::icNotConnected; }
|
||||
|
||||
// Fill density, fraction in <0, 1>
|
||||
float density { 0.f };
|
||||
@ -47,6 +49,10 @@ struct FillParams
|
||||
// Don't connect the fill lines around the inner perimeter.
|
||||
InfillConnection connection{ icConnected };
|
||||
|
||||
// Length of an infill anchor along the perimeter.
|
||||
// 1000mm is roughly the maximum length line that fits into a 32bit coord_t.
|
||||
float anchor_length { 1000.f };
|
||||
|
||||
// Don't adjust spacing to fill the space evenly.
|
||||
bool dont_adjust { true };
|
||||
|
||||
@ -101,6 +107,7 @@ protected:
|
||||
|
||||
public:
|
||||
virtual ~Fill() {}
|
||||
virtual Fill* clone() const = 0;
|
||||
|
||||
static Fill* new_from_type(const InfillPattern type);
|
||||
static Fill* new_from_type(const std::string &type);
|
||||
@ -118,7 +125,6 @@ public:
|
||||
// Perform the fill.
|
||||
virtual Polylines fill_surface(const Surface *surface, const FillParams ¶ms) const;
|
||||
|
||||
virtual Fill* clone() const = 0;
|
||||
protected:
|
||||
Fill() :
|
||||
layer_id(size_t(-1)),
|
||||
@ -135,11 +141,11 @@ protected:
|
||||
{}
|
||||
|
||||
// The expolygon may be modified by the method to avoid a copy.
|
||||
virtual void _fill_surface_single(
|
||||
virtual void _fill_surface_single(
|
||||
const FillParams & /* params */,
|
||||
unsigned int /* thickness_layers */,
|
||||
const std::pair<float, Point> & /* direction */,
|
||||
ExPolygon & /* expolygon */,
|
||||
ExPolygon /* expolygon */,
|
||||
Polylines & /* polylines_out */) const {
|
||||
BOOST_LOG_TRIVIAL(error)<<"Error, the fill isn't implemented";
|
||||
};
|
||||
@ -166,7 +172,9 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
static void connect_infill(Polylines &&infill_ordered, const ExPolygon &boundary, Polylines &polylines_out, double spacing, const FillParams ¶ms);
|
||||
static void connect_infill(Polylines &&infill_ordered, const ExPolygon &boundary, Polylines &polylines_out, const double spacing, const FillParams ¶ms);
|
||||
static void connect_infill(Polylines &&infill_ordered, const Polygons &boundary, const BoundingBox& bbox, Polylines &polylines_out, const double spacing, const FillParams ¶ms);
|
||||
static void connect_infill(Polylines &&infill_ordered, const std::vector<const Polygon*> &boundary, const BoundingBox &bbox, Polylines &polylines_out, double spacing, const FillParams ¶ms);
|
||||
|
||||
static coord_t _adjust_solid_spacing(const coord_t width, const coord_t distance);
|
||||
|
||||
|
@ -23,7 +23,7 @@ FillConcentric::_fill_surface_single(
|
||||
const FillParams ¶ms,
|
||||
unsigned int thickness_layers,
|
||||
const std::pair<float, Point> &direction,
|
||||
ExPolygon &expolygon,
|
||||
ExPolygon expolygon,
|
||||
Polylines &polylines_out) const
|
||||
{
|
||||
// no rotation is supported for this infill pattern
|
||||
|
@ -8,19 +8,19 @@ namespace Slic3r {
|
||||
class FillConcentric : public Fill
|
||||
{
|
||||
public:
|
||||
virtual ~FillConcentric() {}
|
||||
~FillConcentric() override {}
|
||||
|
||||
protected:
|
||||
virtual Fill* clone() const { return new FillConcentric(*this); };
|
||||
Fill* clone() const override { return new FillConcentric(*this); };
|
||||
void init_spacing(coordf_t spacing, const FillParams ¶ms) override;
|
||||
virtual void _fill_surface_single(
|
||||
void _fill_surface_single(
|
||||
const FillParams ¶ms,
|
||||
unsigned int thickness_layers,
|
||||
const std::pair<float, Point> &direction,
|
||||
ExPolygon &expolygon,
|
||||
ExPolygon expolygon,
|
||||
Polylines &polylines_out) const override;
|
||||
|
||||
virtual bool no_sort() const { return true; }
|
||||
bool no_sort() const override { return true; }
|
||||
};
|
||||
|
||||
|
||||
@ -29,10 +29,10 @@ public:
|
||||
virtual ~FillConcentricWGapFill() {}
|
||||
|
||||
protected:
|
||||
virtual Fill* clone() const { return new FillConcentricWGapFill(*this); };
|
||||
virtual void fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, ExtrusionEntitiesPtr &out) const override;
|
||||
Fill* clone() const override { return new FillConcentricWGapFill(*this); };
|
||||
void fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, ExtrusionEntitiesPtr &out) const override;
|
||||
|
||||
virtual bool no_sort() const { return true; }
|
||||
bool no_sort() const override { return true; }
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
|
@ -41,7 +41,7 @@ static inline Polyline make_wave(
|
||||
|
||||
size_t n = points.size();
|
||||
do {
|
||||
points.emplace_back(Vec2d(points[points.size()-n](0) + period, points[points.size()-n](1)));
|
||||
points.emplace_back(points[points.size()-n].x() + period, points[points.size()-n].y());
|
||||
} while (points.back()(0) < width - EPSILON);
|
||||
|
||||
points.emplace_back(Vec2d(width, f(width, z_sin, z_cos, vertical, flip)));
|
||||
@ -151,7 +151,7 @@ void FillGyroid::_fill_surface_single(
|
||||
const FillParams ¶ms,
|
||||
unsigned int thickness_layers,
|
||||
const std::pair<float, Point> &direction,
|
||||
ExPolygon &expolygon,
|
||||
ExPolygon expolygon,
|
||||
Polylines &polylines_out) const
|
||||
{
|
||||
float infill_angle = float(this->angle + (CorrectionAngle * 2 * M_PI) / 360.f);
|
||||
@ -189,11 +189,10 @@ void FillGyroid::_fill_surface_single(
|
||||
polylines.end());
|
||||
|
||||
if (! polylines.empty()) {
|
||||
polylines = chain_polylines(polylines);
|
||||
// connect lines
|
||||
size_t polylines_out_first_idx = polylines_out.size();
|
||||
if (params.connection == icNotConnected){
|
||||
append(polylines_out, std::move(polylines));
|
||||
append(polylines_out, chain_polylines(polylines));
|
||||
} else {
|
||||
this->connect_infill(std::move(polylines), expolygon, polylines_out, this->get_spacing(), params);
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ class FillGyroid : public Fill
|
||||
{
|
||||
public:
|
||||
FillGyroid() {}
|
||||
virtual Fill* clone() const { return new FillGyroid(*this); }
|
||||
Fill* clone() const override { return new FillGyroid(*this); }
|
||||
|
||||
// Correction applied to regular infill angle to maximize printing
|
||||
// speed in default configuration (degrees)
|
||||
@ -25,11 +25,11 @@ public:
|
||||
|
||||
|
||||
protected:
|
||||
virtual void _fill_surface_single(
|
||||
void _fill_surface_single(
|
||||
const FillParams ¶ms,
|
||||
unsigned int thickness_layers,
|
||||
const std::pair<float, Point> &direction,
|
||||
ExPolygon &expolygon,
|
||||
ExPolygon expolygon,
|
||||
Polylines &polylines_out) const override;
|
||||
};
|
||||
|
||||
|
@ -12,7 +12,7 @@ void FillHoneycomb::_fill_surface_single(
|
||||
const FillParams ¶ms,
|
||||
unsigned int thickness_layers,
|
||||
const std::pair<float, Point> &direction,
|
||||
ExPolygon &expolygon,
|
||||
ExPolygon expolygon,
|
||||
Polylines &polylines_out) const
|
||||
{
|
||||
// cache hexagons math
|
||||
@ -21,20 +21,20 @@ void FillHoneycomb::_fill_surface_single(
|
||||
if (it_m == FillHoneycomb::cache.end()) {
|
||||
it_m = FillHoneycomb::cache.insert(it_m, std::pair<CacheID, CacheData>(cache_id, CacheData()));
|
||||
CacheData &m = it_m->second;
|
||||
coord_t min_spacing = scale_(this->get_spacing());
|
||||
m.distance = coord_t(double(min_spacing) / params.density);
|
||||
m.hex_side = coord_t(double(m.distance) / (sqrt(3)/2));
|
||||
coord_t min_spacing = coord_t(scale_(this->get_spacing()));
|
||||
m.distance = coord_t(double(min_spacing) / params.density);
|
||||
m.hex_side = coord_t(double(m.distance) / (sqrt(3)/2));
|
||||
m.hex_width = m.distance * 2; // $m->{hex_width} == $m->{hex_side} * sqrt(3);
|
||||
coord_t hex_height = m.hex_side * 2;
|
||||
m.pattern_height = hex_height + m.hex_side;
|
||||
m.y_short = coord_t(double(m.distance) * sqrt(3)/3);
|
||||
m.y_short = coord_t(double(m.distance) * sqrt(3)/3);
|
||||
m.x_offset = min_spacing / 2;
|
||||
m.y_offset = coord_t(double(m.x_offset) * sqrt(3)/3);
|
||||
m.y_offset = coord_t(double(m.x_offset) * sqrt(3)/3);
|
||||
m.hex_center = Point(m.hex_width/2, m.hex_side);
|
||||
}
|
||||
CacheData &m = it_m->second;
|
||||
|
||||
Polygons polygons;
|
||||
Polylines all_polylines;
|
||||
{
|
||||
// adjust actual bounding box to the nearest multiple of our hex pattern
|
||||
// and align it so that it matches across layers
|
||||
@ -54,7 +54,7 @@ void FillHoneycomb::_fill_surface_single(
|
||||
|
||||
coord_t x = bounding_box.min(0);
|
||||
while (x <= bounding_box.max(0)) {
|
||||
Polygon p;
|
||||
Polyline p;
|
||||
coord_t ax[2] = { x + m.x_offset, x + m.distance - m.x_offset };
|
||||
for (size_t i = 0; i < 2; ++ i) {
|
||||
std::reverse(p.points.begin(), p.points.end()); // turn first half upside down
|
||||
@ -71,55 +71,15 @@ void FillHoneycomb::_fill_surface_single(
|
||||
x += m.distance;
|
||||
}
|
||||
p.rotate(-direction.first, m.hex_center);
|
||||
polygons.push_back(p);
|
||||
all_polylines.push_back(p);
|
||||
}
|
||||
}
|
||||
|
||||
if (params.complete || true) {
|
||||
// we were requested to complete each loop;
|
||||
// in this case we don't try to make more continuous paths
|
||||
Polygons polygons_trimmed = intersection((Polygons)expolygon, polygons);
|
||||
for (Polygons::iterator it = polygons_trimmed.begin(); it != polygons_trimmed.end(); ++ it)
|
||||
polylines_out.push_back(it->split_at_first_point());
|
||||
} else {
|
||||
// consider polygons as polylines without re-appending the initial point:
|
||||
// this cuts the last segment on purpose, so that the jump to the next
|
||||
// path is more straight
|
||||
Polylines paths;
|
||||
{
|
||||
Polylines p;
|
||||
for (Polygon &poly : polygons)
|
||||
p.emplace_back(poly.points);
|
||||
paths = intersection_pl(p, to_polygons(expolygon));
|
||||
}
|
||||
|
||||
// connect paths
|
||||
if (! paths.empty()) { // prevent calling leftmost_point() on empty collections
|
||||
Polylines chained = chain_polylines(std::move(paths));
|
||||
assert(paths.empty());
|
||||
paths.clear();
|
||||
for (Polyline &path : chained) {
|
||||
if (! paths.empty()) {
|
||||
// distance between first point of this path and last point of last path
|
||||
double distance = (path.first_point() - paths.back().last_point()).cast<double>().norm();
|
||||
if (distance <= m.hex_width) {
|
||||
paths.back().points.insert(paths.back().points.end(), path.points.begin(), path.points.end());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Don't connect the paths.
|
||||
paths.push_back(std::move(path));
|
||||
}
|
||||
}
|
||||
|
||||
// clip paths again to prevent connection segments from crossing the expolygon boundaries
|
||||
paths = intersection_pl(paths, to_polygons(offset_ex(expolygon, (double)SCALED_EPSILON)));
|
||||
// Move the polylines to the output, avoid a deep copy.
|
||||
size_t j = polylines_out.size();
|
||||
polylines_out.resize(j + paths.size(), Polyline());
|
||||
for (size_t i = 0; i < paths.size(); ++ i)
|
||||
std::swap(polylines_out[j ++], paths[i]);
|
||||
}
|
||||
all_polylines = intersection_pl(std::move(all_polylines), to_polygons(expolygon));
|
||||
if (params.connection == icNotConnected || all_polylines.size() <= 1)
|
||||
append(polylines_out, chain_polylines(std::move(all_polylines)));
|
||||
else
|
||||
connect_infill(std::move(all_polylines), expolygon, polylines_out, this->get_spacing(), params);
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
@ -12,15 +12,15 @@ namespace Slic3r {
|
||||
class FillHoneycomb : public Fill
|
||||
{
|
||||
public:
|
||||
virtual ~FillHoneycomb() {}
|
||||
~FillHoneycomb() override {}
|
||||
|
||||
protected:
|
||||
virtual Fill* clone() const { return new FillHoneycomb(*this); };
|
||||
virtual void _fill_surface_single(
|
||||
Fill* clone() const override { return new FillHoneycomb(*this); };
|
||||
void _fill_surface_single(
|
||||
const FillParams ¶ms,
|
||||
unsigned int thickness_layers,
|
||||
const std::pair<float, Point> &direction,
|
||||
ExPolygon &expolygon,
|
||||
ExPolygon expolygon,
|
||||
Polylines &polylines_out) const override;
|
||||
|
||||
// Caching the
|
||||
@ -49,7 +49,7 @@ protected:
|
||||
typedef std::map<CacheID, CacheData> Cache;
|
||||
static Cache cache;
|
||||
|
||||
virtual float _layer_angle(size_t idx) const { return float(M_PI/3.) * (idx % 3); }
|
||||
float _layer_angle(size_t idx) const override { return float(M_PI/3.) * (idx % 3); }
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
|
136
src/libslic3r/Fill/FillLine.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
#include "../ClipperUtils.hpp"
|
||||
#include "../ExPolygon.hpp"
|
||||
#include "../ShortestPath.hpp"
|
||||
#include "../Surface.hpp"
|
||||
|
||||
#include "FillLine.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
void FillLine::init_spacing(coordf_t spacing, const FillParams& params) {
|
||||
|
||||
this->_min_spacing = scale_(spacing);
|
||||
assert(params.density > 0.0001f && params.density <= 1.f);
|
||||
this->_line_spacing = coord_t(coordf_t(this->_min_spacing) / params.density);
|
||||
this->_diagonal_distance = this->_line_spacing * 2;
|
||||
this->_line_oscillation = this->_line_spacing - this->_min_spacing; // only for Line infill
|
||||
|
||||
// define flow spacing according to requested density
|
||||
if (params.density > 0.9999f && !params.dont_adjust) {
|
||||
this->_line_spacing = this->_adjust_solid_spacing(bounding_box.size()(0), this->_line_spacing);
|
||||
this->spacing_priv = unscale<double>(this->_line_spacing);
|
||||
}
|
||||
}
|
||||
|
||||
void FillLine::_fill_surface_single(
|
||||
const FillParams ¶ms,
|
||||
unsigned int thickness_layers,
|
||||
const std::pair<float, Point> &direction,
|
||||
ExPolygon expolygon,
|
||||
Polylines &polylines_out) const
|
||||
{
|
||||
//Quick hack to put it at a sane position.
|
||||
//FIXME for real
|
||||
ExPolygons polys = offset_ex(to_polygons(expolygon), -this->_min_spacing*(1- 0.3/*INFILL_OVERLAP_OVER_SPACING*/));
|
||||
if (polys.size() == 1)
|
||||
expolygon = polys[0];
|
||||
|
||||
// rotate polygons so that we can work with vertical lines here
|
||||
expolygon.rotate(- direction.first);
|
||||
|
||||
BoundingBox bounding_box = expolygon.contour.bounding_box();
|
||||
|
||||
if (params.density > 0.9999f && !params.dont_adjust) {
|
||||
//cf init_spacing
|
||||
} else {
|
||||
// extend bounding box so that our pattern will be aligned with other layers
|
||||
// Transform the reference point to the rotated coordinate system.
|
||||
bounding_box.merge(_align_to_grid(
|
||||
bounding_box.min,
|
||||
Point(this->_line_spacing, this->_line_spacing),
|
||||
direction.second.rotated(-direction.first)));
|
||||
}
|
||||
|
||||
// generate the basic pattern
|
||||
coord_t x_max = bounding_box.max(0) + SCALED_EPSILON;
|
||||
Lines lines;
|
||||
for (coord_t x = bounding_box.min(0); x <= x_max; x += this->_line_spacing)
|
||||
lines.push_back(this->_line(lines.size(), x, bounding_box.min(1), bounding_box.max(1)));
|
||||
|
||||
// clip paths against a slightly larger expolygon, so that the first and last paths
|
||||
// are kept even if the expolygon has vertical sides
|
||||
// the minimum offset for preventing edge lines from being clipped is SCALED_EPSILON;
|
||||
// however we use a larger offset to support expolygons with slightly skewed sides and
|
||||
// not perfectly straight
|
||||
//FIXME Vojtech: Update the intersecton function to work directly with lines.
|
||||
Polylines polylines_src;
|
||||
polylines_src.reserve(lines.size());
|
||||
for (Lines::const_iterator it = lines.begin(); it != lines.end(); ++ it) {
|
||||
polylines_src.push_back(Polyline());
|
||||
Points &pts = polylines_src.back().points;
|
||||
pts.reserve(2);
|
||||
pts.push_back(it->a);
|
||||
pts.push_back(it->b);
|
||||
}
|
||||
Polylines polylines = intersection_pl(polylines_src, offset(to_polygons(expolygon), scale_(0.02)), false);
|
||||
|
||||
// FIXME Vojtech: This is only performed for horizontal lines, not for the vertical lines!
|
||||
const float INFILL_OVERLAP_OVER_SPACING = 0.3f;
|
||||
// How much to extend an infill path from expolygon outside?
|
||||
coord_t extra = coord_t(floor(this->_min_spacing * INFILL_OVERLAP_OVER_SPACING + 0.5f));
|
||||
for (Polylines::iterator it_polyline = polylines.begin(); it_polyline != polylines.end(); ++ it_polyline) {
|
||||
Point *first_point = &it_polyline->points.front();
|
||||
Point *last_point = &it_polyline->points.back();
|
||||
if (first_point->y() > last_point->y())
|
||||
std::swap(first_point, last_point);
|
||||
first_point->y() -= extra;
|
||||
last_point->y() += extra;
|
||||
}
|
||||
|
||||
size_t n_polylines_out_old = polylines_out.size();
|
||||
|
||||
// connect lines
|
||||
if (! params.dont_connect() && ! polylines.empty()) { // prevent calling leftmost_point() on empty collections
|
||||
// offset the expolygon by max(min_spacing/2, extra)
|
||||
ExPolygon expolygon_off;
|
||||
{
|
||||
ExPolygons expolygons_off = offset_ex(expolygon, this->_min_spacing/2);
|
||||
if (! expolygons_off.empty()) {
|
||||
// When expanding a polygon, the number of islands could only shrink. Therefore the offset_ex shall generate exactly one expanded island for one input island.
|
||||
assert(expolygons_off.size() == 1);
|
||||
std::swap(expolygon_off, expolygons_off.front());
|
||||
}
|
||||
}
|
||||
bool first = true;
|
||||
for (Polyline &polyline : chain_polylines(std::move(polylines))) {
|
||||
if (! first) {
|
||||
// Try to connect the lines.
|
||||
Points &pts_end = polylines_out.back().points;
|
||||
const Point &first_point = polyline.points.front();
|
||||
const Point &last_point = pts_end.back();
|
||||
// Distance in X, Y.
|
||||
const Vector distance = last_point - first_point;
|
||||
// TODO: we should also check that both points are on a fill_boundary to avoid
|
||||
// connecting paths on the boundaries of internal regions
|
||||
if (this->_can_connect(std::abs(distance(0)), std::abs(distance(1))) &&
|
||||
expolygon_off.contains(Line(last_point, first_point))) {
|
||||
// Append the polyline.
|
||||
pts_end.insert(pts_end.end(), polyline.points.begin(), polyline.points.end());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// The lines cannot be connected.
|
||||
polylines_out.emplace_back(std::move(polyline));
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
// paths must be rotated back
|
||||
for (Polylines::iterator it = polylines_out.begin() + n_polylines_out_old; it != polylines_out.end(); ++ it) {
|
||||
// No need to translate, the absolute position is irrelevant.
|
||||
// it->translate(- direction.second(0), - direction.second(1));
|
||||
it->rotate(direction.first);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
50
src/libslic3r/Fill/FillLine.hpp
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef slic3r_FillLine_hpp_
|
||||
#define slic3r_FillLine_hpp_
|
||||
|
||||
#include "../libslic3r.h"
|
||||
|
||||
#include "FillBase.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class Surface;
|
||||
|
||||
class FillLine : public Fill
|
||||
{
|
||||
public:
|
||||
Fill* clone() const override { return new FillLine(*this); };
|
||||
~FillLine() override = default;
|
||||
|
||||
void init_spacing(coordf_t spacing, const FillParams& params) override;
|
||||
protected:
|
||||
void _fill_surface_single(
|
||||
const FillParams ¶ms,
|
||||
unsigned int thickness_layers,
|
||||
const std::pair<float, Point> &direction,
|
||||
ExPolygon expolygon,
|
||||
Polylines &polylines_out) const override;
|
||||
|
||||
coord_t _min_spacing;
|
||||
coord_t _line_spacing;
|
||||
// distance threshold for allowing the horizontal infill lines to be connected into a continuous path
|
||||
coord_t _diagonal_distance;
|
||||
// only for line infill
|
||||
coord_t _line_oscillation;
|
||||
|
||||
Line _line(int i, coord_t x, coord_t y_min, coord_t y_max) const {
|
||||
coord_t osc = (i & 1) ? this->_line_oscillation : 0;
|
||||
return Line(Point(x - osc, y_min), Point(x + osc, y_max));
|
||||
}
|
||||
|
||||
bool _can_connect(coord_t dist_X, coord_t dist_Y) const
|
||||
{
|
||||
coord_t TOLERANCE = 10 * SCALED_EPSILON;
|
||||
return (dist_X >= (this->_line_spacing - this->_line_oscillation) - TOLERANCE)
|
||||
&& (dist_X <= (this->_line_spacing + this->_line_oscillation) + TOLERANCE)
|
||||
&& (dist_Y <= this->_diagonal_distance);
|
||||
}
|
||||
};
|
||||
|
||||
}; // namespace Slic3r
|
||||
|
||||
#endif // slic3r_FillLine_hpp_
|
@ -1,4 +1,5 @@
|
||||
#include "../ClipperUtils.hpp"
|
||||
#include "../ShortestPath.hpp"
|
||||
#include "../Surface.hpp"
|
||||
|
||||
#include "FillPlanePath.hpp"
|
||||
@ -9,7 +10,7 @@ void FillPlanePath::_fill_surface_single(
|
||||
const FillParams ¶ms,
|
||||
unsigned int thickness_layers,
|
||||
const std::pair<float, Point> &direction,
|
||||
ExPolygon &expolygon,
|
||||
ExPolygon expolygon,
|
||||
Polylines &polylines_out) const
|
||||
{
|
||||
expolygon.rotate(- direction.first);
|
||||
@ -27,10 +28,10 @@ void FillPlanePath::_fill_surface_single(
|
||||
bounding_box.translate(-double(shift.x()), -double(shift.y()));
|
||||
|
||||
Pointfs pts = _generate(
|
||||
coord_t(ceil(coordf_t(bounding_box.min(0)) / distance_between_lines)),
|
||||
coord_t(ceil(coordf_t(bounding_box.min(1)) / distance_between_lines)),
|
||||
coord_t(ceil(coordf_t(bounding_box.max(0)) / distance_between_lines)),
|
||||
coord_t(ceil(coordf_t(bounding_box.max(1)) / distance_between_lines)));
|
||||
coord_t(ceil(coordf_t(bounding_box.min.x()) / distance_between_lines)),
|
||||
coord_t(ceil(coordf_t(bounding_box.min.y()) / distance_between_lines)),
|
||||
coord_t(ceil(coordf_t(bounding_box.max.x()) / distance_between_lines)),
|
||||
coord_t(ceil(coordf_t(bounding_box.max.y()) / distance_between_lines)));
|
||||
|
||||
Polylines polylines;
|
||||
if (pts.size() >= 2) {
|
||||
@ -38,39 +39,24 @@ void FillPlanePath::_fill_surface_single(
|
||||
polylines.push_back(Polyline());
|
||||
Polyline &polyline = polylines.back();
|
||||
polyline.points.reserve(pts.size());
|
||||
for (Pointfs::iterator it = pts.begin(); it != pts.end(); ++ it)
|
||||
for (const Vec2d &pt : pts)
|
||||
polyline.points.push_back(Point(
|
||||
coord_t(floor((*it)(0) * distance_between_lines + 0.5)),
|
||||
coord_t(floor((*it)(1) * distance_between_lines + 0.5))));
|
||||
coord_t(floor(pt.x() * distance_between_lines + 0.5)),
|
||||
coord_t(floor(pt.y() * distance_between_lines + 0.5))));
|
||||
// intersection(polylines_src, offset((Polygons)expolygon, scale_(0.02)), &polylines);
|
||||
polylines = intersection_pl(polylines, to_polygons(expolygon));
|
||||
|
||||
/*
|
||||
if (1) {
|
||||
require "Slic3r/SVG.pm";
|
||||
print "Writing fill.svg\n";
|
||||
Slic3r::SVG::output("fill.svg",
|
||||
no_arrows => 1,
|
||||
polygons => \@$expolygon,
|
||||
green_polygons => [ $bounding_box->polygon ],
|
||||
polylines => [ $polyline ],
|
||||
red_polylines => \@paths,
|
||||
);
|
||||
}
|
||||
*/
|
||||
|
||||
polylines = intersection_pl(std::move(polylines), to_polygons(expolygon));
|
||||
Polylines chained;
|
||||
if (params.dont_connect() || params.density > 0.5 || polylines.size() <= 1)
|
||||
chained = chain_polylines(std::move(polylines));
|
||||
else
|
||||
connect_infill(std::move(polylines), expolygon, chained, this->get_spacing(), params);
|
||||
// paths must be repositioned and rotated back
|
||||
for (Polylines::iterator it = polylines.begin(); it != polylines.end(); ++ it) {
|
||||
it->translate(double(shift.x()), double(shift.y()));
|
||||
it->rotate(direction.first);
|
||||
for (Polyline &pl : chained) {
|
||||
pl.translate(double(shift.x()), double(shift.y()));
|
||||
pl.rotate(direction.first);
|
||||
}
|
||||
append(polylines_out, std::move(chained));
|
||||
}
|
||||
|
||||
// Move the polylines to the output, avoid a deep copy.
|
||||
size_t j = polylines_out.size();
|
||||
polylines_out.resize(j + polylines.size(), Polyline());
|
||||
for (size_t i = 0; i < polylines.size(); ++ i)
|
||||
std::swap(polylines_out[j ++], polylines[i]);
|
||||
}
|
||||
|
||||
// Follow an Archimedean spiral, in polar coordinates: r=a+b\theta
|
||||
@ -85,13 +71,13 @@ Pointfs FillArchimedeanChords::_generate(coord_t min_x, coord_t min_y, coord_t m
|
||||
coordf_t r = 1;
|
||||
Pointfs out;
|
||||
//FIXME Vojtech: If used as a solid infill, there is a gap left at the center.
|
||||
out.push_back(Vec2d(0, 0));
|
||||
out.push_back(Vec2d(1, 0));
|
||||
out.emplace_back(0, 0);
|
||||
out.emplace_back(1, 0);
|
||||
while (r < rmax) {
|
||||
// Discretization angle to achieve a discretization error lower than RESOLUTION.
|
||||
theta += 2. * acos(1. - RESOLUTION / r);
|
||||
r = a + b * theta;
|
||||
out.push_back(Vec2d(r * cos(theta), r * sin(theta)));
|
||||
out.emplace_back(r * cos(theta), r * sin(theta));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@ -129,14 +115,11 @@ static inline Point hilbert_n_to_xy(const size_t n)
|
||||
}
|
||||
}
|
||||
int state = (ndigits & 1) ? 4 : 0;
|
||||
// int dirstate = (ndigits & 1) ? 0 : 4;
|
||||
coord_t x = 0;
|
||||
coord_t y = 0;
|
||||
for (int i = (int)ndigits - 1; i >= 0; -- i) {
|
||||
int digit = (n >> (i * 2)) & 3;
|
||||
state += digit;
|
||||
// if (digit != 3)
|
||||
// dirstate = state; // lowest non-3 digit
|
||||
x |= digit_to_x[state] << i;
|
||||
y |= digit_to_y[state] << i;
|
||||
state = next_state[state];
|
||||
@ -162,7 +145,7 @@ Pointfs FillHilbertCurve::_generate(coord_t min_x, coord_t min_y, coord_t max_x,
|
||||
line.reserve(sz2);
|
||||
for (size_t i = 0; i < sz2; ++ i) {
|
||||
Point p = hilbert_n_to_xy(i);
|
||||
line.push_back(Vec2d(p(0) + min_x, p(1) + min_y));
|
||||
line.emplace_back(p.x() + min_x, p.y() + min_y);
|
||||
}
|
||||
return line;
|
||||
}
|
||||
@ -175,27 +158,27 @@ Pointfs FillOctagramSpiral::_generate(coord_t min_x, coord_t min_y, coord_t max_
|
||||
coordf_t r = 0;
|
||||
coordf_t r_inc = sqrt(2.);
|
||||
Pointfs out;
|
||||
out.push_back(Vec2d(0, 0));
|
||||
out.emplace_back(0., 0.);
|
||||
while (r < rmax) {
|
||||
r += r_inc;
|
||||
coordf_t rx = r / sqrt(2.);
|
||||
coordf_t r2 = r + rx;
|
||||
out.push_back(Vec2d( r, 0.));
|
||||
out.push_back(Vec2d( r2, rx));
|
||||
out.push_back(Vec2d( rx, rx));
|
||||
out.push_back(Vec2d( rx, r2));
|
||||
out.push_back(Vec2d(0., r));
|
||||
out.push_back(Vec2d(-rx, r2));
|
||||
out.push_back(Vec2d(-rx, rx));
|
||||
out.push_back(Vec2d(-r2, rx));
|
||||
out.push_back(Vec2d(-r, 0.));
|
||||
out.push_back(Vec2d(-r2, -rx));
|
||||
out.push_back(Vec2d(-rx, -rx));
|
||||
out.push_back(Vec2d(-rx, -r2));
|
||||
out.push_back(Vec2d(0., -r));
|
||||
out.push_back(Vec2d( rx, -r2));
|
||||
out.push_back(Vec2d( rx, -rx));
|
||||
out.push_back(Vec2d( r2+r_inc, -rx));
|
||||
out.emplace_back( r, 0.);
|
||||
out.emplace_back( r2, rx);
|
||||
out.emplace_back( rx, rx);
|
||||
out.emplace_back( rx, r2);
|
||||
out.emplace_back( 0., r);
|
||||
out.emplace_back(-rx, r2);
|
||||
out.emplace_back(-rx, rx);
|
||||
out.emplace_back(-r2, rx);
|
||||
out.emplace_back(- r, 0.);
|
||||
out.emplace_back(-r2, -rx);
|
||||
out.emplace_back(-rx, -rx);
|
||||
out.emplace_back(-rx, -r2);
|
||||
out.emplace_back( 0., -r);
|
||||
out.emplace_back( rx, -r2);
|
||||
out.emplace_back( rx, -rx);
|
||||
out.emplace_back( r2+r_inc, -rx);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
@ -16,17 +16,17 @@ namespace Slic3r {
|
||||
class FillPlanePath : public Fill
|
||||
{
|
||||
public:
|
||||
virtual ~FillPlanePath() {}
|
||||
~FillPlanePath() override = default;
|
||||
|
||||
protected:
|
||||
virtual void _fill_surface_single(
|
||||
void _fill_surface_single(
|
||||
const FillParams ¶ms,
|
||||
unsigned int thickness_layers,
|
||||
const std::pair<float, Point> &direction,
|
||||
ExPolygon &expolygon,
|
||||
ExPolygon expolygon,
|
||||
Polylines &polylines_out) const override;
|
||||
|
||||
virtual float _layer_angle(size_t idx) const { return 0.f; }
|
||||
float _layer_angle(size_t idx) const override { return 0.f; }
|
||||
virtual bool _centered() const = 0;
|
||||
virtual Pointfs _generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y) const = 0;
|
||||
};
|
||||
@ -34,34 +34,34 @@ protected:
|
||||
class FillArchimedeanChords : public FillPlanePath
|
||||
{
|
||||
public:
|
||||
virtual Fill* clone() const { return new FillArchimedeanChords(*this); };
|
||||
virtual ~FillArchimedeanChords() {}
|
||||
Fill* clone() const override { return new FillArchimedeanChords(*this); };
|
||||
~FillArchimedeanChords() override = default;
|
||||
|
||||
protected:
|
||||
virtual bool _centered() const { return true; }
|
||||
virtual Pointfs _generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y) const;
|
||||
bool _centered() const override { return true; }
|
||||
Pointfs _generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y) const override;
|
||||
};
|
||||
|
||||
class FillHilbertCurve : public FillPlanePath
|
||||
{
|
||||
public:
|
||||
virtual Fill* clone() const { return new FillHilbertCurve(*this); };
|
||||
virtual ~FillHilbertCurve() {}
|
||||
Fill* clone() const override { return new FillHilbertCurve(*this); };
|
||||
~FillHilbertCurve() override = default;
|
||||
|
||||
protected:
|
||||
virtual bool _centered() const { return false; }
|
||||
virtual Pointfs _generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y) const;
|
||||
bool _centered() const override { return false; }
|
||||
Pointfs _generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y) const override;
|
||||
};
|
||||
|
||||
class FillOctagramSpiral : public FillPlanePath
|
||||
{
|
||||
public:
|
||||
virtual Fill* clone() const { return new FillOctagramSpiral(*this); };
|
||||
virtual ~FillOctagramSpiral() {}
|
||||
Fill* clone() const override { return new FillOctagramSpiral(*this); };
|
||||
~FillOctagramSpiral() override = default;
|
||||
|
||||
protected:
|
||||
virtual bool _centered() const { return true; }
|
||||
virtual Pointfs _generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y) const;
|
||||
bool _centered() const override { return true; }
|
||||
Pointfs _generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y) const override;
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
|
@ -8,73 +8,132 @@
|
||||
namespace Slic3r {
|
||||
|
||||
class Surface;
|
||||
class SegmentedIntersectionLine;
|
||||
struct ExPolygonWithOffset;
|
||||
|
||||
class FillRectilinear : public Fill
|
||||
{
|
||||
public:
|
||||
virtual Fill* clone() const { return new FillRectilinear(*this); };
|
||||
virtual ~FillRectilinear() {}
|
||||
Fill* clone() const override { return new FillRectilinear(*this); };
|
||||
~FillRectilinear() override = default;
|
||||
virtual void init_spacing(coordf_t spacing, const FillParams& params) override;
|
||||
Polylines fill_surface(const Surface* surface, const FillParams& params) const override;
|
||||
|
||||
protected:
|
||||
virtual void _fill_surface_single(
|
||||
const FillParams ¶ms,
|
||||
unsigned int thickness_layers,
|
||||
const std::pair<float, Point> &direction,
|
||||
ExPolygon &expolygon,
|
||||
Polylines &polylines_out) const override;
|
||||
virtual std::vector<SegmentedIntersectionLine> _vert_lines_for_polygon(const ExPolygonWithOffset& poly_with_offset, const BoundingBox& bounding_box, const FillParams& params, coord_t line_spacing) const;
|
||||
|
||||
coord_t _min_spacing;
|
||||
coord_t _line_spacing;
|
||||
// distance threshold for allowing the horizontal infill lines to be connected into a continuous path
|
||||
coord_t _diagonal_distance;
|
||||
// only for line infill
|
||||
coord_t _line_oscillation;
|
||||
virtual void init_spacing(coordf_t spacing, const FillParams ¶ms) override;
|
||||
// Fill by single directional lines, interconnect the lines along perimeters.
|
||||
bool fill_surface_by_lines(const Surface* surface, const FillParams& params, float angleBase, float pattern_shift, Polylines& polylines_out) const;
|
||||
|
||||
// Enabled for the grid infill, disabled for the rectilinear and line infill.
|
||||
virtual bool _horizontal_lines() const { return false; }
|
||||
|
||||
virtual Line _line(int i, coord_t x, coord_t y_min, coord_t y_max) const
|
||||
{ return Line(Point(x, y_min), Point(x, y_max)); }
|
||||
|
||||
virtual bool _can_connect(coord_t dist_X, coord_t dist_Y) const {
|
||||
return dist_X <= this->_diagonal_distance
|
||||
&& dist_Y <= this->_diagonal_distance;
|
||||
}
|
||||
// Fill by multiple sweeps of differing directions.
|
||||
struct SweepParams {
|
||||
float angle_base;
|
||||
float pattern_shift;
|
||||
};
|
||||
bool fill_surface_by_multilines(const Surface* surface, FillParams params, const std::initializer_list<SweepParams>& sweep_params, Polylines& polylines_out) const;
|
||||
};
|
||||
|
||||
class FillLine : public FillRectilinear
|
||||
class FillMonotonic : public FillRectilinear
|
||||
{
|
||||
public:
|
||||
virtual ~FillLine() {}
|
||||
|
||||
protected:
|
||||
virtual Line _line(int i, coord_t x, coord_t y_min, coord_t y_max) const override {
|
||||
coord_t osc = (i & 1) ? this->_line_oscillation : 0;
|
||||
return Line(Point(x - osc, y_min), Point(x + osc, y_max));
|
||||
}
|
||||
|
||||
virtual bool _can_connect(coord_t dist_X, coord_t dist_Y) const override
|
||||
{
|
||||
double TOLERANCE = 10 * SCALED_EPSILON;
|
||||
return (dist_X >= (this->_line_spacing - this->_line_oscillation) - TOLERANCE)
|
||||
&& (dist_X <= (this->_line_spacing + this->_line_oscillation) + TOLERANCE)
|
||||
&& (dist_Y <= this->_diagonal_distance);
|
||||
}
|
||||
Fill* clone() const override { return new FillMonotonic(*this); };
|
||||
~FillMonotonic() override = default;
|
||||
Polylines fill_surface(const Surface* surface, const FillParams& params) const override;
|
||||
bool no_sort() const override { return true; }
|
||||
};
|
||||
|
||||
class FillGrid : public FillRectilinear
|
||||
{
|
||||
public:
|
||||
virtual ~FillGrid() {}
|
||||
Fill* clone() const override { return new FillGrid(*this); };
|
||||
~FillGrid() override = default;
|
||||
Polylines fill_surface(const Surface* surface, const FillParams& params) const override;
|
||||
|
||||
protected:
|
||||
// The grid fill will keep the angle constant between the layers, see the implementation of Slic3r::Fill.
|
||||
virtual float _layer_angle(size_t idx) const override { return 0.f; }
|
||||
// Flag for Slic3r::Fill::Rectilinear to fill both directions.
|
||||
virtual bool _horizontal_lines() const override { return true; }
|
||||
// The grid fill will keep the angle constant between the layers, see the implementation of Slic3r::Fill.
|
||||
float _layer_angle(size_t idx) const override { return 0.f; }
|
||||
};
|
||||
|
||||
class FillTriangles : public FillRectilinear
|
||||
{
|
||||
public:
|
||||
Fill* clone() const override { return new FillTriangles(*this); };
|
||||
~FillTriangles() override = default;
|
||||
Polylines fill_surface(const Surface* surface, const FillParams& params) const override;
|
||||
|
||||
protected:
|
||||
// The grid fill will keep the angle constant between the layers, see the implementation of Slic3r::Fill.
|
||||
float _layer_angle(size_t idx) const override { return 0.f; }
|
||||
};
|
||||
|
||||
class FillStars : public FillRectilinear
|
||||
{
|
||||
public:
|
||||
Fill* clone() const override { return new FillStars(*this); };
|
||||
~FillStars() override = default;
|
||||
Polylines fill_surface(const Surface* surface, const FillParams& params) const override;
|
||||
|
||||
protected:
|
||||
// The grid fill will keep the angle constant between the layers, see the implementation of Slic3r::Fill.
|
||||
float _layer_angle(size_t idx) const override { return 0.f; }
|
||||
};
|
||||
|
||||
class FillCubic : public FillRectilinear
|
||||
{
|
||||
public:
|
||||
Fill* clone() const override { return new FillCubic(*this); };
|
||||
~FillCubic() override = default;
|
||||
Polylines fill_surface(const Surface* surface, const FillParams& params) const override;
|
||||
|
||||
protected:
|
||||
// The grid fill will keep the angle constant between the layers, see the implementation of Slic3r::Fill.
|
||||
float _layer_angle(size_t idx) const override { return 0.f; }
|
||||
};
|
||||
|
||||
class FillRectilinearPeri : public FillRectilinear
|
||||
{
|
||||
public:
|
||||
Fill* clone() const override { return new FillRectilinearPeri(*this); };
|
||||
~FillRectilinearPeri() override = default;
|
||||
//Polylines fill_surface(const Surface *surface, const FillParams ¶ms);
|
||||
void fill_surface_extrusion(const Surface* surface, const FillParams& params, ExtrusionEntitiesPtr& out) const override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class FillScatteredRectilinear : public FillRectilinear
|
||||
{
|
||||
public:
|
||||
Fill* clone() const override { return new FillScatteredRectilinear(*this); };
|
||||
~FillScatteredRectilinear() override = default;
|
||||
Polylines fill_surface(const Surface* surface, const FillParams& params) const override;
|
||||
|
||||
protected:
|
||||
float _layer_angle(size_t idx) const override;
|
||||
std::vector<SegmentedIntersectionLine> _vert_lines_for_polygon(const ExPolygonWithOffset& poly_with_offset, const BoundingBox& bounding_box, const FillParams& params, coord_t line_spacing) const override;
|
||||
coord_t _line_spacing_for_density(float density) const override;
|
||||
};
|
||||
|
||||
class FillRectilinearSawtooth : public FillRectilinear {
|
||||
public:
|
||||
|
||||
Fill* clone() const override { return new FillRectilinearSawtooth(*this); };
|
||||
~FillRectilinearSawtooth() override = default;
|
||||
void fill_surface_extrusion(const Surface* surface, const FillParams& params, ExtrusionEntitiesPtr& out) const override;
|
||||
|
||||
};
|
||||
|
||||
class FillRectilinearWGapFill : public FillRectilinear
|
||||
{
|
||||
public:
|
||||
|
||||
Fill* clone() const override { return new FillRectilinearWGapFill(*this); };
|
||||
~FillRectilinearWGapFill() override = default;
|
||||
void fill_surface_extrusion(const Surface* surface, const FillParams& params, ExtrusionEntitiesPtr& out) const override;
|
||||
static void split_polygon_gap_fill(const Surface& surface, const FillParams& params, ExPolygons& rectilinear, ExPolygons& gapfill);
|
||||
};
|
||||
|
||||
|
||||
}; // namespace Slic3r
|
||||
|
||||
#endif // slic3r_FillRectilinear_hpp_
|
||||
|