mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-30 20:22:02 +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
|
||||
has 'mesh' => (is => 'ro', required => 1);
|
||||
has 'size' => (is => 'ro', required => 1);
|
||||
|
||||
#private
|
||||
has 'normal_z' => (is => 'ro', default => sub { [] }); # facet_id => [normal];
|
||||
@ -158,5 +159,37 @@ sub _facet_cusp_height {
|
||||
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;
|
@ -455,7 +455,7 @@ sub build {
|
||||
my $self = shift;
|
||||
|
||||
$self->init_config_options(qw(
|
||||
adaptive_slicing cusp_value
|
||||
adaptive_slicing cusp_value match_horizontal_surfaces
|
||||
layer_height first_layer_height
|
||||
perimeters spiral_vase
|
||||
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('adaptive_slicing');
|
||||
$optgroup->append_single_option_line('cusp_value');
|
||||
$optgroup->append_single_option_line('match_horizontal_surfaces');
|
||||
}
|
||||
{
|
||||
my $optgroup = $page->new_optgroup('Vertical shells');
|
||||
@ -787,7 +788,7 @@ sub _update {
|
||||
|
||||
my $have_adaptive_slicing = $config->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)
|
||||
for qw(layer_height);
|
||||
|
||||
|
@ -108,7 +108,8 @@ sub slice {
|
||||
}
|
||||
|
||||
$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)) {
|
||||
# get cusp 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)
|
||||
? $self->config->get_value('first_layer_height')
|
||||
|
@ -46,7 +46,8 @@ my $test = sub {
|
||||
my $print = Slic3r::Test::init_print('slopy_cube', config => $config);
|
||||
$print->models->[0]->mesh->repair();
|
||||
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->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->label = "Max";
|
||||
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->sidetext = "mm";
|
||||
def->cli = "max-layer-height=f@";
|
||||
//def->min = 0;
|
||||
def->min = 0;
|
||||
{
|
||||
ConfigOptionFloats* opt = new ConfigOptionFloats();
|
||||
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->sidetext = "mm";
|
||||
def->cli = "min-layer-height=f@";
|
||||
//def->min = 0;
|
||||
def->min = 0;
|
||||
{
|
||||
ConfigOptionFloats* opt = new ConfigOptionFloats();
|
||||
opt->values.push_back(0.15);
|
||||
|
@ -110,6 +110,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig
|
||||
ConfigOptionBool infill_only_where_needed;
|
||||
ConfigOptionBool interface_shells;
|
||||
ConfigOptionFloat layer_height;
|
||||
ConfigOptionBool match_horizontal_surfaces;
|
||||
ConfigOptionInt raft_layers;
|
||||
ConfigOptionEnum<SeamPosition> seam_position;
|
||||
ConfigOptionBool support_material;
|
||||
@ -141,6 +142,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig
|
||||
OPT_PTR(infill_only_where_needed);
|
||||
OPT_PTR(interface_shells);
|
||||
OPT_PTR(layer_height);
|
||||
OPT_PTR(match_horizontal_surfaces);
|
||||
OPT_PTR(raft_layers);
|
||||
OPT_PTR(seam_position);
|
||||
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 == "adaptive_slicing"
|
||||
|| *opt_key == "cusp_value"
|
||||
|| *opt_key == "match_horizontal_surfaces"
|
||||
|| *opt_key == "raft_layers") {
|
||||
steps.insert(posSlice);
|
||||
} else if (*opt_key == "support_material"
|
||||
|
Loading…
x
Reference in New Issue
Block a user