New --perimeters-extrusion-width and --infill-extrusion-width options. #302
This commit is contained in:
parent
8a031fe501
commit
82dd3c7a3e
1
MANIFEST
1
MANIFEST
@ -18,6 +18,7 @@ lib/Slic3r/Fill/Line.pm
|
|||||||
lib/Slic3r/Fill/OctagramSpiral.pm
|
lib/Slic3r/Fill/OctagramSpiral.pm
|
||||||
lib/Slic3r/Fill/PlanePath.pm
|
lib/Slic3r/Fill/PlanePath.pm
|
||||||
lib/Slic3r/Fill/Rectilinear.pm
|
lib/Slic3r/Fill/Rectilinear.pm
|
||||||
|
lib/Slic3r/Flow.pm
|
||||||
lib/Slic3r/Format/AMF.pm
|
lib/Slic3r/Format/AMF.pm
|
||||||
lib/Slic3r/Format/AMF/Parser.pm
|
lib/Slic3r/Format/AMF/Parser.pm
|
||||||
lib/Slic3r/Format/OBJ.pm
|
lib/Slic3r/Format/OBJ.pm
|
||||||
|
@ -210,6 +210,10 @@ The author is Alessandro Ranellucci.
|
|||||||
Flow options (advanced):
|
Flow options (advanced):
|
||||||
--extrusion-width Set extrusion width manually; it accepts either an absolute value in mm
|
--extrusion-width Set extrusion width manually; it accepts either an absolute value in mm
|
||||||
(like 0.65) or a percentage over layer height (like 200%)
|
(like 0.65) or a percentage over layer height (like 200%)
|
||||||
|
--perimeters-extrusion-width
|
||||||
|
Set a different extrusion width for perimeters
|
||||||
|
--infill-extrusion-width
|
||||||
|
Set a different extrusion width for infill
|
||||||
--bridge-flow-ratio Multiplier for extrusion when bridging (> 0, default: 1)
|
--bridge-flow-ratio Multiplier for extrusion when bridging (> 0, default: 1)
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ use Slic3r::ExtrusionPath;
|
|||||||
use Slic3r::ExtrusionPath::Arc;
|
use Slic3r::ExtrusionPath::Arc;
|
||||||
use Slic3r::ExtrusionPath::Collection;
|
use Slic3r::ExtrusionPath::Collection;
|
||||||
use Slic3r::Fill;
|
use Slic3r::Fill;
|
||||||
|
use Slic3r::Flow;
|
||||||
use Slic3r::Format::AMF;
|
use Slic3r::Format::AMF;
|
||||||
use Slic3r::Format::OBJ;
|
use Slic3r::Format::OBJ;
|
||||||
use Slic3r::Format::STL;
|
use Slic3r::Format::STL;
|
||||||
@ -102,14 +103,14 @@ our $infill_every_layers = 1;
|
|||||||
# flow options
|
# flow options
|
||||||
our $extrusion_width = 0;
|
our $extrusion_width = 0;
|
||||||
our $first_layer_extrusion_width = 0;
|
our $first_layer_extrusion_width = 0;
|
||||||
|
our $perimeters_extrusion_width = 0;
|
||||||
|
our $infill_extrusion_width = 0;
|
||||||
our $bridge_flow_ratio = 1;
|
our $bridge_flow_ratio = 1;
|
||||||
our $overlap_factor = 0.5;
|
our $overlap_factor = 0.5;
|
||||||
our $flow_width;
|
our $flow = Slic3r::Flow->new;
|
||||||
our $min_flow_spacing;
|
our $first_layer_flow = undef;
|
||||||
our $flow_spacing;
|
our $perimeters_flow = Slic3r::Flow->new;
|
||||||
our $first_layer_flow_width;
|
our $infill_flow = Slic3r::Flow->new;
|
||||||
our $first_layer_min_flow_spacing;
|
|
||||||
our $first_layer_flow_spacing;
|
|
||||||
|
|
||||||
# print options
|
# print options
|
||||||
our $perimeters = 3;
|
our $perimeters = 3;
|
||||||
|
@ -204,10 +204,20 @@ our $Options = {
|
|||||||
type => 'f',
|
type => 'f',
|
||||||
},
|
},
|
||||||
'first_layer_extrusion_width' => {
|
'first_layer_extrusion_width' => {
|
||||||
label => 'First layer extrusion width (mm or %; leave zero to use default)',
|
label => 'First layer extrusion width (mm or % or 0 for default)',
|
||||||
cli => 'first-layer-extrusion-width=s',
|
cli => 'first-layer-extrusion-width=s',
|
||||||
type => 'f',
|
type => 'f',
|
||||||
},
|
},
|
||||||
|
'perimeters_extrusion_width' => {
|
||||||
|
label => 'Perimeters extrusion width (mm or % or 0 for default)',
|
||||||
|
cli => 'perimeters-extrusion-width=s',
|
||||||
|
type => 'f',
|
||||||
|
},
|
||||||
|
'infill_extrusion_width' => {
|
||||||
|
label => 'Infill extrusion width (mm or % or 0 for default)',
|
||||||
|
cli => 'infill-extrusion-width=s',
|
||||||
|
type => 'f',
|
||||||
|
},
|
||||||
'bridge_flow_ratio' => {
|
'bridge_flow_ratio' => {
|
||||||
label => 'Bridge flow ratio',
|
label => 'Bridge flow ratio',
|
||||||
cli => 'bridge-flow-ratio=f',
|
cli => 'bridge-flow-ratio=f',
|
||||||
@ -596,16 +606,13 @@ sub validate {
|
|||||||
if $Slic3r::_first_layer_height > $Slic3r::nozzle_diameter;
|
if $Slic3r::_first_layer_height > $Slic3r::nozzle_diameter;
|
||||||
|
|
||||||
# calculate flow
|
# calculate flow
|
||||||
($Slic3r::flow_width, $Slic3r::min_flow_spacing, $Slic3r::flow_spacing) = calculate_flow($Slic3r::extrusion_width);
|
$Slic3r::flow->calculate($Slic3r::extrusion_width);
|
||||||
Slic3r::debugf "Flow width = $Slic3r::flow_width\n";
|
$Slic3r::first_layer_flow->calculate($Slic3r::first_layer_extrusion_width)
|
||||||
Slic3r::debugf "Flow spacing = $Slic3r::flow_spacing\n";
|
if $Slic3r::first_layer_extrusion_width;
|
||||||
Slic3r::debugf "Min flow spacing = $Slic3r::min_flow_spacing\n";
|
$Slic3r::perimeters_flow->calculate($Slic3r::perimeters_extrusion_width || $Slic3r::extrusion_width);
|
||||||
|
$Slic3r::infill_flow->calculate($Slic3r::infill_extrusion_width || $Slic3r::extrusion_width);
|
||||||
# calculate first layer flow
|
Slic3r::debugf "Default flow width = %s, spacing = %s, min_spacing = %d\n",
|
||||||
($Slic3r::first_layer_flow_width, $Slic3r::first_layer_min_flow_spacing, $Slic3r::first_layer_flow_spacing) = calculate_flow($Slic3r::first_layer_extrusion_width || $Slic3r::extrusion_width);
|
$Slic3r::flow->width, $Slic3r::flow->spacing, $Slic3r::flow->min_spacing;
|
||||||
Slic3r::debugf "First Layer Flow width = $Slic3r::first_layer_flow_width\n";
|
|
||||||
Slic3r::debugf "First Layer Flow spacing = $Slic3r::first_layer_flow_spacing\n";
|
|
||||||
Slic3r::debugf "First Layer Min flow spacing = $Slic3r::first_layer_min_flow_spacing\n";
|
|
||||||
|
|
||||||
# --perimeters
|
# --perimeters
|
||||||
die "Invalid value for --perimeters\n"
|
die "Invalid value for --perimeters\n"
|
||||||
@ -723,44 +730,4 @@ sub replace_options {
|
|||||||
return $string;
|
return $string;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub calculate_flow {
|
|
||||||
my ($extrusion_width) = @_;
|
|
||||||
|
|
||||||
my ($flow_width, $min_flow_spacing, $flow_spacing);
|
|
||||||
if ($extrusion_width) {
|
|
||||||
$flow_width = $extrusion_width =~ /^(\d+(?:\.\d+)?)%$/
|
|
||||||
? ($Slic3r::layer_height * $1 / 100)
|
|
||||||
: $extrusion_width;
|
|
||||||
} else {
|
|
||||||
# here we calculate a sane default by matching the flow speed (at the nozzle)
|
|
||||||
# and the feed rate
|
|
||||||
my $volume = ($Slic3r::nozzle_diameter**2) * PI/4;
|
|
||||||
my $shape_threshold = $Slic3r::nozzle_diameter * $Slic3r::layer_height
|
|
||||||
+ ($Slic3r::layer_height**2) * PI/4;
|
|
||||||
if ($volume >= $shape_threshold) {
|
|
||||||
# rectangle with semicircles at the ends
|
|
||||||
$flow_width = (($Slic3r::nozzle_diameter**2) * PI + ($Slic3r::layer_height**2) * (4 - PI)) / (4 * $Slic3r::layer_height);
|
|
||||||
} else {
|
|
||||||
# rectangle with squished semicircles at the ends
|
|
||||||
$flow_width = $Slic3r::nozzle_diameter * ($Slic3r::nozzle_diameter/$Slic3r::layer_height - 4/PI + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
my $min_flow_width = $Slic3r::nozzle_diameter * 1.05;
|
|
||||||
my $max_flow_width = $Slic3r::nozzle_diameter * 1.4;
|
|
||||||
$flow_width = $max_flow_width if $flow_width > $max_flow_width;
|
|
||||||
$flow_width = $min_flow_width if $flow_width < $min_flow_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($flow_width >= ($Slic3r::nozzle_diameter + $Slic3r::layer_height)) {
|
|
||||||
# rectangle with semicircles at the ends
|
|
||||||
$min_flow_spacing = $flow_width - $Slic3r::layer_height * (1 - PI/4);
|
|
||||||
} else {
|
|
||||||
# rectangle with shrunk semicircles at the ends
|
|
||||||
$min_flow_spacing = $flow_width * (1 - PI/4) + $Slic3r::nozzle_diameter * PI/4;
|
|
||||||
}
|
|
||||||
$flow_spacing = $flow_width - $Slic3r::overlap_factor * ($flow_width - $min_flow_spacing);
|
|
||||||
|
|
||||||
return ($flow_width, $min_flow_spacing, $flow_spacing);
|
|
||||||
}
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
@ -102,7 +102,7 @@ sub extrude_loop {
|
|||||||
# clip the path to avoid the extruder to get exactly on the first point of the loop;
|
# clip the path to avoid the extruder to get exactly on the first point of the loop;
|
||||||
# if polyline was shorter than the clipping distance we'd get a null polyline, so
|
# if polyline was shorter than the clipping distance we'd get a null polyline, so
|
||||||
# we discard it in that case
|
# we discard it in that case
|
||||||
$extrusion_path->clip_end(scale($self->layer->flow_width || $Slic3r::flow_width) * 0.15);
|
$extrusion_path->clip_end(scale($self->layer ? $self->layer->flow->width : $Slic3r::flow->width) * 0.15);
|
||||||
return '' if !@{$extrusion_path->polyline};
|
return '' if !@{$extrusion_path->polyline};
|
||||||
|
|
||||||
# extrude along the path
|
# extrude along the path
|
||||||
@ -129,7 +129,7 @@ sub extrude_path {
|
|||||||
{
|
{
|
||||||
my $distance_from_last_pos = $self->last_pos->distance_to($path->points->[0]) * $Slic3r::scaling_factor;
|
my $distance_from_last_pos = $self->last_pos->distance_to($path->points->[0]) * $Slic3r::scaling_factor;
|
||||||
my $distance_threshold = $Slic3r::retract_before_travel;
|
my $distance_threshold = $Slic3r::retract_before_travel;
|
||||||
$distance_threshold = 2 * ($self->layer->flow_width || $Slic3r::flow_width) / $Slic3r::fill_density * sqrt(2)
|
$distance_threshold = 2 * ($self->layer ? $self->layer->flow->width : $Slic3r::flow->width) / $Slic3r::fill_density * sqrt(2)
|
||||||
if $Slic3r::fill_density > 0 && $description =~ /fill/;
|
if $Slic3r::fill_density > 0 && $description =~ /fill/;
|
||||||
|
|
||||||
if ($distance_from_last_pos >= $distance_threshold) {
|
if ($distance_from_last_pos >= $distance_threshold) {
|
||||||
@ -145,9 +145,9 @@ sub extrude_path {
|
|||||||
$gcode .= $self->unretract if $self->retracted;
|
$gcode .= $self->unretract if $self->retracted;
|
||||||
|
|
||||||
# calculate extrusion length per distance unit
|
# calculate extrusion length per distance unit
|
||||||
my $s = $path->flow_spacing || $self->layer->flow_spacing || $Slic3r::flow_spacing;
|
my $s = $path->flow_spacing || $self->layer ? $self->layer->flow->spacing : $Slic3r::flow->spacing;
|
||||||
my $h = $path->depth_layers * $self->layer->height;
|
my $h = $path->depth_layers * $self->layer->height;
|
||||||
my $w = ($s - $Slic3r::min_flow_spacing * $Slic3r::overlap_factor) / (1 - $Slic3r::overlap_factor);
|
my $w = ($s - ($self->layer ? $self->layer->flow->min_spacing : $Slic3r::flow->min_spacing) * $Slic3r::overlap_factor) / (1 - $Slic3r::overlap_factor);
|
||||||
|
|
||||||
my $area;
|
my $area;
|
||||||
if ($path->role == EXTR_ROLE_BRIDGE) {
|
if ($path->role == EXTR_ROLE_BRIDGE) {
|
||||||
|
@ -99,7 +99,7 @@ sub make_fill {
|
|||||||
|
|
||||||
# add spacing between adjacent surfaces
|
# add spacing between adjacent surfaces
|
||||||
{
|
{
|
||||||
my $distance = scale $layer->flow_spacing / 2;
|
my $distance = scale $layer->flow->spacing / 2;
|
||||||
my @offsets = ();
|
my @offsets = ();
|
||||||
foreach my $surface (@surfaces) {
|
foreach my $surface (@surfaces) {
|
||||||
my $expolygon = $surface->expolygon;
|
my $expolygon = $surface->expolygon;
|
||||||
@ -137,7 +137,7 @@ sub make_fill {
|
|||||||
SURFACE: foreach my $surface (@surfaces) {
|
SURFACE: foreach my $surface (@surfaces) {
|
||||||
my $filler = $Slic3r::fill_pattern;
|
my $filler = $Slic3r::fill_pattern;
|
||||||
my $density = $Slic3r::fill_density;
|
my $density = $Slic3r::fill_density;
|
||||||
my $flow_spacing = $layer->flow_spacing;
|
my $flow_spacing = $layer->flow->spacing;
|
||||||
my $is_bridge = $layer->id > 0 && $surface->surface_type == S_TYPE_BOTTOM;
|
my $is_bridge = $layer->id > 0 && $surface->surface_type == S_TYPE_BOTTOM;
|
||||||
my $is_solid = (grep { $surface->surface_type == $_ } S_TYPE_TOP, S_TYPE_BOTTOM, S_TYPE_INTERNALSOLID) ? 1 : 0;
|
my $is_solid = (grep { $surface->surface_type == $_ } S_TYPE_TOP, S_TYPE_BOTTOM, S_TYPE_INTERNALSOLID) ? 1 : 0;
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ sub fill_surface {
|
|||||||
$path->deserialize;
|
$path->deserialize;
|
||||||
|
|
||||||
# clip the path to avoid the extruder to get exactly on the first point of the loop
|
# clip the path to avoid the extruder to get exactly on the first point of the loop
|
||||||
$path->clip_end(scale($self->layer->flow_width || $Slic3r::flow_width) * 0.15);
|
$path->clip_end(scale($self->layer ? $self->layer->flow->width : $Slic3r::flow->width) * 0.15);
|
||||||
|
|
||||||
push @paths, $path->points if @{$path->points};
|
push @paths, $path->points if @{$path->points};
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ sub fill_surface {
|
|||||||
# infill math
|
# infill math
|
||||||
my $min_spacing = scale $params{flow_spacing};
|
my $min_spacing = scale $params{flow_spacing};
|
||||||
my $distance = $min_spacing / $params{density};
|
my $distance = $min_spacing / $params{density};
|
||||||
my $overlap_distance = scale($self->layer->flow_width || $Slic3r::flow_width) * 0.4;
|
my $overlap_distance = scale($self->layer ? $self->layer->flow->width : $Slic3r::flow->width) * 0.4;
|
||||||
|
|
||||||
my $cache_id = sprintf "d%s_s%s_a%s",
|
my $cache_id = sprintf "d%s_s%s_a%s",
|
||||||
$params{density}, $params{flow_spacing}, $rotate_vector->[0][0];
|
$params{density}, $params{flow_spacing}, $rotate_vector->[0][0];
|
||||||
|
@ -32,7 +32,7 @@ sub fill_surface {
|
|||||||
$flow_spacing = unscale $distance_between_lines;
|
$flow_spacing = unscale $distance_between_lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $overlap_distance = scale($self->layer->flow_width || $Slic3r::flow_width) * 0.4;
|
my $overlap_distance = scale($self->layer ? $self->layer->flow->width : $Slic3r::flow->width) * 0.4;
|
||||||
|
|
||||||
my $x = $bounding_box->[X1];
|
my $x = $bounding_box->[X1];
|
||||||
my $is_line_pattern = $self->isa('Slic3r::Fill::Line');
|
my $is_line_pattern = $self->isa('Slic3r::Fill::Line');
|
||||||
|
53
lib/Slic3r/Flow.pm
Normal file
53
lib/Slic3r/Flow.pm
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package Slic3r::Flow;
|
||||||
|
use Moo;
|
||||||
|
|
||||||
|
use Slic3r::Geometry qw(PI);
|
||||||
|
|
||||||
|
has 'width' => (is => 'rw');
|
||||||
|
has 'min_spacing' => (is => 'rw');
|
||||||
|
has 'spacing' => (is => 'rw');
|
||||||
|
|
||||||
|
sub calculate {
|
||||||
|
my $self = shift;
|
||||||
|
my ($extrusion_width) = @_;
|
||||||
|
|
||||||
|
my ($flow_width, $min_flow_spacing, $flow_spacing);
|
||||||
|
if ($extrusion_width) {
|
||||||
|
$flow_width = $extrusion_width =~ /^(\d+(?:\.\d+)?)%$/
|
||||||
|
? ($Slic3r::layer_height * $1 / 100)
|
||||||
|
: $extrusion_width;
|
||||||
|
} else {
|
||||||
|
# here we calculate a sane default by matching the flow speed (at the nozzle)
|
||||||
|
# and the feed rate
|
||||||
|
my $volume = ($Slic3r::nozzle_diameter**2) * PI/4;
|
||||||
|
my $shape_threshold = $Slic3r::nozzle_diameter * $Slic3r::layer_height
|
||||||
|
+ ($Slic3r::layer_height**2) * PI/4;
|
||||||
|
if ($volume >= $shape_threshold) {
|
||||||
|
# rectangle with semicircles at the ends
|
||||||
|
$flow_width = (($Slic3r::nozzle_diameter**2) * PI + ($Slic3r::layer_height**2) * (4 - PI)) / (4 * $Slic3r::layer_height);
|
||||||
|
} else {
|
||||||
|
# rectangle with squished semicircles at the ends
|
||||||
|
$flow_width = $Slic3r::nozzle_diameter * ($Slic3r::nozzle_diameter/$Slic3r::layer_height - 4/PI + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
my $min_flow_width = $Slic3r::nozzle_diameter * 1.05;
|
||||||
|
my $max_flow_width = $Slic3r::nozzle_diameter * 1.4;
|
||||||
|
$flow_width = $max_flow_width if $flow_width > $max_flow_width;
|
||||||
|
$flow_width = $min_flow_width if $flow_width < $min_flow_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($flow_width >= ($Slic3r::nozzle_diameter + $Slic3r::layer_height)) {
|
||||||
|
# rectangle with semicircles at the ends
|
||||||
|
$min_flow_spacing = $flow_width - $Slic3r::layer_height * (1 - PI/4);
|
||||||
|
} else {
|
||||||
|
# rectangle with shrunk semicircles at the ends
|
||||||
|
$min_flow_spacing = $flow_width * (1 - PI/4) + $Slic3r::nozzle_diameter * PI/4;
|
||||||
|
}
|
||||||
|
$flow_spacing = $flow_width - $Slic3r::overlap_factor * ($flow_width - $min_flow_spacing);
|
||||||
|
|
||||||
|
$self->width($flow_width);
|
||||||
|
$self->min_spacing($min_flow_spacing);
|
||||||
|
$self->spacing($flow_spacing);
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
@ -70,7 +70,7 @@ sub new {
|
|||||||
},
|
},
|
||||||
extrusion => {
|
extrusion => {
|
||||||
title => 'Extrusion',
|
title => 'Extrusion',
|
||||||
options => [qw(extrusion_width first_layer_extrusion_width bridge_flow_ratio)],
|
options => [qw(extrusion_width first_layer_extrusion_width perimeters_extrusion_width infill_extrusion_width bridge_flow_ratio)],
|
||||||
},
|
},
|
||||||
output => {
|
output => {
|
||||||
title => 'Output',
|
title => 'Output',
|
||||||
|
@ -890,7 +890,7 @@ sub arrange {
|
|||||||
# margin needed for the skirt
|
# margin needed for the skirt
|
||||||
my $skirt_margin;
|
my $skirt_margin;
|
||||||
if ($Slic3r::skirts > 0) {
|
if ($Slic3r::skirts > 0) {
|
||||||
$skirt_margin = ($Slic3r::flow_spacing * $Slic3r::skirts + $Slic3r::skirt_distance) * 2;
|
$skirt_margin = ($Slic3r::flow->spacing * $Slic3r::skirts + $Slic3r::skirt_distance) * 2;
|
||||||
} else {
|
} else {
|
||||||
$skirt_margin = 0;
|
$skirt_margin = 0;
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,9 @@ has 'slicing_errors' => (is => 'rw');
|
|||||||
has 'slice_z' => (is => 'lazy');
|
has 'slice_z' => (is => 'lazy');
|
||||||
has 'print_z' => (is => 'lazy');
|
has 'print_z' => (is => 'lazy');
|
||||||
has 'height' => (is => 'lazy');
|
has 'height' => (is => 'lazy');
|
||||||
has 'flow_spacing' => (is => 'lazy');
|
has 'flow' => (is => 'lazy');
|
||||||
has 'flow_width' => (is => 'lazy');
|
has 'perimeters_flow' => (is => 'lazy');
|
||||||
|
has 'infill_flow' => (is => 'lazy');
|
||||||
|
|
||||||
# collection of spare segments generated by slicing the original geometry;
|
# collection of spare segments generated by slicing the original geometry;
|
||||||
# these need to be merged in continuos (closed) polylines
|
# these need to be merged in continuos (closed) polylines
|
||||||
@ -101,14 +102,25 @@ sub _build_height {
|
|||||||
return $self->id == 0 ? $Slic3r::_first_layer_height : $Slic3r::layer_height;
|
return $self->id == 0 ? $Slic3r::_first_layer_height : $Slic3r::layer_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub _build_flow_spacing {
|
sub _build_flow {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
return $self->id == 0 ? $Slic3r::first_layer_flow_spacing : $Slic3r::flow_spacing;
|
return $self->id == 0 && $Slic3r::first_layer_flow
|
||||||
|
? $Slic3r::first_layer_flow
|
||||||
|
: $Slic3r::flow;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub _build_flow_width {
|
sub _build_perimeters_flow {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
return $self->id == 0 ? $Slic3r::first_layer_flow_width : $Slic3r::flow_width;
|
return $self->id == 0 && $Slic3r::first_layer_flow
|
||||||
|
? $Slic3r::first_layer_flow
|
||||||
|
: $Slic3r::perimeters_flow;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _build_infill_flow {
|
||||||
|
my $self = shift;
|
||||||
|
return $self->id == 0 && $Slic3r::first_layer_flow
|
||||||
|
? $Slic3r::first_layer_flow
|
||||||
|
: $Slic3r::infill_flow;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub add_line {
|
sub add_line {
|
||||||
@ -139,7 +151,7 @@ sub make_surfaces {
|
|||||||
|
|
||||||
# the contours must be offsetted by half extrusion width inwards
|
# the contours must be offsetted by half extrusion width inwards
|
||||||
{
|
{
|
||||||
my $distance = scale $self->flow_width / 2;
|
my $distance = scale $self->perimeters_flow->width / 2;
|
||||||
my @surfaces = @{$self->slices};
|
my @surfaces = @{$self->slices};
|
||||||
@{$self->slices} = ();
|
@{$self->slices} = ();
|
||||||
foreach my $surface (@surfaces) {
|
foreach my $surface (@surfaces) {
|
||||||
@ -158,12 +170,12 @@ sub make_surfaces {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (@$diff) {
|
if (@$diff) {
|
||||||
my $area_threshold = scale($self->flow_spacing) ** 2;
|
my $area_threshold = scale($self->perimeters_flow->spacing) ** 2;
|
||||||
@$diff = grep $_->area > ($area_threshold), @$diff;
|
@$diff = grep $_->area > ($area_threshold), @$diff;
|
||||||
|
|
||||||
push @{$self->thin_walls},
|
push @{$self->thin_walls},
|
||||||
grep $_,
|
grep $_,
|
||||||
map $_->medial_axis(scale $self->flow_width),
|
map $_->medial_axis(scale $self->perimeters_flow->width),
|
||||||
@$diff;
|
@$diff;
|
||||||
|
|
||||||
Slic3r::debugf " %d thin walls detected\n", scalar(@{$self->thin_walls}) if @{$self->thin_walls};
|
Slic3r::debugf " %d thin walls detected\n", scalar(@{$self->thin_walls}) if @{$self->thin_walls};
|
||||||
@ -213,8 +225,8 @@ sub make_perimeters {
|
|||||||
next unless $circumference <= $Slic3r::small_perimeter_length;
|
next unless $circumference <= $Slic3r::small_perimeter_length;
|
||||||
# revert the compensation done in make_surfaces() and get the actual radius
|
# revert the compensation done in make_surfaces() and get the actual radius
|
||||||
# of the hole
|
# of the hole
|
||||||
my $radius = ($circumference / PI / 2) - scale $self->flow_spacing/2;
|
my $radius = ($circumference / PI / 2) - scale $self->perimeters_flow->spacing/2;
|
||||||
my $new_radius = (scale($self->flow_width) + sqrt((scale($self->flow_width)**2) + (4*($radius**2)))) / 2;
|
my $new_radius = (scale($self->perimeters_flow->width) + sqrt((scale($self->perimeters_flow->width)**2) + (4*($radius**2)))) / 2;
|
||||||
# holes are always turned to contours, so reverse point order before and after
|
# holes are always turned to contours, so reverse point order before and after
|
||||||
$hole->reverse;
|
$hole->reverse;
|
||||||
my @offsetted = $hole->offset(+ ($new_radius - $radius));
|
my @offsetted = $hole->offset(+ ($new_radius - $radius));
|
||||||
@ -233,7 +245,7 @@ sub make_perimeters {
|
|||||||
push @{ $perimeters[-1] }, [@last_offsets];
|
push @{ $perimeters[-1] }, [@last_offsets];
|
||||||
|
|
||||||
# offset distance for inner loops
|
# offset distance for inner loops
|
||||||
$distance = scale $self->flow_spacing;
|
$distance = scale $self->perimeters_flow->spacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
# create one more offset to be used as boundary for fill
|
# create one more offset to be used as boundary for fill
|
||||||
@ -249,7 +261,7 @@ sub make_perimeters {
|
|||||||
);
|
);
|
||||||
push @{ $self->thin_fills },
|
push @{ $self->thin_fills },
|
||||||
grep $_,
|
grep $_,
|
||||||
map $_->medial_axis(scale $self->flow_width),
|
map $_->medial_axis(scale $self->perimeters_flow->width),
|
||||||
@$small_gaps if 0;
|
@$small_gaps if 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -321,7 +333,7 @@ sub add_perimeter {
|
|||||||
my $self = shift;
|
my $self = shift;
|
||||||
my ($polygon, $role) = @_;
|
my ($polygon, $role) = @_;
|
||||||
|
|
||||||
return unless $polygon->is_printable($self->flow_width);
|
return unless $polygon->is_printable($self->perimeters_flow->width);
|
||||||
push @{ $self->perimeters }, Slic3r::ExtrusionLoop->new(
|
push @{ $self->perimeters }, Slic3r::ExtrusionLoop->new(
|
||||||
polygon => $polygon,
|
polygon => $polygon,
|
||||||
role => (abs($polygon->length) <= $Slic3r::small_perimeter_length) ? EXTR_ROLE_SMALLPERIMETER : ($role // EXTR_ROLE_PERIMETER), #/
|
role => (abs($polygon->length) <= $Slic3r::small_perimeter_length) ? EXTR_ROLE_SMALLPERIMETER : ($role // EXTR_ROLE_PERIMETER), #/
|
||||||
@ -336,7 +348,7 @@ sub prepare_fill_surfaces {
|
|||||||
# merge too small internal surfaces with their surrounding tops
|
# merge too small internal surfaces with their surrounding tops
|
||||||
# (if they're too small, they can be treated as solid)
|
# (if they're too small, they can be treated as solid)
|
||||||
{
|
{
|
||||||
my $min_area = ((7 * $self->flow_spacing / $Slic3r::scaling_factor)**2) * PI;
|
my $min_area = ((7 * $self->infill_flow->spacing / $Slic3r::scaling_factor)**2) * PI;
|
||||||
my $small_internal = [
|
my $small_internal = [
|
||||||
grep { $_->expolygon->contour->area <= $min_area }
|
grep { $_->expolygon->contour->area <= $min_area }
|
||||||
grep { $_->surface_type == S_TYPE_INTERNAL }
|
grep { $_->surface_type == S_TYPE_INTERNAL }
|
||||||
@ -369,7 +381,7 @@ sub prepare_fill_surfaces {
|
|||||||
sub remove_small_surfaces {
|
sub remove_small_surfaces {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
my $distance = scale $self->flow_spacing / 2;
|
my $distance = scale $self->infill_flow->spacing / 2;
|
||||||
|
|
||||||
my @surfaces = @{$self->fill_surfaces};
|
my @surfaces = @{$self->fill_surfaces};
|
||||||
@{$self->fill_surfaces} = ();
|
@{$self->fill_surfaces} = ();
|
||||||
@ -429,7 +441,7 @@ sub process_bridges {
|
|||||||
# offset the contour and intersect it with the internal surfaces to discover
|
# offset the contour and intersect it with the internal surfaces to discover
|
||||||
# which of them has contact with our bridge
|
# which of them has contact with our bridge
|
||||||
my @supporting_surfaces = ();
|
my @supporting_surfaces = ();
|
||||||
my ($contour_offset) = $expolygon->contour->offset(scale $self->flow_spacing * sqrt(2));
|
my ($contour_offset) = $expolygon->contour->offset(scale $self->flow->spacing * sqrt(2));
|
||||||
foreach my $internal_surface (@internal_surfaces) {
|
foreach my $internal_surface (@internal_surfaces) {
|
||||||
my $intersection = intersection_ex([$contour_offset], [$internal_surface->p]);
|
my $intersection = intersection_ex([$contour_offset], [$internal_surface->p]);
|
||||||
if (@$intersection) {
|
if (@$intersection) {
|
||||||
|
@ -114,7 +114,7 @@ sub is_printable {
|
|||||||
# detect them and we would be discarding them.
|
# detect them and we would be discarding them.
|
||||||
my $p = $self->clone;
|
my $p = $self->clone;
|
||||||
$p->make_counter_clockwise;
|
$p->make_counter_clockwise;
|
||||||
return $p->offset(scale($flow_width || $Slic3r::flow_width) / 2) ? 1 : 0;
|
return $p->offset(scale($flow_width || $Slic3r::flow->width) / 2) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub is_valid {
|
sub is_valid {
|
||||||
|
@ -410,7 +410,7 @@ sub make_skirt {
|
|||||||
# draw outlines from outside to inside
|
# draw outlines from outside to inside
|
||||||
my @skirt = ();
|
my @skirt = ();
|
||||||
for (my $i = $Slic3r::skirts - 1; $i >= 0; $i--) {
|
for (my $i = $Slic3r::skirts - 1; $i >= 0; $i--) {
|
||||||
my $distance = scale ($Slic3r::skirt_distance + ($Slic3r::flow_spacing * $i));
|
my $distance = scale ($Slic3r::skirt_distance + ($Slic3r::flow->spacing * $i));
|
||||||
my $outline = offset([$convex_hull], $distance, $Slic3r::scaling_factor * 100, JT_ROUND);
|
my $outline = offset([$convex_hull], $distance, $Slic3r::scaling_factor * 100, JT_ROUND);
|
||||||
push @skirt, Slic3r::ExtrusionLoop->new(
|
push @skirt, Slic3r::ExtrusionLoop->new(
|
||||||
polygon => Slic3r::Polygon->new(@{$outline->[0]}),
|
polygon => Slic3r::Polygon->new(@{$outline->[0]}),
|
||||||
@ -440,9 +440,9 @@ sub write_gcode {
|
|||||||
extrusion_multiplier perimeter_speed infill_speed travel_speed scale)) {
|
extrusion_multiplier perimeter_speed infill_speed travel_speed scale)) {
|
||||||
printf $fh "; %s = %s\n", $_, Slic3r::Config->get($_);
|
printf $fh "; %s = %s\n", $_, Slic3r::Config->get($_);
|
||||||
}
|
}
|
||||||
printf $fh "; single wall width = %.2fmm\n", $Slic3r::flow_width;
|
printf $fh "; single wall width = %.2fmm\n", $Slic3r::flow->width;
|
||||||
printf $fh "; first layer single wall width = %.2fmm\n", $Slic3r::first_layer_flow_width
|
printf $fh "; first layer single wall width = %.2fmm\n", $Slic3r::first_layer_flow->width
|
||||||
if $Slic3r::first_layer_flow_width != $Slic3r::flow_width;
|
if $Slic3r::first_layer_flow;
|
||||||
print $fh "\n";
|
print $fh "\n";
|
||||||
|
|
||||||
# set up our extruder object
|
# set up our extruder object
|
||||||
|
@ -174,13 +174,13 @@ sub make_perimeters {
|
|||||||
my $layer = $self->layers->[$layer_id];
|
my $layer = $self->layers->[$layer_id];
|
||||||
my $upper_layer = $self->layers->[$layer_id+1];
|
my $upper_layer = $self->layers->[$layer_id+1];
|
||||||
|
|
||||||
my $overlap = $layer->flow_spacing; # one perimeter
|
my $overlap = $layer->perimeters_flow->spacing; # one perimeter
|
||||||
|
|
||||||
# compute polygons representing the thickness of the first external perimeter of
|
# compute polygons representing the thickness of the first external perimeter of
|
||||||
# the upper layer slices
|
# the upper layer slices
|
||||||
my $upper = diff_ex(
|
my $upper = diff_ex(
|
||||||
[ map @$_, map $_->expolygon->offset_ex(+ 0.5 * scale $layer->flow_spacing), @{$upper_layer->slices} ],
|
[ map @$_, map $_->expolygon->offset_ex(+ 0.5 * scale $layer->perimeters_flow->spacing), @{$upper_layer->slices} ],
|
||||||
[ map @$_, map $_->expolygon->offset_ex(- scale($overlap) + (0.5 * scale $layer->flow_spacing)), @{$upper_layer->slices} ],
|
[ map @$_, map $_->expolygon->offset_ex(- scale($overlap) + (0.5 * scale $layer->perimeters_flow->spacing)), @{$upper_layer->slices} ],
|
||||||
);
|
);
|
||||||
next if !@$upper;
|
next if !@$upper;
|
||||||
|
|
||||||
@ -189,10 +189,10 @@ sub make_perimeters {
|
|||||||
my $ignore = [];
|
my $ignore = [];
|
||||||
{
|
{
|
||||||
my $diff = diff_ex(
|
my $diff = diff_ex(
|
||||||
[ map @$_, map $_->expolygon->offset_ex(- ($Slic3r::perimeters-0.5) * scale $layer->flow_spacing), @{$layer->slices} ],
|
[ map @$_, map $_->expolygon->offset_ex(- ($Slic3r::perimeters-0.5) * scale $layer->perimeters_flow->spacing), @{$layer->slices} ],
|
||||||
[ map @{$_->expolygon}, @{$upper_layer->slices} ],
|
[ map @{$_->expolygon}, @{$upper_layer->slices} ],
|
||||||
);
|
);
|
||||||
$ignore = [ map @$_, map $_->offset_ex(scale $layer->flow_spacing), @$diff ];
|
$ignore = [ map @$_, map $_->offset_ex(scale $layer->perimeters_flow->spacing), @$diff ];
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach my $slice (@{$layer->slices}) {
|
foreach my $slice (@{$layer->slices}) {
|
||||||
@ -202,9 +202,9 @@ sub make_perimeters {
|
|||||||
# of our slice
|
# of our slice
|
||||||
my $hypothetical_perimeter;
|
my $hypothetical_perimeter;
|
||||||
{
|
{
|
||||||
my $outer = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-1.5) * scale $layer->flow_spacing) ];
|
my $outer = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-1.5) * scale $layer->perimeters_flow->spacing) ];
|
||||||
last CYCLE if !@$outer;
|
last CYCLE if !@$outer;
|
||||||
my $inner = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-0.5) * scale $layer->flow_spacing) ];
|
my $inner = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-0.5) * scale $layer->perimeters_flow->spacing) ];
|
||||||
last CYCLE if !@$inner;
|
last CYCLE if !@$inner;
|
||||||
$hypothetical_perimeter = diff_ex($outer, $inner);
|
$hypothetical_perimeter = diff_ex($outer, $inner);
|
||||||
}
|
}
|
||||||
@ -236,7 +236,7 @@ sub detect_surfaces_type {
|
|||||||
[ map { ref $_ eq 'ARRAY' ? $_ : ref $_ eq 'Slic3r::ExPolygon' ? @$_ : $_->p } @$clip_surfaces ],
|
[ map { ref $_ eq 'ARRAY' ? $_ : ref $_ eq 'Slic3r::ExPolygon' ? @$_ : $_->p } @$clip_surfaces ],
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
return grep $_->contour->is_printable($layer->flow_width),
|
return grep $_->contour->is_printable($layer->flow->width),
|
||||||
map Slic3r::Surface->new(expolygon => $_, surface_type => $result_type),
|
map Slic3r::Surface->new(expolygon => $_, surface_type => $result_type),
|
||||||
@$expolygons;
|
@$expolygons;
|
||||||
};
|
};
|
||||||
@ -310,14 +310,14 @@ sub discover_horizontal_shells {
|
|||||||
|
|
||||||
Slic3r::debugf "==> DISCOVERING HORIZONTAL SHELLS\n";
|
Slic3r::debugf "==> DISCOVERING HORIZONTAL SHELLS\n";
|
||||||
|
|
||||||
my $area_threshold = scale($Slic3r::flow_spacing) ** 2;
|
my $area_threshold = scale($Slic3r::flow->spacing) ** 2;
|
||||||
|
|
||||||
for (my $i = 0; $i < $self->layer_count; $i++) {
|
for (my $i = 0; $i < $self->layer_count; $i++) {
|
||||||
my $layer = $self->layers->[$i];
|
my $layer = $self->layers->[$i];
|
||||||
foreach my $type (S_TYPE_TOP, S_TYPE_BOTTOM) {
|
foreach my $type (S_TYPE_TOP, S_TYPE_BOTTOM) {
|
||||||
# find surfaces of current type for current layer
|
# find surfaces of current type for current layer
|
||||||
# and offset them to take perimeters into account
|
# and offset them to take perimeters into account
|
||||||
my @surfaces = map $_->offset($Slic3r::perimeters * scale $layer->flow_width),
|
my @surfaces = map $_->offset($Slic3r::perimeters * scale $layer->perimeters_flow->width),
|
||||||
grep $_->surface_type == $type, @{$layer->fill_surfaces} or next;
|
grep $_->surface_type == $type, @{$layer->fill_surfaces} or next;
|
||||||
my $surfaces_p = [ map $_->p, @surfaces ];
|
my $surfaces_p = [ map $_->p, @surfaces ];
|
||||||
Slic3r::debugf "Layer %d has %d surfaces of type '%s'\n",
|
Slic3r::debugf "Layer %d has %d surfaces of type '%s'\n",
|
||||||
@ -396,7 +396,7 @@ sub infill_every_layers {
|
|||||||
my $self = shift;
|
my $self = shift;
|
||||||
return unless $Slic3r::infill_every_layers > 1 && $Slic3r::fill_density > 0;
|
return unless $Slic3r::infill_every_layers > 1 && $Slic3r::fill_density > 0;
|
||||||
|
|
||||||
my $area_threshold = scale($Slic3r::flow_spacing) ** 2;
|
my $area_threshold = scale($Slic3r::flow->spacing) ** 2;
|
||||||
|
|
||||||
# start from bottom, skip first layer
|
# start from bottom, skip first layer
|
||||||
for (my $i = 1; $i < $self->layer_count; $i++) {
|
for (my $i = 1; $i < $self->layer_count; $i++) {
|
||||||
@ -512,13 +512,13 @@ sub generate_support_material {
|
|||||||
# those parts. a visibility check algorithm is needed.
|
# those parts. a visibility check algorithm is needed.
|
||||||
# @a = @{diff_ex(
|
# @a = @{diff_ex(
|
||||||
# [ map $_->p, grep $_->surface_type == S_TYPE_BOTTOM, @{$layer->slices} ],
|
# [ map $_->p, grep $_->surface_type == S_TYPE_BOTTOM, @{$layer->slices} ],
|
||||||
# [ map @$_, map $_->expolygon->offset_ex(scale $layer->flow_spacing * $Slic3r::perimeters),
|
# [ map @$_, map $_->expolygon->offset_ex(scale $layer->flow->spacing * $Slic3r::perimeters),
|
||||||
# grep $_->surface_type == S_TYPE_BOTTOM && defined $_->bridge_angle,
|
# grep $_->surface_type == S_TYPE_BOTTOM && defined $_->bridge_angle,
|
||||||
# @{$layer->fill_surfaces} ],
|
# @{$layer->fill_surfaces} ],
|
||||||
# )};
|
# )};
|
||||||
@a = map $_->expolygon->clone, grep $_->surface_type == S_TYPE_BOTTOM, @{$layer->slices};
|
@a = map $_->expolygon->clone, grep $_->surface_type == S_TYPE_BOTTOM, @{$layer->slices};
|
||||||
|
|
||||||
$_->simplify(scale $layer->flow_spacing * 3) for @a;
|
$_->simplify(scale $layer->flow->spacing * 3) for @a;
|
||||||
push @unsupported_expolygons, @a;
|
push @unsupported_expolygons, @a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -541,7 +541,7 @@ sub generate_support_material {
|
|||||||
#bridge_angle => $Slic3r::fill_angle + 45 + $angle,
|
#bridge_angle => $Slic3r::fill_angle + 45 + $angle,
|
||||||
),
|
),
|
||||||
density => 0.20,
|
density => 0.20,
|
||||||
flow_spacing => $Slic3r::flow_spacing,
|
flow_spacing => $Slic3r::flow->spacing,
|
||||||
);
|
);
|
||||||
my $params = shift @paths;
|
my $params = shift @paths;
|
||||||
|
|
||||||
|
@ -256,6 +256,10 @@ $j
|
|||||||
(like 0.65) or a percentage over layer height (like 200%)
|
(like 0.65) or a percentage over layer height (like 200%)
|
||||||
--first-layer-extrusion-width
|
--first-layer-extrusion-width
|
||||||
Set a different extrusion width for first layer
|
Set a different extrusion width for first layer
|
||||||
|
--perimeters-extrusion-width
|
||||||
|
Set a different extrusion width for perimeters
|
||||||
|
--infill-extrusion-width
|
||||||
|
Set a different extrusion width for infill
|
||||||
--bridge-flow-ratio Multiplier for extrusion when bridging (> 0, default: $Slic3r::bridge_flow_ratio)
|
--bridge-flow-ratio Multiplier for extrusion when bridging (> 0, default: $Slic3r::bridge_flow_ratio)
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
|
Loading…
Reference in New Issue
Block a user