Fixes for bridges

This commit is contained in:
Alessandro Ranellucci 2011-10-09 22:18:06 +02:00
parent 459577f9a2
commit 84abd41cf4
9 changed files with 131 additions and 31 deletions

View file

@ -15,6 +15,8 @@ our @EXPORT_OK = qw(
sum_vectors multiply_vector subtract_vectors dot perp polygon_points_visibility
line_intersection bounding_box bounding_box_intersect
clip_segment_complex_polygon longest_segment angle3points
polyline_remove_parallel_continuous_edges polyline_remove_acute_vertices
polygon_remove_acute_vertices polygon_remove_parallel_continuous_edges
);
use Slic3r::Geometry::DouglasPeucker qw(Douglas_Peucker);
@ -575,4 +577,39 @@ sub angle3points {
return $angle <= 0 ? $angle + 2*PI() : $angle;
}
sub polyline_remove_parallel_continuous_edges {
my ($points, $isPolygon) = @_;
for (my $i = $isPolygon ? 0 : 2; $i <= $#$points; $i++) {
if (Slic3r::Geometry::lines_parallel([$points->[$i-2], $points->[$i-1]], [$points->[$i-1], $points->[$i]])) {
# we can remove $points->[$i-1]
splice @$points, $i-1, 1;
$i--;
}
}
}
sub polygon_remove_parallel_continuous_edges {
my ($points) = @_;
return polyline_remove_parallel_continuous_edges($points, 1);
}
sub polyline_remove_acute_vertices {
my ($points, $isPolygon) = @_;
for (my $i = $isPolygon ? -1 : 1; $i < $#$points; $i++) {
my $angle = angle3points($points->[$i], $points->[$i-1], $points->[$i+1]);
if ($angle < 0.01 || $angle >= 2*PI - 0.01) {
# we can remove $points->[$i]
splice @$points, $i, 1;
$i--;
}
}
}
sub polygon_remove_acute_vertices {
my ($points) = @_;
return polyline_remove_acute_vertices($points, 1);
}
1;

View file

@ -157,8 +157,21 @@ sub make_surfaces {
my %seen_points = map { $get_point_id->($points[$_]) => $_ } 0..1;
CYCLE: while (1) {
my $next_lines = $pointmap{ $get_point_id->($points[-1]) }
or die sprintf "No lines start at point %d,%d. This shouldn't happen", @{$points[-1]};
my $next_lines = $pointmap{ $get_point_id->($points[-1]) };
# shouldn't we find the point, let's try with a slower algorithm
# as approximation may make the coordinates differ
if (!$next_lines) {
local $Slic3r::Geometry::epsilon = 1;
for (keys %pointmap) {
$next_lines = $pointmap{$_} if points_coincide($points[-1], [ split /,/, $_ ]);
last if $next_lines;
}
}
$next_lines
or die sprintf "No lines start at point %s. This shouldn't happen",
$get_point_id->($points[-1]);
last CYCLE if !@$next_lines;
my @ordered_next_lines = sort
@ -256,6 +269,12 @@ sub process_bridges {
# in a convex polygon; this will print thin membranes eventually
my $surface_p = convex_hull($surface->contour->p);
#use Slic3r::SVG;
#Slic3r::SVG::output(undef, "bridge.svg",
# green_polygons => [ map $_->p, @supporting_surfaces ],
# red_polygons => [ $surface_p ],
#);
# find all supported edges (as polylines, thus keeping notion of
# consecutive supported edges)
my @supported_polylines = ();

View file

@ -2,6 +2,8 @@ package Slic3r::Polyline;
use Moo;
use Math::Clipper qw();
use Slic3r::Geometry qw(polyline_remove_parallel_continuous_edges polyline_remove_acute_vertices
polygon_remove_acute_vertices polygon_remove_parallel_continuous_edges);
use Sub::Quote;
use XXX;
@ -46,18 +48,24 @@ sub p {
sub merge_continuous_lines {
my $self = shift;
my @points = map $_->p, @{$self->points};
for (my $i = 2; $i <= $#points; $i++) {
if (Slic3r::Geometry::lines_parallel([$points[$i-2], $points[$i-1]], [$points[$i-1], $points[$i]])) {
# we can remove $points[$i-1]
splice @points, $i-1, 1;
$i--;
}
my $points = $self->p;
if ($self->isa('Slic3r::Polyline::Closed')) {
polygon_remove_parallel_continuous_edges($points);
} else {
polyline_remove_parallel_continuous_edges($points);
}
@{$self->points} = map Slic3r::Point->cast($_), @points;
@{$self->points} = map Slic3r::Point->cast($_), @$points;
}
sub remove_acute_vertices {
my $self = shift;
my $points = $self->p;
if ($self->isa('Slic3r::Polyline::Closed')) {
polygon_remove_acute_vertices($points);
} else {
polyline_remove_acute_vertices($points);
}
@{$self->points} = map Slic3r::Point->cast($_), @$points;
}
sub cleanup {

View file

@ -15,18 +15,6 @@ sub lines {
return @lines;
}
# superclass doesn't check whether last line of our closed polyline
# is parallel to first one, so let's do it here
sub merge_continuous_lines {
my $self = shift;
$self->SUPER::merge_continuous_lines(@_);
my @lines = $self->lines;
if ($lines[-1]->parallel_to($lines[0])) {
shift @{$self->points};
}
}
sub encloses_point {
my $self = shift;
my ($point) = @_;

View file

@ -120,6 +120,15 @@ sub detect_surfaces_type {
# of current layer and lower one)
if ($lower_layer) {
@bottom = $surface_difference->($layer->surfaces, $lower_layer->surfaces, 'bottom');
for (@bottom) {
$_->contour->merge_continuous_lines;
$_->contour->remove_acute_vertices;
# okay, this is an Ugly Hack(tm) to avoid floating point math problems
# with diagonal bridges. will find a nicer solution, promised.
my $offset = offset([$_->contour->p], 100, 100, JT_MITER, 2);
@{$_->contour->points} = map Slic3r::Point->cast($_), @{ $offset->[0] };
}
#Slic3r::SVG::output(undef, "layer_" . $layer->id . "_diff.svg",
# green_polygons => [ map $_->p, @{$layer->surfaces} ],

View file

@ -65,7 +65,7 @@ sub output {
foreach my $type (qw(points red_points)) {
if ($things{$type}) {
my ($colour, $r) = $type eq 'points' ? ('black', 2) : ('red', 3);
my ($colour, $r) = $type eq 'points' ? ('black', 5) : ('red', 3);
my $g = $svg->group(
style => {
'stroke-width' => 2,