Make tests pass

This commit is contained in:
Alessandro Ranellucci 2014-01-05 00:36:33 +01:00
parent a2cbb261cb
commit 07b9b12475
16 changed files with 159 additions and 82 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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));
$_
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;
}
map $_->clone,
@{$extrusion_path->intersect_expolygons($self->_layer_overhangs)};
# 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'

View File

@ -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');
}

View File

@ -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);

View File

@ -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,
);

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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];
}
});

View File

@ -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,

View File

@ -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);

View File

@ -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
};

View File

@ -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;

View File

@ -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';

View File

@ -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);