Bugfix: prevent fatal error in the rare case that no bridge anchors are found. #1607

issue1834
Alessandro Ranellucci 2014-01-15 00:24:37 +01:00
parent a40556ab56
commit dfd9bc8958
1 changed files with 36 additions and 34 deletions

View File

@ -484,44 +484,46 @@ sub _detect_bridge_direction {
1, # safety offset required to avoid Clipper from detecting empty intersection while Boost actually found some @edges 1, # safety offset required to avoid Clipper from detecting empty intersection while Boost actually found some @edges
); );
# we'll now try several directions using a rudimentary visibility check: if (@$anchors) {
# bridge in several directions and then sum the length of lines having both # we'll now try several directions using a rudimentary visibility check:
# endpoints within anchors # bridge in several directions and then sum the length of lines having both
my %directions = (); # angle => score # endpoints within anchors
my $angle_increment = PI/36; # 5° my %directions = (); # angle => score
my $line_increment = $infill_flow->scaled_width; my $angle_increment = PI/36; # 5°
for (my $angle = 0; $angle <= PI; $angle += $angle_increment) { my $line_increment = $infill_flow->scaled_width;
# rotate everything - the center point doesn't matter for (my $angle = 0; $angle <= PI; $angle += $angle_increment) {
$_->rotate($angle, [0,0]) for @$inset, @$anchors; # rotate everything - the center point doesn't matter
$_->rotate($angle, [0,0]) for @$inset, @$anchors;
# generate lines in this direction # generate lines in this direction
my $bounding_box = Slic3r::Geometry::BoundingBox->new_from_points([ map @$_, map @$_, @$anchors ]); my $bounding_box = Slic3r::Geometry::BoundingBox->new_from_points([ map @$_, map @$_, @$anchors ]);
my @lines = (); my @lines = ();
for (my $x = $bounding_box->x_min; $x <= $bounding_box->x_max; $x += $line_increment) { for (my $x = $bounding_box->x_min; $x <= $bounding_box->x_max; $x += $line_increment) {
push @lines, Slic3r::Polyline->new([$x, $bounding_box->y_min], [$x, $bounding_box->y_max]); push @lines, Slic3r::Polyline->new([$x, $bounding_box->y_min], [$x, $bounding_box->y_max]);
}
my @clipped_lines = map Slic3r::Line->new(@$_), @{ intersection_pl(\@lines, [ map @$_, @$inset ]) };
# remove any line not having both endpoints within anchors
# NOTE: these calls to contains_point() probably need to check whether the point
# is on the anchor boundaries too
@clipped_lines = grep {
my $line = $_;
!(first { $_->contains_point($line->a) } @$anchors)
&& !(first { $_->contains_point($line->b) } @$anchors);
} @clipped_lines;
# sum length of bridged lines
$directions{-$angle} = sum(map $_->length, @clipped_lines) // 0;
} }
my @clipped_lines = map Slic3r::Line->new(@$_), @{ intersection_pl(\@lines, [ map @$_, @$inset ]) }; # this could be slightly optimized with a max search instead of the sort
my @sorted_directions = sort { $directions{$a} <=> $directions{$b} } keys %directions;
# remove any line not having both endpoints within anchors # the best direction is the one causing most lines to be bridged
# NOTE: these calls to contains_point() probably need to check whether the point $bridge_angle = Slic3r::Geometry::rad2deg_dir($sorted_directions[-1]);
# is on the anchor boundaries too
@clipped_lines = grep {
my $line = $_;
!(first { $_->contains_point($line->a) } @$anchors)
&& !(first { $_->contains_point($line->b) } @$anchors);
} @clipped_lines;
# sum length of bridged lines
$directions{-$angle} = sum(map $_->length, @clipped_lines) // 0;
} }
# this could be slightly optimized with a max search instead of the sort
my @sorted_directions = sort { $directions{$a} <=> $directions{$b} } keys %directions;
# the best direction is the one causing most lines to be bridged
$bridge_angle = Slic3r::Geometry::rad2deg_dir($sorted_directions[-1]);
} }
Slic3r::debugf " Optimal infill angle of bridge on layer %d is %d degrees\n", Slic3r::debugf " Optimal infill angle of bridge on layer %d is %d degrees\n",