From 8efe46e58de31bd505292d4b4b9a319c8c4d3faf Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Mon, 4 Feb 2013 15:48:57 +0100 Subject: [PATCH] New option to enforce support material on a given number of layers to improve adhesion of objects with poor footprint --- README.markdown | 3 +++ lib/Slic3r/Config.pm | 8 ++++++++ lib/Slic3r/GUI/Tab.pm | 2 +- lib/Slic3r/Print.pm | 16 ++++++++++++---- lib/Slic3r/Print/Object.pm | 13 +++++++++---- slic3r.pl | 3 +++ 6 files changed, 36 insertions(+), 9 deletions(-) diff --git a/README.markdown b/README.markdown index 8a54b2fae..21498b0f5 100644 --- a/README.markdown +++ b/README.markdown @@ -214,6 +214,9 @@ The author of the Silk icon set is Mark James. --support-material-interface-spacing Spacing between interface pattern lines (mm, set 0 to get a solid layer, default: 0) --raft-layers Number of layers to raise the printed objects by (range: 0+, default: 0) + --support-material-enforce-layers + Enforce support material on the specified number of layers from bottom, + regardless of --support-material and threshold (0+, default: 0) Retraction options: --retract-length Length of retraction in mm when pausing extrusion (default: 1) diff --git a/lib/Slic3r/Config.pm b/lib/Slic3r/Config.pm index 7247d1894..f693ba00c 100644 --- a/lib/Slic3r/Config.pm +++ b/lib/Slic3r/Config.pm @@ -594,6 +594,14 @@ our $Options = { type => 'f', default => 0, }, + 'support_material_enforce_layers' => { + label => 'Enforce support for the first', + tooltip => 'Generate support material for the specified number of layers counting from bottom, regardless of whether normal support material is enabled or not and regardless of any angle threshold. This is useful for getting more adhesion of objects having a very thin or poor footprint on the build plate.', + sidetext => 'layers', + cli => 'support-material-enforce-layers=f', + type => 'i', + default => 0, + }, 'raft_layers' => { label => 'Raft layers', tooltip => 'Number of total raft layers to insert below the object(s).', diff --git a/lib/Slic3r/GUI/Tab.pm b/lib/Slic3r/GUI/Tab.pm index aee600f88..c9b292b72 100644 --- a/lib/Slic3r/GUI/Tab.pm +++ b/lib/Slic3r/GUI/Tab.pm @@ -454,7 +454,7 @@ sub build { $self->add_options_page('Support material', 'building.png', optgroups => [ { title => 'Support material', - options => [qw(support_material support_material_threshold)], + options => [qw(support_material support_material_threshold support_material_enforce_layers)], }, { title => 'Raft', diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index 2c5f2acbe..5cb6b4233 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -19,6 +19,7 @@ has 'extruders' => (is => 'rw', default => sub {[]}); has 'regions' => (is => 'rw', default => sub {[]}); has 'support_material_flow' => (is => 'rw'); has 'first_layer_support_material_flow' => (is => 'rw'); +has 'has_support_material' => (is => 'lazy'); # ordered collection of extrusion paths to build skirt loops has 'skirt' => ( @@ -62,6 +63,13 @@ sub _trigger_config { $self->config->set('extrusion_axis', '') if $self->config->gcode_flavor eq 'no-extrusion'; } +sub _build_has_support_material { + my $self = shift; + return $self->config->support_material + || $self->config->raft_layers > 0 + || $self->config->support_material_enforce_layers > 0; +} + sub add_model { my $self = shift; my ($model) = @_; @@ -216,7 +224,7 @@ sub init_extruders { } # calculate support material flow - if ($self->config->support_material || $self->config->raft_layers > 0) { + if ($self->has_support_material) { my $extruder = $self->extruders->[$self->config->support_material_extruder-1]; $self->support_material_flow($extruder->make_flow( width => $self->config->support_material_extrusion_width || $self->config->extrusion_width, @@ -413,7 +421,7 @@ sub export_gcode { } # generate support material - if ($Slic3r::Config->support_material || $Slic3r::Config->raft_layers > 0) { + if ($self->has_support_material) { $status_cb->(85, "Generating support material"); $_->generate_support_material for @{$self->objects}; } @@ -510,7 +518,7 @@ EOF } } # generate support material - if (($Slic3r::Config->support_material || $self->config->raft_layers > 0) && $layer_id > 0) { + if ($self->has_support_material && $layer_id > 0) { my (@supported_slices, @unsupported_slices) = (); foreach my $expolygon (@current_layer_slices) { my $intersection = intersection_ex( @@ -801,7 +809,7 @@ sub write_gcode { # extrude support material before other things because it might use a lower Z # and also because we avoid travelling on other things when printing it - if ($Slic3r::Config->support_material || $self->config->raft_layers > 0) { + if ($self->has_support_material) { $gcode .= $gcodegen->move_z($layer->support_material_contact_z) if ($layer->support_contact_fills && @{ $layer->support_contact_fills->paths }); $gcode .= $gcodegen->set_extruder($self->extruders->[$Slic3r::Config->support_material_extruder-1]); diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index edac073d1..e57620a87 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -593,7 +593,9 @@ sub generate_support_material { my @current_support_regions = (); # expolygons we've started to support (i.e. below the empty interface layers) my @upper_layers_overhangs = (map [], 1..$Slic3r::Config->support_material_interface_layers); for my $i (reverse 0 .. $#{$self->layers}) { - next unless $Slic3r::Config->support_material || ($i <= $Slic3r::Config->raft_layers); # <= because we need to start from the first non-raft layer + next unless $Slic3r::Config->support_material + || ($i <= $Slic3r::Config->raft_layers) # <= because we need to start from the first non-raft layer + || ($i <= $Slic3r::Config->support_material_enforce_layers + $Slic3r::Config->raft_layers); my $layer = $self->layers->[$i]; my $lower_layer = $i > 0 ? $self->layers->[$i-1] : undef; @@ -635,7 +637,6 @@ sub generate_support_material { [ map @$_, @current_support_regions ], [ (map @$_, @current_layer_offsetted_slices), - (map @$_, @{ $layers_contact_areas{$i} }), (map @$_, @{ $layers_interfaces{$i} }), ], ); @@ -645,6 +646,10 @@ sub generate_support_material { # we need an angle threshold for this my @overhangs = (); if ($lower_layer) { + # consider all overhangs regardless of their angle if we're told to enforce support on this layer + my $distance = $i <= ($Slic3r::Config->support_material_enforce_layers + $Slic3r::Config->raft_layers) + ? 0 + : $overhang_width; @overhangs = map $_->offset_ex(2 * $overhang_width), @{diff_ex( [ map @$_, map $_->offset_ex(-$overhang_width), @{$layer->slices} ], [ map @$_, @{$lower_layer->slices} ], @@ -654,8 +659,8 @@ sub generate_support_material { push @upper_layers_overhangs, [@overhangs]; if ($Slic3r::debug) { - printf "Layer %d has %d generic support areas, %d normal interface areas, %d contact areas\n", - $i, scalar(@{$layers{$i}}), scalar(@{$layers_interfaces{$i}}), scalar(@{$layers_contact_areas{$i}}); + printf "Layer %d (z = %.2f) has %d generic support areas, %d normal interface areas, %d contact areas\n", + $i, unscale($layer->print_z), scalar(@{$layers{$i}}), scalar(@{$layers_interfaces{$i}}), scalar(@{$layers_contact_areas{$i}}); } } } diff --git a/slic3r.pl b/slic3r.pl index fcd33eccd..04aa1be9e 100755 --- a/slic3r.pl +++ b/slic3r.pl @@ -262,6 +262,9 @@ $j --support-material-interface-spacing Spacing between interface pattern lines (mm, set 0 to get a solid layer, default: $config->{support_material_interface_spacing}) --raft-layers Number of layers to raise the printed objects by (range: 0+, default: $config->{raft_layers}) + --support-material-enforce-layers + Enforce support material on the specified number of layers from bottom, + regardless of --support-material and threshold (0+, default: $config->{support_material_enforce_layers}) Retraction options: --retract-length Length of retraction in mm when pausing extrusion (default: $config->{retract_length}[0])