Merge pull request #3525 from lordofhyphens/infill-over-plate

A new feature "support_material_buildplate_only" implemented.
This commit is contained in:
Alessandro Ranellucci 2017-03-26 23:38:32 +02:00 committed by GitHub
commit c347487de5
6 changed files with 66 additions and 11 deletions

View File

@ -428,7 +428,7 @@ sub options {
raft_layers raft_layers
support_material_pattern support_material_spacing support_material_angle support_material_pattern support_material_spacing support_material_angle
support_material_interface_layers support_material_interface_spacing support_material_interface_layers support_material_interface_spacing
support_material_contact_distance dont_support_bridges support_material_contact_distance support_material_buildplate_only dont_support_bridges
notes notes
complete_objects extruder_clearance_radius extruder_clearance_height complete_objects extruder_clearance_radius extruder_clearance_height
gcode_comments output_filename_format gcode_comments output_filename_format
@ -578,6 +578,7 @@ sub build {
$optgroup->append_single_option_line('support_material_angle'); $optgroup->append_single_option_line('support_material_angle');
$optgroup->append_single_option_line('support_material_interface_layers'); $optgroup->append_single_option_line('support_material_interface_layers');
$optgroup->append_single_option_line('support_material_interface_spacing'); $optgroup->append_single_option_line('support_material_interface_spacing');
$optgroup->append_single_option_line('support_material_buildplate_only');
$optgroup->append_single_option_line('dont_support_bridges'); $optgroup->append_single_option_line('dont_support_bridges');
} }
} }

View File

@ -1,3 +1,5 @@
# Instantiated by Slic3r::Print::Object->_support_material()
# only generate() and contact_distance() are called from the outside of this module.
package Slic3r::Print::SupportMaterial; package Slic3r::Print::SupportMaterial;
use Moo; use Moo;
@ -25,6 +27,7 @@ use constant PILLAR_SIZE => 2.5;
use constant PILLAR_SPACING => 10; use constant PILLAR_SPACING => 10;
sub generate { sub generate {
# $object is Slic3r::Print::Object
my ($self, $object) = @_; my ($self, $object) = @_;
# Determine the top surfaces of the support, defined as: # Determine the top surfaces of the support, defined as:
@ -88,6 +91,7 @@ sub generate {
} }
sub contact_area { sub contact_area {
# $object is Slic3r::Print::Object
my ($self, $object) = @_; my ($self, $object) = @_;
# if user specified a custom angle threshold, convert it to radians # if user specified a custom angle threshold, convert it to radians
@ -97,6 +101,12 @@ sub contact_area {
Slic3r::debugf "Threshold angle = %d°\n", rad2deg($threshold_rad); 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_top_surfaces = [];
# determine contact areas # determine contact areas
my %contact = (); # contact_z => [ polygons ] my %contact = (); # contact_z => [ polygons ]
my %overhang = (); # contact_z => [ polygons ] - this stores the actual overhang supported by each contact layer my %overhang = (); # contact_z => [ polygons ] - this stores the actual overhang supported by each contact layer
@ -114,6 +124,21 @@ sub contact_area {
} }
my $layer = $object->get_layer($layer_id); my $layer = $object->get_layer($layer_id);
if ($buildplate_only) {
# Collect the top surfaces up to this layer and merge them.
my $projection_new = [];
push @$projection_new, ( map $_->p, map @{$_->slices->filter_by_type(S_TYPE_TOP)}, @{$layer->regions} );
if (@$projection_new) {
# Merge the new top surfaces with the preceding top surfaces.
# Apply the safety offset to the newly added polygons, so they will connect
# with the polygons collected before,
# but don't apply the safety offset during the union operation as it would
# inflate the polygons over and over.
push @$buildplate_only_top_surfaces, @{ offset($projection_new, scale(0.01)) };
$buildplate_only_top_surfaces = union($buildplate_only_top_surfaces, 0);
}
}
# detect overhangs and contact areas needed to support them # detect overhangs and contact areas needed to support them
my (@overhang, @contact) = (); my (@overhang, @contact) = ();
if ($layer_id == 0) { if ($layer_id == 0) {
@ -239,6 +264,12 @@ sub contact_area {
1, 1,
); );
} }
} # if ($self->object_config->dont_support_bridges)
if ($buildplate_only) {
# Don't support overhangs above the top surfaces.
# This step is done before the contact surface is calcuated by growing the overhang region.
$diff = diff($diff, $buildplate_only_top_surfaces);
} }
next if !@$diff; next if !@$diff;
@ -249,11 +280,16 @@ sub contact_area {
# We increment the area in steps because we don't want our support to overflow # We increment the area in steps because we don't want our support to overflow
# on the other side of the object (if it's very thin). # on the other side of the object (if it's very thin).
{ {
my @slices_margin = @{offset([ map @$_, @{$lower_layer->slices} ], +$fw/2)}; my $slices_margin = offset([ map @$_, @{$lower_layer->slices} ], +$fw/2);
if ($buildplate_only) {
# Trim the inflated contact surfaces by the top surfaces as well.
push @$slices_margin, map $_->clone, @{$buildplate_only_top_surfaces};
$slices_margin = union($slices_margin);
}
for ($fw/2, map {scale MARGIN_STEP} 1..(MARGIN / MARGIN_STEP)) { for ($fw/2, map {scale MARGIN_STEP} 1..(MARGIN / MARGIN_STEP)) {
$diff = diff( $diff = diff(
offset($diff, $_), offset($diff, $_),
\@slices_margin, $slices_margin,
); );
} }
} }
@ -280,9 +316,10 @@ sub contact_area {
if (0) { if (0) {
require "Slic3r/SVG.pm"; require "Slic3r/SVG.pm";
Slic3r::SVG::output("contact_" . $contact_z . ".svg", Slic3r::SVG::output("out\\contact_" . $contact_z . ".svg",
expolygons => union_ex(\@contact), green_expolygons => union_ex($buildplate_only_top_surfaces),
red_expolygons => union_ex(\@overhang), blue_expolygons => union_ex(\@contact),
red_expolygons => union_ex(\@overhang),
); );
} }
} }
@ -297,6 +334,8 @@ sub object_top {
# find object top surfaces # find object top surfaces
# we'll use them to clip our support and detect where does it stick # we'll use them to clip our support and detect where does it stick
my %top = (); # print_z => [ expolygons ] my %top = (); # print_z => [ expolygons ]
return \%top if ($self->object_config->support_material_buildplate_only);
my $projection = []; my $projection = [];
foreach my $layer (reverse @{$object->layers}) { foreach my $layer (reverse @{$object->layers}) {
if (my @top = map @{$_->slices->filter_by_type(S_TYPE_TOP)}, @{$layer->regions}) { if (my @top = map @{$_->slices->filter_by_type(S_TYPE_TOP)}, @{$layer->regions}) {
@ -430,6 +469,9 @@ sub generate_interface_layers {
sub generate_bottom_interface_layers { sub generate_bottom_interface_layers {
my ($self, $support_z, $base, $top, $interface) = @_; my ($self, $support_z, $base, $top, $interface) = @_;
# If no interface layers are allowed, don't generate bottom interface layers.
return if $self->object_config->support_material_interface_layers == 0;
my $area_threshold = $self->interface_flow->scaled_spacing ** 2; my $area_threshold = $self->interface_flow->scaled_spacing ** 2;
# loop through object's top surfaces # loop through object's top surfaces

View File

@ -486,6 +486,8 @@ $j
--support-material-enforce-layers --support-material-enforce-layers
Enforce support material on the specified number of layers from bottom, Enforce support material on the specified number of layers from bottom,
regardless of --support-material and threshold (0+, default: $config->{support_material_enforce_layers}) regardless of --support-material and threshold (0+, default: $config->{support_material_enforce_layers})
--support-material-buildplate-only
Only create support if it lies on a build plate. Don't create support on a print. (default: no)
--dont-support-bridges --dont-support-bridges
Experimental option for preventing support material from being generated under bridged areas (default: yes) Experimental option for preventing support material from being generated under bridged areas (default: yes)

View File

@ -1282,6 +1282,13 @@ PrintConfigDef::PrintConfigDef()
def->max = 359; def->max = 359;
def->default_value = new ConfigOptionInt(0); def->default_value = new ConfigOptionInt(0);
def = this->add("support_material_buildplate_only", coBool);
def->label = "Support on build plate only";
def->category = "Support material";
def->tooltip = "Only create support if it lies on a build plate. Don't create support on a print.";
def->cli = "support-material-buildplate-only!";
def->default_value = new ConfigOptionBool(false);
def = this->add("support_material_contact_distance", coFloat); def = this->add("support_material_contact_distance", coFloat);
def->gui_type = "f_enum_open"; def->gui_type = "f_enum_open";
def->label = "Contact Z distance"; def->label = "Contact Z distance";

View File

@ -153,6 +153,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig
ConfigOptionEnum<SeamPosition> seam_position; ConfigOptionEnum<SeamPosition> seam_position;
ConfigOptionBool support_material; ConfigOptionBool support_material;
ConfigOptionInt support_material_angle; ConfigOptionInt support_material_angle;
ConfigOptionBool support_material_buildplate_only;
ConfigOptionFloat support_material_contact_distance; ConfigOptionFloat support_material_contact_distance;
ConfigOptionInt support_material_enforce_layers; ConfigOptionInt support_material_enforce_layers;
ConfigOptionInt support_material_extruder; ConfigOptionInt support_material_extruder;
@ -183,6 +184,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig
OPT_PTR(seam_position); OPT_PTR(seam_position);
OPT_PTR(support_material); OPT_PTR(support_material);
OPT_PTR(support_material_angle); OPT_PTR(support_material_angle);
OPT_PTR(support_material_buildplate_only);
OPT_PTR(support_material_contact_distance); OPT_PTR(support_material_contact_distance);
OPT_PTR(support_material_enforce_layers); OPT_PTR(support_material_enforce_layers);
OPT_PTR(support_material_extruder); OPT_PTR(support_material_extruder);

View File

@ -240,6 +240,7 @@ PrintObject::invalidate_state_by_config_options(const std::vector<t_config_optio
|| *opt_key == "support_material_interface_extruder" || *opt_key == "support_material_interface_extruder"
|| *opt_key == "support_material_interface_spacing" || *opt_key == "support_material_interface_spacing"
|| *opt_key == "support_material_interface_speed" || *opt_key == "support_material_interface_speed"
|| *opt_key == "support_material_buildplate_only"
|| *opt_key == "support_material_pattern" || *opt_key == "support_material_pattern"
|| *opt_key == "support_material_spacing" || *opt_key == "support_material_spacing"
|| *opt_key == "support_material_threshold" || *opt_key == "support_material_threshold"