Просмотр исходного кода

Restore correct ordering of concentric infill loops, preventing them from being reordered during G-code generation

Alessandro Ranellucci 10 лет назад
Родитель
Сommit
6cab5668e3

+ 3 - 1
lib/Slic3r/Fill/Concentric.pm

@@ -6,6 +6,8 @@ extends 'Slic3r::Fill::Base';
 use Slic3r::Geometry qw(scale unscale X);
 use Slic3r::Geometry qw(scale unscale X);
 use Slic3r::Geometry::Clipper qw(offset offset2 union_pt_chained);
 use Slic3r::Geometry::Clipper qw(offset offset2 union_pt_chained);
 
 
+sub no_sort { 1 }
+
 sub fill_surface {
 sub fill_surface {
     my $self = shift;
     my $self = shift;
     my ($surface, %params) = @_;
     my ($surface, %params) = @_;
@@ -36,7 +38,7 @@ sub fill_surface {
     @loops = map Slic3r::Polygon->new(@$_),
     @loops = map Slic3r::Polygon->new(@$_),
         reverse @{union_pt_chained(\@loops)};
         reverse @{union_pt_chained(\@loops)};
     
     
-    # order paths using a nearest neighbor search
+    # split paths using a nearest neighbor search
     my @paths = ();
     my @paths = ();
     my $last_pos = Slic3r::Point->new(0,0);
     my $last_pos = Slic3r::Point->new(0,0);
     foreach my $loop (@loops) {
     foreach my $loop (@loops) {

+ 6 - 0
xs/src/libslic3r/ExtrusionEntity.hpp

@@ -38,6 +38,9 @@ class ExtrusionEntity
     virtual bool is_loop() const {
     virtual bool is_loop() const {
         return false;
         return false;
     };
     };
+    virtual bool can_reverse() const {
+        return true;
+    };
     virtual ExtrusionEntity* clone() const = 0;
     virtual ExtrusionEntity* clone() const = 0;
     virtual ~ExtrusionEntity() {};
     virtual ~ExtrusionEntity() {};
     virtual void reverse() = 0;
     virtual void reverse() = 0;
@@ -92,6 +95,9 @@ class ExtrusionLoop : public ExtrusionEntity
     bool is_loop() const {
     bool is_loop() const {
         return true;
         return true;
     };
     };
+    bool can_reverse() const {
+        return false;
+    };
     ExtrusionLoop* clone() const;
     ExtrusionLoop* clone() const;
     bool make_clockwise();
     bool make_clockwise();
     bool make_counter_clockwise();
     bool make_counter_clockwise();

+ 2 - 2
xs/src/libslic3r/ExtrusionEntityCollection.cpp

@@ -86,7 +86,7 @@ ExtrusionEntityCollection::chained_path_from(Point start_near, ExtrusionEntityCo
     Points endpoints;
     Points endpoints;
     for (ExtrusionEntitiesPtr::iterator it = my_paths.begin(); it != my_paths.end(); ++it) {
     for (ExtrusionEntitiesPtr::iterator it = my_paths.begin(); it != my_paths.end(); ++it) {
         endpoints.push_back((*it)->first_point());
         endpoints.push_back((*it)->first_point());
-        if (no_reverse) {
+        if (no_reverse || !(*it)->can_reverse()) {
             endpoints.push_back((*it)->first_point());
             endpoints.push_back((*it)->first_point());
         } else {
         } else {
             endpoints.push_back((*it)->last_point());
             endpoints.push_back((*it)->last_point());
@@ -99,7 +99,7 @@ ExtrusionEntityCollection::chained_path_from(Point start_near, ExtrusionEntityCo
         int path_index = start_index/2;
         int path_index = start_index/2;
         ExtrusionEntity* entity = my_paths.at(path_index);
         ExtrusionEntity* entity = my_paths.at(path_index);
         // never reverse loops, since it's pointless for chained path and callers might depend on orientation
         // 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();
             entity->reverse();
         }
         }
         retval->entities.push_back(my_paths.at(path_index));
         retval->entities.push_back(my_paths.at(path_index));

+ 3 - 0
xs/src/libslic3r/ExtrusionEntityCollection.hpp

@@ -16,6 +16,9 @@ class ExtrusionEntityCollection : public ExtrusionEntity
     ExtrusionEntityCollection(): no_sort(false) {};
     ExtrusionEntityCollection(): no_sort(false) {};
     ExtrusionEntityCollection(const ExtrusionEntityCollection &collection);
     ExtrusionEntityCollection(const ExtrusionEntityCollection &collection);
     ExtrusionEntityCollection& operator= (const ExtrusionEntityCollection &other);
     ExtrusionEntityCollection& operator= (const ExtrusionEntityCollection &other);
+    bool can_reverse() const {
+        return !this->no_sort;
+    };
     void swap (ExtrusionEntityCollection &c);
     void swap (ExtrusionEntityCollection &c);
     void chained_path(ExtrusionEntityCollection* retval, bool no_reverse = false, std::vector<size_t>* orig_indices = NULL) const;
     void chained_path(ExtrusionEntityCollection* retval, bool no_reverse = false, std::vector<size_t>* orig_indices = NULL) const;
     void chained_path_from(Point start_near, ExtrusionEntityCollection* retval, bool no_reverse = false, std::vector<size_t>* orig_indices = NULL) const;
     void chained_path_from(Point start_near, ExtrusionEntityCollection* retval, bool no_reverse = false, std::vector<size_t>* orig_indices = NULL) const;

+ 8 - 1
xs/t/12_extrusionpathcollection.t

@@ -4,7 +4,7 @@ use strict;
 use warnings;
 use warnings;
 
 
 use Slic3r::XS;
 use Slic3r::XS;
-use Test::More tests => 16;
+use Test::More tests => 18;
 
 
 my $points = [
 my $points = [
     [100, 100],
     [100, 100],
@@ -87,4 +87,11 @@ is scalar(@{$collection->[1]}), 1, 'appended collection was duplicated';
     pass 'chained_path with no_sort';
     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__
 __END__

+ 2 - 0
xs/xsp/ExtrusionEntityCollection.xsp

@@ -7,6 +7,8 @@
 
 
 %name{Slic3r::ExtrusionPath::Collection} class ExtrusionEntityCollection {
 %name{Slic3r::ExtrusionPath::Collection} class ExtrusionEntityCollection {
     %name{_new} ExtrusionEntityCollection();
     %name{_new} ExtrusionEntityCollection();
+    Clone<ExtrusionEntityCollection> clone()
+        %code{% RETVAL = THIS->clone(); %};
     void reverse();
     void reverse();
     void clear()
     void clear()
         %code{% THIS->entities.clear(); %};
         %code{% THIS->entities.clear(); %};