From bc101bd93e6e4ea59d147d334e0ee7e84f896995 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Mon, 21 Apr 2014 23:21:15 +0200 Subject: [PATCH] Assume bridge angle is stored in radians in infill generation. #1917 --- lib/Slic3r/Fill.pm | 10 +++++----- lib/Slic3r/Fill/Base.pm | 36 ++++++++++++++++++++---------------- xs/src/Surface.hpp | 2 +- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/lib/Slic3r/Fill.pm b/lib/Slic3r/Fill.pm index c22b9186c..de1dc68af 100644 --- a/lib/Slic3r/Fill.pm +++ b/lib/Slic3r/Fill.pm @@ -13,7 +13,7 @@ use Slic3r::Fill::OctagramSpiral; use Slic3r::Fill::PlanePath; use Slic3r::Fill::Rectilinear; use Slic3r::Flow ':roles'; -use Slic3r::Geometry qw(X Y PI scale chained_path); +use Slic3r::Geometry qw(X Y PI scale chained_path deg2rad); use Slic3r::Geometry::Clipper qw(union union_ex diff diff_ex intersection_ex offset offset2); use Slic3r::Surface ':types'; @@ -62,7 +62,7 @@ sub make_fill { # in case of bridge surfaces, the ones with defined angle will be attached to the ones # without any angle (shouldn't this logic be moved to process_external_surfaces()?) { - my @surfaces_with_bridge_angle = grep defined $_->bridge_angle, @{$layerm->fill_surfaces}; + my @surfaces_with_bridge_angle = grep { $_->bridge_angle >= 0 } @{$layerm->fill_surfaces}; # group surfaces by distinct properties my @groups = @{$layerm->fill_surfaces->group}; @@ -111,13 +111,13 @@ sub make_fill { } # give priority to bridges - @groups = sort { defined $a->[0]->bridge_angle ? -1 : 0 } @groups; + @groups = sort { ($a->[0]->bridge_angle >= 0) ? -1 : 0 } @groups; foreach my $group (@groups) { my $union_p = union([ map $_->p, @$group ], 1); # subtract surfaces having a defined bridge_angle from any other - if (@surfaces_with_bridge_angle && !defined $group->[0]->bridge_angle) { + if (@surfaces_with_bridge_angle && $group->[0]->bridge_angle < 0) { $union_p = diff( $union_p, [ map $_->p, @surfaces_with_bridge_angle ], @@ -211,7 +211,7 @@ sub make_fill { my $f = $self->filler($filler); $f->layer_id($layerm->id); - $f->angle($layerm->config->fill_angle); + $f->angle(deg2rad($layerm->config->fill_angle)); my ($params, @polylines) = $f->fill_surface( $surface, density => $density/100, diff --git a/lib/Slic3r/Fill/Base.pm b/lib/Slic3r/Fill/Base.pm index 348e22383..f71367215 100644 --- a/lib/Slic3r/Fill/Base.pm +++ b/lib/Slic3r/Fill/Base.pm @@ -1,10 +1,10 @@ package Slic3r::Fill::Base; use Moo; -use Slic3r::Geometry qw(PI); +use Slic3r::Geometry qw(PI rad2deg); has 'layer_id' => (is => 'rw'); -has 'angle' => (is => 'rw'); +has 'angle' => (is => 'rw'); # in radians, ccw, 0 = East has 'bounding_box' => (is => 'ro', required => 0); # Slic3r::Geometry::BoundingBox object sub angles () { [0, PI/2] } @@ -19,28 +19,29 @@ sub infill_direction { } # set infill angle - my (@rotate, @shift); - $rotate[0] = Slic3r::Geometry::deg2rad($self->angle); + my (@rotate); + $rotate[0] = $self->angle; $rotate[1] = $self->bounding_box ? $self->bounding_box->center : $surface->expolygon->bounding_box->center; - @shift = @{$rotate[1]}; + my $shift = $rotate[1]->clone; if (defined $self->layer_id) { # alternate fill direction my $layer_num = $self->layer_id / $surface->thickness_layers; my $angle = $self->angles->[$layer_num % @{$self->angles}]; - $rotate[0] = Slic3r::Geometry::deg2rad($self->angle) + $angle if $angle; + $rotate[0] = $self->angle + $angle if $angle; } # use bridge angle - if ($surface->bridge_angle != -1) { - Slic3r::debugf "Filling bridge with angle %d\n", $surface->bridge_angle; - $rotate[0] = Slic3r::Geometry::deg2rad($surface->bridge_angle); + if ($surface->bridge_angle >= 0) { + Slic3r::debugf "Filling bridge with angle %d\n", rad2deg($surface->bridge_angle); + $rotate[0] = $surface->bridge_angle; } - @shift = @{ +(Slic3r::Geometry::rotate_points(@rotate, \@shift))[0] }; - return [\@rotate, \@shift]; + $rotate[0] += PI/2; + $shift->rotate(@rotate); + return [\@rotate, $shift]; } # this method accepts any object that implements rotate() and translate() @@ -49,18 +50,21 @@ sub rotate_points { my ($expolygon, $rotate_vector) = @_; # rotate points - $expolygon->rotate(@{$rotate_vector->[0]}); - $expolygon->translate(@{$rotate_vector->[1]}); + my ($rotate, $shift) = @$rotate_vector; + $rotate = [ -$rotate->[0], $rotate->[1] ]; + $expolygon->rotate(@$rotate); + $expolygon->translate(@$shift); } sub rotate_points_back { my $self = shift; my ($paths, $rotate_vector) = @_; - my @rotate = (-$rotate_vector->[0][0], $rotate_vector->[0][1]); - my $shift = [ map -$_, @{$rotate_vector->[1]} ]; + + my ($rotate, $shift) = @$rotate_vector; + $shift = [ map -$_, @$shift ]; $_->translate(@$shift) for @$paths; - $_->rotate(@rotate) for @$paths; + $_->rotate(@$rotate) for @$paths; } sub adjust_solid_spacing { diff --git a/xs/src/Surface.hpp b/xs/src/Surface.hpp index 162c9cb66..4c776089a 100644 --- a/xs/src/Surface.hpp +++ b/xs/src/Surface.hpp @@ -14,7 +14,7 @@ class Surface SurfaceType surface_type; double thickness; // in mm unsigned short thickness_layers; // in layers - double bridge_angle; + double bridge_angle; // in radians, ccw, 0 = East, only 0+ (negative means undefined) unsigned short extra_perimeters; double area() const; bool is_solid() const;