A new feature "support_material_buildplate_only" implemented.
Also a bug has been fixed for zero interface layers. Before slic3r would put infinite number of interface layers over top surfaces, if the number of interface layers was set to zero.
This commit is contained in:
parent
ae2bae137a
commit
5bb37ad2c4
@ -124,7 +124,7 @@ sub build {
|
||||
layer_height perimeters top_solid_layers bottom_solid_layers
|
||||
fill_density fill_pattern external_fill_pattern
|
||||
support_material support_material_spacing raft_layers
|
||||
support_material_contact_distance dont_support_bridges
|
||||
support_material_contact_distance support_material_buildplate_only dont_support_bridges
|
||||
perimeter_speed infill_speed travel_speed
|
||||
brim_width
|
||||
xy_size_compensation
|
||||
@ -155,6 +155,7 @@ sub build {
|
||||
$optgroup->append_single_option_line('support_material');
|
||||
$optgroup->append_single_option_line('support_material_spacing');
|
||||
$optgroup->append_single_option_line('support_material_contact_distance');
|
||||
$optgroup->append_single_option_line('support_material_buildplate_only');
|
||||
$optgroup->append_single_option_line('dont_support_bridges');
|
||||
$optgroup->append_single_option_line('raft_layers');
|
||||
}
|
||||
|
@ -482,7 +482,7 @@ sub build {
|
||||
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
|
||||
@ -592,6 +592,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');
|
||||
}
|
||||
}
|
||||
|
@ -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:
|
||||
@ -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
|
||||
@ -114,6 +124,21 @@ sub contact_area {
|
||||
}
|
||||
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,6 +264,12 @@ 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;
|
||||
@ -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,8 +316,9 @@ sub contact_area {
|
||||
|
||||
if (0) {
|
||||
require "Slic3r/SVG.pm";
|
||||
Slic3r::SVG::output("contact_" . $contact_z . ".svg",
|
||||
expolygons => union_ex(\@contact),
|
||||
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),
|
||||
);
|
||||
}
|
||||
@ -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}) {
|
||||
@ -430,6 +469,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;
|
||||
|
||||
# loop through object's top surfaces
|
||||
|
@ -432,6 +432,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)
|
||||
|
||||
|
@ -1092,6 +1092,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";
|
||||
|
@ -145,6 +145,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig
|
||||
// ConfigOptionFloat seam_preferred_direction_jitter;
|
||||
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;
|
||||
@ -177,6 +178,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig
|
||||
// OPT_PTR(seam_preferred_direction_jitter);
|
||||
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);
|
||||
|
@ -236,6 +236,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"
|
||||
|
Loading…
Reference in New Issue
Block a user