<commit_before>package Slic3r::Extruder;
use Moo;

use Slic3r::Geometry qw(scale unscale);

has 'layer'              => (is => 'rw');
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');

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 'retracted'          => (is => 'rw', default => sub {1} );  # this spits out some plastic at start
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 {{
        travel          => 60 * $Slic3r::travel_speed,
        perimeter       => 60 * $Slic3r::perimeter_speed,
        small_perimeter => 60 * $Slic3r::small_perimeter_speed,
        infill          => 60 * $Slic3r::infill_speed,
        solid_infill    => 60 * $Slic3r::solid_infill_speed,
        bridge          => 60 * $Slic3r::bridge_speed,
        retract         => 60 * $Slic3r::retract_speed,
    }},
);

use Slic3r::Geometry qw(points_coincide PI X Y);

sub change_layer {
    my $self = shift;
    my ($layer) = @_;
    
    $self->layer($layer);
    my $z = $Slic3r::z_offset + $layer->print_z * $Slic3r::scaling_factor;
    
    my $gcode = "";
    
    $gcode .= $self->retract(move_z => $z);
    $gcode .= $self->G0(undef, $z, 0, 'move to next layer (' . $layer->id . ')')
        if $self->z != $z;
    
    $gcode .= Slic3r::Config->replace_options($Slic3r::layer_gcode) . "\n"
        if $Slic3r::layer_gcode;
    
    return $gcode;
}

sub extrude {
    my $self = shift;
    
    return $_[0]->isa('Slic3r::ExtrusionLoop')
        ? $self->extrude_loop(@_)
        : $self->extrude_path(@_);
}

sub extrude_loop {
    my $self = shift;
    my ($loop, $description) = @_;
    
    # extrude all loops ccw
    $loop->polygon->make_counter_clockwise;
    
    # find the point of the loop that is closest to the current extruder position
    my $start_at = $loop->nearest_point_to($self->last_pos);
    
    # split the loop at the starting point and make a path
    my $extrusion_path = $loop->split_at($start_at);
    
    # 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 $Slic3r::flow_width * 0.15);
    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) = @_;
    
    $path->merge_continuous_lines;
    
    # detect arcs
    if ($Slic3r::gcode_arcs && !$recursive) {
        my $gcode = "";
        $gcode .= $self->extrude_path($_, $description, 1) for $path->detect_arcs;
        return $gcode;
    }
    
    my $gcode = "";
    
    # retract if distance from previous position is greater or equal to the one
    # specified by the user *and* to the maximum distance between infill lines
    {
        my $distance_from_last_pos = $self->last_pos->distance_to($path->points->[0]) * $Slic3r::scaling_factor;
        my $distance_threshold = $Slic3r::retract_before_travel;
        $distance_threshold = 2 * $Slic3r::flow_width / $Slic3r::fill_density * sqrt(2)
            if $Slic3r::fill_density > 0 && $description =~ /fill/;
    
        if ($distance_from_last_pos >= $distance_threshold) {
            $gcode .= $self->retract(travel_to => $path->points->[0]);
        }
    }
    
    # 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
    $gcode .= $self->unretract if $self->retracted;
    
    # calculate extrusion length per distance unit
    my $s = $path->flow_spacing
        || ($path->role eq 'support-material'
            ? ($Slic3r::flow_spacing * 1.5)
            : $Slic3r::flow_spacing);
    my $h = $path->depth_layers * $self->layer->height;
    my $w = ($s - $Slic3r::min_flow_spacing * $Slic3r::overlap_factor) / (1 - $Slic3r::overlap_factor);
    
    my $area;
    if ($path->role eq 'bridge') {
        $area = ($s**2) * PI/4;
    } elsif ($w >= ($Slic3r::nozzle_diameter + $h)) {
        # rectangle with semicircles at the ends
        $area = $w * $h + ($h**2) / 4 * (PI - 4);
    } else {<commit_msg>Restore 100% flow for support material<commit_after>package Slic3r::Extruder;
use Moo;

use Slic3r::Geometry qw(scale unscale);

has 'layer'              => (is => 'rw');
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');

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 'retracted'          => (is => 'rw', default => sub {1} );  # this spits out some plastic at start
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 {{
        travel          => 60 * $Slic3r::travel_speed,
        perimeter       => 60 * $Slic3r::perimeter_speed,
        small_perimeter => 60 * $Slic3r::small_perimeter_speed,
        infill          => 60 * $Slic3r::infill_speed,
        solid_infill    => 60 * $Slic3r::solid_infill_speed,
        bridge          => 60 * $Slic3r::bridge_speed,
        retract         => 60 * $Slic3r::retract_speed,
    }},
);

use Slic3r::Geometry qw(points_coincide PI X Y);

sub change_layer {
    my $self = shift;
    my ($layer) = @_;
    
    $self->layer($layer);
    my $z = $Slic3r::z_offset + $layer->print_z * $Slic3r::scaling_factor;
    
    my $gcode = "";
    
    $gcode .= $self->retract(move_z => $z);
    $gcode .= $self->G0(undef, $z, 0, 'move to next layer (' . $layer->id . ')')
        if $self->z != $z;
    
    $gcode .= Slic3r::Config->replace_options($Slic3r::layer_gcode) . "\n"
        if $Slic3r::layer_gcode;
    
    return $gcode;
}

sub extrude {
    my $self = shift;
    
    return $_[0]->isa('Slic3r::ExtrusionLoop')
        ? $self->extrude_loop(@_)
        : $self->extrude_path(@_);
}

sub extrude_loop {
    my $self = shift;
    my ($loop, $description) = @_;
    
    # extrude all loops ccw
    $loop->polygon->make_counter_clockwise;
    
    # find the point of the loop that is closest to the current extruder position
    my $start_at = $loop->nearest_point_to($self->last_pos);
    
    # split the loop at the starting point and make a path
    my $extrusion_path = $loop->split_at($start_at);
    
    # 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 $Slic3r::flow_width * 0.15);
    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) = @_;
    
    $path->merge_continuous_lines;
    
    # detect arcs
    if ($Slic3r::gcode_arcs && !$recursive) {
        my $gcode = "";
        $gcode .= $self->extrude_path($_, $description, 1) for $path->detect_arcs;
        return $gcode;
    }
    
    my $gcode = "";
    
    # retract if distance from previous position is greater or equal to the one
    # specified by the user *and* to the maximum distance between infill lines
    {
        my $distance_from_last_pos = $self->last_pos->distance_to($path->points->[0]) * $Slic3r::scaling_factor;
        my $distance_threshold = $Slic3r::retract_before_travel;
        $distance_threshold = 2 * $Slic3r::flow_width / $Slic3r::fill_density * sqrt(2)
            if $Slic3r::fill_density > 0 && $description =~ /fill/;
    
        if ($distance_from_last_pos >= $distance_threshold) {
            $gcode .= $self->retract(travel_to => $path->points->[0]);
        }
    }
    
    # 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
    $gcode .= $self->unretract if $self->retracted;
    
    # calculate extrusion length per distance unit
    my $s = $path->flow_spacing || $Slic3r::flow_spacing;
    my $h = $path->depth_layers * $self->layer->height;
    my $w = ($s - $Slic3r::min_flow_spacing * $Slic3r::overlap_factor) / (1 - $Slic3r::overlap_factor);
    
    my $area;
    if ($path->role eq 'bridge') {
        $area = ($s**2) * PI/4;
    } elsif ($w >= ($Slic3r::nozzle_diameter + $h)) {
        # rectangle with semicircles at the ends
        $area = $w * $h + ($h**2) / 4 * (PI - 4);
    } else {
{'fraction_non_alphanumeric': 0.16564355439267384, 'fraction_numerical': 0.016101439066116534, 'mean_word_length': 2.535396655994308, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 198, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1166908', 'n_tokens_mistral': 3563, 'n_tokens_neox': 3467, 'n_words': 872}