New fill types (hilbertcurve, archimedeanchords, octagramspiral) and ability to use different patterns for solid layers. #20

This commit is contained in:
Alessandro Ranellucci 2011-11-13 18:14:02 +01:00
parent 041e9877a3
commit 038caddcda
22 changed files with 391 additions and 93 deletions

View file

@ -0,0 +1,7 @@
package Slic3r::Fill::ArchimedeanChords;
use Moo;
extends 'Slic3r::Fill::PlanePath';
use Math::PlanePath::ArchimedeanChords;
1;

View file

@ -35,14 +35,15 @@ sub infill_direction {
sub rotate_points {
my $self = shift;
my ($polygons, $rotate_vector) = @_;
my ($expolygon, $rotate_vector) = @_;
my @rotate = @{$rotate_vector->[0]};
my @shift = @{$rotate_vector->[1]};
# rotate surface as needed
@$polygons = map [ Slic3r::Geometry::move_points(\@shift, @$_) ],
map [ Slic3r::Geometry::rotate_points(@rotate, @$_) ], @$polygons if $rotate[0];
# rotate points as needed
if ($rotate[0]) {
$expolygon->rotate(@rotate);
$expolygon->translate(@shift);
}
}
sub rotate_points_back {

View file

@ -0,0 +1,18 @@
package Slic3r::Fill::Flowsnake;
use Moo;
extends 'Slic3r::Fill::PlanePath';
use Math::PlanePath::Flowsnake;
use Slic3r::Geometry qw(X X1 X2);
# Sorry, this fill is currently broken.
sub process_polyline {
my $self = shift;
my ($polyline, $bounding_box) = @_;
$_->[X] += ($bounding_box->[X1] + $bounding_box->[X2]/2) for @{$polyline->points};
}
1;

View file

@ -0,0 +1,7 @@
package Slic3r::Fill::HilbertCurve;
use Moo;
extends 'Slic3r::Fill::PlanePath';
use Math::PlanePath::HilbertCurve;
1;

View file

@ -0,0 +1,9 @@
package Slic3r::Fill::OctagramSpiral;
use Moo;
extends 'Slic3r::Fill::PlanePath';
use Math::PlanePath::OctagramSpiral;
sub multiplier () { sqrt(2) }
1;

View file

@ -0,0 +1,62 @@
package Slic3r::Fill::PlanePath;
use Moo;
extends 'Slic3r::Fill::Base';
use Slic3r::Geometry qw(bounding_box);
use XXX;
sub multiplier () { 1 }
sub get_n {
my $self = shift;
my ($path, $bounding_box) = @_;
my ($n_lo, $n_hi) = $path->rect_to_n_range(@$bounding_box);
return ($n_lo .. $n_hi);
}
sub process_polyline {}
sub fill_surface {
my $self = shift;
my ($surface, %params) = @_;
# rotate polygons
my $expolygon = $surface->expolygon;
my $rotate_vector = $self->infill_direction($surface);
$self->rotate_points($expolygon, $rotate_vector);
my $distance_between_lines = $Slic3r::flow_width / $Slic3r::resolution / $params{density} * $self->multiplier;
my $bounding_box = [ bounding_box(map @$_, $expolygon) ];
(ref $self) =~ /::([^:]+)$/;
my $path = "Math::PlanePath::$1"->new;
my @n = $self->get_n($path, [map +($_ / $distance_between_lines), @$bounding_box]);
my $polyline = Slic3r::Polyline->cast([
map [ map {$_*$distance_between_lines} $path->n_to_xy($_) ], @n,
]);
return [] if !@{$polyline->points};
$self->process_polyline($polyline, $bounding_box);
my @paths = ($polyline->clip_with_expolygon($expolygon));
if (0) {
require "Slic3r/SVG.pm";
Slic3r::SVG::output(undef, "fill.svg",
polygons => $expolygon,
polylines => [map $_->p, @paths],
);
}
@paths = map $_->p, @paths;
# paths must be rotated back
$self->rotate_points_back(\@paths, $rotate_vector);
return @paths;
}
1;

View file

@ -3,11 +3,7 @@ use Moo;
extends 'Slic3r::Fill::Base';
use constant X1 => 0;
use constant Y1 => 1;
use constant X2 => 2;
use constant Y2 => 3;
use Slic3r::Geometry qw(X1 Y1 X2 Y2);
use XXX;
sub fill_surface {
@ -15,21 +11,18 @@ sub fill_surface {
my ($surface, %params) = @_;
# rotate polygons so that we can work with vertical lines here
my $polygons = [ $surface->p ];
my $expolygon = $surface->expolygon;
my $rotate_vector = $self->infill_direction($surface);
$self->rotate_points($polygons, $rotate_vector);
my $bounding_box = [ Slic3r::Geometry::bounding_box(map @$_, $polygons) ];
my $surface_width = $bounding_box->[X2] - $bounding_box->[X1];
my $surface_height = $bounding_box->[Y2] - $bounding_box->[Y1];
$self->rotate_points($expolygon, $rotate_vector);
my $bounding_box = [ $expolygon->bounding_box ];
my $distance_between_lines = $Slic3r::flow_width / $Slic3r::resolution / $params{density};
my @paths = ();
my $x = $bounding_box->[X1];
while ($x < $bounding_box->[X2]) {
my $vertical_line = [ [$x, $bounding_box->[Y2]], [$x, $bounding_box->[Y1]] ];
push @paths, @{ Slic3r::Geometry::clip_segment_complex_polygon($vertical_line, $polygons) };
push @paths, @{ $expolygon->clip_line($vertical_line) };
$x += int($distance_between_lines);
}

View file

@ -3,15 +3,7 @@ use Moo;
extends 'Slic3r::Fill::Base';
use constant X1 => 0;
use constant Y1 => 1;
use constant X2 => 2;
use constant Y2 => 3;
use constant A => 0;
use constant B => 1;
use constant X => 0;
use constant Y => 1;
use Slic3r::Geometry qw(X1 Y1 X2 Y2 A B X Y);
use XXX;
sub fill_surface {