Merge branch 'grow-narrow' of github.com:alexrj/Slic3r into grow-narrow

This commit is contained in:
Alessandro Ranellucci 2013-03-17 14:05:23 +01:00
commit 8117bc88a0
17 changed files with 148 additions and 97 deletions

View File

@ -300,6 +300,8 @@ The author of the Silk icon set is Mark James.
Set a different extrusion width for perimeters
--infill-extrusion-width
Set a different extrusion width for infill
--solid-infill-extrusion-width
Set a different extrusion width for solid infill
--top-infill-extrusion-width
Set a different extrusion width for top infill
--support-material-extrusion-width

View File

@ -67,7 +67,7 @@ use constant SCALED_RESOLUTION => RESOLUTION / SCALING_FACTOR;
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 PERIMETER_INFILL_OVERLAP_OVER_SPACING => 0.45;
use constant INFILL_OVERLAP_OVER_SPACING => 0.45;
our $Config;

View File

@ -377,7 +377,7 @@ our $Options = {
cli => 'first-layer-height=s',
type => 'f',
ratio_over => 'layer_height',
default => '100%',
default => 0.35,
},
'infill_every_layers' => {
label => 'Infill every',
@ -446,8 +446,16 @@ our $Options = {
type => 'f',
default => 0,
},
'solid_infill_extrusion_width' => {
label => 'Solid infill',
tooltip => 'Set this to a non-zero value to set a manual extrusion width for infill for solid surfaces. If expressed as percentage (for example 90%) if will be computed over layer height.',
sidetext => 'mm or % (leave 0 for default)',
cli => 'solid-infill-extrusion-width=s',
type => 'f',
default => 0,
},
'top_infill_extrusion_width' => {
label => 'Top infill',
label => 'Top solid infill',
tooltip => 'Set this to a non-zero value to set a manual extrusion width for infill for top surfaces. You may want to use thinner extrudates to fill all narrow regions and get a smoother finish. If expressed as percentage (for example 90%) if will be computed over layer height.',
sidetext => 'mm or % (leave 0 for default)',
cli => 'top-infill-extrusion-width=s',
@ -515,7 +523,7 @@ our $Options = {
type => 'select',
values => [qw(rectilinear line concentric honeycomb hilbertcurve archimedeanchords octagramspiral)],
labels => [qw(rectilinear line concentric honeycomb), 'hilbertcurve (slow)', 'archimedeanchords (slow)', 'octagramspiral (slow)'],
default => 'rectilinear',
default => 'honeycomb',
},
'solid_fill_pattern' => {
label => 'Top/bottom fill pattern',

View File

@ -5,8 +5,8 @@ require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(EXTR_ROLE_PERIMETER EXTR_ROLE_EXTERNAL_PERIMETER
EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER
EXTR_ROLE_FILL EXTR_ROLE_SOLIDFILL EXTR_ROLE_TOPSOLIDFILL EXTR_ROLE_BRIDGE EXTR_ROLE_SKIRT
EXTR_ROLE_SUPPORTMATERIAL EXTR_ROLE_GAPFILL);
EXTR_ROLE_FILL EXTR_ROLE_SOLIDFILL EXTR_ROLE_TOPSOLIDFILL EXTR_ROLE_BRIDGE
EXTR_ROLE_INTERNALBRIDGE EXTR_ROLE_SKIRT EXTR_ROLE_SUPPORTMATERIAL EXTR_ROLE_GAPFILL);
our %EXPORT_TAGS = (roles => \@EXPORT_OK);
use Slic3r::Geometry qw(PI X Y epsilon deg2rad rotate_points);
@ -30,9 +30,10 @@ use constant EXTR_ROLE_FILL => 4;
use constant EXTR_ROLE_SOLIDFILL => 5;
use constant EXTR_ROLE_TOPSOLIDFILL => 6;
use constant EXTR_ROLE_BRIDGE => 7;
use constant EXTR_ROLE_SKIRT => 8;
use constant EXTR_ROLE_SUPPORTMATERIAL => 9;
use constant EXTR_ROLE_GAPFILL => 10;
use constant EXTR_ROLE_INTERNALBRIDGE => 8;
use constant EXTR_ROLE_SKIRT => 9;
use constant EXTR_ROLE_SUPPORTMATERIAL => 10;
use constant EXTR_ROLE_GAPFILL => 11;
use constant PACK_FMT => 'ffca*';

View File

@ -90,10 +90,11 @@ sub make_fill {
);
push @surfaces, map Slic3r::Surface->new(
expolygon => $_,
surface_type => $group->[0]->surface_type,
bridge_angle => $group->[0]->bridge_angle,
depth_layers => $group->[0]->depth_layers,
expolygon => $_,
surface_type => $group->[0]->surface_type,
bridge_angle => $group->[0]->bridge_angle,
thickness => $group->[0]->thickness,
thickness_layers => $group->[0]->thickness_layers,
), @$union;
}
}
@ -107,7 +108,7 @@ sub make_fill {
# we are going to grow such regions by overlapping them with the void (if any)
# TODO: detect and investigate whether there could be narrow regions without
# any void neighbors
my $distance_between_surfaces = $layerm->infill_flow->scaled_spacing;
my $distance_between_surfaces = $layerm->solid_infill_flow->scaled_spacing;
{
my $collapsed = diff(
[ map @{$_->expolygon}, @surfaces ],
@ -132,7 +133,7 @@ sub make_fill {
}
# add spacing between surfaces
@surfaces = map $_->offset(-$distance_between_surfaces/2), @surfaces;
@surfaces = map $_->offset(-$distance_between_surfaces / 2 * &Slic3r::INFILL_OVERLAP_OVER_SPACING), @surfaces;
my @fills = ();
my @fills_ordering_points = ();
@ -140,9 +141,12 @@ sub make_fill {
next if $surface->surface_type == S_TYPE_INTERNALVOID;
my $filler = $Slic3r::Config->fill_pattern;
my $density = $Slic3r::Config->fill_density;
my $flow_spacing = ($surface->surface_type == S_TYPE_TOP)
? $layerm->top_infill_flow->spacing
: $layerm->infill_flow->spacing;
my $flow = ($surface->surface_type == S_TYPE_TOP)
? $layerm->top_infill_flow
: $surface->is_solid
? $layerm->solid_infill_flow
: $layerm->infill_flow;
my $flow_spacing = $flow->spacing;
my $is_bridge = $layerm->id > 0 && $surface->is_bridge;
my $is_solid = $surface->is_solid;
@ -184,12 +188,14 @@ sub make_fill {
paths => [
map Slic3r::ExtrusionPath->pack(
polyline => Slic3r::Polyline->new(@$_),
role => ($is_bridge
? EXTR_ROLE_BRIDGE
: $is_solid
? ($surface->surface_type == S_TYPE_TOP ? EXTR_ROLE_TOPSOLIDFILL : EXTR_ROLE_SOLIDFILL)
: EXTR_ROLE_FILL),
height => $surface->depth_layers * $layerm->height,
role => ($surface->surface_type == S_TYPE_INTERNALBRIDGE
? EXTR_ROLE_INTERNALBRIDGE
: $is_bridge
? EXTR_ROLE_BRIDGE
: $is_solid
? ($surface->surface_type == S_TYPE_TOP ? EXTR_ROLE_TOPSOLIDFILL : EXTR_ROLE_SOLIDFILL)
: EXTR_ROLE_FILL),
height => $surface->thickness,
flow_spacing => $params->{flow_spacing} || (warn "Warning: no flow_spacing was returned by the infill engine, please report this to the developer\n"),
), @paths,
],

View File

@ -20,7 +20,7 @@ sub infill_direction {
if (defined $self->layer_id) {
# alternate fill direction
my $layer_num = $self->layer_id / $surface->depth_layers;
my $layer_num = $self->layer_id / $surface->thickness_layers;
my $angle = $self->angles->[$layer_num % @{$self->angles}];
$rotate[0] = Slic3r::Geometry::deg2rad($self->angle) + $angle if $angle;
}

View File

@ -22,11 +22,10 @@ sub fill_surface {
# infill math
my $min_spacing = scale $params{flow_spacing};
my $distance = $min_spacing / $params{density};
my $overlap_distance = scale $params{flow_spacing} * &Slic3r::PERIMETER_INFILL_OVERLAP_OVER_SPACING;
my $cache_id = sprintf "d%s_s%s_a%s",
$params{density}, $params{flow_spacing}, $rotate_vector->[0][0];
if (!$self->cache->{$cache_id}) {
if (!$self->cache->{$cache_id} || !defined $self->bounding_box) {
# hexagons math
my $hex_side = $distance / (sqrt(3)/2);
@ -40,15 +39,10 @@ sub fill_surface {
# adjust actual bounding box to the nearest multiple of our hex pattern
# and align it so that it matches across layers
$self->bounding_box([ $expolygon->bounding_box ]) if !defined $self->bounding_box;
my $bounding_box = [ 0, 0, $self->bounding_box->[X2], $self->bounding_box->[Y2] ];
my $bounding_box = [ $self->bounding_box ? @{$self->bounding_box} : $expolygon->bounding_box ];
$bounding_box->[$_] = 0 for X1, Y1;
{
my $bb_polygon = Slic3r::Polygon->new([
[ $bounding_box->[X1], $bounding_box->[Y1] ],
[ $bounding_box->[X2], $bounding_box->[Y1] ],
[ $bounding_box->[X2], $bounding_box->[Y2] ],
[ $bounding_box->[X1], $bounding_box->[Y2] ],
]);
my $bb_polygon = Slic3r::Polygon->new_from_bounding_box($bounding_box);
$bb_polygon->rotate($rotate_vector->[0][0], $hex_center);
$bounding_box = [ Slic3r::Geometry::bounding_box($bb_polygon) ];
# $bounding_box->[X1] and [Y1] represent the displacement between new bounding box offset and old one
@ -89,7 +83,7 @@ sub fill_surface {
# path is more straight
my @paths = map Slic3r::Polyline->new(@$_), map @$_, @{intersection_ex(
$self->cache->{$cache_id},
[ map @$_, $expolygon->offset_ex($overlap_distance) ],
$expolygon,
)};
return { flow_spacing => $params{flow_spacing} },

View File

@ -31,8 +31,6 @@ sub fill_surface {
$flow_spacing = unscale $distance_between_lines;
}
my $overlap_distance = scale $params{flow_spacing} * &Slic3r::PERIMETER_INFILL_OVERLAP_OVER_SPACING;
my $x = $bounding_box->[X1];
my $is_line_pattern = $self->isa('Slic3r::Fill::Line');
my @vertical_lines = ();
@ -52,10 +50,6 @@ sub fill_surface {
+($expolygon->offset_ex(scaled_epsilon))[0], # TODO: we should use all the resulting expolygons and clip the linestrings to a multipolygon object
[ @vertical_lines ],
) };
for (@paths) {
$_->[0][Y] += $overlap_distance;
$_->[-1][Y] -= $overlap_distance;
}
# connect lines
unless ($params{dont_connect}) {

View File

@ -1,11 +1,11 @@
package Slic3r::Flow;
use Moo;
use List::Util qw(max);
use Slic3r::Geometry qw(PI scale);
has 'nozzle_diameter' => (is => 'ro', required => 1);
has 'layer_height' => (is => 'ro', default => sub { $Slic3r::Config->layer_height });
has 'role' => (is => 'ro', default => sub { '' });
has 'width' => (is => 'rwp', builder => 1);
has 'spacing' => (is => 'lazy');
@ -36,12 +36,13 @@ sub _build_width {
$width = $self->nozzle_diameter * ($self->nozzle_diameter/$self->layer_height - 4/PI + 1);
}
my $min = max(
($volume / $self->layer_height),
($self->nozzle_diameter * 1.05),
);
my $max = $self->nozzle_diameter * 2;
$width = $max if $width > $max;
my $min = $self->nozzle_diameter * 1.05;
my $max;
if ($self->role ne 'infill') {
# do not limit width for sparse infill so that we use full native flow for it
$max = $self->nozzle_diameter * 1.7;
}
$width = $max if defined($max) && $width > $max;
$width = $min if $width < $min;
return $width;

View File

@ -53,6 +53,7 @@ my %role_speeds = (
&EXTR_ROLE_SOLIDFILL => 'solid_infill',
&EXTR_ROLE_TOPSOLIDFILL => 'top_solid_infill',
&EXTR_ROLE_BRIDGE => 'bridge',
&EXTR_ROLE_INTERNALBRIDGE => 'solid_infill',
&EXTR_ROLE_SKIRT => 'perimeter',
&EXTR_ROLE_SUPPORTMATERIAL => 'support_material',
&EXTR_ROLE_GAPFILL => 'gap_fill',
@ -203,13 +204,13 @@ sub extrude_path {
$acceleration = $Slic3r::Config->perimeter_acceleration;
} elsif ($Slic3r::Config->infill_acceleration && $path->is_fill) {
$acceleration = $Slic3r::Config->infill_acceleration;
} elsif ($Slic3r::Config->infill_acceleration && $path->role == EXTR_ROLE_BRIDGE) {
} elsif ($Slic3r::Config->infill_acceleration && ($path->role == EXTR_ROLE_BRIDGE || $path->role == EXTR_ROLE_INTERNALBRIDGE)) {
$acceleration = $Slic3r::Config->bridge_acceleration;
}
$gcode .= $self->set_acceleration($acceleration) if $acceleration;
my $area; # mm^3 of extrudate per mm of tool movement
if ($path->role == EXTR_ROLE_BRIDGE) {
if ($path->role == EXTR_ROLE_BRIDGE || $path->role == EXTR_ROLE_INTERNALBRIDGE) {
my $s = $path->flow_spacing;
$area = ($s**2) * PI/4;
} else {

View File

@ -511,7 +511,7 @@ sub build {
{
title => 'Extrusion width',
label_width => 180,
options => [qw(extrusion_width first_layer_extrusion_width perimeter_extrusion_width infill_extrusion_width top_infill_extrusion_width support_material_extrusion_width)],
options => [qw(extrusion_width first_layer_extrusion_width perimeter_extrusion_width infill_extrusion_width solid_infill_extrusion_width top_infill_extrusion_width support_material_extrusion_width)],
},
{
title => 'Flow',

View File

@ -16,6 +16,7 @@ has 'layer' => (
has 'region' => (is => 'ro', required => 1, handles => [qw(extruders)]);
has 'perimeter_flow' => (is => 'rw');
has 'infill_flow' => (is => 'rw');
has 'solid_infill_flow' => (is => 'rw');
has 'top_infill_flow' => (is => 'rw');
has 'infill_area_threshold' => (is => 'lazy');
has 'overhang_width' => (is => 'lazy');
@ -59,15 +60,15 @@ sub _update_flows {
return if !$self->region;
if ($self->id == 0) {
$self->perimeter_flow
($self->region->first_layer_flows->{perimeter} || $self->region->flows->{perimeter});
$self->infill_flow
($self->region->first_layer_flows->{infill} || $self->region->flows->{infill});
$self->top_infill_flow
($self->region->first_layer_flows->{top_infill} || $self->region->flows->{top_infill});
for (qw(perimeter infill solid_infill top_infill)) {
my $method = "${_}_flow";
$self->$method
($self->region->first_layer_flows->{$_} || $self->region->flows->{$_});
}
} else {
$self->perimeter_flow($self->region->flows->{perimeter});
$self->infill_flow($self->region->flows->{infill});
$self->solid_infill_flow($self->region->flows->{solid_infill});
$self->top_infill_flow($self->region->flows->{top_infill});
}
}
@ -80,7 +81,7 @@ sub _build_overhang_width {
sub _build_infill_area_threshold {
my $self = shift;
return $self->infill_flow->scaled_spacing ** 2;
return $self->solid_infill_flow->scaled_spacing ** 2;
}
# build polylines from lines
@ -160,7 +161,7 @@ sub make_perimeters {
my $self = shift;
my $perimeter_spacing = $self->perimeter_flow->scaled_spacing;
my $infill_spacing = $self->infill_flow->scaled_spacing;
my $infill_spacing = $self->solid_infill_flow->scaled_spacing;
my $gap_area_threshold = $self->perimeter_flow->scaled_width ** 2;
# this array will hold one arrayref per original surface (island);

View File

@ -6,9 +6,22 @@ use warnings;
use parent 'Slic3r::Polyline';
use Slic3r::Geometry qw(polygon_lines polygon_remove_parallel_continuous_edges
polygon_remove_acute_vertices polygon_segment_having_point point_in_polygon);
polygon_remove_acute_vertices polygon_segment_having_point point_in_polygon
X1 X2 Y1 Y2);
use Slic3r::Geometry::Clipper qw(JT_MITER);
sub new_from_bounding_box {
my $class = shift;
my ($bounding_box) = @_;
return $class->new([
[ $bounding_box->[X1], $bounding_box->[Y1] ],
[ $bounding_box->[X2], $bounding_box->[Y1] ],
[ $bounding_box->[X2], $bounding_box->[Y2] ],
[ $bounding_box->[X1], $bounding_box->[Y2] ],
]);
}
sub lines {
my $self = shift;
return polygon_lines($self);

View File

@ -134,7 +134,7 @@ sub add_model {
if ($object->instances) {
# replace the default [0,0] instance with the custom ones
@{$print_object->copies} = map [ scale $_->offset->[X], scale $_->offset->[Y] ], @{$object->instances};
$print_object->copies([ map [ scale $_->offset->[X], scale $_->offset->[Y] ], @{$object->instances} ]);
}
}
}
@ -201,17 +201,20 @@ sub init_extruders {
my $region = $self->regions->[$region_id];
# per-role extruders and flows
for (qw(perimeter infill top_infill)) {
my $extruder_name = $_ eq 'top_infill' ? 'infill' : $_;
for (qw(perimeter infill solid_infill top_infill)) {
my $extruder_name = $_;
$extruder_name =~ s/^(?:solid|top)_//;
$region->extruders->{$_} = ($self->regions_count > 1)
? $self->extruders->[$extruder_mapping{$region_id}]
: $self->extruders->[$self->config->get("${extruder_name}_extruder")-1];
$region->flows->{$_} = $region->extruders->{$_}->make_flow(
width => $self->config->get("${_}_extrusion_width") || $self->config->extrusion_width,
role => $_,
);
$region->first_layer_flows->{$_} = $region->extruders->{$_}->make_flow(
layer_height => $self->config->get_value('first_layer_height'),
width => $self->config->first_layer_extrusion_width,
role => $_,
) if $self->config->first_layer_extrusion_width;
}
}
@ -221,10 +224,12 @@ sub init_extruders {
my $extruder = $self->extruders->[$self->config->support_material_extruder-1];
$self->support_material_flow($extruder->make_flow(
width => $self->config->support_material_extrusion_width || $self->config->extrusion_width,
role => 'support_material',
));
$self->first_layer_support_material_flow($extruder->make_flow(
layer_height => $self->config->get_value('first_layer_height'),
width => $self->config->first_layer_extrusion_width,
role => 'support_material',
));
}
}
@ -696,6 +701,8 @@ sub write_gcode {
}
printf $fh "; perimeters extrusion width = %.2fmm\n", $self->regions->[0]->flows->{perimeter}->width;
printf $fh "; infill extrusion width = %.2fmm\n", $self->regions->[0]->flows->{infill}->width;
printf $fh "; solid infill extrusion width = %.2fmm\n", $self->regions->[0]->flows->{solid_infill}->width;
printf $fh "; top infill extrusion width = %.2fmm\n", $self->regions->[0]->flows->{top_infill}->width;
printf $fh "; support material extrusion width = %.2fmm\n", $self->support_material_flow->width
if $self->support_material_flow;
printf $fh "; first layer extrusion width = %.2fmm\n", $self->regions->[0]->first_layer_flows->{perimeter}->width

View File

@ -3,7 +3,7 @@ use Moo;
use List::Util qw(min sum first);
use Slic3r::ExtrusionPath ':roles';
use Slic3r::Geometry qw(Z PI scale unscale deg2rad rad2deg scaled_epsilon);
use Slic3r::Geometry qw(Z PI scale unscale deg2rad rad2deg scaled_epsilon chained_path_points);
use Slic3r::Geometry::Clipper qw(diff_ex intersection_ex union_ex offset collapse_ex);
use Slic3r::Surface ':types';
@ -11,7 +11,7 @@ has 'print' => (is => 'ro', weak_ref => 1, required => 1);
has 'input_file' => (is => 'rw', required => 0);
has 'meshes' => (is => 'rw', default => sub { [] }); # by region_id
has 'size' => (is => 'rw', required => 1);
has 'copies' => (is => 'rw', default => sub {[ [0,0] ]});
has 'copies' => (is => 'rw', default => sub {[ [0,0] ]}, trigger => 1);
has 'layers' => (is => 'rw', default => sub { [] });
has 'layer_height_ranges' => (is => 'rw', default => sub { [] }); # [ z_min, z_max, layer_height ]
@ -50,6 +50,14 @@ sub BUILD {
}
}
sub _trigger_copies {
my $self = shift;
return unless @{$self->copies} > 1;
# order copies with a nearest neighbor search
@{$self->copies} = @{chained_path_points($self->copies)}
}
sub layer_count {
my $self = shift;
return scalar @{ $self->layers };
@ -580,7 +588,7 @@ sub discover_horizontal_shells {
# make sure the new internal solid is wide enough, as it might get collapsed when
# spacing is added in Fill.pm
{
my $margin = 3 * $layerm->infill_flow->scaled_width; # require at least this size
my $margin = 3 * $layerm->solid_infill_flow->scaled_width; # require at least this size
my $too_narrow = diff_ex(
[ map @$_, @$new_internal_solid ],
[ offset([ offset([ map @$_, @$new_internal_solid ], -$margin) ], +$margin) ],
@ -658,7 +666,7 @@ sub combine_infill {
my $nozzle_diameter = $self->print->regions->[$region_id]->extruders->{infill}->nozzle_diameter;
# define the combinations
my @combine = (); # layer_id => depth
my @combine = (); # layer_id => thickness in layers
{
my $current_height = my $layers = 0;
for my $layer_id (1 .. $#layer_heights) {
@ -706,15 +714,16 @@ sub combine_infill {
# $intersection now contains the regions that can be combined across the full amount of layers
# so let's remove those areas from all layers
my @intersection_with_clearance = map $_->offset(
$layerms[-1]->infill_flow->scaled_width / 2
+ $layerms[-1]->perimeter_flow->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 || $Slic3r::Config->fill_pattern =~ /(rectilinear|honeycomb)/)
? $layerms[-1]->infill_flow->scaled_width * &Slic3r::PERIMETER_INFILL_OVERLAP_OVER_SPACING
: 0)
), @$intersection;
my @intersection_with_clearance = map $_->offset(
$layerms[-1]->solid_infill_flow->scaled_width / 2
+ $layerms[-1]->perimeter_flow->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 || $Slic3r::Config->fill_pattern =~ /(rectilinear|honeycomb)/)
? $layerms[-1]->solid_infill_flow->scaled_width * &Slic3r::INFILL_OVERLAP_OVER_SPACING
: 0)
), @$intersection;
foreach my $layerm (@layerms) {
my @this_type = grep $_->surface_type == $type, @{$layerm->fill_surfaces};
@ -729,7 +738,12 @@ sub combine_infill {
# apply surfaces back with adjusted depth to the uppermost layer
if ($layerm->id == $layer_id) {
push @new_this_type,
map Slic3r::Surface->new(expolygon => $_, surface_type => $type, depth_layers => $every),
map Slic3r::Surface->new(
expolygon => $_,
surface_type => $type,
thickness => sum(map $_->height, @layerms),
thickness_layers => scalar(@layerms),
),
@$intersection;
} else {
# save void surfaces
@ -841,8 +855,8 @@ sub generate_support_material {
? scale $lower_layer->height * ((cos $threshold_rad) / (sin $threshold_rad))
: $self->layers->[1]->regions->[0]->overhang_width;
@overhangs = map $_->offset_ex(2 * $distance), @{diff_ex(
[ map @$_, map $_->offset_ex(-$distance), @{$layer->slices} ],
@overhangs = map $_->offset_ex(+$distance), @{diff_ex(
[ map @$_, @{$layer->slices} ],
[ map @$_, @{$lower_layer->slices} ],
1,
)};
@ -864,7 +878,7 @@ sub generate_support_material {
{
# 0.5 ensures the paths don't get clipped externally when applying them to layers
my @areas = map $_->offset_ex(- 0.5 * $flow->scaled_width),
@{union_ex([ map $_->contour, map @$_, values %layers ])};
@{union_ex([ map $_->contour, map @$_, values %layers, values %layers_interfaces, values %layers_contact_areas ])};
my $pattern = $Slic3r::Config->support_material_pattern;
my @angles = ($Slic3r::Config->support_material_angle);
@ -872,7 +886,11 @@ sub generate_support_material {
$pattern = 'rectilinear';
push @angles, $angles[0] + 90;
}
my $filler = Slic3r::Fill->filler($pattern);
$filler->bounding_box([ Slic3r::Geometry::bounding_box([ map @$_, map @$_, @areas ]) ])
if $filler->can('bounding_box');
my $make_pattern = sub {
my ($expolygon, $density) = @_;

View File

@ -7,11 +7,12 @@ our @ISA = qw(Exporter);
our @EXPORT_OK = qw(S_TYPE_TOP S_TYPE_BOTTOM S_TYPE_INTERNAL S_TYPE_INTERNALSOLID S_TYPE_INTERNALBRIDGE S_TYPE_INTERNALVOID);
our %EXPORT_TAGS = (types => \@EXPORT_OK);
use constant S_EXPOLYGON => 0;
use constant S_SURFACE_TYPE => 1;
use constant S_DEPTH_LAYERS => 2;
use constant S_BRIDGE_ANGLE => 3;
use constant S_EXTRA_PERIMETERS => 4;
use constant S_EXPOLYGON => 0;
use constant S_SURFACE_TYPE => 1;
use constant S_THICKNESS => 2; # in mm
use constant S_THICKNESS_LAYERS => 3; # in layers
use constant S_BRIDGE_ANGLE => 4;
use constant S_EXTRA_PERIMETERS => 5;
use constant S_TYPE_TOP => 0;
use constant S_TYPE_BOTTOM => 1;
@ -25,9 +26,9 @@ sub new {
my %args = @_;
my $self = [
map delete $args{$_}, qw(expolygon surface_type depth_layers bridge_angle extra_perimeters),
map delete $args{$_}, qw(expolygon surface_type thickness thickness_layers bridge_angle extra_perimeters),
];
$self->[S_DEPTH_LAYERS] //= 1; #/
$self->[$_] //= 1 for S_THICKNESS, S_THICKNESS_LAYERS;
bless $self, $class;
$self;
@ -35,7 +36,8 @@ sub new {
sub expolygon { $_[0][S_EXPOLYGON] }
sub surface_type { $_[0][S_SURFACE_TYPE] = $_[1] if defined $_[1]; $_[0][S_SURFACE_TYPE] }
sub depth_layers { $_[0][S_DEPTH_LAYERS] } # this integer represents the thickness of the surface expressed in layers
sub thickness { $_[0][S_THICKNESS] }
sub thickness_layers { $_[0][S_THICKNESS_LAYERS] }
sub bridge_angle { $_[0][S_BRIDGE_ANGLE] = $_[1] if defined $_[1]; $_[0][S_BRIDGE_ANGLE] }
sub extra_perimeters { $_[0][S_EXTRA_PERIMETERS] = $_[1] if defined $_[1]; $_[0][S_EXTRA_PERIMETERS] }
@ -46,7 +48,8 @@ if (eval "use Class::XSAccessor::Array; 1") {
},
accessors => {
surface_type => S_SURFACE_TYPE,
depth_layers => S_DEPTH_LAYERS,
thickness => S_THICKNESS,
thickness_layers => S_THICKNESS_LAYERS,
bridge_angle => S_BRIDGE_ANGLE,
extra_perimeters => S_EXTRA_PERIMETERS,
},
@ -60,7 +63,7 @@ sub lines { $_[0]->expolygon->lines }
sub contour { $_[0]->expolygon->contour }
sub holes { $_[0]->expolygon->holes }
# static method to group surfaces having same surface_type, bridge_angle and depth_layers
# static method to group surfaces having same surface_type, bridge_angle and thickness*
sub group {
my $class = shift;
my $params = ref $_[0] eq 'HASH' ? shift(@_) : {};
@ -68,11 +71,11 @@ sub group {
my %unique_types = ();
foreach my $surface (@surfaces) {
my $type = ($params->{merge_solid} && $surface->is_solid)
? 'solid'
: $surface->surface_type;
$type .= "_" . ($surface->bridge_angle // ''); #/
$type .= "_" . $surface->depth_layers;
my $type = join '_',
($params->{merge_solid} && $surface->is_solid) ? 'solid' : $surface->surface_type,
($surface->bridge_angle // ''),
$surface->thickness,
$surface->thickness_layers;
$unique_types{$type} ||= [];
push @{ $unique_types{$type} }, $surface;
}
@ -96,7 +99,7 @@ sub _inflate_expolygon {
return (ref $self)->new(
expolygon => $expolygon,
map { $_ => $self->$_ } qw(surface_type depth_layers bridge_angle),
map { $_ => $self->$_ } qw(surface_type thickness thickness_layers bridge_angle),
);
}

View File

@ -353,6 +353,8 @@ $j
Set a different extrusion width for perimeters
--infill-extrusion-width
Set a different extrusion width for infill
--solid-infill-extrusion-width
Set a different extrusion width for solid infill
--top-infill-extrusion-width
Set a different extrusion width for top infill
--support-material-extrusion-width