New option to customize infill angle

This commit is contained in:
Alessandro Ranellucci 2011-09-26 15:51:22 +02:00
parent 742f646372
commit b0433097d4
6 changed files with 48 additions and 14 deletions

View File

@ -29,7 +29,9 @@ Slic3r current features are:
* read binary and ASCII STL files; * read binary and ASCII STL files;
* generate multiple perimeters (skins); * generate multiple perimeters (skins);
* generate rectilinear fill (100% solid for external surfaces or with customizable less density for inner surfaces); * generate rectilinear fill;
* set 0% - 100% infill density;
* set infill angle;
* retraction; * retraction;
* skirt (with rounded corners); * skirt (with rounded corners);
* use relative or absolute extrusion commands; * use relative or absolute extrusion commands;

View File

@ -48,6 +48,7 @@ our $flow_width;
our $perimeter_offsets = 3; our $perimeter_offsets = 3;
our $solid_layers = 3; our $solid_layers = 3;
our $fill_density = 0.4; # 1 = 100% our $fill_density = 0.4; # 1 = 100%
our $fill_angle = 0;
our $temperature = 195; our $temperature = 195;
# retraction options # retraction options

View File

@ -20,7 +20,7 @@ sub make_fill {
my ($print, $layer) = @_; my ($print, $layer) = @_;
printf "Filling layer %d:\n", $layer->id; printf "Filling layer %d:\n", $layer->id;
my $max_print_dimension = $print->max_length; my $max_print_dimension = $print->max_length * sqrt(2);
my $n = 1; my $n = 1;
foreach my $surface_collection (@{ $layer->fill_surfaces }) { foreach my $surface_collection (@{ $layer->fill_surfaces }) {
@ -30,18 +30,23 @@ sub make_fill {
Slic3r::debugf " Processing surface %s:\n", $surface->id; Slic3r::debugf " Processing surface %s:\n", $surface->id;
my $polygon = $surface->mgp_polygon; my $polygon = $surface->mgp_polygon;
# alternate fill direction # set infill angle
my (@rotate, @shift); my (@rotate, @shift);
$rotate[0] = Slic3r::Geometry::deg2rad($Slic3r::fill_angle);
$rotate[1] = [ $print->x_length / 2, $print->y_length / 2 ];
$shift[X] = $max_print_dimension / 2;
$shift[Y] = $max_print_dimension / 2;
# alternate fill direction
if ($layer->id % 2) { if ($layer->id % 2) {
@rotate = ( PI/2, [ $print->x_length / 2, $print->y_length / 2 ] ); $rotate[0] = Slic3r::Geometry::deg2rad($Slic3r::fill_angle) + PI/2;
$shift[X] = $print->y_length / 2 - $print->x_length / 2;
$shift[Y] = -$shift[X];
} }
# TODO: here we should implement an "infill in direction of bridges" option # TODO: here we should implement an "infill in direction of bridges" option
# rotate surface as needed # rotate surface as needed
$polygon = $polygon->rotate(@rotate)->move(@shift) if @rotate; @shift = @{ +(Slic3r::Geometry::rotate_points(@rotate, \@shift))[0] };
$polygon = $polygon->rotate(@rotate)->move(@shift) if $rotate[0];
# force 100% density for external surfaces # force 100% density for external surfaces
my $density = $surface->surface_type eq 'internal' ? $Slic3r::fill_density : 1; my $density = $surface->surface_type eq 'internal' ? $Slic3r::fill_density : 1;
@ -50,8 +55,8 @@ sub make_fill {
my $distance_between_lines = $Slic3r::flow_width / $Slic3r::resolution / $density; my $distance_between_lines = $Slic3r::flow_width / $Slic3r::resolution / $density;
my $number_of_lines = ceil($max_print_dimension / $distance_between_lines); my $number_of_lines = ceil($max_print_dimension / $distance_between_lines);
printf "distance = %f\n", $distance_between_lines; #printf "distance = %f\n", $distance_between_lines;
printf "number_of_lines = %d\n", $number_of_lines; #printf "number_of_lines = %d\n", $number_of_lines;
# this arrayref will hold intersection points of the fill grid with surface segments # this arrayref will hold intersection points of the fill grid with surface segments
my $points = [ map [], 0..$number_of_lines-1 ]; my $points = [ map [], 0..$number_of_lines-1 ];
@ -68,7 +73,7 @@ sub make_fill {
$c <= $line_c[1]; $c += $distance_between_lines) { $c <= $line_c[1]; $c += $distance_between_lines) {
next if $c < $line_c[0] || $c > $line_c[1]; next if $c < $line_c[0] || $c > $line_c[1];
my $i = sprintf('%.0f', $c / $distance_between_lines) - 1; my $i = sprintf('%.0f', $c / $distance_between_lines) - 1;
printf "CURRENT \$i = %d, \$c = %f\n", $i, $c; #printf "CURRENT \$i = %d, \$c = %f\n", $i, $c;
# if the segment is parallel to our ray, there will be two intersection points # if the segment is parallel to our ray, there will be two intersection points
if ($line_c[0] == $line_c[1]) { if ($line_c[0] == $line_c[1]) {
@ -157,9 +162,9 @@ sub make_fill {
} }
# paths must be rotated back # paths must be rotated back
if (@rotate) { if ($rotate[0]) {
# TODO: this skips 2-points paths! we shouldn't create a mgp polygon @paths = map [ Slic3r::Geometry::rotate_points(-$rotate[0], $rotate[1], @$_) ],
@paths = map $self->_mgp_from_points_ref($_)->move(map -$_, @shift)->rotate(-$rotate[0], $rotate[1])->points, @paths; map [ Slic3r::Geometry::move_points([map -$_, @shift], @$_) ], @paths;
} }
push @path_collection, @paths; push @path_collection, @paths;
@ -194,7 +199,7 @@ sub find_connectable_points {
sub can_connect { sub can_connect {
my $self = shift; my $self = shift;
my ($polygon, $p1, $p2) = @_; my ($polygon, $p1, $p2) = @_;
printf " Checking connectability of point %d\n", $p2->[1]; #printf " Checking connectability of point %d\n", $p2->[1];
# there's room for optimization here # there's room for optimization here

View File

@ -4,6 +4,7 @@ use warnings;
use XXX; use XXX;
use constant PI => 4 * atan2(1, 1);
use constant A => 0; use constant A => 0;
use constant B => 1; use constant B => 1;
use constant X => 0; use constant X => 0;
@ -145,4 +146,25 @@ sub point_along_segment {
return $point; return $point;
} }
sub deg2rad {
my ($degrees) = @_;
return PI() * $degrees / 180;
}
sub rotate_points {
my ($radians, $center, @points) = @_;
$center ||= [0,0];
return map {
[
$center->[X] + cos($radians) * ($_->[X] - $center->[X]) - sin($radians) * ($_->[Y] - $center->[Y]),
$center->[Y] + cos($radians) * ($_->[Y] - $center->[Y]) + sin($radians) * ($_->[X] - $center->[X]),
]
} @points;
}
sub move_points {
my ($shift, @points) = @_;
return map [ $shift->[X] + $_->[X], $shift->[Y] + $_->[Y] ], @points;
}
1; 1;

View File

@ -156,6 +156,8 @@ sub export_gcode {
my $self = shift; my $self = shift;
my ($file) = @_; my ($file) = @_;
printf "Exporting GCODE file...\n";
# open output gcode file # open output gcode file
open my $fh, ">", $file open my $fh, ">", $file
or die "Failed to open $file for writing\n"; or die "Failed to open $file for writing\n";

View File

@ -41,6 +41,7 @@ GetOptions(
'perimeters=i' => \$Slic3r::perimeter_offsets, 'perimeters=i' => \$Slic3r::perimeter_offsets,
'solid-layers=i' => \$Slic3r::solid_layers, 'solid-layers=i' => \$Slic3r::solid_layers,
'fill-density=f' => \$Slic3r::fill_density, 'fill-density=f' => \$Slic3r::fill_density,
'fill-angle=i' => \$Slic3r::fill_angle,
'temperature=i' => \$Slic3r::temperature, 'temperature=i' => \$Slic3r::temperature,
# retraction options # retraction options
@ -159,6 +160,7 @@ Usage: slic3r.pl [ OPTIONS ] file.stl
--solid-layers Number of solid layers to do for top/bottom surfaces --solid-layers Number of solid layers to do for top/bottom surfaces
(range: 1+, default: $Slic3r::solid_layers) (range: 1+, default: $Slic3r::solid_layers)
--fill-density Infill density (range: 0-1, default: $Slic3r::fill_density) --fill-density Infill density (range: 0-1, default: $Slic3r::fill_density)
--fill-angle Infill angle (range: 0-90, default: $Slic3r::fill_angle)
--temperature Extrusion temperature (default: $Slic3r::temperature) --temperature Extrusion temperature (default: $Slic3r::temperature)
Retraction options: Retraction options: