1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
use Test::More;
use strict;
use warnings;
BEGIN {
use FindBin;
use lib "$FindBin::Bin/../lib";
use local::lib "$FindBin::Bin/../local-lib";
}
use List::Util qw(first);
use Slic3r;
use Slic3r::Surface ':types';
use Slic3r::Test;
plan tests => 8;
{
my $test = sub {
my ($config) = @_;
my $print = Slic3r::Test::init_print('20mm_cube', config => $config);
ok my $gcode = Slic3r::Test::gcode($print), "infill_every_layers does not crash";
my $tool = undef;
my %layers = (); # layer_z => 1
my %layer_infill = (); # layer_z => has_infill
Slic3r::GCode::Reader->new->parse($gcode, sub {
my ($self, $cmd, $args, $info) = @_;
if ($cmd =~ /^T(\d+)/) {
$tool = $1;
} elsif ($cmd eq 'G1' && $info->{extruding} && $info->{dist_XY} > 0 && $tool != $config->support_material_extruder-1) {
$layer_infill{$self->Z} //= 0;
if ($tool == $config->infill_extruder-1) {
$layer_infill{$self->Z} = 1;
}
}
$layers{$args->{Z}} = 1 if $cmd eq 'G1' && $info->{dist_Z} > 0;
});
my $layers_with_perimeters = scalar(keys %layer_infill);
my $layers_with_infill = grep $_ > 0, values %layer_infill;
is scalar(keys %layers), $layers_with_perimeters+$config->raft_layers, 'expected number of layers';
# first infill layer is never combined, so we don't consider it
$layers_with_infill--;
$layers_with_perimeters--;
# we expect that infill is generated for half the number of combined layers
# plus for each single layer that was not combined (remainder)
is $layers_with_infill,
int($layers_with_perimeters/$config->infill_every_layers) + ($layers_with_perimeters % $config->infill_every_layers),
'infill is only present in correct number of layers';
};
my $config = Slic3r::Config::new_from_defaults;
$config->set('layer_height', 0.2);
$config->set('first_layer_height', 0.2);
$config->set('nozzle_diameter', [0.5]);
$config->set('infill_every_layers', 2);
$config->set('perimeter_extruder', 1);
$config->set('infill_extruder', 2);
$config->set('support_material_extruder', 3);
$config->set('support_material_interface_extruder', 3);
$config->set('top_solid_layers', 0);
$config->set('bottom_solid_layers', 0);
$test->($config);
$config->set('skirts', 0); # prevent usage of perimeter_extruder in raft layers
$config->set('raft_layers', 5);
$test->($config);
}
{
my $config = Slic3r::Config::new_from_defaults;
$config->set('layer_height', 0.2);
$config->set('first_layer_height', 0.2);
$config->set('nozzle_diameter', [0.5]);
$config->set('infill_every_layers', 2);
my $print = Slic3r::Test::init_print('20mm_cube', config => $config);
$print->process;
ok defined(first { @{$_->get_region(0)->fill_surfaces->filter_by_type(S_TYPE_INTERNALVOID)} > 0 }
@{$print->print->get_object(0)->layers}),
'infill combination produces internal void surfaces';
# we disable combination after infill has been generated
$config->set('infill_every_layers', 1);
$print->apply_config($config);
$print->process;
ok !(defined first { @{$_->get_region(0)->fill_surfaces} == 0 }
@{$print->print->get_object(0)->layers}),
'infill combination is idempotent';
}
# the following needs to be adapted to the new API
if (0) {
my $config = Slic3r::Config::new_from_defaults;
$config->set('skirts', 0);
$config->set('solid_layers', 0);
$config->set('bottom_solid_layers', 0);
$config->set('top_solid_layers', 0);
$config->set('infill_every_layers', 6);
$config->set('layer_height', 0.06);
$config->set('perimeters', 1);
my $test = sub {
my ($shift) = @_;
my $self = Slic3r::Test::init_print('20mm_cube', config => $config);
$shift /= &Slic3r::SCALING_FACTOR;
my $scale = 4; # make room for fat infill lines with low layer height
# Put a slope on the box's sides by shifting x and y coords by $tilt * (z / boxheight).
# The test here is to put such a slight slope on the walls that it should
# not trigger any extra fill on fill layers that should be empty when
# combine infill is enabled.
$_->[0] += $shift * ($_->[2] / (20 / &Slic3r::SCALING_FACTOR)) for @{$self->objects->[0]->meshes->[0]->vertices};
$_->[1] += $shift * ($_->[2] / (20 / &Slic3r::SCALING_FACTOR)) for @{$self->objects->[0]->meshes->[0]->vertices};
$_ = [$_->[0]*$scale, $_->[1]*$scale, $_->[2]] for @{$self->objects->[0]->meshes->[0]->vertices};
# copy of Print::export_gcode() up to the point
# after fill surfaces are combined
$_->slice for @{$self->objects};
$_->make_perimeters for @{$self->objects};
$_->detect_surfaces_type for @{$self->objects};
$_->prepare_fill_surfaces for map @{$_->regions}, map @{$_->layers}, @{$self->objects};
$_->process_external_surfaces for map @{$_->regions}, map @{$_->layers}, @{$self->objects};
$_->discover_horizontal_shells for @{$self->objects};
$_->combine_infill for @{$self->objects};
# Only layers with id % 6 == 0 should have fill.
my $spurious_infill = 0;
foreach my $layer (map @{$_->layers}, @{$self->objects}) {
++$spurious_infill if ($layer->id % 6 && grep @{$_->fill_surfaces} > 0, @{$layer->regions});
}
$spurious_infill -= scalar(@{$self->objects->[0]->layers} - 1) % 6;
fail "spurious fill surfaces found on layers that should have none (walls " . sprintf("%.4f", Slic3r::Geometry::rad2deg(atan2($shift, 20/&Slic3r::SCALING_FACTOR))) . " degrees off vertical)"
unless $spurious_infill == 0;
1;
};
# Test with mm skew offsets for the top of the 20mm-high box
for my $shift (0, 0.0001, 1) {
ok $test->($shift), "no spurious fill surfaces with box walls " . sprintf("%.4f",Slic3r::Geometry::rad2deg(atan2($shift, 20))) . " degrees off of vertical";
}
}
__END__
|