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:
Alessandro Ranellucci 2015-04-12 20:16:27 +02:00
parent 901716adc8
commit 1f8ef2a63c
7 changed files with 46 additions and 4 deletions

View file

@ -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})
);
}

View file

@ -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__

View file

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

View file

@ -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");

View file

@ -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;
};
}

View file

@ -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

View file

@ -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()