From 6776d6bc00101de798df0eb5ec1f453162b3ac94 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Mon, 5 Jan 2015 15:51:57 +0100 Subject: [PATCH] Bugfix: a bug in Polyline::split_at() caused random loss of perimeter segments. #2495 --- lib/Slic3r/Point.pm | 5 +++++ xs/src/libslic3r/ExtrusionEntity.cpp | 2 +- xs/src/libslic3r/Polyline.cpp | 2 +- xs/t/08_extrusionloop.t | 15 ++++++++++++++- xs/t/09_polyline.t | 11 ++++++++++- 5 files changed, 31 insertions(+), 4 deletions(-) diff --git a/lib/Slic3r/Point.pm b/lib/Slic3r/Point.pm index abb7a5edf..6d9e0891a 100644 --- a/lib/Slic3r/Point.pm +++ b/lib/Slic3r/Point.pm @@ -7,6 +7,11 @@ sub new_scale { return $class->new(map Slic3r::Geometry::scale($_), @_); } +sub dump_perl { + my $self = shift; + return sprintf "[%s,%s]", @$self; +} + package Slic3r::Pointf; use strict; use warnings; diff --git a/xs/src/libslic3r/ExtrusionEntity.cpp b/xs/src/libslic3r/ExtrusionEntity.cpp index ee49e3357..843dfda29 100644 --- a/xs/src/libslic3r/ExtrusionEntity.cpp +++ b/xs/src/libslic3r/ExtrusionEntity.cpp @@ -278,7 +278,7 @@ ExtrusionLoop::split_at(const Point &point) { if (this->paths.empty()) return; - // find the closest path and closest point + // find the closest path and closest point belonging to that path size_t path_idx = 0; Point p = this->paths.front().first_point(); double min = point.distance_to(p); diff --git a/xs/src/libslic3r/Polyline.cpp b/xs/src/libslic3r/Polyline.cpp index 1ae5055ba..7f27adf58 100644 --- a/xs/src/libslic3r/Polyline.cpp +++ b/xs/src/libslic3r/Polyline.cpp @@ -159,7 +159,7 @@ Polyline::split_at(const Point &point, Polyline* p1, Polyline* p2) const p2->points.clear(); p2->points.push_back(point); for (Lines::const_iterator line = lines.begin() + line_idx; line != lines.end(); ++line) { - if (!line->b.coincides_with(p)) p2->points.push_back(line->b); + p2->points.push_back(line->b); } } diff --git a/xs/t/08_extrusionloop.t b/xs/t/08_extrusionloop.t index 0657766c8..92d720dc3 100644 --- a/xs/t/08_extrusionloop.t +++ b/xs/t/08_extrusionloop.t @@ -5,7 +5,7 @@ use warnings; use List::Util qw(sum); use Slic3r::XS; -use Test::More tests => 46; +use Test::More tests => 48; { my $square = [ @@ -133,8 +133,10 @@ use Test::More tests => 46; Slic3r::ExtrusionPath->new(polyline => $polylines[2], role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, mm3_per_mm => 1), Slic3r::ExtrusionPath->new(polyline => $polylines[3], role => Slic3r::ExtrusionPath::EXTR_ROLE_OVERHANG_PERIMETER, mm3_per_mm => 1), ); + my $len = $loop->length; my $point = Slic3r::Point->new(4821067,9321068); $loop->split_at_vertex($point) or $loop->split_at($point); + is $loop->length, $len, 'total length is preserved after splitting'; is_deeply [ map $_->role, @$loop ], [ Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, Slic3r::ExtrusionPath::EXTR_ROLE_OVERHANG_PERIMETER, @@ -144,4 +146,15 @@ use Test::More tests => 46; ], 'order is correctly preserved after splitting'; } +{ + my $loop = Slic3r::ExtrusionLoop->new; + $loop->append(Slic3r::ExtrusionPath->new( + polyline => Slic3r::Polyline->new([15896783,15868739],[24842049,12117558],[33853238,15801279],[37591780,24780128],[37591780,24844970],[33853231,33825297],[24842049,37509013],[15896798,33757841],[12211841,24812544],[15896783,15868739]), + role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, mm3_per_mm => 1 + )); + my $len = $loop->length; + $loop->split_at(Slic3r::Point->new(15896783,15868739)); + is $loop->length, $len, 'split_at() preserves total length'; +} + __END__ diff --git a/xs/t/09_polyline.t b/xs/t/09_polyline.t index 99077aad3..824f049e9 100644 --- a/xs/t/09_polyline.t +++ b/xs/t/09_polyline.t @@ -4,7 +4,7 @@ use strict; use warnings; use Slic3r::XS; -use Test::More tests => 16; +use Test::More tests => 18; my $points = [ [100, 100], @@ -79,4 +79,13 @@ is_deeply $polyline->pp, [ @$points, @$points ], 'append_polyline'; ok $p2->first_point->coincides_with($point), 'split_at'; } +{ + my $polyline = Slic3r::Polyline->new(@$points[0,1,2,0]); + my $p1 = Slic3r::Polyline->new; + my $p2 = Slic3r::Polyline->new; + $polyline->split_at($polyline->first_point, $p1, $p2); + is scalar(@$p1), 1, 'split_at'; + is scalar(@$p2), 4, 'split_at'; +} + __END__