diff --git a/lib/Slic3r/Extruder.pm b/lib/Slic3r/Extruder.pm index 9cfc4dcf7..ece4be017 100644 --- a/lib/Slic3r/Extruder.pm +++ b/lib/Slic3r/Extruder.pm @@ -13,12 +13,18 @@ use constant OPTIONS => [qw( has 'id' => (is => 'rw', required => 1); has $_ => (is => 'ro', required => 1) for @{&OPTIONS}; +has 'bridge_flow' => (is => 'lazy'); has 'retracted' => (is => 'rw', default => sub {0} ); has 'restart_extra' => (is => 'rw', default => sub {0} ); has 'e_per_mm3' => (is => 'lazy'); has 'retract_speed_mm_min' => (is => 'lazy'); has '_mm3_per_mm_cache' => (is => 'ro', default => sub {{}}); +sub _build_bridge_flow { + my $self = shift; + return Slic3r::Flow::Bridge->new(nozzle_diameter => $self->nozzle_diameter); +} + sub _build_e_per_mm3 { my $self = shift; return $self->extrusion_multiplier * (4 / (($self->filament_diameter ** 2) * PI)); diff --git a/lib/Slic3r/Fill.pm b/lib/Slic3r/Fill.pm index 1031b6e86..809fcfd61 100644 --- a/lib/Slic3r/Fill.pm +++ b/lib/Slic3r/Fill.pm @@ -135,7 +135,7 @@ sub make_fill { $filler = $Slic3r::Config->solid_fill_pattern; if ($is_bridge) { $filler = 'rectilinear'; - $flow_spacing = $layer->infill_flow->bridge_spacing; + $flow_spacing = $layer->extruders->{infill}->bridge_flow->spacing; } elsif ($surface->surface_type == S_TYPE_INTERNALSOLID) { $filler = 'rectilinear'; } @@ -157,7 +157,7 @@ sub make_fill { my $params = shift @paths; # ugly hack(tm) to get the right amount of flow (GCode.pm should be fixed) - $params->{flow_spacing} = $layer->infill_flow->bridge_width if $is_bridge; + $params->{flow_spacing} = $layer->extruders->{infill}->bridge_flow->width if $is_bridge; # save into layer next unless @paths; diff --git a/lib/Slic3r/Flow.pm b/lib/Slic3r/Flow.pm index 66a8213dc..e2e780921 100644 --- a/lib/Slic3r/Flow.pm +++ b/lib/Slic3r/Flow.pm @@ -9,8 +9,6 @@ has 'layer_height' => (is => 'ro', default => sub { $Slic3r::Config->layer_ has 'width' => (is => 'rwp', builder => 1); has 'spacing' => (is => 'lazy'); -has 'bridge_width' => (is => 'lazy'); -has 'bridge_spacing' => (is => 'lazy'); has 'scaled_width' => (is => 'lazy'); has 'scaled_spacing' => (is => 'lazy'); @@ -73,17 +71,6 @@ sub clone { ); } -sub _build_bridge_width { - my $self = shift; - return sqrt($Slic3r::Config->bridge_flow_ratio * ($self->nozzle_diameter**2)); -} - -sub _build_bridge_spacing { - my $self = shift; - my $width = $self->bridge_width; - return $width + &Slic3r::OVERLAP_FACTOR * ($width * PI / 4 - $width); -} - sub _build_scaled_width { my $self = shift; return scale $self->width; @@ -94,4 +81,22 @@ sub _build_scaled_spacing { return scale $self->spacing; } + +package Slic3r::Flow::Bridge; +use Moo; +extends 'Slic3r::Flow'; + +use Slic3r::Geometry qw(PI); + +sub _build_width { + my $self = shift; + return sqrt($Slic3r::Config->bridge_flow_ratio * ($self->nozzle_diameter**2)); +} + +sub _build_spacing { + my $self = shift; + my $width = $self->width; + return $width + &Slic3r::OVERLAP_FACTOR * ($width * PI / 4 - $width); +} + 1; diff --git a/lib/Slic3r/Layer.pm b/lib/Slic3r/Layer.pm index ec350e1d1..951805c8a 100644 --- a/lib/Slic3r/Layer.pm +++ b/lib/Slic3r/Layer.pm @@ -64,7 +64,7 @@ sub support_material_contact_height { # TODO: check what upper region applies instead of considering the first one my $upper_layer = $self->object->layers->[ $self->id + 1 ] // $self; - my $h = ($self->height + $upper_layer->height) - $upper_layer->regions->[0]->infill_flow->bridge_width; + my $h = ($self->height + $upper_layer->height) - $upper_layer->regions->[0]->extruders->{infill}->bridge_flow->width; # If layer height is less than half the bridge width then we'll get a negative height for contact area. # The optimal solution would be to skip some layers during support material generation, but for now diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm index cb23f719a..eb55fcc55 100644 --- a/lib/Slic3r/Layer/Region.pm +++ b/lib/Slic3r/Layer/Region.pm @@ -13,7 +13,7 @@ has 'layer' => ( trigger => 1, handles => [qw(id slice_z print_z height flow)], ); -has 'region' => (is => 'ro', required => 1); +has 'region' => (is => 'ro', required => 1, handles => [qw(extruders)]); has 'perimeter_flow' => (is => 'rw'); has 'infill_flow' => (is => 'rw'); has 'infill_area_threshold' => (is => 'lazy'); diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index dc270a9db..e502fa83d 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -473,7 +473,7 @@ sub bridge_over_infill { # exclude infill from the layers below if needed # see discussion at https://github.com/alexrj/Slic3r/issues/240 { - my $excess = $layerm->infill_flow->bridge_width - $layerm->height; + my $excess = $layerm->extruders->{infill}->bridge_flow->width - $layerm->height; for (my $i = $layer_id-1; $excess >= $self->layers->[$i]->height; $i--) { Slic3r::debugf " skipping infill below those areas at layer %d\n", $i; foreach my $lower_layerm (@{$self->layers->[$i]->regions}) {