Make tests pass
This commit is contained in:
parent
a2cbb261cb
commit
07b9b12475
@ -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);
|
||||
|
@ -11,10 +11,41 @@ use List::Util qw(first);
|
||||
use Slic3r;
|
||||
use Slic3r::Test;
|
||||
|
||||
plan skip_all => 'this test is currently disabled'; # needs to be adapted to the new API
|
||||
plan tests => 3;
|
||||
plan tests => 2;
|
||||
|
||||
{
|
||||
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('infill_extruder', 2);
|
||||
$config->set('top_solid_layers', 0);
|
||||
$config->set('bottom_solid_layers', 0);
|
||||
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 %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) {
|
||||
$layer_infill{$self->Z} //= 0;
|
||||
if ($tool == $config->infill_extruder-1) {
|
||||
$layer_infill{$self->Z} = 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
my $layers_with_infill = grep $_, values %layer_infill;
|
||||
$layers_with_infill--; # first layer is never combined
|
||||
is $layers_with_infill, scalar(keys %layer_infill)/2, 'infill is only present in correct number of layers';
|
||||
}
|
||||
|
||||
# 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);
|
||||
|
@ -41,8 +41,8 @@ my $test = sub {
|
||||
|
||||
if ($info->{dist_Z}) {
|
||||
# lift move or lift + change layer
|
||||
if (_eq($info->{dist_Z}, $print->extruders->[$tool]->retract_lift)
|
||||
|| (_eq($info->{dist_Z}, $conf->layer_height + $print->extruders->[$tool]->retract_lift) && $print->extruders->[$tool]->retract_lift > 0)) {
|
||||
if (_eq($info->{dist_Z}, $print->config->get_at('retract_lift', $tool))
|
||||
|| (_eq($info->{dist_Z}, $conf->layer_height + $print->config->get_at('retract_lift', $tool)) && $print->config->get_at('retract_lift', $tool) > 0)) {
|
||||
fail 'only lifting while retracted' if !$retracted[$tool] && !($conf->g0 && $info->{retracting});
|
||||
fail 'double lift' if $lifted;
|
||||
$lifted = 1;
|
||||
@ -50,8 +50,8 @@ my $test = sub {
|
||||
if ($info->{dist_Z} < 0) {
|
||||
fail 'going down only after lifting' if !$lifted;
|
||||
fail 'going down by the same amount of the lift or by the amount needed to get to next layer'
|
||||
if !_eq($info->{dist_Z}, -$print->extruders->[$tool]->retract_lift)
|
||||
&& !_eq($info->{dist_Z}, -$print->extruders->[$tool]->retract_lift + $conf->layer_height);
|
||||
if !_eq($info->{dist_Z}, -$print->config->get_at('retract_lift', $tool))
|
||||
&& !_eq($info->{dist_Z}, -$print->config->get_at('retract_lift', $tool) + $conf->layer_height);
|
||||
$lifted = 0;
|
||||
}
|
||||
fail 'move Z at travel speed' if ($args->{F} // $self->F) != $conf->travel_speed * 60;
|
||||
@ -59,9 +59,9 @@ my $test = sub {
|
||||
if ($info->{retracting}) {
|
||||
$retracted[$tool] = 1;
|
||||
$retracted_length[$tool] += -$info->{dist_E};
|
||||
if (_eq($retracted_length[$tool], $print->extruders->[$tool]->retract_length)) {
|
||||
if (_eq($retracted_length[$tool], $print->config->get_at('retract_length', $tool))) {
|
||||
# okay
|
||||
} elsif (_eq($retracted_length[$tool], $print->extruders->[$tool]->retract_length_toolchange)) {
|
||||
} elsif (_eq($retracted_length[$tool], $print->config->get_at('retract_length_toolchange', $tool))) {
|
||||
$wait_for_toolchange = 1;
|
||||
} else {
|
||||
fail 'retracted by the correct amount';
|
||||
@ -72,9 +72,9 @@ my $test = sub {
|
||||
if ($info->{extruding}) {
|
||||
fail 'only extruding while not lifted' if $lifted;
|
||||
if ($retracted[$tool]) {
|
||||
my $expected_amount = $retracted_length[$tool] + $print->extruders->[$tool]->retract_restart_extra;
|
||||
my $expected_amount = $retracted_length[$tool] + $print->config->get_at('retract_restart_extra', $tool);
|
||||
if ($changed_tool && $toolchange_count[$tool] > 1) {
|
||||
$expected_amount = $print->extruders->[$tool]->retract_length_toolchange + $print->extruders->[$tool]->retract_restart_extra_toolchange;
|
||||
$expected_amount = $print->config->get_at('retract_length_toolchange', $tool) + $print->config->get_at('retract_restart_extra_toolchange', $tool);
|
||||
$changed_tool = 0;
|
||||
}
|
||||
fail 'unretracted by the correct amount'
|
||||
@ -83,7 +83,7 @@ my $test = sub {
|
||||
$retracted_length[$tool] = 0;
|
||||
}
|
||||
}
|
||||
if ($info->{travel} && $info->{dist_XY} >= $print->extruders->[$tool]->retract_before_travel) {
|
||||
if ($info->{travel} && $info->{dist_XY} >= $print->config->get_at('retract_before_travel', $tool)) {
|
||||
fail 'retracted before long travel move' if !$retracted[$tool];
|
||||
}
|
||||
});
|
||||
|
@ -23,7 +23,13 @@ use Slic3r::Test;
|
||||
$print->init_extruders;
|
||||
my $flow = $print->objects->[0]->support_material_flow;
|
||||
my $support_z = Slic3r::Print::SupportMaterial
|
||||
->new(object_config => $print->objects->[0]->config, print_config => $print->config, flow => $flow)
|
||||
->new(
|
||||
object_config => $print->objects->[0]->config,
|
||||
print_config => $print->config,
|
||||
flow => $flow,
|
||||
interface_flow => $flow,
|
||||
first_layer_flow => $flow,
|
||||
)
|
||||
->support_layers_z(\@contact_z, \@top_z, $config->layer_height);
|
||||
|
||||
is $support_z->[0], $config->first_layer_height,
|
||||
|
@ -130,9 +130,9 @@ ConfigBase::get(t_config_option_key opt_key) {
|
||||
return optv->point.to_SV_pureperl();
|
||||
} else if (ConfigOptionPoints* optv = dynamic_cast<ConfigOptionPoints*>(opt)) {
|
||||
AV* av = newAV();
|
||||
av_fill(av, optv->points.size()-1);
|
||||
for (Pointfs::iterator it = optv->points.begin(); it != optv->points.end(); ++it)
|
||||
av_store(av, it - optv->points.begin(), it->to_SV_pureperl());
|
||||
av_fill(av, optv->values.size()-1);
|
||||
for (Pointfs::iterator it = optv->values.begin(); it != optv->values.end(); ++it)
|
||||
av_store(av, it - optv->values.begin(), it->to_SV_pureperl());
|
||||
return newRV_noinc((SV*)av);
|
||||
} else if (ConfigOptionBool* optv = dynamic_cast<ConfigOptionBool*>(opt)) {
|
||||
return newSViv(optv->value ? 1 : 0);
|
||||
@ -148,6 +148,28 @@ ConfigBase::get(t_config_option_key opt_key) {
|
||||
}
|
||||
}
|
||||
|
||||
SV*
|
||||
ConfigBase::get_at(t_config_option_key opt_key, size_t i) {
|
||||
ConfigOption* opt = this->option(opt_key);
|
||||
if (opt == NULL) return &PL_sv_undef;
|
||||
|
||||
if (ConfigOptionFloats* optv = dynamic_cast<ConfigOptionFloats*>(opt)) {
|
||||
return newSVnv(optv->get_at(i));
|
||||
} else if (ConfigOptionInts* optv = dynamic_cast<ConfigOptionInts*>(opt)) {
|
||||
return newSViv(optv->get_at(i));
|
||||
} else if (ConfigOptionStrings* optv = dynamic_cast<ConfigOptionStrings*>(opt)) {
|
||||
// we don't serialize() because that would escape newlines
|
||||
std::string val = optv->get_at(i);
|
||||
return newSVpvn(val.c_str(), val.length());
|
||||
} else if (ConfigOptionPoints* optv = dynamic_cast<ConfigOptionPoints*>(opt)) {
|
||||
return optv->get_at(i).to_SV_pureperl();
|
||||
} else if (ConfigOptionBools* optv = dynamic_cast<ConfigOptionBools*>(opt)) {
|
||||
return newSViv(optv->get_at(i) ? 1 : 0);
|
||||
} else {
|
||||
return &PL_sv_undef;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ConfigBase::set(t_config_option_key opt_key, SV* value) {
|
||||
ConfigOption* opt = this->option(opt_key, true);
|
||||
@ -193,14 +215,14 @@ ConfigBase::set(t_config_option_key opt_key, SV* value) {
|
||||
} else if (ConfigOptionPoint* optv = dynamic_cast<ConfigOptionPoint*>(opt)) {
|
||||
optv->point.from_SV(value);
|
||||
} else if (ConfigOptionPoints* optv = dynamic_cast<ConfigOptionPoints*>(opt)) {
|
||||
optv->points.clear();
|
||||
optv->values.clear();
|
||||
AV* av = (AV*)SvRV(value);
|
||||
const size_t len = av_len(av)+1;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
SV** elem = av_fetch(av, i, 0);
|
||||
Pointf point;
|
||||
point.from_SV(*elem);
|
||||
optv->points.push_back(point);
|
||||
optv->values.push_back(point);
|
||||
}
|
||||
} else if (ConfigOptionBool* optv = dynamic_cast<ConfigOptionBool*>(opt)) {
|
||||
optv->value = SvTRUE(value);
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "Point.hpp"
|
||||
@ -24,6 +25,22 @@ class ConfigOption {
|
||||
virtual void deserialize(std::string str) = 0;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class ConfigOptionVector
|
||||
{
|
||||
public:
|
||||
virtual ~ConfigOptionVector() {};
|
||||
std::vector<T> values;
|
||||
|
||||
T get_at(size_t i) {
|
||||
try {
|
||||
return this->values.at(i);
|
||||
} catch (const std::out_of_range& oor) {
|
||||
return this->values.front();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class ConfigOptionFloat : public ConfigOption
|
||||
{
|
||||
public:
|
||||
@ -43,10 +60,9 @@ class ConfigOptionFloat : public ConfigOption
|
||||
};
|
||||
};
|
||||
|
||||
class ConfigOptionFloats : public ConfigOption
|
||||
class ConfigOptionFloats : public ConfigOption, public ConfigOptionVector<double>
|
||||
{
|
||||
public:
|
||||
std::vector<double> values;
|
||||
|
||||
std::string serialize() {
|
||||
std::ostringstream ss;
|
||||
@ -86,10 +102,9 @@ class ConfigOptionInt : public ConfigOption
|
||||
};
|
||||
};
|
||||
|
||||
class ConfigOptionInts : public ConfigOption
|
||||
class ConfigOptionInts : public ConfigOption, public ConfigOptionVector<int>
|
||||
{
|
||||
public:
|
||||
std::vector<int> values;
|
||||
|
||||
std::string serialize() {
|
||||
std::ostringstream ss;
|
||||
@ -144,10 +159,9 @@ class ConfigOptionString : public ConfigOption
|
||||
};
|
||||
|
||||
// semicolon-separated strings
|
||||
class ConfigOptionStrings : public ConfigOption
|
||||
class ConfigOptionStrings : public ConfigOption, public ConfigOptionVector<std::string>
|
||||
{
|
||||
public:
|
||||
std::vector<std::string> values;
|
||||
|
||||
std::string serialize() {
|
||||
std::ostringstream ss;
|
||||
@ -215,15 +229,14 @@ class ConfigOptionPoint : public ConfigOption
|
||||
};
|
||||
};
|
||||
|
||||
class ConfigOptionPoints : public ConfigOption
|
||||
class ConfigOptionPoints : public ConfigOption, public ConfigOptionVector<Pointf>
|
||||
{
|
||||
public:
|
||||
Pointfs points;
|
||||
|
||||
std::string serialize() {
|
||||
std::ostringstream ss;
|
||||
for (Pointfs::const_iterator it = this->points.begin(); it != this->points.end(); ++it) {
|
||||
if (it - this->points.begin() != 0) ss << ",";
|
||||
for (Pointfs::const_iterator it = this->values.begin(); it != this->values.end(); ++it) {
|
||||
if (it - this->values.begin() != 0) ss << ",";
|
||||
ss << it->x;
|
||||
ss << "x";
|
||||
ss << it->y;
|
||||
@ -232,13 +245,13 @@ class ConfigOptionPoints : public ConfigOption
|
||||
};
|
||||
|
||||
void deserialize(std::string str) {
|
||||
this->points.clear();
|
||||
this->values.clear();
|
||||
std::istringstream is(str);
|
||||
std::string point_str;
|
||||
while (std::getline(is, point_str, ',')) {
|
||||
Pointf point;
|
||||
sscanf(point_str.c_str(), "%lfx%lf", &point.x, &point.y);
|
||||
this->points.push_back(point);
|
||||
this->values.push_back(point);
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -260,10 +273,9 @@ class ConfigOptionBool : public ConfigOption
|
||||
};
|
||||
};
|
||||
|
||||
class ConfigOptionBools : public ConfigOption
|
||||
class ConfigOptionBools : public ConfigOption, public ConfigOptionVector<bool>
|
||||
{
|
||||
public:
|
||||
std::vector<bool> values;
|
||||
|
||||
std::string serialize() {
|
||||
std::ostringstream ss;
|
||||
@ -398,6 +410,7 @@ class ConfigBase
|
||||
#ifdef SLIC3RXS
|
||||
SV* as_hash();
|
||||
SV* get(t_config_option_key opt_key);
|
||||
SV* get_at(t_config_option_key opt_key, size_t i);
|
||||
void set(t_config_option_key opt_key, SV* value);
|
||||
#endif
|
||||
};
|
||||
|
@ -1131,8 +1131,8 @@ class PrintConfig : public virtual StaticConfig
|
||||
this->external_perimeters_first.value = false;
|
||||
this->extruder_clearance_height.value = 20;
|
||||
this->extruder_clearance_radius.value = 20;
|
||||
this->extruder_offset.points.resize(1);
|
||||
this->extruder_offset.points[0] = Pointf(0,0);
|
||||
this->extruder_offset.values.resize(1);
|
||||
this->extruder_offset.values[0] = Pointf(0,0);
|
||||
this->extrusion_axis.value = "E";
|
||||
this->extrusion_multiplier.values.resize(1);
|
||||
this->extrusion_multiplier.values[0] = 1;
|
||||
|
@ -4,7 +4,7 @@ use strict;
|
||||
use warnings;
|
||||
|
||||
use Slic3r::XS;
|
||||
use Test::More tests => 82;
|
||||
use Test::More tests => 88;
|
||||
|
||||
foreach my $config (Slic3r::Config->new, Slic3r::Config::Full->new) {
|
||||
$config->set('layer_height', 0.3);
|
||||
@ -75,6 +75,9 @@ foreach my $config (Slic3r::Config->new, Slic3r::Config::Full->new) {
|
||||
|
||||
$config->set('wipe', [1,0]);
|
||||
is_deeply $config->get('wipe'), [1,0], 'set/get bools';
|
||||
is $config->get_at('wipe', 0), 1, 'get_at bools';
|
||||
is $config->get_at('wipe', 1), 0, 'get_at bools';
|
||||
is $config->get_at('wipe', 9), 1, 'get_at bools';
|
||||
is $config->serialize('wipe'), '1,0', 'serialize bools';
|
||||
$config->set_deserialize('wipe', '0,1,1');
|
||||
is_deeply $config->get('wipe'), [0,1,1], 'deserialize bools';
|
||||
|
@ -11,6 +11,7 @@
|
||||
bool has(t_config_option_key opt_key);
|
||||
SV* as_hash();
|
||||
SV* get(t_config_option_key opt_key);
|
||||
SV* get_at(t_config_option_key opt_key, int i);
|
||||
void set(t_config_option_key opt_key, SV* value);
|
||||
void set_deserialize(t_config_option_key opt_key, std::string str);
|
||||
std::string serialize(t_config_option_key opt_key);
|
||||
@ -31,6 +32,7 @@
|
||||
bool has(t_config_option_key opt_key);
|
||||
SV* as_hash();
|
||||
SV* get(t_config_option_key opt_key);
|
||||
SV* get_at(t_config_option_key opt_key, int i);
|
||||
void set(t_config_option_key opt_key, SV* value);
|
||||
void set_deserialize(t_config_option_key opt_key, std::string str);
|
||||
std::string serialize(t_config_option_key opt_key);
|
||||
@ -50,6 +52,7 @@
|
||||
bool has(t_config_option_key opt_key);
|
||||
SV* as_hash();
|
||||
SV* get(t_config_option_key opt_key);
|
||||
SV* get_at(t_config_option_key opt_key, int i);
|
||||
void set(t_config_option_key opt_key, SV* value);
|
||||
void set_deserialize(t_config_option_key opt_key, std::string str);
|
||||
std::string serialize(t_config_option_key opt_key);
|
||||
@ -70,6 +73,7 @@
|
||||
bool has(t_config_option_key opt_key);
|
||||
SV* as_hash();
|
||||
SV* get(t_config_option_key opt_key);
|
||||
SV* get_at(t_config_option_key opt_key, int i);
|
||||
void set(t_config_option_key opt_key, SV* value);
|
||||
void set_deserialize(t_config_option_key opt_key, std::string str);
|
||||
std::string serialize(t_config_option_key opt_key);
|
||||
@ -90,6 +94,7 @@
|
||||
bool has(t_config_option_key opt_key);
|
||||
SV* as_hash();
|
||||
SV* get(t_config_option_key opt_key);
|
||||
SV* get_at(t_config_option_key opt_key, int i);
|
||||
void set(t_config_option_key opt_key, SV* value);
|
||||
void set_deserialize(t_config_option_key opt_key, std::string str);
|
||||
std::string serialize(t_config_option_key opt_key);
|
||||
|
Loading…
Reference in New Issue
Block a user