Implemented retraction and fixed extrusion math
This commit is contained in:
parent
5595839b31
commit
d8b848a67f
@ -33,6 +33,7 @@ Slic3r is able to:
|
||||
* read binary and ASCII STL files;
|
||||
* generate multiple perimeters (skins);
|
||||
* generate rectilinear fill (100% solid for external surfaces or with customizable less density for inner surfaces);
|
||||
* retraction;
|
||||
* use relative or absolute extrusion commands;
|
||||
* center print around bed center point;
|
||||
* use different speed for bottom layer;
|
||||
@ -42,10 +43,10 @@ Roadmap includes the following goals:
|
||||
|
||||
* output some statistics;
|
||||
* allow the user to customize initial and final GCODE commands;
|
||||
* retraction;
|
||||
* option for filling multiple solid layers near external surfaces;
|
||||
* support material for internal perimeters;
|
||||
* ability to infill in the direction of bridges;
|
||||
* extra perimeters on alternate layers;
|
||||
* skirt;
|
||||
* cool;
|
||||
* nice packaging for cross-platform deployment.
|
||||
|
@ -24,15 +24,20 @@ use Slic3r::Surface;
|
||||
our $layer_height = 0.4;
|
||||
our $resolution = 0.1;
|
||||
our $perimeter_offsets = 3;
|
||||
our $fill_density = 0.2; # 1 = 100%
|
||||
our $flow_width = 0.4;
|
||||
our $fill_density = 0.4; # 1 = 100%
|
||||
our $filament_diameter = 3; # mm
|
||||
our $filament_packing_density = 0.85;
|
||||
our $flow_width = 0.50;
|
||||
our $temperature = 195;
|
||||
|
||||
our $flow_rate = 60; # mm/sec
|
||||
our $print_feed_rate = 60; # mm/sec
|
||||
our $travel_feed_rate = 80; # mm/sec
|
||||
our $bottom_layer_speed_ratio = 0.6;
|
||||
|
||||
our $retract_length = 2; # mm
|
||||
our $retract_restart_extra = 0; # mm
|
||||
our $retract_speed = 40; # mm/sec
|
||||
|
||||
our $use_relative_e_distances = 0;
|
||||
|
||||
our $print_center = [100,100]; # object will be centered around this point
|
||||
|
@ -19,7 +19,7 @@ sub make_fill {
|
||||
# let's alternate fill direction
|
||||
my @axes = $layer->id % 2 == 0 ? (0,1) : (1,0);
|
||||
|
||||
foreach my $surface (@{ $layer->fill_surfaces }) {
|
||||
SURFACE: foreach my $surface (@{ $layer->fill_surfaces }) {
|
||||
Slic3r::debugf " Processing surface %s:\n", $surface->id;
|
||||
my $polygon = $surface->mgp_polygon;
|
||||
|
||||
@ -30,6 +30,7 @@ sub make_fill {
|
||||
|
||||
# force 100% density for external surfaces
|
||||
my $density = $surface->surface_type eq 'internal' ? $Slic3r::fill_density : 1;
|
||||
next SURFACE unless $density > 0;
|
||||
my $distance_between_lines = $Slic3r::flow_width / $Slic3r::resolution / $density;
|
||||
my $number_of_lines = ($axes[0] == 0 ? $print->x_length : $print->y_length) / $distance_between_lines;
|
||||
|
||||
@ -96,7 +97,7 @@ sub make_fill {
|
||||
|
||||
# loop through rows
|
||||
ROW: for (my $i = 0; $i < $number_of_lines; $i++) {
|
||||
my $row = $points->[$i];
|
||||
my $row = $points->[$i] or next ROW;
|
||||
Slic3r::debugf "Processing row %d...\n", $i;
|
||||
if (!@$row) {
|
||||
Slic3r::debugf " no points\n";
|
||||
|
@ -1,6 +1,7 @@
|
||||
package Slic3r::Print;
|
||||
use Moose;
|
||||
|
||||
use constant PI => 4 * atan2(1, 1);
|
||||
use constant X => 0;
|
||||
use constant Y => 1;
|
||||
|
||||
@ -75,10 +76,10 @@ sub export_gcode {
|
||||
# calculate speed for gcode commands
|
||||
my $travel_feed_rate = $Slic3r::travel_feed_rate * 60; # mm/min
|
||||
my $print_feed_rate = $Slic3r::print_feed_rate * 60; # mm/min
|
||||
my $extrusion_speed_ratio = ($Slic3r::flow_rate / $Slic3r::print_feed_rate);
|
||||
my $retract_speed = $Slic3r::retract_speed * 60; # mm/min
|
||||
|
||||
# calculate number of decimals
|
||||
my $dec = length((1 / $Slic3r::resolution) - 1);
|
||||
my $dec = length((1 / $Slic3r::resolution) - 1) + 1;
|
||||
|
||||
# calculate X,Y shift to center print around specified origin
|
||||
my @shift = (
|
||||
@ -103,17 +104,33 @@ sub export_gcode {
|
||||
}
|
||||
|
||||
# make up a subroutine to generate G1 commands
|
||||
my $extrusion_distance = 0;
|
||||
my $G1 = sub {
|
||||
my ($point, $z, $extrusion_distance, $comment) = @_;
|
||||
printf $fh "G1 X%.${dec}f Y%.${dec}f Z%.${dec}f",
|
||||
($point->x * $Slic3r::resolution) + $shift[X],
|
||||
($point->y * $Slic3r::resolution) + $shift[Y], #**
|
||||
$z;
|
||||
my $speed_multiplier = $z == 0 ? $Slic3r::bottom_layer_speed_ratio : 1;
|
||||
if ($extrusion_distance) {
|
||||
printf $fh " F%.${dec}f E%.${dec}f",
|
||||
($print_feed_rate * $speed_multiplier),
|
||||
($extrusion_distance * $extrusion_speed_ratio * $Slic3r::resolution);
|
||||
my ($point, $z, $e, $comment) = @_;
|
||||
printf $fh "G1";
|
||||
|
||||
if ($point) {
|
||||
printf $fh " X%.${dec}f Y%.${dec}f",
|
||||
($point->x * $Slic3r::resolution) + $shift[X],
|
||||
($point->y * $Slic3r::resolution) + $shift[Y]; #**
|
||||
}
|
||||
if ($z) {
|
||||
printf $fh " Z%.${dec}f", $z;
|
||||
}
|
||||
|
||||
# apply the speed reduction for print moves on bottom layer
|
||||
my $speed_multiplier = defined $z && $z == 0 && $point
|
||||
? $Slic3r::bottom_layer_speed_ratio
|
||||
: 1;
|
||||
|
||||
if ($e) {
|
||||
$extrusion_distance = 0 if $Slic3r::use_relative_e_distances;
|
||||
$extrusion_distance += $e;
|
||||
printf $fh " F%.${dec}f E%.5f",
|
||||
$e < 0
|
||||
? $retract_speed
|
||||
: ($print_feed_rate * $speed_multiplier),
|
||||
$extrusion_distance;
|
||||
} else {
|
||||
printf $fh " F%.${dec}f", ($travel_feed_rate * $speed_multiplier);
|
||||
}
|
||||
@ -122,26 +139,41 @@ sub export_gcode {
|
||||
};
|
||||
|
||||
my $z;
|
||||
my $retracted = 0;
|
||||
my $Extrude = sub {
|
||||
my ($path, $description) = @_;
|
||||
|
||||
# reset extrusion distance counter
|
||||
my $extrusion_distance = 0;
|
||||
if (!$Slic3r::use_relative_e_distances) {
|
||||
$extrusion_distance = 0;
|
||||
print $fh "G92 E0 ; reset extrusion distance\n";
|
||||
}
|
||||
|
||||
# go to first point (without extruding)
|
||||
$G1->($path->lines->[0]->a, $z, 0, "move to first $description point");
|
||||
# go to first point while compensating retraction
|
||||
$G1->($path->lines->[0]->a, $z,
|
||||
$retracted
|
||||
? ($Slic3r::retract_length + $Slic3r::retract_restart_extra)
|
||||
: 0,
|
||||
"move to first $description point");
|
||||
|
||||
# extrude while going to next points
|
||||
foreach my $line (@{ $path->lines }) {
|
||||
$extrusion_distance = 0 if $Slic3r::use_relative_e_distances;
|
||||
$extrusion_distance += $line->a->distance_to($line->b);
|
||||
$G1->($line->b, $z, $extrusion_distance, $description);
|
||||
# calculate how much filament to drive into the extruder
|
||||
# to get the desired amount of extruded plastic
|
||||
my $e = $line->a->distance_to($line->b) * $Slic3r::resolution
|
||||
* $Slic3r::flow_width
|
||||
* $Slic3r::layer_height
|
||||
/ (($Slic3r::filament_diameter ** 2) * PI)
|
||||
/ $Slic3r::filament_packing_density;
|
||||
|
||||
$G1->($line->b, $z, $e, $description);
|
||||
}
|
||||
|
||||
# TODO: retraction
|
||||
# retract
|
||||
if ($Slic3r::retract_length > 0) {
|
||||
$G1->(undef, undef, -$Slic3r::retract_length, "retract");
|
||||
$retracted = 1;
|
||||
}
|
||||
};
|
||||
|
||||
# write gcode commands layer by layer
|
||||
|
27
slic3r.pl
27
slic3r.pl
@ -10,6 +10,7 @@ BEGIN {
|
||||
|
||||
use Getopt::Long;
|
||||
use Slic3r;
|
||||
use Time::HiRes qw(gettimeofday tv_interval);
|
||||
use XXX;
|
||||
|
||||
my %opt;
|
||||
@ -23,15 +24,16 @@ GetOptions(
|
||||
'resolution=f' => \$Slic3r::resolution,
|
||||
'perimeters=i' => \$Slic3r::perimeter_offsets,
|
||||
'fill-density=f' => \$Slic3r::fill_density,
|
||||
'filament-diameter=f' => \$Slic3r::filament_diameter,
|
||||
'flow-width=f' => \$Slic3r::flow_width,
|
||||
'temperature=i' => \$Slic3r::temperature,
|
||||
'flow-rate=i' => \$Slic3r::flow_rate,
|
||||
'print-feed-rate=i' => \$Slic3r::print_feed_rate,
|
||||
'travel-feed-rate=i' => \$Slic3r::travel_feed_rate,
|
||||
'bottom-layer-speed-ratio=f' => \$Slic3r::bottom_layer_speed_ratio,
|
||||
'use-relative-e-distances' => \$Slic3r::use_relative_e_distances,
|
||||
'print-center=s' => \$Slic3r::print_center,
|
||||
'',
|
||||
'retract-length=f' => \$Slic3r::retract_length,
|
||||
'retract-restart-extra=f' => \$Slic3r::retract_restart_extra,
|
||||
);
|
||||
|
||||
# validate configuration
|
||||
@ -42,6 +44,10 @@ GetOptions(
|
||||
die "--layer-height must be a multiple of print resolution\n"
|
||||
if $Slic3r::layer_height / $Slic3r::resolution % 1 != 0;
|
||||
|
||||
# --filament-diameter
|
||||
die "Invalid value for --filament-diameter\n"
|
||||
if $Slic3r::filament_diameter < 1;
|
||||
|
||||
# --flow-width
|
||||
die "Invalid value for --flow-width\n"
|
||||
if $Slic3r::flow_width < 0;
|
||||
@ -72,6 +78,7 @@ if ($action eq 'skein') {
|
||||
die "Input file must have .stl extension\n"
|
||||
if $input_file !~ /\.stl$/i;
|
||||
|
||||
my $t0 = [gettimeofday];
|
||||
my $print = $stl_parser->parse_file($input_file);
|
||||
$print->extrude_perimeters;
|
||||
$print->extrude_fills;
|
||||
@ -79,6 +86,10 @@ if ($action eq 'skein') {
|
||||
my $output_file = $input_file;
|
||||
$output_file =~ s/\.stl$/.gcode/i;
|
||||
$print->export_gcode($opt{output} || $output_file);
|
||||
|
||||
my $processing_time = tv_interval($t0);
|
||||
printf "Done. Process took %d minutes and %.3f seconds\n",
|
||||
int($processing_time/60), $processing_time - int($processing_time/60);
|
||||
}
|
||||
|
||||
sub usage {
|
||||
@ -93,14 +104,22 @@ Usage: slic3r.pl [ OPTIONS ] file.stl
|
||||
--perimeters Number of perimeters/horizontal skins
|
||||
(range: 1+, default: $Slic3r::perimeter_offsets)
|
||||
--fill-density Infill density (range: 0-1, default: $Slic3r::fill_density)
|
||||
--filament-diameter Diameter of your raw filament (default: $Slic3r::filament_diameter)
|
||||
--filament-packing-density
|
||||
Ratio of the extruded volume over volume pushed into
|
||||
the extruder (default: $Slic3r::filament_packing_density)
|
||||
--flow-width Width of extruded flow in mm (default: $Slic3r::flow_width)
|
||||
--flow-rate Speed of extrusion in mm/sec; should be equal to
|
||||
--print-feed-rate (default: $Slic3r::flow_rate)
|
||||
--print-feed-rate Speed of print moves in mm/sec (default: $Slic3r::print_feed_rate)
|
||||
--travel-feed-rate Speed of non-print moves in mm/sec (default: $Slic3r::travel_feed_rate)
|
||||
--bottom-layer-speed-ratio
|
||||
Factor to increase/decrease speeds on bottom layer by
|
||||
(default: $Slic3r::bottom_layer_speed_ratio)
|
||||
--retract-length Length of retraction in mm when pausing extrusion
|
||||
(default: $Slic3r::retract_length)
|
||||
--retract-speed Speed for retraction in mm/sec (default: $Slic3r::retract_speed)
|
||||
--retract-restart-extra
|
||||
Additional amount of filament in mm to push after compensating
|
||||
retraction (default: $Slic3r::retract_restart_extra)
|
||||
--use-relative-e-distances
|
||||
Use relative distances for extrusion in GCODE output
|
||||
--print-center Coordinates of the point to center the print around
|
||||
|
Loading…
Reference in New Issue
Block a user