diff --git a/lib/Slic3r/Geometry.pm b/lib/Slic3r/Geometry.pm index e884b1d42..918422c78 100644 --- a/lib/Slic3r/Geometry.pm +++ b/lib/Slic3r/Geometry.pm @@ -12,7 +12,7 @@ use constant X => 0; use constant Y => 1; use constant epsilon => 1E-8; use constant epsilon2 => epsilon**2; -our $parallel_degrees_limit = abs(deg2rad(10)); +our $parallel_degrees_limit = abs(deg2rad(3)); sub slope { my ($line) = @_; diff --git a/lib/Slic3r/Polyline.pm b/lib/Slic3r/Polyline.pm index 166cd711f..27adc0ca1 100644 --- a/lib/Slic3r/Polyline.pm +++ b/lib/Slic3r/Polyline.pm @@ -46,25 +46,17 @@ sub p { sub merge_continuous_lines { my $self = shift; - my $finished = 0; - CYCLE: while (!$finished) { - my $last_line; - foreach my $line ($self->lines) { - if (defined $last_line && $line->parallel_to($last_line)) { - # $line and $last_line are parallel and continuous, - # so we can remove their common point from our polyline - - # find common point - my ($common_point) = grep $_ eq $line->a || $_ eq $line->b, @{$last_line->points}; - - # remove point from polyline - @{$self->points} = grep $_ ne $common_point, @{$self->points}; - $finished = 0; - } - $last_line = $line; + 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--; } - $finished = 1; } + + @{$self->points} = map Slic3r::Point->cast($_), @points; } sub cleanup { diff --git a/t/clean_polylines.t b/t/clean_polylines.t index e1188d9cf..9ad552f8e 100644 --- a/t/clean_polylines.t +++ b/t/clean_polylines.t @@ -1,6 +1,6 @@ use Test::More; -plan tests => 3; +plan tests => 4; BEGIN { use FindBin; @@ -56,3 +56,40 @@ my $num_points = scalar @{$polyline->points}; $polyline->cleanup; note sprintf "original points: %d\nnew points: %d", $num_points, scalar(@{$polyline->points}); ok @{$polyline->points} < $num_points, 'gear was further simplified using Douglas-Peucker'; + +my $circle = [ + [3744.8,8045.8],[3788.1,8061.4],[3940.6,8116.3],[3984.8,8129.2],[4140.6,8174.4],[4185.5,8184.4],[4343.8,8219.9], + [4389.2,8227.1],[4549.4,8252.4],[4595.2,8256.7],[4756.6,8272],[4802.6,8273.4],[4964.7,8278.5],[5010.7,8277.1], + [5172.8,8272],[5218.6,8267.7],[5380,8252.4],[5425.5,8245.2],[5585.6,8219.9],[5630.5,8209.8],[5788.8,8174.4], + [5833,8161.6],[5988.8,8116.3],[6032,8100.7],[6184.6,8045.8],[6226.8,8027.5],[6375.6,7963.2],[6416.6,7942.3], + [6561.1,7868.6],[6600.7,7845.2],[6740.3,7762.7],[6778.4,7736.8],[6912.5,7645.7],[6948.8,7617.5],[7077,7518], + [7111.5,7487.6],[7233.2,7380.4],[7347.9,7265.7],[7380.4,7233.2],[7410.8,7198.7],[7518,7077],[7546.2,7040.6], + [7645.7,6912.5],[7671.5,6874.4],[7762.7,6740.3],[7786.1,6700.7],[7868.6,6561.1],[7889.5,6520.2],[7963.2,6375.6], + [7981.4,6333.4],[8045.8,6184.6],[8061.4,6141.3],[8116.3,5988.8],[8129.2,5944.6],[8174.4,5788.8],[8184.4,5743.9], + [8219.9,5585.6],[8227.1,5540.2],[8252.4,5380],[8256.7,5334.2],[8272,5172.8],[8273.4,5126.8],[8278.5,4964.7], + [8277.1,4918.7],[8272,4756.6],[8267.7,4710.8],[8252.4,4549.4],[8245.2,4503.9],[8219.9,4343.8],[8209.8,4298.9], + [8174.4,4140.6],[8161.6,4096.4],[8116.3,3940.6],[8100.7,3897.4],[8045.8,3744.8],[8027.5,3702.6],[7963.2,3553.8], + [7942.3,3512.8],[7868.6,3368.3],[7845.2,3328.7],[7762.7,3189.1],[7736.8,3151],[7645.7,3016.9],[7617.5,2980.6], + [7518,2852.4],[7487.6,2817.9],[7380.4,2696.2],[7347.9,2663.7],[7233.2,2549],[7198.7,2518.6],[7077,2411.4], + [7040.6,2383.2],[6912.5,2283.7],[6874.4,2257.9],[6740.3,2166.7],[6700.7,2143.3],[6561.1,2060.8],[6520.2,2039.9], + [6375.6,1966.2],[6333.4,1948],[6184.6,1883.6],[6141.3,1868],[5988.8,1813.1],[5944.6,1800.2],[5788.8,1755], + [5743.9,1745],[5585.6,1709.5],[5540.2,1702.3],[5380,1677],[5334.2,1672.7],[5172.8,1657.4],[5126.8,1656], + [4964.7,1650.9],[4918.7,1652.3],[4756.6,1657.4],[4710.8,1661.7],[4549.4,1677],[4503.9,1684.2],[4343.8,1709.5], + [4298.9,1719.6],[4140.6,1755],[4096.4,1767.8],[3940.6,1813.1],[3897.4,1828.7],[3744.8,1883.6],[3702.6,1901.9], + [3553.8,1966.2],[3512.8,1987.1],[3368.3,2060.8],[3328.7,2084.2],[3189.1,2166.7],[3151,2192.6],[3016.9,2283.7], + [2980.6,2311.9],[2852.4,2411.4],[2817.9,2441.8],[2696.2,2549],[2581.5,2663.7],[2549,2696.2],[2518.6,2730.7], + [2411.4,2852.4],[2383.2,2888.8],[2283.7,3016.9],[2257.9,3055],[2166.7,3189.1],[2143.3,3228.7],[2060.8,3368.3], + [2039.9,3409.2],[1966.2,3553.8],[1948,3596],[1883.6,3744.8],[1868,3788.1],[1813.1,3940.6],[1800.2,3984.8], + [1755,4140.6],[1745,4185.5],[1709.5,4343.8],[1702.3,4389.2],[1677,4549.4],[1672.7,4595.2],[1657.4,4756.6], + [1656,4802.6],[1650.9,4964.7],[1652.3,5010.7],[1657.4,5172.8],[1661.7,5218.6],[1677,5380],[1684.2,5425.5], + [1709.5,5585.6],[1719.6,5630.5],[1755,5788.8],[1767.8,5833],[1813.1,5988.8],[1828.7,6032],[1883.6,6184.6], + [1901.9,6226.8],[1966.2,6375.6],[1987.1,6416.6],[2060.8,6561.1],[2084.2,6600.7],[2166.7,6740.3],[2192.6,6778.4], + [2283.7,6912.5],[2311.9,6948.8],[2411.4,7077],[2441.8,7111.5],[2549,7233.2],[2581.5,7265.7],[2696.2,7380.4], + [2730.7,7410.8],[2852.4,7518],[2888.8,7546.2],[3016.9,7645.7],[3055,7671.5],[3189.1,7762.7],[3228.7,7786.1], + [3368.3,7868.6],[3409.2,7889.5],[3553.8,7963.2],[3596,7981.4], +]; + +$polyline = Slic3r::Polyline::Closed->cast($circle); +$polyline->merge_continuous_lines; +note sprintf "original points: %d\nnew points: %d", scalar(@$circle), scalar(@{$polyline->points}); +ok @{$polyline->points} >= @$gear/3, 'circle was simplified using merge_continuous_lines';