diff --git a/lib/Slic3r/Geometry/Clipper.pm b/lib/Slic3r/Geometry/Clipper.pm
index 0c35c93d98..b7a7da7727 100644
--- a/lib/Slic3r/Geometry/Clipper.pm
+++ b/lib/Slic3r/Geometry/Clipper.pm
@@ -5,7 +5,7 @@ use warnings;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(
- offset offset2
+ offset
offset_ex offset2_ex
diff_ex diff union_ex intersection_ex
JT_ROUND JT_MITER JT_SQUARE
diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm
index 7370881ea3..0385f88b88 100644
--- a/lib/Slic3r/Print/Object.pm
+++ b/lib/Slic3r/Print/Object.pm
@@ -7,7 +7,7 @@ use List::Util qw(min max sum first);
use Slic3r::Flow ':roles';
use Slic3r::Geometry qw(scale epsilon);
use Slic3r::Geometry::Clipper qw(diff diff_ex intersection intersection_ex union union_ex
- offset offset2 offset_ex offset2_ex JT_MITER);
+ offset offset_ex offset2_ex JT_MITER);
use Slic3r::Print::State ':steps';
use Slic3r::Surface ':types';
diff --git a/resources/profiles/Anycubic.ini b/resources/profiles/Anycubic.ini
index ff03672910..c1b763879c 100644
--- a/resources/profiles/Anycubic.ini
+++ b/resources/profiles/Anycubic.ini
@@ -1163,7 +1163,7 @@ before_layer_gcode = ;BEFORE_LAYER_CHANGE\nG92 E0.0\n;[layer_z]
default_filament_profile = Generic PLA @MEGA
default_print_profile = 0.15mm QUALITY @MEGA
deretract_speed = 40
-end_gcode = G1 E-1.0 F2100 ; retract\nG92 E0.0\nG1{if max_layer_z < max_print_height} Z{z_offset+min(max_layer_z+30, max_print_height)}{endif} ; move print head up\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y105 F3000 ; park print head\nM84 ; disable motors
+end_gcode = G1 E-1.0 F2100 ; retract\nG92 E0.0\nG1{if max_layer_z < max_print_height} Z{z_offset+min(max_layer_z+30, max_print_height)}{endif} E-34.0 F720 ; move print head up & retract filament\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y105 F3000 ; park print head\nM84 ; disable motors
extruder_colour = #808080
gcode_flavor = marlin
layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z]
@@ -1178,7 +1178,7 @@ retract_lift = 0.2
retract_lift_below = 204
retract_speed = 70
silent_mode = 0
-start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM204 S[machine_max_acceleration_extruding] T[machine_max_acceleration_retracting]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nG28 ; home all\nG1 Y2.0 Z0.2 F1000 ; move print head up\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG92 E0.0\nG1 X60.0 E9.0 F1000 ; intro line\nG1 X100.0 E12.5 F1000 ; intro line\nG92 E0.0
+start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM204 S[machine_max_acceleration_extruding] T[machine_max_acceleration_retracting]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nG28 ; home all\nG1 Y1.0 Z0.3 F1000 ; move print head up\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG92 E0.0\n; initial load\nG1 X205.0 E19 F1000\nG1 Y1.6\nG1 X5.0 E19 F1000\nG92 E0.0\n; intro line\nG1 Y2.0 Z0.2 F1000\nG1 X65.0 E9.0 F1000\nG1 X105.0 E12.5 F1000\nG92 E0.0
thumbnails = 16x16,220x124
use_relative_e_distances = 1
wipe = 1
@@ -1892,4 +1892,4 @@ default_print_profile = 0.24mm 0.8 nozzle DETAILED QUALITY @PREDATOR
#########################################
########## end printer presets ##########
-#########################################"do not" cause ' is bad for syntax highlighting
+#########################################
diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini
index 5248155250..717b495581 100644
--- a/resources/profiles/Creality.ini
+++ b/resources/profiles/Creality.ini
@@ -21,7 +21,7 @@ technology = FFF
family = ENDER
bed_model = ender3_bed.stl
bed_texture = ender3.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:ENDER3BLTOUCH]
name = Creality Ender-3 BLTouch
@@ -30,7 +30,7 @@ technology = FFF
family = ENDER
bed_model = ender3_bed.stl
bed_texture = ender3.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:ENDER3V2]
name = Creality Ender-3 V2
@@ -39,7 +39,7 @@ technology = FFF
family = ENDER
bed_model = ender3v2_bed.stl
bed_texture = ender3v2.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:ENDER3MAX]
name = Creality Ender-3 Max
@@ -48,7 +48,7 @@ technology = FFF
family = ENDER
bed_model = cr10v2_bed.stl
bed_texture = cr10spro.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:ENDER4]
name = Creality Ender-4
@@ -57,7 +57,7 @@ technology = FFF
family = ENDER
bed_model = ender3v2_bed.stl
bed_texture = ender3v2.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:ENDER5]
name = Creality Ender-5
@@ -66,7 +66,7 @@ technology = FFF
family = ENDER
bed_model = ender3_bed.stl
bed_texture = ender3.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:ENDER5PLUS]
name = Creality Ender-5 Plus
@@ -75,7 +75,7 @@ technology = FFF
family = ENDER
bed_model = ender5plus_bed.stl
bed_texture = ender5plus.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:ENDER6]
name = Creality Ender-6
@@ -84,7 +84,7 @@ technology = FFF
family = ENDER
bed_model = ender6_bed.stl
bed_texture = ender6.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:ENDER2]
name = Creality Ender-2
@@ -93,7 +93,7 @@ technology = FFF
family = ENDER
bed_model = ender2_bed.stl
bed_texture = ender2.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:CR5PRO]
name = Creality CR-5 Pro
@@ -102,7 +102,7 @@ technology = FFF
family = CR
bed_model = cr5pro_bed.stl
bed_texture = cr5pro.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:CR5PROH]
name = Creality CR-5 Pro H
@@ -111,7 +111,7 @@ technology = FFF
family = CR
bed_model = cr5pro_bed.stl
bed_texture = cr5pro.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:CR6SE]
name = Creality CR-6 SE
@@ -120,7 +120,7 @@ technology = FFF
family = CR
bed_model = cr6se_bed.stl
bed_texture = cr6se.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:CR6MAX]
name = Creality CR-6 Max
@@ -129,7 +129,7 @@ technology = FFF
family = CR
bed_model = cr10s4_bed.stl
bed_texture = cr10s4.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:CR10MINI]
name = Creality CR-10 Mini
@@ -138,7 +138,7 @@ technology = FFF
family = CR
bed_model = cr10mini_bed.stl
bed_texture = cr10mini.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:CR10MAX]
name = Creality CR-10 Max
@@ -147,7 +147,7 @@ technology = FFF
family = CR
bed_model = cr10max_bed.stl
bed_texture = cr10max.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:CR10]
name = Creality CR-10
@@ -156,7 +156,7 @@ technology = FFF
family = CR
bed_model = cr10_bed.stl
bed_texture = cr10.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:CR10V2]
name = Creality CR-10 V2
@@ -165,7 +165,7 @@ technology = FFF
family = CR
bed_model = cr10v2_bed.stl
bed_texture = cr10.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:CR10V3]
name = Creality CR-10 V3
@@ -174,7 +174,7 @@ technology = FFF
family = CR
bed_model = cr10v2_bed.stl
bed_texture = cr10.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:CR10S]
name = Creality CR-10 S
@@ -183,7 +183,7 @@ technology = FFF
family = CR
bed_model = cr10_bed.stl
bed_texture = cr10.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:CR10SPRO]
name = Creality CR-10 S Pro
@@ -192,7 +192,7 @@ technology = FFF
family = CR
bed_model = cr10v2_bed.stl
bed_texture = cr10spro.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:CR10SPROV2]
name = Creality CR-10 S Pro V2
@@ -201,7 +201,7 @@ technology = FFF
family = CR
bed_model = cr10v2_bed.stl
bed_texture = cr10.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:CR10S4]
name = Creality CR-10 S4
@@ -210,7 +210,7 @@ technology = FFF
family = CR
bed_model = cr10s4_bed.stl
bed_texture = cr10s4.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:CR10S5]
name = Creality CR-10 S5
@@ -219,7 +219,7 @@ technology = FFF
family = CR
bed_model = cr10s5_bed.stl
bed_texture = cr10s5.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:CR20]
name = Creality CR-20
@@ -228,7 +228,7 @@ technology = FFF
family = CR
bed_model = ender3_bed.stl
bed_texture = cr20.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:CR20PRO]
name = Creality CR-20 Pro
@@ -237,7 +237,7 @@ technology = FFF
family = CR
bed_model = ender3_bed.stl
bed_texture = cr20.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:CR200B]
name = Creality CR-200B
@@ -246,7 +246,7 @@ technology = FFF
family = CR
bed_model = cr200b_bed.stl
bed_texture = cr200b.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:CR8]
name = Creality CR-8
@@ -255,7 +255,7 @@ technology = FFF
family = CR
bed_model = cr8_bed.stl
bed_texture = cr8.svg
-default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
#[printer_model:CRX]
#name = Creality CR-X
@@ -264,7 +264,7 @@ default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @
#family = CR-X
#bed_model = cr10v2_bed.stl
#bed_texture = cr10spro.svg
-#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
#[printer_model:CRXPRO]
#name = Creality CR-X Pro
@@ -273,7 +273,7 @@ default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @
#family = CR-X
#bed_model = cr10v2_bed.stl
#bed_texture = cr10spro.svg
-#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
+#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
# All presets starting with asterisk, for example *common*, are intermediate and they will
# not make it into the user interface.
@@ -326,7 +326,7 @@ notes =
overhangs = 0
only_retract_when_crossing_perimeters = 0
ooze_prevention = 0
-output_filename_format = {input_filename_base}_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode
+output_filename_format = {input_filename_base}_{print_time}_{layer_height}mm_{temperature[0]}C_{filament_type[0]}_{printer_model}.gcode
perimeters = 2
perimeter_extruder = 1
perimeter_extrusion_width = 0.45
@@ -639,6 +639,18 @@ filament_density = 1.24
filament_colour = #FF0000
filament_spool_weight = 256
+[filament:Devil Design PLA Matt @CREALITY]
+inherits = *PLA*
+filament_vendor = Devil Design
+temperature = 205
+bed_temperature = 60
+first_layer_temperature = 205
+first_layer_bed_temperature = 60
+filament_cost = 20.00
+filament_density = 1.38
+filament_colour = #FF0000
+filament_spool_weight = 256
+
[filament:Devil Design PLA Galaxy @CREALITY]
inherits = *PLA*
renamed_from = "Devil Design PLA (Galaxy) @CREALITY"
diff --git a/resources/profiles/PrusaResearch/mk2.svg b/resources/profiles/PrusaResearch/mk2.svg
index 6214a55523..1fe5b4c57d 100644
--- a/resources/profiles/PrusaResearch/mk2.svg
+++ b/resources/profiles/PrusaResearch/mk2.svg
@@ -47,7 +47,8 @@
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1.43643"
- id="line3904" />
+ id="line3904"
+ style="stroke-width:1.433;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3906"
+ style="stroke-width:1.433;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3908"
+ style="stroke-width:1.42;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3924"
+ style="stroke-width:1.433;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3926"
+ style="stroke-width:1.433;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3928"
+ style="stroke-width:1.433;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3932"
+ style="stroke-width:1.42;stroke-miterlimit:4;stroke-dasharray:none" />
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3956"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3958"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3960"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3964"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3966"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3968"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3970"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3972"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3974"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3976"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3978"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3980"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3982"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3984"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3986"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3988"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3990"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3992"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3994"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3996"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line3998"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line4000"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line4002"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line4004"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line4006"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line4008"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line4010"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line4012"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line4014"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line4018"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line4020"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line4022"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line4024"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line4026"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line4028"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2794"
+ style="stroke-width:1.42;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2796"
+ style="stroke-width:1.433;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2798"
+ style="stroke-width:1.433;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2800"
+ style="stroke-width:1.42;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2816"
+ style="stroke-width:1.433;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2818"
+ style="stroke-width:1.433;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2820"
+ style="stroke-width:1.433;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2822"
+ style="stroke-width:1.433;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2824"
+ style="stroke-width:1.433;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2844"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2848"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2850"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2852"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2854"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2856"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2858"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2860"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2862"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2864"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2866"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2868"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2870"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2872"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2874"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2876"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2878"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2880"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2882"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2884"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2886"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2888"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2890"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2892"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2894"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2896"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2898"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2900"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2902"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2904"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2906"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2908"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2910"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2912"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2914"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2916"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2918"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
+ id="line2920"
+ style="stroke-width:0.374;stroke-miterlimit:4;stroke-dasharray:none" />
_anchor_regions = intersection_ex(grown, to_polygons(this->lower_slices), true);
+ this->_anchor_regions = intersection_ex(grown, union_safety_offset(this->lower_slices));
/*
if (0) {
diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt
index 16299f442d..0cf67597a3 100644
--- a/src/libslic3r/CMakeLists.txt
+++ b/src/libslic3r/CMakeLists.txt
@@ -163,6 +163,7 @@ add_library(libslic3r STATIC
AppConfig.hpp
Print.cpp
Print.hpp
+ PrintApply.cpp
PrintBase.cpp
PrintBase.hpp
PrintConfig.cpp
diff --git a/src/libslic3r/ClipperUtils.cpp b/src/libslic3r/ClipperUtils.cpp
index 8bca3b25a3..7242246040 100644
--- a/src/libslic3r/ClipperUtils.cpp
+++ b/src/libslic3r/ClipperUtils.cpp
@@ -137,13 +137,23 @@ static ClipperLib::Paths safety_offset(PathsProvider &&paths)
for (const ClipperLib::Path &path : paths) {
co.Clear();
co.MiterLimit = 2.;
+ // Execute reorients the contours so that the outer most contour has a positive area. Thus the output
+ // contours will be CCW oriented even though the input paths are CW oriented.
+ // Offset is applied after contour reorientation, thus the signum of the offset value is reversed.
co.AddPath(path, ClipperLib::jtMiter, ClipperLib::etClosedPolygon);
- co.Execute(out_this, ClipperSafetyOffset);
+ bool ccw = ClipperLib::Orientation(path);
+ co.Execute(out_this, ccw ? ClipperSafetyOffset : - ClipperSafetyOffset);
+ if (! ccw) {
+ // Reverse the resulting contours.
+ for (ClipperLib::Path &path : out_this)
+ std::reverse(path.begin(), path.end());
+ }
append(out, std::move(out_this));
}
return out;
}
+// Only safe for a single path.
template
ClipperLib::Paths _offset(PathsProvider &&input, ClipperLib::EndType endType, const float delta, ClipperLib::JoinType joinType, double miterLimit)
{
@@ -161,12 +171,14 @@ ClipperLib::Paths _offset(PathsProvider &&input, ClipperLib::EndType endType, co
return retval;
}
-Slic3r::Polygons offset(const Slic3r::Polygon &polygon, const float delta, ClipperLib::JoinType joinType, double miterLimit)
+Slic3r::Polygons offset(const Slic3r::Polygon& polygon, const float delta, ClipperLib::JoinType joinType, double miterLimit)
{ return to_polygons(_offset(ClipperUtils::SinglePathProvider(polygon.points), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
#ifdef CLIPPERUTILS_UNSAFE_OFFSET
Slic3r::Polygons offset(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType, double miterLimit)
{ return to_polygons(_offset(ClipperUtils::PolygonsProvider(polygons), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
+Slic3r::ExPolygons offset_ex(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType, double miterLimit)
+ { return ClipperPaths_to_Slic3rExPolygons(_offset(ClipperUtils::PolygonsProvider(polygons), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
#endif // CLIPPERUTILS_UNSAFE_OFFSET
Slic3r::Polygons offset(const Slic3r::Polyline &polyline, const float delta, ClipperLib::JoinType joinType, double miterLimit)
@@ -174,11 +186,6 @@ Slic3r::Polygons offset(const Slic3r::Polyline &polyline, const float delta, Cli
Slic3r::Polygons offset(const Slic3r::Polylines &polylines, const float delta, ClipperLib::JoinType joinType, double miterLimit)
{ return to_polygons(_offset(ClipperUtils::PolylinesProvider(polylines), ClipperLib::etOpenButt, delta, joinType, miterLimit)); }
-#ifdef CLIPPERUTILS_UNSAFE_OFFSET
-Slic3r::ExPolygons offset_ex(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType, double miterLimit)
- { return ClipperPaths_to_Slic3rExPolygons(_offset(ClipperUtils::PolygonsProvider(polygons), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
-#endif // CLIPPERUTILS_UNSAFE_OFFSET
-
// returns number of expolygons collected (0 or 1).
static int offset_expolygon_inner(const Slic3r::ExPolygon &expoly, const float delta, ClipperLib::JoinType joinType, double miterLimit, ClipperLib::Paths &out)
{
@@ -313,6 +320,18 @@ Slic3r::ExPolygons offset_ex(const Slic3r::ExPolygons &expolygons, const float d
Slic3r::ExPolygons offset_ex(const Slic3r::Surfaces &surfaces, const float delta, ClipperLib::JoinType joinType, double miterLimit)
{ return ClipperPaths_to_Slic3rExPolygons(_offset(surfaces, delta, joinType, miterLimit)); }
+#ifdef CLIPPERUTILS_UNSAFE_OFFSET
+Slic3r::Polygons union_safety_offset(const Slic3r::Polygons &polygons)
+ { return offset(polygons, ClipperSafetyOffset); }
+Slic3r::ExPolygons union_safety_offset_ex(const Slic3r::Polygons &polygons)
+ { return offset_ex(polygons, ClipperSafetyOffset); }
+#endif // CLIPPERUTILS_UNSAFE_OFFSET
+
+Slic3r::Polygons union_safety_offset(const Slic3r::ExPolygons &expolygons)
+ { return offset(expolygons, ClipperSafetyOffset); }
+Slic3r::ExPolygons union_safety_offset_ex(const Slic3r::ExPolygons &expolygons)
+ { return offset_ex(expolygons, ClipperSafetyOffset); }
+
ClipperLib::Paths _offset2(const Polygons &polygons, const float delta1, const float delta2, const ClipperLib::JoinType joinType, const double miterLimit)
{
// prepare ClipperOffset object
@@ -382,12 +401,12 @@ TResult _clipper_do(
TSubj && subject,
TClip && clip,
const ClipperLib::PolyFillType fillType,
- const bool do_safety_offset)
+ const ApplySafetyOffset do_safety_offset)
{
- return do_safety_offset ?
- (clipType == ClipperLib::ctUnion ?
- _clipper_do(clipType, safety_offset(std::forward(subject)), std::forward(clip), fillType) :
- _clipper_do(clipType, std::forward(subject), safety_offset(std::forward(clip)), fillType)) :
+ // Safety offset only allowed on intersection and difference.
+ assert(do_safety_offset == ApplySafetyOffset::No || clipType != ClipperLib::ctUnion);
+ return do_safety_offset == ApplySafetyOffset::Yes ?
+ _clipper_do(clipType, std::forward(subject), safety_offset(std::forward(clip)), fillType) :
_clipper_do(clipType, std::forward(subject), std::forward(clip), fillType);
}
@@ -426,107 +445,103 @@ inline ClipperLib::PolyTree _clipper_do_polytree2(
PathProvider1 &&subject,
PathProvider2 &&clip,
const ClipperLib::PolyFillType fillType,
- const bool do_safety_offset)
+ const ApplySafetyOffset do_safety_offset)
{
- return do_safety_offset ?
- (clipType == ClipperLib::ctUnion ?
- _clipper_do_polytree2(clipType, safety_offset(std::forward(subject)), std::forward(clip), fillType) :
- _clipper_do_polytree2(clipType, std::forward(subject), safety_offset(std::forward(clip)), fillType)) :
+ assert(do_safety_offset == ApplySafetyOffset::No || clipType != ClipperLib::ctUnion);
+ return do_safety_offset == ApplySafetyOffset::Yes ?
+ _clipper_do_polytree2(clipType, std::forward(subject), safety_offset(std::forward(clip)), fillType) :
_clipper_do_polytree2(clipType, std::forward(subject), std::forward(clip), fillType);
}
template
-static inline Polygons _clipper(ClipperLib::ClipType clipType, TSubj &&subject, TClip &&clip, bool do_safety_offset)
+static inline Polygons _clipper(ClipperLib::ClipType clipType, TSubj &&subject, TClip &&clip, ApplySafetyOffset do_safety_offset)
{
return to_polygons(_clipper_do(clipType, std::forward(subject), std::forward(clip), ClipperLib::pftNonZero, do_safety_offset));
}
-Slic3r::Polygons diff(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset)
+Slic3r::Polygons diff(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper(ClipperLib::ctDifference, ClipperUtils::PolygonsProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
-Slic3r::Polygons diff(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset)
+Slic3r::Polygons diff(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper(ClipperLib::ctDifference, ClipperUtils::ExPolygonsProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
-Slic3r::Polygons diff(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset)
+Slic3r::Polygons diff(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper(ClipperLib::ctDifference, ClipperUtils::ExPolygonsProvider(subject), ClipperUtils::ExPolygonsProvider(clip), do_safety_offset); }
-Slic3r::Polygons intersection(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset)
+Slic3r::Polygons intersection(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper(ClipperLib::ctIntersection, ClipperUtils::PolygonsProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
-Slic3r::Polygons intersection(const Slic3r::ExPolygon &subject, const Slic3r::ExPolygon &clip, bool do_safety_offset)
+Slic3r::Polygons intersection(const Slic3r::ExPolygon &subject, const Slic3r::ExPolygon &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper(ClipperLib::ctIntersection, ClipperUtils::ExPolygonProvider(subject), ClipperUtils::ExPolygonProvider(clip), do_safety_offset); }
-Slic3r::Polygons intersection(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset)
+Slic3r::Polygons intersection(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper(ClipperLib::ctIntersection, ClipperUtils::ExPolygonsProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
-Slic3r::Polygons intersection(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset)
+Slic3r::Polygons intersection(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper(ClipperLib::ctIntersection, ClipperUtils::ExPolygonsProvider(subject), ClipperUtils::ExPolygonsProvider(clip), do_safety_offset); }
-Slic3r::Polygons intersection(const Slic3r::Surfaces &subject, const Slic3r::Polygons &clip, bool do_safety_offset)
+Slic3r::Polygons intersection(const Slic3r::Surfaces &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper(ClipperLib::ctIntersection, ClipperUtils::SurfacesProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
-Slic3r::Polygons intersection(const Slic3r::Surfaces &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset)
+Slic3r::Polygons intersection(const Slic3r::Surfaces &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper(ClipperLib::ctIntersection, ClipperUtils::SurfacesProvider(subject), ClipperUtils::ExPolygonsProvider(clip), do_safety_offset); }
-Slic3r::Polygons union_(const Slic3r::Polygons &subject, bool do_safety_offset)
- { return _clipper(ClipperLib::ctUnion, ClipperUtils::PolygonsProvider(subject), ClipperUtils::EmptyPathsProvider(), do_safety_offset); }
-Slic3r::Polygons union_(const Slic3r::ExPolygons &subject, bool do_safety_offset)
- { return _clipper(ClipperLib::ctUnion, ClipperUtils::ExPolygonsProvider(subject), ClipperUtils::EmptyPathsProvider(), do_safety_offset); }
-Slic3r::Polygons union_(const Slic3r::Polygons &subject, const Slic3r::Polygons &subject2, bool do_safety_offset)
- { return _clipper(ClipperLib::ctUnion, ClipperUtils::PolygonsProvider(subject), ClipperUtils::PolygonsProvider(subject2), do_safety_offset); }
+Slic3r::Polygons union_(const Slic3r::Polygons &subject)
+ { return _clipper(ClipperLib::ctUnion, ClipperUtils::PolygonsProvider(subject), ClipperUtils::EmptyPathsProvider(), ApplySafetyOffset::No); }
+Slic3r::Polygons union_(const Slic3r::ExPolygons &subject)
+ { return _clipper(ClipperLib::ctUnion, ClipperUtils::ExPolygonsProvider(subject), ClipperUtils::EmptyPathsProvider(), ApplySafetyOffset::No); }
+Slic3r::Polygons union_(const Slic3r::Polygons &subject, const Slic3r::Polygons &subject2)
+ { return _clipper(ClipperLib::ctUnion, ClipperUtils::PolygonsProvider(subject), ClipperUtils::PolygonsProvider(subject2), ApplySafetyOffset::No); }
template
-static ExPolygons _clipper_ex(ClipperLib::ClipType clipType, TSubject &&subject, TClip &&clip, bool do_safety_offset)
+static ExPolygons _clipper_ex(ClipperLib::ClipType clipType, TSubject &&subject, TClip &&clip, ApplySafetyOffset do_safety_offset)
{ return PolyTreeToExPolygons(_clipper_do_polytree2(clipType, std::forward(subject), std::forward(clip), ClipperLib::pftNonZero, do_safety_offset)); }
-Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset)
+Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctDifference, ClipperUtils::PolygonsProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
-Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::Surfaces &clip, bool do_safety_offset)
+Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::Surfaces &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctDifference, ClipperUtils::PolygonsProvider(subject), ClipperUtils::SurfacesProvider(clip), do_safety_offset); }
-Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset)
+Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctDifference, ClipperUtils::PolygonsProvider(subject), ClipperUtils::ExPolygonsProvider(clip), do_safety_offset); }
-Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygon &subject, const Slic3r::Polygons &clip, bool do_safety_offset)
+Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygon &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctDifference, ClipperUtils::ExPolygonProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
-Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset)
+Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctDifference, ClipperUtils::ExPolygonsProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
-Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset)
+Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctDifference, ClipperUtils::ExPolygonsProvider(subject), ClipperUtils::ExPolygonsProvider(clip), do_safety_offset); }
-Slic3r::ExPolygons diff_ex(const Slic3r::Surfaces &subject, const Slic3r::Polygons &clip, bool do_safety_offset)
+Slic3r::ExPolygons diff_ex(const Slic3r::Surfaces &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctDifference, ClipperUtils::SurfacesProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
-Slic3r::ExPolygons diff_ex(const Slic3r::Surfaces &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset)
+Slic3r::ExPolygons diff_ex(const Slic3r::Surfaces &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctDifference, ClipperUtils::SurfacesProvider(subject), ClipperUtils::ExPolygonsProvider(clip), do_safety_offset); }
-Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::Surfaces &clip, bool do_safety_offset)
+Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::Surfaces &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctDifference, ClipperUtils::ExPolygonsProvider(subject), ClipperUtils::SurfacesProvider(clip), do_safety_offset); }
-Slic3r::ExPolygons diff_ex(const Slic3r::Surfaces &subject, const Slic3r::Surfaces &clip, bool do_safety_offset)
+Slic3r::ExPolygons diff_ex(const Slic3r::Surfaces &subject, const Slic3r::Surfaces &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctDifference, ClipperUtils::SurfacesProvider(subject), ClipperUtils::SurfacesProvider(clip), do_safety_offset); }
-Slic3r::ExPolygons diff_ex(const Slic3r::SurfacesPtr &subject, const Slic3r::Polygons &clip, bool do_safety_offset)
+Slic3r::ExPolygons diff_ex(const Slic3r::SurfacesPtr &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctDifference, ClipperUtils::SurfacesPtrProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
-Slic3r::ExPolygons intersection_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset)
+Slic3r::ExPolygons intersection_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctIntersection, ClipperUtils::PolygonsProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
-Slic3r::ExPolygons intersection_ex(const Slic3r::ExPolygon &subject, const Slic3r::Polygons &clip, bool do_safety_offset)
+Slic3r::ExPolygons intersection_ex(const Slic3r::ExPolygon &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctIntersection, ClipperUtils::ExPolygonProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
-Slic3r::ExPolygons intersection_ex(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset)
+Slic3r::ExPolygons intersection_ex(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctIntersection, ClipperUtils::PolygonsProvider(subject), ClipperUtils::ExPolygonsProvider(clip), do_safety_offset); }
-Slic3r::ExPolygons intersection_ex(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset)
+Slic3r::ExPolygons intersection_ex(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctIntersection, ClipperUtils::ExPolygonsProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
-Slic3r::ExPolygons intersection_ex(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset)
+Slic3r::ExPolygons intersection_ex(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctIntersection, ClipperUtils::ExPolygonsProvider(subject), ClipperUtils::ExPolygonsProvider(clip), do_safety_offset); }
-Slic3r::ExPolygons intersection_ex(const Slic3r::Surfaces &subject, const Slic3r::Polygons &clip, bool do_safety_offset)
+Slic3r::ExPolygons intersection_ex(const Slic3r::Surfaces &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctIntersection, ClipperUtils::SurfacesProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
-Slic3r::ExPolygons intersection_ex(const Slic3r::Surfaces &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset)
+Slic3r::ExPolygons intersection_ex(const Slic3r::Surfaces &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctIntersection, ClipperUtils::SurfacesProvider(subject), ClipperUtils::ExPolygonsProvider(clip), do_safety_offset); }
-Slic3r::ExPolygons intersection_ex(const Slic3r::Surfaces &subject, const Slic3r::Surfaces &clip, bool do_safety_offset)
+Slic3r::ExPolygons intersection_ex(const Slic3r::Surfaces &subject, const Slic3r::Surfaces &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctIntersection, ClipperUtils::SurfacesProvider(subject), ClipperUtils::SurfacesProvider(clip), do_safety_offset); }
-Slic3r::ExPolygons intersection_ex(const Slic3r::SurfacesPtr &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset)
+Slic3r::ExPolygons intersection_ex(const Slic3r::SurfacesPtr &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctIntersection, ClipperUtils::SurfacesPtrProvider(subject), ClipperUtils::ExPolygonsProvider(clip), do_safety_offset); }
-Slic3r::ExPolygons union_ex(const Slic3r::Polygons &subject, bool do_safety_offset)
- { return _clipper_ex(ClipperLib::ctUnion, ClipperUtils::PolygonsProvider(subject), ClipperUtils::EmptyPathsProvider(), do_safety_offset); }
+Slic3r::ExPolygons union_ex(const Slic3r::Polygons &subject)
+ { return _clipper_ex(ClipperLib::ctUnion, ClipperUtils::PolygonsProvider(subject), ClipperUtils::EmptyPathsProvider(), ApplySafetyOffset::No); }
Slic3r::ExPolygons union_ex(const Slic3r::ExPolygons& subject)
{ return PolyTreeToExPolygons(_clipper_do_polytree2(ClipperLib::ctUnion, ClipperUtils::ExPolygonsProvider(subject), ClipperUtils::EmptyPathsProvider(), ClipperLib::pftNonZero)); }
Slic3r::ExPolygons union_ex(const Slic3r::Surfaces& subject)
{ return PolyTreeToExPolygons(_clipper_do_polytree2(ClipperLib::ctUnion, ClipperUtils::SurfacesProvider(subject), ClipperUtils::EmptyPathsProvider(), ClipperLib::pftNonZero)); }
template
-Polylines _clipper_pl_open(ClipperLib::ClipType clipType, PathsProvider1 &&subject, PathsProvider2 &&clip, bool do_safety_offset)
+Polylines _clipper_pl_open(ClipperLib::ClipType clipType, PathsProvider1 &&subject, PathsProvider2 &&clip)
{
ClipperLib::Clipper clipper;
clipper.AddPaths(std::forward(subject), ClipperLib::ptSubject, false);
- if (do_safety_offset)
- clipper.AddPaths(safety_offset(std::forward(clip)), ClipperLib::ptClip, true);
- else
- clipper.AddPaths(std::forward(clip), ClipperLib::ptClip, true);
+ clipper.AddPaths(std::forward(clip), ClipperLib::ptClip, true);
ClipperLib::PolyTree retval;
clipper.Execute(clipType, retval, ClipperLib::pftNonZero, ClipperLib::pftNonZero);
return PolyTreeToPolylines(std::move(retval));
@@ -571,7 +586,7 @@ static void _clipper_pl_recombine(Polylines &polylines)
}
template
-Polylines _clipper_pl_closed(ClipperLib::ClipType clipType, PathProvider1 &&subject, PathProvider2 &&clip, bool do_safety_offset)
+Polylines _clipper_pl_closed(ClipperLib::ClipType clipType, PathProvider1 &&subject, PathProvider2 &&clip)
{
// Transform input polygons into open paths.
ClipperLib::Paths paths;
@@ -585,27 +600,27 @@ Polylines _clipper_pl_closed(ClipperLib::ClipType clipType, PathProvider1 &&subj
path.emplace_back(poly.front());
}
// perform clipping
- Polylines retval = _clipper_pl_open(clipType, paths, std::forward(clip), do_safety_offset);
+ Polylines retval = _clipper_pl_open(clipType, paths, std::forward(clip));
_clipper_pl_recombine(retval);
return retval;
}
-Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, bool do_safety_offset)
- { return _clipper_pl_open(ClipperLib::ctDifference, ClipperUtils::PolylinesProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
-Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::ExPolygon &clip, bool do_safety_offset)
- { return _clipper_pl_open(ClipperLib::ctDifference, ClipperUtils::PolylinesProvider(subject), ClipperUtils::ExPolygonProvider(clip), do_safety_offset); }
-Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset)
- { return _clipper_pl_open(ClipperLib::ctDifference, ClipperUtils::PolylinesProvider(subject), ClipperUtils::ExPolygonsProvider(clip), do_safety_offset); }
-Slic3r::Polylines diff_pl(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset)
- { return _clipper_pl_closed(ClipperLib::ctDifference, ClipperUtils::PolygonsProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
-Slic3r::Polylines intersection_pl(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, bool do_safety_offset)
- { return _clipper_pl_open(ClipperLib::ctIntersection, ClipperUtils::PolylinesProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
-Slic3r::Polylines intersection_pl(const Slic3r::Polylines &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset)
- { return _clipper_pl_open(ClipperLib::ctIntersection, ClipperUtils::PolylinesProvider(subject), ClipperUtils::ExPolygonsProvider(clip), do_safety_offset); }
-Slic3r::Polylines intersection_pl(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset)
- { return _clipper_pl_closed(ClipperLib::ctIntersection, ClipperUtils::PolygonsProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
+Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip)
+ { return _clipper_pl_open(ClipperLib::ctDifference, ClipperUtils::PolylinesProvider(subject), ClipperUtils::PolygonsProvider(clip)); }
+Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::ExPolygon &clip)
+ { return _clipper_pl_open(ClipperLib::ctDifference, ClipperUtils::PolylinesProvider(subject), ClipperUtils::ExPolygonProvider(clip)); }
+Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::ExPolygons &clip)
+ { return _clipper_pl_open(ClipperLib::ctDifference, ClipperUtils::PolylinesProvider(subject), ClipperUtils::ExPolygonsProvider(clip)); }
+Slic3r::Polylines diff_pl(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip)
+ { return _clipper_pl_closed(ClipperLib::ctDifference, ClipperUtils::PolygonsProvider(subject), ClipperUtils::PolygonsProvider(clip)); }
+Slic3r::Polylines intersection_pl(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip)
+ { return _clipper_pl_open(ClipperLib::ctIntersection, ClipperUtils::PolylinesProvider(subject), ClipperUtils::PolygonsProvider(clip)); }
+Slic3r::Polylines intersection_pl(const Slic3r::Polylines &subject, const Slic3r::ExPolygons &clip)
+ { return _clipper_pl_open(ClipperLib::ctIntersection, ClipperUtils::PolylinesProvider(subject), ClipperUtils::ExPolygonsProvider(clip)); }
+Slic3r::Polylines intersection_pl(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip)
+ { return _clipper_pl_closed(ClipperLib::ctIntersection, ClipperUtils::PolygonsProvider(subject), ClipperUtils::PolygonsProvider(clip)); }
-Lines _clipper_ln(ClipperLib::ClipType clipType, const Lines &subject, const Polygons &clip, bool do_safety_offset)
+Lines _clipper_ln(ClipperLib::ClipType clipType, const Lines &subject, const Polygons &clip)
{
// convert Lines to Polylines
Polylines polylines;
@@ -614,7 +629,7 @@ Lines _clipper_ln(ClipperLib::ClipType clipType, const Lines &subject, const Pol
polylines.emplace_back(Polyline(line.a, line.b));
// perform operation
- polylines = _clipper_pl_open(clipType, ClipperUtils::PolylinesProvider(polylines), ClipperUtils::PolygonsProvider(clip), do_safety_offset);
+ polylines = _clipper_pl_open(clipType, ClipperUtils::PolylinesProvider(polylines), ClipperUtils::PolygonsProvider(clip));
// convert Polylines to Lines
Lines retval;
diff --git a/src/libslic3r/ClipperUtils.hpp b/src/libslic3r/ClipperUtils.hpp
index c64828644b..fc9677d8b9 100644
--- a/src/libslic3r/ClipperUtils.hpp
+++ b/src/libslic3r/ClipperUtils.hpp
@@ -13,6 +13,10 @@ using Slic3r::ClipperLib::jtRound;
using Slic3r::ClipperLib::jtSquare;
static constexpr const float ClipperSafetyOffset = 10.f;
+enum class ApplySafetyOffset {
+ No,
+ Yes
+};
#define CLIPPERUTILS_UNSAFE_OFFSET
@@ -37,7 +41,7 @@ namespace ClipperUtils {
constexpr bool operator==(const iterator &rhs) const { return true; }
constexpr bool operator!=(const iterator &rhs) const { return false; }
const Points& operator++(int) { assert(false); return s_empty_points; }
- constexpr iterator& operator++() { assert(false); return *this; }
+ const iterator& operator++() { assert(false); return *this; }
};
constexpr EmptyPathsProvider() {}
@@ -262,10 +266,6 @@ ExPolygons ClipperPaths_to_Slic3rExPolygons(const ClipperLib::Paths &input);
// offset Polygons
Slic3r::Polygons offset(const Slic3r::Polygon &polygon, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
-#ifdef CLIPPERUTILS_UNSAFE_OFFSET
-Slic3r::Polygons offset(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
-#endif // CLIPPERUTILS_UNSAFE_OFFSET
-
// offset Polylines
Slic3r::Polygons offset(const Slic3r::Polyline &polyline, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtSquare, double miterLimit = 3);
Slic3r::Polygons offset(const Slic3r::Polylines &polylines, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtSquare, double miterLimit = 3);
@@ -276,79 +276,86 @@ Slic3r::Polygons offset(const Slic3r::SurfacesPtr &surfaces, const float delta
Slic3r::ExPolygons offset_ex(const Slic3r::ExPolygon &expolygon, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
Slic3r::ExPolygons offset_ex(const Slic3r::ExPolygons &expolygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
Slic3r::ExPolygons offset_ex(const Slic3r::Surfaces &surfaces, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
+Slic3r::Polygons union_safety_offset(const Slic3r::ExPolygons &expolygons);
+Slic3r::ExPolygons union_safety_offset_ex(const Slic3r::ExPolygons &expolygons);
Slic3r::Polygons offset2(const Slic3r::ExPolygons &expolygons, const float delta1, const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
Slic3r::ExPolygons offset2_ex(const Slic3r::ExPolygons &expolygons, const float delta1, const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
#ifdef CLIPPERUTILS_UNSAFE_OFFSET
+Slic3r::Polygons offset(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
Slic3r::ExPolygons offset_ex(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
ClipperLib::Paths _offset2(const Slic3r::Polygons &polygons, const float delta1, const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
Slic3r::Polygons offset2(const Slic3r::Polygons &polygons, const float delta1, const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
Slic3r::ExPolygons offset2_ex(const Slic3r::Polygons &polygons, const float delta1, const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
+Slic3r::Polygons union_safety_offset(const Slic3r::Polygons &expolygons);
+Slic3r::ExPolygons union_safety_offset_ex(const Slic3r::Polygons &polygons);
#endif // CLIPPERUTILS_UNSAFE_OFFSET
-Slic3r::Lines _clipper_ln(ClipperLib::ClipType clipType, const Slic3r::Lines &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
+Slic3r::Lines _clipper_ln(ClipperLib::ClipType clipType, const Slic3r::Lines &subject, const Slic3r::Polygons &clip);
-Slic3r::Polygons diff(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
-Slic3r::Polygons diff(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
-Slic3r::Polygons diff(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
-Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
-Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
-Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::Surfaces &clip, bool do_safety_offset = false);
-Slic3r::ExPolygons diff_ex(const Slic3r::Polygon &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
-Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygon &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
-Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
-Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
-Slic3r::ExPolygons diff_ex(const Slic3r::Surfaces &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
-Slic3r::ExPolygons diff_ex(const Slic3r::Surfaces &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
-Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::Surfaces &clip, bool do_safety_offset = false);
-Slic3r::ExPolygons diff_ex(const Slic3r::Surfaces &subject, const Slic3r::Surfaces &clip, bool do_safety_offset = false);
-Slic3r::ExPolygons diff_ex(const Slic3r::SurfacesPtr &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
-Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
-Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::ExPolygon &clip, bool do_safety_offset = false);
-Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
-Slic3r::Polylines diff_pl(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
+// Safety offset is applied to the clipping polygons only.
+Slic3r::Polygons diff(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::Polygons diff(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::Polygons diff(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::Surfaces &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::ExPolygons diff_ex(const Slic3r::Polygon &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygon &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::ExPolygons diff_ex(const Slic3r::Surfaces &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::ExPolygons diff_ex(const Slic3r::Surfaces &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::Surfaces &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::ExPolygons diff_ex(const Slic3r::Surfaces &subject, const Slic3r::Surfaces &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::ExPolygons diff_ex(const Slic3r::SurfacesPtr &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip);
+Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::ExPolygon &clip);
+Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::ExPolygons &clip);
+Slic3r::Polylines diff_pl(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip);
-inline Slic3r::Lines diff_ln(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false)
+inline Slic3r::Lines diff_ln(const Slic3r::Lines &subject, const Slic3r::Polygons &clip)
{
- return _clipper_ln(ClipperLib::ctDifference, subject, clip, do_safety_offset);
+ return _clipper_ln(ClipperLib::ctDifference, subject, clip);
}
-Slic3r::Polygons intersection(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
-Slic3r::Polygons intersection(const Slic3r::ExPolygon &subject, const Slic3r::ExPolygon &clip, bool do_safety_offset = false);
-Slic3r::Polygons intersection(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
-Slic3r::Polygons intersection(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
-Slic3r::Polygons intersection(const Slic3r::Surfaces &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
-Slic3r::Polygons intersection(const Slic3r::Surfaces &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
-Slic3r::ExPolygons intersection_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
-Slic3r::ExPolygons intersection_ex(const Slic3r::ExPolygon &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
-Slic3r::ExPolygons intersection_ex(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
-Slic3r::ExPolygons intersection_ex(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
-Slic3r::ExPolygons intersection_ex(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
-Slic3r::ExPolygons intersection_ex(const Slic3r::Surfaces &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
-Slic3r::ExPolygons intersection_ex(const Slic3r::Surfaces &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
-Slic3r::ExPolygons intersection_ex(const Slic3r::Surfaces &subject, const Slic3r::Surfaces &clip, bool do_safety_offset = false);
-Slic3r::ExPolygons intersection_ex(const Slic3r::SurfacesPtr &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
-Slic3r::Polylines intersection_pl(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
-Slic3r::Polylines intersection_pl(const Slic3r::Polylines &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
-Slic3r::Polylines intersection_pl(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
+// Safety offset is applied to the clipping polygons only.
+Slic3r::Polygons intersection(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::Polygons intersection(const Slic3r::ExPolygon &subject, const Slic3r::ExPolygon &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::Polygons intersection(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::Polygons intersection(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::Polygons intersection(const Slic3r::Surfaces &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::Polygons intersection(const Slic3r::Surfaces &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::ExPolygons intersection_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::ExPolygons intersection_ex(const Slic3r::ExPolygon &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::ExPolygons intersection_ex(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::ExPolygons intersection_ex(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::ExPolygons intersection_ex(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::ExPolygons intersection_ex(const Slic3r::Surfaces &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::ExPolygons intersection_ex(const Slic3r::Surfaces &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::ExPolygons intersection_ex(const Slic3r::Surfaces &subject, const Slic3r::Surfaces &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::ExPolygons intersection_ex(const Slic3r::SurfacesPtr &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
+Slic3r::Polylines intersection_pl(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip);
+Slic3r::Polylines intersection_pl(const Slic3r::Polylines &subject, const Slic3r::ExPolygons &clip);
+Slic3r::Polylines intersection_pl(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip);
-inline Slic3r::Lines intersection_ln(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false)
+inline Slic3r::Lines intersection_ln(const Slic3r::Lines &subject, const Slic3r::Polygons &clip)
{
- return _clipper_ln(ClipperLib::ctIntersection, subject, clip, do_safety_offset);
+ return _clipper_ln(ClipperLib::ctIntersection, subject, clip);
}
-inline Slic3r::Lines intersection_ln(const Slic3r::Line &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false)
+inline Slic3r::Lines intersection_ln(const Slic3r::Line &subject, const Slic3r::Polygons &clip)
{
Slic3r::Lines lines;
lines.emplace_back(subject);
- return _clipper_ln(ClipperLib::ctIntersection, lines, clip, do_safety_offset);
+ return _clipper_ln(ClipperLib::ctIntersection, lines, clip);
}
-Slic3r::Polygons union_(const Slic3r::Polygons &subject, bool do_safety_offset = false);
-Slic3r::Polygons union_(const Slic3r::ExPolygons &subject, bool do_safety_offset = false);
-Slic3r::Polygons union_(const Slic3r::Polygons &subject, const Slic3r::Polygons &subject2, bool do_safety_offset = false);
-Slic3r::ExPolygons union_ex(const Slic3r::Polygons &subject, bool do_safety_offset = false);
+Slic3r::Polygons union_(const Slic3r::Polygons &subject);
+Slic3r::Polygons union_(const Slic3r::ExPolygons &subject);
+Slic3r::Polygons union_(const Slic3r::Polygons &subject, const Slic3r::Polygons &subject2);
+Slic3r::ExPolygons union_ex(const Slic3r::Polygons &subject);
Slic3r::ExPolygons union_ex(const Slic3r::ExPolygons &subject);
Slic3r::ExPolygons union_ex(const Slic3r::Surfaces &subject);
diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp
index c49c492a3f..adda2654ed 100644
--- a/src/libslic3r/Config.hpp
+++ b/src/libslic3r/Config.hpp
@@ -1390,22 +1390,7 @@ public:
}
// Map from an enum name to an enum integer value.
- static const t_config_enum_names& get_enum_names()
- {
- static t_config_enum_names names;
- if (names.empty()) {
- // Initialize the map.
- const t_config_enum_values &enum_keys_map = ConfigOptionEnum::get_enum_values();
- int cnt = 0;
- for (const auto& kvp : enum_keys_map)
- cnt = std::max(cnt, kvp.second);
- cnt += 1;
- names.assign(cnt, "");
- for (const auto& kvp : enum_keys_map)
- names[kvp.second] = kvp.first;
- }
- return names;
- }
+ static const t_config_enum_names& get_enum_names();
// Map from an enum name to an enum integer value.
static const t_config_enum_values& get_enum_values();
diff --git a/src/libslic3r/EdgeGrid.cpp b/src/libslic3r/EdgeGrid.cpp
index b9e9ec3dd8..1385a51d8d 100644
--- a/src/libslic3r/EdgeGrid.cpp
+++ b/src/libslic3r/EdgeGrid.cpp
@@ -546,7 +546,7 @@ bool EdgeGrid::Grid::inside(const Point &pt_src)
return false;
coord_t ix = p(0) / m_resolution;
coord_t iy = p(1) / m_resolution;
- if (ix >= this->m_cols || iy >= this->m_rows)
+ if (ix >= m_cols || iy >= m_rows)
return false;
size_t i_closest = (size_t)-1;
diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp
index 579259a5fc..7ba6de7d47 100644
--- a/src/libslic3r/Fill/Fill.cpp
+++ b/src/libslic3r/Fill/Fill.cpp
@@ -122,10 +122,10 @@ std::vector group_fills(const Layer &layer)
if (surface.surface_type == stInternalVoid)
has_internal_voids = true;
else {
- const PrintRegionConfig ®ion_config = layerm.region()->config();
+ const PrintRegionConfig ®ion_config = layerm.region().config();
FlowRole extrusion_role = surface.is_top() ? frTopSolidInfill : (surface.is_solid() ? frSolidInfill : frInfill);
bool is_bridge = layer.id() > 0 && surface.is_bridge();
- params.extruder = layerm.region()->extruder(extrusion_role);
+ params.extruder = layerm.region().extruder(extrusion_role);
params.pattern = region_config.fill_pattern.value;
params.density = float(region_config.fill_density);
@@ -160,11 +160,9 @@ std::vector group_fills(const Layer &layer)
params.anchor_length = 1000.f;
params.anchor_length_max = 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
- // layer height
- params.spacing = layerm.flow(frInfill, layer.object()->config().layer_height).spacing();
+ // Internal infill. Calculating infill line spacing independent of the current layer height and 1st layer status,
+ // so that internall infill will be aligned over all layers of the current region.
+ params.spacing = layerm.region().flow(*layer.object(), frInfill, layer.object()->config().layer_height, false).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)
@@ -213,7 +211,7 @@ std::vector group_fills(const Layer &layer)
Polygons polys = to_polygons(std::move(fill.expolygons));
// Make a union of polygons, use a safety offset, subtract the preceding polygons.
// Bridges are processed first (see SurfaceFill::operator<())
- fill.expolygons = all_polygons.empty() ? union_ex(polys, true) : diff_ex(polys, all_polygons, true);
+ fill.expolygons = all_polygons.empty() ? union_safety_offset_ex(polys) : diff_ex(polys, all_polygons, ApplySafetyOffset::Yes);
append(all_polygons, std::move(polys));
} else if (&fill != &surface_fills.back())
append(all_polygons, to_polygons(fill.expolygons));
@@ -254,12 +252,11 @@ std::vector group_fills(const Layer &layer)
// Corners of infill regions, which would not be filled with an extrusion path with a radius of distance_between_surfaces/2
Polygons collapsed = diff(
surfaces_polygons,
- offset2(surfaces_polygons, (float)-distance_between_surfaces/2, (float)+distance_between_surfaces/2),
- true);
+ offset2(surfaces_polygons, (float)-distance_between_surfaces/2, (float)+distance_between_surfaces/2 + ClipperSafetyOffset));
//FIXME why the voids are added to collapsed here? First it is expensive, second the result may lead to some unwanted regions being
// added if two offsetted void regions merge.
// polygons_append(voids, collapsed);
- ExPolygons extensions = intersection_ex(offset(collapsed, (float)distance_between_surfaces), voids, true);
+ ExPolygons extensions = intersection_ex(offset(collapsed, (float)distance_between_surfaces), voids, ApplySafetyOffset::Yes);
// Now find an internal infill SurfaceFill to add these extrusions to.
SurfaceFill *internal_solid_fill = nullptr;
unsigned int region_id = 0;
@@ -277,11 +274,11 @@ std::vector group_fills(const Layer &layer)
}
if (internal_solid_fill == nullptr) {
// Produce another solid fill.
- params.extruder = layerm.region()->extruder(frSolidInfill);
- params.pattern = layerm.region()->config().top_fill_pattern == ipMonotonic ? ipMonotonic : ipRectilinear;
+ params.extruder = layerm.region().extruder(frSolidInfill);
+ params.pattern = layerm.region().config().top_fill_pattern == ipMonotonic ? ipMonotonic : ipRectilinear;
params.density = 100.f;
params.extrusion_role = erInternalInfill;
- params.angle = float(Geometry::deg2rad(layerm.region()->config().fill_angle.value));
+ params.angle = float(Geometry::deg2rad(layerm.region().config().fill_angle.value));
// calculate the actual flow we'll be using for this infill
params.flow = layerm.flow(frSolidInfill);
params.spacing = params.flow.spacing();
@@ -504,7 +501,7 @@ void Layer::make_ironing()
for (LayerRegion *layerm : m_regions)
if (! layerm->slices.empty()) {
IroningParams ironing_params;
- const PrintRegionConfig &config = layerm->region()->config();
+ const PrintRegionConfig &config = layerm->region().config();
if (config.ironing &&
(config.ironing_type == IroningType::AllSolid ||
(config.top_solid_layers > 0 &&
@@ -559,7 +556,7 @@ void Layer::make_ironing()
Polygons infills;
for (size_t k = i; k < j; ++ k) {
const IroningParams &ironing_params = by_extruder[k];
- const PrintRegionConfig ®ion_config = ironing_params.layerm->region()->config();
+ const PrintRegionConfig ®ion_config = ironing_params.layerm->region().config();
bool iron_everything = region_config.ironing_type == IroningType::AllSolid;
bool iron_completely = iron_everything;
if (iron_everything) {
@@ -596,7 +593,7 @@ void Layer::make_ironing()
// For IroningType::AllSolid only:
// Add solid infill areas for layers, that contain some non-ironable infil (sparse infill, bridge infill).
append(infills, to_polygons(std::move(ironing_areas)));
- ironing_areas = union_ex(infills, true);
+ ironing_areas = union_safety_offset_ex(infills);
}
}
diff --git a/src/libslic3r/Fill/FillAdaptive.cpp b/src/libslic3r/Fill/FillAdaptive.cpp
index 6b303e636a..3eabc6106c 100644
--- a/src/libslic3r/Fill/FillAdaptive.cpp
+++ b/src/libslic3r/Fill/FillAdaptive.cpp
@@ -291,13 +291,13 @@ std::pair adaptive_fill_line_spacing(const PrintObject &print_ob
double extrusion_width;
};
std::vector region_fill_data;
- region_fill_data.reserve(print_object.print()->regions().size());
+ region_fill_data.reserve(print_object.num_printing_regions());
bool build_octree = false;
const std::vector &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, float(max_nozzle_diameter));
- for (const PrintRegion *region : print_object.print()->regions()) {
- const PrintRegionConfig &config = region->config();
+ for (size_t region_id = 0; region_id < print_object.num_printing_regions(); ++ region_id) {
+ const PrintRegionConfig &config = print_object.printing_region(region_id).config();
bool nonempty = config.fill_density > 0;
bool has_adaptive_infill = nonempty && config.fill_pattern == ipAdaptiveCubic;
bool has_support_infill = nonempty && config.fill_pattern == ipSupportCubic;
diff --git a/src/libslic3r/Fill/FillLine.cpp b/src/libslic3r/Fill/FillLine.cpp
index f6431a3333..b7ab5430e4 100644
--- a/src/libslic3r/Fill/FillLine.cpp
+++ b/src/libslic3r/Fill/FillLine.cpp
@@ -58,7 +58,7 @@ void FillLine::_fill_surface_single(
pts.push_back(it->a);
pts.push_back(it->b);
}
- Polylines polylines = intersection_pl(polylines_src, offset(expolygon, scale_(0.02)), false);
+ Polylines polylines = intersection_pl(polylines_src, offset(expolygon, scale_(0.02)));
// FIXME Vojtech: This is only performed for horizontal lines, not for the vertical lines!
const float INFILL_OVERLAP_OVER_SPACING = 0.3f;
diff --git a/src/libslic3r/Fill/FillPlanePath.cpp b/src/libslic3r/Fill/FillPlanePath.cpp
index 6385a880e9..f1e3884bc5 100644
--- a/src/libslic3r/Fill/FillPlanePath.cpp
+++ b/src/libslic3r/Fill/FillPlanePath.cpp
@@ -33,18 +33,16 @@ void FillPlanePath::_fill_surface_single(
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) {
// Convert points to a polyline, upscale.
- polylines.push_back(Polyline());
- Polyline &polyline = polylines.back();
+ Polylines polylines(1, Polyline());
+ Polyline &polyline = polylines.front();
polyline.points.reserve(pts.size());
for (const Vec2d &pt : pts)
- polyline.points.push_back(Point(
- 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(std::move(polylines), expolygon);
+ polyline.points.emplace_back(
+ coord_t(floor(pt.x() * distance_between_lines + 0.5)),
+ coord_t(floor(pt.y() * distance_between_lines + 0.5)));
+ polylines = intersection_pl(polylines, expolygon);
Polylines chained;
if (params.dont_connect() || params.density > 0.5 || polylines.size() <= 1)
chained = chain_polylines(std::move(polylines));
diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index c5b28b3a01..4368783a69 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -614,9 +614,44 @@ namespace DoExport {
static void update_print_estimated_times_stats(const GCodeProcessor& processor, PrintStatistics& print_statistics)
{
const GCodeProcessor::Result& result = processor.get_result();
- print_statistics.estimated_normal_print_time = get_time_dhms(result.time_statistics.modes[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Normal)].time);
+ print_statistics.estimated_normal_print_time = get_time_dhms(result.print_statistics.modes[static_cast(PrintEstimatedStatistics::ETimeMode::Normal)].time);
print_statistics.estimated_silent_print_time = processor.is_stealth_time_estimator_enabled() ?
- get_time_dhms(result.time_statistics.modes[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Stealth)].time) : "N/A";
+ get_time_dhms(result.print_statistics.modes[static_cast(PrintEstimatedStatistics::ETimeMode::Stealth)].time) : "N/A";
+ }
+
+ static void update_print_estimated_stats(const GCodeProcessor& processor, const std::vector& extruders, PrintStatistics& print_statistics)
+ {
+ const GCodeProcessor::Result& result = processor.get_result();
+ print_statistics.estimated_normal_print_time = get_time_dhms(result.print_statistics.modes[static_cast(PrintEstimatedStatistics::ETimeMode::Normal)].time);
+ print_statistics.estimated_silent_print_time = processor.is_stealth_time_estimator_enabled() ?
+ get_time_dhms(result.print_statistics.modes[static_cast(PrintEstimatedStatistics::ETimeMode::Stealth)].time) : "N/A";
+
+ // update filament statictics
+ double total_extruded_volume = 0.0;
+ double total_used_filament = 0.0;
+ double total_weight = 0.0;
+ double total_cost = 0.0;
+ for (auto volume : result.print_statistics.volumes_per_extruder) {
+ total_extruded_volume += volume.second;
+
+ size_t extruder_id = volume.first;
+ auto extruder = std::find_if(extruders.begin(), extruders.end(), [extruder_id](const Extruder& extr) { return extr.id() == extruder_id; });
+ if (extruder == extruders.end())
+ continue;
+
+ double s = PI * sqr(0.5* extruder->filament_diameter());
+ double weight = volume.second * extruder->filament_density() * 0.001;
+ total_used_filament += volume.second/s;
+ total_weight += weight;
+ total_cost += weight * extruder->filament_cost() * 0.001;
+ }
+
+ print_statistics.total_extruded_volume = total_extruded_volume;
+ print_statistics.total_used_filament = total_used_filament;
+ print_statistics.total_weight = total_weight;
+ print_statistics.total_cost = total_cost;
+
+ print_statistics.filament_stats = result.print_statistics.volumes_per_extruder;
}
#if ENABLE_VALIDATE_CUSTOM_GCODE
@@ -754,7 +789,8 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessor::Result* re
BOOST_LOG_TRIVIAL(debug) << "Start processing gcode, " << log_memory_info();
m_processor.process_file(path_tmp, true, [print]() { print->throw_if_canceled(); });
- DoExport::update_print_estimated_times_stats(m_processor, print->m_print_statistics);
+// DoExport::update_print_estimated_times_stats(m_processor, print->m_print_statistics);
+ DoExport::update_print_estimated_stats(m_processor, m_writer.extruders(), print->m_print_statistics);
#if ENABLE_GCODE_WINDOW
if (result != nullptr) {
*result = std::move(m_processor.extract_result());
@@ -796,19 +832,19 @@ namespace DoExport {
// get the minimum cross-section used in the print
std::vector mm3_per_mm;
for (auto object : print.objects()) {
- for (size_t region_id = 0; region_id < object->region_volumes.size(); ++ region_id) {
- const PrintRegion* region = print.regions()[region_id];
+ for (size_t region_id = 0; region_id < object->num_printing_regions(); ++ region_id) {
+ const PrintRegion ®ion = object->printing_region(region_id);
for (auto layer : object->layers()) {
const LayerRegion* layerm = layer->regions()[region_id];
- if (region->config().get_abs_value("perimeter_speed") == 0 ||
- region->config().get_abs_value("small_perimeter_speed") == 0 ||
- region->config().get_abs_value("external_perimeter_speed") == 0 ||
- region->config().get_abs_value("bridge_speed") == 0)
+ if (region.config().get_abs_value("perimeter_speed") == 0 ||
+ region.config().get_abs_value("small_perimeter_speed") == 0 ||
+ region.config().get_abs_value("external_perimeter_speed") == 0 ||
+ region.config().get_abs_value("bridge_speed") == 0)
mm3_per_mm.push_back(layerm->perimeters.min_mm3_per_mm());
- if (region->config().get_abs_value("infill_speed") == 0 ||
- region->config().get_abs_value("solid_infill_speed") == 0 ||
- region->config().get_abs_value("top_solid_infill_speed") == 0 ||
- region->config().get_abs_value("bridge_speed") == 0)
+ if (region.config().get_abs_value("infill_speed") == 0 ||
+ region.config().get_abs_value("solid_infill_speed") == 0 ||
+ region.config().get_abs_value("top_solid_infill_speed") == 0 ||
+ region.config().get_abs_value("bridge_speed") == 0)
{
// Minimal volumetric flow should not be calculated over ironing extrusions.
// Use following lambda instead of the built-it method.
@@ -887,8 +923,7 @@ namespace DoExport {
if (thumbnail_cb != nullptr)
{
const size_t max_row_length = 78;
- ThumbnailsList thumbnails;
- thumbnail_cb(thumbnails, sizes, true, true, true, true);
+ ThumbnailsList thumbnails = thumbnail_cb(ThumbnailsParams{ sizes, true, true, true, true });
for (const ThumbnailData& data : thumbnails)
{
if (data.is_valid())
@@ -958,7 +993,6 @@ namespace DoExport {
dst.first += buf;
++ dst.second;
};
- print_statistics.filament_stats.insert(std::pair{extruder.id(), (float)used_filament});
append(out_filament_used_mm, "%.2lf", used_filament);
append(out_filament_used_cm3, "%.2lf", extruded_volume * 0.001);
if (filament_weight > 0.) {
@@ -1113,16 +1147,17 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
const double layer_height = first_object->config().layer_height.value;
assert(! print.config().first_layer_height.percent);
const double first_layer_height = print.config().first_layer_height.value;
- for (const PrintRegion* region : print.regions()) {
- _write_format(file, "; external perimeters extrusion width = %.2fmm\n", region->flow(*first_object, frExternalPerimeter, layer_height).width());
- _write_format(file, "; perimeters extrusion width = %.2fmm\n", region->flow(*first_object, frPerimeter, layer_height).width());
- _write_format(file, "; infill extrusion width = %.2fmm\n", region->flow(*first_object, frInfill, layer_height).width());
- _write_format(file, "; solid infill extrusion width = %.2fmm\n", region->flow(*first_object, frSolidInfill, layer_height).width());
- _write_format(file, "; top infill extrusion width = %.2fmm\n", region->flow(*first_object, frTopSolidInfill, layer_height).width());
+ for (size_t region_id = 0; region_id < print.num_print_regions(); ++ region_id) {
+ const PrintRegion ®ion = print.get_print_region(region_id);
+ _write_format(file, "; external perimeters extrusion width = %.2fmm\n", region.flow(*first_object, frExternalPerimeter, layer_height).width());
+ _write_format(file, "; perimeters extrusion width = %.2fmm\n", region.flow(*first_object, frPerimeter, layer_height).width());
+ _write_format(file, "; infill extrusion width = %.2fmm\n", region.flow(*first_object, frInfill, layer_height).width());
+ _write_format(file, "; solid infill extrusion width = %.2fmm\n", region.flow(*first_object, frSolidInfill, layer_height).width());
+ _write_format(file, "; top infill extrusion width = %.2fmm\n", region.flow(*first_object, frTopSolidInfill, layer_height).width());
if (print.has_support_material())
_write_format(file, "; support material extrusion width = %.2fmm\n", support_material_flow(first_object).width());
if (print.config().first_layer_extrusion_width.value > 0)
- _write_format(file, "; first layer extrusion width = %.2fmm\n", region->flow(*first_object, frPerimeter, first_layer_height, true).width());
+ _write_format(file, "; first layer extrusion width = %.2fmm\n", region.flow(*first_object, frPerimeter, first_layer_height, true).width());
_write_format(file, "\n");
}
print.throw_if_canceled();
@@ -1936,7 +1971,7 @@ void GCode::process_layer(
bool enable = (layer.id() > 0 || !print.has_brim()) && (layer.id() >= (size_t)print.config().skirt_height.value && ! print.has_infinite_skirt());
if (enable) {
for (const LayerRegion *layer_region : layer.regions())
- if (size_t(layer_region->region()->config().bottom_solid_layers.value) > layer.id() ||
+ if (size_t(layer_region->region().config().bottom_solid_layers.value) > layer.id() ||
layer_region->perimeters.items_count() > 1u ||
layer_region->fills.items_count() > 0) {
enable = false;
@@ -2110,7 +2145,9 @@ void GCode::process_layer(
const LayerRegion *layerm = layer.regions()[region_id];
if (layerm == nullptr)
continue;
- const PrintRegion ®ion = *print.regions()[region_id];
+ // PrintObjects own the PrintRegions, thus the pointer to PrintRegion would be unique to a PrintObject, they would not
+ // identify the content of PrintRegion accross the whole print uniquely. Translate to a Print specific PrintRegion.
+ const PrintRegion ®ion = print.get_print_region(layerm->region().print_region_id());
// Now we must process perimeters and infills and create islands of extrusions in by_region std::map.
// It is also necessary to save which extrusions are part of MM wiping and which are not.
@@ -2168,8 +2205,8 @@ void GCode::process_layer(
// extrusions->first_point fits inside ith slice
point_inside_surface(island_idx, extrusions->first_point())) {
if (islands[island_idx].by_region.empty())
- islands[island_idx].by_region.assign(print.regions().size(), ObjectByExtruder::Island::Region());
- islands[island_idx].by_region[region_id].append(entity_type, extrusions, entity_overrides);
+ islands[island_idx].by_region.assign(print.num_print_regions(), ObjectByExtruder::Island::Region());
+ islands[island_idx].by_region[region.print_region_id()].append(entity_type, extrusions, entity_overrides);
break;
}
}
@@ -2571,7 +2608,7 @@ std::string GCode::extrude_perimeters(const Print &print, const std::vectorconfig());
+ m_config.apply(print.get_print_region(®ion - &by_region.front()).config());
for (const ExtrusionEntity *ee : region.perimeters)
gcode += this->extrude_entity(*ee, "perimeter", -1., &lower_layer_edge_grid);
}
@@ -2592,7 +2629,7 @@ std::string GCode::extrude_infill(const Print &print, const std::vectorrole() == erIroning) == ironing)
extrusions.emplace_back(ee);
if (! extrusions.empty()) {
- m_config.apply(print.regions()[®ion - &by_region.front()]->config());
+ m_config.apply(print.get_print_region(®ion - &by_region.front()).config());
chain_and_reorder_extrusion_entities(extrusions, &m_last_pos);
for (const ExtrusionEntity *fill : extrusions) {
auto *eec = dynamic_cast(fill);
diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp
index 006595eb7d..917f84f40b 100644
--- a/src/libslic3r/GCode/GCodeProcessor.cpp
+++ b/src/libslic3r/GCode/GCodeProcessor.cpp
@@ -186,6 +186,72 @@ void GCodeProcessor::TimeMachine::CustomGCodeTime::reset()
times = std::vector>();
}
+void GCodeProcessor::UsedFilaments::reset()
+{
+ color_change_cache = 0.0f;
+ volumes_per_color_change = std::vector();
+
+ tool_change_cache = 0.0f;
+ volumes_per_extruder.clear();
+
+ role_cache = 0.0f;
+ filaments_per_role.clear();
+}
+
+void GCodeProcessor::UsedFilaments::increase_caches(double extruded_volume)
+{
+ color_change_cache += extruded_volume;
+ tool_change_cache += extruded_volume;
+ role_cache += extruded_volume;
+}
+
+void GCodeProcessor::UsedFilaments::process_color_change_cache()
+{
+ if (color_change_cache != 0.0f) {
+ volumes_per_color_change.push_back(color_change_cache);
+ color_change_cache = 0.0f;
+ }
+}
+
+void GCodeProcessor::UsedFilaments::process_extruder_cache(GCodeProcessor* processor)
+{
+ size_t active_extruder_id = processor->m_extruder_id;
+ if (tool_change_cache != 0.0f) {
+ if (volumes_per_extruder.find(active_extruder_id) != volumes_per_extruder.end())
+ volumes_per_extruder[active_extruder_id] += tool_change_cache;
+ else
+ volumes_per_extruder[active_extruder_id] = tool_change_cache;
+ tool_change_cache = 0.0f;
+ }
+}
+
+void GCodeProcessor::UsedFilaments::process_role_cache(GCodeProcessor* processor)
+{
+ if (role_cache != 0.0f) {
+ std::pair filament = { 0.0f, 0.0f };
+
+ double s = PI * sqr(0.5 * processor->m_filament_diameters[processor->m_extruder_id]);
+ filament.first = role_cache/s * 0.001;
+ filament.second = role_cache * processor->m_filament_densities[processor->m_extruder_id] * 0.001;
+
+ ExtrusionRole active_role = processor->m_extrusion_role;
+ if (filaments_per_role.find(active_role) != filaments_per_role.end()) {
+ filaments_per_role[active_role].first += filament.first;
+ filaments_per_role[active_role].second += filament.second;
+ }
+ else
+ filaments_per_role[active_role] = filament;
+ role_cache = 0.0f;
+ }
+}
+
+void GCodeProcessor::UsedFilaments::process_caches(GCodeProcessor* processor)
+{
+ process_color_change_cache();
+ process_extruder_cache(processor);
+ process_role_cache(processor);
+}
+
void GCodeProcessor::TimeMachine::reset()
{
enabled = false;
@@ -348,10 +414,10 @@ void GCodeProcessor::TimeProcessor::reset()
machine_limits = MachineEnvelopeConfig();
filament_load_times = std::vector();
filament_unload_times = std::vector();
- for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
+ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
machines[i].reset();
}
- machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Normal)].enabled = true;
+ machines[static_cast(PrintEstimatedStatistics::ETimeMode::Normal)].enabled = true;
}
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
@@ -416,19 +482,19 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
size_t g1_lines_counter = 0;
// keeps track of last exported pair
#if ENABLE_EXTENDED_M73_LINES
- std::array, static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count)> last_exported_main;
- for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
+ std::array, static_cast(PrintEstimatedStatistics::ETimeMode::Count)> last_exported_main;
+ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
last_exported_main[i] = { 0, time_in_minutes(machines[i].time) };
}
// keeps track of last exported remaining time to next printer stop
- std::array(PrintEstimatedTimeStatistics::ETimeMode::Count)> last_exported_stop;
- for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
+ std::array(PrintEstimatedStatistics::ETimeMode::Count)> last_exported_stop;
+ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
last_exported_stop[i] = time_in_minutes(machines[i].time);
}
#else
- std::array, static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count)> last_exported;
- for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
+ std::array, static_cast(PrintEstimatedStatistics::ETimeMode::Count)> last_exported;
+ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
last_exported[i] = { 0, time_in_minutes(machines[i].time) };
}
#endif // ENABLE_EXTENDED_M73_LINES
@@ -451,7 +517,7 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
line = line.substr(1);
if (export_remaining_time_enabled &&
(line == reserved_tag(ETags::First_Line_M73_Placeholder) || line == reserved_tag(ETags::Last_Line_M73_Placeholder))) {
- for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
+ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
const TimeMachine& machine = machines[i];
if (machine.enabled) {
#if ENABLE_EXTENDED_M73_LINES
@@ -486,7 +552,7 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
else if (line == reserved_tag(ETags::Estimated_Printing_Time_Placeholder)) {
#else
if (export_remaining_time_enabled && (line == First_Line_M73_Placeholder_Tag || line == Last_Line_M73_Placeholder_Tag)) {
- for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
+ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
const TimeMachine& machine = machines[i];
if (machine.enabled) {
ret += format_line_M73(machine.line_m73_mask.c_str(),
@@ -497,13 +563,13 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
}
else if (line == Estimated_Printing_Time_Placeholder_Tag) {
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
- for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
+ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
const TimeMachine& machine = machines[i];
- PrintEstimatedTimeStatistics::ETimeMode mode = static_cast(i);
- if (mode == PrintEstimatedTimeStatistics::ETimeMode::Normal || machine.enabled) {
+ PrintEstimatedStatistics::ETimeMode mode = static_cast(i);
+ if (mode == PrintEstimatedStatistics::ETimeMode::Normal || machine.enabled) {
char buf[128];
sprintf(buf, "; estimated printing time (%s mode) = %s\n",
- (mode == PrintEstimatedTimeStatistics::ETimeMode::Normal) ? "normal" : "silent",
+ (mode == PrintEstimatedStatistics::ETimeMode::Normal) ? "normal" : "silent",
get_time_dhms(machine.time).c_str());
ret += buf;
}
@@ -545,7 +611,7 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
unsigned int exported_lines_count = 0;
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
if (export_remaining_time_enabled) {
- for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
+ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
const TimeMachine& machine = machines[i];
if (machine.enabled) {
// export pair
@@ -789,13 +855,13 @@ GCodeProcessor::GCodeProcessor()
{
reset();
#if ENABLE_EXTENDED_M73_LINES
- m_time_processor.machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Normal)].line_m73_main_mask = "M73 P%s R%s\n";
- m_time_processor.machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Normal)].line_m73_stop_mask = "M73 C%s\n";
- m_time_processor.machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Stealth)].line_m73_main_mask = "M73 Q%s S%s\n";
- m_time_processor.machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Stealth)].line_m73_stop_mask = "M73 D%s\n";
+ m_time_processor.machines[static_cast(PrintEstimatedStatistics::ETimeMode::Normal)].line_m73_main_mask = "M73 P%s R%s\n";
+ m_time_processor.machines[static_cast(PrintEstimatedStatistics::ETimeMode::Normal)].line_m73_stop_mask = "M73 C%s\n";
+ m_time_processor.machines[static_cast(PrintEstimatedStatistics::ETimeMode::Stealth)].line_m73_main_mask = "M73 Q%s S%s\n";
+ m_time_processor.machines[static_cast(PrintEstimatedStatistics::ETimeMode::Stealth)].line_m73_stop_mask = "M73 D%s\n";
#else
- m_time_processor.machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Normal)].line_m73_mask = "M73 P%s R%s\n";
- m_time_processor.machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Stealth)].line_m73_mask = "M73 Q%s S%s\n";
+ m_time_processor.machines[static_cast(PrintEstimatedStatistics::ETimeMode::Normal)].line_m73_mask = "M73 P%s R%s\n";
+ m_time_processor.machines[static_cast(PrintEstimatedStatistics::ETimeMode::Stealth)].line_m73_mask = "M73 Q%s S%s\n";
#endif // ENABLE_EXTENDED_M73_LINES
}
@@ -826,6 +892,11 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
m_filament_diameters[i] = static_cast(config.filament_diameter.values[i]);
}
+ m_filament_densities.resize(config.filament_density.values.size());
+ for (size_t i = 0; i < config.filament_density.values.size(); ++i) {
+ m_filament_densities[i] = static_cast(config.filament_density.values[i]);
+ }
+
if ((m_flavor == gcfMarlinLegacy || m_flavor == gcfMarlinFirmware) && config.machine_limits_usage.value != MachineLimitsUsage::Ignore) {
m_time_processor.machine_limits = reinterpret_cast(config);
if (m_flavor == gcfMarlinLegacy) {
@@ -846,7 +917,7 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
m_time_processor.filament_unload_times[i] = static_cast(config.filament_unload_time.values[i]);
}
- for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
+ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
float max_acceleration = get_option_value(m_time_processor.machine_limits.machine_max_acceleration_extruding, i);
m_time_processor.machines[i].max_acceleration = max_acceleration;
m_time_processor.machines[i].acceleration = (max_acceleration > 0.0f) ? max_acceleration : DEFAULT_ACCELERATION;
@@ -896,6 +967,13 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
}
}
+ const ConfigOptionFloats* filament_densities = config.option("filament_density");
+ if (filament_densities != nullptr) {
+ for (double dens : filament_densities->values) {
+ m_filament_densities.push_back(static_cast(dens));
+ }
+ }
+
m_result.extruders_count = config.option("nozzle_diameter")->values.size();
const ConfigOptionPoints* extruder_offset = config.option("extruder_offset");
@@ -1026,7 +1104,7 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
m_time_processor.machine_limits.machine_min_travel_rate.values = machine_min_travel_rate->values;
}
- for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
+ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
float max_acceleration = get_option_value(m_time_processor.machine_limits.machine_max_acceleration_extruding, i);
m_time_processor.machines[i].max_acceleration = max_acceleration;
m_time_processor.machines[i].acceleration = (max_acceleration > 0.0f) ? max_acceleration : DEFAULT_ACCELERATION;
@@ -1051,7 +1129,7 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
void GCodeProcessor::enable_stealth_time_estimator(bool enabled)
{
- m_time_processor.machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Stealth)].enabled = enabled;
+ m_time_processor.machines[static_cast(PrintEstimatedStatistics::ETimeMode::Stealth)].enabled = enabled;
}
void GCodeProcessor::reset()
@@ -1096,6 +1174,7 @@ void GCodeProcessor::reset()
}
m_filament_diameters = std::vector(Min_Extruder_Count, 1.75f);
+ m_filament_densities = std::vector(Min_Extruder_Count, 1.245f);
m_extruded_last_z = 0.0f;
#if ENABLE_START_GCODE_VISUALIZATION
m_first_layer_height = 0.0f;
@@ -1109,6 +1188,7 @@ void GCodeProcessor::reset()
m_producers_enabled = false;
m_time_processor.reset();
+ m_used_filaments.reset();
m_result.reset();
m_result.id = ++s_result_id;
@@ -1186,7 +1266,7 @@ void GCodeProcessor::process_file(const std::string& filename, bool apply_postpr
}
// process the time blocks
- for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
+ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
TimeMachine& machine = m_time_processor.machines[i];
TimeMachine::CustomGCodeTime& gcode_time = machine.gcode_time;
machine.calculate_time();
@@ -1194,6 +1274,8 @@ void GCodeProcessor::process_file(const std::string& filename, bool apply_postpr
gcode_time.times.push_back({ CustomGCode::ColorChange, gcode_time.cache });
}
+ m_used_filaments.process_caches(this);
+
update_estimated_times_stats();
// post-process to add M73 lines into the gcode
@@ -1216,20 +1298,20 @@ void GCodeProcessor::process_file(const std::string& filename, bool apply_postpr
#endif // ENABLE_GCODE_VIEWER_STATISTICS
}
-float GCodeProcessor::get_time(PrintEstimatedTimeStatistics::ETimeMode mode) const
+float GCodeProcessor::get_time(PrintEstimatedStatistics::ETimeMode mode) const
{
- return (mode < PrintEstimatedTimeStatistics::ETimeMode::Count) ? m_time_processor.machines[static_cast(mode)].time : 0.0f;
+ return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? m_time_processor.machines[static_cast(mode)].time : 0.0f;
}
-std::string GCodeProcessor::get_time_dhm(PrintEstimatedTimeStatistics::ETimeMode mode) const
+std::string GCodeProcessor::get_time_dhm(PrintEstimatedStatistics::ETimeMode mode) const
{
- return (mode < PrintEstimatedTimeStatistics::ETimeMode::Count) ? short_time(get_time_dhms(m_time_processor.machines[static_cast(mode)].time)) : std::string("N/A");
+ return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? short_time(get_time_dhms(m_time_processor.machines[static_cast(mode)].time)) : std::string("N/A");
}
-std::vector>> GCodeProcessor::get_custom_gcode_times(PrintEstimatedTimeStatistics::ETimeMode mode, bool include_remaining) const
+std::vector>> GCodeProcessor::get_custom_gcode_times(PrintEstimatedStatistics::ETimeMode mode, bool include_remaining) const
{
std::vector>> ret;
- if (mode < PrintEstimatedTimeStatistics::ETimeMode::Count) {
+ if (mode < PrintEstimatedStatistics::ETimeMode::Count) {
const TimeMachine& machine = m_time_processor.machines[static_cast(mode)];
float total_time = 0.0f;
for (const auto& [type, time] : machine.gcode_time.times) {
@@ -1241,10 +1323,10 @@ std::vector>> GCodeProcesso
return ret;
}
-std::vector> GCodeProcessor::get_moves_time(PrintEstimatedTimeStatistics::ETimeMode mode) const
+std::vector> GCodeProcessor::get_moves_time(PrintEstimatedStatistics::ETimeMode mode) const
{
std::vector> ret;
- if (mode < PrintEstimatedTimeStatistics::ETimeMode::Count) {
+ if (mode < PrintEstimatedStatistics::ETimeMode::Count) {
for (size_t i = 0; i < m_time_processor.machines[static_cast(mode)].moves_time.size(); ++i) {
float time = m_time_processor.machines[static_cast(mode)].moves_time[i];
if (time > 0.0f)
@@ -1254,10 +1336,10 @@ std::vector> GCodeProcessor::get_moves_time(PrintEst
return ret;
}
-std::vector> GCodeProcessor::get_roles_time(PrintEstimatedTimeStatistics::ETimeMode mode) const
+std::vector> GCodeProcessor::get_roles_time(PrintEstimatedStatistics::ETimeMode mode) const
{
std::vector> ret;
- if (mode < PrintEstimatedTimeStatistics::ETimeMode::Count) {
+ if (mode < PrintEstimatedStatistics::ETimeMode::Count) {
for (size_t i = 0; i < m_time_processor.machines[static_cast(mode)].roles_time.size(); ++i) {
float time = m_time_processor.machines[static_cast(mode)].roles_time[i];
if (time > 0.0f)
@@ -1267,9 +1349,9 @@ std::vector> GCodeProcessor::get_roles_time(Prin
return ret;
}
-std::vector GCodeProcessor::get_layers_time(PrintEstimatedTimeStatistics::ETimeMode mode) const
+std::vector GCodeProcessor::get_layers_time(PrintEstimatedStatistics::ETimeMode mode) const
{
- return (mode < PrintEstimatedTimeStatistics::ETimeMode::Count) ?
+ return (mode < PrintEstimatedStatistics::ETimeMode::Count) ?
m_time_processor.machines[static_cast(mode)].layers_time :
std::vector();
}
@@ -1461,6 +1543,7 @@ void GCodeProcessor::process_tags(const std::string_view comment)
#if ENABLE_VALIDATE_CUSTOM_GCODE
// extrusion role tag
if (boost::starts_with(comment, reserved_tag(ETags::Role))) {
+ m_used_filaments.process_role_cache(this);
m_extrusion_role = ExtrusionEntity::string_to_role(comment.substr(reserved_tag(ETags::Role).length()));
#if ENABLE_SEAMS_VISUALIZATION
if (m_extrusion_role == erExternalPerimeter)
@@ -1546,7 +1629,8 @@ void GCodeProcessor::process_tags(const std::string_view comment)
extruder_id = static_cast(eid);
}
- m_extruder_colors[extruder_id] = static_cast(m_extruder_offsets.size()) + m_cp_color.counter; // color_change position in list of color for preview
+ if (extruder_id < m_extruder_colors.size())
+ m_extruder_colors[extruder_id] = static_cast(m_extruder_offsets.size()) + m_cp_color.counter; // color_change position in list of color for preview
++m_cp_color.counter;
if (m_cp_color.counter == UCHAR_MAX)
m_cp_color.counter = 0;
@@ -1557,6 +1641,7 @@ void GCodeProcessor::process_tags(const std::string_view comment)
}
process_custom_gcode_time(CustomGCode::ColorChange);
+ process_filaments(CustomGCode::ColorChange);
return;
}
@@ -1686,6 +1771,10 @@ bool GCodeProcessor::process_cura_tags(const std::string_view comment)
BOOST_LOG_TRIVIAL(warning) << "GCodeProcessor found unknown extrusion role: " << type;
}
+#if ENABLE_SEAMS_VISUALIZATION
+ if (m_extrusion_role == erExternalPerimeter)
+ m_seams_detector.activate(true);
+#endif // ENABLE_SEAMS_VISUALIZATION
return true;
}
@@ -1750,6 +1839,9 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string_view comment)
pos = cmt.find(" outer perimeter");
if (pos == 0) {
m_extrusion_role = erExternalPerimeter;
+#if ENABLE_SEAMS_VISUALIZATION
+ m_seams_detector.activate(true);
+#endif // ENABLE_SEAMS_VISUALIZATION
return true;
}
@@ -1904,6 +1996,11 @@ bool GCodeProcessor::process_craftware_tags(const std::string_view comment)
BOOST_LOG_TRIVIAL(warning) << "GCodeProcessor found unknown extrusion role: " << type;
}
+#if ENABLE_SEAMS_VISUALIZATION
+ if (m_extrusion_role == erExternalPerimeter)
+ m_seams_detector.activate(true);
+#endif // ENABLE_SEAMS_VISUALIZATION
+
return true;
}
@@ -1942,6 +2039,11 @@ bool GCodeProcessor::process_ideamaker_tags(const std::string_view comment)
m_extrusion_role = erNone;
BOOST_LOG_TRIVIAL(warning) << "GCodeProcessor found unknown extrusion role: " << type;
}
+
+#if ENABLE_SEAMS_VISUALIZATION
+ if (m_extrusion_role == erExternalPerimeter)
+ m_seams_detector.activate(true);
+#endif // ENABLE_SEAMS_VISUALIZATION
return true;
}
@@ -2010,6 +2112,9 @@ bool GCodeProcessor::process_kissslicer_tags(const std::string_view comment)
pos = comment.find(" 'Perimeter Path'");
if (pos == 0) {
m_extrusion_role = erExternalPerimeter;
+#if ENABLE_SEAMS_VISUALIZATION
+ m_seams_detector.activate(true);
+#endif // ENABLE_SEAMS_VISUALIZATION
return true;
}
@@ -2174,6 +2279,9 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
float volume_extruded_filament = area_filament_cross_section * delta_pos[E];
float area_toolpath_cross_section = volume_extruded_filament / delta_xyz;
+ // save extruded volume to the cache
+ m_used_filaments.increase_caches(volume_extruded_filament);
+
// volume extruded filament / tool displacement = area toolpath cross section
m_mm3_per_mm = area_toolpath_cross_section;
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
@@ -2234,7 +2342,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
assert(distance != 0.0f);
float inv_distance = 1.0f / distance;
- for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
+ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
TimeMachine& machine = m_time_processor.machines[i];
if (!machine.enabled)
continue;
@@ -2244,8 +2352,8 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
std::vector& blocks = machine.blocks;
curr.feedrate = (delta_pos[E] == 0.0f) ?
- minimum_travel_feedrate(static_cast(i), m_feedrate) :
- minimum_feedrate(static_cast(i), m_feedrate);
+ minimum_travel_feedrate(static_cast(i), m_feedrate) :
+ minimum_feedrate(static_cast(i), m_feedrate);
TimeBlock block;
block.move_type = type;
@@ -2263,7 +2371,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
curr.abs_axis_feedrate[a] = std::abs(curr.axis_feedrate[a]);
if (curr.abs_axis_feedrate[a] != 0.0f) {
- float axis_max_feedrate = get_axis_max_feedrate(static_cast(i), static_cast(a));
+ float axis_max_feedrate = get_axis_max_feedrate(static_cast(i), static_cast(a));
if (axis_max_feedrate != 0.0f)
min_feedrate_factor = std::min(min_feedrate_factor, axis_max_feedrate / curr.abs_axis_feedrate[a]);
}
@@ -2280,13 +2388,13 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
// calculates block acceleration
float acceleration =
- (type == EMoveType::Travel) ? get_travel_acceleration(static_cast(i)) :
+ (type == EMoveType::Travel) ? get_travel_acceleration(static_cast(i)) :
(is_extrusion_only_move(delta_pos) ?
- get_retract_acceleration(static_cast(i)) :
- get_acceleration(static_cast(i)));
+ get_retract_acceleration(static_cast(i)) :
+ get_acceleration(static_cast(i)));
for (unsigned char a = X; a <= E; ++a) {
- float axis_max_acceleration = get_axis_max_acceleration(static_cast(i), static_cast(a));
+ float axis_max_acceleration = get_axis_max_acceleration(static_cast(i), static_cast(a));
if (acceleration * std::abs(delta_pos[a]) * inv_distance > axis_max_acceleration)
acceleration = axis_max_acceleration;
}
@@ -2297,7 +2405,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
curr.safe_feedrate = block.feedrate_profile.cruise;
for (unsigned char a = X; a <= E; ++a) {
- float axis_max_jerk = get_axis_max_jerk(static_cast(i), static_cast(a));
+ float axis_max_jerk = get_axis_max_jerk(static_cast(i), static_cast(a));
if (curr.abs_axis_feedrate[a] > axis_max_jerk)
curr.safe_feedrate = std::min(curr.safe_feedrate, axis_max_jerk);
}
@@ -2345,7 +2453,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
// axis reversal
std::max(-v_exit, v_entry));
- float axis_max_jerk = get_axis_max_jerk(static_cast(i), static_cast(a));
+ float axis_max_jerk = get_axis_max_jerk(static_cast(i), static_cast(a));
if (jerk > axis_max_jerk) {
v_factor *= axis_max_jerk / jerk;
limited = true;
@@ -2385,27 +2493,28 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
}
#if ENABLE_SEAMS_VISUALIZATION
- // check for seam starting vertex
- if (type == EMoveType::Extrude && m_extrusion_role == erExternalPerimeter && m_seams_detector.is_active() && !m_seams_detector.has_first_vertex())
- m_seams_detector.set_first_vertex(m_result.moves.back().position - m_extruder_offsets[m_extruder_id]);
- // check for seam ending vertex and store the resulting move
- else if ((type != EMoveType::Extrude || m_extrusion_role != erExternalPerimeter) && m_seams_detector.is_active()) {
- auto set_end_position = [this](const Vec3f& pos) {
- m_end_position[X] = pos.x(); m_end_position[Y] = pos.y(); m_end_position[Z] = pos.z();
- };
+ if (m_seams_detector.is_active()) {
+ // check for seam starting vertex
+ if (type == EMoveType::Extrude && m_extrusion_role == erExternalPerimeter && !m_seams_detector.has_first_vertex())
+ m_seams_detector.set_first_vertex(m_result.moves.back().position - m_extruder_offsets[m_extruder_id]);
+ // check for seam ending vertex and store the resulting move
+ else if ((type != EMoveType::Extrude || m_extrusion_role != erExternalPerimeter) && m_seams_detector.has_first_vertex()) {
+ auto set_end_position = [this](const Vec3f& pos) {
+ m_end_position[X] = pos.x(); m_end_position[Y] = pos.y(); m_end_position[Z] = pos.z();
+ };
- assert(m_seams_detector.has_first_vertex());
- const Vec3f curr_pos(m_end_position[X], m_end_position[Y], m_end_position[Z]);
- const Vec3f new_pos = m_result.moves.back().position - m_extruder_offsets[m_extruder_id];
- const std::optional first_vertex = m_seams_detector.get_first_vertex();
- // the threshold value = 0.25 is arbitrary, we may find some smarter condition later
- if ((new_pos - *first_vertex).norm() < 0.25f) {
- set_end_position(0.5f * (new_pos + *first_vertex));
- store_move_vertex(EMoveType::Seam);
- set_end_position(curr_pos);
+ const Vec3f curr_pos(m_end_position[X], m_end_position[Y], m_end_position[Z]);
+ const Vec3f new_pos = m_result.moves.back().position - m_extruder_offsets[m_extruder_id];
+ const std::optional first_vertex = m_seams_detector.get_first_vertex();
+ // the threshold value = 0.0625f == 0.25 * 0.25 is arbitrary, we may find some smarter condition later
+ if ((new_pos - *first_vertex).squaredNorm() < 0.0625f) {
+ set_end_position(0.5f * (new_pos + *first_vertex));
+ store_move_vertex(EMoveType::Seam);
+ set_end_position(curr_pos);
+ }
+
+ m_seams_detector.activate(false);
}
-
- m_seams_detector.activate(false);
}
#endif // ENABLE_SEAMS_VISUALIZATION
@@ -2629,8 +2738,8 @@ void GCodeProcessor::process_M201(const GCodeReader::GCodeLine& line)
// see http://reprap.org/wiki/G-code#M201:_Set_max_printing_acceleration
float factor = ((m_flavor != gcfRepRapSprinter && m_flavor != gcfRepRapFirmware) && m_units == EUnits::Inches) ? INCHES_TO_MM : 1.0f;
- for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
- if (static_cast(i) == PrintEstimatedTimeStatistics::ETimeMode::Normal ||
+ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
+ if (static_cast(i) == PrintEstimatedStatistics::ETimeMode::Normal ||
m_time_processor.machine_envelope_processing_enabled) {
if (line.has_x())
set_option_value(m_time_processor.machine_limits.machine_max_acceleration_x, i, line.x() * factor);
@@ -2657,8 +2766,8 @@ void GCodeProcessor::process_M203(const GCodeReader::GCodeLine& line)
// http://smoothieware.org/supported-g-codes
float factor = (m_flavor == gcfMarlinLegacy || m_flavor == gcfMarlinFirmware || m_flavor == gcfSmoothie) ? 1.0f : MMMIN_TO_MMSEC;
- for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
- if (static_cast(i) == PrintEstimatedTimeStatistics::ETimeMode::Normal ||
+ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
+ if (static_cast(i) == PrintEstimatedStatistics::ETimeMode::Normal ||
m_time_processor.machine_envelope_processing_enabled) {
if (line.has_x())
set_option_value(m_time_processor.machine_limits.machine_max_feedrate_x, i, line.x() * factor);
@@ -2678,27 +2787,27 @@ void GCodeProcessor::process_M203(const GCodeReader::GCodeLine& line)
void GCodeProcessor::process_M204(const GCodeReader::GCodeLine& line)
{
float value;
- for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
- if (static_cast(i) == PrintEstimatedTimeStatistics::ETimeMode::Normal ||
+ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
+ if (static_cast(i) == PrintEstimatedStatistics::ETimeMode::Normal ||
m_time_processor.machine_envelope_processing_enabled) {
if (line.has_value('S', value)) {
// Legacy acceleration format. This format is used by the legacy Marlin, MK2 or MK3 firmware
// It is also generated by PrusaSlicer to control acceleration per extrusion type
// (perimeters, first layer etc) when 'Marlin (legacy)' flavor is used.
- set_acceleration(static_cast(i), value);
- set_travel_acceleration(static_cast(i), value);
+ set_acceleration(static_cast(i), value);
+ set_travel_acceleration(static_cast(i), value);
if (line.has_value('T', value))
set_option_value(m_time_processor.machine_limits.machine_max_acceleration_retracting, i, value);
}
else {
// New acceleration format, compatible with the upstream Marlin.
if (line.has_value('P', value))
- set_acceleration(static_cast(i), value);
+ set_acceleration(static_cast(i), value);
if (line.has_value('R', value))
set_option_value(m_time_processor.machine_limits.machine_max_acceleration_retracting, i, value);
if (line.has_value('T', value))
// Interpret the T value as the travel acceleration in the new Marlin format.
- set_travel_acceleration(static_cast(i), value);
+ set_travel_acceleration(static_cast(i), value);
}
}
}
@@ -2706,8 +2815,8 @@ void GCodeProcessor::process_M204(const GCodeReader::GCodeLine& line)
void GCodeProcessor::process_M205(const GCodeReader::GCodeLine& line)
{
- for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
- if (static_cast(i) == PrintEstimatedTimeStatistics::ETimeMode::Normal ||
+ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
+ if (static_cast(i) == PrintEstimatedStatistics::ETimeMode::Normal ||
m_time_processor.machine_envelope_processing_enabled) {
if (line.has_x()) {
float max_jerk = line.x();
@@ -2740,7 +2849,7 @@ void GCodeProcessor::process_M221(const GCodeReader::GCodeLine& line)
float value_t;
if (line.has_value('S', value_s) && !line.has_value('T', value_t)) {
value_s *= 0.01f;
- for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
+ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
m_time_processor.machines[i].extrude_factor_override_percentage = value_s;
}
}
@@ -2791,7 +2900,7 @@ void GCodeProcessor::process_M402(const GCodeReader::GCodeLine& line)
void GCodeProcessor::process_M566(const GCodeReader::GCodeLine& line)
{
- for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
+ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
if (line.has_x())
set_option_value(m_time_processor.machine_limits.machine_max_jerk_x, i, line.x() * MMMIN_TO_MMSEC);
@@ -2842,6 +2951,7 @@ void GCodeProcessor::process_T(const std::string_view command)
BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid toolchange, maybe from a custom gcode.";
else {
unsigned char old_extruder_id = m_extruder_id;
+ process_filaments(CustomGCode::ToolChange);
m_extruder_id = id;
m_cp_color.current = m_extruder_colors[id];
// Specific to the MK3 MMU2:
@@ -2899,7 +3009,7 @@ void GCodeProcessor::store_move_vertex(EMoveType type)
#if ENABLE_EXTENDED_M73_LINES
// stores stop time placeholders for later use
if (type == EMoveType::Color_change || type == EMoveType::Pause_Print) {
- for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
+ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
TimeMachine& machine = m_time_processor.machines[i];
if (!machine.enabled)
continue;
@@ -2910,7 +3020,7 @@ void GCodeProcessor::store_move_vertex(EMoveType type)
#endif // ENABLE_EXTENDED_M73_LINES
}
-float GCodeProcessor::minimum_feedrate(PrintEstimatedTimeStatistics::ETimeMode mode, float feedrate) const
+float GCodeProcessor::minimum_feedrate(PrintEstimatedStatistics::ETimeMode mode, float feedrate) const
{
if (m_time_processor.machine_limits.machine_min_extruding_rate.empty())
return feedrate;
@@ -2918,7 +3028,7 @@ float GCodeProcessor::minimum_feedrate(PrintEstimatedTimeStatistics::ETimeMode m
return std::max(feedrate, get_option_value(m_time_processor.machine_limits.machine_min_extruding_rate, static_cast(mode)));
}
-float GCodeProcessor::minimum_travel_feedrate(PrintEstimatedTimeStatistics::ETimeMode mode, float feedrate) const
+float GCodeProcessor::minimum_travel_feedrate(PrintEstimatedStatistics::ETimeMode mode, float feedrate) const
{
if (m_time_processor.machine_limits.machine_min_travel_rate.empty())
return feedrate;
@@ -2926,7 +3036,7 @@ float GCodeProcessor::minimum_travel_feedrate(PrintEstimatedTimeStatistics::ETim
return std::max(feedrate, get_option_value(m_time_processor.machine_limits.machine_min_travel_rate, static_cast(mode)));
}
-float GCodeProcessor::get_axis_max_feedrate(PrintEstimatedTimeStatistics::ETimeMode mode, Axis axis) const
+float GCodeProcessor::get_axis_max_feedrate(PrintEstimatedStatistics::ETimeMode mode, Axis axis) const
{
switch (axis)
{
@@ -2938,7 +3048,7 @@ float GCodeProcessor::get_axis_max_feedrate(PrintEstimatedTimeStatistics::ETimeM
}
}
-float GCodeProcessor::get_axis_max_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode, Axis axis) const
+float GCodeProcessor::get_axis_max_acceleration(PrintEstimatedStatistics::ETimeMode mode, Axis axis) const
{
switch (axis)
{
@@ -2950,7 +3060,7 @@ float GCodeProcessor::get_axis_max_acceleration(PrintEstimatedTimeStatistics::ET
}
}
-float GCodeProcessor::get_axis_max_jerk(PrintEstimatedTimeStatistics::ETimeMode mode, Axis axis) const
+float GCodeProcessor::get_axis_max_jerk(PrintEstimatedStatistics::ETimeMode mode, Axis axis) const
{
switch (axis)
{
@@ -2962,18 +3072,18 @@ float GCodeProcessor::get_axis_max_jerk(PrintEstimatedTimeStatistics::ETimeMode
}
}
-float GCodeProcessor::get_retract_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode) const
+float GCodeProcessor::get_retract_acceleration(PrintEstimatedStatistics::ETimeMode mode) const
{
return get_option_value(m_time_processor.machine_limits.machine_max_acceleration_retracting, static_cast(mode));
}
-float GCodeProcessor::get_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode) const
+float GCodeProcessor::get_acceleration(PrintEstimatedStatistics::ETimeMode mode) const
{
size_t id = static_cast(mode);
return (id < m_time_processor.machines.size()) ? m_time_processor.machines[id].acceleration : DEFAULT_ACCELERATION;
}
-void GCodeProcessor::set_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode, float value)
+void GCodeProcessor::set_acceleration(PrintEstimatedStatistics::ETimeMode mode, float value)
{
size_t id = static_cast(mode);
if (id < m_time_processor.machines.size()) {
@@ -2983,13 +3093,13 @@ void GCodeProcessor::set_acceleration(PrintEstimatedTimeStatistics::ETimeMode mo
}
}
-float GCodeProcessor::get_travel_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode) const
+float GCodeProcessor::get_travel_acceleration(PrintEstimatedStatistics::ETimeMode mode) const
{
size_t id = static_cast(mode);
return (id < m_time_processor.machines.size()) ? m_time_processor.machines[id].travel_acceleration : DEFAULT_TRAVEL_ACCELERATION;
}
-void GCodeProcessor::set_travel_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode, float value)
+void GCodeProcessor::set_travel_acceleration(PrintEstimatedStatistics::ETimeMode mode, float value)
{
size_t id = static_cast(mode);
if (id < m_time_processor.machines.size()) {
@@ -3017,7 +3127,7 @@ float GCodeProcessor::get_filament_unload_time(size_t extruder_id)
void GCodeProcessor::process_custom_gcode_time(CustomGCode::Type code)
{
- for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
+ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
TimeMachine& machine = m_time_processor.machines[i];
if (!machine.enabled)
continue;
@@ -3034,17 +3144,26 @@ void GCodeProcessor::process_custom_gcode_time(CustomGCode::Type code)
}
}
+void GCodeProcessor::process_filaments(CustomGCode::Type code)
+{
+ if (code == CustomGCode::ColorChange)
+ m_used_filaments.process_color_change_cache();
+
+ if (code == CustomGCode::ToolChange)
+ m_used_filaments.process_extruder_cache(this);
+}
+
void GCodeProcessor::simulate_st_synchronize(float additional_time)
{
- for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
+ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
m_time_processor.machines[i].simulate_st_synchronize(additional_time);
}
}
void GCodeProcessor::update_estimated_times_stats()
{
- auto update_mode = [this](PrintEstimatedTimeStatistics::ETimeMode mode) {
- PrintEstimatedTimeStatistics::Mode& data = m_result.time_statistics.modes[static_cast(mode)];
+ auto update_mode = [this](PrintEstimatedStatistics::ETimeMode mode) {
+ PrintEstimatedStatistics::Mode& data = m_result.print_statistics.modes[static_cast(mode)];
data.time = get_time(mode);
data.custom_gcode_times = get_custom_gcode_times(mode, true);
data.moves_times = get_moves_time(mode);
@@ -3052,11 +3171,15 @@ void GCodeProcessor::update_estimated_times_stats()
data.layers_times = get_layers_time(mode);
};
- update_mode(PrintEstimatedTimeStatistics::ETimeMode::Normal);
- if (m_time_processor.machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Stealth)].enabled)
- update_mode(PrintEstimatedTimeStatistics::ETimeMode::Stealth);
+ update_mode(PrintEstimatedStatistics::ETimeMode::Normal);
+ if (m_time_processor.machines[static_cast(PrintEstimatedStatistics::ETimeMode::Stealth)].enabled)
+ update_mode(PrintEstimatedStatistics::ETimeMode::Stealth);
else
- m_result.time_statistics.modes[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Stealth)].reset();
+ m_result.print_statistics.modes[static_cast(PrintEstimatedStatistics::ETimeMode::Stealth)].reset();
+
+ m_result.print_statistics.volumes_per_color_change = m_used_filaments.volumes_per_color_change;
+ m_result.print_statistics.volumes_per_extruder = m_used_filaments.volumes_per_extruder;
+ m_result.print_statistics.used_filaments_per_role = m_used_filaments.filaments_per_role;
}
} /* namespace Slic3r */
diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp
index 75ec1546b3..8975255ecf 100644
--- a/src/libslic3r/GCode/GCodeProcessor.hpp
+++ b/src/libslic3r/GCode/GCodeProcessor.hpp
@@ -36,7 +36,7 @@ namespace Slic3r {
Count
};
- struct PrintEstimatedTimeStatistics
+ struct PrintEstimatedStatistics
{
enum class ETimeMode : unsigned char
{
@@ -62,14 +62,21 @@ namespace Slic3r {
}
};
+ std::vector volumes_per_color_change;
+ std::map volumes_per_extruder;
+ std::map> used_filaments_per_role;
+
std::array(ETimeMode::Count)> modes;
- PrintEstimatedTimeStatistics() { reset(); }
+ PrintEstimatedStatistics() { reset(); }
void reset() {
for (auto m : modes) {
m.reset();
}
+ volumes_per_color_change.clear();
+ volumes_per_extruder.clear();
+ used_filaments_per_role.clear();
}
};
@@ -314,7 +321,7 @@ namespace Slic3r {
// Additional load / unload times for a filament exchange sequence.
std::vector filament_load_times;
std::vector filament_unload_times;
- std::array(PrintEstimatedTimeStatistics::ETimeMode::Count)> machines;
+ std::array(PrintEstimatedStatistics::ETimeMode::Count)> machines;
void reset();
@@ -327,6 +334,30 @@ namespace Slic3r {
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
};
+ struct UsedFilaments // filaments per ColorChange
+ {
+ double color_change_cache;
+ std::vector volumes_per_color_change;
+
+ double tool_change_cache;
+ std::map volumes_per_extruder;
+
+ double role_cache;
+ // ExtrusionRole :
+ std::map> filaments_per_role;
+
+ void reset();
+
+ void increase_caches(double extruded_volume);
+
+ void process_color_change_cache();
+ void process_extruder_cache(GCodeProcessor* processor);
+ void process_role_cache(GCodeProcessor* processor);
+ void process_caches(GCodeProcessor* processor);
+
+ friend class GCodeProcessor;
+ };
+
public:
#if !ENABLE_GCODE_LINES_ID_IN_H_SLIDER
struct MoveVertex
@@ -372,7 +403,7 @@ namespace Slic3r {
SettingsIds settings_ids;
size_t extruders_count;
std::vector extruder_colors;
- PrintEstimatedTimeStatistics time_statistics;
+ PrintEstimatedStatistics print_statistics;
#if ENABLE_GCODE_VIEWER_STATISTICS
int64_t time{ 0 };
@@ -519,6 +550,7 @@ namespace Slic3r {
ExtruderColors m_extruder_colors;
ExtruderTemps m_extruder_temps;
std::vector m_filament_diameters;
+ std::vector m_filament_densities;
float m_extruded_last_z;
#if ENABLE_START_GCODE_VISUALIZATION
float m_first_layer_height; // mm
@@ -550,6 +582,7 @@ namespace Slic3r {
bool m_producers_enabled;
TimeProcessor m_time_processor;
+ UsedFilaments m_used_filaments;
Result m_result;
static unsigned int s_result_id;
@@ -566,7 +599,7 @@ namespace Slic3r {
void apply_config(const PrintConfig& config);
void enable_stealth_time_estimator(bool enabled);
bool is_stealth_time_estimator_enabled() const {
- return m_time_processor.machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Stealth)].enabled;
+ return m_time_processor.machines[static_cast(PrintEstimatedStatistics::ETimeMode::Stealth)].enabled;
}
void enable_machine_envelope_processing(bool enabled) { m_time_processor.machine_envelope_processing_enabled = enabled; }
void enable_producers(bool enabled) { m_producers_enabled = enabled; }
@@ -579,13 +612,13 @@ namespace Slic3r {
// throws CanceledException through print->throw_if_canceled() (sent by the caller as callback).
void process_file(const std::string& filename, bool apply_postprocess, std::function cancel_callback = nullptr);
- float get_time(PrintEstimatedTimeStatistics::ETimeMode mode) const;
- std::string get_time_dhm(PrintEstimatedTimeStatistics::ETimeMode mode) const;
- std::vector>> get_custom_gcode_times(PrintEstimatedTimeStatistics::ETimeMode mode, bool include_remaining) const;
+ float get_time(PrintEstimatedStatistics::ETimeMode mode) const;
+ std::string get_time_dhm(PrintEstimatedStatistics::ETimeMode mode) const;
+ std::vector>> get_custom_gcode_times(PrintEstimatedStatistics::ETimeMode mode, bool include_remaining) const;
- std::vector> get_moves_time(PrintEstimatedTimeStatistics::ETimeMode mode) const;
- std::vector> get_roles_time(PrintEstimatedTimeStatistics::ETimeMode mode) const;
- std::vector get_layers_time(PrintEstimatedTimeStatistics::ETimeMode mode) const;
+ std::vector