Browse Source

New --min-skirt-length option. #269

Alessandro Ranellucci 12 years ago
parent
commit
e9ae62a9d1
6 changed files with 49 additions and 6 deletions
  1. 2 0
      README.markdown
  2. 9 0
      lib/Slic3r/Config.pm
  3. 6 0
      lib/Slic3r/Extruder.pm
  4. 1 1
      lib/Slic3r/GUI/Tab.pm
  5. 29 5
      lib/Slic3r/Print.pm
  6. 2 0
      slic3r.pl

+ 2 - 0
README.markdown

@@ -227,6 +227,8 @@ The author of the Silk icon set is Mark James.
         --skirt-distance    Distance in mm between innermost skirt and object 
                             (default: 6)
         --skirt-height      Height of skirts to draw (expressed in layers, 0+, default: 1)
+        --min-skirt-length  Generate no less than the number of loops required to consume this length
+                            of filament on the first layer, for each extruder (mm, 0+, default: 0)
         --brim-width        Width of the brim that will get added to each object to help adhesion
                             (mm, default: 0)
        

+ 9 - 0
lib/Slic3r/Config.pm

@@ -760,6 +760,15 @@ END
         type    => 'i',
         default => 1,
     },
+    'min_skirt_length' => {
+        label   => 'Minimum extrusion length',
+        tooltip => 'Generate no less than the number of skirt loops required to consume the specified amount of filament on the bottom layer. For multi-extruder machines, this minimum applies to each extruder.',
+        sidetext => 'mm',
+        cli     => 'min-skirt-length=f',
+        type    => 'f',
+        default => 0,
+        min     => 0,
+    },
     'skirt_distance' => {
         label   => 'Distance from object',
         tooltip => 'Distance between skirt and object(s). Set this to zero to attach the skirt to the object(s) and get a brim for better adhesion.',

+ 6 - 0
lib/Slic3r/Extruder.pm

@@ -55,4 +55,10 @@ sub mm3_per_mm {
     return $self->_mm3_per_mm_cache->{$cache_key};
 }
 
+sub e_per_mm {
+    my $self = shift;
+    my ($s, $h) = @_;
+    return $self->mm3_per_mm($s, $h) * $self->e_per_mm3;
+}
+
 1;

+ 1 - 1
lib/Slic3r/GUI/Tab.pm

@@ -435,7 +435,7 @@ sub build {
     $self->add_options_page('Skirt and brim', 'box.png', optgroups => [
         {
             title => 'Skirt',
-            options => [qw(skirts skirt_distance skirt_height)],
+            options => [qw(skirts skirt_distance skirt_height min_skirt_length)],
         },
         {
             title => 'Brim',

+ 29 - 5
lib/Slic3r/Print.pm

@@ -3,7 +3,7 @@ use Moo;
 
 use File::Basename qw(basename fileparse);
 use File::Spec;
-use List::Util qw(max);
+use List::Util qw(max first);
 use Math::ConvexHull::MonotoneChain qw(convex_hull);
 use Slic3r::ExtrusionPath ':roles';
 use Slic3r::Geometry qw(X Y Z X1 Y1 X2 Y2 MIN PI scale unscale move_points nearest_point);
@@ -568,16 +568,40 @@ sub make_skirt {
     # find out convex hull
     my $convex_hull = convex_hull(\@points);
     
+    my @extruded_length = ();  # for each extruder
+    my $spacing = $Slic3r::first_layer_flow->spacing;
+    my $first_layer_height = $Slic3r::Config->get_value('first_layer_height');
+    my @extruders_e_per_mm = ();
+    my $extruder_idx = 0;
+    
     # draw outlines from outside to inside
+    # loop while we have less skirts than required or any extruder hasn't reached the min length if any
+    my $distance = scale $Slic3r::Config->skirt_distance;
     for (my $i = $Slic3r::Config->skirts; $i > 0; $i--) {
-        my $distance = scale ($Slic3r::Config->skirt_distance + ($Slic3r::first_layer_flow->spacing * $i));
-        my $outline = Math::Clipper::offset([$convex_hull], $distance, &Slic3r::SCALING_FACTOR * 100, JT_ROUND);
+        $distance += scale $spacing;
+        my $loop = Math::Clipper::offset([$convex_hull], $distance, &Slic3r::SCALING_FACTOR * 100, JT_ROUND)->[0];
         push @{$self->skirt}, Slic3r::ExtrusionLoop->pack(
-            polygon         => Slic3r::Polygon->new(@{$outline->[0]}),
+            polygon         => Slic3r::Polygon->new(@$loop),
             role            => EXTR_ROLE_SKIRT,
-            flow_spacing    => $Slic3r::first_layer_flow->spacing,
+            flow_spacing    => $spacing,
         );
+        
+        if ($Slic3r::Config->min_skirt_length > 0) {
+            bless $loop, 'Slic3r::Polygon';
+            $extruded_length[$extruder_idx]     ||= 0;
+            $extruders_e_per_mm[$extruder_idx]  ||= $self->extruders->[$extruder_idx]->e_per_mm($spacing, $first_layer_height);
+            $extruded_length[$extruder_idx]     += unscale $loop->length * $extruders_e_per_mm[$extruder_idx];
+            $i++ if defined first { ($extruded_length[$_] // 0) < $Slic3r::Config->min_skirt_length } 0 .. $#{$self->extruders};
+            if ($extruded_length[$extruder_idx] >= $Slic3r::Config->min_skirt_length) {
+                if ($extruder_idx < $#{$self->extruders}) {
+                    $extruder_idx++;
+                    next;
+                }
+            }
+        }
     }
+    
+    @{$self->skirt} = reverse @{$self->skirt};
 }
 
 sub make_brim {

+ 2 - 0
slic3r.pl

@@ -275,6 +275,8 @@ $j
     --skirt-distance    Distance in mm between innermost skirt and object 
                         (default: $config->{skirt_distance})
     --skirt-height      Height of skirts to draw (expressed in layers, 0+, default: $config->{skirt_height})
+    --min-skirt-length  Generate no less than the number of loops required to consume this length
+                        of filament on the first layer, for each extruder (mm, 0+, default: $config->{min_skirt_length})
     --brim-width        Width of the brim that will get added to each object to help adhesion
                         (mm, default: $config->{brim_width})