More incomplete work
This commit is contained in:
parent
beb1baa096
commit
83326845dd
@ -14,8 +14,7 @@ has 'layer' => (
|
||||
is => 'ro',
|
||||
weak_ref => 1,
|
||||
required => 1,
|
||||
trigger => 1,
|
||||
handles => [qw(id slice_z print_z height flow config)],
|
||||
handles => [qw(id slice_z print_z height config)],
|
||||
);
|
||||
has 'region' => (is => 'ro', required => 1, handles => [qw(extruders)]);
|
||||
has 'infill_area_threshold' => (is => 'lazy');
|
||||
|
@ -5,6 +5,7 @@ use File::Basename qw(basename fileparse);
|
||||
use File::Spec;
|
||||
use List::Util qw(min max first);
|
||||
use Slic3r::ExtrusionPath ':roles';
|
||||
use Slic3r::Flow ':roles';
|
||||
use Slic3r::Geometry qw(X Y Z X1 Y1 X2 Y2 MIN MAX PI scale unscale move_points chained_path
|
||||
convex_hull);
|
||||
use Slic3r::Geometry::Clipper qw(diff_ex union_ex union_pt intersection_ex intersection offset
|
||||
@ -96,6 +97,7 @@ sub add_model_object {
|
||||
my $config = $object->model->materials->{ $volume->material_id }->config;
|
||||
} else {
|
||||
$config = Slic3r::Config->new;
|
||||
$config->set('extruder', 0);
|
||||
}
|
||||
|
||||
# find an existing print region with the same config
|
||||
@ -110,7 +112,10 @@ sub add_model_object {
|
||||
|
||||
# if no region exists with the same config, create a new one
|
||||
if (!defined $region_id) {
|
||||
push @{$self->regions}, Slic3r::Print::Region->new(config => $config->clone);
|
||||
push @{$self->regions}, Slic3r::Print::Region->new(
|
||||
print => $self,
|
||||
config => $config->clone,
|
||||
);
|
||||
$region_id = $#{$self->regions};
|
||||
}
|
||||
|
||||
@ -233,15 +238,19 @@ sub validate {
|
||||
sub init_extruders {
|
||||
my $self = shift;
|
||||
|
||||
# map regions to extruders (ghetto mapping for now)
|
||||
my %extruder_mapping = map { $_ => $_ } 0..$#{$self->regions};
|
||||
|
||||
# initialize all extruder(s) we need
|
||||
my @used_extruders = (
|
||||
0,
|
||||
(map $self->config->get("${_}_extruder")-1, qw(perimeter infill support_material support_material_interface)),
|
||||
(values %extruder_mapping),
|
||||
);
|
||||
my @used_extruders = ();
|
||||
foreach my $region (@{$self->regions}) {
|
||||
push @used_extruders,
|
||||
map $region->config->get("${_}_extruder")-1,
|
||||
qw(perimeter infill);
|
||||
}
|
||||
foreach my $object (@{$self->objects}) {
|
||||
push @used_extruders,
|
||||
map $object->config->get("${_}_extruder")-1,
|
||||
qw(support_material support_material_interface);
|
||||
}
|
||||
|
||||
for my $extruder_id (keys %{{ map {$_ => 1} @used_extruders }}) {
|
||||
$self->extruders->[$extruder_id] = Slic3r::Extruder->new(
|
||||
config => $self->config,
|
||||
@ -251,51 +260,8 @@ sub init_extruders {
|
||||
);
|
||||
}
|
||||
|
||||
# calculate regions' flows
|
||||
for my $region_id (0 .. $#{$self->regions}) {
|
||||
my $region = $self->regions->[$region_id];
|
||||
|
||||
# per-role extruders and flows
|
||||
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(
|
||||
layer_height => $self->config->layer_height,
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
# calculate support material flow
|
||||
# Note: we should calculate a different flow for support material interface
|
||||
# TODO: support material layers have their own variable layer heights, so we
|
||||
# probably need a DynamicFlow object that calculates flow on the fly
|
||||
# (or the Flow object must support a mutable layer_height)
|
||||
if ($self->has_support_material) {
|
||||
my $extruder = $self->extruders->[$self->config->support_material_extruder-1];
|
||||
$self->support_material_flow($extruder->make_flow(
|
||||
layer_height => $self->config->layer_height, # WRONG!
|
||||
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',
|
||||
));
|
||||
}
|
||||
|
||||
# enforce tall skirt if using ooze_prevention
|
||||
# NOTE: this is not idempotent (i.e. switching ooze_prevention off will not revert skirt settings)
|
||||
# FIXME: this is not idempotent (i.e. switching ooze_prevention off will not revert skirt settings)
|
||||
if ($self->config->ooze_prevention && @{$self->extruders} > 1) {
|
||||
$self->config->set('skirt_height', -1);
|
||||
$self->config->set('skirts', 1) if $self->config->skirts == 0;
|
||||
@ -636,8 +602,17 @@ sub make_skirt {
|
||||
|
||||
my @extruded_length = (); # for each extruder
|
||||
|
||||
# skirt may be printed on several layers, having distinct layer heights,
|
||||
# but loops must be aligned so can't vary width/spacing
|
||||
# TODO: use each extruder's own flow
|
||||
my $spacing = $self->flow(FLOW_ROLE_SUPPORT_MATERIAL)->spacing;
|
||||
my $flow = Slic3r::Flow->new(
|
||||
width => ($self->config->first_layer_extrusion_width || $self->config->perimeter_extrusion_width),
|
||||
role => FLOW_ROLE_PERIMETER,
|
||||
nozzle_diameter => $self->config->nozzle_diameter->[0],
|
||||
layer_height => $self->config->get_abs_value('first_layer_height'),
|
||||
bridge_flow_ratio => 0,
|
||||
);
|
||||
my $spacing = $flow->spacing;
|
||||
|
||||
my $first_layer_height = $self->config->get_value('first_layer_height');
|
||||
my @extruders_e_per_mm = ();
|
||||
@ -678,7 +653,14 @@ sub make_brim {
|
||||
|
||||
$self->brim->clear; # method must be idempotent
|
||||
|
||||
my $flow = $self->flow(FLOW_ROLE_SUPPORT_MATERIAL);
|
||||
# brim is only printed on first layer and uses support material extruder
|
||||
my $flow = Slic3r::Flow->new(
|
||||
width => ($self->config->first_layer_extrusion_width || $self->config->perimeter_extrusion_width),
|
||||
role => FLOW_ROLE_PERIMETER,
|
||||
nozzle_diameter => $self->config->nozzle_diameter->[ $self->config->support_material_extruder-1 ],
|
||||
layer_height => $self->config->get_abs_value('first_layer_height'),
|
||||
bridge_flow_ratio => 0,
|
||||
);
|
||||
|
||||
my $grow_distance = $flow->scaled_width / 2;
|
||||
my @islands = (); # array of polygons
|
||||
@ -763,11 +745,11 @@ sub write_gcode {
|
||||
printf $fh "; top infill extrusion width = %.2fmm\n",
|
||||
$self->regions->[$region_id]->flow(FLOW_ROLE_TOP_SOLID_INFILL)->width;
|
||||
printf $fh "; support material extrusion width = %.2fmm\n",
|
||||
$self->flow(FLOW_ROLE_SUPPORT_MATERIAL)->width
|
||||
if $self->support_material_flow;
|
||||
$self->objects->[0]->support_material_flow->width
|
||||
if $self->has_support_material;
|
||||
printf $fh "; first layer extrusion width = %.2fmm\n",
|
||||
$self->flow(FLOW_ROLE_SUPPORT_MATERIAL, 0, 1)->width
|
||||
if $self->regions->[0]->first_layer_flows->{perimeter};
|
||||
$self->regions->[$region_id]->flow(FLOW_ROLE_PERIMETER, 0, 1)->width
|
||||
if ($self->regions->[$region_id]->config->first_layer_extrusion_width != 0);
|
||||
print $fh "\n";
|
||||
}
|
||||
|
||||
@ -1045,45 +1027,4 @@ sub auto_assign_extruders {
|
||||
}
|
||||
}
|
||||
|
||||
sub flow {
|
||||
my ($self, $role, $layer_height, $bridge, $first_layer, $width) = @_;
|
||||
|
||||
$bridge //= 0;
|
||||
$first_layer //= 0;
|
||||
|
||||
# use the supplied custom width, if any
|
||||
my $config_width = $width;
|
||||
if (!defined $config_width) {
|
||||
# get extrusion width from configuration
|
||||
# (might be an absolute value, or a percent value, or zero for auto)
|
||||
if ($first_layer) {
|
||||
$config_width = $self->config->first_layer_extrusion_width;
|
||||
} elsif ($role == FLOW_ROLE_SUPPORT_MATERIAL || $role == FLOW_ROLE_SUPPORT_MATERIAL_INTERFACE) {
|
||||
$config_width = $self->config->support_material_extrusion_width;
|
||||
} else {
|
||||
die "Unknown role $role";
|
||||
}
|
||||
}
|
||||
|
||||
# get the configured nozzle_diameter for the extruder associated
|
||||
# to the flow role requested
|
||||
my $extruder; # 1-based
|
||||
if ($role == FLOW_ROLE_SUPPORT_MATERIAL) {
|
||||
$config_width = $self->config->support_material_extruder;
|
||||
} elsif ($role == FLOW_ROLE_SUPPORT_MATERIAL_INTERFACE) {
|
||||
$config_width = $self->config->support_material_interface_extruder;
|
||||
} else {
|
||||
die "Unknown role $role";
|
||||
}
|
||||
my $nozzle_diameter = $self->config->nozzle_diameter->[$extruder-1];
|
||||
|
||||
return Slic3r::Flow->new(
|
||||
width => $config_width,
|
||||
role => $role,
|
||||
nozzle_diameter => $nozzle_diameter,
|
||||
layer_height => $layer_height,
|
||||
bridge_flow_ratio => ($bridge ? $self->config->bridge_flow_ratio : 0),
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -2,6 +2,7 @@ package Slic3r::Print::Object;
|
||||
use Moo;
|
||||
|
||||
use List::Util qw(min max sum first);
|
||||
use Slic3r::Flow ':roles';
|
||||
use Slic3r::Geometry qw(X Y Z PI scale unscale deg2rad rad2deg scaled_epsilon chained_path);
|
||||
use Slic3r::Geometry::Clipper qw(diff diff_ex intersection intersection_ex union union_ex
|
||||
offset offset_ex offset2 offset2_ex CLIPPER_OFFSET_SCALE JT_MITER);
|
||||
@ -300,7 +301,7 @@ sub make_perimeters {
|
||||
for my $layer_id (0 .. $self->layer_count-2) {
|
||||
my $layerm = $self->layers->[$layer_id]->regions->[$region_id];
|
||||
my $upper_layerm = $self->layers->[$layer_id+1]->regions->[$region_id];
|
||||
my $perimeter_spacing = $layerm->perimeter_flow->scaled_spacing;
|
||||
my $perimeter_spacing = $layerm->flow(FLOW_ROLE_PERIMETER)->scaled_spacing;
|
||||
|
||||
my $overlap = $perimeter_spacing; # one perimeter
|
||||
|
||||
@ -863,7 +864,8 @@ sub generate_support_material {
|
||||
|
||||
my $s = Slic3r::Print::SupportMaterial->new(
|
||||
config => $self->config,
|
||||
flow => $self->print->support_material_flow,
|
||||
flow => $self->support_material_flow,
|
||||
interface_flow => $self->support_material_flow(FLOW_ROLE_SUPPORT_MATERIAL_INTERFACE),
|
||||
);
|
||||
$s->generate($self);
|
||||
}
|
||||
@ -877,4 +879,23 @@ sub _simplify_slices {
|
||||
}
|
||||
}
|
||||
|
||||
sub support_material_flow {
|
||||
my ($self, $role) = @_;
|
||||
|
||||
$role //= FLOW_ROLE_SUPPORT_MATERIAL;
|
||||
my $extruder = ($role == FLOW_ROLE_SUPPORT_MATERIAL)
|
||||
? $self->config->support_material_extruder
|
||||
: $self->config->support_material_interface_extruder;
|
||||
|
||||
# we use a bogus layer_height because we use the same flow for all
|
||||
# support material layers
|
||||
return Slic3r::Flow->new(
|
||||
width => $self->config->support_material_extrusion_width,
|
||||
role => $role,
|
||||
nozzle_diameter => $self->print->config->nozzle_diameter->[$extruder-1],
|
||||
layer_height => $self->config->layer_height,
|
||||
bridge_flow_ratio => 0,
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -21,7 +21,7 @@ sub flow {
|
||||
if (!defined $config_width) {
|
||||
# get extrusion width from configuration
|
||||
# (might be an absolute value, or a percent value, or zero for auto)
|
||||
if ($first_layer) {
|
||||
if ($first_layer && $self->config->first_layer_extrusion_width != 0) {
|
||||
$config_width = $self->config->first_layer_extrusion_width;
|
||||
} elsif ($role == FLOW_ROLE_PERIMETER) {
|
||||
$config_width = $self->config->perimeter_extrusion_width;
|
||||
|
@ -131,6 +131,13 @@ ConfigBase::set(t_config_option_key opt_key, SV* value) {
|
||||
ConfigOption* opt = this->option(opt_key, true);
|
||||
if (opt == NULL) CONFESS("Trying to set non-existing option");
|
||||
|
||||
ConfigOptionDef* optdef = &(*this->def)[opt_key];
|
||||
if (!optdef->shortcut.empty()) {
|
||||
for (std::vector<t_config_option_key>::iterator it = optdef->shortcut.begin(); it != optdef->shortcut.end(); ++it)
|
||||
this->set(*it, value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ConfigOptionFloat* optv = dynamic_cast<ConfigOptionFloat*>(opt)) {
|
||||
optv->value = SvNV(value);
|
||||
} else if (ConfigOptionFloats* optv = dynamic_cast<ConfigOptionFloats*>(opt)) {
|
||||
|
@ -576,6 +576,14 @@ class PrintConfig : public StaticConfig
|
||||
Options["extra_perimeters"].cli = "extra-perimeters!";
|
||||
Options["extra_perimeters"].scope = "object";
|
||||
|
||||
Options["extruder"].type = coInt;
|
||||
Options["extruder"].label = "Extruder";
|
||||
Options["extruder"].cli = "extruder=i";
|
||||
Options["extruder"].shortcut.push_back("perimeter_extruder");
|
||||
Options["extruder"].shortcut.push_back("infill_extruder");
|
||||
Options["extruder"].shortcut.push_back("support_material_extruder");
|
||||
Options["extruder"].shortcut.push_back("support_material_interface_extruder");
|
||||
|
||||
Options["extruder_clearance_height"].type = coFloat;
|
||||
Options["extruder_clearance_height"].label = "Height";
|
||||
Options["extruder_clearance_height"].tooltip = "Set this to the vertical distance between your nozzle tip and (usually) the X carriage rods. In other words, this is the height of the clearance cylinder around your extruder, and it represents the maximum depth the extruder can peek before colliding with other printed objects.";
|
||||
@ -761,7 +769,6 @@ class PrintConfig : public StaticConfig
|
||||
Options["infill_extruder"].label = "Infill extruder";
|
||||
Options["infill_extruder"].tooltip = "The extruder to use when printing infill.";
|
||||
Options["infill_extruder"].cli = "infill-extruder=i";
|
||||
Options["infill_extruder"].shortcut.push_back("extruder");
|
||||
|
||||
Options["infill_extrusion_width"].type = coFloatOrPercent;
|
||||
Options["infill_extrusion_width"].label = "Infill";
|
||||
@ -879,7 +886,6 @@ class PrintConfig : public StaticConfig
|
||||
Options["perimeter_extruder"].tooltip = "The extruder to use when printing perimeters.";
|
||||
Options["perimeter_extruder"].cli = "perimeter-extruder=i";
|
||||
Options["perimeter_extruder"].aliases.push_back("perimeters_extruder");
|
||||
Options["perimeter_extruder"].shortcut.push_back("extruder");
|
||||
|
||||
Options["perimeter_extrusion_width"].type = coFloatOrPercent;
|
||||
Options["perimeter_extrusion_width"].label = "Perimeters";
|
||||
@ -1141,7 +1147,6 @@ class PrintConfig : public StaticConfig
|
||||
Options["support_material_extruder"].label = "Support material extruder";
|
||||
Options["support_material_extruder"].tooltip = "The extruder to use when printing support material. This affects brim and raft too.";
|
||||
Options["support_material_extruder"].cli = "support-material-extruder=i";
|
||||
Options["support_material_extruder"].shortcut.push_back("extruder");
|
||||
|
||||
Options["support_material_extrusion_width"].type = coFloatOrPercent;
|
||||
Options["support_material_extrusion_width"].label = "Support material";
|
||||
@ -1153,7 +1158,6 @@ class PrintConfig : public StaticConfig
|
||||
Options["support_material_interface_extruder"].label = "Support material interface extruder";
|
||||
Options["support_material_interface_extruder"].tooltip = "The extruder to use when printing support material interface. This affects raft too.";
|
||||
Options["support_material_interface_extruder"].cli = "support-material-interface-extruder=i";
|
||||
Options["support_material_interface_extruder"].shortcut.push_back("extruder");
|
||||
|
||||
Options["support_material_interface_layers"].type = coInt;
|
||||
Options["support_material_interface_layers"].label = "Interface layers";
|
||||
|
@ -4,7 +4,7 @@ use strict;
|
||||
use warnings;
|
||||
|
||||
use Slic3r::XS;
|
||||
use Test::More tests => 78;
|
||||
use Test::More tests => 79;
|
||||
|
||||
foreach my $config (Slic3r::Config->new, Slic3r::Config::Print->new) {
|
||||
$config->set('layer_height', 0.3);
|
||||
@ -88,6 +88,8 @@ foreach my $config (Slic3r::Config->new, Slic3r::Config::Print->new) {
|
||||
{
|
||||
my $config = Slic3r::Config->new;
|
||||
$config->set('perimeters', 2);
|
||||
$config->set('solid_layers', 2);
|
||||
is $config->get('top_solid_layers'), 2, 'shortcut';
|
||||
|
||||
# test that no crash happens when using set_deserialize() with a key that hasn't been set() yet
|
||||
$config->set_deserialize('filament_diameter', '3');
|
||||
|
Loading…
Reference in New Issue
Block a user