Don't put supports under bridges and potential bridges
This commit is contained in:
parent
129b6651f6
commit
ce9cf4d964
@ -257,6 +257,8 @@ The author of the Silk icon set is Mark James.
|
||||
--support-material-enforce-layers
|
||||
Enforce support material on the specified number of layers from bottom,
|
||||
regardless of --support-material and threshold (0+, default: 0)
|
||||
--dont-support-bridges
|
||||
Experimental option for preventing support material from being generated under bridged areas (default: yes)
|
||||
|
||||
Retraction options:
|
||||
--retract-length Length of retraction in mm when pausing extrusion (default: 1)
|
||||
|
@ -493,7 +493,8 @@ sub build {
|
||||
{
|
||||
title => 'Options for support material and raft',
|
||||
options => [qw(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
|
||||
dont_support_bridges)],
|
||||
},
|
||||
]);
|
||||
|
||||
|
@ -3,7 +3,7 @@ use Moo;
|
||||
|
||||
use List::Util qw(first sum max min);
|
||||
use Slic3r::Geometry qw(PI unscale scaled_epsilon rad2deg epsilon);
|
||||
use Slic3r::Geometry::Clipper qw(intersection_pl intersection_ex union);
|
||||
use Slic3r::Geometry::Clipper qw(intersection_pl intersection_ex union offset diff_pl union_ex);
|
||||
|
||||
has 'expolygon' => (is => 'ro', required => 1);
|
||||
has 'lower_slices' => (is => 'rw', required => 1); # ExPolygons or ExPolygonCollection
|
||||
@ -213,4 +213,41 @@ sub coverage {
|
||||
return $coverage;
|
||||
}
|
||||
|
||||
# this method returns the bridge edges (as polylines) that are not supported
|
||||
# but would allow the entire bridge area to be bridged with detected angle
|
||||
# if supported too
|
||||
sub unsupported_edges {
|
||||
my ($self, $angle) = @_;
|
||||
|
||||
if (!defined $angle) {
|
||||
return [] if !defined($angle = $self->angle);
|
||||
}
|
||||
|
||||
# get bridge edges (both contour and holes)
|
||||
my @bridge_edges = map $_->split_at_first_point, @{$self->expolygon};
|
||||
$_->[0]->translate(1,0) for @bridge_edges; # workaround for Clipper bug, see comments in Slic3r::Polygon::clip_as_polyline()
|
||||
|
||||
# get unsupported edges
|
||||
my $grown_lower = offset([ map @$_, @{$self->lower_slices} ], +$self->extrusion_width);
|
||||
my $unsupported = diff_pl(
|
||||
\@bridge_edges,
|
||||
$grown_lower,
|
||||
);
|
||||
|
||||
if (0) {
|
||||
require "Slic3r/SVG.pm";
|
||||
Slic3r::SVG::output(
|
||||
"unsupported_" . rad2deg($angle) . ".svg",
|
||||
expolygons => [$self->expolygon],
|
||||
green_expolygons => $self->_anchors,
|
||||
red_expolygons => union_ex($grown_lower),
|
||||
no_arrows => 1,
|
||||
polylines => [ map $_->split_at_first_point, @{$self->expolygon} ],
|
||||
red_polylines => $unsupported,
|
||||
);
|
||||
}
|
||||
|
||||
return $unsupported;
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -33,6 +33,9 @@ has 'fill_surfaces' => (is => 'rw', default => sub { Slic3r::Surface::Collection
|
||||
# collection of expolygons representing the bridged areas (thus not needing support material)
|
||||
has 'bridged' => (is => 'rw', default => sub { Slic3r::ExPolygon::Collection->new });
|
||||
|
||||
# collection of polylines representing the unsupported bridge edges
|
||||
has 'unsupported_bridge_edges' => (is => 'rw', default => sub { Slic3r::Polyline::Collection->new });
|
||||
|
||||
# ordered collection of extrusion paths/loops to build all perimeters
|
||||
has 'perimeters' => (is => 'rw', default => sub { Slic3r::ExtrusionPath::Collection->new });
|
||||
|
||||
@ -418,6 +421,7 @@ sub process_external_surfaces {
|
||||
|
||||
if (defined $angle && $self->object->config->support_material) {
|
||||
$self->bridged->append(@{ $bridge_detector->coverage($angle) });
|
||||
$self->unsupported_bridge_edges->append(@{ $bridge_detector->unsupported_edges });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,12 +159,33 @@ sub contact_area {
|
||||
# outside the lower slice boundary, thus no overhang
|
||||
}
|
||||
|
||||
# remove bridged areas
|
||||
$diff = diff(
|
||||
$diff,
|
||||
[ map @$_, @{$layerm->bridged} ],
|
||||
1,
|
||||
);
|
||||
if ($self->object_config->dont_support_bridges) {
|
||||
if (1) {
|
||||
# remove the entire bridges and only support the unsupported edges
|
||||
my @bridges = map $_->expolygon,
|
||||
grep $_->bridge_angle != -1,
|
||||
@{$layerm->fill_surfaces->filter_by_type(S_TYPE_BOTTOMBRIDGE)};
|
||||
|
||||
$diff = diff(
|
||||
$diff,
|
||||
[ map @$_, @bridges ],
|
||||
1,
|
||||
);
|
||||
|
||||
push @$diff, @{intersection(
|
||||
[ map @{$_->grow(+scale MARGIN)}, @{$layerm->unsupported_bridge_edges} ],
|
||||
[ map @$_, @bridges ],
|
||||
)}
|
||||
|
||||
} else {
|
||||
# just remove bridged areas
|
||||
$diff = diff(
|
||||
$diff,
|
||||
[ map @$_, @{$layerm->bridged} ],
|
||||
1,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
next if !@$diff;
|
||||
push @overhang, @$diff; # NOTE: this is not the full overhang as it misses the outermost half of the perimeter width!
|
||||
|
@ -381,6 +381,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})
|
||||
--dont-support-bridges
|
||||
Experimental option for preventing support material from being generated under bridged areas (default: yes)
|
||||
|
||||
Retraction options:
|
||||
--retract-length Length of retraction in mm when pausing extrusion (default: $config->{retract_length}[0])
|
||||
|
@ -139,6 +139,11 @@ class PrintConfigDef
|
||||
Options["disable_fan_first_layers"].cli = "disable-fan-first-layers=i";
|
||||
Options["disable_fan_first_layers"].max = 1000;
|
||||
|
||||
Options["dont_support_bridges"].type = coBool;
|
||||
Options["dont_support_bridges"].label = "Don't support bridges";
|
||||
Options["dont_support_bridges"].tooltip = "Experimental option for preventing support material from being generated under bridged areas.";
|
||||
Options["dont_support_bridges"].cli = "dont-support-bridges!";
|
||||
|
||||
Options["duplicate_distance"].type = coFloat;
|
||||
Options["duplicate_distance"].label = "Distance between copies";
|
||||
Options["duplicate_distance"].tooltip = "Distance used for the auto-arrange feature of the plater.";
|
||||
@ -968,6 +973,7 @@ class StaticPrintConfig : public virtual StaticConfig
|
||||
class PrintObjectConfig : public virtual StaticPrintConfig
|
||||
{
|
||||
public:
|
||||
ConfigOptionBool dont_support_bridges;
|
||||
ConfigOptionFloatOrPercent extrusion_width;
|
||||
ConfigOptionFloatOrPercent first_layer_height;
|
||||
ConfigOptionBool infill_only_where_needed;
|
||||
@ -988,6 +994,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig
|
||||
ConfigOptionInt support_material_threshold;
|
||||
|
||||
PrintObjectConfig() : StaticPrintConfig() {
|
||||
this->dont_support_bridges.value = true;
|
||||
this->extrusion_width.value = 0;
|
||||
this->extrusion_width.percent = false;
|
||||
this->first_layer_height.value = 0.35;
|
||||
@ -1012,6 +1019,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig
|
||||
};
|
||||
|
||||
ConfigOption* option(const t_config_option_key opt_key, bool create = false) {
|
||||
if (opt_key == "dont_support_bridges") return &this->dont_support_bridges;
|
||||
if (opt_key == "extrusion_width") return &this->extrusion_width;
|
||||
if (opt_key == "first_layer_height") return &this->first_layer_height;
|
||||
if (opt_key == "infill_only_where_needed") return &this->infill_only_where_needed;
|
||||
|
Loading…
Reference in New Issue
Block a user