Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlessandro Ranellucci <aar@cpan.org>2011-12-30 22:59:51 +0400
committerAlessandro Ranellucci <aar@cpan.org>2011-12-30 22:59:51 +0400
commit8ed91a8ec4d22f1703d00aa1ff351d576be6f516 (patch)
tree5d3691d2c41609e428e9da05134db8e1828d61e8
parent2def6a9787556fda137b464d39122fcc7f98d612 (diff)
Very large refactoring. Ditched Slic3r::Polyline::Closed and reorganized geometric classes.
-rw-r--r--MANIFEST1
-rw-r--r--lib/Slic3r.pm1
-rw-r--r--lib/Slic3r/ExPolygon.pm11
-rw-r--r--lib/Slic3r/ExtrusionLoop.pm25
-rw-r--r--lib/Slic3r/ExtrusionPath.pm51
-rw-r--r--lib/Slic3r/Fill.pm13
-rw-r--r--lib/Slic3r/Fill/Concentric.pm2
-rw-r--r--lib/Slic3r/Fill/PlanePath.pm2
-rw-r--r--lib/Slic3r/Fill/Rectilinear.pm2
-rw-r--r--lib/Slic3r/Layer.pm44
-rw-r--r--lib/Slic3r/Line.pm7
-rw-r--r--lib/Slic3r/Perimeter.pm14
-rw-r--r--lib/Slic3r/Polygon.pm45
-rw-r--r--lib/Slic3r/Polyline.pm77
-rw-r--r--lib/Slic3r/Polyline/Closed.pm49
-rw-r--r--lib/Slic3r/Print.pm43
-rw-r--r--lib/Slic3r/Surface.pm65
-rw-r--r--t/arcs.t13
-rw-r--r--t/clean_polylines.t173
-rw-r--r--t/polyclip.t4
20 files changed, 293 insertions, 349 deletions
diff --git a/MANIFEST b/MANIFEST
index 40cfc3f6c..66051ba3c 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -30,7 +30,6 @@ lib/Slic3r/Perimeter.pm
lib/Slic3r/Point.pm
lib/Slic3r/Polygon.pm
lib/Slic3r/Polyline.pm
-lib/Slic3r/Polyline/Closed.pm
lib/Slic3r/Print.pm
lib/Slic3r/Skein.pm
lib/Slic3r/STL.pm
diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm
index 246dcb0f7..b692e662e 100644
--- a/lib/Slic3r.pm
+++ b/lib/Slic3r.pm
@@ -25,7 +25,6 @@ use Slic3r::Perimeter;
use Slic3r::Point;
use Slic3r::Polygon;
use Slic3r::Polyline;
-use Slic3r::Polyline::Closed;
use Slic3r::Print;
use Slic3r::Skein;
use Slic3r::STL;
diff --git a/lib/Slic3r/ExPolygon.pm b/lib/Slic3r/ExPolygon.pm
index 50c9debac..e710b265f 100644
--- a/lib/Slic3r/ExPolygon.pm
+++ b/lib/Slic3r/ExPolygon.pm
@@ -40,6 +40,11 @@ sub holes {
return @$self[1..$#$self];
}
+sub lines {
+ my $self = shift;
+ return map $_->lines, @$self;
+}
+
sub clipper_expolygon {
my $self = shift;
return {
@@ -106,7 +111,7 @@ sub bounding_box {
sub clip_line {
my $self = shift;
my ($line) = @_;
- $line = Slic3r::Line->cast($line);
+ $line = Slic3r::Line->new($line) if ref $line eq 'ARRAY';
my @intersections = grep $_, map $_->intersection($line, 1), map $_->lines, @$self;
my @dir = (
@@ -203,6 +208,8 @@ sub medial_axis {
}
return undef if !@skeleton_lines;
+ return undef if !@skeleton_lines;
+
# now build a single polyline
my $polyline = [];
{
@@ -248,7 +255,7 @@ sub medial_axis {
if (Slic3r::Geometry::same_point($polyline->[0], $polyline->[-1])) {
return Slic3r::Polygon->new(@$polyline[0..$#$polyline-1]);
} else {
- return Slic3r::Polyline->cast($polyline);
+ return Slic3r::Polyline->new($polyline);
}
}
diff --git a/lib/Slic3r/ExtrusionLoop.pm b/lib/Slic3r/ExtrusionLoop.pm
index 7df64a1e8..caee31ede 100644
--- a/lib/Slic3r/ExtrusionLoop.pm
+++ b/lib/Slic3r/ExtrusionLoop.pm
@@ -3,11 +3,21 @@ use Moo;
use XXX;
-extends 'Slic3r::Polyline::Closed';
+# the underlying Slic3r::Polygon objects holds the geometry
+has 'polygon' => (
+ is => 'ro',
+ required => 1,
+ handles => [qw(is_printable nearest_point_to)],
+);
# perimeter/fill/solid-fill/bridge/skirt
has 'role' => (is => 'rw', required => 1);
+sub BUILD {
+ my $self = shift;
+ bless $self->polygon, 'Slic3r::Polygon';
+}
+
sub split_at {
my $self = shift;
my ($point) = @_;
@@ -16,8 +26,8 @@ sub split_at {
# find index of point
my $i = -1;
- for (my $n = 0; $n <= $#{$self->points}; $n++) {
- if ($point->id eq $self->points->[$n]->id) {
+ for (my $n = 0; $n <= $#{$self->polygon}; $n++) {ZZZ "here" if ref $self->polygon->[$n] eq 'ARRAY';
+ if ($point->id eq $self->polygon->[$n]->id) {
$i = $n;
last;
}
@@ -25,10 +35,13 @@ sub split_at {
die "Point not found" if $i == -1;
my @new_points = ();
- push @new_points, @{$self->points}[$i .. $#{$self->points}];
- push @new_points, @{$self->points}[0 .. $i];
+ push @new_points, @{$self->polygon}[$i .. $#{$self->polygon}];
+ push @new_points, @{$self->polygon}[0 .. $i];
- return Slic3r::ExtrusionPath->new(points => [@new_points], role => $self->role);
+ return Slic3r::ExtrusionPath->new(
+ polyline => Slic3r::Polyline->new(\@new_points),
+ role => $self->role,
+ );
}
1;
diff --git a/lib/Slic3r/ExtrusionPath.pm b/lib/Slic3r/ExtrusionPath.pm
index 592a61638..4f8a5b4c2 100644
--- a/lib/Slic3r/ExtrusionPath.pm
+++ b/lib/Slic3r/ExtrusionPath.pm
@@ -1,7 +1,15 @@
package Slic3r::ExtrusionPath;
use Moo;
-extends 'Slic3r::Polyline';
+use Slic3r::Geometry qw(PI X Y epsilon deg2rad rotate_points);
+use XXX;
+
+# the underlying Slic3r::Polyline objects holds the geometry
+has 'polyline' => (
+ is => 'ro',
+ required => 1,
+ handles => [qw(merge_continuous_lines lines)],
+);
# this integer represents the vertical thickness of the extrusion
# expressed in layers
@@ -12,8 +20,10 @@ has 'flow_spacing' => (is => 'rw');
# perimeter/fill/solid-fill/bridge/skirt
has 'role' => (is => 'rw', required => 1);
-use Slic3r::Geometry qw(PI X Y epsilon deg2rad rotate_points);
-use XXX;
+sub BUILD {
+ my $self = shift;
+ bless $self->polyline, 'Slic3r::Polyline';
+}
sub clip_end {
my $self = shift;
@@ -35,6 +45,11 @@ sub clip_end {
}
}
+sub points {
+ my $self = shift;
+ return $self->polyline;
+}
+
sub endpoints {
my $self = shift;
return ($self->points->[0], $self->points->[-1]);
@@ -68,10 +83,10 @@ sub split_at_acute_angles {
# if the angle between $p[-2], $p[-1], $p3 is too acute
# then consider $p3 only as a starting point of a new
# path and stop the current one as it is
- push @paths, (ref $self)->cast(
- [@p],
- role => $self->role,
- depth_layers => $self->depth_layers,
+ push @paths, (ref $self)->new(
+ polyline => Slic3r::Polyline->new(\@p),
+ role => $self->role,
+ depth_layers => $self->depth_layers,
);
@p = ($p3);
push @p, grep $_, shift @points or last;
@@ -79,10 +94,10 @@ sub split_at_acute_angles {
push @p, $p3;
}
}
- push @paths, (ref $self)->cast(
- [@p],
- role => $self->role,
- depth_layers => $self->depth_layers,
+ push @paths, (ref $self)->new(
+ polyline => Slic3r::Polyline->new(\@p),
+ role => $self->role,
+ depth_layers => $self->depth_layers,
) if @p > 1;
return @paths;
@@ -168,7 +183,7 @@ sub detect_arcs {
}
my $arc = Slic3r::ExtrusionPath::Arc->new(
- points => [@arc_points],
+ polyline => Slic3r::Polyline->new(\@arc_points),
role => $self->role,
orientation => $orientation,
center => $arc_center,
@@ -177,9 +192,9 @@ sub detect_arcs {
# points 0..$i form a linear path
push @paths, (ref $self)->new(
- points => [ @points[0..$i] ],
- role => $self->role,
- depth_layers => $self->depth_layers,
+ polyline => Slic3r::Polyline->new(@points[0..$i]),
+ role => $self->role,
+ depth_layers => $self->depth_layers,
) if $i > 0;
# add our arc
@@ -196,9 +211,9 @@ sub detect_arcs {
# remaining points form a linear path
push @paths, (ref $self)->new(
- points => [@points],
- role => $self->role,
- depth_layers => $self->depth_layers,
+ polyline => Slic3r::Polyline->new(\@points),
+ role => $self->role,
+ depth_layers => $self->depth_layers,
) if @points > 1;
return @paths;
diff --git a/lib/Slic3r/Fill.pm b/lib/Slic3r/Fill.pm
index e602301a5..a817c6ff5 100644
--- a/lib/Slic3r/Fill.pm
+++ b/lib/Slic3r/Fill.pm
@@ -71,7 +71,8 @@ sub make_fill {
1,
);
- push @surfaces, map Slic3r::Surface->cast_from_expolygon($_,
+ push @surfaces, map Slic3r::Surface->new(
+ expolygon => $_,
surface_type => $group->[0]->surface_type,
bridge_angle => $group->[0]->bridge_angle,
depth_layers => $group->[0]->depth_layers,
@@ -100,7 +101,8 @@ sub make_fill {
[ @offsets ],
);
- push @new_surfaces, map Slic3r::Surface->cast_from_expolygon($_,
+ push @new_surfaces, map Slic3r::Surface->new(
+ expolygon => $_,
surface_type => $surface->surface_type,
bridge_angle => $surface->bridge_angle,
depth_layers => $surface->depth_layers,
@@ -111,7 +113,7 @@ sub make_fill {
# organize infill surfaces using a shortest path search
@surfaces = @{shortest_path([
- map [ $_->contour->points->[0], $_ ], @surfaces,
+ map [ $_->contour->[0], $_ ], @surfaces,
])};
SURFACE: foreach my $surface (@surfaces) {
@@ -145,15 +147,14 @@ sub make_fill {
# save into layer
push @{ $layer->fills }, Slic3r::ExtrusionPath::Collection->new(
paths => [
- map Slic3r::ExtrusionPath->cast(
- [ @$_ ],
+ map Slic3r::ExtrusionPath->new(
+ polyline => Slic3r::Polyline->new(@$_),
role => ($is_bridge ? 'bridge' : $is_solid ? 'solid-fill' : 'fill'),
depth_layers => $surface->depth_layers,
flow_spacing => $params->{flow_spacing},
), @paths,
],
) if @paths;
- ###$layer->fills->[-1]->cleanup;
}
}
diff --git a/lib/Slic3r/Fill/Concentric.pm b/lib/Slic3r/Fill/Concentric.pm
index 718bddd9f..a5dab2d24 100644
--- a/lib/Slic3r/Fill/Concentric.pm
+++ b/lib/Slic3r/Fill/Concentric.pm
@@ -51,7 +51,7 @@ sub fill_surface {
($bounding_box->[X1] + $bounding_box->[X2]) / 2,
($bounding_box->[Y1] + $bounding_box->[Y2]) / 2,
);
- foreach my $loop (map Slic3r::ExtrusionLoop->cast($_, role => 'fill'), @loops) {
+ foreach my $loop (map Slic3r::ExtrusionLoop->new(polygon => $_, role => 'fill'), @loops) {
# find the point of the loop that is closest to the current extruder position
$cur_pos = $loop->nearest_point_to($cur_pos);
diff --git a/lib/Slic3r/Fill/PlanePath.pm b/lib/Slic3r/Fill/PlanePath.pm
index caf92c948..c3d3f5d12 100644
--- a/lib/Slic3r/Fill/PlanePath.pm
+++ b/lib/Slic3r/Fill/PlanePath.pm
@@ -40,7 +40,7 @@ sub fill_surface {
my $path = "Math::PlanePath::$1"->new;
my @n = $self->get_n($path, [map +($_ / $distance_between_lines), @$bounding_box]);
- my $polyline = Slic3r::Polyline->cast([
+ my $polyline = Slic3r::Polyline->new([
map [ map {$_*$distance_between_lines} $path->n_to_xy($_) ], @n,
]);
return {} if !@{$polyline->points};
diff --git a/lib/Slic3r/Fill/Rectilinear.pm b/lib/Slic3r/Fill/Rectilinear.pm
index 357284591..dcb14e6ea 100644
--- a/lib/Slic3r/Fill/Rectilinear.pm
+++ b/lib/Slic3r/Fill/Rectilinear.pm
@@ -55,7 +55,7 @@ sub fill_surface {
# connect lines
{
my $collection = Slic3r::ExtrusionPath::Collection->new(
- paths => [ map Slic3r::ExtrusionPath->cast([ @$_ ], role => 'bogus'), @paths ],
+ paths => [ map Slic3r::ExtrusionPath->new(polyline => Slic3r::Polyline->new(@$_), role => 'bogus'), @paths ],
);
@paths = ();
diff --git a/lib/Slic3r/Layer.pm b/lib/Slic3r/Layer.pm
index b924e1902..3ccdbd32e 100644
--- a/lib/Slic3r/Layer.pm
+++ b/lib/Slic3r/Layer.pm
@@ -24,23 +24,15 @@ has 'lines' => (
);
# collection of surfaces generated by slicing the original geometry
-has 'slices' => (
- is => 'rw',
- #isa => 'ArrayRef[Slic3r::Surface]',
- default => sub { [] },
-);
+has 'slices' => (is => 'ro', default => sub { [] });
# collection of polygons or polylines representing thin walls contained
# in the original geometry
-has 'thin_walls' => (is => 'rw', default => sub { [] });
+has 'thin_walls' => (is => 'ro', default => sub { [] });
-# collection of surfaces generated by offsetting the innermost perimeter(s)
+# collection of expolygons generated by offsetting the innermost perimeter(s)
# they represent boundaries of areas to fill
-has 'fill_boundaries' => (
- is => 'rw',
- #isa => 'ArrayRef[Slic3r::Surface]',
- default => sub { [] },
-);
+has 'fill_boundaries' => (is => 'ro', default => sub { [] });
# collection of surfaces generated by clipping the slices to the fill boundaries
has 'surfaces' => (
@@ -150,7 +142,7 @@ sub make_surfaces {
scalar(@$expolygons), scalar(map $_->holes, @$expolygons), scalar(@$loops);
push @{$self->slices},
- map Slic3r::Surface->cast_from_expolygon($_, surface_type => 'internal'),
+ map Slic3r::Surface->new(expolygon => $_, surface_type => 'internal'),
@$expolygons;
}
@@ -160,8 +152,8 @@ sub make_surfaces {
my @surfaces = @{$self->slices};
@{$self->slices} = ();
foreach my $surface (@surfaces) {
- push @{$self->slices}, map Slic3r::Surface->cast_from_expolygon
- ($_, surface_type => 'internal'),
+ push @{$self->slices}, map Slic3r::Surface->new
+ (expolygon => $_, surface_type => 'internal'),
$surface->expolygon->offset_ex(-$distance);
}
@@ -183,7 +175,7 @@ sub make_surfaces {
if (0) {
require "Slic3r/SVG.pm";
Slic3r::SVG::output(undef, "surfaces.svg",
- polygons => [ map $_->contour->p, @{$self->slices} ],
+ polygons => [ map $_->contour, @{$self->slices} ],
red_polygons => [ map $_->p, map @{$_->holes}, @{$self->slices} ],
);
}
@@ -210,7 +202,7 @@ sub prepare_fill_surfaces {
(map $_->p, grep $_->surface_type eq 'top', @surfaces),
(map @$_, map $_->expolygon->safety_offset, @$small_internal),
]);
- my @top = map Slic3r::Surface->cast_from_expolygon($_, surface_type => 'top'), @$union;
+ my @top = map Slic3r::Surface->new(expolygon => $_, surface_type => 'top'), @$union;
@surfaces = (grep($_->surface_type ne 'top', @surfaces), @top);
}
@@ -242,7 +234,8 @@ sub remove_small_surfaces {
@offsets = map $_->offset_ex($distance), @offsets;
@offsets = @{ union_ex([ map @$_, @offsets ], undef, 1) };
- push @{$self->fill_surfaces}, map Slic3r::Surface->cast_from_expolygon($_,
+ push @{$self->fill_surfaces}, map Slic3r::Surface->new(
+ expolygon => $_,
surface_type => $surface->surface_type), @offsets;
}
@@ -257,7 +250,8 @@ sub remove_small_surfaces {
[ map $_->p, @surfaces ],
[ map $_->p, @{$self->fill_surfaces} ],
);
- push @{$self->fill_surfaces}, map Slic3r::Surface->cast_from_expolygon($_,
+ push @{$self->fill_surfaces}, map Slic3r::Surface->new(
+ expolygon => $_,
surface_type => 'internal-solid'), @$diff;
}
}
@@ -382,7 +376,8 @@ sub process_bridges {
[ $bridge_offset ],
);
- push @bridges, map Slic3r::Surface->cast_from_expolygon($_,
+ push @bridges, map Slic3r::Surface->new(
+ expolygon => $_,
surface_type => $surface->surface_type,
bridge_angle => $bridge_angle,
), @$intersection;
@@ -405,7 +400,8 @@ sub process_bridges {
[ map $_->p, @bridges ],
);
- push @bridges, map Slic3r::Surface->cast_from_expolygon($_,
+ push @bridges, map Slic3r::Surface->new(
+ expolygon => $_,
surface_type => $surfaces->[0]->surface_type,
bridge_angle => $surfaces->[0]->bridge_angle,
), @$union;
@@ -424,7 +420,8 @@ sub process_bridges {
[ $bridge->p ],
);
- push @{$self->fill_surfaces}, map Slic3r::Surface->cast_from_expolygon($_,
+ push @{$self->fill_surfaces}, map Slic3r::Surface->new(
+ expolygon => $_,
surface_type => $bridge->surface_type,
bridge_angle => $bridge->bridge_angle,
), @$actual_bridge;
@@ -436,7 +433,8 @@ sub process_bridges {
[ map $_->p, @$group ],
[ map $_->p, @bridges ],
);
- push @{$self->fill_surfaces}, map Slic3r::Surface->cast_from_expolygon($_,
+ push @{$self->fill_surfaces}, map Slic3r::Surface->new(
+ expolygon => $_,
surface_type => $group->[0]->surface_type), @$difference;
}
}
diff --git a/lib/Slic3r/Line.pm b/lib/Slic3r/Line.pm
index 541689d24..494eae4d6 100644
--- a/lib/Slic3r/Line.pm
+++ b/lib/Slic3r/Line.pm
@@ -21,13 +21,6 @@ sub new {
return $self;
}
-sub cast {
- my $class = shift;
- my ($line) = @_;
- return $line if ref $line eq __PACKAGE__;
- return $class->new($line);
-}
-
sub a { $_[0][0] }
sub b { $_[0][1] }
diff --git a/lib/Slic3r/Perimeter.pm b/lib/Slic3r/Perimeter.pm
index ec24c0285..0b9b190bf 100644
--- a/lib/Slic3r/Perimeter.pm
+++ b/lib/Slic3r/Perimeter.pm
@@ -30,7 +30,7 @@ sub make_perimeter {
# organize perimeter surfaces using a shortest path search
my @surfaces = @{shortest_path([
- map [ $_->contour->points->[0], $_ ], @{$layer->slices},
+ map [ $_->contour->[0], $_ ], @{$layer->slices},
])};
foreach my $surface (@surfaces) {
@@ -50,9 +50,7 @@ sub make_perimeter {
# create one more offset to be used as boundary for fill
{
- my @fill_boundaries = map Slic3r::Surface->cast_from_expolygon
- ($_, surface_type => $surface->surface_type),
- map $_->offset_ex(-$distance), @last_offsets;
+ my @fill_boundaries = map $_->offset_ex(-$distance), @last_offsets;
# TODO: diff(offset(@last_offsets, -$distance/2), offset(@fill_boundaries, +$distance/2))
# this represents the small gaps that we need to treat like thin polygons,
@@ -66,12 +64,12 @@ sub make_perimeter {
foreach my $island (@perimeters) {
# do holes starting from innermost one
foreach my $hole (map $_->holes, map @$_, @$island) {
- push @{ $layer->perimeters }, Slic3r::ExtrusionLoop->cast($hole, role => 'perimeter');
+ push @{ $layer->perimeters }, Slic3r::ExtrusionLoop->new(polygon => $hole, role => 'perimeter');
}
# do contours starting from innermost one
foreach my $contour (map $_->contour, map @$_, reverse @$island) {
- push @{ $layer->perimeters }, Slic3r::ExtrusionLoop->cast($contour, role => 'perimeter');
+ push @{ $layer->perimeters }, Slic3r::ExtrusionLoop->new(polygon => $contour, role => 'perimeter');
}
}
@@ -83,9 +81,9 @@ sub make_perimeter {
# add thin walls as perimeters
for (@{ $layer->thin_walls }) {
if ($_->isa('Slic3r::Polygon')) {
- push @{ $layer->perimeters }, Slic3r::ExtrusionLoop->cast($_, role => 'perimeter');
+ push @{ $layer->perimeters }, Slic3r::ExtrusionLoop->new(polygon => $_, role => 'perimeter');
} else {
- push @{ $layer->perimeters }, Slic3r::ExtrusionPath->cast($_->points, role => 'perimeter');
+ push @{ $layer->perimeters }, Slic3r::ExtrusionPath->new(polyline => $_->points, role => 'perimeter');
}
}
}
diff --git a/lib/Slic3r/Polygon.pm b/lib/Slic3r/Polygon.pm
index 441b11056..1c5d9021d 100644
--- a/lib/Slic3r/Polygon.pm
+++ b/lib/Slic3r/Polygon.pm
@@ -3,11 +3,10 @@ use strict;
use warnings;
# a polygon is a closed polyline.
-# if you're asking why there's a Slic3r::Polygon as well
-# as a Slic3r::Polyline::Closed you're right. I plan to
-# ditch the latter and port everything to this class.
+use parent 'Slic3r::Polyline';
use Slic3r::Geometry qw(polygon_lines polygon_remove_parallel_continuous_edges
+ scale polygon_remove_acute_vertices
polygon_segment_having_point point_in_polygon move_points rotate_points);
use Slic3r::Geometry::Clipper qw(JT_MITER);
@@ -31,12 +30,6 @@ sub clone {
return (ref $self)->new(map $_->clone, @$self);
}
-# legacy method, to be removed when we ditch Slic3r::Polyline::Closed
-sub closed_polyline {
- my $self = shift;
- return Slic3r::Polyline::Closed->cast($self);
-}
-
sub lines {
my $self = shift;
return map Slic3r::Line->new($_), polygon_lines($self);
@@ -44,7 +37,20 @@ sub lines {
sub cleanup {
my $self = shift;
+ $self->merge_continuous_lines;
+}
+
+sub merge_continuous_lines {
+ my $self = shift;
+
polygon_remove_parallel_continuous_edges($self);
+ bless $_, 'Slic3r::Point' for @$self;
+}
+
+sub remove_acute_vertices {
+ my $self = shift;
+ polygon_remove_acute_vertices($self);
+ bless $_, 'Slic3r::Point' for @$self;
}
sub point_on_segment {
@@ -106,7 +112,8 @@ sub subdivide {
# $num_points is the number of points to add between $i-1 and $i
my $spacing = $len / ($num_points + 1);
- my @new_points = map Slic3r::Geometry::point_along_segment($self->[$i-1], $self->[$i], $spacing * $_),
+ my @new_points = map Slic3r::Point->new($_),
+ map Slic3r::Geometry::point_along_segment($self->[$i-1], $self->[$i], $spacing * $_),
1..$num_points;
splice @$self, $i, 0, @new_points;
@@ -114,4 +121,22 @@ sub subdivide {
}
}
+# returns false if the polyline is too tight to be printed
+sub is_printable {
+ my $self = shift;
+
+ # try to get an inwards offset
+ # for a distance equal to half of the extrusion width;
+ # if no offset is possible, then polyline is not printable
+ my $p = $self->clone;
+ @$p = reverse @$p if !Math::Clipper::is_counter_clockwise($p);
+ my $offsets = Math::Clipper::offset([$p], -(scale $Slic3r::flow_spacing / 2), $Slic3r::resolution * 100000, JT_MITER, 2);
+ return @$offsets ? 1 : 0;
+}
+
+sub is_valid {
+ my $self = shift;
+ return @{$self->points} >= 3;
+}
+
1; \ No newline at end of file
diff --git a/lib/Slic3r/Polyline.pm b/lib/Slic3r/Polyline.pm
index c820f0b2e..43ee3948d 100644
--- a/lib/Slic3r/Polyline.pm
+++ b/lib/Slic3r/Polyline.pm
@@ -1,38 +1,37 @@
package Slic3r::Polyline;
-use Moo;
+use strict;
+use warnings;
use Math::Clipper qw();
use Slic3r::Geometry qw(A B polyline_remove_parallel_continuous_edges polyline_remove_acute_vertices
- polygon_remove_acute_vertices polygon_remove_parallel_continuous_edges move_points same_point);
-use Sub::Quote;
+ move_points same_point);
use XXX;
-# arrayref of ordered points
-has 'points' => (
- is => 'rw',
- required => 1,
- default => sub { [] },
- isa => quote_sub q{ use Carp; confess "invalid points" if grep ref $_ ne 'Slic3r::Point', @{$_[0]} },
-);
+# the constructor accepts an array(ref) of points
+sub new {
+ my $class = shift;
+ my $self;
+ if (@_ == 1) {
+ $self = [ @{$_[0]} ];
+ } else {
+ $self = [ @_ ];
+ }
+
+ bless $self, $class;
+ bless $_, 'Slic3r::Point' for @$self;
+ $self;
+}
sub id {
my $self = shift;
- return join ' - ', sort map $_->id, @{$self->points};
-}
-
-sub cast {
- my $class = shift;
- my ($points, %args) = @_;
-
- $points = [ map Slic3r::Point->cast($_), @$points ];
- return $class->new(points => $points, %args);
+ return join ' - ', sort map $_->id, @$self;
}
sub lines {
my $self = shift;
my @lines = ();
my $previous_point;
- foreach my $point (@{ $self->points }) {
+ foreach my $point (@$self) {
if ($previous_point) {
push @lines, Slic3r::Line->new($previous_point, $point);
}
@@ -41,43 +40,25 @@ sub lines {
return @lines;
}
-sub p {
- my $self = shift;
- return [ @{$self->points} ];
-}
-
sub merge_continuous_lines {
my $self = shift;
- 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->new($_), @$points;
+
+ polyline_remove_parallel_continuous_edges($self);
+ bless $_, 'Slic3r::Point' for @$self;
}
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->new($_), @$points;
+ polyline_remove_acute_vertices($self);
+ bless $_, 'Slic3r::Point' for @$self;
}
-sub cleanup {
+sub simplify {
my $self = shift;
my $tolerance = shift || 10;
- my $points = $self->p;
- push @$points, $points->[0] if $self->isa('Slic3r::Polyline::Closed');
- my @clean_points = map Slic3r::Point->new($_),
- Slic3r::Geometry::Douglas_Peucker($self->p, $tolerance);
- pop @clean_points if $self->isa('Slic3r::Polyline::Closed');
- @{$self->points} = @clean_points;
+ @$self = Slic3r::Geometry::Douglas_Peucker($self, $tolerance);
+ bless $_, 'Slic3r::Point' for @$self;
}
sub reverse_points {
@@ -104,7 +85,7 @@ sub nearest_point_to {
my $self = shift;
my ($point) = @_;
- $point = Slic3r::Geometry::nearest_point($point, $self->p);
+ $point = Slic3r::Geometry::nearest_point($point, $self);
return Slic3r::Point->new($point);
}
@@ -166,7 +147,7 @@ sub clip_with_expolygon {
}
}
- return map Slic3r::Polyline->cast($_), @polylines;
+ return map Slic3r::Polyline->new($_), @polylines;
}
sub bounding_box {
diff --git a/lib/Slic3r/Polyline/Closed.pm b/lib/Slic3r/Polyline/Closed.pm
deleted file mode 100644
index 8d9d54c3a..000000000
--- a/lib/Slic3r/Polyline/Closed.pm
+++ /dev/null
@@ -1,49 +0,0 @@
-package Slic3r::Polyline::Closed;
-use Moo;
-
-extends 'Slic3r::Polyline';
-
-use Math::Clipper qw(JT_MITER);
-use Slic3r::Geometry qw(scale);
-
-sub lines {
- my $self = shift;
- my @lines = $self->SUPER::lines(@_);
-
- # since this is a closed polyline, we just add a line at the end,
- # connecting the last and the first point
- push @lines, Slic3r::Line->new($self->points->[-1], $self->points->[0]);
- return @lines;
-}
-
-sub encloses_point {
- my $self = shift;
- my ($point) = @_;
-
- return Slic3r::Geometry::point_in_polygon($point->p, $self->p);
-}
-
-# returns false if the polyline is too tight to be printed
-sub is_printable {
- my $self = shift;
-
- # try to get an inwards offset
- # for a distance equal to half of the extrusion width;
- # if no offset is possible, then polyline is not printable
- my $p = $self->p;
- @$p = reverse @$p if !Math::Clipper::is_counter_clockwise($p);
- my $offsets = Math::Clipper::offset([$p], -(scale $Slic3r::flow_spacing / 2), $Slic3r::resolution * 100000, JT_MITER, 2);
- return @$offsets ? 1 : 0;
-}
-
-sub is_valid {
- my $self = shift;
- return @{$self->points} >= 3;
-}
-
-sub polygon {
- my $self = shift;
- return Slic3r::Polygon->new($self->points);
-}
-
-1;
diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm
index 1129080d4..90157a4dc 100644
--- a/lib/Slic3r/Print.pm
+++ b/lib/Slic3r/Print.pm
@@ -125,8 +125,8 @@ sub new_from_mesh {
[ map $_->expolygon->holes, @upper_surfaces, @lower_surfaces, ],
);
- @{$layer->slices} = map Slic3r::Surface->cast_from_expolygon
- ($_, surface_type => 'internal'),
+ @{$layer->slices} = map Slic3r::Surface->new
+ (expolygon => $_, surface_type => 'internal'),
@$diff;
}
@@ -178,7 +178,7 @@ sub detect_surfaces_type {
1,
);
return grep $_->contour->is_printable,
- map Slic3r::Surface->cast_from_expolygon($_, surface_type => $result_type),
+ map Slic3r::Surface->new(expolygon => $_, surface_type => $result_type),
@$expolygons;
};
@@ -223,7 +223,7 @@ sub detect_surfaces_type {
@internal = $surface_difference->($layer->slices, [@top, @bottom], 'internal');
# save surfaces to layer
- $layer->slices([ @bottom, @top, @internal ]);
+ @{$layer->slices} = (@bottom, @top, @internal);
Slic3r::debugf " layer %d has %d bottom, %d top and %d internal surfaces\n",
$layer->id, scalar(@bottom), scalar(@top), scalar(@internal);
@@ -235,10 +235,10 @@ sub detect_surfaces_type {
foreach my $surface (@{$layer->slices}) {
my $intersection = intersection_ex(
[ $surface->p ],
- [ map $_->p, @{$layer->fill_boundaries} ],
+ [ map @$_, @{$layer->fill_boundaries} ],
);
- push @{$layer->surfaces}, map Slic3r::Surface->cast_from_expolygon
- ($_, surface_type => $surface->surface_type),
+ push @{$layer->surfaces}, map Slic3r::Surface->new
+ (expolygon => $_, surface_type => $surface->surface_type),
@$intersection;
}
}
@@ -298,13 +298,13 @@ sub discover_horizontal_shells {
# assign resulting inner surfaces to layer
my $neighbor_fill_surfaces = $self->layers->[$n]->fill_surfaces;
@$neighbor_fill_surfaces = ();
- push @$neighbor_fill_surfaces, Slic3r::Surface->cast_from_expolygon
- ($_, surface_type => 'internal')
+ push @$neighbor_fill_surfaces, Slic3r::Surface->new
+ (expolygon => $_, surface_type => 'internal')
for @$internal;
# assign new internal-solid surfaces to layer
- push @$neighbor_fill_surfaces, Slic3r::Surface->cast_from_expolygon
- ($_, surface_type => 'internal-solid')
+ push @$neighbor_fill_surfaces, Slic3r::Surface->new
+ (expolygon => $_, surface_type => 'internal-solid')
for @$internal_solid;
# assign top and bottom surfaces to layer
@@ -313,8 +313,8 @@ sub discover_horizontal_shells {
[ map $_->p, @$s ],
[ map @$_, @$internal_solid, @$internal ],
);
- push @$neighbor_fill_surfaces, Slic3r::Surface->cast_from_expolygon
- ($_, surface_type => $s->[0]->surface_type, bridge_angle => $s->[0]->bridge_angle)
+ push @$neighbor_fill_surfaces, Slic3r::Surface->new
+ (expolygon => $_, surface_type => $s->[0]->surface_type, bridge_angle => $s->[0]->bridge_angle)
for @$solid_surfaces;
}
}
@@ -341,7 +341,10 @@ sub extrude_skirt {
for (my $i = $Slic3r::skirts - 1; $i >= 0; $i--) {
my $distance = scale ($Slic3r::skirt_distance + ($Slic3r::flow_spacing * $i));
my $outline = offset([$convex_hull], $distance, $Slic3r::resolution * 100, JT_ROUND);
- push @skirts, Slic3r::ExtrusionLoop->cast([ @{$outline->[0]} ], role => 'skirt');
+ push @skirts, Slic3r::ExtrusionLoop->new(
+ polygon => Slic3r::Polygon->new(@{$outline->[0]}),
+ role => 'skirt',
+ );
}
# apply skirts to all layers
@@ -387,12 +390,12 @@ sub infill_every_layers {
{
my @new_surfaces = ();
push @new_surfaces, grep $_->surface_type ne 'internal', @{$layer->fill_surfaces};
- push @new_surfaces, map Slic3r::Surface->cast_from_expolygon
- ($_, surface_type => 'internal', depth_layers => $d + 1), @$intersection;
+ push @new_surfaces, map Slic3r::Surface->new
+ (expolygon => $_, surface_type => 'internal', depth_layers => $d + 1), @$intersection;
foreach my $depth (reverse $d..$Slic3r::infill_every_layers) {
- push @new_surfaces, map Slic3r::Surface->cast_from_expolygon
- ($_, surface_type => 'internal', depth_layers => $depth),
+ push @new_surfaces, map Slic3r::Surface->new
+ (expolygon => $_, surface_type => 'internal', depth_layers => $depth),
# difference between our internal layers with depth == $depth
# and the intersection found
@@ -413,8 +416,8 @@ sub infill_every_layers {
my @new_surfaces = ();
push @new_surfaces, grep $_->surface_type ne 'internal', @{$lower_layer->fill_surfaces};
foreach my $depth (1..$Slic3r::infill_every_layers) {
- push @new_surfaces, map Slic3r::Surface->cast_from_expolygon
- ($_, surface_type => 'internal', depth_layers => $depth),
+ push @new_surfaces, map Slic3r::Surface->new
+ (expolygon => $_, surface_type => 'internal', depth_layers => $depth),
# difference between internal layers with depth == $depth
# and the intersection found
diff --git a/lib/Slic3r/Surface.pm b/lib/Slic3r/Surface.pm
index b1f3ee545..8605f7b81 100644
--- a/lib/Slic3r/Surface.pm
+++ b/lib/Slic3r/Surface.pm
@@ -1,17 +1,10 @@
package Slic3r::Surface;
use Moo;
-has 'contour' => (
- is => 'ro',
- #isa => 'Slic3r::Polyline::Closed',
- required => 1,
-);
-
-has 'holes' => (
- traits => ['Array'],
- is => 'rw',
- #isa => 'ArrayRef[Slic3r::Polyline::Closed]',
- default => sub { [] },
+has 'expolygon' => (
+ is => 'ro',
+ required => 1,
+ handles => [qw(encloses_point lines contour holes)],
);
has 'surface_type' => (
@@ -24,31 +17,6 @@ has 'depth_layers' => (is => 'ro', default => sub {1});
has 'bridge_angle' => (is => 'ro');
-sub cast_from_polygon {
- my $class = shift;
- my ($polygon, %args) = @_;
-
- return $class->new(
- contour => Slic3r::Polyline::Closed->cast($polygon),
- %args,
- );
-}
-
-sub cast_from_expolygon {
- my $class = shift;
- my ($expolygon, %args) = @_;
-
- if (ref $expolygon eq 'HASH') {
- $expolygon = Slic3r::ExPolygon->new($expolygon);
- }
-
- return $class->new(
- contour => $expolygon->contour->closed_polyline,
- holes => [ map $_->closed_polyline, $expolygon->holes ],
- %args,
- );
-}
-
# static method to group surfaces having same surface_type, bridge_angle and depth_layers
sub group {
my $class = shift;
@@ -73,7 +41,7 @@ sub add_hole {
my $self = shift;
my ($hole) = @_;
- push @{ $self->holes }, $hole;
+ push @$self, $hole;
}
sub id {
@@ -81,15 +49,6 @@ sub id {
return $self->contour->id;
}
-sub encloses_point {
- my $self = shift;
- my ($point) = @_;
-
- return 0 if !$self->contour->encloses_point($point);
- return 0 if grep $_->encloses_point($point), @{ $self->holes };
- return 1;
-}
-
sub clipper_polygon {
my $self = shift;
@@ -102,18 +61,8 @@ sub clipper_polygon {
}
sub p {
- my $self = shift;
- return ($self->contour->p, map $_->p, @{$self->holes});
-}
-
-sub expolygon {
- my $self = shift;
- return Slic3r::ExPolygon->new($self->contour->p, map $_->p, @{$self->holes});
-}
-
-sub lines {
- my $self = shift;
- return @{ $self->contour->lines }, map @{ $_->lines }, @{ $self->holes };
+ my $self = shift;use XXX; ZZZ $self->expolygon if !eval { 1 if @{$self->expolygon}; 1 };
+ return @{$self->expolygon};
}
1;
diff --git a/t/arcs.t b/t/arcs.t
index 9faaaf8bc..2589e908f 100644
--- a/t/arcs.t
+++ b/t/arcs.t
@@ -13,13 +13,13 @@ use Slic3r;
use Slic3r::Geometry qw(epsilon);
{
- my $path = Slic3r::ExtrusionPath->cast([
+ my $path = Slic3r::ExtrusionPath->new(polyline => Slic3r::Polyline->new(
[135322.42,26654.96], [187029.11,99546.23], [222515.14,92381.93], [258001.16,99546.23],
[286979.42,119083.91], [306517.1,148062.17], [313681.4,183548.2],
[306517.1,219034.23], [286979.42,248012.49], [258001.16,267550.17], [222515.14,274714.47],
[187029.11,267550.17], [158050.85,248012.49], [138513.17,219034.23], [131348.87,183548.2],
[86948.77,175149.09], [119825.35,100585],
- ], role => 'fill');
+ ), role => 'fill');
my $collection = Slic3r::ExtrusionPath::Collection->new(paths => [$path]);
$collection->detect_arcs(30);
@@ -31,14 +31,17 @@ use Slic3r::Geometry qw(epsilon);
#==========================================================
{
- my $path1 = Slic3r::ExtrusionPath->cast([
+ my $path1 = Slic3r::ExtrusionPath->new(polyline => Slic3r::Polyline->new(
[10,20], [10.7845909572784,19.9691733373313], [11.5643446504023,19.8768834059514],
[12.3344536385591,19.7236992039768], [13.0901699437495,19.5105651629515],
[13.8268343236509,19.2387953251129], [14.5399049973955,18.9100652418837],
[15.2249856471595,18.5264016435409], [15.8778525229247,18.0901699437495],
[16.4944804833018,17.6040596560003],
- ], role => 'fill');
- my $path2 = Slic3r::ExtrusionPath->cast([ reverse @{$path1->points} ], role => 'fill');
+ ), role => 'fill');
+ my $path2 = Slic3r::ExtrusionPath->new(
+ polyline => Slic3r::Polyline->new(reverse @{$path1->points}),
+ role => 'fill',
+ );
my $collection1 = Slic3r::ExtrusionPath::Collection->new(paths => [$path1]);
my $collection2 = Slic3r::ExtrusionPath::Collection->new(paths => [$path2]);
diff --git a/t/clean_polylines.t b/t/clean_polylines.t
index e87575ae9..8f9cbafa1 100644
--- a/t/clean_polylines.t
+++ b/t/clean_polylines.t
@@ -2,7 +2,7 @@ use Test::More;
use strict;
use warnings;
-plan tests => 4;
+plan tests => 3;
BEGIN {
use FindBin;
@@ -11,87 +11,96 @@ BEGIN {
use Slic3r;
-my $polyline = Slic3r::Polyline::Closed->cast([
- [5,0], [10,0], [15,0], [20,0], [20,10], [20,30], [0,0],
-]);
-
-$polyline->merge_continuous_lines;
-is scalar(@{$polyline->points}), 3, 'merge_continuous_lines';
-
-my $gear = [
- [144.9694,317.1543], [145.4181,301.5633], [146.3466,296.921], [131.8436,294.1643], [131.7467,294.1464],
- [121.7238,291.5082], [117.1631,290.2776], [107.9198,308.2068], [100.1735,304.5101], [104.9896,290.3672],
- [106.6511,286.2133], [93.453,279.2327], [81.0065,271.4171], [67.7886,286.5055], [60.7927,280.1127],
- [69.3928,268.2566], [72.7271,264.9224], [61.8152,253.9959], [52.2273,242.8494], [47.5799,245.7224],
- [34.6577,252.6559], [30.3369,245.2236], [42.1712,236.3251], [46.1122,233.9605], [43.2099,228.4876],
- [35.0862,211.5672], [33.1441,207.0856], [13.3923,212.1895], [10.6572,203.3273], [6.0707,204.8561],
- [7.2775,204.4259], [29.6713,196.3631], [25.9815,172.1277], [25.4589,167.2745], [19.8337,167.0129],
- [5.0625,166.3346], [5.0625,156.9425], [5.3701,156.9282], [21.8636,156.1628], [25.3713,156.4613],
- [25.4243,155.9976], [29.3432,155.8157], [30.3838,149.3549], [26.3596,147.8137], [27.1085,141.2604],
- [29.8466,126.8337], [24.5841,124.9201], [10.6664,119.8989], [13.4454,110.9264], [33.1886,116.0691],
- [38.817,103.1819], [45.8311,89.8133], [30.4286,76.81], [35.7686,70.0812], [48.0879,77.6873],
- [51.564,81.1635], [61.9006,69.1791], [72.3019,58.7916], [60.5509,42.5416], [68.3369,37.1532],
- [77.9524,48.1338], [80.405,52.2215], [92.5632,44.5992], [93.0123,44.3223], [106.3561,37.2056],
- [100.8631,17.4679], [108.759,14.3778], [107.3148,11.1283], [117.0002,32.8627], [140.9109,27.3974],
- [145.7004,26.4994], [145.1346,6.1011], [154.502,5.4063], [156.9398,25.6501], [171.0557,26.2017],
- [181.3139,27.323], [186.2377,27.8532], [191.6031,8.5474], [200.6724,11.2756], [197.2362,30.2334],
- [220.0789,39.1906], [224.3261,41.031], [236.3506,24.4291], [243.6897,28.6723], [234.2956,46.7747],
- [245.6562,55.1643], [257.2523,65.0901], [261.4374,61.5679], [273.1709,52.8031], [278.555,59.5164],
- [268.4334,69.8001], [264.1615,72.3633], [268.2763,77.9442], [278.8488,93.5305], [281.4596,97.6332],
- [286.4487,95.5191], [300.2821,90.5903], [303.4456,98.5849], [286.4523,107.7253], [293.7063,131.1779],
- [294.9748,135.8787], [314.918,133.8172], [315.6941,143.2589], [300.9234,146.1746], [296.6419,147.0309],
- [297.1839,161.7052], [296.6136,176.3942], [302.1147,177.4857], [316.603,180.3608], [317.1658,176.7341],
- [315.215,189.6589], [315.1749,189.6548], [294.9411,187.5222], [291.13,201.7233], [286.2615,215.5916],
- [291.1944,218.2545], [303.9158,225.1271], [299.2384,233.3694], [285.7165,227.6001], [281.7091,225.1956],
- [273.8981,237.6457], [268.3486,245.2248], [267.4538,246.4414], [264.8496,250.0221], [268.6392,253.896],
- [278.5017,265.2131], [272.721,271.4403], [257.2776,258.3579], [234.4345,276.5687], [242.6222,294.8315],
- [234.9061,298.5798], [227.0321,286.2841], [225.2505,281.8301], [211.5387,287.8187], [202.3025,291.0935],
- [197.307,292.831], [199.808,313.1906], [191.5298,315.0787], [187.3082,299.8172], [186.4201,295.3766],
- [180.595,296.0487], [161.7854,297.4248], [156.8058,297.6214], [154.3395,317.8592],
-];
-$polyline = Slic3r::Polyline::Closed->cast($gear);
-$polyline->merge_continuous_lines;
-note sprintf "original points: %d\nnew points: %d", scalar(@$gear), scalar(@{$polyline->points});
-ok @{$polyline->points} < @$gear, 'gear was simplified using merge_continuous_lines';
+{
+ my $polygon = Slic3r::Polygon->new([
+ [5,0], [10,0], [15,0], [20,0], [20,10], [20,30], [0,0],
+ ]);
+
+ $polygon->merge_continuous_lines;
+ is scalar(@$polygon), 3, 'merge_continuous_lines';
+}
-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 $gear = [
+ [144.9694,317.1543], [145.4181,301.5633], [146.3466,296.921], [131.8436,294.1643], [131.7467,294.1464],
+ [121.7238,291.5082], [117.1631,290.2776], [107.9198,308.2068], [100.1735,304.5101], [104.9896,290.3672],
+ [106.6511,286.2133], [93.453,279.2327], [81.0065,271.4171], [67.7886,286.5055], [60.7927,280.1127],
+ [69.3928,268.2566], [72.7271,264.9224], [61.8152,253.9959], [52.2273,242.8494], [47.5799,245.7224],
+ [34.6577,252.6559], [30.3369,245.2236], [42.1712,236.3251], [46.1122,233.9605], [43.2099,228.4876],
+ [35.0862,211.5672], [33.1441,207.0856], [13.3923,212.1895], [10.6572,203.3273], [6.0707,204.8561],
+ [7.2775,204.4259], [29.6713,196.3631], [25.9815,172.1277], [25.4589,167.2745], [19.8337,167.0129],
+ [5.0625,166.3346], [5.0625,156.9425], [5.3701,156.9282], [21.8636,156.1628], [25.3713,156.4613],
+ [25.4243,155.9976], [29.3432,155.8157], [30.3838,149.3549], [26.3596,147.8137], [27.1085,141.2604],
+ [29.8466,126.8337], [24.5841,124.9201], [10.6664,119.8989], [13.4454,110.9264], [33.1886,116.0691],
+ [38.817,103.1819], [45.8311,89.8133], [30.4286,76.81], [35.7686,70.0812], [48.0879,77.6873],
+ [51.564,81.1635], [61.9006,69.1791], [72.3019,58.7916], [60.5509,42.5416], [68.3369,37.1532],
+ [77.9524,48.1338], [80.405,52.2215], [92.5632,44.5992], [93.0123,44.3223], [106.3561,37.2056],
+ [100.8631,17.4679], [108.759,14.3778], [107.3148,11.1283], [117.0002,32.8627], [140.9109,27.3974],
+ [145.7004,26.4994], [145.1346,6.1011], [154.502,5.4063], [156.9398,25.6501], [171.0557,26.2017],
+ [181.3139,27.323], [186.2377,27.8532], [191.6031,8.5474], [200.6724,11.2756], [197.2362,30.2334],
+ [220.0789,39.1906], [224.3261,41.031], [236.3506,24.4291], [243.6897,28.6723], [234.2956,46.7747],
+ [245.6562,55.1643], [257.2523,65.0901], [261.4374,61.5679], [273.1709,52.8031], [278.555,59.5164],
+ [268.4334,69.8001], [264.1615,72.3633], [268.2763,77.9442], [278.8488,93.5305], [281.4596,97.6332],
+ [286.4487,95.5191], [300.2821,90.5903], [303.4456,98.5849], [286.4523,107.7253], [293.7063,131.1779],
+ [294.9748,135.8787], [314.918,133.8172], [315.6941,143.2589], [300.9234,146.1746], [296.6419,147.0309],
+ [297.1839,161.7052], [296.6136,176.3942], [302.1147,177.4857], [316.603,180.3608], [317.1658,176.7341],
+ [315.215,189.6589], [315.1749,189.6548], [294.9411,187.5222], [291.13,201.7233], [286.2615,215.5916],
+ [291.1944,218.2545], [303.9158,225.1271], [299.2384,233.3694], [285.7165,227.6001], [281.7091,225.1956],
+ [273.8981,237.6457], [268.3486,245.2248], [267.4538,246.4414], [264.8496,250.0221], [268.6392,253.896],
+ [278.5017,265.2131], [272.721,271.4403], [257.2776,258.3579], [234.4345,276.5687], [242.6222,294.8315],
+ [234.9061,298.5798], [227.0321,286.2841], [225.2505,281.8301], [211.5387,287.8187], [202.3025,291.0935],
+ [197.307,292.831], [199.808,313.1906], [191.5298,315.0787], [187.3082,299.8172], [186.4201,295.3766],
+ [180.595,296.0487], [161.7854,297.4248], [156.8058,297.6214], [154.3395,317.8592],
+ ];
+ my $polygon = Slic3r::Polygon->new($gear);
+ $polygon->merge_continuous_lines;
+ note sprintf "original points: %d\nnew points: %d", scalar(@$gear), scalar(@$polygon);
+ ok @$polygon < @$gear, 'gear was simplified using merge_continuous_lines';
-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],
-];
+ # simplify() is not being used, so we don't test it
+ if (0) {
+ my $num_points = scalar @$polygon;
+ $polygon->simplify;
+ note sprintf "original points: %d\nnew points: %d", $num_points, scalar(@$polygon);
+ ok @$polygon < $num_points, 'gear was further simplified using Douglas-Peucker';
+ }
+}
-$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';
+{
+ 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],
+ ];
+
+ my $polygon = Slic3r::Polygon->new($circle);
+ $polygon->merge_continuous_lines;
+ note sprintf "original points: %d\nnew points: %d", scalar(@$circle), scalar(@$polygon);
+ ok @$polygon >= @$circle/3, 'circle was simplified using merge_continuous_lines';
+}
diff --git a/t/polyclip.t b/t/polyclip.t
index 205f036c8..4b3006e1a 100644
--- a/t/polyclip.t
+++ b/t/polyclip.t
@@ -103,8 +103,8 @@ is_deeply $intersection, [ [12, 12], [18, 16] ], 'internal lines are preserved';
], 'tangent line is clipped to square with hole';
}
{
- my $polyline = Slic3r::Polyline->cast([ [5, 18], [25, 18], [25, 15], [15, 15], [15, 12], [12, 12], [12, 5] ]);
- is_deeply [ map $_->p, $polyline->clip_with_expolygon($expolygon) ], [
+ my $polyline = Slic3r::Polyline->new([ [5, 18], [25, 18], [25, 15], [15, 15], [15, 12], [12, 12], [12, 5] ]);
+ is_deeply [ map $_, $polyline->clip_with_expolygon($expolygon) ], [
[ [10, 18], [20, 18] ],
[ [20, 15], [16, 15] ],
[ [15, 14], [15, 12], [12, 12], [12, 10] ],