From c82302e284b08b8ba43e7dc641cfd386418f3561 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Tue, 2 May 2017 00:56:39 +0200 Subject: [PATCH] Fixed regression in dont_support_bridges. #3859 --- lib/Slic3r/Print/SupportMaterial.pm | 40 +++++++++++++++++++---------- xs/src/libslic3r/Polyline.cpp | 10 ++++---- xs/xsp/ExtrusionLoop.xsp | 1 + xs/xsp/ExtrusionPath.xsp | 1 + 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/lib/Slic3r/Print/SupportMaterial.pm b/lib/Slic3r/Print/SupportMaterial.pm index 1b1edf023..4c25dace2 100644 --- a/lib/Slic3r/Print/SupportMaterial.pm +++ b/lib/Slic3r/Print/SupportMaterial.pm @@ -208,20 +208,29 @@ sub contact_area { if ($conf->dont_support_bridges) { # compute the area of bridging perimeters - # Note: this is duplicate code from GCode.pm, we need to refactor - my $bridged_perimeters; # Polygons { my $bridge_flow = $layerm->flow(FLOW_ROLE_PERIMETER, 1); - my $nozzle_diameter = $self->print_config->get_at('nozzle_diameter', $layerm->region->config->perimeter_extruder-1); - my $lower_grown_slices = offset([ map @$_, @{$lower_layer->slices} ], +scale($nozzle_diameter/2)); + # Get the lower layer's slices and grow them by half the nozzle diameter + # because we will consider the upper perimeters supported even if half nozzle + # falls outside the lower slices. + my $lower_grown_slices; + { + my $nozzle_diameter = $self->print_config->get_at('nozzle_diameter', $layerm->region->config->perimeter_extruder-1); + $lower_grown_slices = offset( + [ map @$_, @{$lower_layer->slices} ], + +scale($nozzle_diameter/2), + ); + } - # TODO: split_at_first_point() could split a bridge mid-way - my @overhang_perimeters = - map { $_->isa('Slic3r::ExtrusionLoop') ? $_->polygon->split_at_first_point : $_->polyline->clone } - map @$_, @{$layerm->perimeters}; + # Get all perimeters as polylines. + # TODO: split_at_first_point() (called by as_polyline() for ExtrusionLoops) + # could split a bridge mid-way + my @overhang_perimeters = map $_->as_polyline, @{$layerm->perimeters->flatten}; + # Only consider the overhang parts of such perimeters, + # overhangs being those parts not supported by # workaround for Clipper bug, see Slic3r::Polygon::clip_as_polyline() $_->[0]->translate(1,0) for @overhang_perimeters; @overhang_perimeters = @{diff_pl( @@ -243,11 +252,16 @@ sub contact_area { # convert bridging polylines into polygons by inflating them with their thickness { - # since we're dealing with bridges, we can't assume width is larger than spacing, - # so we take the largest value and also apply safety offset to be ensure no gaps - # are left in between - my $w = max($bridge_flow->scaled_width, $bridge_flow->scaled_spacing); + # For bridges we can't assume width is larger than spacing because they + # are positioned according to non-bridging perimeters spacing. + my $w = max( + $bridge_flow->scaled_width, + $bridge_flow->scaled_spacing, + $fw, # width of external perimeters + $layerm->flow(FLOW_ROLE_PERIMETER)->scaled_width, + ); $bridged_perimeters = union([ + # Also apply safety offset to ensure no gaps are left in between. map @{$_->grow($w/2 + 10)}, @overhang_perimeters ]); } @@ -258,7 +272,7 @@ sub contact_area { my @bridges = map $_->expolygon, grep $_->bridge_angle != -1, @{$layerm->fill_surfaces->filter_by_type(S_TYPE_BOTTOMBRIDGE)}; - + $diff = diff( $diff, [ diff --git a/xs/src/libslic3r/Polyline.cpp b/xs/src/libslic3r/Polyline.cpp index baa2bbf5d..3c371ae71 100644 --- a/xs/src/libslic3r/Polyline.cpp +++ b/xs/src/libslic3r/Polyline.cpp @@ -198,12 +198,12 @@ Polyline::is_straight() const /* Check that each segment's direction is equal to the line connecting first point and last point. (Checking each line against the previous one would cause the error to accumulate.) */ - double dir = Line(this->first_point(), this->last_point()).direction(); + const double dir = Line(this->first_point(), this->last_point()).direction(); + + for (const Line &line : this->lines()) + if (!line.parallel_to(dir)) + return false; - Lines lines = this->lines(); - for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) { - if (!line->parallel_to(dir)) return false; - } return true; } diff --git a/xs/xsp/ExtrusionLoop.xsp b/xs/xsp/ExtrusionLoop.xsp index 290265b19..6544f9bf6 100644 --- a/xs/xsp/ExtrusionLoop.xsp +++ b/xs/xsp/ExtrusionLoop.xsp @@ -31,6 +31,7 @@ bool is_infill(); bool is_solid_infill(); Polygons grow(); + Clone as_polyline(); %{ SV* diff --git a/xs/xsp/ExtrusionPath.xsp b/xs/xsp/ExtrusionPath.xsp index d9892d10c..a3819caef 100644 --- a/xs/xsp/ExtrusionPath.xsp +++ b/xs/xsp/ExtrusionPath.xsp @@ -27,6 +27,7 @@ bool is_solid_infill(); bool is_bridge(); Polygons grow(); + Clone as_polyline(); %{ ExtrusionPath*