2012-06-28 14:44:54 +02:00
package Slic3r::GCode ;
use Moo ;
2012-08-25 17:18:12 +02:00
use List::Util qw(first) ;
2012-06-28 14:44:54 +02:00
use Slic3r::ExtrusionPath ':roles' ;
2012-09-12 15:19:47 +02:00
use Slic3r::Geometry qw(scale unscale scaled_epsilon points_coincide PI X Y) ;
2012-06-28 14:44:54 +02:00
2012-09-23 02:40:25 +02:00
has 'multiple_extruders' => ( is => 'ro' , default => sub { 0 } );
2012-10-28 16:59:20 +01:00
has 'layer' => ( is => 'rw' ); # this is not very correct, we should replace it with explicit layer_id and avoid using $self->layer->flow at all here because it's too general
2012-06-28 14:44:54 +02:00
has 'shift_x' => ( is => 'rw' , default => sub { 0 } );
has 'shift_y' => ( is => 'rw' , default => sub { 0 } );
has 'z' => ( is => 'rw' , default => sub { 0 } );
has 'speed' => ( is => 'rw' );
2012-09-23 02:40:25 +02:00
has 'extruder' => ( is => 'rw' );
2012-06-28 14:44:54 +02:00
has 'extrusion_distance' => ( is => 'rw' , default => sub { 0 } );
has 'elapsed_time' => ( is => 'rw' , default => sub { 0 } ); # seconds
has 'total_extrusion_length' => ( is => 'rw' , default => sub { 0 } );
has 'lifted' => ( is => 'rw' , default => sub { 0 } );
has 'last_pos' => ( is => 'rw' , default => sub { Slic3r::Point -> new ( 0 , 0 ) } );
has 'last_speed' => ( is => 'rw' , default => sub { "" });
has 'last_fan_speed' => ( is => 'rw' , default => sub { 0 });
has 'dec' => ( is => 'ro' , default => sub { 3 } );
# calculate speeds (mm/min)
has 'speeds' => (
is => 'ro' ,
default => sub {{
2012-07-27 21:13:03 +02:00
travel => 60 * $ Slic3r:: Config -> get_value ( 'travel_speed' ),
perimeter => 60 * $ Slic3r:: Config -> get_value ( 'perimeter_speed' ),
small_perimeter => 60 * $ Slic3r:: Config -> get_value ( 'small_perimeter_speed' ),
external_perimeter => 60 * $ Slic3r:: Config -> get_value ( 'external_perimeter_speed' ),
infill => 60 * $ Slic3r:: Config -> get_value ( 'infill_speed' ),
solid_infill => 60 * $ Slic3r:: Config -> get_value ( 'solid_infill_speed' ),
top_solid_infill => 60 * $ Slic3r:: Config -> get_value ( 'top_solid_infill_speed' ),
bridge => 60 * $ Slic3r:: Config -> get_value ( 'bridge_speed' ),
2012-06-28 14:44:54 +02:00
}},
);
my %role_speeds = (
& EXTR_ROLE_PERIMETER => 'perimeter' ,
& EXTR_ROLE_SMALLPERIMETER => 'small_perimeter' ,
& EXTR_ROLE_EXTERNAL_PERIMETER => 'external_perimeter' ,
& EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER => 'perimeter' ,
& EXTR_ROLE_FILL => 'infill' ,
& EXTR_ROLE_SOLIDFILL => 'solid_infill' ,
& EXTR_ROLE_TOPSOLIDFILL => 'top_solid_infill' ,
& EXTR_ROLE_BRIDGE => 'bridge' ,
& EXTR_ROLE_SKIRT => 'perimeter' ,
& EXTR_ROLE_SUPPORTMATERIAL => 'perimeter' ,
);
sub change_layer {
my $self = shift ;
2012-10-28 16:59:20 +01:00
my ( $layer , %params ) = @_ ;
2012-06-28 14:44:54 +02:00
$self -> layer ( $layer );
my $gcode = "" ;
2012-10-28 16:59:20 +01:00
$gcode .= $self -> move_z ( $layer -> print_z ) unless $params { dont_move_z };
2012-06-28 14:44:54 +02:00
2012-07-27 21:13:03 +02:00
$gcode .= $ Slic3r:: Config -> replace_options ( $ Slic3r:: Config -> layer_gcode ) . "\n"
if $ Slic3r:: Config -> layer_gcode ;
2012-06-28 14:44:54 +02:00
return $gcode ;
}
2012-10-28 16:59:20 +01:00
# this method accepts Z in scaled coordinates
sub move_z {
my $self = shift ;
my ( $z , $comment ) = @_ ;
$z = $ Slic3r:: Config -> z_offset + $z * & Slic3r:: SCALING_FACTOR ;
my $gcode = "" ;
$gcode .= $self -> retract ( move_z => $z );
$gcode .= $self -> G0 ( undef , $z , 0 , $comment || 'move to next layer (' . $self -> layer -> id . ')' )
if $self -> z != $z && ! $self -> lifted ;
return $gcode ;
}
2012-06-28 14:44:54 +02:00
sub extrude {
my $self = shift ;
2012-07-23 17:51:04 +02:00
( $_ [ 0 ] -> isa ( 'Slic3r::ExtrusionLoop' ) || $_ [ 0 ] -> isa ( 'Slic3r::ExtrusionLoop::Packed' ))
2012-07-20 14:39:07 +02:00
? $self -> extrude_loop ( @_ )
: $self -> extrude_path ( @_ );
2012-06-28 14:44:54 +02:00
}
sub extrude_loop {
my $self = shift ;
my ( $loop , $description ) = @_ ;
# extrude all loops ccw
2012-07-23 17:56:20 +02:00
$loop = $loop -> unpack if $loop -> isa ( 'Slic3r::ExtrusionLoop::Packed' );
2012-06-28 14:44:54 +02:00
$loop -> polygon -> make_counter_clockwise ;
# find the point of the loop that is closest to the current extruder position
# or randomize if requested
my $last_pos = $self -> last_pos ;
2012-07-27 21:13:03 +02:00
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 );
2012-06-28 14:44:54 +02:00
}
2012-07-02 20:26:56 +01:00
my $start_index = $loop -> nearest_point_index_to ( $last_pos );
2012-06-28 14:44:54 +02:00
# split the loop at the starting point and make a path
2012-07-02 20:26:56 +01:00
my $extrusion_path = $loop -> split_at_index ( $start_index );
2012-06-28 14:44:54 +02:00
# 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
2012-09-23 03:03:08 +02:00
$extrusion_path -> clip_end ( $self -> layer ? $self -> layer -> flow -> scaled_width : $ Slic3r:: flow -> scaled_width * 0.15 );
2012-06-28 14:44:54 +02:00
return '' if ! @ { $extrusion_path -> polyline };
# extrude along the path
return $self -> extrude_path ( $extrusion_path , $description );
}
sub extrude_path {
my $self = shift ;
my ( $path , $description , $recursive ) = @_ ;
2012-07-20 14:39:07 +02:00
$path = $path -> unpack if $path -> isa ( 'Slic3r::ExtrusionPath::Packed' );
2012-06-28 14:44:54 +02:00
$path -> merge_continuous_lines ;
# detect arcs
2012-07-27 21:13:03 +02:00
if ( $ Slic3r:: Config -> gcode_arcs && ! $recursive ) {
2012-06-28 14:44:54 +02:00
my $gcode = "" ;
foreach my $arc_path ( $path -> detect_arcs ) {
$gcode .= $self -> extrude_path ( $arc_path , $description , 1 );
}
return $gcode ;
}
my $gcode = "" ;
# retract if distance from previous position is greater or equal to the one
2012-08-25 16:30:11 +02:00
# specified by the user
2012-06-28 14:44:54 +02:00
{
2012-08-25 16:30:11 +02:00
my $travel = Slic3r::Line -> new ( $self -> last_pos , $path -> points -> [ 0 ]);
if ( $travel -> length >= scale $self -> extruder -> retract_before_travel ) {
2012-09-23 18:07:44 +02:00
if ( ! $ Slic3r:: Config -> only_retract_when_crossing_perimeters || $path -> role != EXTR_ROLE_FILL || ! first { $_ -> encloses_line ( $travel , scaled_epsilon ) } @ { $self -> layer -> slices }) {
2012-08-25 16:30:11 +02:00
$gcode .= $self -> retract ( travel_to => $path -> points -> [ 0 ]);
}
2012-06-28 14:44:54 +02:00
}
}
# go to first point of extrusion path
$gcode .= $self -> G0 ( $path -> points -> [ 0 ], undef , 0 , "move to first $description point" )
if ! points_coincide ( $self -> last_pos , $path -> points -> [ 0 ]);
# compensate retraction
2012-08-22 18:57:03 +02:00
$gcode .= $self -> unretract if $self -> extruder -> retracted ;
2012-06-28 14:44:54 +02:00
2012-07-03 18:05:31 +02:00
my $area ; # mm^3 of extrudate per mm of tool movement
2012-06-28 14:44:54 +02:00
if ( $path -> role == EXTR_ROLE_BRIDGE ) {
2012-07-03 18:05:31 +02:00
my $s = $path -> flow_spacing || $self -> extruder -> nozzle_diameter ;
2012-06-28 14:44:54 +02:00
$area = ( $s ** 2 ) * PI / 4 ;
} else {
2012-07-03 18:05:31 +02:00
my $s = $path -> flow_spacing || ( $self -> layer ? $self -> layer -> flow -> spacing : $ Slic3r:: flow -> spacing );
2012-10-28 14:22:51 +01:00
my $h = $path -> height // $self -> layer -> height ;
2012-07-03 18:05:31 +02:00
$area = $self -> extruder -> mm3_per_mm ( $s , $h );
2012-06-28 14:44:54 +02:00
}
2012-07-03 18:05:31 +02:00
# calculate extrusion length per distance unit
2012-07-02 17:09:09 +02:00
my $e = $self -> extruder -> e_per_mm3 * $area ;
2012-06-28 14:44:54 +02:00
# extrude arc or line
$self -> speed ( $role_speeds { $path -> role } || die "Unknown role: " . $path -> role );
my $path_length = 0 ;
if ( $path -> isa ( 'Slic3r::ExtrusionPath::Arc' )) {
$path_length = $path -> length ;
$gcode .= $self -> G2_G3 ( $path -> points -> [ - 1 ], $path -> orientation ,
2012-07-03 18:05:31 +02:00
$path -> center , $e * unscale $path_length , $description );
2012-06-28 14:44:54 +02:00
} else {
foreach my $line ( $path -> lines ) {
my $line_length = $line -> length ;
$path_length += $line_length ;
2012-07-03 18:05:31 +02:00
$gcode .= $self -> G1 ( $line -> b , undef , $e * unscale $line_length , $description );
2012-06-28 14:44:54 +02:00
}
}
2012-07-27 21:13:03 +02:00
if ( $ Slic3r:: Config -> cooling ) {
2012-06-28 14:44:54 +02:00
my $path_time = unscale ( $path_length ) / $self -> speeds -> { $self -> last_speed } * 60 ;
if ( $self -> layer -> id == 0 ) {
2012-07-27 21:13:03 +02:00
$path_time = $ Slic3r:: Config -> first_layer_speed =~ /^(\d+(?:\.\d+)?)%$/
2012-06-28 14:44:54 +02:00
? $path_time / ($1/ 100 )
2012-07-27 21:13:03 +02:00
: unscale ( $path_length ) / $ Slic3r:: Config -> first_layer_speed * 60 ;
2012-06-28 14:44:54 +02:00
}
$self -> elapsed_time ( $self -> elapsed_time + $path_time );
}
return $gcode ;
}
sub retract {
my $self = shift ;
my %params = @_ ;
2012-08-22 20:31:03 +02:00
# get the retraction length and abort if none
my ( $length , $restart_extra , $comment ) = $params { toolchange }
? ( $self -> extruder -> retract_length_toolchange , $self -> extruder -> retract_restart_extra_toolchange , "retract for tool change" )
: ( $self -> extruder -> retract_length , $self -> extruder -> retract_restart_extra , "retract" );
2012-08-22 19:11:45 +02:00
2012-08-22 20:31:03 +02:00
# if we already retracted, reduce the required amount of retraction
$length -= $self -> extruder -> retracted ;
return "" unless $length > 0 ;
2012-06-28 14:44:54 +02:00
# prepare moves
$self -> speed ( 'retract' );
2012-08-22 20:31:03 +02:00
my $retract = [ undef , undef , - $length , $comment ];
2012-08-07 21:08:56 +02:00
my $lift = ( $self -> extruder -> retract_lift == 0 || defined $params { move_z })
2012-06-28 14:44:54 +02:00
? undef
2012-08-07 21:08:56 +02:00
: [ undef , $self -> z + $self -> extruder -> retract_lift , 0 , 'lift plate during retraction' ];
2012-06-28 14:44:54 +02:00
my $gcode = "" ;
2012-07-27 21:13:03 +02:00
if (( $ Slic3r:: Config -> g0 || $ Slic3r:: Config -> gcode_flavor eq 'mach3' ) && $params { travel_to }) {
2012-06-28 14:44:54 +02:00
if ( $lift ) {
# combine lift and retract
$lift -> [ 2 ] = $retract -> [ 2 ];
$gcode .= $self -> G0 ( @$lift );
} else {
# combine travel and retract
2012-08-22 20:31:03 +02:00
my $travel = [ $params { travel_to }, undef , $retract -> [ 2 ], "travel and $comment" ];
2012-06-28 14:44:54 +02:00
$gcode .= $self -> G0 ( @$travel );
}
2012-07-27 21:13:03 +02:00
} elsif (( $ Slic3r:: Config -> g0 || $ Slic3r:: Config -> gcode_flavor eq 'mach3' ) && defined $params { move_z }) {
2012-06-28 14:44:54 +02:00
# combine Z change and retraction
2012-08-22 20:31:03 +02:00
my $travel = [ undef , $params { move_z }, $retract -> [ 2 ], "change layer and $comment" ];
2012-06-28 14:44:54 +02:00
$gcode .= $self -> G0 ( @$travel );
} else {
$gcode .= $self -> G1 ( @$retract );
2012-08-07 21:08:56 +02:00
if ( defined $params { move_z } && $self -> extruder -> retract_lift > 0 ) {
my $travel = [ undef , $params { move_z } + $self -> extruder -> retract_lift , 0 , 'move to next layer (' . $self -> layer -> id . ') and lift' ];
2012-06-28 14:44:54 +02:00
$gcode .= $self -> G0 ( @$travel );
2012-08-07 21:08:56 +02:00
$self -> lifted ( $self -> extruder -> retract_lift );
2012-06-28 14:44:54 +02:00
} elsif ( $lift ) {
$gcode .= $self -> G1 ( @$lift );
}
}
2012-08-22 20:31:03 +02:00
$self -> extruder -> retracted ( $self -> extruder -> retracted + $length + $restart_extra );
2012-08-07 21:08:56 +02:00
$self -> lifted ( $self -> extruder -> retract_lift ) if $lift ;
2012-06-28 14:44:54 +02:00
# reset extrusion distance during retracts
# this makes sure we leave sufficient precision in the firmware
2012-07-27 21:13:03 +02:00
$gcode .= $self -> reset_e if $ Slic3r:: Config -> gcode_flavor !~ /^(?:mach3|makerbot)$/ ;
2012-06-28 14:44:54 +02:00
return $gcode ;
}
sub unretract {
my $self = shift ;
2012-08-22 18:57:03 +02:00
2012-06-28 14:44:54 +02:00
my $gcode = "" ;
if ( $self -> lifted ) {
2012-08-07 21:08:56 +02:00
$gcode .= $self -> G0 ( undef , $self -> z - $self -> lifted , 0 , 'restore layer Z' );
2012-06-28 14:44:54 +02:00
$self -> lifted ( 0 );
}
$self -> speed ( 'retract' );
2012-08-22 18:57:03 +02:00
$gcode .= $self -> G0 ( undef , undef , $self -> extruder -> retracted , "compensate retraction" );
$self -> extruder -> retracted ( 0 );
2012-06-28 14:44:54 +02:00
return $gcode ;
}
2012-07-06 19:57:58 +02:00
sub reset_e {
my $self = shift ;
$self -> extrusion_distance ( 0 );
2012-07-27 21:13:03 +02:00
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 ;
2012-07-06 19:57:58 +02:00
}
2012-06-28 14:44:54 +02:00
sub set_acceleration {
my $self = shift ;
my ( $acceleration ) = @_ ;
2012-07-27 21:13:03 +02:00
return "" unless $ Slic3r:: Config -> acceleration ;
2012-06-28 14:44:54 +02:00
return sprintf "M201 E%s%s\n" ,
2012-07-27 21:13:03 +02:00
$acceleration , ( $ Slic3r:: Config -> gcode_comments ? ' ; adjust acceleration' : '' );
2012-06-28 14:44:54 +02:00
}
sub G0 {
my $self = shift ;
2012-07-27 21:13:03 +02:00
return $self -> G1 ( @_ ) if ! ( $ Slic3r:: Config -> g0 || $ Slic3r:: Config -> gcode_flavor eq 'mach3' );
2012-06-28 14:44:54 +02:00
return $self -> _G0_G1 ( "G0" , @_ );
}
sub G1 {
my $self = shift ;
return $self -> _G0_G1 ( "G1" , @_ );
}
sub _G0_G1 {
my $self = shift ;
my ( $gcode , $point , $z , $e , $comment ) = @_ ;
my $dec = $self -> dec ;
if ( $point ) {
$gcode .= sprintf " X%.${dec}f Y%.${dec}f" ,
2012-08-07 21:39:45 +02:00
( $point -> x * & Slic3r:: SCALING_FACTOR ) + $self -> shift_x - $self -> extruder -> extruder_offset -> [ X ],
( $point -> y * & Slic3r:: SCALING_FACTOR ) + $self -> shift_y - $self -> extruder -> extruder_offset -> [ Y ]; #**
2012-06-28 14:44:54 +02:00
$self -> last_pos ( $point );
}
if ( defined $z && $z != $self -> z ) {
$self -> z ( $z );
$gcode .= sprintf " Z%.${dec}f" , $z ;
}
return $self -> _Gx ( $gcode , $e , $comment );
}
sub G2_G3 {
my $self = shift ;
my ( $point , $orientation , $center , $e , $comment ) = @_ ;
my $dec = $self -> dec ;
my $gcode = $orientation eq 'cw' ? "G2" : "G3" ;
$gcode .= sprintf " X%.${dec}f Y%.${dec}f" ,
2012-08-07 21:39:45 +02:00
( $point -> x * & Slic3r:: SCALING_FACTOR ) + $self -> shift_x - $self -> extruder -> extruder_offset -> [ X ],
( $point -> y * & Slic3r:: SCALING_FACTOR ) + $self -> shift_y - $self -> extruder -> extruder_offset -> [ Y ]; #**
2012-06-28 14:44:54 +02:00
# XY distance of the center from the start position
$gcode .= sprintf " I%.${dec}f J%.${dec}f" ,
2012-07-27 21:13:03 +02:00
( $center -> [ X ] - $self -> last_pos -> [ X ]) * & Slic3r:: SCALING_FACTOR ,
( $center -> [ Y ] - $self -> last_pos -> [ Y ]) * & Slic3r:: SCALING_FACTOR ;
2012-06-28 14:44:54 +02:00
$self -> last_pos ( $point );
return $self -> _Gx ( $gcode , $e , $comment );
}
sub _Gx {
my $self = shift ;
my ( $gcode , $e , $comment ) = @_ ;
my $dec = $self -> dec ;
# determine speed
my $speed = ( $e ? $self -> speed : 'travel' );
# output speed if it's different from last one used
# (goal: reduce gcode size)
my $append_bridge_off = 0 ;
if ( $speed ne $self -> last_speed ) {
if ( $speed eq 'bridge' ) {
$gcode = ";_BRIDGE_FAN_START\n$gcode" ;
} elsif ( $self -> last_speed eq 'bridge' ) {
$append_bridge_off = 1 ;
}
# apply the speed reduction for print moves on bottom layer
2012-08-07 21:08:56 +02:00
my $speed_f = $speed eq 'retract'
? ( $self -> extruder -> retract_speed_mm_min )
: $self -> speeds -> { $speed };
2012-08-22 18:57:03 +02:00
if ( $e && $self -> layer && $self -> layer -> id == 0 && $comment !~ /retract/ ) {
2012-07-27 21:13:03 +02:00
$speed_f = $ Slic3r:: Config -> first_layer_speed =~ /^(\d+(?:\.\d+)?)%$/
2012-06-28 14:44:54 +02:00
? ( $speed_f * $1 / 100 )
2012-07-27 21:13:03 +02:00
: $ Slic3r:: Config -> first_layer_speed * 60 ;
2012-06-28 14:44:54 +02:00
}
$gcode .= sprintf " F%.${dec}f" , $speed_f ;
$self -> last_speed ( $speed );
}
# output extrusion distance
2012-07-27 21:13:03 +02:00
if ( $e && $ Slic3r:: Config -> extrusion_axis ) {
$self -> extrusion_distance ( 0 ) if $ Slic3r:: Config -> use_relative_e_distances ;
2012-06-28 14:44:54 +02:00
$self -> extrusion_distance ( $self -> extrusion_distance + $e );
$self -> total_extrusion_length ( $self -> total_extrusion_length + $e );
2012-07-27 21:13:03 +02:00
$gcode .= sprintf " %s%.5f" , $ Slic3r:: Config -> extrusion_axis , $self -> extrusion_distance ;
2012-06-28 14:44:54 +02:00
}
2012-07-27 21:13:03 +02:00
$gcode .= sprintf " ; %s" , $comment if $comment && $ Slic3r:: Config -> gcode_comments ;
2012-06-28 14:44:54 +02:00
if ( $append_bridge_off ) {
$gcode .= "\n;_BRIDGE_FAN_END" ;
}
return "$gcode\n" ;
}
2012-09-23 02:40:25 +02:00
sub set_extruder {
2012-06-28 14:44:54 +02:00
my $self = shift ;
2012-09-23 02:40:25 +02:00
my ( $extruder ) = @_ ;
2012-06-28 14:44:54 +02:00
2012-09-23 02:40:25 +02:00
# return nothing if this extruder was already selected
2012-10-25 18:49:59 +02:00
return "" if ( defined $self -> extruder ) && ( $self -> extruder -> id == $extruder -> id );
2012-08-22 19:20:34 +02:00
2012-08-22 19:47:59 +02:00
# if we are running a single-extruder setup, just set the extruder and return nothing
2012-09-23 02:40:25 +02:00
if ( ! $self -> multiple_extruders ) {
$self -> extruder ( $extruder );
2012-08-22 19:47:59 +02:00
return "" ;
}
2012-09-23 02:40:25 +02:00
# trigger retraction on the current extruder (if any)
2012-08-22 19:47:59 +02:00
my $gcode = "" ;
2012-09-23 02:40:25 +02:00
$gcode .= $self -> retract ( toolchange => 1 ) if defined $self -> extruder ;
2012-08-22 19:47:59 +02:00
2012-09-23 02:40:25 +02:00
# set the new extruder
$self -> extruder ( $extruder );
2012-10-01 18:22:35 +02:00
$gcode .= sprintf "T%d%s\n" , $extruder -> id , ( $ Slic3r:: Config -> gcode_comments ? ' ; change extruder' : '' );
2012-08-22 19:47:59 +02:00
$gcode .= $self -> reset_e ;
return $gcode ;
2012-06-28 14:44:54 +02:00
}
sub set_fan {
my $self = shift ;
my ( $speed , $dont_save ) = @_ ;
if ( $self -> last_fan_speed != $speed || $dont_save ) {
$self -> last_fan_speed ( $speed ) if ! $dont_save ;
if ( $speed == 0 ) {
2012-07-27 21:13:03 +02:00
return sprintf "M107%s\n" , ( $ Slic3r:: Config -> gcode_comments ? ' ; disable fan' : '' );
2012-06-28 14:44:54 +02:00
} else {
2012-07-27 21:13:03 +02:00
return sprintf "M106 %s%d%s\n" , ( $ Slic3r:: Config -> gcode_flavor eq 'mach3' ? 'P' : 'S' ),
( 255 * $speed / 100 ), ( $ Slic3r:: Config -> gcode_comments ? ' ; enable fan' : '' );
2012-06-28 14:44:54 +02:00
}
}
return "" ;
}
sub set_temperature {
my $self = shift ;
2012-06-28 16:22:11 +02:00
my ( $temperature , $wait , $tool ) = @_ ;
2012-06-28 14:44:54 +02:00
2012-07-27 21:13:03 +02:00
return "" if $wait && $ Slic3r:: Config -> gcode_flavor eq 'makerbot' ;
2012-06-28 14:44:54 +02:00
2012-08-30 23:13:28 +02:00
my ( $code , $comment ) = ( $wait && $ Slic3r:: Config -> gcode_flavor ne 'teacup' )
2012-06-28 14:44:54 +02:00
? ( 'M109' , 'wait for temperature to be reached' )
: ( 'M104' , 'set temperature' );
2012-08-30 23:13:28 +02:00
my $gcode = sprintf "$code %s%d %s; $comment\n" ,
2012-07-27 21:13:03 +02:00
( $ Slic3r:: Config -> gcode_flavor eq 'mach3' ? 'P' : 'S' ), $temperature ,
2012-10-21 21:44:06 +02:00
( defined $tool && $self -> multiple_extruders ) ? "T$tool " : "" ;
2012-08-30 23:13:28 +02:00
$gcode .= "M116 ; wait for temperature to be reached\n"
if $ Slic3r:: Config -> gcode_flavor eq 'teacup' && $wait ;
return $gcode ;
2012-06-28 14:44:54 +02:00
}
sub set_bed_temperature {
my $self = shift ;
my ( $temperature , $wait ) = @_ ;
2012-08-30 23:13:28 +02:00
my ( $code , $comment ) = ( $wait && $ Slic3r:: Config -> gcode_flavor ne 'teacup' )
2012-07-27 21:13:03 +02:00
? (( $ Slic3r:: Config -> gcode_flavor eq 'makerbot' ? 'M109'
2012-07-10 19:31:09 +02:00
: 'M190' ), 'wait for bed temperature to be reached' )
2012-06-28 14:44:54 +02:00
: ( 'M140' , 'set bed temperature' );
2012-08-30 23:13:28 +02:00
my $gcode = sprintf "$code %s%d ; $comment\n" ,
2012-07-27 21:13:03 +02:00
( $ Slic3r:: Config -> gcode_flavor eq 'mach3' ? 'P' : 'S' ), $temperature ;
2012-08-30 23:13:28 +02:00
$gcode .= "M116 ; wait for bed temperature to be reached\n"
if $ Slic3r:: Config -> gcode_flavor eq 'teacup' && $wait ;
return $gcode ;
2012-06-28 14:44:54 +02:00
}
1 ;