Store config in Slic3r::GCode object

This commit is contained in:
Alessandro Ranellucci 2013-05-31 11:19:36 +02:00
parent 7baaf6bf5d
commit da76496988
3 changed files with 72 additions and 68 deletions

View File

@ -6,6 +6,7 @@ use Slic3r::ExtrusionPath ':roles';
use Slic3r::Geometry qw(scale unscale scaled_epsilon points_coincide PI X Y B);
use Slic3r::Geometry::Clipper qw(union_ex);
has 'config' => (is => 'ro', required => 1);
has 'multiple_extruders' => (is => 'ro', default => sub {0} );
has 'layer_count' => (is => 'ro', required => 1 );
has 'layer' => (is => 'rw');
@ -15,6 +16,7 @@ has 'shift_y' => (is => 'rw', default => sub {0} );
has 'z' => (is => 'rw');
has 'speed' => (is => 'rw');
has 'speeds' => (is => 'lazy'); # mm/min
has 'external_mp' => (is => 'rw');
has 'layer_mp' => (is => 'rw');
has 'new_object' => (is => 'rw', default => sub {0});
@ -35,15 +37,14 @@ has 'dec' => (is => 'ro', default => sub { 3 } );
has 'last_dir' => (is => 'ro', default => sub { [0,0] });
has 'dir_time' => (is => 'ro', default => sub { [0,0] });
# calculate speeds (mm/min)
has 'speeds' => (
is => 'ro',
default => sub {+{
map { $_ => 60 * $Slic3r::Config->get_value("${_}_speed") }
sub _build_speeds {
my $self = shift;
return {
map { $_ => 60 * $self->config->get_value("${_}_speed") }
qw(travel perimeter small_perimeter external_perimeter infill
solid_infill top_solid_infill support_material bridge gap_fill retract),
}},
);
};
}
# assign speeds to roles
my %role_speeds = (
@ -81,17 +82,17 @@ sub change_layer {
my ($layer) = @_;
$self->layer($layer);
if ($Slic3r::Config->avoid_crossing_perimeters) {
if ($self->config->avoid_crossing_perimeters) {
$self->layer_mp(Slic3r::GCode::MotionPlanner->new(
islands => union_ex([ map @$_, @{$layer->slices} ], undef, 1),
));
}
my $gcode = "";
if ($Slic3r::Config->gcode_flavor =~ /^(?:makerbot|sailfish)$/) {
if ($self->config->gcode_flavor =~ /^(?:makerbot|sailfish)$/) {
$gcode .= sprintf "M73 P%s%s\n",
int(99 * ($layer->id / ($self->layer_count - 1))),
($Slic3r::Config->gcode_comments ? ' ; update progress' : '');
($self->config->gcode_comments ? ' ; update progress' : '');
}
return $gcode;
}
@ -102,7 +103,7 @@ sub move_z {
my ($z, $comment) = @_;
$z *= &Slic3r::SCALING_FACTOR;
$z += $Slic3r::Config->z_offset;
$z += $self->config->z_offset;
my $gcode = "";
my $current_z = $self->z;
@ -136,9 +137,9 @@ sub extrude_loop {
# find the point of the loop that is closest to the current extruder position
# or randomize if requested
my $last_pos = $self->last_pos;
if ($Slic3r::Config->randomize_start && $loop->role == EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER) {
$last_pos = Slic3r::Point->new(scale $Slic3r::Config->print_center->[X], scale $Slic3r::Config->bed_size->[Y]);
$last_pos->rotate(rand(2*PI), $Slic3r::Config->print_center);
if ($self->config->randomize_start && $loop->role == EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER) {
$last_pos = Slic3r::Point->new(scale $self->config->print_center->[X], scale $self->config->bed_size->[Y]);
$last_pos->rotate(rand(2*PI), $self->config->print_center);
}
my $start_index = $loop->nearest_point_index_to($last_pos);
@ -156,7 +157,7 @@ sub extrude_loop {
$self->wipe_path($extrusion_path->polyline);
# make a little move inwards before leaving loop
if ($loop->role == EXTR_ROLE_EXTERNAL_PERIMETER && $Slic3r::Config->perimeters > 1) {
if ($loop->role == EXTR_ROLE_EXTERNAL_PERIMETER && $self->config->perimeters > 1) {
# detect angle between last and first segment
# the side depends on the original winding order of the polygon (left for contours, right for holes)
my @points = $was_clockwise ? (-2, 1) : (1, -2);
@ -187,7 +188,7 @@ sub extrude_path {
$path->simplify(&Slic3r::SCALED_RESOLUTION);
# detect arcs
if ($Slic3r::Config->gcode_arcs && !$recursive) {
if ($self->config->gcode_arcs && !$recursive) {
my $gcode = "";
foreach my $arc_path ($path->detect_arcs) {
$gcode .= $self->extrude_path($arc_path, $description, 1);
@ -204,12 +205,12 @@ sub extrude_path {
# adjust acceleration
my $acceleration;
if ($Slic3r::Config->perimeter_acceleration && $path->is_perimeter) {
$acceleration = $Slic3r::Config->perimeter_acceleration;
} elsif ($Slic3r::Config->infill_acceleration && $path->is_fill) {
$acceleration = $Slic3r::Config->infill_acceleration;
} elsif ($Slic3r::Config->infill_acceleration && ($path->role == EXTR_ROLE_BRIDGE || $path->role == EXTR_ROLE_INTERNALBRIDGE)) {
$acceleration = $Slic3r::Config->bridge_acceleration;
if ($self->config->perimeter_acceleration && $path->is_perimeter) {
$acceleration = $self->config->perimeter_acceleration;
} elsif ($self->config->infill_acceleration && $path->is_fill) {
$acceleration = $self->config->infill_acceleration;
} elsif ($self->config->infill_acceleration && ($path->role == EXTR_ROLE_BRIDGE || $path->role == EXTR_ROLE_INTERNALBRIDGE)) {
$acceleration = $self->config->bridge_acceleration;
}
$gcode .= $self->set_acceleration($acceleration) if $acceleration;
@ -251,19 +252,19 @@ sub extrude_path {
if $self->extruder->wipe;
}
if ($Slic3r::Config->cooling) {
if ($self->config->cooling) {
my $path_time = $path_length / $self->speeds->{$self->last_speed} * 60;
if ($self->layer->id == 0) {
$path_time = $Slic3r::Config->first_layer_speed =~ /^(\d+(?:\.\d+)?)%$/
$path_time = $self->config->first_layer_speed =~ /^(\d+(?:\.\d+)?)%$/
? $path_time / ($1/100)
: $path_length / $Slic3r::Config->first_layer_speed * 60;
: $path_length / $self->config->first_layer_speed * 60;
}
$self->elapsed_time($self->elapsed_time + $path_time);
}
# reset acceleration
$gcode .= $self->set_acceleration($Slic3r::Config->default_acceleration)
if $acceleration && $Slic3r::Config->default_acceleration;
$gcode .= $self->set_acceleration($self->config->default_acceleration)
if $acceleration && $self->config->default_acceleration;
return $gcode;
}
@ -282,13 +283,13 @@ sub travel_to {
$travel->translate(-$self->shift_x, -$self->shift_y);
if ($travel->length < scale $self->extruder->retract_before_travel
|| ($Slic3r::Config->only_retract_when_crossing_perimeters && first { $_->encloses_line($travel, scaled_epsilon) } @{$self->layer->slices})
|| ($self->config->only_retract_when_crossing_perimeters && first { $_->encloses_line($travel, scaled_epsilon) } @{$self->layer->slices})
|| ($role == EXTR_ROLE_SUPPORTMATERIAL && $self->layer->support_islands_enclose_line($travel))
) {
$self->straight_once(0);
$self->speed('travel');
$gcode .= $self->G0($point, undef, 0, $comment || "");
} elsif (!$Slic3r::Config->avoid_crossing_perimeters || $self->straight_once) {
} elsif (!$self->config->avoid_crossing_perimeters || $self->straight_once) {
$self->straight_once(0);
$gcode .= $self->retract(travel_to => $point);
$self->speed('travel');
@ -322,7 +323,7 @@ sub _plan {
my @travel = $mp->shortest_path($self->last_pos, $point)->lines;
# if the path is not contained in a single island we need to retract
my $need_retract = !$Slic3r::Config->only_retract_when_crossing_perimeters;
my $need_retract = !$self->config->only_retract_when_crossing_perimeters;
if (!$need_retract) {
$need_retract = 1;
foreach my $slice (@{$self->layer->slices}) {
@ -370,7 +371,7 @@ sub retract {
? undef
: [undef, $self->z + $self->extruder->retract_lift, 0, 'lift plate during travel'];
if (($Slic3r::Config->g0 || $Slic3r::Config->gcode_flavor eq 'mach3') && $params{travel_to}) {
if (($self->config->g0 || $self->config->gcode_flavor eq 'mach3') && $params{travel_to}) {
$self->speed('travel');
if ($lift) {
# combine lift and retract
@ -381,7 +382,7 @@ sub retract {
my $travel = [$params{travel_to}, undef, $retract->[2], "travel and $comment"];
$gcode .= $self->G0(@$travel);
}
} elsif (($Slic3r::Config->g0 || $Slic3r::Config->gcode_flavor eq 'mach3') && defined $params{move_z}) {
} elsif (($self->config->g0 || $self->config->gcode_flavor eq 'mach3') && defined $params{move_z}) {
# combine Z change and retraction
$self->speed('travel');
my $travel = [undef, $params{move_z}, $retract->[2], "change layer and $comment"];
@ -417,7 +418,7 @@ sub retract {
# reset extrusion distance during retracts
# this makes sure we leave sufficient precision in the firmware
$gcode .= $self->reset_e if $Slic3r::Config->gcode_flavor !~ /^(?:mach3|makerbot)$/;
$gcode .= $self->reset_e if $self->config->gcode_flavor !~ /^(?:mach3|makerbot)$/;
return $gcode;
}
@ -448,8 +449,8 @@ sub reset_e {
my $self = shift;
$self->extrusion_distance(0);
return sprintf "G92 %s0%s\n", $Slic3r::Config->extrusion_axis, ($Slic3r::Config->gcode_comments ? ' ; reset extrusion distance' : '')
if $Slic3r::Config->extrusion_axis && !$Slic3r::Config->use_relative_e_distances;
return sprintf "G92 %s0%s\n", $self->config->extrusion_axis, ($self->config->gcode_comments ? ' ; reset extrusion distance' : '')
if $self->config->extrusion_axis && !$self->config->use_relative_e_distances;
}
sub set_acceleration {
@ -458,12 +459,12 @@ sub set_acceleration {
return "" if !$acceleration;
return sprintf "M204 S%s%s\n",
$acceleration, ($Slic3r::Config->gcode_comments ? ' ; adjust acceleration' : '');
$acceleration, ($self->config->gcode_comments ? ' ; adjust acceleration' : '');
}
sub G0 {
my $self = shift;
return $self->G1(@_) if !($Slic3r::Config->g0 || $Slic3r::Config->gcode_flavor eq 'mach3');
return $self->G1(@_) if !($self->config->g0 || $self->config->gcode_flavor eq 'mach3');
return $self->_G0_G1("G0", @_);
}
@ -533,9 +534,9 @@ sub _Gx {
? ($self->extruder->retract_speed_mm_min)
: $self->speeds->{$self->speed} // $self->speed;
if ($e && $self->layer && $self->layer->id == 0 && $comment !~ /retract/) {
$F = $Slic3r::Config->first_layer_speed =~ /^(\d+(?:\.\d+)?)%$/
$F = $self->config->first_layer_speed =~ /^(\d+(?:\.\d+)?)%$/
? ($F * $1/100)
: $Slic3r::Config->first_layer_speed * 60;
: $self->config->first_layer_speed * 60;
}
$self->last_speed($self->speed);
$self->last_f($F);
@ -543,14 +544,14 @@ sub _Gx {
$gcode .= sprintf " F%.${dec}f", $F if defined $F;
# output extrusion distance
if ($e && $Slic3r::Config->extrusion_axis) {
$self->extrusion_distance(0) if $Slic3r::Config->use_relative_e_distances;
if ($e && $self->config->extrusion_axis) {
$self->extrusion_distance(0) if $self->config->use_relative_e_distances;
$self->extrusion_distance($self->extrusion_distance + $e);
$self->total_extrusion_length($self->total_extrusion_length + $e);
$gcode .= sprintf " %s%.5f", $Slic3r::Config->extrusion_axis, $self->extrusion_distance;
$gcode .= sprintf " %s%.5f", $self->config->extrusion_axis, $self->extrusion_distance;
}
$gcode .= sprintf " ; %s", $comment if $comment && $Slic3r::Config->gcode_comments;
$gcode .= sprintf " ; %s", $comment if $comment && $self->config->gcode_comments;
if ($append_bridge_off) {
$gcode .= "\n;_BRIDGE_FAN_END";
}
@ -575,8 +576,8 @@ sub set_extruder {
$gcode .= $self->retract(toolchange => 1) if defined $self->extruder;
# append custom toolchange G-code
if (defined $self->extruder && $Slic3r::Config->toolchange_gcode) {
$gcode .= sprintf "%s\n", $Slic3r::Config->replace_options($Slic3r::Config->toolchange_gcode, {
if (defined $self->extruder && $self->config->toolchange_gcode) {
$gcode .= sprintf "%s\n", $self->config->replace_options($self->config->toolchange_gcode, {
previous_extruder => $self->extruder->id,
next_extruder => $extruder->id,
});
@ -585,11 +586,11 @@ sub set_extruder {
# set the new extruder
$self->extruder($extruder);
my $toolchange_gcode = sprintf "%s%d%s\n",
($Slic3r::Config->gcode_flavor =~ /^(?:makerbot|sailfish)$/ ? 'M108 T' : 'T'),
($self->config->gcode_flavor =~ /^(?:makerbot|sailfish)$/ ? 'M108 T' : 'T'),
$extruder->id,
($Slic3r::Config->gcode_comments ? ' ; change extruder' : '');
($self->config->gcode_comments ? ' ; change extruder' : '');
if ($Slic3r::Config->gcode_flavor =~ /^(?:makerbot|sailfish)$/) {
if ($self->config->gcode_flavor =~ /^(?:makerbot|sailfish)$/) {
$gcode .= $self->reset_e;
$gcode .= $toolchange_gcode;
} else {
@ -607,18 +608,18 @@ sub set_fan {
if ($self->last_fan_speed != $speed || $dont_save) {
$self->last_fan_speed($speed) if !$dont_save;
if ($speed == 0) {
my $code = $Slic3r::Config->gcode_flavor eq 'teacup'
my $code = $self->config->gcode_flavor eq 'teacup'
? 'M106 S0'
: $Slic3r::Config->gcode_flavor =~ /^(?:makerbot|sailfish)$/
: $self->config->gcode_flavor =~ /^(?:makerbot|sailfish)$/
? 'M127'
: 'M107';
return sprintf "$code%s\n", ($Slic3r::Config->gcode_comments ? ' ; disable fan' : '');
return sprintf "$code%s\n", ($self->config->gcode_comments ? ' ; disable fan' : '');
} else {
if ($Slic3r::Config->gcode_flavor =~ /^(?:makerbot|sailfish)$/) {
return sprintf "M126%s\n", ($Slic3r::Config->gcode_comments ? ' ; enable fan' : '');
if ($self->config->gcode_flavor =~ /^(?:makerbot|sailfish)$/) {
return sprintf "M126%s\n", ($self->config->gcode_comments ? ' ; enable fan' : '');
} else {
return sprintf "M106 %s%d%s\n", ($Slic3r::Config->gcode_flavor eq 'mach3' ? 'P' : 'S'),
(255 * $speed / 100), ($Slic3r::Config->gcode_comments ? ' ; enable fan' : '');
return sprintf "M106 %s%d%s\n", ($self->config->gcode_flavor eq 'mach3' ? 'P' : 'S'),
(255 * $speed / 100), ($self->config->gcode_comments ? ' ; enable fan' : '');
}
}
}
@ -629,17 +630,17 @@ sub set_temperature {
my $self = shift;
my ($temperature, $wait, $tool) = @_;
return "" if $wait && $Slic3r::Config->gcode_flavor =~ /^(?:makerbot|sailfish)$/;
return "" if $wait && $self->config->gcode_flavor =~ /^(?:makerbot|sailfish)$/;
my ($code, $comment) = ($wait && $Slic3r::Config->gcode_flavor ne 'teacup')
my ($code, $comment) = ($wait && $self->config->gcode_flavor ne 'teacup')
? ('M109', 'wait for temperature to be reached')
: ('M104', 'set temperature');
my $gcode = sprintf "$code %s%d %s; $comment\n",
($Slic3r::Config->gcode_flavor eq 'mach3' ? 'P' : 'S'), $temperature,
(defined $tool && ($self->multiple_extruders || $Slic3r::Config->gcode_flavor =~ /^(?:makerbot|sailfish)$/)) ? "T$tool " : "";
($self->config->gcode_flavor eq 'mach3' ? 'P' : 'S'), $temperature,
(defined $tool && ($self->multiple_extruders || $self->config->gcode_flavor =~ /^(?:makerbot|sailfish)$/)) ? "T$tool " : "";
$gcode .= "M116 ; wait for temperature to be reached\n"
if $Slic3r::Config->gcode_flavor eq 'teacup' && $wait;
if $self->config->gcode_flavor eq 'teacup' && $wait;
return $gcode;
}
@ -648,14 +649,14 @@ sub set_bed_temperature {
my $self = shift;
my ($temperature, $wait) = @_;
my ($code, $comment) = ($wait && $Slic3r::Config->gcode_flavor ne 'teacup')
? (($Slic3r::Config->gcode_flavor =~ /^(?:makerbot|sailfish)$/ ? 'M109' : 'M190'), 'wait for bed temperature to be reached')
my ($code, $comment) = ($wait && $self->config->gcode_flavor ne 'teacup')
? (($self->config->gcode_flavor =~ /^(?:makerbot|sailfish)$/ ? 'M109' : 'M190'), 'wait for bed temperature to be reached')
: ('M140', 'set bed temperature');
my $gcode = sprintf "$code %s%d ; $comment\n",
($Slic3r::Config->gcode_flavor eq 'mach3' ? 'P' : 'S'), $temperature;
($self->config->gcode_flavor eq 'mach3' ? 'P' : 'S'), $temperature;
$gcode .= "M116 ; wait for bed temperature to be reached\n"
if $Slic3r::Config->gcode_flavor eq 'teacup' && $wait;
if $self->config->gcode_flavor eq 'teacup' && $wait;
return $gcode;
}
@ -665,8 +666,8 @@ sub _limit_frequency {
my $self = shift;
my ($point) = @_;
return '' if $Slic3r::Config->vibration_limit == 0;
my $min_time = 1 / ($Slic3r::Config->vibration_limit * 60); # in minutes
return '' if $self->config->vibration_limit == 0;
my $min_time = 1 / ($self->config->vibration_limit * 60); # in minutes
# calculate the move vector and move direction
my $vector = Slic3r::Line->new($self->last_pos, $point)->vector;

View File

@ -688,6 +688,7 @@ sub write_gcode {
# set up our extruder object
my $gcodegen = Slic3r::GCode->new(
config => $self->config,
multiple_extruders => (@{$self->extruders} > 1),
layer_count => $self->layer_count,
);

View File

@ -11,8 +11,10 @@ use Slic3r;
use Slic3r::Geometry qw(scale);
{
local $Slic3r::Config = Slic3r::Config->new_from_defaults;
my $gcodegen = Slic3r::GCode->new(layer_count => 1);
my $gcodegen = Slic3r::GCode->new(
config => Slic3r::Config->new_from_defaults,
layer_count => 1,
);
$gcodegen->set_shift(10, 10);
is_deeply $gcodegen->last_pos, [scale -10, scale -10], 'last_pos is shifted correctly';
}