mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	Merge branch 'master' into sender
Conflicts: Build.PL lib/Slic3r.pm xs/MANIFEST xs/src/libslic3r/PrintConfig.hpp
This commit is contained in:
		
						commit
						9b21ac877a
					
				
					 93 changed files with 3339 additions and 2050 deletions
				
			
		| 
						 | 
				
			
			@ -15,7 +15,8 @@ has '_brim_done'                     => (is => 'rw');
 | 
			
		|||
has '_second_layer_things_done'      => (is => 'rw');
 | 
			
		||||
has '_last_obj_copy'                 => (is => 'rw');
 | 
			
		||||
 | 
			
		||||
use List::Util qw(first sum);
 | 
			
		||||
use List::Util qw(first sum min max);
 | 
			
		||||
use Slic3r::ExtrusionPath ':roles';
 | 
			
		||||
use Slic3r::Flow ':roles';
 | 
			
		||||
use Slic3r::Geometry qw(X Y scale unscale chained_path convex_hull);
 | 
			
		||||
use Slic3r::Geometry::Clipper qw(JT_SQUARE union_ex offset);
 | 
			
		||||
| 
						 | 
				
			
			@ -35,14 +36,65 @@ sub BUILD {
 | 
			
		|||
        }
 | 
			
		||||
    
 | 
			
		||||
        # set up our helper object
 | 
			
		||||
        my $gcodegen = Slic3r::GCode->new(
 | 
			
		||||
            placeholder_parser  => $self->placeholder_parser,
 | 
			
		||||
            layer_count         => $layer_count,
 | 
			
		||||
            enable_cooling_markers => 1,
 | 
			
		||||
        );
 | 
			
		||||
        my $gcodegen = Slic3r::GCode->new;
 | 
			
		||||
        $self->_gcodegen($gcodegen);
 | 
			
		||||
        $gcodegen->set_placeholder_parser($self->placeholder_parser);
 | 
			
		||||
        $gcodegen->set_layer_count($layer_count);
 | 
			
		||||
        $gcodegen->set_enable_cooling_markers(1);
 | 
			
		||||
        $gcodegen->apply_print_config($self->config);
 | 
			
		||||
        $gcodegen->set_extruders($self->print->extruders);
 | 
			
		||||
        $self->_gcodegen($gcodegen);
 | 
			
		||||
        
 | 
			
		||||
        # initialize autospeed
 | 
			
		||||
        {
 | 
			
		||||
            # get the minimum cross-section used in the print
 | 
			
		||||
            my @mm3_per_mm = ();
 | 
			
		||||
            foreach my $object (@{$self->print->objects}) {
 | 
			
		||||
                foreach my $region_id (0..$#{$self->print->regions}) {
 | 
			
		||||
                    my $region = $self->print->get_region($region_id);
 | 
			
		||||
                    foreach my $layer (@{$object->layers}) {
 | 
			
		||||
                        my $layerm = $layer->get_region($region_id);
 | 
			
		||||
                        if ($region->config->get_abs_value('perimeter_speed') == 0
 | 
			
		||||
                            || $region->config->get_abs_value('small_perimeter_speed') == 0
 | 
			
		||||
                            || $region->config->get_abs_value('external_perimeter_speed') == 0
 | 
			
		||||
                            || $region->config->get_abs_value('bridge_speed') == 0) {
 | 
			
		||||
                            push @mm3_per_mm, $layerm->perimeters->min_mm3_per_mm;
 | 
			
		||||
                        }
 | 
			
		||||
                        if ($region->config->get_abs_value('infill_speed') == 0
 | 
			
		||||
                            || $region->config->get_abs_value('solid_infill_speed') == 0
 | 
			
		||||
                            || $region->config->get_abs_value('top_solid_infill_speed') == 0
 | 
			
		||||
                            || $region->config->get_abs_value('bridge_speed') == 0) {
 | 
			
		||||
                            push @mm3_per_mm, $layerm->fills->min_mm3_per_mm;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if ($object->config->get_abs_value('support_material_speed') == 0
 | 
			
		||||
                    || $object->config->get_abs_value('support_material_interface_speed') == 0) {
 | 
			
		||||
                    foreach my $layer (@{$object->support_layers}) {
 | 
			
		||||
                        push @mm3_per_mm, $layer->support_fills->min_mm3_per_mm;
 | 
			
		||||
                        push @mm3_per_mm, $layer->support_interface_fills->min_mm3_per_mm;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            @mm3_per_mm = grep $_ != 0, @mm3_per_mm;
 | 
			
		||||
            if (@mm3_per_mm) {
 | 
			
		||||
                my $min_mm3_per_mm = min(@mm3_per_mm);
 | 
			
		||||
                # In order to honor max_print_speed we need to find a target volumetric
 | 
			
		||||
                # speed that we can use throughout the print. So we define this target 
 | 
			
		||||
                # volumetric speed as the volumetric speed produced by printing the 
 | 
			
		||||
                # smallest cross-section at the maximum speed: any larger cross-section
 | 
			
		||||
                # will need slower feedrates.
 | 
			
		||||
                my $volumetric_speed = $min_mm3_per_mm * $self->config->max_print_speed;
 | 
			
		||||
                
 | 
			
		||||
                # limit such volumetric speed with max_volumetric_speed if set
 | 
			
		||||
                if ($self->config->max_volumetric_speed > 0) {
 | 
			
		||||
                    $volumetric_speed = min(
 | 
			
		||||
                        $volumetric_speed,
 | 
			
		||||
                        $self->config->max_volumetric_speed,
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
                $gcodegen->set_volumetric_speed($volumetric_speed);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    $self->_cooling_buffer(Slic3r::GCode::CoolingBuffer->new(
 | 
			
		||||
| 
						 | 
				
			
			@ -160,8 +212,8 @@ sub export {
 | 
			
		|||
            }
 | 
			
		||||
            my $convex_hull = convex_hull([ map @$_, @skirts ]);
 | 
			
		||||
            
 | 
			
		||||
            $gcodegen->ooze_prevention->enable(1);
 | 
			
		||||
            $gcodegen->ooze_prevention->standby_points(
 | 
			
		||||
            $gcodegen->ooze_prevention->set_enable(1);
 | 
			
		||||
            $gcodegen->ooze_prevention->set_standby_points(
 | 
			
		||||
                [ map @{$_->equally_spaced_points(scale 10)}, @{offset([$convex_hull], scale 3)} ]
 | 
			
		||||
            );
 | 
			
		||||
            
 | 
			
		||||
| 
						 | 
				
			
			@ -195,18 +247,18 @@ sub export {
 | 
			
		|||
                # no collision happens hopefully.
 | 
			
		||||
                if ($finished_objects > 0) {
 | 
			
		||||
                    $gcodegen->set_origin(Slic3r::Pointf->new(map unscale $copy->[$_], X,Y));
 | 
			
		||||
                    $gcodegen->enable_cooling_markers(0);  # we're not filtering these moves through CoolingBuffer
 | 
			
		||||
                    $gcodegen->avoid_crossing_perimeters->use_external_mp_once(1);
 | 
			
		||||
                    $gcodegen->set_enable_cooling_markers(0);  # we're not filtering these moves through CoolingBuffer
 | 
			
		||||
                    $gcodegen->avoid_crossing_perimeters->set_use_external_mp_once(1);
 | 
			
		||||
                    print $fh $gcodegen->retract;
 | 
			
		||||
                    print $fh $gcodegen->travel_to(
 | 
			
		||||
                        Slic3r::Point->new(0,0),
 | 
			
		||||
                        undef,
 | 
			
		||||
                        EXTR_ROLE_NONE,
 | 
			
		||||
                        'move to origin position for next object',
 | 
			
		||||
                    );
 | 
			
		||||
                    $gcodegen->enable_cooling_markers(1);
 | 
			
		||||
                    $gcodegen->set_enable_cooling_markers(1);
 | 
			
		||||
                    
 | 
			
		||||
                    # disable motion planner when traveling to first object point
 | 
			
		||||
                    $gcodegen->avoid_crossing_perimeters->disable_once(1);
 | 
			
		||||
                    $gcodegen->avoid_crossing_perimeters->set_disable_once(1);
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                my @layers = sort { $a->print_z <=> $b->print_z } @{$object->layers}, @{$object->support_layers};
 | 
			
		||||
| 
						 | 
				
			
			@ -308,14 +360,14 @@ sub process_layer {
 | 
			
		|||
        $self->_spiral_vase->enable(
 | 
			
		||||
            ($layer->id > 0 || $self->print->config->brim_width == 0)
 | 
			
		||||
                && ($layer->id >= $self->print->config->skirt_height && !$self->print->has_infinite_skirt)
 | 
			
		||||
                && !defined(first { $_->config->bottom_solid_layers > $layer->id } @{$layer->regions})
 | 
			
		||||
                && !defined(first { $_->region->config->bottom_solid_layers > $layer->id } @{$layer->regions})
 | 
			
		||||
                && !defined(first { $_->perimeters->items_count > 1 } @{$layer->regions})
 | 
			
		||||
                && !defined(first { $_->fills->items_count > 0 } @{$layer->regions})
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    # if we're going to apply spiralvase to this layer, disable loop clipping
 | 
			
		||||
    $self->_gcodegen->enable_loop_clipping(!defined $self->_spiral_vase || !$self->_spiral_vase->enable);
 | 
			
		||||
    $self->_gcodegen->set_enable_loop_clipping(!defined $self->_spiral_vase || !$self->_spiral_vase->enable);
 | 
			
		||||
    
 | 
			
		||||
    if (!$self->_second_layer_things_done && $layer->id == 1) {
 | 
			
		||||
        for my $extruder (@{$self->_gcodegen->writer->extruders}) {
 | 
			
		||||
| 
						 | 
				
			
			@ -329,15 +381,19 @@ sub process_layer {
 | 
			
		|||
    }
 | 
			
		||||
    
 | 
			
		||||
    # set new layer - this will change Z and force a retraction if retract_layer_change is enabled
 | 
			
		||||
    $gcode .= $self->_gcodegen->placeholder_parser->process($self->print->config->before_layer_gcode, {
 | 
			
		||||
        layer_num => $self->_gcodegen->layer_index + 1,
 | 
			
		||||
        layer_z   => $layer->print_z,
 | 
			
		||||
    }) . "\n" if $self->print->config->before_layer_gcode;
 | 
			
		||||
    $gcode .= $self->_gcodegen->change_layer($layer);  # this will increase $self->_gcodegen->layer_index
 | 
			
		||||
    $gcode .= $self->_gcodegen->placeholder_parser->process($self->print->config->layer_gcode, {
 | 
			
		||||
        layer_num => $self->_gcodegen->layer_index,
 | 
			
		||||
        layer_z   => $layer->print_z,
 | 
			
		||||
    }) . "\n" if $self->print->config->layer_gcode;
 | 
			
		||||
    if ($self->print->config->before_layer_gcode) {
 | 
			
		||||
        my $pp = $self->_gcodegen->placeholder_parser->clone;
 | 
			
		||||
        $pp->set('layer_num' => $self->_gcodegen->layer_index + 1);
 | 
			
		||||
        $pp->set('layer_z'   => $layer->print_z);
 | 
			
		||||
        $gcode .= $pp->process($self->print->config->before_layer_gcode) . "\n";
 | 
			
		||||
    }
 | 
			
		||||
    $gcode .= $self->_gcodegen->change_layer($layer->as_layer);  # this will increase $self->_gcodegen->layer_index
 | 
			
		||||
    if ($self->print->config->layer_gcode) {
 | 
			
		||||
        my $pp = $self->_gcodegen->placeholder_parser->clone;
 | 
			
		||||
        $pp->set('layer_num' => $self->_gcodegen->layer_index);
 | 
			
		||||
        $pp->set('layer_z'   => $layer->print_z);
 | 
			
		||||
        $gcode .= $pp->process($self->print->config->layer_gcode) . "\n";
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    # extrude skirt along raft layers and normal object layers
 | 
			
		||||
    # (not along interlaced support material layers)
 | 
			
		||||
| 
						 | 
				
			
			@ -345,7 +401,7 @@ sub process_layer {
 | 
			
		|||
        && !$self->_skirt_done->{$layer->print_z}
 | 
			
		||||
        && (!$layer->isa('Slic3r::Layer::Support') || $layer->id < $object->config->raft_layers)) {
 | 
			
		||||
        $self->_gcodegen->set_origin(Slic3r::Pointf->new(0,0));
 | 
			
		||||
        $self->_gcodegen->avoid_crossing_perimeters->use_external_mp(1);
 | 
			
		||||
        $self->_gcodegen->avoid_crossing_perimeters->set_use_external_mp(1);
 | 
			
		||||
        my @extruder_ids = map { $_->id } @{$self->_gcodegen->writer->extruders};
 | 
			
		||||
        $gcode .= $self->_gcodegen->set_extruder($extruder_ids[0]);
 | 
			
		||||
        # skip skirt if we have a large brim
 | 
			
		||||
| 
						 | 
				
			
			@ -378,12 +434,12 @@ sub process_layer {
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
        $self->_skirt_done->{$layer->print_z} = 1;
 | 
			
		||||
        $self->_gcodegen->avoid_crossing_perimeters->use_external_mp(0);
 | 
			
		||||
        $self->_gcodegen->avoid_crossing_perimeters->set_use_external_mp(0);
 | 
			
		||||
        
 | 
			
		||||
        # allow a straight travel move to the first object point if this is the first layer
 | 
			
		||||
        # (but don't in next layers)
 | 
			
		||||
        if ($layer->id == 0) {
 | 
			
		||||
            $self->_gcodegen->avoid_crossing_perimeters->disable_once(1);
 | 
			
		||||
            $self->_gcodegen->avoid_crossing_perimeters->set_disable_once(1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			@ -391,19 +447,19 @@ sub process_layer {
 | 
			
		|||
    if (!$self->_brim_done) {
 | 
			
		||||
        $gcode .= $self->_gcodegen->set_extruder($self->print->regions->[0]->config->perimeter_extruder-1);
 | 
			
		||||
        $self->_gcodegen->set_origin(Slic3r::Pointf->new(0,0));
 | 
			
		||||
        $self->_gcodegen->avoid_crossing_perimeters->use_external_mp(1);
 | 
			
		||||
        $self->_gcodegen->avoid_crossing_perimeters->set_use_external_mp(1);
 | 
			
		||||
        $gcode .= $self->_gcodegen->extrude_loop($_, 'brim', $object->config->support_material_speed)
 | 
			
		||||
            for @{$self->print->brim};
 | 
			
		||||
        $self->_brim_done(1);
 | 
			
		||||
        $self->_gcodegen->avoid_crossing_perimeters->use_external_mp(0);
 | 
			
		||||
        $self->_gcodegen->avoid_crossing_perimeters->set_use_external_mp(0);
 | 
			
		||||
        
 | 
			
		||||
        # allow a straight travel move to the first object point
 | 
			
		||||
        $self->_gcodegen->avoid_crossing_perimeters->disable_once(1);
 | 
			
		||||
        $self->_gcodegen->avoid_crossing_perimeters->set_disable_once(1);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    for my $copy (@$object_copies) {
 | 
			
		||||
        # when starting a new object, use the external motion planner for the first travel move
 | 
			
		||||
        $self->_gcodegen->avoid_crossing_perimeters->use_external_mp_once(1) if ($self->_last_obj_copy // '') ne "$copy";
 | 
			
		||||
        $self->_gcodegen->avoid_crossing_perimeters->set_use_external_mp_once(1) if ($self->_last_obj_copy // '') ne "$copy";
 | 
			
		||||
        $self->_last_obj_copy("$copy");
 | 
			
		||||
        
 | 
			
		||||
        $self->_gcodegen->set_origin(Slic3r::Pointf->new(map unscale $copy->[$_], X,Y));
 | 
			
		||||
| 
						 | 
				
			
			@ -539,7 +595,7 @@ sub _extrude_perimeters {
 | 
			
		|||
    my $gcode = "";
 | 
			
		||||
    foreach my $region_id (sort keys %$entities_by_region) {
 | 
			
		||||
        $self->_gcodegen->config->apply_region_config($self->print->get_region($region_id)->config);
 | 
			
		||||
        $gcode .= $self->_gcodegen->extrude($_, 'perimeter')
 | 
			
		||||
        $gcode .= $self->_gcodegen->extrude($_, 'perimeter', -1)
 | 
			
		||||
            for @{ $entities_by_region->{$region_id} };
 | 
			
		||||
    }
 | 
			
		||||
    return $gcode;
 | 
			
		||||
| 
						 | 
				
			
			@ -555,10 +611,10 @@ sub _extrude_infill {
 | 
			
		|||
        my $collection = Slic3r::ExtrusionPath::Collection->new(@{ $entities_by_region->{$region_id} });
 | 
			
		||||
        for my $fill (@{$collection->chained_path_from($self->_gcodegen->last_pos, 0)}) {
 | 
			
		||||
            if ($fill->isa('Slic3r::ExtrusionPath::Collection')) {
 | 
			
		||||
                $gcode .= $self->_gcodegen->extrude($_, 'infill') 
 | 
			
		||||
                $gcode .= $self->_gcodegen->extrude($_, 'infill', -1) 
 | 
			
		||||
                    for @{$fill->chained_path_from($self->_gcodegen->last_pos, 0)};
 | 
			
		||||
            } else {
 | 
			
		||||
                $gcode .= $self->_gcodegen->extrude($fill, 'infill') ;
 | 
			
		||||
                $gcode .= $self->_gcodegen->extrude($fill, 'infill', -1) ;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,8 +45,9 @@ sub slice {
 | 
			
		|||
        $self->clear_layers;
 | 
			
		||||
    
 | 
			
		||||
        # make layers taking custom heights into account
 | 
			
		||||
        my $print_z = my $slice_z = my $height = my $id = 0;
 | 
			
		||||
        my $first_object_layer_height = -1;
 | 
			
		||||
        my $id      = 0;
 | 
			
		||||
        my $print_z = 0;
 | 
			
		||||
        my $first_object_layer_height   = -1;
 | 
			
		||||
        my $first_object_layer_distance = -1;
 | 
			
		||||
    
 | 
			
		||||
        # add raft layers
 | 
			
		||||
| 
						 | 
				
			
			@ -63,8 +64,8 @@ sub slice {
 | 
			
		|||
            {
 | 
			
		||||
                my @nozzle_diameters = (
 | 
			
		||||
                    map $self->print->config->get_at('nozzle_diameter', $_),
 | 
			
		||||
                        $self->config->support_material_extruder,
 | 
			
		||||
                        $self->config->support_material_interface_extruder,
 | 
			
		||||
                        $self->config->support_material_extruder-1,
 | 
			
		||||
                        $self->config->support_material_interface_extruder-1,
 | 
			
		||||
                );
 | 
			
		||||
                $support_material_layer_height = 0.75 * min(@nozzle_diameters);
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -78,20 +79,17 @@ sub slice {
 | 
			
		|||
                );
 | 
			
		||||
                $nozzle_diameter = sum(@nozzle_diameters)/@nozzle_diameters;
 | 
			
		||||
            }
 | 
			
		||||
            my $distance = $self->_support_material->contact_distance($self->config->layer_height, $nozzle_diameter);
 | 
			
		||||
            $first_object_layer_distance = $self->_support_material->contact_distance($self->config->layer_height, $nozzle_diameter);
 | 
			
		||||
        
 | 
			
		||||
            # force first layer print_z according to the contact distance
 | 
			
		||||
            # (the loop below will raise print_z by such height)
 | 
			
		||||
            if ($self->config->support_material_contact_distance == 0) {
 | 
			
		||||
                $first_object_layer_height = $distance;
 | 
			
		||||
            } else {
 | 
			
		||||
                $first_object_layer_height = $nozzle_diameter;
 | 
			
		||||
            }
 | 
			
		||||
            $first_object_layer_distance = $distance;
 | 
			
		||||
            $first_object_layer_height = $first_object_layer_distance - $self->config->support_material_contact_distance;
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        # loop until we have at least one layer and the max slice_z reaches the object height
 | 
			
		||||
        my $max_z = unscale($self->size->z);
 | 
			
		||||
        my $slice_z = 0;
 | 
			
		||||
        my $height  = 0;
 | 
			
		||||
        my $max_z   = unscale($self->size->z);
 | 
			
		||||
        while (($slice_z - $height) <= $max_z) {
 | 
			
		||||
            # assign the default height to the layer according to the general settings
 | 
			
		||||
            $height = ($id == 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -439,7 +437,7 @@ sub make_perimeters {
 | 
			
		|||
                    $slice->extra_perimeters($slice->extra_perimeters + 1);
 | 
			
		||||
                }
 | 
			
		||||
                Slic3r::debugf "  adding %d more perimeter(s) at layer %d\n",
 | 
			
		||||
                    $slice->extra_perimeters, $layerm->id
 | 
			
		||||
                    $slice->extra_perimeters, $layerm->layer->id
 | 
			
		||||
                    if $slice->extra_perimeters > 0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -832,17 +830,6 @@ sub clip_fill_surfaces {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sub process_external_surfaces {
 | 
			
		||||
    my ($self) = @_;
 | 
			
		||||
    
 | 
			
		||||
    for my $region_id (0 .. ($self->print->region_count-1)) {
 | 
			
		||||
        $self->get_layer(0)->regions->[$region_id]->process_external_surfaces(undef);
 | 
			
		||||
        for my $i (1 .. ($self->layer_count - 1)) {
 | 
			
		||||
            $self->get_layer($i)->regions->[$region_id]->process_external_surfaces($self->get_layer($i-1));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sub discover_horizontal_shells {
 | 
			
		||||
    my $self = shift;
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			@ -852,8 +839,8 @@ sub discover_horizontal_shells {
 | 
			
		|||
        for (my $i = 0; $i < $self->layer_count; $i++) {
 | 
			
		||||
            my $layerm = $self->get_layer($i)->regions->[$region_id];
 | 
			
		||||
            
 | 
			
		||||
            if ($layerm->config->solid_infill_every_layers && $layerm->config->fill_density > 0
 | 
			
		||||
                && ($i % $layerm->config->solid_infill_every_layers) == 0) {
 | 
			
		||||
            if ($layerm->region->config->solid_infill_every_layers && $layerm->region->config->fill_density > 0
 | 
			
		||||
                && ($i % $layerm->region->config->solid_infill_every_layers) == 0) {
 | 
			
		||||
                $_->surface_type(S_TYPE_INTERNALSOLID) for @{$layerm->fill_surfaces->filter_by_type(S_TYPE_INTERNAL)};
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
| 
						 | 
				
			
			@ -875,8 +862,8 @@ sub discover_horizontal_shells {
 | 
			
		|||
                Slic3r::debugf "Layer %d has %s surfaces\n", $i, ($type == S_TYPE_TOP) ? 'top' : 'bottom';
 | 
			
		||||
                
 | 
			
		||||
                my $solid_layers = ($type == S_TYPE_TOP)
 | 
			
		||||
                    ? $layerm->config->top_solid_layers
 | 
			
		||||
                    : $layerm->config->bottom_solid_layers;
 | 
			
		||||
                    ? $layerm->region->config->top_solid_layers
 | 
			
		||||
                    : $layerm->region->config->bottom_solid_layers;
 | 
			
		||||
                NEIGHBOR: for (my $n = ($type == S_TYPE_TOP) ? $i-1 : $i+1; 
 | 
			
		||||
                        abs($n - $i) <= $solid_layers-1; 
 | 
			
		||||
                        ($type == S_TYPE_TOP) ? $n-- : $n++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -904,7 +891,7 @@ sub discover_horizontal_shells {
 | 
			
		|||
                    );
 | 
			
		||||
                    next EXTERNAL if !@$new_internal_solid;
 | 
			
		||||
                    
 | 
			
		||||
                    if ($layerm->config->fill_density == 0) {
 | 
			
		||||
                    if ($layerm->region->config->fill_density == 0) {
 | 
			
		||||
                        # if we're printing a hollow object we discard any solid shell thinner
 | 
			
		||||
                        # than a perimeter width, since it's probably just crossing a sloping wall
 | 
			
		||||
                        # and it's not wanted in a hollow print even if it would make sense when
 | 
			
		||||
| 
						 | 
				
			
			@ -944,7 +931,12 @@ sub discover_horizontal_shells {
 | 
			
		|||
                            # make sure our grown surfaces don't exceed the fill area
 | 
			
		||||
                            my @grown = @{intersection(
 | 
			
		||||
                                offset($too_narrow, +$margin),
 | 
			
		||||
                                [ map $_->p, @neighbor_fill_surfaces ],
 | 
			
		||||
                                # Discard bridges as they are grown for anchoring and we can't
 | 
			
		||||
                                # remove such anchors. (This may happen when a bridge is being 
 | 
			
		||||
                                # anchored onto a wall where little space remains after the bridge
 | 
			
		||||
                                # is grown, and that little space is an internal solid shell so 
 | 
			
		||||
                                # it triggers this too_narrow logic.)
 | 
			
		||||
                                [ map $_->p, grep { $_->is_internal && !$_->is_bridge } @neighbor_fill_surfaces ],
 | 
			
		||||
                            )};
 | 
			
		||||
                            $new_internal_solid = $solid = [ @grown, @$new_internal_solid ];
 | 
			
		||||
                        }
 | 
			
		||||
| 
						 | 
				
			
			@ -1080,7 +1072,7 @@ sub combine_infill {
 | 
			
		|||
                     + $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)/)
 | 
			
		||||
                     + (($type == S_TYPE_INTERNALSOLID || $region->config->fill_pattern =~ /(rectilinear|grid|line|honeycomb)/)
 | 
			
		||||
                       ? $layerms[-1]->flow(FLOW_ROLE_SOLID_INFILL)->scaled_width
 | 
			
		||||
                       : 0)
 | 
			
		||||
                     )}, @$intersection;
 | 
			
		||||
| 
						 | 
				
			
			@ -1097,12 +1089,12 @@ sub combine_infill {
 | 
			
		|||
                        )};
 | 
			
		||||
                    
 | 
			
		||||
                    # apply surfaces back with adjusted depth to the uppermost layer
 | 
			
		||||
                    if ($layerm->id == $self->get_layer($layer_idx)->id) {
 | 
			
		||||
                    if ($layerm->layer->id == $self->get_layer($layer_idx)->id) {
 | 
			
		||||
                        push @new_this_type,
 | 
			
		||||
                            map Slic3r::Surface->new(
 | 
			
		||||
                                expolygon        => $_,
 | 
			
		||||
                                surface_type     => $type,
 | 
			
		||||
                                thickness        => sum(map $_->height, @layerms),
 | 
			
		||||
                                thickness        => sum(map $_->layer->height, @layerms),
 | 
			
		||||
                                thickness_layers => scalar(@layerms),
 | 
			
		||||
                            ),
 | 
			
		||||
                            @$intersection;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@ use Moo;
 | 
			
		|||
use List::Util qw(sum min max);
 | 
			
		||||
use Slic3r::ExtrusionPath ':roles';
 | 
			
		||||
use Slic3r::Flow ':roles';
 | 
			
		||||
use Slic3r::Geometry qw(scale scaled_epsilon PI rad2deg deg2rad convex_hull);
 | 
			
		||||
use Slic3r::Geometry qw(epsilon scale scaled_epsilon PI rad2deg deg2rad convex_hull);
 | 
			
		||||
use Slic3r::Geometry::Clipper qw(offset diff union union_ex intersection offset_ex offset2
 | 
			
		||||
    intersection_pl offset2_ex diff_pl);
 | 
			
		||||
use Slic3r::Surface ':types';
 | 
			
		||||
| 
						 | 
				
			
			@ -235,7 +235,7 @@ sub contact_area {
 | 
			
		|||
                        # just remove bridged areas
 | 
			
		||||
                        $diff = diff(
 | 
			
		||||
                            $diff,
 | 
			
		||||
                            [ map @$_, @{$layerm->bridged} ],
 | 
			
		||||
                            $layerm->bridged,
 | 
			
		||||
                            1,
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
| 
						 | 
				
			
			@ -267,13 +267,13 @@ sub contact_area {
 | 
			
		|||
            # get the average nozzle diameter used on this layer
 | 
			
		||||
            my @nozzle_diameters = map $self->print_config->get_at('nozzle_diameter', $_),
 | 
			
		||||
                map { $_->config->perimeter_extruder-1, $_->config->infill_extruder-1, $_->config->solid_infill_extruder-1 }
 | 
			
		||||
                @{$layer->regions};
 | 
			
		||||
                map $_->region, @{$layer->regions};
 | 
			
		||||
            my $nozzle_diameter = sum(@nozzle_diameters)/@nozzle_diameters;
 | 
			
		||||
            
 | 
			
		||||
            my $contact_z = $layer->print_z - $self->contact_distance($layer->height, $nozzle_diameter);
 | 
			
		||||
            
 | 
			
		||||
            # ignore this contact area if it's too low
 | 
			
		||||
            next if $contact_z < $self->object_config->get_value('first_layer_height');
 | 
			
		||||
            next if $contact_z < $self->object_config->get_value('first_layer_height') - epsilon;
 | 
			
		||||
            
 | 
			
		||||
            $contact{$contact_z}  = [ @contact ];
 | 
			
		||||
            $overhang{$contact_z} = [ @overhang ];
 | 
			
		||||
| 
						 | 
				
			
			@ -356,13 +356,16 @@ sub support_layers_z {
 | 
			
		|||
    if ($self->object_config->raft_layers > 1 && @z >= 2) {
 | 
			
		||||
        # $z[1] is last raft layer (contact layer for the first layer object)
 | 
			
		||||
        my $height = ($z[1] - $z[0]) / ($self->object_config->raft_layers - 1);
 | 
			
		||||
        # since we already have two raft layers ($z[0] and $z[1]) we need to insert
 | 
			
		||||
        # raft_layers-2 more
 | 
			
		||||
        splice @z, 1, 0,
 | 
			
		||||
            map { sprintf "%.2f", $_ }
 | 
			
		||||
            map { $z[0] + $height * $_ }
 | 
			
		||||
            0..($self->object_config->raft_layers - 1);
 | 
			
		||||
            1..($self->object_config->raft_layers - 2);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    for (my $i = $#z; $i >= 0; $i--) {
 | 
			
		||||
    # create other layers (skip raft layers as they're already done and use thicker layers)
 | 
			
		||||
    for (my $i = $#z; $i >= $self->object_config->raft_layers; $i--) {
 | 
			
		||||
        my $target_height = $support_material_height;
 | 
			
		||||
        if ($i > 0 && $top{ $z[$i-1] }) {
 | 
			
		||||
            $target_height = $nozzle_diameter;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue