mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-08-06 13:34:05 -06:00
Make tests pass
This commit is contained in:
parent
a2cbb261cb
commit
07b9b12475
16 changed files with 159 additions and 82 deletions
|
@ -40,8 +40,7 @@ sub new_from_config {
|
|||
use_relative_e_distances => $config->use_relative_e_distances,
|
||||
);
|
||||
foreach my $opt_key (@{&OPTIONS}) {
|
||||
my $value = $config->get($opt_key);
|
||||
$conf{$opt_key} = $value->[$extruder_id] // $value->[0];
|
||||
$conf{$opt_key} = $config->get_at($opt_key, $extruder_id);
|
||||
}
|
||||
return $class->new(%conf);
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ sub mm3_per_mm {
|
|||
my $s = $self->spacing;
|
||||
|
||||
if ($self->bridge) {
|
||||
return ($s**2) * PI/4;
|
||||
return ($w**2) * PI/4;
|
||||
} elsif ($w >= ($self->nozzle_diameter + $h)) {
|
||||
# rectangle with semicircles at the ends
|
||||
return $w * $h + ($h**2) / 4 * (PI - 4);
|
||||
|
@ -140,7 +140,7 @@ sub _spacing {
|
|||
if ($bridge_flow_ratio > 0) {
|
||||
return $width + BRIDGE_EXTRA_SPACING;
|
||||
}
|
||||
|
||||
use XXX; ZZZ "here" if !defined $nozzle_diameter;
|
||||
my $min_flow_spacing;
|
||||
if ($width >= ($nozzle_diameter + $layer_height)) {
|
||||
# rectangle with semicircles at the ends
|
||||
|
|
|
@ -12,7 +12,7 @@ has 'print_config' => (is => 'ro', default => sub { Slic3r::Config::Print-
|
|||
has 'extra_variables' => (is => 'rw', default => sub {{}});
|
||||
has 'standby_points' => (is => 'rw');
|
||||
has 'enable_loop_clipping' => (is => 'rw', default => sub {1});
|
||||
has 'enable_wipe' => (is => 'lazy'); # at least one extruder has wipe enabled
|
||||
has 'enable_wipe' => (is => 'rw', default => sub {0}); # at least one extruder has wipe enabled
|
||||
has 'layer_count' => (is => 'ro', required => 1 );
|
||||
has 'layer' => (is => 'rw');
|
||||
has 'region' => (is => 'rw');
|
||||
|
@ -25,14 +25,13 @@ has 'z' => (is => 'rw');
|
|||
has 'speed' => (is => 'rw');
|
||||
has '_extrusion_axis' => (is => 'rw');
|
||||
has '_retract_lift' => (is => 'rw');
|
||||
has 'extruders' => (is => 'ro', default => sub {[]});
|
||||
|
||||
has 'extruders' => (is => 'ro', default => sub {{}});
|
||||
has 'extruder' => (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});
|
||||
has 'straight_once' => (is => 'rw', default => sub {1});
|
||||
has 'extruder' => (is => 'rw');
|
||||
has 'elapsed_time' => (is => 'rw', default => sub {0} ); # seconds
|
||||
has 'lifted' => (is => 'rw', default => sub {0} );
|
||||
has 'last_pos' => (is => 'rw', default => sub { Slic3r::Point->new(0,0) } );
|
||||
|
@ -52,7 +51,8 @@ sub set_extruders {
|
|||
my ($self, $extruder_ids) = @_;
|
||||
|
||||
foreach my $i (@$extruder_ids) {
|
||||
$self->extruders->[$i] = Slic3r::Extruder->new_from_config($self->print_config, $i);
|
||||
$self->extruders->{$i} = my $e = Slic3r::Extruder->new_from_config($self->print_config, $i);
|
||||
$self->enable_wipe(1) if $e->wipe;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,12 +82,7 @@ my %role_speeds = (
|
|||
|
||||
sub multiple_extruders {
|
||||
my $self = shift;
|
||||
return @{$self->extruders} > 1;
|
||||
}
|
||||
|
||||
sub _build_enable_wipe {
|
||||
my $self = shift;
|
||||
return (first { $_->wipe } @{$self->extruders}) ? 1 : 0;
|
||||
return (keys %{$self->extruders}) > 1;
|
||||
}
|
||||
|
||||
sub set_shift {
|
||||
|
@ -248,14 +243,12 @@ sub extrude_loop {
|
|||
@{$extrusion_path->subtract_expolygons($self->_layer_overhangs)};
|
||||
|
||||
# get overhang paths by intersecting overhangs with the loop
|
||||
push @paths,
|
||||
map {
|
||||
$_->role(EXTR_ROLE_OVERHANG_PERIMETER);
|
||||
$_->mm3_per_mm($self->region->flow(FLOW_ROLE_PERIMETER, undef, 1)->mm3_per_mm(undef));
|
||||
$_
|
||||
}
|
||||
map $_->clone,
|
||||
@{$extrusion_path->intersect_expolygons($self->_layer_overhangs)};
|
||||
foreach my $path (@{$extrusion_path->intersect_expolygons($self->_layer_overhangs)}) {
|
||||
$path = $path->clone;
|
||||
$path->role(EXTR_ROLE_OVERHANG_PERIMETER);
|
||||
$path->mm3_per_mm($self->region->flow(FLOW_ROLE_PERIMETER, undef, 1)->mm3_per_mm(undef));
|
||||
push @paths, $path;
|
||||
}
|
||||
|
||||
# reapply the nearest point search for starting point
|
||||
# (clone because the collection gets DESTROY'ed)
|
||||
|
@ -644,7 +637,7 @@ sub set_extruder {
|
|||
|
||||
# if we are running a single-extruder setup, just set the extruder and return nothing
|
||||
if (!$self->multiple_extruders) {
|
||||
$self->extruder($self->extruders->[$extruder_id]);
|
||||
$self->extruder($self->extruders->{$extruder_id});
|
||||
return "";
|
||||
}
|
||||
|
||||
|
@ -673,7 +666,7 @@ sub set_extruder {
|
|||
}
|
||||
|
||||
# set the new extruder
|
||||
$self->extruder($self->extruders->[$extruder_id]);
|
||||
$self->extruder($self->extruders->{$extruder_id});
|
||||
$gcode .= sprintf "%s%d%s\n",
|
||||
($self->print_config->gcode_flavor eq 'makerware'
|
||||
? 'M135 T'
|
||||
|
|
|
@ -4,8 +4,8 @@ use Moo;
|
|||
use List::Util qw(first);
|
||||
use Slic3r::Geometry qw(X Y unscale);
|
||||
|
||||
has 'print' => (is => 'ro', required => 1, handles => [qw(extruders)]);
|
||||
has 'gcodegen' => (is => 'ro', required => 1);
|
||||
has 'print' => (is => 'ro', required => 1);
|
||||
has 'gcodegen' => (is => 'ro', required => 1, handles => [qw(extruders)]);
|
||||
has 'shift' => (is => 'ro', default => sub { [0,0] });
|
||||
|
||||
has 'spiralvase' => (is => 'lazy');
|
||||
|
@ -57,9 +57,10 @@ sub process_layer {
|
|||
$self->gcodegen->enable_loop_clipping(!$spiralvase);
|
||||
|
||||
if (!$self->second_layer_things_done && $layer->id == 1) {
|
||||
for my $t (grep $self->extruders->[$_], 0 .. $#{$self->print->config->temperature}) {
|
||||
$gcode .= $self->gcodegen->set_temperature($self->extruders->[$t]->temperature, 0, $t)
|
||||
if $self->print->extruders->[$t]->temperature && $self->extruders->[$t]->temperature != $self->extruders->[$t]->first_layer_temperature;
|
||||
for my $extruder_id (sort keys %{$self->extruders}) {
|
||||
my $extruder = $self->extruders->{$extruder_id};
|
||||
$gcode .= $self->gcodegen->set_temperature($extruder->temperature, 0, $extruder->id)
|
||||
if $extruder->temperature && $extruder->temperature != $extruder->first_layer_temperature;
|
||||
}
|
||||
$gcode .= $self->gcodegen->set_bed_temperature($self->print->config->bed_temperature)
|
||||
if $self->print->config->bed_temperature && $self->print->config->bed_temperature != $self->print->config->first_layer_bed_temperature;
|
||||
|
@ -76,7 +77,8 @@ sub process_layer {
|
|||
if (((values %{$self->skirt_done}) < $self->print->config->skirt_height || $self->print->config->skirt_height == -1)
|
||||
&& !$self->skirt_done->{$layer->print_z}) {
|
||||
$self->gcodegen->set_shift(@{$self->shift});
|
||||
$gcode .= $self->gcodegen->set_extruder($self->extruders->[0]);
|
||||
my @extruder_ids = sort keys %{$self->extruders};
|
||||
$gcode .= $self->gcodegen->set_extruder($extruder_ids[0]);
|
||||
# skip skirt if we have a large brim
|
||||
if ($layer->id < $self->print->config->skirt_height || $self->print->config->skirt_height == -1) {
|
||||
# distribute skirt loops across all extruders
|
||||
|
@ -85,7 +87,7 @@ sub process_layer {
|
|||
# when printing layers > 0 ignore 'min_skirt_length' and
|
||||
# just use the 'skirts' setting; also just use the current extruder
|
||||
last if ($layer->id > 0) && ($i >= $self->print->config->skirts);
|
||||
$gcode .= $self->gcodegen->set_extruder(($i/@{$self->extruders}) % @{$self->extruders})
|
||||
$gcode .= $self->gcodegen->set_extruder(($i/@extruder_ids) % @extruder_ids)
|
||||
if $layer->id == 0;
|
||||
$gcode .= $self->gcodegen->extrude_loop($skirt_loops[$i], 'skirt');
|
||||
}
|
||||
|
|
|
@ -709,7 +709,7 @@ sub make_brim {
|
|||
my $flow = Slic3r::Flow->new_from_width(
|
||||
width => ($self->config->first_layer_extrusion_width || $self->regions->[0]->config->perimeter_extrusion_width),
|
||||
role => FLOW_ROLE_PERIMETER,
|
||||
nozzle_diameter => $self->config->nozzle_diameter->[ $self->objects->[0]->config->support_material_extruder-1 ],
|
||||
nozzle_diameter => $self->config->get_at('nozzle_diameter', $self->objects->[0]->config->support_material_extruder-1),
|
||||
layer_height => $first_layer_height,
|
||||
bridge_flow_ratio => 0,
|
||||
);
|
||||
|
@ -807,7 +807,6 @@ sub write_gcode {
|
|||
layer_count => $self->layer_count,
|
||||
);
|
||||
$gcodegen->set_extruders($self->extruders);
|
||||
$gcodegen->set_extruder($self->extruders->[0]);
|
||||
|
||||
print $fh "G21 ; set units to millimeters\n" if $self->config->gcode_flavor ne 'makerware';
|
||||
print $fh $gcodegen->set_fan(0, 1) if $self->config->cooling && $self->config->disable_fan_first_layers;
|
||||
|
@ -822,8 +821,8 @@ sub write_gcode {
|
|||
my ($wait) = @_;
|
||||
|
||||
return if $self->config->start_gcode =~ /M(?:109|104)/i;
|
||||
for my $t (0 .. $#{$self->extruders}) {
|
||||
my $temp = $self->config->first_layer_temperature->[$t] // $self->config->first_layer_temperature->[0];
|
||||
for my $t (@{$self->extruders}) {
|
||||
my $temp = $self->config->get_at('first_layer_temperature', $t);
|
||||
$temp += $self->config->standby_temperature_delta if $self->config->ooze_prevention;
|
||||
printf $fh $gcodegen->set_temperature($temp, $wait, $t) if $temp > 0;
|
||||
}
|
||||
|
@ -873,9 +872,9 @@ sub write_gcode {
|
|||
if (@skirt_points) {
|
||||
my $outer_skirt = convex_hull(\@skirt_points);
|
||||
my @skirts = ();
|
||||
foreach my $extruder (@{$self->extruders}) {
|
||||
foreach my $extruder_id (@{$self->extruders}) {
|
||||
push @skirts, my $s = $outer_skirt->clone;
|
||||
$s->translate(map scale($_), @{$extruder->extruder_offset});
|
||||
$s->translate(map scale($_), @{$self->config->get_at('extruder_offset', $extruder_id)});
|
||||
}
|
||||
my $convex_hull = convex_hull([ map @$_, @skirts ]);
|
||||
$gcodegen->standby_points([ map $_->clone, map @$_, map $_->subdivide(scale 10), @{offset([$convex_hull], scale 3)} ]);
|
||||
|
@ -888,6 +887,9 @@ sub write_gcode {
|
|||
gcodegen => $gcodegen,
|
||||
);
|
||||
|
||||
# set initial extruder only after custom start G-code
|
||||
print $fh $gcodegen->set_extruder($self->extruders->[0]);
|
||||
|
||||
# do all objects for each layer
|
||||
if ($self->config->complete_objects) {
|
||||
# print objects from the smallest to the tallest to avoid collisions
|
||||
|
@ -975,7 +977,7 @@ sub write_gcode {
|
|||
$self->total_used_filament(0);
|
||||
$self->total_extruded_volume(0);
|
||||
foreach my $extruder_id (@{$self->extruders}) {
|
||||
my $extruder = $gcodegen->extruders->[$extruder_id];
|
||||
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);
|
||||
|
||||
|
|
|
@ -758,7 +758,7 @@ sub combine_infill {
|
|||
my $every = $region->config->infill_every_layers;
|
||||
|
||||
# limit the number of combined layers to the maximum height allowed by this regions' nozzle
|
||||
my $nozzle_diameter = $self->print->config->nozzle_diameter->[ $region->config->infill_extruder-1 ];
|
||||
my $nozzle_diameter = $self->print->config->get_at('nozzle_diameter', $region->config->infill_extruder-1);
|
||||
|
||||
# define the combinations
|
||||
my @combine = (); # layer_id => thickness in layers
|
||||
|
@ -810,12 +810,12 @@ sub combine_infill {
|
|||
# so let's remove those areas from all layers
|
||||
|
||||
my @intersection_with_clearance = map @{$_->offset(
|
||||
$layerms[-1]->solid_infill_flow->scaled_width / 2
|
||||
+ $layerms[-1]->perimeter_flow->scaled_width / 2
|
||||
$layerms[-1]->flow(FLOW_ROLE_SOLID_INFILL)->scaled_width / 2
|
||||
+ $layerms[-1]->flow(FLOW_ROLE_PERIMETER)->scaled_width / 2
|
||||
# Because fill areas for rectilinear and honeycomb are grown
|
||||
# later to overlap perimeters, we need to counteract that too.
|
||||
+ (($type == S_TYPE_INTERNALSOLID || $region->config->fill_pattern =~ /(rectilinear|honeycomb)/)
|
||||
? $layerms[-1]->solid_infill_flow->scaled_width * &Slic3r::INFILL_OVERLAP_OVER_SPACING
|
||||
? $layerms[-1]->flow(FLOW_ROLE_SOLID_INFILL)->scaled_width * &Slic3r::INFILL_OVERLAP_OVER_SPACING
|
||||
: 0)
|
||||
)}, @$intersection;
|
||||
|
||||
|
@ -866,7 +866,8 @@ sub generate_support_material {
|
|||
my $first_layer_flow = Slic3r::Flow->new_from_width(
|
||||
width => ($self->config->first_layer_extrusion_width || $self->config->support_material_extrusion_width),
|
||||
role => FLOW_ROLE_SUPPORT_MATERIAL,
|
||||
nozzle_diameter => $self->print->config->nozzle_diameter->[ $self->config->support_material_extruder-1 ],
|
||||
nozzle_diameter => $self->print->config->nozzle_diameter->[ $self->config->support_material_extruder-1 ]
|
||||
// $self->print->config->nozzle_diameter->[0],
|
||||
layer_height => $self->config->get_abs_value('first_layer_height'),
|
||||
bridge_flow_ratio => 0,
|
||||
);
|
||||
|
@ -903,7 +904,7 @@ sub support_material_flow {
|
|||
return Slic3r::Flow->new_from_width(
|
||||
width => $self->config->support_material_extrusion_width,
|
||||
role => $role,
|
||||
nozzle_diameter => $self->print->config->nozzle_diameter->[$extruder-1],
|
||||
nozzle_diameter => $self->print->config->nozzle_diameter->[$extruder-1] // $self->print->config->nozzle_diameter->[0],
|
||||
layer_height => $self->config->layer_height,
|
||||
bridge_flow_ratio => 0,
|
||||
);
|
||||
|
|
|
@ -46,7 +46,7 @@ sub flow {
|
|||
} else {
|
||||
die "Unknown role $role";
|
||||
}
|
||||
my $nozzle_diameter = $self->print->config->nozzle_diameter->[$extruder-1];
|
||||
my $nozzle_diameter = $self->print->config->get_at('nozzle_diameter', $extruder-1);
|
||||
|
||||
return Slic3r::Flow->new_from_width(
|
||||
width => $config_width,
|
||||
|
|
|
@ -174,7 +174,7 @@ sub contact_area {
|
|||
# now apply the contact areas to the layer were they need to be made
|
||||
{
|
||||
# get the average nozzle diameter used on this layer
|
||||
my @nozzle_diameters = map $self->print_config->nozzle_diameter->[$_],
|
||||
my @nozzle_diameters = map $self->print_config->get_at('nozzle_diameter', $_),
|
||||
map { $_->config->perimeter_extruder-1, $_->config->infill_extruder-1 }
|
||||
@{$layer->regions};
|
||||
my $nozzle_diameter = sum(@nozzle_diameters)/@nozzle_diameters;
|
||||
|
@ -246,7 +246,7 @@ sub support_layers_z {
|
|||
# determine layer height for any non-contact layer
|
||||
# we use max() to prevent many ultra-thin layers to be inserted in case
|
||||
# layer_height > nozzle_diameter * 0.75
|
||||
my $nozzle_diameter = $self->print_config->nozzle_diameter->[$self->object_config->support_material_extruder-1];
|
||||
my $nozzle_diameter = $self->print_config->get_at('nozzle_diameter', $self->object_config->support_material_extruder-1);
|
||||
my $support_material_height = max($max_object_layer_height, $nozzle_diameter * 0.75);
|
||||
|
||||
my @z = sort { $a <=> $b } @$contact_z, @$top_z, (map $_ + $nozzle_diameter, @$top_z);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue