Skip to content

Commit

Permalink
Addressed logic of enforced supports. There are inconsistent rare cra…
Browse files Browse the repository at this point in the history
…shes which I cannot find as related to my changes.
  • Loading branch information
jaggzh committed Apr 13, 2017
1 parent 5c2a05c commit 3164217
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 18 deletions.
6 changes: 5 additions & 1 deletion lib/Slic3r/Print/Object.pm
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,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;
}
Expand Down
51 changes: 34 additions & 17 deletions lib/Slic3r/Print/SupportMaterial.pm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);

Expand Down Expand Up @@ -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(75);
}
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),
Expand All @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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 ];
Expand Down

0 comments on commit 3164217

Please sign in to comment.