mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-18 20:28:08 -06:00
New fill types (hilbertcurve, archimedeanchords, octagramspiral) and ability to use different patterns for solid layers. #20
This commit is contained in:
parent
041e9877a3
commit
038caddcda
22 changed files with 391 additions and 93 deletions
7
lib/Slic3r/Fill/ArchimedeanChords.pm
Normal file
7
lib/Slic3r/Fill/ArchimedeanChords.pm
Normal file
|
@ -0,0 +1,7 @@
|
|||
package Slic3r::Fill::ArchimedeanChords;
|
||||
use Moo;
|
||||
|
||||
extends 'Slic3r::Fill::PlanePath';
|
||||
use Math::PlanePath::ArchimedeanChords;
|
||||
|
||||
1;
|
|
@ -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 {
|
||||
|
|
18
lib/Slic3r/Fill/Flowsnake.pm
Normal file
18
lib/Slic3r/Fill/Flowsnake.pm
Normal 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;
|
7
lib/Slic3r/Fill/HilbertCurve.pm
Normal file
7
lib/Slic3r/Fill/HilbertCurve.pm
Normal file
|
@ -0,0 +1,7 @@
|
|||
package Slic3r::Fill::HilbertCurve;
|
||||
use Moo;
|
||||
|
||||
extends 'Slic3r::Fill::PlanePath';
|
||||
use Math::PlanePath::HilbertCurve;
|
||||
|
||||
1;
|
9
lib/Slic3r/Fill/OctagramSpiral.pm
Normal file
9
lib/Slic3r/Fill/OctagramSpiral.pm
Normal file
|
@ -0,0 +1,9 @@
|
|||
package Slic3r::Fill::OctagramSpiral;
|
||||
use Moo;
|
||||
|
||||
extends 'Slic3r::Fill::PlanePath';
|
||||
use Math::PlanePath::OctagramSpiral;
|
||||
|
||||
sub multiplier () { sqrt(2) }
|
||||
|
||||
1;
|
62
lib/Slic3r/Fill/PlanePath.pm
Normal file
62
lib/Slic3r/Fill/PlanePath.pm
Normal 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;
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue