diff --git a/lib/Slic3r/Print/GCode.pm b/lib/Slic3r/Print/GCode.pm index d1463b302..8c7c7627f 100644 --- a/lib/Slic3r/Print/GCode.pm +++ b/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}) ); } diff --git a/t/gcode.t b/t/gcode.t index 79ab1a7de..fb85ee5e4 100644 --- a/t/gcode.t +++ b/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__ diff --git a/xs/src/libslic3r/ExtrusionEntity.hpp b/xs/src/libslic3r/ExtrusionEntity.hpp index d785c8f65..b5262eae0 100644 --- a/xs/src/libslic3r/ExtrusionEntity.hpp +++ b/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; }; diff --git a/xs/src/libslic3r/ExtrusionEntityCollection.cpp b/xs/src/libslic3r/ExtrusionEntityCollection.cpp index 4afbd8887..075429d9d 100644 --- a/xs/src/libslic3r/ExtrusionEntityCollection.cpp +++ b/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(*it); + count += collection->items_count(); + } else { + ++count; + } + } + return count; +} + #ifdef SLIC3RXS // there is no ExtrusionLoop::Collection or ExtrusionEntity::Collection REGISTER_CLASS(ExtrusionEntityCollection, "ExtrusionPath::Collection"); diff --git a/xs/src/libslic3r/ExtrusionEntityCollection.hpp b/xs/src/libslic3r/ExtrusionEntityCollection.hpp index 6264b4faf..18e15e318 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 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; }; } diff --git a/xs/src/libslic3r/Layer.hpp b/xs/src/libslic3r/Layer.hpp index 6dd6e81a5..8b2ef6f3f 100644 --- a/xs/src/libslic3r/Layer.hpp +++ b/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 diff --git a/xs/xsp/ExtrusionEntityCollection.xsp b/xs/xsp/ExtrusionEntityCollection.xsp index f5b075888..08577c892 100644 --- a/xs/xsp/ExtrusionEntityCollection.xsp +++ b/xs/xsp/ExtrusionEntityCollection.xsp @@ -26,6 +26,8 @@ Clone 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 orig_indices()