mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-12 02:29:03 +08:00
Merge pull request #3525 from lordofhyphens/infill-over-plate
A new feature "support_material_buildplate_only" implemented.
This commit is contained in:
commit
c347487de5
@ -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');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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";
|
||||||
|
@ -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);
|
||||||
|
@ -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"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user