Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlessandro Ranellucci <aar@cpan.org>2014-01-05 03:36:33 +0400
committerAlessandro Ranellucci <aar@cpan.org>2014-01-05 03:36:33 +0400
commit07b9b12475ddcc206252abb43cb457db06dd334b (patch)
treef87789520ae936b0c32f563fe514eaf6802da404
parenta2cbb261cbef9b95b7e900fac3408fc3513fe52b (diff)
Make tests pass
-rw-r--r--lib/Slic3r/Extruder.pm3
-rw-r--r--lib/Slic3r/Flow.pm4
-rw-r--r--lib/Slic3r/GCode.pm35
-rw-r--r--lib/Slic3r/GCode/Layer.pm16
-rw-r--r--lib/Slic3r/Print.pm16
-rw-r--r--lib/Slic3r/Print/Object.pm13
-rw-r--r--lib/Slic3r/Print/Region.pm2
-rw-r--r--lib/Slic3r/Print/SupportMaterial.pm4
-rw-r--r--t/combineinfill.t35
-rw-r--r--t/retraction.t18
-rw-r--r--t/support.t8
-rw-r--r--xs/src/Config.cpp32
-rw-r--r--xs/src/Config.hpp41
-rw-r--r--xs/src/PrintConfig.hpp4
-rw-r--r--xs/t/15_config.t5
-rw-r--r--xs/xsp/Config.xsp5
16 files changed, 159 insertions, 82 deletions
diff --git a/lib/Slic3r/Extruder.pm b/lib/Slic3r/Extruder.pm
index 2a8371cef..514aec7c7 100644
--- a/lib/Slic3r/Extruder.pm
+++ b/lib/Slic3r/Extruder.pm
@@ -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);
}
diff --git a/lib/Slic3r/Flow.pm b/lib/Slic3r/Flow.pm
index 5b1502a73..f07be98f5 100644
--- a/lib/Slic3r/Flow.pm
+++ b/lib/Slic3r/Flow.pm
@@ -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
diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm
index b1c05d95d..78324f3bd 100644
--- a/lib/Slic3r/GCode.pm
+++ b/lib/Slic3r/GCode.pm
@@ -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'
diff --git a/lib/Slic3r/GCode/Layer.pm b/lib/Slic3r/GCode/Layer.pm
index 96029eaab..08de360ec 100644
--- a/lib/Slic3r/GCode/Layer.pm
+++ b/lib/Slic3r/GCode/Layer.pm
@@ -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');
}
diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm
index f31e6665a..e24070354 100644
--- a/lib/Slic3r/Print.pm
+++ b/lib/Slic3r/Print.pm
@@ -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);
diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm
index 2d9e9b53c..bf196c100 100644
--- a/lib/Slic3r/Print/Object.pm
+++ b/lib/Slic3r/Print/Object.pm
@@ -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,
);
diff --git a/lib/Slic3r/Print/Region.pm b/lib/Slic3r/Print/Region.pm
index 472968478..657aa34d3 100644
--- a/lib/Slic3r/Print/Region.pm
+++ b/lib/Slic3r/Print/Region.pm
@@ -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,
diff --git a/lib/Slic3r/Print/SupportMaterial.pm b/lib/Slic3r/Print/SupportMaterial.pm
index a88728e67..2c533d8d9 100644
--- a/lib/Slic3r/Print/SupportMaterial.pm
+++ b/lib/Slic3r/Print/SupportMaterial.pm
@@ -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);
diff --git a/t/combineinfill.t b/t/combineinfill.t
index bd80b0d30..62e22e6b2 100644
--- a/t/combineinfill.t
+++ b/t/combineinfill.t
@@ -11,11 +11,42 @@ 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);
$config->set('bottom_solid_layers', 0);
diff --git a/t/retraction.t b/t/retraction.t
index 636359149..3737f63cd 100644
--- a/t/retraction.t
+++ b/t/retraction.t
@@ -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];
}
});
diff --git a/t/support.t b/t/support.t
index bd82d0ce1..a1e7173d9 100644
--- a/t/support.t
+++ b/t/support.t
@@ -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,
diff --git a/xs/src/Config.cpp b/xs/src/Config.cpp
index 58c9343e2..32c6d6074 100644
--- a/xs/src/Config.cpp
+++ b/xs/src/Config.cpp
@@ -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);
diff --git a/xs/src/Config.hpp b/xs/src/Config.hpp
index 9306a18b2..64229cb2c 100644
--- a/xs/src/Config.hpp
+++ b/xs/src/Config.hpp
@@ -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
};
diff --git a/xs/src/PrintConfig.hpp b/xs/src/PrintConfig.hpp
index c5adff7c1..cb44a007f 100644
--- a/xs/src/PrintConfig.hpp
+++ b/xs/src/PrintConfig.hpp
@@ -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;
diff --git a/xs/t/15_config.t b/xs/t/15_config.t
index 0d2080602..c80f14408 100644
--- a/xs/t/15_config.t
+++ b/xs/t/15_config.t
@@ -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';
diff --git a/xs/xsp/Config.xsp b/xs/xsp/Config.xsp
index 743b38ca1..79d9bd269 100644
--- a/xs/xsp/Config.xsp
+++ b/xs/xsp/Config.xsp
@@ -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);