Ignore small_perimeter_speed when perimeter has overhangs. #3951

This commit is contained in:
Alessandro Ranellucci 2017-05-16 21:49:00 +02:00
parent 68711c7f2b
commit 172c324475
5 changed files with 54 additions and 13 deletions

View File

@ -133,6 +133,13 @@ sub mesh {
$facets = [ $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] [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 'bridge_with_hole') {
$vertices = [
[75,69.5,8],[80,76.9091644287109,8],[75,94.5,8],[125,69.5,8],[120,76.9091644287109,8],[120,87.0908355712891,8],[80,87.0908355712891,8],[125,94.5,8],[80,87.0908355712891,5],[120,87.0908355712891,5],[125,94.5,0],[120,69.5,0],[120,94.5,0],[125,69.5,0],[120,94.5,5],[80,94.5,5],[80,94.5,0],[75,94.5,0],[80,69.5,5],[80,69.5,0],[80,76.9091644287109,5],[120,69.5,5],[75,69.5,0],[120,76.9091644287109,5]
];
$facets = [
[0,1,2],[1,0,3],[1,3,4],[4,3,5],[2,6,7],[6,2,1],[7,6,5],[7,5,3],[5,8,9],[8,5,6],[10,11,12],[11,10,13],[14,8,15],[8,14,9],[2,16,17],[16,2,15],[15,2,14],[14,10,12],[10,14,7],[7,14,2],[16,18,19],[18,16,20],[20,16,1],[1,16,8],[8,16,15],[6,1,8],[3,11,13],[11,3,21],[21,3,18],[18,22,19],[22,18,0],[0,18,3],[16,22,17],[22,16,19],[2,22,0],[22,2,17],[5,23,4],[23,11,21],[11,23,12],[12,23,9],[9,23,5],[12,9,14],[23,18,20],[18,23,21],[10,3,13],[3,10,7],[1,23,20],[23,1,4]
];
} elsif ($name eq 'step') { } elsif ($name eq 'step') {
$vertices = [ $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] [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]

View File

@ -1,4 +1,4 @@
use Test::More tests => 59; use Test::More tests => 63;
use strict; use strict;
use warnings; use warnings;
@ -393,10 +393,39 @@ use Slic3r::Test;
}); });
return scalar keys %z_with_bridges; return scalar keys %z_with_bridges;
}; };
ok $test->(Slic3r::Test::init_print('V', config => $config)) == 1, is $test->(Slic3r::Test::init_print('V', config => $config)), 1,
'no overhangs printed with bridge speed'; # except for the first internal solid layers above void 'no overhangs printed with bridge speed'; # except for the first internal solid layers above void
ok $test->(Slic3r::Test::init_print('V', config => $config, scale_xyz => [3,1,1])) > 1, ok $test->(Slic3r::Test::init_print('V', config => $config, scale_xyz => [3,1,1])) > 1,
'overhangs printed with bridge speed'; 'overhangs printed with bridge speed';
$config->set('bottom_solid_layers', 0);
$config->set('top_solid_layers', 0);
my $test2 = sub {
my ($print) = @_;
my $num_bridges = 0;
Slic3r::GCode::Reader->new->parse(my $gcode = Slic3r::Test::gcode($print), sub {
my ($self, $cmd, $args, $info) = @_;
if ($info->{extruding} && $info->{dist_XY} > 0) {
$num_bridges++ if ($args->{F} // $self->F) == $config->bridge_speed*60;
}
});
open my $fh, ">", "bridges.gcode";
print $fh $gcode;
return $num_bridges;
};
is $test2->(Slic3r::Test::init_print('overhang', config => $config)), $config->perimeters*3,
'expected number of segments use bridge speed (overhang)';
is $test2->(Slic3r::Test::init_print('bridge', config => $config)), $config->perimeters*2,
'expected number of segments use bridge speed (bridge)';
is $test2->(Slic3r::Test::init_print('bridge_with_hole', config => $config)), $config->perimeters*4,
'expected number of segments use bridge speed (bridge with hole)';
# scale the test model so that the hole perimeter length is smaller than small perimeter
# threshold (~40mm). check that we still use overhang settings regardless of it being small
is $test2->(Slic3r::Test::init_print('bridge_with_hole', config => $config, scale_xyz => [0.3,0.5,1])),
$config->perimeters*4,
'expected number of segments use bridge speed (bridge with small hole)';
} }
{ {

View File

@ -167,6 +167,11 @@ class ExtrusionLoop : public ExtrusionEntity
void append(const ExtrusionPath &path) { void append(const ExtrusionPath &path) {
this->paths.push_back(path); this->paths.push_back(path);
}; };
bool has(ExtrusionRole role) const {
for (const auto &path : this->paths)
if (path.role == role) return true;
return false;
};
}; };
} }

View File

@ -415,9 +415,11 @@ GCode::extrude(ExtrusionLoop loop, std::string description, double speed)
if (paths.empty()) return ""; if (paths.empty()) return "";
// apply the small perimeter speed // apply the small perimeter speed
if (paths.front().is_perimeter() && loop.length() <= SMALL_PERIMETER_LENGTH) { if (paths.front().is_perimeter()
if (speed == -1) speed = this->config.get_abs_value("small_perimeter_speed"); && !loop.has(erOverhangPerimeter)
} && loop.length() <= SMALL_PERIMETER_LENGTH
&& speed == -1)
speed = this->config.get_abs_value("small_perimeter_speed");
// extrude along the path // extrude along the path
std::string gcode; std::string gcode;

View File

@ -349,11 +349,10 @@ PerimeterGenerator::_traverse_loops(const PerimeterGeneratorLoops &loops,
&& !(this->object_config->support_material && this->object_config->support_material_contact_distance.value == 0)) { && !(this->object_config->support_material && this->object_config->support_material_contact_distance.value == 0)) {
// get non-overhang paths by intersecting this loop with the grown lower slices // get non-overhang paths by intersecting this loop with the grown lower slices
{ {
Polylines polylines = intersection_pl(loop->polygon, this->_lower_slices_p); const Polylines polylines = intersection_pl(loop->polygon, this->_lower_slices_p);
for (const Polyline &polyline : polylines) {
for (Polylines::const_iterator polyline = polylines.begin(); polyline != polylines.end(); ++polyline) {
ExtrusionPath path(role); ExtrusionPath path(role);
path.polyline = *polyline; path.polyline = polyline;
path.mm3_per_mm = is_external ? this->_ext_mm3_per_mm : this->_mm3_per_mm; path.mm3_per_mm = is_external ? this->_ext_mm3_per_mm : this->_mm3_per_mm;
path.width = is_external ? this->ext_perimeter_flow.width : this->perimeter_flow.width; path.width = is_external ? this->ext_perimeter_flow.width : this->perimeter_flow.width;
path.height = this->layer_height; path.height = this->layer_height;
@ -365,11 +364,10 @@ PerimeterGenerator::_traverse_loops(const PerimeterGeneratorLoops &loops,
// outside the grown lower slices (thus where the distance between // outside the grown lower slices (thus where the distance between
// the loop centerline and original lower slices is >= half nozzle diameter // the loop centerline and original lower slices is >= half nozzle diameter
{ {
Polylines polylines = diff_pl(loop->polygon, this->_lower_slices_p); const Polylines polylines = diff_pl(loop->polygon, this->_lower_slices_p);
for (const Polyline &polyline : polylines) {
for (Polylines::const_iterator polyline = polylines.begin(); polyline != polylines.end(); ++polyline) {
ExtrusionPath path(erOverhangPerimeter); ExtrusionPath path(erOverhangPerimeter);
path.polyline = *polyline; path.polyline = polyline;
path.mm3_per_mm = this->_mm3_per_mm_overhang; path.mm3_per_mm = this->_mm3_per_mm_overhang;
path.width = this->overhang_flow.width; path.width = this->overhang_flow.width;
path.height = this->overhang_flow.height; path.height = this->overhang_flow.height;