diff --git a/lib/Slic3r/Config.pm b/lib/Slic3r/Config.pm index 1c78843f..e5318d87 100644 --- a/lib/Slic3r/Config.pm +++ b/lib/Slic3r/Config.pm @@ -424,9 +424,23 @@ our $Options = { }, 'solid_layers' => { label => 'Solid layers', - tooltip => 'Number of solid layers to generate on top and bottom.', + tooltip => 'Number of solid layers to generate on top and bottom surfaces.', cli => 'solid-layers=i', type => 'i', + shortcut => [qw(top_solid_layers bottom_solid_layers)], + }, + 'top_solid_layers' => { + label => 'Top', + tooltip => 'Number of solid layers to generate on top surfaces.', + cli => 'top-solid-layers=i', + type => 'i', + default => 3, + }, + 'bottom_solid_layers' => { + label => 'Bottom', + tooltip => 'Number of solid layers to generate on bottom surfaces.', + cli => 'bottom-solid-layers=i', + type => 'i', default => 3, }, 'fill_pattern' => { @@ -867,7 +881,11 @@ sub new { sub new_from_defaults { my $class = shift; my @opt_keys = - return $class->new(map { $_ => $Options->{$_}{default} } (@_ ? @_ : keys %$Options)); + return $class->new( + map { $_ => $Options->{$_}{default} } + grep !$Options->{$_}{shortcut}, + (@_ ? @_ : keys %$Options) + ); } sub new_from_cli { @@ -972,6 +990,10 @@ sub set { if $deserialize && $Options->{$opt_key}{deserialize}; $self->{$opt_key} = $value; + + if ($Options->{$opt_key}{shortcut}) { + $self->set($_, $value, $deserialize) for @{$Options->{$opt_key}{shortcut}}; + } } sub set_ifndef { @@ -1003,6 +1025,7 @@ sub save { my $ini = { _ => {} }; foreach my $opt_key (sort keys %$self) { + next if $Options->{$opt_key}{shortcut}; next if $Options->{$opt_key}{gui_only}; $ini->{_}{$opt_key} = $self->serialize($opt_key); } @@ -1055,8 +1078,9 @@ sub validate { if $self->perimeters < 0; # --solid-layers - die "Invalid value for --solid-layers\n" - if $self->solid_layers < 0; + die "Invalid value for --solid-layers\n" if defined $self->solid_layers && $self->solid_layers < 0; + die "Invalid value for --top-solid-layers\n" if $self->top_solid_layers < 0; + die "Invalid value for --bottom-solid-layers\n" if $self->bottom_solid_layers < 0; # --print-center die "Invalid value for --print-center\n" diff --git a/lib/Slic3r/GUI/OptionsGroup.pm b/lib/Slic3r/GUI/OptionsGroup.pm index 9eec3791..6cfda414 100644 --- a/lib/Slic3r/GUI/OptionsGroup.pm +++ b/lib/Slic3r/GUI/OptionsGroup.pm @@ -103,16 +103,27 @@ sub _build_line { } my @fields = (); + my @field_labels = (); foreach my $opt_key (@{$line->{options}}) { my $opt = first { $_->{opt_key} eq $opt_key } @{$self->options}; push @fields, $self->_build_field($opt); + push @field_labels, $opt->{label}; } if (@fields > 1 || $line->{sidetext}) { my $sizer = Wx::BoxSizer->new(wxHORIZONTAL); - $sizer->Add($_, 0, wxALIGN_CENTER_VERTICAL, 0) for @fields; - my $sidetext = Wx::StaticText->new($self->parent, -1, $line->{sidetext}, wxDefaultPosition, wxDefaultSize); - $sidetext->SetFont($self->{sidetext_font}); - $sizer->Add($sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL , 4); + for my $i (0 .. $#fields) { + if (@fields > 1) { + my $field_label = Wx::StaticText->new($self->parent, -1, "$field_labels[$i]:", wxDefaultPosition, wxDefaultSize); + $field_label->SetFont($self->{sidetext_font}); + $sizer->Add($field_label, 0, wxALIGN_CENTER_VERTICAL, 0); + } + $sizer->Add($fields[$i], 0, wxALIGN_CENTER_VERTICAL, 0); + } + if ($line->{sidetext}) { + my $sidetext = Wx::StaticText->new($self->parent, -1, $line->{sidetext}, wxDefaultPosition, wxDefaultSize); + $sidetext->SetFont($self->{sidetext_font}); + $sizer->Add($sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL , 4); + } $grid_sizer->Add($sizer); } else { $grid_sizer->Add($fields[0], 0, ($line->{full_width} ? wxEXPAND : 0) | wxALIGN_CENTER_VERTICAL, 0); diff --git a/lib/Slic3r/GUI/Tab.pm b/lib/Slic3r/GUI/Tab.pm index fbab74eb..45b23504 100644 --- a/lib/Slic3r/GUI/Tab.pm +++ b/lib/Slic3r/GUI/Tab.pm @@ -396,11 +396,11 @@ sub build { }, { title => 'Horizontal shells', - options => [qw(solid_layers)], + options => [qw(top_solid_layers bottom_solid_layers)], lines => [ { label => 'Solid layers', - options => [qw(solid_layers)], + options => [qw(top_solid_layers bottom_solid_layers)], }, ], }, diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm index a23a85b6..564a436a 100644 --- a/lib/Slic3r/Layer/Region.pm +++ b/lib/Slic3r/Layer/Region.pm @@ -384,7 +384,7 @@ sub prepare_fill_surfaces { # if no solid layers are requested, turn top/bottom surfaces to internal # note that this modifies $self->surfaces in place - if ($Slic3r::Config->solid_layers == 0) { + if ($Slic3r::Config->top_solid_layers == 0 && $Slic3r::Config->bottom_solid_layers == 0) { $_->surface_type(S_TYPE_INTERNAL) for grep $_->surface_type != S_TYPE_INTERNAL, @surfaces; } diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index 652a1dee..06ef9e5c 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -54,6 +54,8 @@ sub _trigger_config { $self->config->set_ifndef('bridge_speed', $self->config->infill_speed); $self->config->set_ifndef('solid_infill_speed', $self->config->infill_speed); $self->config->set_ifndef('top_solid_infill_speed', $self->config->solid_infill_speed); + $self->config->set_ifndef('top_solid_layers', $self->config->solid_layers); + $self->config->set_ifndef('bottom_solid_layers', $self->config->solid_layers); # G-code flavors $self->config->set('extrusion_axis', 'A') if $self->config->gcode_flavor eq 'mach3'; @@ -629,7 +631,7 @@ sub write_gcode { print $fh "; $_\n" foreach split /\R/, $Slic3r::Config->notes; print $fh "\n" if $Slic3r::Config->notes; - for (qw(layer_height perimeters solid_layers fill_density perimeter_speed infill_speed travel_speed scale)) { + for (qw(layer_height perimeters top_solid_layers bottom_solid_layers fill_density perimeter_speed infill_speed travel_speed scale)) { printf $fh "; %s = %s\n", $_, $Slic3r::Config->$_; } for (qw(nozzle_diameter filament_diameter extrusion_multiplier)) { diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 3d7066a3..2760fa6f 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -344,8 +344,9 @@ sub discover_horizontal_shells { Slic3r::debugf "Layer %d has %d surfaces of type '%s'\n", $i, scalar(@surfaces), ($type == S_TYPE_TOP ? 'top' : 'bottom'); + my $solid_layers = S_TYPE_TOP ? $Slic3r::Config->top_solid_layers : $Slic3r::Config->bottom_solid_layers; for (my $n = $type == S_TYPE_TOP ? $i-1 : $i+1; - abs($n - $i) <= $Slic3r::Config->solid_layers-1; + abs($n - $i) <= $solid_layers-1; $type == S_TYPE_TOP ? $n-- : $n++) { next if $n < 0 || $n >= $self->layer_count;