mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-31 15:11:57 +08:00
Merge pull request #3877 from jaggzh/jaggz--enforce-supports-logic
Addressed logic of enforced supports.
This commit is contained in:
commit
b69a52b105
@ -213,7 +213,11 @@ sub generate_support_material {
|
||||
|
||||
$self->clear_support_layers;
|
||||
|
||||
if ((!$self->config->support_material && $self->config->raft_layers == 0) || scalar(@{$self->layers}) < 2) {
|
||||
if ((!$self->config->support_material
|
||||
&& $self->config->raft_layers == 0
|
||||
&& $self->config->support_material_enforce_layers == 0)
|
||||
|| scalar(@{$self->layers}) < 2
|
||||
) {
|
||||
$self->set_step_done(STEP_SUPPORTMATERIAL);
|
||||
return;
|
||||
}
|
||||
|
@ -93,18 +93,21 @@ sub generate {
|
||||
sub contact_area {
|
||||
# $object is Slic3r::Print::Object
|
||||
my ($self, $object) = @_;
|
||||
my $conf = $self->object_config;
|
||||
|
||||
# if user specified a custom angle threshold, convert it to radians
|
||||
my $threshold_rad;
|
||||
if (!($self->object_config->support_material_threshold =~ /%$/)) {
|
||||
$threshold_rad = deg2rad($self->object_config->support_material_threshold + 1); # +1 makes the threshold inclusive
|
||||
if (!($conf->support_material_threshold =~ /%$/)) {
|
||||
$threshold_rad = deg2rad($conf->support_material_threshold + 1); # +1 makes the threshold inclusive
|
||||
Slic3r::debugf "Threshold angle = %d°\n", rad2deg($threshold_rad);
|
||||
}
|
||||
|
||||
# Build support on a build plate only? If so, then collect top surfaces into $buildplate_only_top_surfaces
|
||||
# and subtract $buildplate_only_top_surfaces from the contact surfaces, so
|
||||
# there is no contact surface supported by a top surface.
|
||||
my $buildplate_only = $self->object_config->support_material && $self->object_config->support_material_buildplate_only;
|
||||
my $buildplate_only =
|
||||
( $conf->support_material || $conf->support_material_enforce_layers)
|
||||
&& $conf->support_material_buildplate_only;
|
||||
my $buildplate_only_top_surfaces = [];
|
||||
|
||||
# determine contact areas
|
||||
@ -115,12 +118,19 @@ sub contact_area {
|
||||
# so $layer_id == 0 means first object layer
|
||||
# and $layer->id == 0 means first print layer (including raft)
|
||||
|
||||
if ($self->object_config->raft_layers == 0) {
|
||||
next if $layer_id == 0;
|
||||
} elsif (!$self->object_config->support_material) {
|
||||
# if no raft, and we're at layer 0, skip to layer 1
|
||||
if ( $conf->raft_layers == 0 && $layer_id == 0 ) {
|
||||
next;
|
||||
}
|
||||
# with or without raft, if we're above layer 1, we need to quit
|
||||
# support generation if supports are disabled, or if we're at a high
|
||||
# enough layer that enforce-supports no longer applies
|
||||
if ( $layer_id > 0
|
||||
&& !$conf->support_material
|
||||
&& ($layer_id >= $conf->support_material_enforce_layers) ) {
|
||||
# if we are only going to generate raft just check
|
||||
# the 'overhangs' of the first object layer
|
||||
last if $layer_id > 0;
|
||||
last;
|
||||
}
|
||||
my $layer = $object->get_layer($layer_id);
|
||||
|
||||
@ -154,12 +164,19 @@ sub contact_area {
|
||||
my $diff;
|
||||
|
||||
# If a threshold angle was specified, use a different logic for detecting overhangs.
|
||||
if (defined $threshold_rad
|
||||
|| $layer_id < $self->object_config->support_material_enforce_layers
|
||||
|| ($self->object_config->raft_layers > 0 && $layer_id == 0)) {
|
||||
my $d = defined $threshold_rad
|
||||
? scale $lower_layer->height * ((cos $threshold_rad) / (sin $threshold_rad))
|
||||
: 0;
|
||||
if (($conf->support_material && defined $threshold_rad)
|
||||
|| $layer_id <= $conf->support_material_enforce_layers
|
||||
|| ($conf->raft_layers > 0 && $layer_id == 0)) {
|
||||
my $d = 0;
|
||||
my $layer_threshold_rad = $threshold_rad;
|
||||
if ($layer_id <= $conf->support_material_enforce_layers) {
|
||||
# Use ~45 deg number for enforced supports if we are in auto
|
||||
$layer_threshold_rad = deg2rad(89);
|
||||
}
|
||||
if (defined $layer_threshold_rad) {
|
||||
$d = scale $lower_layer->height
|
||||
* ((cos $layer_threshold_rad) / (sin $layer_threshold_rad));
|
||||
}
|
||||
|
||||
$diff = diff(
|
||||
offset([ map $_->p, @{$layerm->slices} ], -$d),
|
||||
@ -177,7 +194,7 @@ sub contact_area {
|
||||
} else {
|
||||
$diff = diff(
|
||||
[ map $_->p, @{$layerm->slices} ],
|
||||
offset([ map @$_, @{$lower_layer->slices} ], +$self->object_config->get_abs_value_over('support_material_threshold', $fw)),
|
||||
offset([ map @$_, @{$lower_layer->slices} ], +$conf->get_abs_value_over('support_material_threshold', $fw)),
|
||||
);
|
||||
|
||||
# collapse very tiny spots
|
||||
@ -189,7 +206,7 @@ sub contact_area {
|
||||
# outside the lower slice boundary, thus no overhang
|
||||
}
|
||||
|
||||
if ($self->object_config->dont_support_bridges) {
|
||||
if ($conf->dont_support_bridges) {
|
||||
# compute the area of bridging perimeters
|
||||
# Note: this is duplicate code from GCode.pm, we need to refactor
|
||||
|
||||
@ -264,7 +281,7 @@ sub contact_area {
|
||||
1,
|
||||
);
|
||||
}
|
||||
} # if ($self->object_config->dont_support_bridges)
|
||||
} # if ($conf->dont_support_bridges)
|
||||
|
||||
if ($buildplate_only) {
|
||||
# Don't support overhangs above the top surfaces.
|
||||
@ -309,7 +326,7 @@ sub contact_area {
|
||||
my $contact_z = $layer->print_z - $self->contact_distance($layer->height, $nozzle_diameter);
|
||||
|
||||
# ignore this contact area if it's too low
|
||||
next if $contact_z < $self->object_config->get_value('first_layer_height') - epsilon;
|
||||
next if $contact_z < $conf->get_value('first_layer_height') - epsilon;
|
||||
|
||||
$contact{$contact_z} = [ @contact ];
|
||||
$overhang{$contact_z} = [ @overhang ];
|
||||
|
31
t/support.t
31
t/support.t
@ -1,4 +1,4 @@
|
||||
use Test::More tests => 27;
|
||||
use Test::More tests => 28;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
@ -258,5 +258,32 @@ use Slic3r::Test;
|
||||
@{ $layer_heights_by_tool{$config->support_material_extruder-1} }),
|
||||
'no support material layer is as thin as object layers';
|
||||
}
|
||||
|
||||
{
|
||||
my $config = Slic3r::Config->new_from_defaults;
|
||||
$config->set('support_material_enforce_layers', 100);
|
||||
$config->set('support_material', 0);
|
||||
my @contact_z = my @top_z = ();
|
||||
|
||||
my $test = sub {
|
||||
my $print = Slic3r::Test::init_print('20mm_cube', config => $config);
|
||||
my $flow = $print->print->objects->[0]->support_material_flow;
|
||||
my $support = Slic3r::Print::SupportMaterial->new(
|
||||
object_config => $print->print->objects->[0]->config,
|
||||
print_config => $print->print->config,
|
||||
flow => $flow,
|
||||
interface_flow => $flow,
|
||||
first_layer_flow => $flow,
|
||||
);
|
||||
my $support_z = $support->support_layers_z(\@contact_z, \@top_z, $config->layer_height);
|
||||
|
||||
is scalar(grep { $support_z->[$_]-$support_z->[$_-1] <= 0 } 1..$#$support_z), 0,
|
||||
'forced support is generated';
|
||||
|
||||
};
|
||||
$config->set('layer_height', 0.2);
|
||||
$config->set('first_layer_height', 0.3);
|
||||
@contact_z = (1.9);
|
||||
@top_z = (1.1);
|
||||
$test->();
|
||||
}
|
||||
__END__
|
||||
|
Loading…
x
Reference in New Issue
Block a user