Don't extrude acute angles
This commit is contained in:
parent
25ea8a0204
commit
ea88cad8e3
@ -3,6 +3,8 @@ use Moo;
|
||||
|
||||
extends 'Slic3r::Polyline';
|
||||
|
||||
use constant PI => 4 * atan2(1, 1);
|
||||
|
||||
sub clip_end {
|
||||
my $self = shift;
|
||||
my ($distance) = @_;
|
||||
@ -34,4 +36,36 @@ sub reverse {
|
||||
@{$self->points} = reverse @{$self->points};
|
||||
}
|
||||
|
||||
sub split_at_acute_angles {
|
||||
my $self = shift;
|
||||
|
||||
# calculate angle limit
|
||||
my $angle_limit = abs(Slic3r::Geometry::deg2rad(40));
|
||||
my @points = @{$self->p};
|
||||
|
||||
my @paths = ();
|
||||
|
||||
# take first two points
|
||||
my @p = splice @points, 0, 2;
|
||||
|
||||
# loop until we have one spare point
|
||||
while (my $p3 = shift @points) {
|
||||
my $angle = abs(Slic3r::Geometry::angle3points($p[-1], $p[-2], $p3));
|
||||
$angle = 2*PI - $angle if $angle > PI;
|
||||
|
||||
if ($angle < $angle_limit) {
|
||||
# if the angle between $p[-2], $p[-1], $p3 is too acute
|
||||
# then consider $p3 only as a starting point of a new
|
||||
# path and stop the current one as it is
|
||||
push @paths, __PACKAGE__->cast([@p]);
|
||||
@p = ($p3);
|
||||
push @p, grep $_, shift @points or last;
|
||||
} else {
|
||||
push @p, $p3;
|
||||
}
|
||||
}
|
||||
push @paths, __PACKAGE__->cast([@p]) if @p > 1;
|
||||
return @paths;
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -52,4 +52,11 @@ sub shortest_path {
|
||||
return @paths;
|
||||
}
|
||||
|
||||
sub cleanup {
|
||||
my $self = shift;
|
||||
|
||||
# split paths at angles that are too acute to be printed as they will cause blobs
|
||||
@{$self->paths} = map $_->split_at_acute_angles, @{$self->paths};
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -170,9 +170,10 @@ sub make_fill {
|
||||
}
|
||||
|
||||
# save into layer
|
||||
FINISH: push @{ $layer->fills }, Slic3r::ExtrusionPath::Collection->new(
|
||||
push @{ $layer->fills }, Slic3r::ExtrusionPath::Collection->new(
|
||||
paths => [ map Slic3r::ExtrusionPath->cast([ @$_ ]), @path_collection ],
|
||||
);
|
||||
$layer->fills->[-1]->cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,12 +8,12 @@ use constant X => 0;
|
||||
use constant Y => 1;
|
||||
|
||||
sub factor {
|
||||
return $Slic3r::resolution * 10;
|
||||
return $Slic3r::resolution * 100;
|
||||
}
|
||||
|
||||
sub svg {
|
||||
my ($print) = @_;
|
||||
|
||||
$print ||= Slic3r::Print->new(x_length => 200 / $Slic3r::resolution, y_length => 200 / $Slic3r::resolution);
|
||||
return SVG->new(width => $print->max_length * factor(), height => $print->max_length * factor());
|
||||
}
|
||||
|
||||
@ -56,7 +56,8 @@ sub output_points {
|
||||
}
|
||||
|
||||
sub output_polygons {
|
||||
my ($print, $filename, $polygons) = @_;
|
||||
my ($print, $filename, $polygons, $type) = @_;
|
||||
$type ||= 'polygon';
|
||||
|
||||
my $svg = svg($print);
|
||||
my $g = $svg->group(
|
||||
@ -72,7 +73,7 @@ sub output_polygons {
|
||||
'y' => [ map($_->[Y] * factor(), @$polygon) ],
|
||||
-type => 'polygon',
|
||||
);
|
||||
$g->polygon(
|
||||
$g->$type(
|
||||
%$path,
|
||||
);
|
||||
}
|
||||
@ -80,6 +81,10 @@ sub output_polygons {
|
||||
write_svg($svg, $filename);
|
||||
}
|
||||
|
||||
sub output_polylines {
|
||||
return output_polygons(@_, 'polyline');
|
||||
}
|
||||
|
||||
sub output_lines {
|
||||
my ($print, $filename, $lines) = @_;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user