Fixes for bridges
This commit is contained in:
parent
459577f9a2
commit
84abd41cf4
@ -55,7 +55,7 @@ our $flow_width;
|
|||||||
# print options
|
# print options
|
||||||
our $perimeter_offsets = 3;
|
our $perimeter_offsets = 3;
|
||||||
our $solid_layers = 3;
|
our $solid_layers = 3;
|
||||||
our $bridge_overlap = 2; # mm
|
our $bridge_overlap = 3; # mm
|
||||||
our $fill_type = 'rectilinear';
|
our $fill_type = 'rectilinear';
|
||||||
our $fill_density = 0.4; # 1 = 100%
|
our $fill_density = 0.4; # 1 = 100%
|
||||||
our $fill_angle = 0;
|
our $fill_angle = 0;
|
||||||
|
@ -15,6 +15,8 @@ our @EXPORT_OK = qw(
|
|||||||
sum_vectors multiply_vector subtract_vectors dot perp polygon_points_visibility
|
sum_vectors multiply_vector subtract_vectors dot perp polygon_points_visibility
|
||||||
line_intersection bounding_box bounding_box_intersect
|
line_intersection bounding_box bounding_box_intersect
|
||||||
clip_segment_complex_polygon longest_segment angle3points
|
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);
|
use Slic3r::Geometry::DouglasPeucker qw(Douglas_Peucker);
|
||||||
@ -575,4 +577,39 @@ sub angle3points {
|
|||||||
return $angle <= 0 ? $angle + 2*PI() : $angle;
|
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;
|
1;
|
||||||
|
@ -157,8 +157,21 @@ sub make_surfaces {
|
|||||||
my %seen_points = map { $get_point_id->($points[$_]) => $_ } 0..1;
|
my %seen_points = map { $get_point_id->($points[$_]) => $_ } 0..1;
|
||||||
|
|
||||||
CYCLE: while (1) {
|
CYCLE: while (1) {
|
||||||
my $next_lines = $pointmap{ $get_point_id->($points[-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]};
|
|
||||||
|
# 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;
|
last CYCLE if !@$next_lines;
|
||||||
|
|
||||||
my @ordered_next_lines = sort
|
my @ordered_next_lines = sort
|
||||||
@ -256,6 +269,12 @@ sub process_bridges {
|
|||||||
# in a convex polygon; this will print thin membranes eventually
|
# in a convex polygon; this will print thin membranes eventually
|
||||||
my $surface_p = convex_hull($surface->contour->p);
|
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
|
# find all supported edges (as polylines, thus keeping notion of
|
||||||
# consecutive supported edges)
|
# consecutive supported edges)
|
||||||
my @supported_polylines = ();
|
my @supported_polylines = ();
|
||||||
|
@ -2,6 +2,8 @@ package Slic3r::Polyline;
|
|||||||
use Moo;
|
use Moo;
|
||||||
|
|
||||||
use Math::Clipper qw();
|
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 Sub::Quote;
|
||||||
use XXX;
|
use XXX;
|
||||||
|
|
||||||
@ -46,18 +48,24 @@ sub p {
|
|||||||
|
|
||||||
sub merge_continuous_lines {
|
sub merge_continuous_lines {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
my $points = $self->p;
|
||||||
my @points = map $_->p, @{$self->points};
|
if ($self->isa('Slic3r::Polyline::Closed')) {
|
||||||
for (my $i = 2; $i <= $#points; $i++) {
|
polygon_remove_parallel_continuous_edges($points);
|
||||||
if (Slic3r::Geometry::lines_parallel([$points[$i-2], $points[$i-1]], [$points[$i-1], $points[$i]])) {
|
} else {
|
||||||
# we can remove $points[$i-1]
|
polyline_remove_parallel_continuous_edges($points);
|
||||||
splice @points, $i-1, 1;
|
|
||||||
|
|
||||||
$i--;
|
|
||||||
}
|
}
|
||||||
|
@{$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 {
|
sub cleanup {
|
||||||
|
@ -15,18 +15,6 @@ sub lines {
|
|||||||
return @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 {
|
sub encloses_point {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my ($point) = @_;
|
my ($point) = @_;
|
||||||
|
@ -120,6 +120,15 @@ sub detect_surfaces_type {
|
|||||||
# of current layer and lower one)
|
# of current layer and lower one)
|
||||||
if ($lower_layer) {
|
if ($lower_layer) {
|
||||||
@bottom = $surface_difference->($layer->surfaces, $lower_layer->surfaces, 'bottom');
|
@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",
|
#Slic3r::SVG::output(undef, "layer_" . $layer->id . "_diff.svg",
|
||||||
# green_polygons => [ map $_->p, @{$layer->surfaces} ],
|
# green_polygons => [ map $_->p, @{$layer->surfaces} ],
|
||||||
|
@ -65,7 +65,7 @@ sub output {
|
|||||||
|
|
||||||
foreach my $type (qw(points red_points)) {
|
foreach my $type (qw(points red_points)) {
|
||||||
if ($things{$type}) {
|
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(
|
my $g = $svg->group(
|
||||||
style => {
|
style => {
|
||||||
'stroke-width' => 2,
|
'stroke-width' => 2,
|
||||||
|
43
t/geometry.t
43
t/geometry.t
@ -2,7 +2,7 @@ use Test::More;
|
|||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
plan tests => 15;
|
plan tests => 17;
|
||||||
|
|
||||||
BEGIN {
|
BEGIN {
|
||||||
use FindBin;
|
use FindBin;
|
||||||
@ -10,7 +10,9 @@ BEGIN {
|
|||||||
}
|
}
|
||||||
|
|
||||||
use Slic3r;
|
use Slic3r;
|
||||||
use Slic3r::Geometry qw(PI);
|
use Slic3r::Geometry qw(PI polyline_remove_parallel_continuous_edges
|
||||||
|
polyline_remove_acute_vertices polygon_remove_acute_vertices
|
||||||
|
polygon_remove_parallel_continuous_edges);
|
||||||
|
|
||||||
#==========================================================
|
#==========================================================
|
||||||
|
|
||||||
@ -114,3 +116,40 @@ is Slic3r::Geometry::can_connect_points(@$points, $polygons), 0, 'can_connect_po
|
|||||||
}
|
}
|
||||||
|
|
||||||
#==========================================================
|
#==========================================================
|
||||||
|
|
||||||
|
{
|
||||||
|
my $polygon = [
|
||||||
|
[2265447881, 7013509857], [2271869937, 7009802077], [2606221146, 6816764300], [1132221146, 4263721402],
|
||||||
|
[1098721150, 4205697705], [1228411320, 4130821051], [1557501031, 3940821051], [1737340080, 3836990933],
|
||||||
|
[1736886253, 3837252951], [1494771522, 3977037948], [2959638603, 6514262167], [3002271522, 6588104548],
|
||||||
|
[3083252364, 6541350240], [2854283608, 6673545411], [2525193897, 6863545411],
|
||||||
|
];
|
||||||
|
polygon_remove_parallel_continuous_edges($polygon);
|
||||||
|
polygon_remove_acute_vertices($polygon);
|
||||||
|
is scalar(@$polygon), 4, 'polygon_remove_acute_vertices';
|
||||||
|
|
||||||
|
use Slic3r::SVG;
|
||||||
|
#pop @$polygon;
|
||||||
|
Slic3r::SVG::output(undef, "vert.svg",
|
||||||
|
polylines => [$polygon],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#==========================================================
|
||||||
|
|
||||||
|
{
|
||||||
|
my $polygon = [
|
||||||
|
[226.5447881,701.3509857], [260.6221146,681.67643], [109.872115,420.5697705], [149.4771522,397.7037948],
|
||||||
|
[300.2271522,658.8104548], [308.3252364,654.135024],
|
||||||
|
];
|
||||||
|
polyline_remove_acute_vertices($polygon);
|
||||||
|
is scalar(@$polygon), 6, 'polyline_remove_acute_vertices';
|
||||||
|
use Slic3r::SVG;
|
||||||
|
local $Slic3r::resolution = 0.1;
|
||||||
|
pop @$polygon;
|
||||||
|
Slic3r::SVG::output(undef, "vert2.svg",
|
||||||
|
polylines => [$polygon],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#==========================================================
|
4
t/stl.t
4
t/stl.t
@ -25,8 +25,8 @@ is_deeply lines(22, 20, 20), [ [ $points[2], $points[1] ] ], 'lower edge on laye
|
|||||||
is_deeply lines(20, 20, 10), [ [ $points[0], $points[1] ] ], 'upper edge on layer';
|
is_deeply lines(20, 20, 10), [ [ $points[0], $points[1] ] ], 'upper edge on layer';
|
||||||
is_deeply lines(20, 15, 10), [ ], 'upper vertex on layer';
|
is_deeply lines(20, 15, 10), [ ], 'upper vertex on layer';
|
||||||
is_deeply lines(28, 20, 30), [ ], 'lower vertex on layer';
|
is_deeply lines(28, 20, 30), [ ], 'lower vertex on layer';
|
||||||
is_deeply lines(24, 10, 16), [ [ [2, 6], [4, 4] ] ], 'two edges intersect';
|
is_deeply lines(24, 10, 16), [ [ [4, 4], [2, 6] ] ], 'two edges intersect';
|
||||||
is_deeply lines(24, 10, 20), [ [ [1, 9], [4, 4] ] ], 'one vertex on plane and one edge intersects';
|
is_deeply lines(24, 10, 20), [ [ [4, 4], [1, 9] ] ], 'one vertex on plane and one edge intersects';
|
||||||
|
|
||||||
my @lower = $stl->intersect_facet(vertices(22, 20, 20), $z, $dz);
|
my @lower = $stl->intersect_facet(vertices(22, 20, 20), $z, $dz);
|
||||||
my @upper = $stl->intersect_facet(vertices(20, 20, 10), $z, $dz);
|
my @upper = $stl->intersect_facet(vertices(20, 20, 10), $z, $dz);
|
||||||
|
Loading…
Reference in New Issue
Block a user