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
This commit is contained in:
supermerill 2020-11-23 00:28:47 +01:00
commit 1a19b023f0
214 changed files with 39875 additions and 31593 deletions

BIN
PrusaSlicer.mo Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 42 KiB

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

View 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();
}

View File

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

View File

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

View File

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

View File

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

View File

@ -8,4 +8,5 @@ Customized with the following commits:
042880ba2df913916b2cc77f7bb677e07bfd2c58
67c55c74901f1d337ef08f2090a87cfb4263bb0f
a94c952b40d36b1505fb77b87c0dd739e1034659
3ca3a544a87cc569b69351a77996c287763388a5
3ca3a544a87cc569b69351a77996c287763388a5
6586a46ea23e86d54d228c55c63ca55680d25d56

View File

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

View File

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

View File

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

View File

@ -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 &params) {
// 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 &params,
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 &params,
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>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -138,7 +138,7 @@ void Fill3DHoneycomb::_fill_surface_single(
const FillParams &params,
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

View File

@ -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 &params,
unsigned int thickness_layers,
const std::pair<float, Point> &direction,
ExPolygon &expolygon,
ExPolygon expolygon,
Polylines &polylines_out) const override;
};

View File

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

View File

@ -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 &params,
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

File diff suppressed because it is too large Load Diff

View File

@ -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 &params) 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 &params);
static void connect_infill(Polylines &&infill_ordered, const ExPolygon &boundary, Polylines &polylines_out, const double spacing, const FillParams &params);
static void connect_infill(Polylines &&infill_ordered, const Polygons &boundary, const BoundingBox& bbox, Polylines &polylines_out, const double spacing, const FillParams &params);
static void connect_infill(Polylines &&infill_ordered, const std::vector<const Polygon*> &boundary, const BoundingBox &bbox, Polylines &polylines_out, double spacing, const FillParams &params);
static coord_t _adjust_solid_spacing(const coord_t width, const coord_t distance);

View File

@ -23,7 +23,7 @@ FillConcentric::_fill_surface_single(
const FillParams &params,
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

View File

@ -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 &params) override;
virtual void _fill_surface_single(
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 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 &params, ExtrusionEntitiesPtr &out) const override;
Fill* clone() const override { return new FillConcentricWGapFill(*this); };
void fill_surface_extrusion(const Surface *surface, const FillParams &params, ExtrusionEntitiesPtr &out) const override;
virtual bool no_sort() const { return true; }
bool no_sort() const override { return true; }
};
} // namespace Slic3r

View File

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

View File

@ -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 &params,
unsigned int thickness_layers,
const std::pair<float, Point> &direction,
ExPolygon &expolygon,
ExPolygon expolygon,
Polylines &polylines_out) const override;
};

View File

@ -12,7 +12,7 @@ void FillHoneycomb::_fill_surface_single(
const FillParams &params,
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

View File

@ -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 &params,
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

View 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 &params,
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

View 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 &params,
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_

View File

@ -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 &params,
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;
}

View File

@ -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 &params,
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

File diff suppressed because it is too large Load Diff

View File

@ -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 &params,
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 &params) 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 &params);
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_

Some files were not shown because too many files have changed in this diff Show More