Rewrite honeycomb infill so that it only generates the pattern for the bounding box of the region instead of the full print, so reduce complexity of the clipping routine
This commit is contained in:
parent
ac4a0bcdd8
commit
961586fe8f
@ -14,69 +14,67 @@ sub fill_surface {
|
|||||||
my $self = shift;
|
my $self = shift;
|
||||||
my ($surface, %params) = @_;
|
my ($surface, %params) = @_;
|
||||||
|
|
||||||
# rotate polygons so that we can work with vertical lines here
|
|
||||||
my $expolygon = $surface->expolygon->clone;
|
|
||||||
my $rotate_vector = $self->infill_direction($surface);
|
my $rotate_vector = $self->infill_direction($surface);
|
||||||
|
|
||||||
# infill math
|
# cache hexagons math
|
||||||
my $min_spacing = scale $params{flow_spacing};
|
my $cache_id = sprintf "d%s_s%s", $params{density}, $params{flow_spacing};
|
||||||
my $distance = $min_spacing / $params{density};
|
my $m;
|
||||||
|
if (!($m = $self->cache->{$cache_id})) {
|
||||||
|
$m = $self->cache->{$cache_id} = {};
|
||||||
|
my $min_spacing = scale $params{flow_spacing};
|
||||||
|
$m->{distance} = $min_spacing / $params{density};
|
||||||
|
$m->{hex_side} = $m->{distance} / (sqrt(3)/2);
|
||||||
|
$m->{hex_width} = $m->{distance} * 2; # $m->{hex_width} == $m->{hex_side} * sqrt(3);
|
||||||
|
my $hex_height = $m->{hex_side} * 2;
|
||||||
|
$m->{pattern_height} = $hex_height + $m->{hex_side};
|
||||||
|
$m->{y_short} = $m->{distance} * sqrt(3)/3;
|
||||||
|
$m->{x_offset} = $min_spacing / 2;
|
||||||
|
$m->{y_offset} = $m->{x_offset} * sqrt(3)/3;
|
||||||
|
$m->{hex_center} = Slic3r::Point->new($m->{hex_width}/2, $m->{hex_side});
|
||||||
|
}
|
||||||
|
|
||||||
my $cache_id = sprintf "d%s_s%s_a%s",
|
my @polygons = ();
|
||||||
$params{density}, $params{flow_spacing}, $rotate_vector->[0][0];
|
{
|
||||||
if (!$self->cache->{$cache_id}) {
|
|
||||||
|
|
||||||
# hexagons math
|
|
||||||
my $hex_side = $distance / (sqrt(3)/2);
|
|
||||||
my $hex_width = $distance * 2; # $hex_width == $hex_side * sqrt(3);
|
|
||||||
my $hex_height = $hex_side * 2;
|
|
||||||
my $pattern_height = $hex_height + $hex_side;
|
|
||||||
my $y_short = $distance * sqrt(3)/3;
|
|
||||||
my $x_offset = $min_spacing / 2;
|
|
||||||
my $y_offset = $x_offset * sqrt(3)/3;
|
|
||||||
my $hex_center = Slic3r::Point->new($hex_width/2, $hex_side);
|
|
||||||
|
|
||||||
# adjust actual bounding box to the nearest multiple of our hex pattern
|
# adjust actual bounding box to the nearest multiple of our hex pattern
|
||||||
# and align it so that it matches across layers
|
# and align it so that it matches across layers
|
||||||
|
|
||||||
my $bounding_box = $self->bounding_box->clone;
|
my $bounding_box = $surface->expolygon->bounding_box;
|
||||||
$bounding_box->extents->[$_][MIN] = 0 for X, Y;
|
|
||||||
{
|
{
|
||||||
|
# rotate bounding box according to infill direction
|
||||||
my $bb_polygon = $bounding_box->polygon;
|
my $bb_polygon = $bounding_box->polygon;
|
||||||
$bb_polygon->scale(sqrt 2);
|
$bb_polygon->rotate($rotate_vector->[0][0], $m->{hex_center});
|
||||||
$bb_polygon->rotate($rotate_vector->[0][0], $hex_center);
|
|
||||||
$bounding_box = $bb_polygon->bounding_box;
|
$bounding_box = $bb_polygon->bounding_box;
|
||||||
# $bounding_box->y_min and $bounding_box->y_max represent the displacement between new bounding box offset and old one
|
|
||||||
$bounding_box->extents->[X][MIN] -= $bounding_box->x_min % $hex_width;
|
# extend bounding box so that our pattern will be aligned with other layers
|
||||||
$bounding_box->extents->[Y][MAX] -= $bounding_box->y_min % $pattern_height;
|
# $bounding_box->[X1] and [Y1] represent the displacement between new bounding box offset and old one
|
||||||
|
$bounding_box->extents->[X][MIN] -= $bounding_box->x_min % $m->{hex_width};
|
||||||
|
$bounding_box->extents->[Y][MIN] -= $bounding_box->y_min % $m->{pattern_height};
|
||||||
}
|
}
|
||||||
|
|
||||||
my @polygons = ();
|
|
||||||
my $x = $bounding_box->x_min;
|
my $x = $bounding_box->x_min;
|
||||||
while ($x <= $bounding_box->x_max) {
|
while ($x <= $bounding_box->x_max) {
|
||||||
my $p = [];
|
my $p = [];
|
||||||
|
|
||||||
my @x = ($x + $x_offset, $x + $distance - $x_offset);
|
my @x = ($x + $m->{x_offset}, $x + $m->{distance} - $m->{x_offset});
|
||||||
for (1..2) {
|
for (1..2) {
|
||||||
@$p = reverse @$p; # turn first half upside down
|
@$p = reverse @$p; # turn first half upside down
|
||||||
my @p = ();
|
my @p = ();
|
||||||
for (my $y = $bounding_box->x_min; $y <= $bounding_box->y_max; $y += $y_short + $hex_side + $y_short + $hex_side) {
|
for (my $y = $bounding_box->y_min; $y <= $bounding_box->y_max; $y += $m->{y_short} + $m->{hex_side} + $m->{y_short} + $m->{hex_side}) {
|
||||||
push @$p,
|
push @$p,
|
||||||
[ $x[1], $y + $y_offset ],
|
[ $x[1], $y + $m->{y_offset} ],
|
||||||
[ $x[0], $y + $y_short - $y_offset ],
|
[ $x[0], $y + $m->{y_short} - $m->{y_offset} ],
|
||||||
[ $x[0], $y + $y_short + $hex_side + $y_offset ],
|
[ $x[0], $y + $m->{y_short} + $m->{hex_side} + $m->{y_offset} ],
|
||||||
[ $x[1], $y + $y_short + $hex_side + $y_short - $y_offset ],
|
[ $x[1], $y + $m->{y_short} + $m->{hex_side} + $m->{y_short} - $m->{y_offset} ],
|
||||||
[ $x[1], $y + $y_short + $hex_side + $y_short + $hex_side + $y_offset ];
|
[ $x[1], $y + $m->{y_short} + $m->{hex_side} + $m->{y_short} + $m->{hex_side} + $m->{y_offset} ];
|
||||||
}
|
}
|
||||||
@x = map $_ + $distance, reverse @x; # draw symmetrical pattern
|
@x = map $_ + $m->{distance}, reverse @x; # draw symmetrical pattern
|
||||||
$x += $distance;
|
$x += $m->{distance};
|
||||||
}
|
}
|
||||||
|
|
||||||
push @polygons, Slic3r::Polygon->new($p);
|
push @polygons, Slic3r::Polygon->new($p);
|
||||||
}
|
}
|
||||||
|
|
||||||
$_->rotate(-$rotate_vector->[0][0], $hex_center) for @polygons;
|
$_->rotate(-$rotate_vector->[0][0], $m->{hex_center}) for @polygons;
|
||||||
$self->cache->{$cache_id} = [@polygons];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# consider polygons as polylines without re-appending the initial point:
|
# consider polygons as polylines without re-appending the initial point:
|
||||||
@ -84,8 +82,8 @@ sub fill_surface {
|
|||||||
# path is more straight
|
# path is more straight
|
||||||
my @paths = map Slic3r::Polyline->new($_),
|
my @paths = map Slic3r::Polyline->new($_),
|
||||||
@{ Boost::Geometry::Utils::polygon_multi_linestring_intersection(
|
@{ Boost::Geometry::Utils::polygon_multi_linestring_intersection(
|
||||||
$expolygon,
|
$surface->expolygon,
|
||||||
$self->cache->{$cache_id},
|
\@polygons,
|
||||||
) };
|
) };
|
||||||
|
|
||||||
return { flow_spacing => $params{flow_spacing} },
|
return { flow_spacing => $params{flow_spacing} },
|
||||||
|
Loading…
Reference in New Issue
Block a user