mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-31 19:41:58 +08:00
Feature: try to match horizontal surfaces with adaptive slicing
This commit is contained in:
parent
8485e4bea2
commit
5bb1ffba0d
@ -6,6 +6,7 @@ use Slic3r::Geometry qw(X Y Z triangle_normal scale unscale);
|
|||||||
|
|
||||||
# public
|
# public
|
||||||
has 'mesh' => (is => 'ro', required => 1);
|
has 'mesh' => (is => 'ro', required => 1);
|
||||||
|
has 'size' => (is => 'ro', required => 1);
|
||||||
|
|
||||||
#private
|
#private
|
||||||
has 'normal_z' => (is => 'ro', default => sub { [] }); # facet_id => [normal];
|
has 'normal_z' => (is => 'ro', default => sub { [] }); # facet_id => [normal];
|
||||||
@ -158,5 +159,37 @@ sub _facet_cusp_height {
|
|||||||
return $cusp;
|
return $cusp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Returns the distance to the next horizontal facet in Z-dir
|
||||||
|
# to consider horizontal object features in slice thickness
|
||||||
|
sub horizontal_facet_distance {
|
||||||
|
my $self = shift;
|
||||||
|
my ($z, $max_height) = @_;
|
||||||
|
$max_height = scale $max_height;
|
||||||
|
|
||||||
|
my $ordered_id = $self->current_facet;
|
||||||
|
while ($ordered_id <= $#{$self->ordered_facets}) {
|
||||||
|
|
||||||
|
# facet's minimum is higher than max forward distance -> end loop
|
||||||
|
if($self->ordered_facets->[$ordered_id]->[1] > $z+$max_height) {
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
|
||||||
|
# min_z == max_z -> horizontal facet
|
||||||
|
if($self->ordered_facets->[$ordered_id]->[1] > $z) {
|
||||||
|
if($self->ordered_facets->[$ordered_id]->[1] == $self->ordered_facets->[$ordered_id]->[2]) {
|
||||||
|
return unscale $self->ordered_facets->[$ordered_id]->[1] - $z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$ordered_id++;
|
||||||
|
}
|
||||||
|
|
||||||
|
# objects maximum?
|
||||||
|
if($z + $max_height > $self->size) {
|
||||||
|
return max(unscale $self->size - $z, 0);
|
||||||
|
}
|
||||||
|
return unscale $max_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
1;
|
1;
|
@ -455,7 +455,7 @@ sub build {
|
|||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
$self->init_config_options(qw(
|
$self->init_config_options(qw(
|
||||||
adaptive_slicing cusp_value
|
adaptive_slicing cusp_value match_horizontal_surfaces
|
||||||
layer_height first_layer_height
|
layer_height first_layer_height
|
||||||
perimeters spiral_vase
|
perimeters spiral_vase
|
||||||
top_solid_layers bottom_solid_layers
|
top_solid_layers bottom_solid_layers
|
||||||
@ -504,6 +504,7 @@ sub build {
|
|||||||
$optgroup->append_single_option_line('first_layer_height');
|
$optgroup->append_single_option_line('first_layer_height');
|
||||||
$optgroup->append_single_option_line('adaptive_slicing');
|
$optgroup->append_single_option_line('adaptive_slicing');
|
||||||
$optgroup->append_single_option_line('cusp_value');
|
$optgroup->append_single_option_line('cusp_value');
|
||||||
|
$optgroup->append_single_option_line('match_horizontal_surfaces');
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
my $optgroup = $page->new_optgroup('Vertical shells');
|
my $optgroup = $page->new_optgroup('Vertical shells');
|
||||||
@ -787,7 +788,7 @@ sub _update {
|
|||||||
|
|
||||||
my $have_adaptive_slicing = $config->adaptive_slicing;
|
my $have_adaptive_slicing = $config->adaptive_slicing;
|
||||||
$self->get_field($_)->toggle($have_adaptive_slicing)
|
$self->get_field($_)->toggle($have_adaptive_slicing)
|
||||||
for qw(cusp_value);
|
for qw(cusp_value match_horizontal_surfaces);
|
||||||
$self->get_field($_)->toggle(!$have_adaptive_slicing)
|
$self->get_field($_)->toggle(!$have_adaptive_slicing)
|
||||||
for qw(layer_height);
|
for qw(layer_height);
|
||||||
|
|
||||||
|
@ -108,7 +108,8 @@ sub slice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$adaptive_slicing[$region_id] = Slic3r::AdaptiveSlicing->new(
|
$adaptive_slicing[$region_id] = Slic3r::AdaptiveSlicing->new(
|
||||||
mesh => $mesh
|
mesh => $mesh,
|
||||||
|
size => $self->size->z
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,6 +137,24 @@ sub slice {
|
|||||||
for my $region_id (0 .. ($self->region_count - 1)) {
|
for my $region_id (0 .. ($self->region_count - 1)) {
|
||||||
# get cusp height
|
# get cusp height
|
||||||
my $cusp_height = $adaptive_slicing[$region_id]->cusp_height(scale $slice_z, $cusp_value, $min_height, $max_height);
|
my $cusp_height = $adaptive_slicing[$region_id]->cusp_height(scale $slice_z, $cusp_value, $min_height, $max_height);
|
||||||
|
|
||||||
|
# check for horizontal features and object size
|
||||||
|
if($self->config->get_value('match_horizontal_surfaces')) {
|
||||||
|
my $horizontal_dist = $adaptive_slicing[$region_id]->horizontal_facet_distance(scale $slice_z+$cusp_height, $min_height);
|
||||||
|
if(($horizontal_dist < $min_height) && ($horizontal_dist > 0)) {
|
||||||
|
Slic3r::debugf "Horizontal feature ahead, distance: %f\n", $horizontal_dist;
|
||||||
|
# can we shrink the current layer a bit?
|
||||||
|
if($cusp_height-($min_height-$horizontal_dist) > $min_height) {
|
||||||
|
# yes we can
|
||||||
|
$cusp_height = $cusp_height-($min_height-$horizontal_dist);
|
||||||
|
Slic3r::debugf "Shrink layer height to %f\n", $cusp_height;
|
||||||
|
}else{
|
||||||
|
# no, current layer would become too thin
|
||||||
|
$cusp_height = $cusp_height+$horizontal_dist;
|
||||||
|
Slic3r::debugf "Widen layer height to %f\n", $cusp_height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$height = ($id == 0)
|
$height = ($id == 0)
|
||||||
? $self->config->get_value('first_layer_height')
|
? $self->config->get_value('first_layer_height')
|
||||||
|
@ -46,7 +46,8 @@ my $test = sub {
|
|||||||
my $print = Slic3r::Test::init_print('slopy_cube', config => $config);
|
my $print = Slic3r::Test::init_print('slopy_cube', config => $config);
|
||||||
$print->models->[0]->mesh->repair();
|
$print->models->[0]->mesh->repair();
|
||||||
my $adaptive_slicing = Slic3r::AdaptiveSlicing->new(
|
my $adaptive_slicing = Slic3r::AdaptiveSlicing->new(
|
||||||
mesh => Slic3r::Test::mesh('slopy_cube')
|
mesh => Slic3r::Test::mesh('slopy_cube'),
|
||||||
|
size => 20
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -585,6 +585,12 @@ PrintConfigDef::PrintConfigDef()
|
|||||||
def->min = 0;
|
def->min = 0;
|
||||||
def->default_value = new ConfigOptionFloat(0.3);
|
def->default_value = new ConfigOptionFloat(0.3);
|
||||||
|
|
||||||
|
def = this->add("match_horizontal_surfaces", coBool);
|
||||||
|
def->label = "Match horizontal surfaces";
|
||||||
|
def->tooltip = "Try to match horizontal surfaces during the slicing process. Matching is not guaranteed, very small surfaces and multiple surfaces with low vertical distance might cause bad results.";
|
||||||
|
def->cli = "match-horizontal-surfaces!";
|
||||||
|
def->default_value = new ConfigOptionBool(true);
|
||||||
|
|
||||||
def = this->add("max_fan_speed", coInt);
|
def = this->add("max_fan_speed", coInt);
|
||||||
def->label = "Max";
|
def->label = "Max";
|
||||||
def->tooltip = "This setting represents the maximum speed of your fan.";
|
def->tooltip = "This setting represents the maximum speed of your fan.";
|
||||||
@ -599,7 +605,7 @@ PrintConfigDef::PrintConfigDef()
|
|||||||
def->tooltip = "This is the highest printable layer height for this extruder and limits the resolution for adaptive slicing. Typical values are slightly smaller than nozzle_diameter.";
|
def->tooltip = "This is the highest printable layer height for this extruder and limits the resolution for adaptive slicing. Typical values are slightly smaller than nozzle_diameter.";
|
||||||
def->sidetext = "mm";
|
def->sidetext = "mm";
|
||||||
def->cli = "max-layer-height=f@";
|
def->cli = "max-layer-height=f@";
|
||||||
//def->min = 0;
|
def->min = 0;
|
||||||
{
|
{
|
||||||
ConfigOptionFloats* opt = new ConfigOptionFloats();
|
ConfigOptionFloats* opt = new ConfigOptionFloats();
|
||||||
opt->values.push_back(0.3);
|
opt->values.push_back(0.3);
|
||||||
@ -636,7 +642,7 @@ PrintConfigDef::PrintConfigDef()
|
|||||||
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.";
|
||||||
def->sidetext = "mm";
|
def->sidetext = "mm";
|
||||||
def->cli = "min-layer-height=f@";
|
def->cli = "min-layer-height=f@";
|
||||||
//def->min = 0;
|
def->min = 0;
|
||||||
{
|
{
|
||||||
ConfigOptionFloats* opt = new ConfigOptionFloats();
|
ConfigOptionFloats* opt = new ConfigOptionFloats();
|
||||||
opt->values.push_back(0.15);
|
opt->values.push_back(0.15);
|
||||||
|
@ -110,6 +110,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig
|
|||||||
ConfigOptionBool infill_only_where_needed;
|
ConfigOptionBool infill_only_where_needed;
|
||||||
ConfigOptionBool interface_shells;
|
ConfigOptionBool interface_shells;
|
||||||
ConfigOptionFloat layer_height;
|
ConfigOptionFloat layer_height;
|
||||||
|
ConfigOptionBool match_horizontal_surfaces;
|
||||||
ConfigOptionInt raft_layers;
|
ConfigOptionInt raft_layers;
|
||||||
ConfigOptionEnum<SeamPosition> seam_position;
|
ConfigOptionEnum<SeamPosition> seam_position;
|
||||||
ConfigOptionBool support_material;
|
ConfigOptionBool support_material;
|
||||||
@ -141,6 +142,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig
|
|||||||
OPT_PTR(infill_only_where_needed);
|
OPT_PTR(infill_only_where_needed);
|
||||||
OPT_PTR(interface_shells);
|
OPT_PTR(interface_shells);
|
||||||
OPT_PTR(layer_height);
|
OPT_PTR(layer_height);
|
||||||
|
OPT_PTR(match_horizontal_surfaces);
|
||||||
OPT_PTR(raft_layers);
|
OPT_PTR(raft_layers);
|
||||||
OPT_PTR(seam_position);
|
OPT_PTR(seam_position);
|
||||||
OPT_PTR(support_material);
|
OPT_PTR(support_material);
|
||||||
|
@ -229,6 +229,7 @@ PrintObject::invalidate_state_by_config_options(const std::vector<t_config_optio
|
|||||||
|| *opt_key == "xy_size_compensation"
|
|| *opt_key == "xy_size_compensation"
|
||||||
|| *opt_key == "adaptive_slicing"
|
|| *opt_key == "adaptive_slicing"
|
||||||
|| *opt_key == "cusp_value"
|
|| *opt_key == "cusp_value"
|
||||||
|
|| *opt_key == "match_horizontal_surfaces"
|
||||||
|| *opt_key == "raft_layers") {
|
|| *opt_key == "raft_layers") {
|
||||||
steps.insert(posSlice);
|
steps.insert(posSlice);
|
||||||
} else if (*opt_key == "support_material"
|
} else if (*opt_key == "support_material"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user