Fixed regression introduced by the recent PerimeterGenerator refactoring causing spiral vase not to be correctly skipped on multi-loop layers. Includes regression test. #2761
This commit is contained in:
parent
901716adc8
commit
1f8ef2a63c
7 changed files with 46 additions and 4 deletions
|
@ -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})
|
||||
);
|
||||
}
|
||||
|
||||
|
|
19
t/gcode.t
19
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__
|
||||
|
|
|
@ -35,6 +35,9 @@ enum ExtrusionLoopRole {
|
|||
class ExtrusionEntity
|
||||
{
|
||||
public:
|
||||
virtual bool is_collection() const {
|
||||
return false;
|
||||
};
|
||||
virtual bool is_loop() const {
|
||||
return false;
|
||||
};
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in a new issue