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 SCALED_RESOLUTION => RESOLUTION / SCALING_FACTOR;
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 EXTERNAL_INFILL_MARGIN => 3;

View File

@ -168,7 +168,9 @@ sub make_fill {
);
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
push @fills, my $collection = Slic3r::ExtrusionPath::Collection->new;

View File

@ -15,16 +15,22 @@ sub fill_surface {
my $expolygon = $surface->expolygon;
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 $flow_spacing = $params{flow_spacing};
my $flow_spacing = $flow->spacing;
if ($params{density} == 1 && !$params{dont_adjust}) {
$distance = $self->adjust_solid_spacing(
width => $bounding_box->size->[X],
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
@ -48,11 +54,11 @@ sub fill_surface {
}
# 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;
# 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;

View File

@ -27,7 +27,8 @@ sub fill_surface {
my $rotate_vector = $self->infill_direction($surface);
$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;
(ref $self) =~ /::([^:]+)$/;
@ -54,7 +55,7 @@ sub fill_surface {
# paths must be rotated back
$self->rotate_points_back(\@paths, $rotate_vector);
return { flow_spacing => $params{flow_spacing} }, @paths;
return { flow => $flow }, @paths;
}
1;

View File

@ -17,7 +17,7 @@ sub fill_surface {
my $rotate_vector = $self->infill_direction($surface);
$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 $line_spacing = $min_spacing / $params{density};
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;
# if polyline was shorter than the clipping distance we'd get a null polyline, so
# 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;
return '' if !@{$extrusion_path->polyline};
@ -251,7 +251,7 @@ sub extrude_loop {
push @paths,
map {
$_->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,
@ -287,7 +287,7 @@ sub extrude_loop {
# 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
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);
$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 'status_cb' => (is => 'rw');
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 });
# ordered collection of extrusion paths to build skirt loops
@ -970,7 +972,13 @@ sub write_gcode {
print $fh $gcodegen->set_fan(0);
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",
$extruder->absolute_E, $extruder->extruded_volume/1000;
}

View File

@ -6,7 +6,8 @@ use Slic3r::Geometry qw(X Y);
has '_print' => (
is => 'ro',
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' => (

View File

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

View File

@ -43,9 +43,14 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ }
surface_type => S_TYPE_TOP,
expolygon => $expolygon,
);
my $flow = Slic3r::Flow->new(
width => 0.69,
spacing => 0.69,
nozzle_diameter => 0.50,
);
foreach my $angle (0, 45) {
$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';
}
}
@ -62,14 +67,19 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ }
surface_type => S_TYPE_BOTTOM,
expolygon => $expolygon,
);
my $flow = Slic3r::Flow->new(
width => $flow_spacing,
spacing => $flow_spacing,
nozzle_diameter => $flow_spacing,
);
my ($params, @paths) = $filler->fill_surface(
$surface,
flow_spacing => $flow_spacing,
flow => $flow,
density => $density // 1,
);
# 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);
# ignore very small dots