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
support_material_pattern support_material_spacing support_material_angle
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
complete_objects extruder_clearance_radius extruder_clearance_height
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_interface_layers');
$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');
}
}

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;
use Moo;
@ -25,6 +27,7 @@ use constant PILLAR_SIZE => 2.5;
use constant PILLAR_SPACING => 10;
sub generate {
# $object is Slic3r::Print::Object
my ($self, $object) = @_;
# Determine the top surfaces of the support, defined as:
@ -38,7 +41,7 @@ sub generate {
# the layer heights of support material and to clip support to the object
# silhouette.
my ($top) = $self->object_top($object, $contact);
# We now know the upper and lower boundaries for our support material object
# (@$contact_z and @$top_z), so we can generate intermediate layers.
my $support_z = $self->support_layers_z(
@ -88,6 +91,7 @@ sub generate {
}
sub contact_area {
# $object is Slic3r::Print::Object
my ($self, $object) = @_;
# 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);
}
# 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
my %contact = (); # contact_z => [ polygons ]
my %overhang = (); # contact_z => [ polygons ] - this stores the actual overhang supported by each contact layer
@ -113,7 +123,22 @@ sub contact_area {
last if $layer_id > 0;
}
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
my (@overhang, @contact) = ();
if ($layer_id == 0) {
@ -239,8 +264,14 @@ sub contact_area {
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;
push @overhang, @$diff; # NOTE: this is not the full overhang as it misses the outermost half of the perimeter width!
@ -249,11 +280,16 @@ sub contact_area {
# 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).
{
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)) {
$diff = diff(
offset($diff, $_),
\@slices_margin,
$slices_margin,
);
}
}
@ -280,14 +316,15 @@ sub contact_area {
if (0) {
require "Slic3r/SVG.pm";
Slic3r::SVG::output("contact_" . $contact_z . ".svg",
expolygons => union_ex(\@contact),
red_expolygons => union_ex(\@overhang),
Slic3r::SVG::output("out\\contact_" . $contact_z . ".svg",
green_expolygons => union_ex($buildplate_only_top_surfaces),
blue_expolygons => union_ex(\@contact),
red_expolygons => union_ex(\@overhang),
);
}
}
}
return (\%contact, \%overhang);
}
@ -297,6 +334,8 @@ sub object_top {
# find object top surfaces
# we'll use them to clip our support and detect where does it stick
my %top = (); # print_z => [ expolygons ]
return \%top if ($self->object_config->support_material_buildplate_only);
my $projection = [];
foreach my $layer (reverse @{$object->layers}) {
if (my @top = map @{$_->slices->filter_by_type(S_TYPE_TOP)}, @{$layer->regions}) {
@ -429,6 +468,9 @@ sub generate_interface_layers {
sub generate_bottom_interface_layers {
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;
@ -722,7 +764,7 @@ sub generate_toolpaths {
width => $_interface_flow->width,
height => $layer->height,
), @$p;
}
}
$layer->support_interface_fills->append(@paths);
}

View File

@ -486,6 +486,8 @@ $j
--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})
--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
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->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->gui_type = "f_enum_open";
def->label = "Contact Z distance";

View File

@ -153,6 +153,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig
ConfigOptionEnum<SeamPosition> seam_position;
ConfigOptionBool support_material;
ConfigOptionInt support_material_angle;
ConfigOptionBool support_material_buildplate_only;
ConfigOptionFloat support_material_contact_distance;
ConfigOptionInt support_material_enforce_layers;
ConfigOptionInt support_material_extruder;
@ -183,6 +184,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig
OPT_PTR(seam_position);
OPT_PTR(support_material);
OPT_PTR(support_material_angle);
OPT_PTR(support_material_buildplate_only);
OPT_PTR(support_material_contact_distance);
OPT_PTR(support_material_enforce_layers);
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_spacing"
|| *opt_key == "support_material_interface_speed"
|| *opt_key == "support_material_buildplate_only"
|| *opt_key == "support_material_pattern"
|| *opt_key == "support_material_spacing"
|| *opt_key == "support_material_threshold"