mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-01 02:32:04 +08:00
Allow to set shell thickness for top/bottom layers (#4430)
* Fix a warning in PresetEditor line 806. * Remove min_shell_thickness from the if condition in LayerRegion.cpp * Add missing line in spiral vase check. * Add initial set top shell thickness. * Add minimum shell thickness for top/bottom layers. * Some refactoring. * Some Fixes. * revert last change. * a fix. * Some refactoring. * Some fix in calculating solid layers count. * Refactoring in LayerRegion.cpp, Object.pm and PresetEditor.pm
This commit is contained in:
parent
31ba88eaa4
commit
1527cfbb26
@ -191,6 +191,7 @@ sub validate {
|
|||||||
die "Invalid value for --solid-layers\n" if defined $self->solid_layers && $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 --top-solid-layers\n" if $self->top_solid_layers < 0;
|
||||||
die "Invalid value for --bottom-solid-layers\n" if $self->bottom_solid_layers < 0;
|
die "Invalid value for --bottom-solid-layers\n" if $self->bottom_solid_layers < 0;
|
||||||
|
die "Invalid value for --min-top-bottom-shell-thickness\n" if $self->min_top_bottom_shell_thickness < 0;
|
||||||
|
|
||||||
# --gcode-flavor
|
# --gcode-flavor
|
||||||
die "Invalid value for --gcode-flavor\n"
|
die "Invalid value for --gcode-flavor\n"
|
||||||
|
@ -438,7 +438,7 @@ sub options {
|
|||||||
layer_height first_layer_height
|
layer_height first_layer_height
|
||||||
adaptive_slicing adaptive_slicing_quality match_horizontal_surfaces
|
adaptive_slicing adaptive_slicing_quality match_horizontal_surfaces
|
||||||
perimeters spiral_vase
|
perimeters spiral_vase
|
||||||
top_solid_layers min_shell_thickness bottom_solid_layers
|
top_solid_layers min_shell_thickness min_top_bottom_shell_thickness bottom_solid_layers
|
||||||
extra_perimeters avoid_crossing_perimeters thin_walls overhangs
|
extra_perimeters avoid_crossing_perimeters thin_walls overhangs
|
||||||
seam_position external_perimeters_first
|
seam_position external_perimeters_first
|
||||||
fill_density fill_pattern top_infill_pattern bottom_infill_pattern fill_gaps
|
fill_density fill_pattern top_infill_pattern bottom_infill_pattern fill_gaps
|
||||||
@ -532,6 +532,8 @@ sub build {
|
|||||||
$line->append_option($optgroup->get_option('top_solid_layers'));
|
$line->append_option($optgroup->get_option('top_solid_layers'));
|
||||||
$line->append_option($optgroup->get_option('bottom_solid_layers'));
|
$line->append_option($optgroup->get_option('bottom_solid_layers'));
|
||||||
$optgroup->append_line($line);
|
$optgroup->append_line($line);
|
||||||
|
|
||||||
|
$optgroup->append_single_option_line('min_top_bottom_shell_thickness');
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
my $optgroup = $page->new_optgroup('Quality (slower slicing)');
|
my $optgroup = $page->new_optgroup('Quality (slower slicing)');
|
||||||
@ -622,7 +624,7 @@ sub build {
|
|||||||
$optgroup->append_single_option_line('dont_support_bridges');
|
$optgroup->append_single_option_line('dont_support_bridges');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
my $page = $self->add_options_page('Speed', 'time.png');
|
my $page = $self->add_options_page('Speed', 'time.png');
|
||||||
{
|
{
|
||||||
@ -802,11 +804,12 @@ sub _update {
|
|||||||
$opt_key = "all_keys" if (length($key // '') == 0);
|
$opt_key = "all_keys" if (length($key // '') == 0);
|
||||||
my $config = $self->{config};
|
my $config = $self->{config};
|
||||||
|
|
||||||
if (any { /$opt_key/ } qw(all_keys spiral_vase perimeters top_solid_layers fill_density support_material min_shell_thickness)) {
|
if (any { /$opt_key/ } qw(all_keys spiral_vase perimeters top_solid_layers fill_density support_material min_shell_thickness min_top_bottom_shell_thickness)) {
|
||||||
if ($config->spiral_vase && !($config->perimeters == 1 && $config->min_shell_thickness == 0 && $config->top_solid_layers == 0 && $config->fill_density == 0 && $config->support_material == 0)) {
|
if ($config->spiral_vase && !($config->perimeters == 1 && $config->min_shell_thickness == 0 && $config->min_top_bottom_shell_thickness == 0 && $config->top_solid_layers == 0 && $config->fill_density == 0 && $config->support_material == 0)) {
|
||||||
my $dialog = Wx::MessageDialog->new($self,
|
my $dialog = Wx::MessageDialog->new($self,
|
||||||
"The Spiral Vase mode requires:\n"
|
"The Spiral Vase mode requires:\n"
|
||||||
. "- one perimeter\n"
|
. "- one perimeter\n"
|
||||||
|
. "- shell thickness to be 0\n"
|
||||||
. "- no top solid layers\n"
|
. "- no top solid layers\n"
|
||||||
. "- 0% fill density\n"
|
. "- 0% fill density\n"
|
||||||
. "- no support material\n"
|
. "- no support material\n"
|
||||||
@ -816,6 +819,7 @@ sub _update {
|
|||||||
my $new_conf = Slic3r::Config->new;
|
my $new_conf = Slic3r::Config->new;
|
||||||
$new_conf->set("perimeters", 1);
|
$new_conf->set("perimeters", 1);
|
||||||
$new_conf->set("min_shell_thickness", 0);
|
$new_conf->set("min_shell_thickness", 0);
|
||||||
|
$new_conf->set("min_top_bottom_shell_thickness", 0);
|
||||||
$new_conf->set("top_solid_layers", 0);
|
$new_conf->set("top_solid_layers", 0);
|
||||||
$new_conf->set("fill_density", 0);
|
$new_conf->set("fill_density", 0);
|
||||||
$new_conf->set("support_material", 0);
|
$new_conf->set("support_material", 0);
|
||||||
@ -901,7 +905,7 @@ sub _update {
|
|||||||
solid_infill_below_area infill_extruder);
|
solid_infill_below_area infill_extruder);
|
||||||
}
|
}
|
||||||
|
|
||||||
my $have_solid_infill = ($config->top_solid_layers > 0) || ($config->bottom_solid_layers > 0);
|
my $have_solid_infill = ($config->top_solid_layers > 0) || ($config->bottom_solid_layers > 0) || ($config->min_top_bottom_shell_thickness > 0);
|
||||||
if (any { /$opt_key/ } qw(all_keys top_solid_layers bottom_solid_layers)) {
|
if (any { /$opt_key/ } qw(all_keys top_solid_layers bottom_solid_layers)) {
|
||||||
# solid_infill_extruder uses the same logic as in Print::extruders()
|
# solid_infill_extruder uses the same logic as in Print::extruders()
|
||||||
$self->get_field($_)->toggle($have_solid_infill)
|
$self->get_field($_)->toggle($have_solid_infill)
|
||||||
@ -919,7 +923,7 @@ sub _update {
|
|||||||
$self->get_field('gap_fill_speed')->toggle($have_perimeters && $have_infill && $config->fill_gaps);
|
$self->get_field('gap_fill_speed')->toggle($have_perimeters && $have_infill && $config->fill_gaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
my $have_top_solid_infill = ($config->top_solid_layers > 0) || ($config->min_shell_thickness > 0);
|
my $have_top_solid_infill = ($config->top_solid_layers > 0) || ($config->min_top_bottom_shell_thickness > 0);
|
||||||
|
|
||||||
$self->get_field($_)->toggle($have_top_solid_infill)
|
$self->get_field($_)->toggle($have_top_solid_infill)
|
||||||
for qw(top_infill_extrusion_width top_solid_infill_speed);
|
for qw(top_infill_extrusion_width top_solid_infill_speed);
|
||||||
|
@ -3,6 +3,7 @@ package Slic3r::Print::Object;
|
|||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
|
use POSIX;
|
||||||
use List::Util qw(min max sum first any);
|
use List::Util qw(min max sum first any);
|
||||||
use Slic3r::Flow ':roles';
|
use Slic3r::Flow ':roles';
|
||||||
use Slic3r::Geometry qw(X Y Z PI scale unscale chained_path epsilon);
|
use Slic3r::Geometry qw(X Y Z PI scale unscale chained_path epsilon);
|
||||||
@ -387,10 +388,21 @@ sub discover_horizontal_shells {
|
|||||||
];
|
];
|
||||||
next if !@$solid;
|
next if !@$solid;
|
||||||
Slic3r::debugf "Layer %d has %s surfaces\n", $i, ($type == S_TYPE_TOP) ? 'top' : 'bottom';
|
Slic3r::debugf "Layer %d has %s surfaces\n", $i, ($type == S_TYPE_TOP) ? 'top' : 'bottom';
|
||||||
|
|
||||||
my $solid_layers = ($type == S_TYPE_TOP)
|
my $solid_layers = ($type == S_TYPE_TOP)
|
||||||
? $layerm->region->config->top_solid_layers
|
? $layerm->region->config->top_solid_layers
|
||||||
: $layerm->region->config->bottom_solid_layers;
|
: $layerm->region->config->bottom_solid_layers;
|
||||||
|
|
||||||
|
if ($layerm->region->config->min_top_bottom_shell_thickness > 0) {
|
||||||
|
my $current_shell_thickness = $solid_layers * $self->get_layer($i)->height;
|
||||||
|
my $minimum_shell_thickness = $layerm->region->config->min_top_bottom_shell_thickness;
|
||||||
|
|
||||||
|
while ($minimum_shell_thickness - $current_shell_thickness > epsilon) {
|
||||||
|
$solid_layers++;
|
||||||
|
$current_shell_thickness = $solid_layers * $self->get_layer($i)->height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NEIGHBOR: for (my $n = ($type == S_TYPE_TOP) ? $i-1 : $i+1;
|
NEIGHBOR: for (my $n = ($type == S_TYPE_TOP) ? $i-1 : $i+1;
|
||||||
abs($n - $i) <= $solid_layers-1;
|
abs($n - $i) <= $solid_layers-1;
|
||||||
($type == S_TYPE_TOP) ? $n-- : $n++) {
|
($type == S_TYPE_TOP) ? $n-- : $n++) {
|
||||||
|
@ -237,26 +237,25 @@ LayerRegion::prepare_fill_surfaces()
|
|||||||
the only meaningful information returned by psPerimeters. */
|
the only meaningful information returned by psPerimeters. */
|
||||||
|
|
||||||
// if no solid layers are requested, turn top/bottom surfaces to internal
|
// if no solid layers are requested, turn top/bottom surfaces to internal
|
||||||
if (this->region()->config.min_shell_thickness == 0) {
|
if (this->region()->config.top_solid_layers == 0 && this->region()->config.min_top_bottom_shell_thickness <= 0) {
|
||||||
if (this->region()->config.top_solid_layers == 0) {
|
for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface) {
|
||||||
for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface) {
|
if (surface->surface_type == stTop) {
|
||||||
if (surface->surface_type == stTop) {
|
if (this->layer()->object()->config.infill_only_where_needed) {
|
||||||
if (this->layer()->object()->config.infill_only_where_needed) {
|
surface->surface_type = stInternalVoid;
|
||||||
surface->surface_type = stInternalVoid;
|
} else {
|
||||||
} else {
|
surface->surface_type = stInternal;
|
||||||
surface->surface_type = stInternal;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this->region()->config.bottom_solid_layers == 0) {
|
}
|
||||||
for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface) {
|
|
||||||
if (surface->surface_type == stBottom || surface->surface_type == stBottomBridge)
|
if (this->region()->config.bottom_solid_layers == 0 && this->region()->config.min_top_bottom_shell_thickness <= 0) {
|
||||||
surface->surface_type = stInternal;
|
for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface) {
|
||||||
}
|
if (surface->surface_type == stBottom || surface->surface_type == stBottomBridge)
|
||||||
|
surface->surface_type = stInternal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// turn too small internal regions into solid regions according to the user setting
|
// turn too small internal regions into solid regions according to the user setting
|
||||||
const float &fill_density = this->region()->config.fill_density;
|
const float &fill_density = this->region()->config.fill_density;
|
||||||
if (fill_density > 0 && fill_density < 100) {
|
if (fill_density > 0 && fill_density < 100) {
|
||||||
|
@ -338,7 +338,9 @@ Print::object_extruders() const
|
|||||||
if ((*region)->config.fill_density.value > 0)
|
if ((*region)->config.fill_density.value > 0)
|
||||||
extruders.insert((*region)->config.infill_extruder - 1);
|
extruders.insert((*region)->config.infill_extruder - 1);
|
||||||
|
|
||||||
if ((*region)->config.top_solid_layers.value > 0 || (*region)->config.bottom_solid_layers.value > 0)
|
if ((*region)->config.top_solid_layers.value > 0
|
||||||
|
|| (*region)->config.bottom_solid_layers.value > 0
|
||||||
|
|| (*region)->config.min_top_bottom_shell_thickness.value > 0)
|
||||||
extruders.insert((*region)->config.solid_infill_extruder - 1);
|
extruders.insert((*region)->config.solid_infill_extruder - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -837,6 +837,15 @@ PrintConfigDef::PrintConfigDef()
|
|||||||
def->min = 0;
|
def->min = 0;
|
||||||
def->default_value = new ConfigOptionFloat(0);
|
def->default_value = new ConfigOptionFloat(0);
|
||||||
|
|
||||||
|
def = this->add("min_top_bottom_shell_thickness", coFloat);
|
||||||
|
def->label = "Minimum shell thickness";
|
||||||
|
def->category = "Layers and Perimeters";
|
||||||
|
def->sidetext = "mm";
|
||||||
|
def->tooltip = "Alternative method of configuring top/bottom layers. If this is above 0 extra solid layers will be generated when necessary";
|
||||||
|
def->cli = "min-vertical-shell-thickness=f";
|
||||||
|
def->min = 0;
|
||||||
|
def->default_value = new ConfigOptionFloat(0);
|
||||||
|
|
||||||
def = this->add("min_layer_height", coFloats);
|
def = this->add("min_layer_height", coFloats);
|
||||||
def->label = "Min";
|
def->label = "Min";
|
||||||
def->tooltip = "This is the lowest printable layer height for this extruder and limits the resolution for adaptive slicing. Typical values are 0.1 or 0.05.";
|
def->tooltip = "This is the lowest printable layer height for this extruder and limits the resolution for adaptive slicing. Typical values are 0.1 or 0.05.";
|
||||||
|
@ -256,6 +256,7 @@ class PrintRegionConfig : public virtual StaticPrintConfig
|
|||||||
ConfigOptionFloatOrPercent infill_overlap;
|
ConfigOptionFloatOrPercent infill_overlap;
|
||||||
ConfigOptionFloat infill_speed;
|
ConfigOptionFloat infill_speed;
|
||||||
ConfigOptionFloat min_shell_thickness;
|
ConfigOptionFloat min_shell_thickness;
|
||||||
|
ConfigOptionFloat min_top_bottom_shell_thickness;
|
||||||
ConfigOptionBool overhangs;
|
ConfigOptionBool overhangs;
|
||||||
ConfigOptionInt perimeter_extruder;
|
ConfigOptionInt perimeter_extruder;
|
||||||
ConfigOptionFloatOrPercent perimeter_extrusion_width;
|
ConfigOptionFloatOrPercent perimeter_extrusion_width;
|
||||||
@ -314,7 +315,8 @@ class PrintRegionConfig : public virtual StaticPrintConfig
|
|||||||
OPT_PTR(top_infill_pattern);
|
OPT_PTR(top_infill_pattern);
|
||||||
OPT_PTR(top_solid_infill_speed);
|
OPT_PTR(top_solid_infill_speed);
|
||||||
OPT_PTR(top_solid_layers);
|
OPT_PTR(top_solid_layers);
|
||||||
|
OPT_PTR(min_top_bottom_shell_thickness);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -99,6 +99,7 @@ PrintRegion::invalidate_state_by_config(const PrintConfigBase &config)
|
|||||||
|| opt_key == "solid_infill_every_layers"
|
|| opt_key == "solid_infill_every_layers"
|
||||||
|| opt_key == "bottom_solid_layers"
|
|| opt_key == "bottom_solid_layers"
|
||||||
|| opt_key == "top_solid_layers"
|
|| opt_key == "top_solid_layers"
|
||||||
|
|| opt_key == "min_top_bottom_shell_thickness"
|
||||||
|| opt_key == "min_shell_thickness"
|
|| opt_key == "min_shell_thickness"
|
||||||
|| opt_key == "infill_extruder"
|
|| opt_key == "infill_extruder"
|
||||||
|| opt_key == "solid_infill_extruder"
|
|| opt_key == "solid_infill_extruder"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user