Browse Source

Make tests pass

Alessandro Ranellucci 11 years ago
parent
commit
07b9b12475

+ 1 - 2
lib/Slic3r/Extruder.pm

@@ -40,8 +40,7 @@ sub new_from_config {
         use_relative_e_distances => $config->use_relative_e_distances,
     );
     foreach my $opt_key (@{&OPTIONS}) {
-        my $value = $config->get($opt_key);
-        $conf{$opt_key} = $value->[$extruder_id] // $value->[0];
+        $conf{$opt_key} = $config->get_at($opt_key, $extruder_id);
     }
     return $class->new(%conf);
 }

+ 2 - 2
lib/Slic3r/Flow.pm

@@ -72,7 +72,7 @@ sub mm3_per_mm {
     my $s = $self->spacing;
     
     if ($self->bridge) {
-        return ($s**2) * PI/4;
+        return ($w**2) * PI/4;
     } elsif ($w >= ($self->nozzle_diameter + $h)) {
         # rectangle with semicircles at the ends
         return $w * $h + ($h**2) / 4 * (PI - 4);
@@ -140,7 +140,7 @@ sub _spacing {
     if ($bridge_flow_ratio > 0) {
         return $width + BRIDGE_EXTRA_SPACING;
     }
-    
+    use XXX; ZZZ "here" if !defined $nozzle_diameter;
     my $min_flow_spacing;
     if ($width >= ($nozzle_diameter + $layer_height)) {
         # rectangle with semicircles at the ends

+ 14 - 21
lib/Slic3r/GCode.pm

@@ -12,7 +12,7 @@ has 'print_config'       => (is => 'ro', default => sub { Slic3r::Config::Print-
 has 'extra_variables'    => (is => 'rw', default => sub {{}});
 has 'standby_points'     => (is => 'rw');
 has 'enable_loop_clipping' => (is => 'rw', default => sub {1});
-has 'enable_wipe'        => (is => 'lazy');   # at least one extruder has wipe enabled
+has 'enable_wipe'        => (is => 'rw', default => sub {0});   # at least one extruder has wipe enabled
 has 'layer_count'        => (is => 'ro', required => 1 );
 has 'layer'              => (is => 'rw');
 has 'region'             => (is => 'rw');
@@ -25,14 +25,13 @@ has 'z'                  => (is => 'rw');
 has 'speed'              => (is => 'rw');
 has '_extrusion_axis'    => (is => 'rw');
 has '_retract_lift'      => (is => 'rw');
-has 'extruders'          => (is => 'ro', default => sub {[]});
-
+has 'extruders'          => (is => 'ro', default => sub {{}});
+has 'extruder'           => (is => 'rw');
 has 'speeds'             => (is => 'lazy');  # mm/min
 has 'external_mp'        => (is => 'rw');
 has 'layer_mp'           => (is => 'rw');
 has 'new_object'         => (is => 'rw', default => sub {0});
 has 'straight_once'      => (is => 'rw', default => sub {1});
-has 'extruder'           => (is => 'rw');
 has 'elapsed_time'       => (is => 'rw', default => sub {0} );  # seconds
 has 'lifted'             => (is => 'rw', default => sub {0} );
 has 'last_pos'           => (is => 'rw', default => sub { Slic3r::Point->new(0,0) } );
@@ -52,7 +51,8 @@ sub set_extruders {
     my ($self, $extruder_ids) = @_;
     
     foreach my $i (@$extruder_ids) {
-        $self->extruders->[$i] = Slic3r::Extruder->new_from_config($self->print_config, $i);
+        $self->extruders->{$i} = my $e = Slic3r::Extruder->new_from_config($self->print_config, $i);
+        $self->enable_wipe(1) if $e->wipe;
     }
 }
 
@@ -82,12 +82,7 @@ my %role_speeds = (
 
 sub multiple_extruders {
     my $self = shift;
-    return @{$self->extruders} > 1;
-}
-
-sub _build_enable_wipe {
-    my $self = shift;
-    return (first { $_->wipe } @{$self->extruders}) ? 1 : 0;
+    return (keys %{$self->extruders}) > 1;
 }
 
 sub set_shift {
@@ -248,14 +243,12 @@ sub extrude_loop {
             @{$extrusion_path->subtract_expolygons($self->_layer_overhangs)};
         
         # get overhang paths by intersecting overhangs with the loop
-        push @paths,
-            map {
-                $_->role(EXTR_ROLE_OVERHANG_PERIMETER);
-                $_->mm3_per_mm($self->region->flow(FLOW_ROLE_PERIMETER, undef, 1)->mm3_per_mm(undef));
-                $_
-            }
-            map $_->clone,
-            @{$extrusion_path->intersect_expolygons($self->_layer_overhangs)};
+        foreach my $path (@{$extrusion_path->intersect_expolygons($self->_layer_overhangs)}) {
+            $path = $path->clone;
+            $path->role(EXTR_ROLE_OVERHANG_PERIMETER);
+            $path->mm3_per_mm($self->region->flow(FLOW_ROLE_PERIMETER, undef, 1)->mm3_per_mm(undef));
+            push @paths, $path;
+        }
         
         # reapply the nearest point search for starting point
         # (clone because the collection gets DESTROY'ed)
@@ -644,7 +637,7 @@ sub set_extruder {
     
     # if we are running a single-extruder setup, just set the extruder and return nothing
     if (!$self->multiple_extruders) {
-        $self->extruder($self->extruders->[$extruder_id]);
+        $self->extruder($self->extruders->{$extruder_id});
         return "";
     }
     
@@ -673,7 +666,7 @@ sub set_extruder {
     }
     
     # set the new extruder
-    $self->extruder($self->extruders->[$extruder_id]);
+    $self->extruder($self->extruders->{$extruder_id});
     $gcode .= sprintf "%s%d%s\n", 
         ($self->print_config->gcode_flavor eq 'makerware'
             ? 'M135 T'

+ 9 - 7
lib/Slic3r/GCode/Layer.pm

@@ -4,8 +4,8 @@ use Moo;
 use List::Util qw(first);
 use Slic3r::Geometry qw(X Y unscale);
 
-has 'print'                         => (is => 'ro', required => 1, handles => [qw(extruders)]);
-has 'gcodegen'                      => (is => 'ro', required => 1);
+has 'print'                         => (is => 'ro', required => 1);
+has 'gcodegen'                      => (is => 'ro', required => 1, handles => [qw(extruders)]);
 has 'shift'                         => (is => 'ro', default => sub { [0,0] });
 
 has 'spiralvase'                    => (is => 'lazy');
@@ -57,9 +57,10 @@ sub process_layer {
     $self->gcodegen->enable_loop_clipping(!$spiralvase);
     
     if (!$self->second_layer_things_done && $layer->id == 1) {
-        for my $t (grep $self->extruders->[$_], 0 .. $#{$self->print->config->temperature}) {
-            $gcode .= $self->gcodegen->set_temperature($self->extruders->[$t]->temperature, 0, $t)
-                if $self->print->extruders->[$t]->temperature && $self->extruders->[$t]->temperature != $self->extruders->[$t]->first_layer_temperature;
+        for my $extruder_id (sort keys %{$self->extruders}) {
+            my $extruder = $self->extruders->{$extruder_id};
+            $gcode .= $self->gcodegen->set_temperature($extruder->temperature, 0, $extruder->id)
+                if $extruder->temperature && $extruder->temperature != $extruder->first_layer_temperature;
         }
         $gcode .= $self->gcodegen->set_bed_temperature($self->print->config->bed_temperature)
             if $self->print->config->bed_temperature && $self->print->config->bed_temperature != $self->print->config->first_layer_bed_temperature;
@@ -76,7 +77,8 @@ sub process_layer {
     if (((values %{$self->skirt_done}) < $self->print->config->skirt_height || $self->print->config->skirt_height == -1)
         && !$self->skirt_done->{$layer->print_z}) {
         $self->gcodegen->set_shift(@{$self->shift});
-        $gcode .= $self->gcodegen->set_extruder($self->extruders->[0]);
+        my @extruder_ids = sort keys %{$self->extruders};
+        $gcode .= $self->gcodegen->set_extruder($extruder_ids[0]);
         # skip skirt if we have a large brim
         if ($layer->id < $self->print->config->skirt_height || $self->print->config->skirt_height == -1) {
             # distribute skirt loops across all extruders
@@ -85,7 +87,7 @@ sub process_layer {
                 # when printing layers > 0 ignore 'min_skirt_length' and 
                 # just use the 'skirts' setting; also just use the current extruder
                 last if ($layer->id > 0) && ($i >= $self->print->config->skirts);
-                $gcode .= $self->gcodegen->set_extruder(($i/@{$self->extruders}) % @{$self->extruders})
+                $gcode .= $self->gcodegen->set_extruder(($i/@extruder_ids) % @extruder_ids)
                     if $layer->id == 0;
                 $gcode .= $self->gcodegen->extrude_loop($skirt_loops[$i], 'skirt');
             }

+ 9 - 7
lib/Slic3r/Print.pm

@@ -709,7 +709,7 @@ sub make_brim {
     my $flow = Slic3r::Flow->new_from_width(
         width               => ($self->config->first_layer_extrusion_width || $self->regions->[0]->config->perimeter_extrusion_width),
         role                => FLOW_ROLE_PERIMETER,
-        nozzle_diameter     => $self->config->nozzle_diameter->[ $self->objects->[0]->config->support_material_extruder-1 ],
+        nozzle_diameter     => $self->config->get_at('nozzle_diameter', $self->objects->[0]->config->support_material_extruder-1),
         layer_height        => $first_layer_height,
         bridge_flow_ratio   => 0,
     );
@@ -807,7 +807,6 @@ sub write_gcode {
         layer_count         => $self->layer_count,
     );
     $gcodegen->set_extruders($self->extruders);
-    $gcodegen->set_extruder($self->extruders->[0]);
     
     print $fh "G21 ; set units to millimeters\n" if $self->config->gcode_flavor ne 'makerware';
     print $fh $gcodegen->set_fan(0, 1) if $self->config->cooling && $self->config->disable_fan_first_layers;
@@ -822,8 +821,8 @@ sub write_gcode {
         my ($wait) = @_;
         
         return if $self->config->start_gcode =~ /M(?:109|104)/i;
-        for my $t (0 .. $#{$self->extruders}) {
-            my $temp = $self->config->first_layer_temperature->[$t] // $self->config->first_layer_temperature->[0];
+        for my $t (@{$self->extruders}) {
+            my $temp = $self->config->get_at('first_layer_temperature', $t);
             $temp += $self->config->standby_temperature_delta if $self->config->ooze_prevention;
             printf $fh $gcodegen->set_temperature($temp, $wait, $t) if $temp > 0;
         }
@@ -873,9 +872,9 @@ sub write_gcode {
         if (@skirt_points) {
             my $outer_skirt = convex_hull(\@skirt_points);
             my @skirts = ();
-            foreach my $extruder (@{$self->extruders}) {
+            foreach my $extruder_id (@{$self->extruders}) {
                 push @skirts, my $s = $outer_skirt->clone;
-                $s->translate(map scale($_), @{$extruder->extruder_offset});
+                $s->translate(map scale($_), @{$self->config->get_at('extruder_offset', $extruder_id)});
             }
             my $convex_hull = convex_hull([ map @$_, @skirts ]);
             $gcodegen->standby_points([ map $_->clone, map @$_, map $_->subdivide(scale 10), @{offset([$convex_hull], scale 3)} ]);
@@ -888,6 +887,9 @@ sub write_gcode {
         gcodegen    => $gcodegen,
     );
     
+    # set initial extruder only after custom start G-code
+    print $fh $gcodegen->set_extruder($self->extruders->[0]);
+    
     # do all objects for each layer
     if ($self->config->complete_objects) {
         # print objects from the smallest to the tallest to avoid collisions
@@ -975,7 +977,7 @@ sub write_gcode {
     $self->total_used_filament(0);
     $self->total_extruded_volume(0);
     foreach my $extruder_id (@{$self->extruders}) {
-        my $extruder = $gcodegen->extruders->[$extruder_id];
+        my $extruder = $gcodegen->extruders->{$extruder_id};
         $self->total_used_filament($self->total_used_filament + $extruder->absolute_E);
         $self->total_extruded_volume($self->total_extruded_volume + $extruder->extruded_volume);
         

+ 7 - 6
lib/Slic3r/Print/Object.pm

@@ -758,7 +758,7 @@ sub combine_infill {
         my $every = $region->config->infill_every_layers;
         
         # limit the number of combined layers to the maximum height allowed by this regions' nozzle
-        my $nozzle_diameter = $self->print->config->nozzle_diameter->[ $region->config->infill_extruder-1 ];
+        my $nozzle_diameter = $self->print->config->get_at('nozzle_diameter', $region->config->infill_extruder-1);
         
         # define the combinations
         my @combine = ();   # layer_id => thickness in layers
@@ -810,12 +810,12 @@ sub combine_infill {
                 # so let's remove those areas from all layers
                 
                  my @intersection_with_clearance = map @{$_->offset(
-                       $layerms[-1]->solid_infill_flow->scaled_width    / 2
-                     + $layerms[-1]->perimeter_flow->scaled_width / 2
+                       $layerms[-1]->flow(FLOW_ROLE_SOLID_INFILL)->scaled_width    / 2
+                     + $layerms[-1]->flow(FLOW_ROLE_PERIMETER)->scaled_width / 2
                      # Because fill areas for rectilinear and honeycomb are grown 
                      # later to overlap perimeters, we need to counteract that too.
                      + (($type == S_TYPE_INTERNALSOLID || $region->config->fill_pattern =~ /(rectilinear|honeycomb)/)
-                       ? $layerms[-1]->solid_infill_flow->scaled_width * &Slic3r::INFILL_OVERLAP_OVER_SPACING
+                       ? $layerms[-1]->flow(FLOW_ROLE_SOLID_INFILL)->scaled_width * &Slic3r::INFILL_OVERLAP_OVER_SPACING
                        : 0)
                      )}, @$intersection;
 
@@ -866,7 +866,8 @@ sub generate_support_material {
     my $first_layer_flow = Slic3r::Flow->new_from_width(
         width               => ($self->config->first_layer_extrusion_width || $self->config->support_material_extrusion_width),
         role                => FLOW_ROLE_SUPPORT_MATERIAL,
-        nozzle_diameter     => $self->print->config->nozzle_diameter->[ $self->config->support_material_extruder-1 ],
+        nozzle_diameter     => $self->print->config->nozzle_diameter->[ $self->config->support_material_extruder-1 ]
+                                // $self->print->config->nozzle_diameter->[0],
         layer_height        => $self->config->get_abs_value('first_layer_height'),
         bridge_flow_ratio   => 0,
     );
@@ -903,7 +904,7 @@ sub support_material_flow {
     return Slic3r::Flow->new_from_width(
         width               => $self->config->support_material_extrusion_width,
         role                => $role,
-        nozzle_diameter     => $self->print->config->nozzle_diameter->[$extruder-1],
+        nozzle_diameter     => $self->print->config->nozzle_diameter->[$extruder-1] // $self->print->config->nozzle_diameter->[0],
         layer_height        => $self->config->layer_height,
         bridge_flow_ratio   => 0,
     );

+ 1 - 1
lib/Slic3r/Print/Region.pm

@@ -46,7 +46,7 @@ sub flow {
     } else {
         die "Unknown role $role";
     }
-    my $nozzle_diameter = $self->print->config->nozzle_diameter->[$extruder-1];
+    my $nozzle_diameter = $self->print->config->get_at('nozzle_diameter', $extruder-1);
     
     return Slic3r::Flow->new_from_width(
         width               => $config_width,

+ 2 - 2
lib/Slic3r/Print/SupportMaterial.pm

@@ -174,7 +174,7 @@ sub contact_area {
         # now apply the contact areas to the layer were they need to be made
         {
             # get the average nozzle diameter used on this layer
-            my @nozzle_diameters = map $self->print_config->nozzle_diameter->[$_],
+            my @nozzle_diameters = map $self->print_config->get_at('nozzle_diameter', $_),
                 map { $_->config->perimeter_extruder-1, $_->config->infill_extruder-1 }
                 @{$layer->regions};
             my $nozzle_diameter = sum(@nozzle_diameters)/@nozzle_diameters;
@@ -246,7 +246,7 @@ sub support_layers_z {
     # determine layer height for any non-contact layer
     # we use max() to prevent many ultra-thin layers to be inserted in case
     # layer_height > nozzle_diameter * 0.75
-    my $nozzle_diameter = $self->print_config->nozzle_diameter->[$self->object_config->support_material_extruder-1];
+    my $nozzle_diameter = $self->print_config->get_at('nozzle_diameter', $self->object_config->support_material_extruder-1);
     my $support_material_height = max($max_object_layer_height, $nozzle_diameter * 0.75);
     
     my @z = sort { $a <=> $b } @$contact_z, @$top_z, (map $_ + $nozzle_diameter, @$top_z);

+ 33 - 2
t/combineinfill.t

@@ -11,10 +11,41 @@ use List::Util qw(first);
 use Slic3r;
 use Slic3r::Test;
 
-plan skip_all => 'this test is currently disabled';  # needs to be adapted to the new API
-plan tests => 3;
+plan tests => 2;
 
 {
+    my $config = Slic3r::Config->new_from_defaults;
+    $config->set('layer_height', 0.2);
+    $config->set('first_layer_height', 0.2);
+    $config->set('nozzle_diameter', [0.5]);
+    $config->set('infill_every_layers', 2);
+    $config->set('infill_extruder', 2);
+    $config->set('top_solid_layers', 0);
+    $config->set('bottom_solid_layers', 0);
+    my $print = Slic3r::Test::init_print('20mm_cube', config => $config);
+    ok my $gcode = Slic3r::Test::gcode($print), "infill_every_layers does not crash";
+    
+    my $tool = undef;
+    my %layer_infill = ();  # layer_z => has_infill
+    Slic3r::GCode::Reader->new->parse($gcode, sub {
+        my ($self, $cmd, $args, $info) = @_;
+        
+        if ($cmd =~ /^T(\d+)/) {
+            $tool = $1;
+        } elsif ($cmd eq 'G1' && $info->{extruding} && $info->{dist_XY} > 0) {
+            $layer_infill{$self->Z} //= 0;
+            if ($tool == $config->infill_extruder-1) {
+                $layer_infill{$self->Z} = 1;
+            }
+        }
+    });
+    my $layers_with_infill = grep $_,  values %layer_infill;
+    $layers_with_infill--; # first layer is never combined
+    is $layers_with_infill, scalar(keys %layer_infill)/2, 'infill is only present in correct number of layers';
+}
+
+# the following needs to be adapted to the new API
+if (0) {
     my $config = Slic3r::Config->new_from_defaults;
     $config->set('skirts', 0);
     $config->set('solid_layers', 0);

+ 9 - 9
t/retraction.t

@@ -41,8 +41,8 @@ my $test = sub {
         
         if ($info->{dist_Z}) {
             # lift move or lift + change layer
-            if (_eq($info->{dist_Z}, $print->extruders->[$tool]->retract_lift)
-                || (_eq($info->{dist_Z}, $conf->layer_height + $print->extruders->[$tool]->retract_lift) && $print->extruders->[$tool]->retract_lift > 0)) {
+            if (_eq($info->{dist_Z}, $print->config->get_at('retract_lift', $tool))
+                || (_eq($info->{dist_Z}, $conf->layer_height + $print->config->get_at('retract_lift', $tool)) && $print->config->get_at('retract_lift', $tool) > 0)) {
                 fail 'only lifting while retracted' if !$retracted[$tool] && !($conf->g0 && $info->{retracting});
                 fail 'double lift' if $lifted;
                 $lifted = 1;
@@ -50,8 +50,8 @@ my $test = sub {
             if ($info->{dist_Z} < 0) {
                 fail 'going down only after lifting' if !$lifted;
                 fail 'going down by the same amount of the lift or by the amount needed to get to next layer'
-                    if !_eq($info->{dist_Z}, -$print->extruders->[$tool]->retract_lift)
-                        && !_eq($info->{dist_Z}, -$print->extruders->[$tool]->retract_lift + $conf->layer_height);
+                    if !_eq($info->{dist_Z}, -$print->config->get_at('retract_lift', $tool))
+                        && !_eq($info->{dist_Z}, -$print->config->get_at('retract_lift', $tool) + $conf->layer_height);
                 $lifted = 0;
             }
             fail 'move Z at travel speed' if ($args->{F} // $self->F) != $conf->travel_speed * 60;
@@ -59,9 +59,9 @@ my $test = sub {
         if ($info->{retracting}) {
             $retracted[$tool] = 1;
             $retracted_length[$tool] += -$info->{dist_E};
-            if (_eq($retracted_length[$tool], $print->extruders->[$tool]->retract_length)) {
+            if (_eq($retracted_length[$tool], $print->config->get_at('retract_length', $tool))) {
                 # okay
-            } elsif (_eq($retracted_length[$tool], $print->extruders->[$tool]->retract_length_toolchange)) {
+            } elsif (_eq($retracted_length[$tool], $print->config->get_at('retract_length_toolchange', $tool))) {
                 $wait_for_toolchange = 1;
             } else {
                 fail 'retracted by the correct amount';
@@ -72,9 +72,9 @@ my $test = sub {
         if ($info->{extruding}) {
             fail 'only extruding while not lifted' if $lifted;
             if ($retracted[$tool]) {
-                my $expected_amount = $retracted_length[$tool] + $print->extruders->[$tool]->retract_restart_extra;
+                my $expected_amount = $retracted_length[$tool] + $print->config->get_at('retract_restart_extra', $tool);
                 if ($changed_tool && $toolchange_count[$tool] > 1) {
-                    $expected_amount = $print->extruders->[$tool]->retract_length_toolchange + $print->extruders->[$tool]->retract_restart_extra_toolchange;
+                    $expected_amount = $print->config->get_at('retract_length_toolchange', $tool) + $print->config->get_at('retract_restart_extra_toolchange', $tool);
                     $changed_tool = 0;
                 }
                 fail 'unretracted by the correct amount'
@@ -83,7 +83,7 @@ my $test = sub {
                 $retracted_length[$tool] = 0;
             }
         }
-        if ($info->{travel} && $info->{dist_XY} >= $print->extruders->[$tool]->retract_before_travel) {
+        if ($info->{travel} && $info->{dist_XY} >= $print->config->get_at('retract_before_travel', $tool)) {
             fail 'retracted before long travel move' if !$retracted[$tool];
         }
     });

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