mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-12 11:59:03 +08:00
Keep edge lines in rectilinear infill even when the sides are not perfectly straight
This commit is contained in:
parent
99963775ff
commit
80676f358a
@ -84,6 +84,12 @@ sub wkt {
|
|||||||
join ',', map "($_)", map { join ',', map "$_->[0] $_->[1]", @$_ } @$self;
|
join ',', map "($_)", map { join ',', map "$_->[0] $_->[1]", @$_ } @$self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub dump_perl {
|
||||||
|
my $self = shift;
|
||||||
|
return sprintf "[%s]",
|
||||||
|
join ',', map "[$_]", map { join ',', map "[$_->[0],$_->[1]]", @$_ } @$self;
|
||||||
|
}
|
||||||
|
|
||||||
sub offset {
|
sub offset {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
return Slic3r::Geometry::Clipper::offset($self, @_);
|
return Slic3r::Geometry::Clipper::offset($self, @_);
|
||||||
|
@ -55,8 +55,11 @@ sub fill_surface {
|
|||||||
|
|
||||||
# clip paths against a slightly offsetted expolygon, so that the first and last paths
|
# clip paths against a slightly offsetted expolygon, so that the first and last paths
|
||||||
# are kept even if the expolygon has vertical sides
|
# are kept even if the expolygon has vertical sides
|
||||||
|
# the minimum offset for preventing edge lines from being clipped is scaled_epsilon;
|
||||||
|
# however we use a larger offset to support expolygons with slightly skewed sides and
|
||||||
|
# not perfectly straight
|
||||||
my @paths = @{ Boost::Geometry::Utils::multi_polygon_multi_linestring_intersection(
|
my @paths = @{ Boost::Geometry::Utils::multi_polygon_multi_linestring_intersection(
|
||||||
[ $expolygon->offset_ex(scaled_epsilon) ],
|
[ $expolygon->offset_ex($line_spacing*0.05) ],
|
||||||
[ @vertical_lines ],
|
[ @vertical_lines ],
|
||||||
) };
|
) };
|
||||||
|
|
||||||
|
22
t/fill.t
22
t/fill.t
@ -2,7 +2,7 @@ use Test::More;
|
|||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
plan tests => 31;
|
plan tests => 32;
|
||||||
|
|
||||||
BEGIN {
|
BEGIN {
|
||||||
use FindBin;
|
use FindBin;
|
||||||
@ -51,8 +51,8 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ }
|
|||||||
|
|
||||||
{
|
{
|
||||||
my $test = sub {
|
my $test = sub {
|
||||||
my ($expolygon) = @_;
|
my ($expolygon, $flow_spacing) = @_;
|
||||||
$expolygon->align_to_origin;
|
|
||||||
my $filler = Slic3r::Fill::Rectilinear->new(
|
my $filler = Slic3r::Fill::Rectilinear->new(
|
||||||
bounding_box => $expolygon->bounding_box,
|
bounding_box => $expolygon->bounding_box,
|
||||||
angle => 0,
|
angle => 0,
|
||||||
@ -61,12 +61,17 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ }
|
|||||||
surface_type => S_TYPE_BOTTOM,
|
surface_type => S_TYPE_BOTTOM,
|
||||||
expolygon => $expolygon,
|
expolygon => $expolygon,
|
||||||
);
|
);
|
||||||
my ($params, @paths) = $filler->fill_surface($surface, flow_spacing => 0.55, density => 1);
|
my ($params, @paths) = $filler->fill_surface($surface, flow_spacing => $flow_spacing, density => 1);
|
||||||
|
|
||||||
# check whether any part was left uncovered
|
# check whether any part was left uncovered
|
||||||
my @grown_paths = map Slic3r::Polyline->new(@$_)->grow(scale $params->{flow_spacing}/2), @paths;
|
my @grown_paths = map Slic3r::Polyline->new(@$_)->grow(scale $params->{flow_spacing}/2), @paths;
|
||||||
my $uncovered = diff_ex([ @$expolygon ], [ @grown_paths ], 1);
|
my $uncovered = diff_ex([ @$expolygon ], [ @grown_paths ], 1);
|
||||||
|
|
||||||
|
# ignore very small dots
|
||||||
|
@$uncovered = grep $_->area > (scale $flow_spacing)**2, @$uncovered;
|
||||||
|
|
||||||
is scalar(@$uncovered), 0, 'solid surface is fully filled';
|
is scalar(@$uncovered), 0, 'solid surface is fully filled';
|
||||||
|
|
||||||
if (0 && @$uncovered) {
|
if (0 && @$uncovered) {
|
||||||
require "Slic3r/SVG.pm";
|
require "Slic3r/SVG.pm";
|
||||||
Slic3r::SVG::output(
|
Slic3r::SVG::output(
|
||||||
@ -84,12 +89,17 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ }
|
|||||||
[3116896, 20327272.01297],
|
[3116896, 20327272.01297],
|
||||||
[3116896, 9598327.01296997],
|
[3116896, 9598327.01296997],
|
||||||
]);
|
]);
|
||||||
$test->($expolygon);
|
$test->($expolygon, 0.55);
|
||||||
|
|
||||||
for (1..20) {
|
for (1..20) {
|
||||||
$expolygon->scale(1.05);
|
$expolygon->scale(1.05);
|
||||||
$test->($expolygon);
|
$test->($expolygon, 0.55);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$expolygon = Slic3r::ExPolygon->new(
|
||||||
|
[[59515297,5422499],[59531249,5578697],[59695801,6123186],[59965713,6630228],[60328214,7070685],[60773285,7434379],[61274561,7702115],[61819378,7866770],[62390306,7924789],[62958700,7866744],[63503012,7702244],[64007365,7434357],[64449960,7070398],[64809327,6634999],[65082143,6123325],[65245005,5584454],[65266967,5422499],[66267307,5422499],[66269190,8310081],[66275379,17810072],[66277259,20697500],[65267237,20697500],[65245004,20533538],[65082082,19994444],[64811462,19488579],[64450624,19048208],[64012101,18686514],[63503122,18415781],[62959151,18251378],[62453416,18198442],[62390147,18197355],[62200087,18200576],[61813519,18252990],[61274433,18415918],[60768598,18686517],[60327567,19047892],[59963609,19493297],[59695865,19994587],[59531222,20539379],[59515153,20697500],[58502480,20697500],[58502480,5422499]]
|
||||||
|
);
|
||||||
|
$test->($expolygon, 0.524341649025257);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user