From 6cab5668e30d7168421178c36d41b790e260ec7b Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Mon, 9 Mar 2015 18:28:07 +0100 Subject: [PATCH] Restore correct ordering of concentric infill loops, preventing them from being reordered during G-code generation --- lib/Slic3r/Fill/Concentric.pm | 4 +++- xs/src/libslic3r/ExtrusionEntity.hpp | 6 ++++++ xs/src/libslic3r/ExtrusionEntityCollection.cpp | 4 ++-- xs/src/libslic3r/ExtrusionEntityCollection.hpp | 3 +++ xs/t/12_extrusionpathcollection.t | 9 ++++++++- xs/xsp/ExtrusionEntityCollection.xsp | 2 ++ 6 files changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/Slic3r/Fill/Concentric.pm b/lib/Slic3r/Fill/Concentric.pm index 1bc9b79f9..ca1837c4e 100644 --- a/lib/Slic3r/Fill/Concentric.pm +++ b/lib/Slic3r/Fill/Concentric.pm @@ -6,6 +6,8 @@ extends 'Slic3r::Fill::Base'; use Slic3r::Geometry qw(scale unscale X); use Slic3r::Geometry::Clipper qw(offset offset2 union_pt_chained); +sub no_sort { 1 } + sub fill_surface { my $self = shift; my ($surface, %params) = @_; @@ -36,7 +38,7 @@ sub fill_surface { @loops = map Slic3r::Polygon->new(@$_), reverse @{union_pt_chained(\@loops)}; - # order paths using a nearest neighbor search + # split paths using a nearest neighbor search my @paths = (); my $last_pos = Slic3r::Point->new(0,0); foreach my $loop (@loops) { diff --git a/xs/src/libslic3r/ExtrusionEntity.hpp b/xs/src/libslic3r/ExtrusionEntity.hpp index 323d935a1..d785c8f65 100644 --- a/xs/src/libslic3r/ExtrusionEntity.hpp +++ b/xs/src/libslic3r/ExtrusionEntity.hpp @@ -38,6 +38,9 @@ class ExtrusionEntity virtual bool is_loop() const { return false; }; + virtual bool can_reverse() const { + return true; + }; virtual ExtrusionEntity* clone() const = 0; virtual ~ExtrusionEntity() {}; virtual void reverse() = 0; @@ -92,6 +95,9 @@ class ExtrusionLoop : public ExtrusionEntity bool is_loop() const { return true; }; + bool can_reverse() const { + return false; + }; ExtrusionLoop* clone() const; bool make_clockwise(); bool make_counter_clockwise(); diff --git a/xs/src/libslic3r/ExtrusionEntityCollection.cpp b/xs/src/libslic3r/ExtrusionEntityCollection.cpp index 4ceef0387..4afbd8887 100644 --- a/xs/src/libslic3r/ExtrusionEntityCollection.cpp +++ b/xs/src/libslic3r/ExtrusionEntityCollection.cpp @@ -86,7 +86,7 @@ ExtrusionEntityCollection::chained_path_from(Point start_near, ExtrusionEntityCo Points endpoints; for (ExtrusionEntitiesPtr::iterator it = my_paths.begin(); it != my_paths.end(); ++it) { endpoints.push_back((*it)->first_point()); - if (no_reverse) { + if (no_reverse || !(*it)->can_reverse()) { endpoints.push_back((*it)->first_point()); } else { endpoints.push_back((*it)->last_point()); @@ -99,7 +99,7 @@ ExtrusionEntityCollection::chained_path_from(Point start_near, ExtrusionEntityCo int path_index = start_index/2; ExtrusionEntity* entity = my_paths.at(path_index); // never reverse loops, since it's pointless for chained path and callers might depend on orientation - if (start_index % 2 && !no_reverse && !entity->is_loop()) { + if (start_index % 2 && !no_reverse && entity->can_reverse()) { entity->reverse(); } retval->entities.push_back(my_paths.at(path_index)); diff --git a/xs/src/libslic3r/ExtrusionEntityCollection.hpp b/xs/src/libslic3r/ExtrusionEntityCollection.hpp index be557bb5f..6264b4faf 100644 --- a/xs/src/libslic3r/ExtrusionEntityCollection.hpp +++ b/xs/src/libslic3r/ExtrusionEntityCollection.hpp @@ -16,6 +16,9 @@ class ExtrusionEntityCollection : public ExtrusionEntity ExtrusionEntityCollection(): no_sort(false) {}; ExtrusionEntityCollection(const ExtrusionEntityCollection &collection); ExtrusionEntityCollection& operator= (const ExtrusionEntityCollection &other); + bool can_reverse() const { + return !this->no_sort; + }; void swap (ExtrusionEntityCollection &c); void chained_path(ExtrusionEntityCollection* retval, bool no_reverse = false, std::vector* orig_indices = NULL) const; void chained_path_from(Point start_near, ExtrusionEntityCollection* retval, bool no_reverse = false, std::vector* orig_indices = NULL) const; diff --git a/xs/t/12_extrusionpathcollection.t b/xs/t/12_extrusionpathcollection.t index 73608cba7..e7e0b1316 100644 --- a/xs/t/12_extrusionpathcollection.t +++ b/xs/t/12_extrusionpathcollection.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], @@ -87,4 +87,11 @@ is scalar(@{$collection->[1]}), 1, 'appended collection was duplicated'; pass 'chained_path with no_sort'; } +{ + my $coll2 = $collection->clone; + ok !$coll2->no_sort, 'expected no_sort value'; + $coll2->no_sort(1); + ok $coll2->clone->no_sort, 'no_sort is kept after clone'; +} + __END__ diff --git a/xs/xsp/ExtrusionEntityCollection.xsp b/xs/xsp/ExtrusionEntityCollection.xsp index a7c5a8be0..f5b075888 100644 --- a/xs/xsp/ExtrusionEntityCollection.xsp +++ b/xs/xsp/ExtrusionEntityCollection.xsp @@ -7,6 +7,8 @@ %name{Slic3r::ExtrusionPath::Collection} class ExtrusionEntityCollection { %name{_new} ExtrusionEntityCollection(); + Clone clone() + %code{% RETVAL = THIS->clone(); %}; void reverse(); void clear() %code{% THIS->entities.clear(); %};