Don't extrude acute angles
This commit is contained in:
parent
25ea8a0204
commit
ea88cad8e3
4 changed files with 52 additions and 5 deletions
|
@ -3,6 +3,8 @@ use Moo;
|
||||||
|
|
||||||
extends 'Slic3r::Polyline';
|
extends 'Slic3r::Polyline';
|
||||||
|
|
||||||
|
use constant PI => 4 * atan2(1, 1);
|
||||||
|
|
||||||
sub clip_end {
|
sub clip_end {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my ($distance) = @_;
|
my ($distance) = @_;
|
||||||
|
@ -34,4 +36,36 @@ sub reverse {
|
||||||
@{$self->points} = reverse @{$self->points};
|
@{$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;
|
1;
|
||||||
|
|
|
@ -52,4 +52,11 @@ sub shortest_path {
|
||||||
return @paths;
|
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;
|
1;
|
||||||
|
|
|
@ -170,9 +170,10 @@ sub make_fill {
|
||||||
}
|
}
|
||||||
|
|
||||||
# save into layer
|
# 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 ],
|
paths => [ map Slic3r::ExtrusionPath->cast([ @$_ ]), @path_collection ],
|
||||||
);
|
);
|
||||||
|
$layer->fills->[-1]->cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,12 @@ use constant X => 0;
|
||||||
use constant Y => 1;
|
use constant Y => 1;
|
||||||
|
|
||||||
sub factor {
|
sub factor {
|
||||||
return $Slic3r::resolution * 10;
|
return $Slic3r::resolution * 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub svg {
|
sub svg {
|
||||||
my ($print) = @_;
|
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());
|
return SVG->new(width => $print->max_length * factor(), height => $print->max_length * factor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,8 @@ sub output_points {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub output_polygons {
|
sub output_polygons {
|
||||||
my ($print, $filename, $polygons) = @_;
|
my ($print, $filename, $polygons, $type) = @_;
|
||||||
|
$type ||= 'polygon';
|
||||||
|
|
||||||
my $svg = svg($print);
|
my $svg = svg($print);
|
||||||
my $g = $svg->group(
|
my $g = $svg->group(
|
||||||
|
@ -72,7 +73,7 @@ sub output_polygons {
|
||||||
'y' => [ map($_->[Y] * factor(), @$polygon) ],
|
'y' => [ map($_->[Y] * factor(), @$polygon) ],
|
||||||
-type => 'polygon',
|
-type => 'polygon',
|
||||||
);
|
);
|
||||||
$g->polygon(
|
$g->$type(
|
||||||
%$path,
|
%$path,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -80,6 +81,10 @@ sub output_polygons {
|
||||||
write_svg($svg, $filename);
|
write_svg($svg, $filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub output_polylines {
|
||||||
|
return output_polygons(@_, 'polyline');
|
||||||
|
}
|
||||||
|
|
||||||
sub output_lines {
|
sub output_lines {
|
||||||
my ($print, $filename, $lines) = @_;
|
my ($print, $filename, $lines) = @_;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue