From 2bbda6abfff1349d0a013a88265e7d3a938576bb Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Thu, 25 Jul 2013 23:43:26 +0200 Subject: [PATCH] Contact loops --- lib/Slic3r/GCode/Layer.pm | 5 +-- lib/Slic3r/Print.pm | 2 +- lib/Slic3r/Print/Object.pm | 81 ++++++++++++++------------------------ 3 files changed, 32 insertions(+), 56 deletions(-) diff --git a/lib/Slic3r/GCode/Layer.pm b/lib/Slic3r/GCode/Layer.pm index f633dbfb..50ae5ebc 100644 --- a/lib/Slic3r/GCode/Layer.pm +++ b/lib/Slic3r/GCode/Layer.pm @@ -89,15 +89,12 @@ sub process_layer { # extrude support material before other things because it might use a lower Z # and also because we avoid travelling on other things when printing it if ($self->print->has_support_material && $layer->isa('Slic3r::Layer::Support')) { - $gcode .= $self->gcodegen->move_z($layer->support_material_contact_z) - if ($layer->support_contact_fills && @{ $layer->support_contact_fills->paths }); $gcode .= $self->gcodegen->set_extruder($self->extruders->[$Slic3r::Config->support_material_extruder-1]); + $gcode .= $self->gcodegen->move_z($layer->print_z); if ($layer->support_contact_fills) { $gcode .= $self->gcodegen->extrude_path($_, 'support material contact area') for $layer->support_contact_fills->chained_path($self->gcodegen->last_pos); } - - $gcode .= $self->gcodegen->move_z($layer->print_z); if ($layer->support_fills) { $gcode .= $self->gcodegen->extrude_path($_, 'support material') for $layer->support_fills->chained_path($self->gcodegen->last_pos); diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index 44e1f3f0..38249928 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -446,7 +446,7 @@ sub export_gcode { printf " fills = %.1fMb\n", List::Util::sum(map Devel::Size::total_size($_->fills), map @{$_->regions}, map @{$_->layers}, @{$self->objects})/1024/1024; printf " print object = %.1fMb\n", Devel::Size::total_size($self)/1024/1024; } - if (1) { + if (0) { eval "use Slic3r::Test::SectionCut"; Slic3r::Test::SectionCut->new(print => $self)->export_svg("section_cut.svg"); } diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 0620c85e..d5d2e543 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -819,13 +819,13 @@ sub generate_support_material { } # shape of contact area - # Move down? + my $contact_loops = 1; my $circle_distance = 5 * $flow->scaled_width; my $circle; { # TODO: make sure teeth between circles are compatible with support material flow my $r = 1.5 * $flow->scaled_width; - $circle = Slic3r::Polygon->new([ map [ $r * cos $_, $r * sin $_ ], (5*PI/3, 4*PI/3, PI, 2*PI/3, PI/3, 0) ]); + $circle = Slic3r::Polygon->new(map [ $r * cos $_, $r * sin $_ ], (5*PI/3, 4*PI/3, PI, 2*PI/3, PI/3, 0)); } # determine contact areas @@ -1009,72 +1009,51 @@ sub generate_support_material { $support{$layer_id} ||= []; # contact - if (0 && @{$contact{$layer_id}}) { - # remove contact areas from interface areas of this layer - $interface{$layer_id} = diff( - $interface{$layer_id}, - $contact{$layer_id}, - ); + if ((my $contact = $contact{$support_layers[$layer_id]}) && $contact_loops > 0) { + my $overhang = $overhang{$support_layers[$layer_id]}; + $contact = [ grep $_->is_counter_clockwise, @$contact ]; # find centerline of the external loop of the contours - my @external_loops = offset($contact{$layer_id}, -$flow->scaled_width/2); + my @external_loops = offset($contact, -$flow->scaled_width/2); # apply a pattern to the loop - my @loops; + my @loops0; { my @positions = map Slic3r::Polygon->new(@$_)->split_at_first_point->regular_points($circle_distance), @external_loops; - @loops = @{diff( + @loops0 = @{diff( [ @external_loops ], [ map $circle->clone->translate(@$_), @positions ], )}; } - # make a second loop - push @loops, offset( - [ offset([ @loops ], -1.5*$flow->scaled_spacing) ], - +0.5*$flow->scaled_spacing, - ); + # make more loops + my @loops = @loops0; + for my $i (2..$contact_loops) { + my $d = ($i-1) * $flow->scaled_spacing; + push @loops, offset2(\@loops0, -$d -0.5*$flow->scaled_spacing, +0.5*$flow->scaled_spacing); + } # clip such loops to the side oriented towards the object - @loops = @{ Boost::Geometry::Utils::multi_polygon_multi_linestring_intersection( - [ offset_ex([ map @$_, @{$overhang{$layer_id}} ], +$margin) ], - [ map Slic3r::Polygon->new(@$_)->split_at_first_point, @loops ], - ) }; + @loops = map Slic3r::Polyline->new(@$_), + @{ Boost::Geometry::Utils::multi_polygon_multi_linestring_intersection( + [ offset_ex([ map @$_, @$overhang ], +scale 3) ], + [ map Slic3r::Polygon->new(@$_)->split_at_first_point, @loops ], + ) }; + + # subtract loops from the contact area to detect the remaining part + $interface{$layer_id} = diff( + $interface{$layer_id}, + [ map $_->grow($flow->scaled_width), @loops ], + ); # transform loops into ExtrusionPath objects @loops = map Slic3r::ExtrusionPath->pack( - polyline => Slic3r::Polyline->new(@$_), + polyline => $_, role => EXTR_ROLE_SUPPORTMATERIAL, flow_spacing => $flow->spacing, ), @loops; - # subtract such paths from the contact area to detect the remaining part - my $to_infill = diff_ex( - [ @external_loops ], - [ map $_->unpack->polyline->grow($flow->scaled_width), @loops ], - ); - - # fill the interior - $fillers{interface}->angle($interface_angle); - - my @paths = (); - foreach my $expolygon (@$to_infill) { - my @p = $fillers{interface}->fill_surface( - Slic3r::Surface->new(expolygon => $expolygon), - density => $interface_density, - flow_spacing => $flow->spacing, - complete => 1, - ); - my $params = shift @p; - - push @paths, map Slic3r::ExtrusionPath->new( - polyline => Slic3r::Polyline->new(@$_), - role => EXTR_ROLE_SUPPORTMATERIAL, - flow_spacing => $params->{flow_spacing}, - ), @p; - } - - $result->{contact} = [ @loops, @paths ]; + $result->{contact} = [ @loops ]; } # interface @@ -1101,7 +1080,7 @@ sub generate_support_material { ); my $params = shift @p; - push @paths, map Slic3r::ExtrusionPath->new( + push @paths, map Slic3r::ExtrusionPath->pack( polyline => Slic3r::Polyline->new(@$_), role => EXTR_ROLE_SUPPORTMATERIAL, height => undef, @@ -1131,7 +1110,7 @@ sub generate_support_material { } else { # draw a perimeter all around support infill # TODO: use brim ordering algorithm - push @paths, map Slic3r::ExtrusionPath->new( + push @paths, map Slic3r::ExtrusionPath->pack( polyline => $_->split_at_first_point, role => EXTR_ROLE_SUPPORTMATERIAL, height => undef, @@ -1151,7 +1130,7 @@ sub generate_support_material { ); my $params = shift @p; - push @paths, map Slic3r::ExtrusionPath->new( + push @paths, map Slic3r::ExtrusionPath->pack( polyline => Slic3r::Polyline->new(@$_), role => EXTR_ROLE_SUPPORTMATERIAL, height => undef,