Trigger extra perimeters also when a diagonal gap would be visible. #3732

This commit is contained in:
Alessandro Ranellucci 2017-03-08 14:40:00 +01:00
parent 798b6c8a08
commit bb214b0cd6
5 changed files with 50 additions and 17 deletions

View File

@ -133,6 +133,13 @@ sub mesh {
$facets = [
[0,1,2],[1,0,3],[2,1,4],[2,5,0],[0,6,3],[1,3,7],[1,8,4],[4,9,2],[10,5,2],[5,6,0],[6,11,3],[3,12,7],[7,8,1],[4,8,11],[4,11,9],[9,10,2],[10,13,5],[14,6,5],[9,11,6],[11,12,3],[12,8,7],[11,8,15],[13,10,9],[5,13,14],[14,13,6],[6,13,9],[15,12,11],[15,8,12]
];
} elsif ($name eq 'step') {
$vertices = [
[0,20,5],[0,20,0],[0,0,5],[0,0,0],[20,0,0],[20,0,5],[1,19,5],[1,1,5],[19,1,5],[20,20,5],[19,19,5],[20,20,0],[19,19,10],[1,19,10],[1,1,10],[19,1,10]
];
$facets = [
[0,1,2],[1,3,2],[3,4,5],[2,3,5],[6,0,2],[6,2,7],[5,8,7],[5,7,2],[9,10,8],[9,8,5],[9,0,6],[9,6,10],[9,11,1],[9,1,0],[3,1,11],[4,3,11],[5,11,9],[5,4,11],[12,10,6],[12,6,13],[6,7,14],[13,6,14],[7,8,15],[14,7,15],[15,8,10],[15,10,12],[12,13,14],[12,14,15]
];
} else {
return undef;
}

View File

@ -1,4 +1,4 @@
use Test::More tests => 21;
use Test::More tests => 24;
use strict;
use warnings;
@ -11,6 +11,7 @@ BEGIN {
use List::Util qw(first sum);
use Slic3r;
use Slic3r::Geometry qw(epsilon);
use Slic3r::Surface qw(S_TYPE_TOP);
use Slic3r::Test;
{
@ -318,4 +319,23 @@ use Slic3r::Test;
is $diagonal_moves, 0, 'no spiral moves on two-island object';
}
{
# GH: #3732
my $config = Slic3r::Config->new_from_defaults;
$config->set('perimeters', 2);
$config->set('extrusion_width', 0.55);
$config->set('first_layer_height', 0.25);
$config->set('infill_overlap', '50%');
$config->set('layer_height', 0.25);
$config->set('perimeters', 2);
$config->set('extra_perimeters', 1);
my $tprint = Slic3r::Test::init_print('step', config => $config);
$tprint->print->process;
my $layerm19 = $tprint->print->get_object(0)->get_layer(19)->get_region(0);
is scalar(@{$layerm19->slices->filter_by_type(S_TYPE_TOP)}), 1, 'top slice detected';
is scalar(@{$layerm19->fill_surfaces->filter_by_type(S_TYPE_TOP)}), 0, 'no top fill_surface detected';
is $layerm19->perimeters->items_count, 3, 'extra perimeter detected';
}
__END__

View File

@ -315,8 +315,7 @@ PerimeterGenerator::process()
);
// append infill areas to fill_surfaces
for (ExPolygons::const_iterator ex = expp.begin(); ex != expp.end(); ++ex)
this->fill_surfaces->surfaces.push_back(Surface(stInternal, *ex)); // use a bogus surface type
this->fill_surfaces->append(expp, stInternal); // use a bogus surface type
}
}
}

View File

@ -384,7 +384,7 @@ PrintObject::detect_surfaces_type()
const Layer* lower_layer = layer_idx > 0 ? this->get_layer(layer_idx-1) : NULL;
// collapse very narrow parts (using the safety offset in the diff is not enough)
const float offset = layerm.flow(frExternalPerimeter).scaled_width() / 10.f;
const float offs = layerm.flow(frExternalPerimeter).scaled_width() / 10.f;
const Polygons layerm_slices_surfaces = layerm.slices;
@ -392,14 +392,14 @@ PrintObject::detect_surfaces_type()
// of current layer and upper one)
SurfaceCollection top;
if (upper_layer != NULL) {
const Polygons upper_slices = this->config.interface_shells.value
Polygons upper_slices = this->config.interface_shells.value
? (Polygons)upper_layer->get_region(region_id)->slices
: (Polygons)upper_layer->slices;
top.append(
offset2_ex(
diff(layerm_slices_surfaces, upper_slices, true),
-offset, offset
-offs, offs
),
stTop
);
@ -426,7 +426,7 @@ PrintObject::detect_surfaces_type()
bottom.append(
offset2_ex(
diff(layerm_slices_surfaces, lower_layer->slices, true),
-offset, offset
-offs, offs
),
surface_type_bottom
);
@ -443,7 +443,7 @@ PrintObject::detect_surfaces_type()
lower_layer->get_region(region_id)->slices,
true
),
-offset, offset
-offs, offs
),
stBottom
);
@ -470,7 +470,7 @@ PrintObject::detect_surfaces_type()
const Polygons top_polygons = to_polygons(STDMOVE(top));
top.clear();
top.append(
offset2_ex(diff(top_polygons, bottom, true), -offset, offset),
offset2_ex(diff(top_polygons, bottom, true), -offs, offs),
stTop
);
}
@ -487,17 +487,18 @@ PrintObject::detect_surfaces_type()
layerm.slices.append(
offset2_ex(
diff(layerm_slices_surfaces, topbottom, true),
-offset, offset
-offs, offs
),
stInternal
);
}
/*
Slic3r::debugf " layer %d has %d bottom, %d top and %d internal surfaces\n",
$layerm->layer->id, scalar(@bottom), scalar(@top), scalar(@internal) if $Slic3r::debug;
*/
#ifdef SLIC3R_DEBUG
printf(" layer %zu has %zu bottom, %zu top and %zu internal surfaces\n",
layerm.layer()->id(), bottom.size(), top.size(),
layerm.slices.size()-bottom.size()-top.size());
#endif
} // for each layer of a region
/* Fill in layerm->fill_surfaces by trimming the layerm->slices by the cummulative layerm->fill_surfaces.
@ -782,7 +783,6 @@ PrintObject::_make_perimeters()
size_t region_id = region_it - this->_print->regions.begin();
const PrintRegion &region = **region_it;
if (!region.config.extra_perimeters
|| region.config.perimeters == 0
|| region.config.fill_density == 0
@ -791,7 +791,13 @@ PrintObject::_make_perimeters()
for (size_t i = 0; i <= (this->layer_count()-2); ++i) {
LayerRegion &layerm = *this->get_layer(i)->get_region(region_id);
const LayerRegion &upper_layerm = *this->get_layer(i+1)->get_region(region_id);
const Polygons upper_layerm_polygons = upper_layerm.slices;
// In order to avoid diagonal gaps (GH #3732) we ignore the external half of the upper
// perimeter, since it's not truly covering this layer.
const Polygons upper_layerm_polygons = offset(
upper_layerm.slices,
-upper_layerm.flow(frExternalPerimeter).scaled_width()/2
);
// Filter upper layer polygons in intersection_ppl by their bounding boxes?
// my $upper_layerm_poly_bboxes= [ map $_->bounding_box, @{$upper_layerm_polygons} ];

View File

@ -29,6 +29,7 @@ class SurfaceCollection
void append(const ExPolygons &src, SurfaceType surfaceType);
size_t polygons_count() const;
bool empty() const { return this->surfaces.empty(); };
size_t size() const { return this->surfaces.size(); };
void clear() { this->surfaces.clear(); };
};