Browse Source

Fixed regression introduced by the recent PerimeterGenerator refactoring causing spiral vase not to be correctly skipped on multi-loop layers. Includes regression test. #2761

Alessandro Ranellucci 10 years ago
parent
commit
1f8ef2a63c

+ 2 - 2
lib/Slic3r/Print/GCode.pm

@@ -306,8 +306,8 @@ sub process_layer {
             ($layer->id > 0 || $self->print->config->brim_width == 0)
                 && ($layer->id >= $self->print->config->skirt_height && !$self->print->has_infinite_skirt)
                 && !defined(first { $_->config->bottom_solid_layers > $layer->id } @{$layer->regions})
-                && !defined(first { @{$_->perimeters} > 1 } @{$layer->regions})
-                && !defined(first { @{$_->fills} > 0 } @{$layer->regions})
+                && !defined(first { $_->perimeters->items_count > 1 } @{$layer->regions})
+                && !defined(first { $_->fills->items_count > 0 } @{$layer->regions})
         );
     }
     

+ 18 - 1
t/gcode.t

@@ -1,4 +1,4 @@
-use Test::More tests => 22;
+use Test::More tests => 23;
 use strict;
 use warnings;
 
@@ -200,4 +200,21 @@ use Slic3r::Test;
     like $gcode, qr/START:20mm_cube/, '[input_filename] is also available in custom G-code';
 }
 
+{
+    my $config = Slic3r::Config->new_from_defaults;
+    $config->set('spiral_vase', 1);
+    my $print = Slic3r::Test::init_print('cube_with_hole', config => $config);
+    
+    my $spiral = 0;
+    Slic3r::GCode::Reader->new->parse(Slic3r::Test::gcode($print), sub {
+        my ($self, $cmd, $args, $info) = @_;
+        
+        if ($cmd eq 'G1' && exists $args->{E} && exists $args->{Z}) {
+            $spiral = 1;
+        }
+    });
+    
+    ok !$spiral, 'spiral vase is correctly disabled on layers with multiple loops';
+}
+
 __END__

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

@@ -35,6 +35,9 @@ enum ExtrusionLoopRole {
 class ExtrusionEntity
 {
     public:
+    virtual bool is_collection() const {
+        return false;
+    };
     virtual bool is_loop() const {
         return false;
     };

+ 16 - 0
xs/src/libslic3r/ExtrusionEntityCollection.cpp

@@ -121,6 +121,22 @@ ExtrusionEntityCollection::grow() const
     return pp;
 }
 
+/* Recursively count paths and loops contained in this collection */
+size_t
+ExtrusionEntityCollection::items_count() const
+{
+    size_t count = 0;
+    for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) {
+        if ((*it)->is_collection()) {
+            ExtrusionEntityCollection* collection = dynamic_cast<ExtrusionEntityCollection*>(*it);
+            count += collection->items_count();
+        } else {
+            ++count;
+        }
+    }
+    return count;
+}
+
 #ifdef SLIC3RXS
 // there is no ExtrusionLoop::Collection or ExtrusionEntity::Collection
 REGISTER_CLASS(ExtrusionEntityCollection, "ExtrusionPath::Collection");

+ 4 - 0
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 is_collection() const {
+        return true;
+    };
     bool can_reverse() const {
         return !this->no_sort;
     };
@@ -26,6 +29,7 @@ class ExtrusionEntityCollection : public ExtrusionEntity
     Point first_point() const;
     Point last_point() const;
     Polygons grow() const;
+    size_t items_count() const;
 };
 
 }

+ 1 - 1
xs/src/libslic3r/Layer.hpp

@@ -47,7 +47,7 @@ class LayerRegion
     PolylineCollection unsupported_bridge_edges;
 
     // ordered collection of extrusion paths/loops to build all perimeters
-    // (this collection contains both ExtrusionPath and ExtrusionLoop objects)
+    // (this collection contains only ExtrusionEntityCollection objects)
     ExtrusionEntityCollection perimeters;
 
     // ordered collection of extrusion paths to fill surfaces

+ 2 - 0
xs/xsp/ExtrusionEntityCollection.xsp

@@ -26,6 +26,8 @@
     Clone<Point> last_point();
     int count()
         %code{% RETVAL = THIS->entities.size(); %};
+    int items_count()
+        %code{% RETVAL = THIS->items_count(); %};
     bool empty()
         %code{% RETVAL = THIS->entities.empty(); %};
     std::vector<size_t> orig_indices()