mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-13 06:21:50 +08:00
Trigger extra perimeters also when a diagonal gap would be visible. #3732
This commit is contained in:
parent
798b6c8a08
commit
bb214b0cd6
@ -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;
|
||||
}
|
||||
|
22
t/shells.t
22
t/shells.t
@ -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__
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 ®ion = **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} ];
|
||||
|
@ -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(); };
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user