Browse Source

Merge branch 'master' into xsdata

Conflicts:
	lib/Slic3r/Layer/Region.pm
	lib/Slic3r/Print.pm
	lib/Slic3r/Print/Object.pm
Alessandro Ranellucci 11 years ago
parent
commit
fa07c512b4

+ 3 - 0
README.markdown

@@ -172,6 +172,9 @@ The author of the Silk icon set is Mark James.
         --bridge-acceleration
                             Overrides firmware's default acceleration for bridges. (mm/s^2, set zero
                             to disable; default: 0)
+        --first-layer-acceleration
+                            Overrides firmware's default acceleration for first layer. (mm/s^2, set zero
+                            to disable; default: 0)
         --default-acceleration
                             Acceleration will be reset to this value after the specific settings above
                             have been applied. (mm/s^2, set zero to disable; default: 130)

+ 1 - 0
lib/Slic3r.pm

@@ -79,6 +79,7 @@ use constant OVERLAP_FACTOR         => 1;
 use constant SMALL_PERIMETER_LENGTH => (6.5 / SCALING_FACTOR) * 2 * PI;
 use constant LOOP_CLIPPING_LENGTH_OVER_SPACING      => 0.15;
 use constant INFILL_OVERLAP_OVER_SPACING  => 0.45;
+use constant EXTERNAL_INFILL_MARGIN => 3;
 
 our $Config;
 

+ 13 - 0
lib/Slic3r/Config.pm

@@ -369,6 +369,14 @@ our $Options = {
         type    => 'f',
         default => 0,
     },
+    'first_layer_acceleration' => {
+        label   => 'First layer',
+        tooltip => 'This is the acceleration your printer will use for first layer. Set zero to disable acceleration control for first layer.',
+        sidetext => 'mm/s²',
+        cli     => 'first-layer-acceleration=f',
+        type    => 'f',
+        default => 0,
+    },
     
     # accuracy options
     'layer_height' => {
@@ -1377,6 +1385,11 @@ sub validate {
     die "Invalid value for --extrusion-multiplier\n"
         if defined first { $_ <= 0 } @{$self->extrusion_multiplier};
     
+    # --default-acceleration
+    die "Invalid zero value for --default-acceleration when using other acceleration settings\n"
+        if ($self->perimeter_acceleration || $self->infill_acceleration || $self->bridge_acceleration || $self->first_layer_acceleration)
+            && !$self->default_acceleration;
+    
     # general validation, quick and dirty
     foreach my $opt_key (keys %$Options) {
         my $opt = $Options->{$opt_key};

+ 8 - 0
lib/Slic3r/Fill.pm

@@ -127,6 +127,14 @@ sub make_fill {
     # add spacing between surfaces
     @surfaces = map @{$_->offset(-$distance_between_surfaces / 2 * &Slic3r::INFILL_OVERLAP_OVER_SPACING)}, @surfaces;
     
+    if (0) {
+        require "Slic3r/SVG.pm";
+        Slic3r::SVG::output("fill_" . $layerm->print_z . ".svg",
+            expolygons      => [ map $_->expolygon, grep !$_->is_solid, @surfaces ],
+            red_expolygons  => [ map $_->expolygon, grep  $_->is_solid, @surfaces ],
+        );
+    }
+    
     my @fills = ();
     my @fills_ordering_points =  ();
     SURFACE: foreach my $surface (@surfaces) {

+ 2 - 3
lib/Slic3r/Fill/Rectilinear.pm

@@ -32,9 +32,8 @@ sub fill_surface {
         $flow_spacing = unscale $line_spacing;
     } else {
         # extend bounding box so that our pattern will be aligned with other layers
-        # $bounding_box->[X1] and [Y1] represent the displacement between new bounding box offset and old one
-        $bounding_box->extents->[X][MIN] -= $bounding_box->x_min;
-        $bounding_box->extents->[Y][MIN] -= $bounding_box->y_min;
+        $bounding_box->extents->[X][MIN] -= $bounding_box->x_min % $line_spacing;
+        $bounding_box->extents->[Y][MIN] -= $bounding_box->y_min % $line_spacing;
     }
     
     # generate the basic pattern

+ 33 - 15
lib/Slic3r/GCode.pm

@@ -14,8 +14,9 @@ has 'enable_loop_clipping' => (is => 'rw', default => sub {1});
 has 'enable_wipe'        => (is => 'lazy');   # at least one extruder has wipe enabled
 has 'layer_count'        => (is => 'ro', required => 1 );
 has 'layer'              => (is => 'rw');
+has '_layer_islands'     => (is => 'rw');
+has '_upper_layer_islands'  => (is => 'rw');
 has '_layer_overhangs'   => (is => 'rw');
-has 'move_z_callback'    => (is => 'rw');
 has 'shift_x'            => (is => 'rw', default => sub {0} );
 has 'shift_y'            => (is => 'rw', default => sub {0} );
 has 'z'                  => (is => 'rw');
@@ -98,7 +99,14 @@ sub change_layer {
     
     $self->layer($layer);
     
-    # avoid computing overhangs if they're not needed
+    # avoid computing islands and overhangs if they're not needed
+    if ($self->config->only_retract_when_crossing_perimeters) {
+        $self->_layer_islands([ $layer->islands ]);
+        $self->_upper_layer_islands([ $layer->upper_layer_islands ]);
+    } else {
+        $self->_layer_islands([]);
+        $self->_upper_layer_islands([]);
+    }
     $self->_layer_overhangs(
         $layer->id > 0 && ($Slic3r::Config->overhangs || $Slic3r::Config->start_perimeters_at_non_overhang)
             ? [ map $_->expolygon, grep $_->surface_type == S_TYPE_BOTTOM, map @{$_->slices}, @{$layer->regions} ]
@@ -116,6 +124,15 @@ sub change_layer {
             int(99 * ($layer->id / ($self->layer_count - 1))),
             ($self->config->gcode_comments ? ' ; update progress' : '');
     }
+    if ($self->config->first_layer_acceleration) {
+        if ($layer->id == 0) {
+            $gcode .= $self->set_acceleration($self->config->first_layer_acceleration);
+        } elsif ($layer->id == 1) {
+            $gcode .= $self->set_acceleration($self->config->default_acceleration);
+        }
+    }
+    
+    $gcode .= $self->move_z($layer->print_z);
     return $gcode;
 }
 
@@ -137,7 +154,6 @@ sub move_z {
         $self->speed('travel');
         $gcode .= $self->G0(undef, $z, 0, $comment || ('move to next layer (' . $self->layer->id . ')'))
             if !defined $self->z || abs($z - ($self->z - $self->lifted)) > epsilon;
-        $gcode .= $self->move_z_callback->() if defined $self->move_z_callback;
     } elsif ($z < $self->z && $z > ($self->z - $self->lifted + epsilon)) {
         # we're moving to a layer height which is greater than the nominal current one
         # (nominal = actual - lifted) and less than the actual one.  we're basically
@@ -286,14 +302,16 @@ sub extrude_path {
     
     # adjust acceleration
     my $acceleration;
-    if ($self->config->perimeter_acceleration && $path->is_perimeter) {
-        $acceleration = $self->config->perimeter_acceleration;
-    } elsif ($self->config->infill_acceleration && $path->is_fill) {
-        $acceleration = $self->config->infill_acceleration;
-    } elsif ($self->config->infill_acceleration && $path->is_bridge) {
-        $acceleration = $self->config->bridge_acceleration;
+    if (!$self->config->first_layer_acceleration || $self->layer->id != 0) {
+        if ($self->config->perimeter_acceleration && $path->is_perimeter) {
+            $acceleration = $self->config->perimeter_acceleration;
+        } elsif ($self->config->infill_acceleration && $path->is_fill) {
+            $acceleration = $self->config->infill_acceleration;
+        } elsif ($self->config->infill_acceleration && $path->is_bridge) {
+            $acceleration = $self->config->bridge_acceleration;
+        }
+        $gcode .= $self->set_acceleration($acceleration) if $acceleration;
     }
-    $gcode .= $self->set_acceleration($acceleration) if $acceleration;
     
     my $area;  # mm^3 of extrudate per mm of tool movement 
     if ($path->is_bridge) {
@@ -361,9 +379,9 @@ sub travel_to {
     # *and* in an island in the upper layer (so that the ooze will not be visible)
     if ($travel->length < scale $self->extruder->retract_before_travel
         || ($self->config->only_retract_when_crossing_perimeters
-            && (first { $_->encloses_line($travel, scaled_epsilon) } @{$self->layer->upper_layer_slices})
-            && (first { $_->encloses_line($travel, scaled_epsilon) } @{$self->layer->slices}))
-        || ($role == EXTR_ROLE_SUPPORTMATERIAL && $self->layer->support_islands_enclose_line($travel))
+            && (first { $_->encloses_line($travel, scaled_epsilon) } @{$self->_upper_layer_islands})
+            && (first { $_->encloses_line($travel, scaled_epsilon) } @{$self->_layer_islands}))
+        || ($role == EXTR_ROLE_SUPPORTMATERIAL && (first { $_->encloses_line($travel, scaled_epsilon) } @{$self->layer->support_islands}))
         ) {
         $self->straight_once(0);
         $self->speed('travel');
@@ -405,9 +423,9 @@ sub _plan {
     my $need_retract = !$self->config->only_retract_when_crossing_perimeters;
     if (!$need_retract) {
         $need_retract = 1;
-        foreach my $slice (@{$self->layer->upper_layer_slices}) {
+        foreach my $island ($self->layer->upper_layer_islands) {
             # discard the island if at any line is not enclosed in it
-            next if first { !$slice->encloses_line($_, scaled_epsilon) } @travel;
+            next if first { !$island->encloses_line($_, scaled_epsilon) } @travel;
             # okay, this island encloses the full travel path
             $need_retract = 0;
             last;

+ 6 - 18
lib/Slic3r/GCode/Layer.pm

@@ -46,23 +46,16 @@ sub process_layer {
         $self->second_layer_things_done(1);
     }
     
-    # set new layer, but don't move Z as support material contact areas may need an intermediate one
+    # set new layer - this will change Z and force a retraction if retract_layer_change is enabled
     $gcode .= $self->gcodegen->change_layer($layer);
-    
-    # prepare callback to call as soon as a Z command is generated
-    $self->gcodegen->move_z_callback(sub {
-        $self->gcodegen->move_z_callback(undef);  # circular ref or not?
-        return "" if !$Slic3r::Config->layer_gcode;
-        return $Slic3r::Config->replace_options($Slic3r::Config->layer_gcode, {
-            layer_num => $self->gcodegen->layer->id,
-        }) . "\n";
-    });
+    $gcode .= $Slic3r::Config->replace_options($Slic3r::Config->layer_gcode, {
+        layer_num => $self->gcodegen->layer->id,
+    }) . "\n" if $Slic3r::Config->layer_gcode;
     
     # extrude skirt
     if ((values %{$self->skirt_done}) < $Slic3r::Config->skirt_height && !$self->skirt_done->{$layer->print_z}) {
         $self->gcodegen->set_shift(@{$self->shift});
-        $gcode .= $self->gcodegen->set_extruder($self->extruders->[0]);  # move_z requires extruder
-        $gcode .= $self->gcodegen->move_z($layer->print_z);
+        $gcode .= $self->gcodegen->set_extruder($self->extruders->[0]);
         # skip skirt if we have a large brim
         if ($layer->id < $Slic3r::Config->skirt_height) {
             # distribute skirt loops across all extruders
@@ -81,8 +74,7 @@ sub process_layer {
     
     # extrude brim
     if (!$self->brim_done) {
-        $gcode .= $self->gcodegen->set_extruder($self->extruders->[$Slic3r::Config->support_material_extruder-1]);  # move_z requires extruder
-        $gcode .= $self->gcodegen->move_z($layer->print_z);
+        $gcode .= $self->gcodegen->set_extruder($self->extruders->[$Slic3r::Config->support_material_extruder-1]);
         $self->gcodegen->set_shift(@{$self->shift});
         $gcode .= $self->gcodegen->extrude_loop($_, 'brim') for @{$self->print->brim};
         $self->brim_done(1);
@@ -98,7 +90,6 @@ 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->print_z);
             if ($layer->support_interface_fills) {
                 $gcode .= $self->gcodegen->set_extruder($self->extruders->[$Slic3r::Config->support_material_interface_extruder-1]);
                 $gcode .= $self->gcodegen->extrude_path($_, 'support material interface') 
@@ -111,9 +102,6 @@ sub process_layer {
             }
         }
         
-        # set actual Z - this will force a retraction
-        $gcode .= $self->gcodegen->move_z($layer->print_z);
-        
         # tweak region ordering to save toolchanges
         my @region_ids = 0 .. ($self->print->regions_count-1);
         if ($self->gcodegen->multiple_extruders) {

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

@@ -461,7 +461,7 @@ sub build {
         },
         {
             title => 'Acceleration control (advanced)',
-            options => [qw(perimeter_acceleration infill_acceleration bridge_acceleration default_acceleration)],
+            options => [qw(perimeter_acceleration infill_acceleration bridge_acceleration first_layer_acceleration default_acceleration)],
         },
     ]);
     

+ 1 - 1
lib/Slic3r/Geometry/Clipper.pm

@@ -29,7 +29,7 @@ sub union {
     my ($polygons, $jointype, $safety_offset) = @_;
     $jointype = PFT_NONZERO unless defined $jointype;
     $clipper->clear;
-    $clipper->add_subject_polygons($safety_offset ? safety_offset($polygons) : $polygons);
+    $clipper->add_subject_polygons(_convert($safety_offset ? safety_offset($polygons) : $polygons));
     return [
         map Slic3r::Polygon->new(@$_),
             @{ $clipper->execute(CT_UNION, $jointype, $jointype) },

+ 14 - 11
lib/Slic3r/Layer.pm

@@ -23,11 +23,16 @@ sub _trigger_id {
     $_->_trigger_layer for @{$self->regions || []};
 }
 
-sub upper_layer_slices {
+sub islands {
+    my $self = shift;
+    return @{$self->slices};
+}
+
+sub upper_layer_islands {
     my $self = shift;
     
-    my $upper_layer = $self->object->layers->[ $self->id + 1 ] or return [];
-    return $upper_layer->slices;
+    my $upper_layer = $self->object->layers->[ $self->id + 1 ] or return ();
+    return $upper_layer->islands;
 }
 
 sub region {
@@ -59,20 +64,18 @@ sub make_perimeters {
     $_->make_perimeters for @{$self->regions};
 }
 
-sub support_islands_enclose_line {
-    my $self = shift;
-    my ($line) = @_;
-    return 0 if !$self->support_islands;   # why can we arrive here if there are no support islands?
-    return (first { $_->encloses_line($line) } @{$self->support_islands}) ? 1 : 0;
-}
-
 package Slic3r::Layer::Support;
 use Moo;
 extends 'Slic3r::Layer';
 
 # ordered collection of extrusion paths to fill surfaces for support material
-has 'support_islands'           => (is => 'rw');
+has 'support_islands'           => (is => 'rw', default => sub { [] });
 has 'support_fills'             => (is => 'rw');
 has 'support_interface_fills'   => (is => 'rw');
 
+sub islands {
+    my $self = shift;
+    return @{$self->slices}, @{$self->support_islands};
+}
+
 1;

Some files were not shown because too many files changed in this diff