New --fill-every-layers option to get high accuracy on external surfaces while speeding up infill
This commit is contained in:
parent
54cc6216a1
commit
7f341cfcd3
19
MANIFEST
19
MANIFEST
@ -1,25 +1,42 @@
|
|||||||
Build.PL
|
Build.PL
|
||||||
lib/Slic3r.pm
|
lib/Slic3r.pm
|
||||||
|
lib/Slic3r/Config.pm
|
||||||
|
lib/Slic3r/ExPolygon.pm
|
||||||
lib/Slic3r/Extruder.pm
|
lib/Slic3r/Extruder.pm
|
||||||
lib/Slic3r/ExtrusionLoop.pm
|
lib/Slic3r/ExtrusionLoop.pm
|
||||||
lib/Slic3r/ExtrusionPath.pm
|
lib/Slic3r/ExtrusionPath.pm
|
||||||
lib/Slic3r/ExtrusionPath/Collection.pm
|
lib/Slic3r/ExtrusionPath/Collection.pm
|
||||||
lib/Slic3r/Fill.pm
|
lib/Slic3r/Fill.pm
|
||||||
|
lib/Slic3r/Fill/Base.pm
|
||||||
lib/Slic3r/Fill/Rectilinear.pm
|
lib/Slic3r/Fill/Rectilinear.pm
|
||||||
|
lib/Slic3r/Fill/Rectilinear2.pm
|
||||||
lib/Slic3r/Geometry.pm
|
lib/Slic3r/Geometry.pm
|
||||||
|
lib/Slic3r/Geometry/Clipper.pm
|
||||||
lib/Slic3r/Geometry/DouglasPeucker.pm
|
lib/Slic3r/Geometry/DouglasPeucker.pm
|
||||||
|
lib/Slic3r/GUI.pm
|
||||||
|
lib/Slic3r/GUI/OptionsGroup.pm
|
||||||
|
lib/Slic3r/GUI/SkeinPanel.pm
|
||||||
lib/Slic3r/Layer.pm
|
lib/Slic3r/Layer.pm
|
||||||
lib/Slic3r/Line.pm
|
lib/Slic3r/Line.pm
|
||||||
|
lib/Slic3r/Line/FacetEdge.pm
|
||||||
|
lib/Slic3r/Line/FacetEdge/Bottom.pm
|
||||||
|
lib/Slic3r/Line/FacetEdge/Top.pm
|
||||||
lib/Slic3r/Perimeter.pm
|
lib/Slic3r/Perimeter.pm
|
||||||
lib/Slic3r/Point.pm
|
lib/Slic3r/Point.pm
|
||||||
|
lib/Slic3r/Polygon.pm
|
||||||
lib/Slic3r/Polyline.pm
|
lib/Slic3r/Polyline.pm
|
||||||
lib/Slic3r/Polyline/Closed.pm
|
lib/Slic3r/Polyline/Closed.pm
|
||||||
lib/Slic3r/Print.pm
|
lib/Slic3r/Print.pm
|
||||||
|
lib/Slic3r/Skein.pm
|
||||||
lib/Slic3r/STL.pm
|
lib/Slic3r/STL.pm
|
||||||
lib/Slic3r/Surface.pm
|
lib/Slic3r/Surface.pm
|
||||||
lib/Slic3r/Surface/Collection.pm
|
lib/Slic3r/Surface/Bridge.pm
|
||||||
lib/Slic3r/SVG.pm
|
lib/Slic3r/SVG.pm
|
||||||
MANIFEST This list of files
|
MANIFEST This list of files
|
||||||
README.markdown
|
README.markdown
|
||||||
slic3r.pl
|
slic3r.pl
|
||||||
t/clean_polylines.t
|
t/clean_polylines.t
|
||||||
|
t/clipper.t
|
||||||
|
t/geometry.t
|
||||||
|
t/polyclip.t
|
||||||
|
t/stl.t
|
||||||
|
@ -40,7 +40,7 @@ Slic3r current features are:
|
|||||||
* retraction;
|
* retraction;
|
||||||
* skirt (with rounded corners);
|
* skirt (with rounded corners);
|
||||||
* use relative or absolute extrusion commands;
|
* use relative or absolute extrusion commands;
|
||||||
* high-res perimeters (like the "Skin" plugin for Skeinforge);
|
* infill every N layers (like the "Skin" plugin for Skeinforge);
|
||||||
* detect optimal infill direction for bridges;
|
* detect optimal infill direction for bridges;
|
||||||
* save configuration profiles;
|
* save configuration profiles;
|
||||||
* center print around bed center point;
|
* center print around bed center point;
|
||||||
@ -53,6 +53,7 @@ Roadmap includes the following goals:
|
|||||||
|
|
||||||
* output some statistics;
|
* output some statistics;
|
||||||
* support material for internal perimeters;
|
* support material for internal perimeters;
|
||||||
|
* new and better GUI;
|
||||||
* cool;
|
* cool;
|
||||||
* other fill patterns.
|
* other fill patterns.
|
||||||
|
|
||||||
@ -111,9 +112,8 @@ The author is Alessandro Ranellucci (me).
|
|||||||
|
|
||||||
Accuracy options:
|
Accuracy options:
|
||||||
--layer-height Layer height in mm (default: 0.4)
|
--layer-height Layer height in mm (default: 0.4)
|
||||||
--high-res-perimeters
|
--infill-every-layers
|
||||||
Print perimeters at half layer height to get surface accuracy
|
Infill every N layers (default: 1)
|
||||||
(default: disabled)
|
|
||||||
|
|
||||||
Print options:
|
Print options:
|
||||||
--perimeters Number of perimeters/horizontal skins (range: 1+,
|
--perimeters Number of perimeters/horizontal skins (range: 1+,
|
||||||
|
@ -50,7 +50,7 @@ our $bottom_layer_speed_ratio = 0.3;
|
|||||||
# accuracy options
|
# accuracy options
|
||||||
our $resolution = 0.00000001;
|
our $resolution = 0.00000001;
|
||||||
our $layer_height = 0.4;
|
our $layer_height = 0.4;
|
||||||
our $high_res_perimeters = 0;
|
our $infill_every_layers = 1;
|
||||||
our $thickness_ratio = 1;
|
our $thickness_ratio = 1;
|
||||||
our $flow_width;
|
our $flow_width;
|
||||||
|
|
||||||
|
@ -64,9 +64,9 @@ our $Options = {
|
|||||||
label => 'Layer height (mm)',
|
label => 'Layer height (mm)',
|
||||||
type => 'f',
|
type => 'f',
|
||||||
},
|
},
|
||||||
'high_res_perimeters' => {
|
'infill_every_layers' => {
|
||||||
label => 'High-res perimeters',
|
label => 'Infill every N layers',
|
||||||
type => 'bool',
|
type => 'i',
|
||||||
},
|
},
|
||||||
|
|
||||||
# print options
|
# print options
|
||||||
@ -262,6 +262,12 @@ sub validate {
|
|||||||
die "Invalid value for --fill-density\n"
|
die "Invalid value for --fill-density\n"
|
||||||
if $Slic3r::fill_density < 0 || $Slic3r::fill_density > 1;
|
if $Slic3r::fill_density < 0 || $Slic3r::fill_density > 1;
|
||||||
|
|
||||||
|
# --infill-every-layers
|
||||||
|
die "Invalid value for --infill-every-layers\n"
|
||||||
|
if $Slic3r::infill_every_layers !~ /^\d+$/ || $Slic3r::infill_every_layers < 1;
|
||||||
|
die "Maximum infill thickness can't exceed nozzle diameter\n"
|
||||||
|
if $Slic3r::infill_every_layers * $Slic3r::layer_height > $Slic3r::nozzle_diameter;
|
||||||
|
|
||||||
# --scale
|
# --scale
|
||||||
die "Invalid value for --scale\n"
|
die "Invalid value for --scale\n"
|
||||||
if $Slic3r::scale <= 0;
|
if $Slic3r::scale <= 0;
|
||||||
|
@ -84,7 +84,7 @@ sub extrude {
|
|||||||
|
|
||||||
# compensate retraction
|
# compensate retraction
|
||||||
$gcode .= $self->unretract if $self->retracted;
|
$gcode .= $self->unretract if $self->retracted;
|
||||||
|
XXX "yes!\n" if $path->depth_layers > 1;
|
||||||
# extrude while going to next points
|
# extrude while going to next points
|
||||||
foreach my $line ($path->lines) {
|
foreach my $line ($path->lines) {
|
||||||
# calculate how much filament to drive into the extruder
|
# calculate how much filament to drive into the extruder
|
||||||
@ -93,7 +93,8 @@ sub extrude {
|
|||||||
* (($Slic3r::nozzle_diameter**2) / ($Slic3r::filament_diameter ** 2))
|
* (($Slic3r::nozzle_diameter**2) / ($Slic3r::filament_diameter ** 2))
|
||||||
* $Slic3r::thickness_ratio
|
* $Slic3r::thickness_ratio
|
||||||
* $self->flow_ratio
|
* $self->flow_ratio
|
||||||
* $Slic3r::filament_packing_density;
|
* $Slic3r::filament_packing_density
|
||||||
|
* $path->depth_layers;
|
||||||
|
|
||||||
$gcode .= $self->G1($line->b, undef, $e, $description);
|
$gcode .= $self->G1($line->b, undef, $e, $description);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,10 @@ use Moo;
|
|||||||
|
|
||||||
extends 'Slic3r::Polyline';
|
extends 'Slic3r::Polyline';
|
||||||
|
|
||||||
|
# this integer represents the vertical thickness of the extrusion
|
||||||
|
# expressed in layers
|
||||||
|
has 'depth_layers' => (is => 'ro', default => sub {1});
|
||||||
|
|
||||||
use constant PI => 4 * atan2(1, 1);
|
use constant PI => 4 * atan2(1, 1);
|
||||||
|
|
||||||
sub clip_end {
|
sub clip_end {
|
||||||
|
@ -48,14 +48,20 @@ sub make_fill {
|
|||||||
$filler = 'rectilinear';
|
$filler = 'rectilinear';
|
||||||
}
|
}
|
||||||
|
|
||||||
push @path_collection, $self->fillers->{$filler}->fill_surface($surface,
|
my @paths = $self->fillers->{$filler}->fill_surface(
|
||||||
|
$surface,
|
||||||
density => $density,
|
density => $density,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
push @path_collection, map Slic3r::ExtrusionPath->cast(
|
||||||
|
[ @$_ ],
|
||||||
|
depth_layers => $surface->depth_layers,
|
||||||
|
), @paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
# save into layer
|
# save into layer
|
||||||
push @{ $layer->fills }, Slic3r::ExtrusionPath::Collection->new(
|
push @{ $layer->fills }, Slic3r::ExtrusionPath::Collection->new(
|
||||||
paths => [ map Slic3r::ExtrusionPath->cast([ @$_ ]), @path_collection ],
|
paths => [ @path_collection ],
|
||||||
);
|
);
|
||||||
$layer->fills->[-1]->cleanup;
|
$layer->fills->[-1]->cleanup;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ sub infill_direction {
|
|||||||
@shift = @{$rotate[1]};
|
@shift = @{$rotate[1]};
|
||||||
|
|
||||||
# alternate fill direction
|
# alternate fill direction
|
||||||
if ($self->layer->id % 2) {
|
if (($self->layer->id / $surface->depth_layers) % 2) {
|
||||||
$rotate[0] = Slic3r::Geometry::deg2rad($Slic3r::fill_angle) + PI/2;
|
$rotate[0] = Slic3r::Geometry::deg2rad($Slic3r::fill_angle) + PI/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ sub new {
|
|||||||
),
|
),
|
||||||
accuracy => Slic3r::GUI::OptionsGroup->new($self,
|
accuracy => Slic3r::GUI::OptionsGroup->new($self,
|
||||||
title => 'Accuracy',
|
title => 'Accuracy',
|
||||||
options => [qw(layer_height high_res_perimeters)],
|
options => [qw(layer_height infill_every_layers)],
|
||||||
),
|
),
|
||||||
print => Slic3r::GUI::OptionsGroup->new($self,
|
print => Slic3r::GUI::OptionsGroup->new($self,
|
||||||
title => 'Print settings',
|
title => 'Print settings',
|
||||||
|
@ -4,11 +4,27 @@ use warnings;
|
|||||||
|
|
||||||
require Exporter;
|
require Exporter;
|
||||||
our @ISA = qw(Exporter);
|
our @ISA = qw(Exporter);
|
||||||
our @EXPORT_OK = qw(diff_ex diff union_ex);
|
our @EXPORT_OK = qw(explode_expolygon explode_expolygons safety_offset
|
||||||
|
diff_ex diff union_ex intersection_ex);
|
||||||
|
|
||||||
use Math::Clipper 1.02 ':all';
|
use Math::Clipper 1.02 ':all';
|
||||||
our $clipper = Math::Clipper->new;
|
our $clipper = Math::Clipper->new;
|
||||||
|
|
||||||
|
sub explode_expolygon {
|
||||||
|
my ($expolygon) = @_;
|
||||||
|
return ($expolygon->{outer}, @{ $expolygon->{holes} });
|
||||||
|
}
|
||||||
|
|
||||||
|
sub explode_expolygons {
|
||||||
|
my ($expolygons) = @_;
|
||||||
|
return map explode_expolygon($_), @$expolygons;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub safety_offset {
|
||||||
|
my ($polygons) = @_;
|
||||||
|
return Math::Clipper::offset($polygons, 100, 100, JT_MITER, 2);
|
||||||
|
}
|
||||||
|
|
||||||
sub diff_ex {
|
sub diff_ex {
|
||||||
my ($subject, $clip) = @_;
|
my ($subject, $clip) = @_;
|
||||||
|
|
||||||
@ -29,4 +45,13 @@ sub union_ex {
|
|||||||
return $clipper->ex_execute(CT_UNION, PFT_NONZERO, PFT_NONZERO);
|
return $clipper->ex_execute(CT_UNION, PFT_NONZERO, PFT_NONZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub intersection_ex {
|
||||||
|
my ($subject, $clip) = @_;
|
||||||
|
|
||||||
|
$clipper->clear;
|
||||||
|
$clipper->add_subject_polygons($subject);
|
||||||
|
$clipper->add_clip_polygons($clip);
|
||||||
|
return $clipper->ex_execute(CT_INTERSECTION, PFT_NONZERO, PFT_NONZERO);
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
@ -4,7 +4,7 @@ use Moo;
|
|||||||
use Math::Clipper ':all';
|
use Math::Clipper ':all';
|
||||||
use Slic3r::Geometry qw(polygon_lines points_coincide angle3points polyline_lines nearest_point
|
use Slic3r::Geometry qw(polygon_lines points_coincide angle3points polyline_lines nearest_point
|
||||||
line_length);
|
line_length);
|
||||||
use Slic3r::Geometry::Clipper qw(union_ex);
|
use Slic3r::Geometry::Clipper qw(safety_offset union_ex);
|
||||||
use XXX;
|
use XXX;
|
||||||
|
|
||||||
use constant PI => 4 * atan2(1, 1);
|
use constant PI => 4 * atan2(1, 1);
|
||||||
@ -184,7 +184,7 @@ sub make_surfaces {
|
|||||||
#) if !$next_lines;
|
#) if !$next_lines;
|
||||||
|
|
||||||
$next_lines
|
$next_lines
|
||||||
or die sprintf("No lines start at point %s. This shouldn't happen", $get_point_id->($points[-1]));
|
or die sprintf("No lines start at point %s. This shouldn't happen. Please check the model for manifoldness.", $get_point_id->($points[-1]));
|
||||||
last CYCLE if !@$next_lines;
|
last CYCLE if !@$next_lines;
|
||||||
|
|
||||||
my @ordered_next_lines = sort
|
my @ordered_next_lines = sort
|
||||||
@ -284,10 +284,7 @@ sub process_bridges {
|
|||||||
# offset the surface a bit to avoid approximation issues when doing the
|
# offset the surface a bit to avoid approximation issues when doing the
|
||||||
# intersection below (this is to make sure we overlap with supporting
|
# intersection below (this is to make sure we overlap with supporting
|
||||||
# surfaces, otherwise a little gap will result from intersection)
|
# surfaces, otherwise a little gap will result from intersection)
|
||||||
{
|
$surface_p = safety_offset([$surface_p])->[0];
|
||||||
my $offset = offset([$surface_p], 100, 100, JT_MITER, 2);
|
|
||||||
$surface_p = $offset->[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
#use Slic3r::SVG;
|
#use Slic3r::SVG;
|
||||||
#Slic3r::SVG::output(undef, "bridge.svg",
|
#Slic3r::SVG::output(undef, "bridge.svg",
|
||||||
|
@ -22,10 +22,10 @@ sub id {
|
|||||||
|
|
||||||
sub cast {
|
sub cast {
|
||||||
my $class = shift;
|
my $class = shift;
|
||||||
my ($points) = @_;
|
my ($points, %args) = @_;
|
||||||
|
|
||||||
$points = [ map { ref $_ eq 'ARRAY' ? Slic3r::Point->new($_) : $_ } @$points ];
|
$points = [ map { ref $_ eq 'ARRAY' ? Slic3r::Point->new($_) : $_ } @$points ];
|
||||||
return $class->new(points => $points);
|
return $class->new(points => $points, %args);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub lines {
|
sub lines {
|
||||||
|
@ -2,7 +2,7 @@ package Slic3r::Print;
|
|||||||
use Moo;
|
use Moo;
|
||||||
|
|
||||||
use Math::Clipper ':all';
|
use Math::Clipper ':all';
|
||||||
use Slic3r::Geometry::Clipper qw(diff_ex union_ex);
|
use Slic3r::Geometry::Clipper qw(explode_expolygons safety_offset diff_ex union_ex intersection_ex);
|
||||||
use XXX;
|
use XXX;
|
||||||
|
|
||||||
use constant X => 0;
|
use constant X => 0;
|
||||||
@ -145,7 +145,7 @@ sub detect_surfaces_type {
|
|||||||
|
|
||||||
# okay, this is an Ugly Hack(tm) to avoid floating point math problems
|
# okay, this is an Ugly Hack(tm) to avoid floating point math problems
|
||||||
# with diagonal bridges. will find a nicer solution, promised.
|
# with diagonal bridges. will find a nicer solution, promised.
|
||||||
my $offset = offset([$surface->contour->p], 100, 100, JT_MITER, 2);
|
my $offset = safety_offset([$surface->contour->p]);
|
||||||
@{$surface->contour->points} = map Slic3r::Point->new($_), @{ $offset->[0] };
|
@{$surface->contour->points} = map Slic3r::Point->new($_), @{ $offset->[0] };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,6 +301,91 @@ sub split_bridges_fills {
|
|||||||
$_->split_bridges_fills for @{$self->layers};
|
$_->split_bridges_fills for @{$self->layers};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# combine fill surfaces across layers
|
||||||
|
sub infill_every_layers {
|
||||||
|
my $self = shift;
|
||||||
|
return unless $Slic3r::infill_every_layers > 1;
|
||||||
|
|
||||||
|
printf "==> COMBINING INFILL\n";
|
||||||
|
|
||||||
|
# start from bottom, skip first layer
|
||||||
|
for (my $i = 1; $i < $self->layer_count; $i++) {
|
||||||
|
my $layer = $self->layer($i);
|
||||||
|
|
||||||
|
# skip layer if no internal fill surfaces
|
||||||
|
next if !grep $_->surface_type eq 'internal', map @$_, @{$layer->fill_surfaces};
|
||||||
|
|
||||||
|
# for each possible depth, look for intersections with the lower layer
|
||||||
|
# we do this from the greater depth to the smaller
|
||||||
|
for (my $d = $Slic3r::infill_every_layers - 1; $d >= 1; $d--) {
|
||||||
|
next if ($i - $d) < 0;
|
||||||
|
my $lower_layer = $self->layer($i - 1);
|
||||||
|
|
||||||
|
# select surfaces of the lower layer having the depth we're looking for
|
||||||
|
my @lower_surfaces = grep $_->depth_layers == $d && $_->surface_type eq 'internal',
|
||||||
|
map @$_, @{$lower_layer->fill_surfaces};
|
||||||
|
next if !@lower_surfaces;
|
||||||
|
# process each group of surfaces separately
|
||||||
|
foreach my $surfaces (@{$layer->fill_surfaces}) {
|
||||||
|
# calculate intersection between our surfaces and theirs
|
||||||
|
my $intersection = intersection_ex(
|
||||||
|
[ map $_->p, grep $_->depth_layers <= $d, @lower_surfaces ],
|
||||||
|
[ map $_->p, grep $_->surface_type eq 'internal', @$surfaces ],
|
||||||
|
);
|
||||||
|
next if !@$intersection;
|
||||||
|
|
||||||
|
# new fill surfaces of the current layer are:
|
||||||
|
# - any non-internal surface
|
||||||
|
# - intersections found (with a $d + 1 depth)
|
||||||
|
# - any internal surface not belonging to the intersection (with its original depth)
|
||||||
|
{
|
||||||
|
my @new_surfaces = ();
|
||||||
|
push @new_surfaces, grep $_->surface_type ne 'internal', @$surfaces;
|
||||||
|
push @new_surfaces, map Slic3r::Surface->cast_from_expolygon
|
||||||
|
($_, surface_type => 'internal', depth_layers => $d + 1), @$intersection;
|
||||||
|
|
||||||
|
foreach my $depth (reverse $d..$Slic3r::infill_every_layers) {
|
||||||
|
push @new_surfaces, map Slic3r::Surface->cast_from_expolygon
|
||||||
|
($_, surface_type => 'internal', depth_layers => $depth),
|
||||||
|
|
||||||
|
# difference between our internal layers with depth == $depth
|
||||||
|
# and the intersection found
|
||||||
|
@{diff_ex(
|
||||||
|
[
|
||||||
|
map $_->p, grep $_->surface_type eq 'internal' && $_->depth_layers == $depth,
|
||||||
|
@$surfaces,
|
||||||
|
],
|
||||||
|
safety_offset([ explode_expolygons($intersection) ]),
|
||||||
|
)};
|
||||||
|
}
|
||||||
|
@$surfaces = @new_surfaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
# now we remove the intersections from lower layer
|
||||||
|
foreach my $lower_surfaces (@{$lower_layer->fill_surfaces}) {
|
||||||
|
my @new_surfaces = ();
|
||||||
|
push @new_surfaces, grep $_->surface_type ne 'internal', @$lower_surfaces;
|
||||||
|
foreach my $depth (1..$Slic3r::infill_every_layers) {
|
||||||
|
push @new_surfaces, map Slic3r::Surface->cast_from_expolygon
|
||||||
|
($_, surface_type => 'internal', depth_layers => $depth),
|
||||||
|
|
||||||
|
# difference between internal layers with depth == $depth
|
||||||
|
# and the intersection found
|
||||||
|
@{diff_ex(
|
||||||
|
[
|
||||||
|
map $_->p, grep $_->surface_type eq 'internal' && $_->depth_layers == $depth,
|
||||||
|
@$lower_surfaces,
|
||||||
|
],
|
||||||
|
safety_offset([ explode_expolygons($intersection) ]),
|
||||||
|
)};
|
||||||
|
}
|
||||||
|
@$lower_surfaces = @new_surfaces;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sub extrude_fills {
|
sub extrude_fills {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
@ -345,19 +430,6 @@ sub export_gcode {
|
|||||||
|
|
||||||
# write gcode commands layer by layer
|
# write gcode commands layer by layer
|
||||||
foreach my $layer (@{ $self->layers }) {
|
foreach my $layer (@{ $self->layers }) {
|
||||||
|
|
||||||
# with the --high-res-perimeters options enabled we extrude perimeters for
|
|
||||||
# each layer twice at half height
|
|
||||||
if ($Slic3r::high_res_perimeters && $layer->id > 0) {
|
|
||||||
# go to half-layer
|
|
||||||
printf $fh $extruder->move_z($Slic3r::z_offset + $layer->z * $Slic3r::resolution - $Slic3r::layer_height/2);
|
|
||||||
|
|
||||||
# extrude perimeters
|
|
||||||
$extruder->flow_ratio(0.5);
|
|
||||||
printf $fh $extruder->extrude_loop($_, 'perimeter') for @{ $layer->perimeters };
|
|
||||||
$extruder->flow_ratio(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
# go to layer
|
# go to layer
|
||||||
printf $fh $extruder->move_z($Slic3r::z_offset + $layer->z * $Slic3r::resolution);
|
printf $fh $extruder->move_z($Slic3r::z_offset + $layer->z * $Slic3r::resolution);
|
||||||
|
|
||||||
|
@ -47,6 +47,9 @@ sub go {
|
|||||||
# they will be split in internal and internal-solid surfaces
|
# they will be split in internal and internal-solid surfaces
|
||||||
$print->discover_horizontal_shells;
|
$print->discover_horizontal_shells;
|
||||||
|
|
||||||
|
# combine fill surfaces to honor the "infill every N layers" option
|
||||||
|
$print->infill_every_layers;
|
||||||
|
|
||||||
# this will generate extrusion paths for each layer
|
# this will generate extrusion paths for each layer
|
||||||
$print->extrude_fills;
|
$print->extrude_fills;
|
||||||
|
|
||||||
|
@ -19,6 +19,9 @@ has 'surface_type' => (
|
|||||||
#isa => enum([qw(internal internal-solid bottom top)]),
|
#isa => enum([qw(internal internal-solid bottom top)]),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# this integer represents the thickness of the surface expressed in layers
|
||||||
|
has 'depth_layers' => (is => 'ro', default => sub {1});
|
||||||
|
|
||||||
sub cast_from_polygon {
|
sub cast_from_polygon {
|
||||||
my $class = shift;
|
my $class = shift;
|
||||||
my ($polygon, %args) = @_;
|
my ($polygon, %args) = @_;
|
||||||
@ -34,6 +37,7 @@ sub cast_from_expolygon {
|
|||||||
my ($expolygon, %args) = @_;
|
my ($expolygon, %args) = @_;
|
||||||
|
|
||||||
if (ref $expolygon ne 'HASH') {
|
if (ref $expolygon ne 'HASH') {
|
||||||
|
use XXX; ZZZ $expolygon if ref $expolygon eq 'ARRAY';
|
||||||
$expolygon = $expolygon->clipper_expolygon;
|
$expolygon = $expolygon->clipper_expolygon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ GetOptions(
|
|||||||
|
|
||||||
# accuracy options
|
# accuracy options
|
||||||
'layer-height=f' => \$Slic3r::layer_height,
|
'layer-height=f' => \$Slic3r::layer_height,
|
||||||
'high-res-perimeters' => \$Slic3r::high_res_perimeters,
|
'infill-every-layers=i' => \$Slic3r::infill_every_layers,
|
||||||
|
|
||||||
# print options
|
# print options
|
||||||
'perimeters=i' => \$Slic3r::perimeter_offsets,
|
'perimeters=i' => \$Slic3r::perimeter_offsets,
|
||||||
@ -147,9 +147,8 @@ Usage: slic3r.pl [ OPTIONS ] file.stl
|
|||||||
|
|
||||||
Accuracy options:
|
Accuracy options:
|
||||||
--layer-height Layer height in mm (default: $Slic3r::layer_height)
|
--layer-height Layer height in mm (default: $Slic3r::layer_height)
|
||||||
--high-res-perimeters
|
--infill-every-layers
|
||||||
Print perimeters at half layer height to get surface accuracy
|
Infill every N layers (default: $Slic3r::infill_every_layers)
|
||||||
(default: disabled)
|
|
||||||
|
|
||||||
Print options:
|
Print options:
|
||||||
--perimeters Number of perimeters/horizontal skins (range: 1+,
|
--perimeters Number of perimeters/horizontal skins (range: 1+,
|
||||||
|
Loading…
Reference in New Issue
Block a user