More work for refactoring Flow/Extruder

This commit is contained in:
Alessandro Ranellucci 2014-01-03 20:02:00 +01:00
parent 8ed738d3f7
commit a2cbb261cb
10 changed files with 48 additions and 21 deletions

View File

@ -78,7 +78,7 @@ use constant SCALING_FACTOR => 0.000001;
use constant RESOLUTION => 0.0125; use constant RESOLUTION => 0.0125;
use constant SCALED_RESOLUTION => RESOLUTION / SCALING_FACTOR; use constant SCALED_RESOLUTION => RESOLUTION / SCALING_FACTOR;
use constant SMALL_PERIMETER_LENGTH => (6.5 / SCALING_FACTOR) * 2 * PI; use constant SMALL_PERIMETER_LENGTH => (6.5 / SCALING_FACTOR) * 2 * PI;
use constant LOOP_CLIPPING_LENGTH_OVER_SPACING => 0.15; use constant LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER => 0.15;
use constant INFILL_OVERLAP_OVER_SPACING => 0.45; use constant INFILL_OVERLAP_OVER_SPACING => 0.45;
use constant EXTERNAL_INFILL_MARGIN => 3; use constant EXTERNAL_INFILL_MARGIN => 3;

View File

@ -168,7 +168,9 @@ sub make_fill {
); );
next unless @polylines; next unless @polylines;
my $mm3_per_mm = $params->{flow}->mm3_per_mm($surface->thickness); my $h = $surface->thickness;
$h = $layerm->height if $h == -1;
my $mm3_per_mm = $params->{flow}->mm3_per_mm($h);
# save into layer # save into layer
push @fills, my $collection = Slic3r::ExtrusionPath::Collection->new; push @fills, my $collection = Slic3r::ExtrusionPath::Collection->new;

View File

@ -15,16 +15,22 @@ sub fill_surface {
my $expolygon = $surface->expolygon; my $expolygon = $surface->expolygon;
my $bounding_box = $expolygon->bounding_box; my $bounding_box = $expolygon->bounding_box;
my $min_spacing = scale $params{flow_spacing}; my $flow = $params{flow};
my $min_spacing = $flow->scaled_spacing;
my $distance = $min_spacing / $params{density}; my $distance = $min_spacing / $params{density};
my $flow_spacing = $params{flow_spacing}; my $flow_spacing = $flow->spacing;
if ($params{density} == 1 && !$params{dont_adjust}) { if ($params{density} == 1 && !$params{dont_adjust}) {
$distance = $self->adjust_solid_spacing( $distance = $self->adjust_solid_spacing(
width => $bounding_box->size->[X], width => $bounding_box->size->[X],
distance => $distance, distance => $distance,
); );
$flow_spacing = unscale $distance; $flow = Slic3r::Flow->new_from_spacing(
spacing => unscale($distance),
nozzle_diameter => $flow->nozzle_diameter,
layer_height => $surface->thickness,
bridge => $flow->bridge,
);
} }
# compensate the overlap which is good for rectilinear but harmful for concentric # compensate the overlap which is good for rectilinear but harmful for concentric
@ -48,11 +54,11 @@ sub fill_surface {
} }
# clip the paths to avoid the extruder to get exactly on the first point of the loop # clip the paths to avoid the extruder to get exactly on the first point of the loop
my $clip_length = scale $flow_spacing * &Slic3r::LOOP_CLIPPING_LENGTH_OVER_SPACING; my $clip_length = scale($flow->nozzle_diameter) * &Slic3r::LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER;
$_->clip_end($clip_length) for @paths; $_->clip_end($clip_length) for @paths;
# TODO: return ExtrusionLoop objects to get better chained paths # TODO: return ExtrusionLoop objects to get better chained paths
return { flow_spacing => $flow_spacing, no_sort => 1 }, @paths; return { flow => $flow, no_sort => 1 }, @paths;
} }
1; 1;

View File

@ -27,7 +27,8 @@ sub fill_surface {
my $rotate_vector = $self->infill_direction($surface); my $rotate_vector = $self->infill_direction($surface);
$self->rotate_points($expolygon, $rotate_vector); $self->rotate_points($expolygon, $rotate_vector);
my $distance_between_lines = scale $params{flow_spacing} / $params{density} * $self->multiplier; my $flow = $params{flow};
my $distance_between_lines = $flow->scaled_spacing / $params{density} * $self->multiplier;
my $bounding_box = $expolygon->bounding_box; my $bounding_box = $expolygon->bounding_box;
(ref $self) =~ /::([^:]+)$/; (ref $self) =~ /::([^:]+)$/;
@ -54,7 +55,7 @@ sub fill_surface {
# paths must be rotated back # paths must be rotated back
$self->rotate_points_back(\@paths, $rotate_vector); $self->rotate_points_back(\@paths, $rotate_vector);
return { flow_spacing => $params{flow_spacing} }, @paths; return { flow => $flow }, @paths;
} }
1; 1;

View File

@ -17,7 +17,7 @@ sub fill_surface {
my $rotate_vector = $self->infill_direction($surface); my $rotate_vector = $self->infill_direction($surface);
$self->rotate_points($expolygon, $rotate_vector); $self->rotate_points($expolygon, $rotate_vector);
my $flow = $params{flow}; my $flow = $params{flow} or die "No flow supplied to fill_surface()";
my $min_spacing = $flow->scaled_spacing; my $min_spacing = $flow->scaled_spacing;
my $line_spacing = $min_spacing / $params{density}; my $line_spacing = $min_spacing / $params{density};
my $line_oscillation = $line_spacing - $min_spacing; my $line_oscillation = $line_spacing - $min_spacing;

View File

@ -235,7 +235,7 @@ sub extrude_loop {
# clip the path to avoid the extruder to get exactly on the first point of the loop; # clip the path to avoid the extruder to get exactly on the first point of the loop;
# if polyline was shorter than the clipping distance we'd get a null polyline, so # if polyline was shorter than the clipping distance we'd get a null polyline, so
# we discard it in that case # we discard it in that case
$extrusion_path->clip_end(scale $extrusion_path->flow_spacing * &Slic3r::LOOP_CLIPPING_LENGTH_OVER_SPACING) $extrusion_path->clip_end(scale($self->extruder->nozzle_diameter) * &Slic3r::LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER)
if $self->enable_loop_clipping; if $self->enable_loop_clipping;
return '' if !@{$extrusion_path->polyline}; return '' if !@{$extrusion_path->polyline};
@ -251,7 +251,7 @@ sub extrude_loop {
push @paths, push @paths,
map { map {
$_->role(EXTR_ROLE_OVERHANG_PERIMETER); $_->role(EXTR_ROLE_OVERHANG_PERIMETER);
$_->flow_spacing($self->region->flow(FLOW_ROLE_PERIMETER, undef, 1)->width); $_->mm3_per_mm($self->region->flow(FLOW_ROLE_PERIMETER, undef, 1)->mm3_per_mm(undef));
$_ $_
} }
map $_->clone, map $_->clone,
@ -287,7 +287,7 @@ sub extrude_loop {
# we make sure we don't exceed the segment length because we don't know # we make sure we don't exceed the segment length because we don't know
# the rotation of the second segment so we might cross the object boundary # the rotation of the second segment so we might cross the object boundary
my $first_segment = Slic3r::Line->new(@{$extrusion_path->polyline}[0,1]); my $first_segment = Slic3r::Line->new(@{$extrusion_path->polyline}[0,1]);
my $distance = min(scale $extrusion_path->flow_spacing, $first_segment->length); my $distance = min(scale($self->extruder->nozzle_diameter), $first_segment->length);
my $point = $first_segment->point_at($distance); my $point = $first_segment->point_at($distance);
$point->rotate($angle, $extrusion_path->first_point); $point->rotate($angle, $extrusion_path->first_point);

View File

@ -19,6 +19,8 @@ has 'extra_variables' => (is => 'rw', default => sub {{}});
has 'objects' => (is => 'rw', default => sub {[]}); has 'objects' => (is => 'rw', default => sub {[]});
has 'status_cb' => (is => 'rw'); has 'status_cb' => (is => 'rw');
has 'regions' => (is => 'rw', default => sub {[]}); has 'regions' => (is => 'rw', default => sub {[]});
has 'total_used_filament' => (is => 'rw');
has 'total_extruded_volume' => (is => 'rw');
has '_state' => (is => 'ro', default => sub { Slic3r::Print::State->new }); has '_state' => (is => 'ro', default => sub { Slic3r::Print::State->new });
# ordered collection of extrusion paths to build skirt loops # ordered collection of extrusion paths to build skirt loops
@ -970,7 +972,13 @@ sub write_gcode {
print $fh $gcodegen->set_fan(0); print $fh $gcodegen->set_fan(0);
printf $fh "%s\n", $gcodegen->replace_variables($self->config->end_gcode); printf $fh "%s\n", $gcodegen->replace_variables($self->config->end_gcode);
foreach my $extruder (@{$self->extruders}) { $self->total_used_filament(0);
$self->total_extruded_volume(0);
foreach my $extruder_id (@{$self->extruders}) {
my $extruder = $gcodegen->extruders->[$extruder_id];
$self->total_used_filament($self->total_used_filament + $extruder->absolute_E);
$self->total_extruded_volume($self->total_extruded_volume + $extruder->extruded_volume);
printf $fh "; filament used = %.1fmm (%.1fcm3)\n", printf $fh "; filament used = %.1fmm (%.1fcm3)\n",
$extruder->absolute_E, $extruder->extruded_volume/1000; $extruder->absolute_E, $extruder->extruded_volume/1000;
} }

View File

@ -6,7 +6,8 @@ use Slic3r::Geometry qw(X Y);
has '_print' => ( has '_print' => (
is => 'ro', is => 'ro',
default => sub { Slic3r::Print->new }, default => sub { Slic3r::Print->new },
handles => [qw(apply_config extruders expanded_output_filepath)], handles => [qw(apply_config extruders expanded_output_filepath
total_used_filament total_extruded_volume)],
); );
has 'duplicate' => ( has 'duplicate' => (

View File

@ -163,9 +163,8 @@ if (@ARGV) { # slicing from command line
printf "Done. Process took %d minutes and %.3f seconds\n", printf "Done. Process took %d minutes and %.3f seconds\n",
int($duration/60), ($duration - int($duration/60)*60); # % truncates to integer int($duration/60), ($duration - int($duration/60)*60); # % truncates to integer
} }
print map sprintf("Filament required: %.1fmm (%.1fcm3)\n", printf "Filament required: %.1fmm (%.1fcm3)\n",
$_->absolute_E, $_->extruded_volume/1000), $sprint->total_used_filament, $sprint->total_extruded_volume/1000;
@{$sprint->extruders};
} }
} }
} else { } else {

View File

@ -43,9 +43,14 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ }
surface_type => S_TYPE_TOP, surface_type => S_TYPE_TOP,
expolygon => $expolygon, expolygon => $expolygon,
); );
my $flow = Slic3r::Flow->new(
width => 0.69,
spacing => 0.69,
nozzle_diameter => 0.50,
);
foreach my $angle (0, 45) { foreach my $angle (0, 45) {
$surface->expolygon->rotate(Slic3r::Geometry::deg2rad($angle), [0,0]); $surface->expolygon->rotate(Slic3r::Geometry::deg2rad($angle), [0,0]);
my ($params, @paths) = $filler->fill_surface($surface, flow_spacing => 0.69, density => 0.4); my ($params, @paths) = $filler->fill_surface($surface, flow => $flow, density => 0.4);
is scalar @paths, 1, 'one continuous path'; is scalar @paths, 1, 'one continuous path';
} }
} }
@ -62,14 +67,19 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ }
surface_type => S_TYPE_BOTTOM, surface_type => S_TYPE_BOTTOM,
expolygon => $expolygon, expolygon => $expolygon,
); );
my $flow = Slic3r::Flow->new(
width => $flow_spacing,
spacing => $flow_spacing,
nozzle_diameter => $flow_spacing,
);
my ($params, @paths) = $filler->fill_surface( my ($params, @paths) = $filler->fill_surface(
$surface, $surface,
flow_spacing => $flow_spacing, flow => $flow,
density => $density // 1, density => $density // 1,
); );
# check whether any part was left uncovered # check whether any part was left uncovered
my @grown_paths = map @{Slic3r::Polyline->new(@$_)->grow(scale $params->{flow_spacing}/2)}, @paths; my @grown_paths = map @{Slic3r::Polyline->new(@$_)->grow(scale $params->{flow}->spacing/2)}, @paths;
my $uncovered = diff_ex([ @$expolygon ], [ @grown_paths ], 1); my $uncovered = diff_ex([ @$expolygon ], [ @grown_paths ], 1);
# ignore very small dots # ignore very small dots