mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-05-11 05:29:05 +08:00
Fix support material
This commit is contained in:
parent
94e28b9ab8
commit
a578af9d28
@ -486,49 +486,66 @@ sub generate_support_material {
|
|||||||
my $self = shift;
|
my $self = shift;
|
||||||
my %params = @_;
|
my %params = @_;
|
||||||
|
|
||||||
my $distance_from_object = 3; # mm
|
my $distance_from_object = scale $Slic3r::flow->width;
|
||||||
|
my $extra_margin = scale 1;
|
||||||
|
|
||||||
# determine unsupported surfaces
|
# determine unsupported surfaces
|
||||||
my %layers = ();
|
|
||||||
my @unsupported_expolygons = ();
|
my @unsupported_expolygons = ();
|
||||||
|
|
||||||
|
# determine support regions in each layer (for upper layers)
|
||||||
|
Slic3r::debugf "Detecting regions\n";
|
||||||
|
my %layers = ();
|
||||||
{
|
{
|
||||||
my (@a, @b) = ();
|
my @current_support_regions = (); # expolygons we've started to support (i.e. below the empty interface layers)
|
||||||
|
my @queue = (); # the number of items of this array determines the number of empty interface layers
|
||||||
for my $i (reverse 0 .. $#{$self->layers}) {
|
for my $i (reverse 0 .. $#{$self->layers}) {
|
||||||
my $layer = $self->layers->[$i];
|
my $layer = $self->layers->[$i];
|
||||||
my @c = ();
|
my $upper_layer = $i < $#{$self->layers} ? $self->layers->[$i+1] : undef;
|
||||||
if (@b) {
|
|
||||||
@c = @{diff_ex(
|
# step 1: generate support material in current layer (for upper layers)
|
||||||
[ map @$_, @b ],
|
push @current_support_regions, @{ shift @queue } if @queue && $i < $#{$self->layers};
|
||||||
[ map @$_, map $_->expolygon->offset_ex(scale $distance_from_object), @{$layer->slices} ],
|
@current_support_regions = @{diff_ex(
|
||||||
|
[ map @$_, @current_support_regions ],
|
||||||
|
[ map @$_, map $_->expolygon->offset_ex($distance_from_object), @{$layer->slices} ],
|
||||||
|
)};
|
||||||
|
|
||||||
|
$layers{$i} = [@current_support_regions];
|
||||||
|
|
||||||
|
# step 2: get layer overhangs and put them into queue for adding support inside lower layers
|
||||||
|
# we need an angle threshold for this
|
||||||
|
my @overhangs = ();
|
||||||
|
if ($upper_layer) {
|
||||||
|
@overhangs = @{diff_ex(
|
||||||
|
[ map @$_, map $_->expolygon->offset_ex($extra_margin), @{$upper_layer->slices} ],
|
||||||
|
[ map @{$_->expolygon}, @{$layer->slices} ],
|
||||||
|
1,
|
||||||
)};
|
)};
|
||||||
$layers{$i} = [@c];
|
|
||||||
}
|
}
|
||||||
@b = @{union_ex([ map @$_, @c, @a ])};
|
|
||||||
|
|
||||||
# get unsupported surfaces for current layer as all bottom slices
|
# get unsupported surfaces for current layer as all bottom slices
|
||||||
# minus the bridges offsetted to cover their perimeters.
|
# minus the bridges offsetted to cover their perimeters.
|
||||||
# actually, we are marking as bridges more than we should be, so
|
# actually, we are marking as bridges more than we should be, so
|
||||||
# better build support material for bridges too rather than ignoring
|
# better build support material for bridges too rather than ignoring
|
||||||
# those parts. a visibility check algorithm is needed.
|
# those parts. a visibility check algorithm is needed.
|
||||||
# @a = @{diff_ex(
|
# @overhangs = @{diff_ex(
|
||||||
# [ map $_->p, grep $_->surface_type == S_TYPE_BOTTOM, @{$layer->slices} ],
|
# [ map @$_, @overhangs ],
|
||||||
# [ map @$_, map $_->expolygon->offset_ex(scale $layer->flow->spacing * $Slic3r::perimeters),
|
# [ map @$_, map $_->expolygon->offset_ex(scale $layer->flow->spacing * $Slic3r::perimeters),
|
||||||
# grep $_->surface_type == S_TYPE_BOTTOM && defined $_->bridge_angle,
|
# grep $_->surface_type == S_TYPE_BOTTOM && defined $_->bridge_angle,
|
||||||
# @{$layer->fill_surfaces} ],
|
# @{$layer->fill_surfaces} ],
|
||||||
# )};
|
# )};
|
||||||
@a = map $_->expolygon->clone, grep $_->surface_type == S_TYPE_BOTTOM, @{$layer->slices};
|
push @queue, [ map $_->clone, @overhangs ];
|
||||||
|
|
||||||
$_->simplify(scale $layer->flow->spacing * 3) for @a;
|
$_->simplify(scale $layer->flow->spacing * 3) for @{ $queue[-1] };
|
||||||
push @unsupported_expolygons, @a;
|
push @unsupported_expolygons, @{ $queue[-1] };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return if !@unsupported_expolygons;
|
return if !@unsupported_expolygons;
|
||||||
|
|
||||||
# generate paths for the pattern that we're going to use
|
# generate paths for the pattern that we're going to use
|
||||||
|
Slic3r::debugf "Generating patterns\n";
|
||||||
my $support_patterns = [];
|
my $support_patterns = [];
|
||||||
{
|
{
|
||||||
my @support_material_areas = map $_->offset_ex(scale 5),
|
my @support_material_areas = @{union_ex([ map @$_, @unsupported_expolygons ])};
|
||||||
@{union_ex([ map @$_, @unsupported_expolygons ])};
|
|
||||||
|
|
||||||
my $fill = Slic3r::Fill->new(print => $params{print});
|
my $fill = Slic3r::Fill->new(print => $params{print});
|
||||||
foreach my $layer (map $self->layers->[$_], 0,1,2) { # ugly hack
|
foreach my $layer (map $self->layers->[$_], 0,1,2) { # ugly hack
|
||||||
@ -556,16 +573,18 @@ sub generate_support_material {
|
|||||||
$_->deserialize for @patterns;
|
$_->deserialize for @patterns;
|
||||||
push @$support_patterns, [@patterns];
|
push @$support_patterns, [@patterns];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (0) {
|
if (0) {
|
||||||
require "Slic3r/SVG.pm";
|
require "Slic3r/SVG.pm";
|
||||||
Slic3r::SVG::output(undef, "support.svg",
|
Slic3r::SVG::output(undef, "support_$_.svg",
|
||||||
polylines => [ map $_->polyline, map @$_, @$support_patterns ],
|
polylines => [ map $_->polyline, map @$_, $support_patterns->[$_] ],
|
||||||
);
|
polygons => [ map @$_, @support_material_areas ],
|
||||||
|
) for (0,1,2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# apply the pattern to layers
|
# apply the pattern to layers
|
||||||
|
Slic3r::debugf "Applying patterns\n";
|
||||||
{
|
{
|
||||||
my $clip_pattern = sub {
|
my $clip_pattern = sub {
|
||||||
my ($layer_id, $expolygons) = @_;
|
my ($layer_id, $expolygons) = @_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user