Fix the extruder override logic. All role-based extruder options now default to 0, meaning no override is defined and the default (inherited) extruder is used. The default extruder option does not use the shortcut logic anymore (it was thus moved to be a CLI-specific logic)
This commit is contained in:
parent
2e6213fea6
commit
0ff33f47f1
@ -57,6 +57,8 @@ sub new_from_cli {
|
||||
foreach my $opt_key (keys %args) {
|
||||
if ($opt_key =~ /^(?:print_center|bed_size|duplicate_grid|extruder_offset|retract_layer_change|wipe)$/) {
|
||||
$self->set_deserialize($opt_key, $args{$opt_key});
|
||||
} elsif (my $shortcut = $Options->{$opt_key}{shortcut}) {
|
||||
$self->set($_, $args{$opt_key}) for @$shortcut;
|
||||
} else {
|
||||
$self->set($opt_key, $args{$opt_key});
|
||||
}
|
||||
|
@ -528,7 +528,7 @@ sub build {
|
||||
|
||||
$self->add_options_page('Multiple Extruders', 'funnel.png', optgroups => [
|
||||
{
|
||||
title => 'Extruders',
|
||||
title => 'Override extruders',
|
||||
options => [qw(perimeter_extruder infill_extruder support_material_extruder support_material_interface_extruder)],
|
||||
},
|
||||
{
|
||||
|
@ -319,37 +319,6 @@ StaticConfig::keys(t_config_option_keys *keys) const {
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StaticConfig::apply(const DynamicConfig &other, bool ignore_nonexistent) {
|
||||
// clone the other config so that we can remove shortcut options after applying them
|
||||
DynamicConfig other_clone = other;
|
||||
|
||||
// get list of option keys to apply
|
||||
t_config_option_keys opt_keys;
|
||||
other_clone.keys(&opt_keys);
|
||||
|
||||
// loop through options and apply them
|
||||
for (t_config_option_keys::const_iterator opt_key = opt_keys.begin(); opt_key != opt_keys.end(); ++opt_key) {
|
||||
// if this is not a shortcut, skip it
|
||||
ConfigOptionDef* optdef = &(*this->def)[*opt_key];
|
||||
if (optdef->shortcut.empty()) continue;
|
||||
|
||||
// expand the option into other_clone if it does not exist already
|
||||
for (std::vector<t_config_option_key>::iterator it = optdef->shortcut.begin(); it != optdef->shortcut.end(); ++it) {
|
||||
if (other_clone.has(*it)) continue;
|
||||
ConfigOption* my_opt = other_clone.option(*it, true);
|
||||
|
||||
// not the most efficient way, but easier than casting pointers to subclasses
|
||||
my_opt->deserialize( other_clone.option(*opt_key)->serialize() );
|
||||
}
|
||||
|
||||
// remove the shortcut option from other_clone
|
||||
other_clone.erase(*opt_key);
|
||||
}
|
||||
|
||||
static_cast<ConfigBase*>(this)->apply(other_clone, ignore_nonexistent);
|
||||
}
|
||||
|
||||
const ConfigOption*
|
||||
StaticConfig::option(const t_config_option_key opt_key) const
|
||||
{
|
||||
|
@ -22,6 +22,8 @@ class ConfigOption {
|
||||
virtual ~ConfigOption() {};
|
||||
virtual std::string serialize() const = 0;
|
||||
virtual bool deserialize(std::string str) = 0;
|
||||
virtual int getInt() const { return 0; };
|
||||
virtual void setInt(int val) {};
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@ -91,6 +93,8 @@ class ConfigOptionInt : public ConfigOption
|
||||
ConfigOptionInt() : value(0) {};
|
||||
|
||||
operator int() const { return this->value; };
|
||||
int getInt() const { return this->value; };
|
||||
void setInt(int val) { this->value = val; };
|
||||
|
||||
std::string serialize() const {
|
||||
std::ostringstream ss;
|
||||
@ -499,11 +503,6 @@ class StaticConfig : public ConfigBase
|
||||
{
|
||||
public:
|
||||
void keys(t_config_option_keys *keys) const;
|
||||
void apply(const ConfigBase &other, bool ignore_nonexistent = false) {
|
||||
// this proxy appears to be needed otherwise the inherited signature couldn't be found from .xsp
|
||||
ConfigBase::apply(other, ignore_nonexistent);
|
||||
};
|
||||
void apply(const DynamicConfig &other, bool ignore_nonexistent = false);
|
||||
virtual ConfigOption* option(const t_config_option_key opt_key, bool create = false) = 0;
|
||||
const ConfigOption* option(const t_config_option_key opt_key) const;
|
||||
|
||||
|
@ -4,4 +4,44 @@ namespace Slic3r {
|
||||
|
||||
t_optiondef_map PrintConfigDef::def = PrintConfigDef::build_def();
|
||||
|
||||
void
|
||||
StaticPrintConfig::prepare_extruder_option(const t_config_option_key opt_key, DynamicPrintConfig& other)
|
||||
{
|
||||
// don't apply role-based extruders if their value is zero
|
||||
if (other.has(opt_key) && other.option(opt_key)->getInt() == 0)
|
||||
other.erase(opt_key);
|
||||
|
||||
// only apply default extruder if our role-based value is zero
|
||||
// (i.e. default extruder has the lowest priority among all other values)
|
||||
if (other.has("extruder")) {
|
||||
int extruder = other.option("extruder")->getInt();
|
||||
if (extruder > 0) {
|
||||
if (!other.has(opt_key) && this->option(opt_key)->getInt() == 0)
|
||||
other.option(opt_key, true)->setInt(extruder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PrintObjectConfig::apply(const ConfigBase &other, bool ignore_nonexistent) {
|
||||
DynamicPrintConfig other_clone;
|
||||
other_clone.apply(other);
|
||||
|
||||
this->prepare_extruder_option("support_material_extruder", other_clone);
|
||||
this->prepare_extruder_option("support_material_interface_extruder", other_clone);
|
||||
|
||||
StaticConfig::apply(other_clone, ignore_nonexistent);
|
||||
};
|
||||
|
||||
void
|
||||
PrintRegionConfig::apply(const ConfigBase &other, bool ignore_nonexistent) {
|
||||
DynamicPrintConfig other_clone;
|
||||
other_clone.apply(other);
|
||||
|
||||
this->prepare_extruder_option("infill_extruder", other_clone);
|
||||
this->prepare_extruder_option("perimeter_extruder", other_clone);
|
||||
|
||||
StaticConfig::apply(other_clone, ignore_nonexistent);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -177,10 +177,6 @@ class PrintConfigDef
|
||||
Options["extruder"].tooltip = "The extruder to use (unless more specific extruder settings are specified).";
|
||||
Options["extruder"].cli = "extruder=i";
|
||||
Options["extruder"].min = 1;
|
||||
Options["extruder"].shortcut.push_back("infill_extruder");
|
||||
Options["extruder"].shortcut.push_back("perimeter_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";
|
||||
@ -404,8 +400,9 @@ class PrintConfigDef
|
||||
Options["infill_extruder"].label = "Infill extruder";
|
||||
Options["infill_extruder"].category = "Extruders";
|
||||
Options["infill_extruder"].tooltip = "The extruder to use when printing infill.";
|
||||
Options["infill_extruder"].sidetext = "(leave 0 for default)";
|
||||
Options["infill_extruder"].cli = "infill-extruder=i";
|
||||
Options["infill_extruder"].min = 1;
|
||||
Options["infill_extruder"].min = 0;
|
||||
|
||||
Options["infill_extrusion_width"].type = coFloatOrPercent;
|
||||
Options["infill_extrusion_width"].label = "Infill";
|
||||
@ -528,9 +525,10 @@ class PrintConfigDef
|
||||
Options["perimeter_extruder"].label = "Perimeter extruder";
|
||||
Options["perimeter_extruder"].category = "Extruders";
|
||||
Options["perimeter_extruder"].tooltip = "The extruder to use when printing perimeters.";
|
||||
Options["perimeter_extruder"].sidetext = "(leave 0 for default)";
|
||||
Options["perimeter_extruder"].cli = "perimeter-extruder=i";
|
||||
Options["perimeter_extruder"].aliases.push_back("perimeters_extruder");
|
||||
Options["perimeter_extruder"].min = 1;
|
||||
Options["perimeter_extruder"].min = 0;
|
||||
|
||||
Options["perimeter_extrusion_width"].type = coFloatOrPercent;
|
||||
Options["perimeter_extrusion_width"].label = "Perimeters";
|
||||
@ -777,8 +775,9 @@ class PrintConfigDef
|
||||
Options["support_material_extruder"].label = "Support material extruder";
|
||||
Options["support_material_extruder"].category = "Extruders";
|
||||
Options["support_material_extruder"].tooltip = "The extruder to use when printing support material. This affects brim and raft too.";
|
||||
Options["support_material_extruder"].sidetext = "(leave 0 for default)";
|
||||
Options["support_material_extruder"].cli = "support-material-extruder=i";
|
||||
Options["support_material_extruder"].min = 1;
|
||||
Options["support_material_extruder"].min = 0;
|
||||
|
||||
Options["support_material_extrusion_width"].type = coFloatOrPercent;
|
||||
Options["support_material_extrusion_width"].label = "Support material";
|
||||
@ -791,8 +790,9 @@ class PrintConfigDef
|
||||
Options["support_material_interface_extruder"].label = "Support material interface extruder";
|
||||
Options["support_material_interface_extruder"].category = "Extruders";
|
||||
Options["support_material_interface_extruder"].tooltip = "The extruder to use when printing support material interface. This affects raft too.";
|
||||
Options["support_material_interface_extruder"].sidetext = "(leave 0 for default)";
|
||||
Options["support_material_interface_extruder"].cli = "support-material-interface-extruder=i";
|
||||
Options["support_material_interface_extruder"].min = 1;
|
||||
Options["support_material_interface_extruder"].min = 0;
|
||||
|
||||
Options["support_material_interface_layers"].type = coInt;
|
||||
Options["support_material_interface_layers"].label = "Interface layers";
|
||||
@ -934,7 +934,26 @@ class PrintConfigDef
|
||||
};
|
||||
};
|
||||
|
||||
class PrintObjectConfig : public virtual StaticConfig
|
||||
class DynamicPrintConfig : public DynamicConfig
|
||||
{
|
||||
public:
|
||||
DynamicPrintConfig() {
|
||||
this->def = &PrintConfigDef::def;
|
||||
};
|
||||
};
|
||||
|
||||
class StaticPrintConfig : public virtual StaticConfig
|
||||
{
|
||||
public:
|
||||
StaticPrintConfig() {
|
||||
this->def = &PrintConfigDef::def;
|
||||
};
|
||||
|
||||
protected:
|
||||
void prepare_extruder_option(const t_config_option_key opt_key, DynamicPrintConfig& other);
|
||||
};
|
||||
|
||||
class PrintObjectConfig : public virtual StaticPrintConfig
|
||||
{
|
||||
public:
|
||||
ConfigOptionFloatOrPercent extrusion_width;
|
||||
@ -956,9 +975,7 @@ class PrintObjectConfig : public virtual StaticConfig
|
||||
ConfigOptionFloat support_material_speed;
|
||||
ConfigOptionInt support_material_threshold;
|
||||
|
||||
PrintObjectConfig() {
|
||||
this->def = &PrintConfigDef::def;
|
||||
|
||||
PrintObjectConfig() : StaticPrintConfig() {
|
||||
this->extrusion_width.value = 0;
|
||||
this->extrusion_width.percent = false;
|
||||
this->first_layer_height.value = 0.35;
|
||||
@ -970,10 +987,10 @@ class PrintObjectConfig : public virtual StaticConfig
|
||||
this->support_material.value = false;
|
||||
this->support_material_angle.value = 0;
|
||||
this->support_material_enforce_layers.value = 0;
|
||||
this->support_material_extruder.value = 1;
|
||||
this->support_material_extruder.value = 0;
|
||||
this->support_material_extrusion_width.value = 0;
|
||||
this->support_material_extrusion_width.percent = false;
|
||||
this->support_material_interface_extruder.value = 1;
|
||||
this->support_material_interface_extruder.value = 0;
|
||||
this->support_material_interface_layers.value = 3;
|
||||
this->support_material_interface_spacing.value = 0;
|
||||
this->support_material_pattern.value = smpHoneycomb;
|
||||
@ -1004,9 +1021,11 @@ class PrintObjectConfig : public virtual StaticConfig
|
||||
|
||||
return NULL;
|
||||
};
|
||||
|
||||
void apply(const ConfigBase &other, bool ignore_nonexistent = false);
|
||||
};
|
||||
|
||||
class PrintRegionConfig : public virtual StaticConfig
|
||||
class PrintRegionConfig : public virtual StaticPrintConfig
|
||||
{
|
||||
public:
|
||||
ConfigOptionInt bottom_solid_layers;
|
||||
@ -1028,19 +1047,17 @@ class PrintRegionConfig : public virtual StaticConfig
|
||||
ConfigOptionFloatOrPercent top_infill_extrusion_width;
|
||||
ConfigOptionInt top_solid_layers;
|
||||
|
||||
PrintRegionConfig() {
|
||||
this->def = &PrintConfigDef::def;
|
||||
|
||||
PrintRegionConfig() : StaticPrintConfig() {
|
||||
this->bottom_solid_layers.value = 3;
|
||||
this->extra_perimeters.value = true;
|
||||
this->fill_angle.value = 45;
|
||||
this->fill_density.value = 40;
|
||||
this->fill_pattern.value = ipHoneycomb;
|
||||
this->infill_extruder.value = 1;
|
||||
this->infill_extruder.value = 0;
|
||||
this->infill_extrusion_width.value = 0;
|
||||
this->infill_extrusion_width.percent = false;
|
||||
this->infill_every_layers.value = 1;
|
||||
this->perimeter_extruder.value = 1;
|
||||
this->perimeter_extruder.value = 0;
|
||||
this->perimeter_extrusion_width.value = 0;
|
||||
this->perimeter_extrusion_width.percent = false;
|
||||
this->perimeters.value = 3;
|
||||
@ -1077,9 +1094,11 @@ class PrintRegionConfig : public virtual StaticConfig
|
||||
|
||||
return NULL;
|
||||
};
|
||||
|
||||
void apply(const ConfigBase &other, bool ignore_nonexistent = false);
|
||||
};
|
||||
|
||||
class PrintConfig : public virtual StaticConfig
|
||||
class PrintConfig : public virtual StaticPrintConfig
|
||||
{
|
||||
public:
|
||||
ConfigOptionBool avoid_crossing_perimeters;
|
||||
@ -1166,9 +1185,7 @@ class PrintConfig : public virtual StaticConfig
|
||||
ConfigOptionBools wipe;
|
||||
ConfigOptionFloat z_offset;
|
||||
|
||||
PrintConfig() {
|
||||
this->def = &PrintConfigDef::def;
|
||||
|
||||
PrintConfig() : StaticPrintConfig() {
|
||||
this->avoid_crossing_perimeters.value = false;
|
||||
this->bed_size.point = Pointf(200,200);
|
||||
this->bed_temperature.value = 0;
|
||||
@ -1372,15 +1389,8 @@ class PrintConfig : public virtual StaticConfig
|
||||
}
|
||||
};
|
||||
|
||||
class DynamicPrintConfig : public DynamicConfig
|
||||
{
|
||||
public:
|
||||
DynamicPrintConfig() {
|
||||
this->def = &PrintConfigDef::def;
|
||||
};
|
||||
};
|
||||
|
||||
class FullPrintConfig : public PrintObjectConfig, public PrintRegionConfig, public PrintConfig {
|
||||
public:
|
||||
ConfigOption* option(const t_config_option_key opt_key, bool create = false) {
|
||||
ConfigOption* opt;
|
||||
if ((opt = PrintObjectConfig::option(opt_key, create)) != NULL) return opt;
|
||||
@ -1388,6 +1398,12 @@ class FullPrintConfig : public PrintObjectConfig, public PrintRegionConfig, publ
|
||||
if ((opt = PrintConfig::option(opt_key, create)) != NULL) return opt;
|
||||
return NULL;
|
||||
};
|
||||
|
||||
void apply(const ConfigBase &other, bool ignore_nonexistent = false) {
|
||||
PrintObjectConfig::apply(other, ignore_nonexistent);
|
||||
PrintRegionConfig::apply(other, ignore_nonexistent);
|
||||
PrintConfig::apply(other, ignore_nonexistent);
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use strict;
|
||||
use warnings;
|
||||
|
||||
use Slic3r::XS;
|
||||
use Test::More tests => 95;
|
||||
use Test::More tests => 99;
|
||||
|
||||
foreach my $config (Slic3r::Config->new, Slic3r::Config::Full->new) {
|
||||
$config->set('layer_height', 0.3);
|
||||
@ -127,20 +127,60 @@ foreach my $config (Slic3r::Config->new, Slic3r::Config::Full->new) {
|
||||
}
|
||||
|
||||
{
|
||||
my $config = Slic3r::Config->new;
|
||||
$config->set('extruder', 2);
|
||||
is $config->get('extruder'), 2, 'shortcut option value is kept in dynamic config';
|
||||
ok !$config->has('perimeter_extruder'), 'shortcut is not expanded in dynamic config';
|
||||
|
||||
{
|
||||
my $config2 = Slic3r::Config::Full->new;
|
||||
$config2->set('extruder', 2);
|
||||
is $config2->get('perimeter_extruder'), 2, 'shortcut is expanded in static config (set)';
|
||||
my $config = Slic3r::Config->new;
|
||||
$config->set('infill_extruder', 2);
|
||||
my $config2 = Slic3r::Config::PrintRegion->new;
|
||||
$config2->apply($config);
|
||||
is $config2->get('infill_extruder'), $config->get('infill_extruder'),
|
||||
'non-zero infill_extruder is applied';
|
||||
}
|
||||
{
|
||||
my $config3 = Slic3r::Config::Full->new;
|
||||
$config3->apply_dynamic($config);
|
||||
is $config3->get('perimeter_extruder'), 2, 'shortcut is expanded in static config (apply)';
|
||||
my $config = Slic3r::Config->new;
|
||||
$config->set('infill_extruder', 0);
|
||||
my $config2 = Slic3r::Config::PrintRegion->new;
|
||||
$config2->set('infill_extruder', 3);
|
||||
$config2->apply($config);
|
||||
isnt $config2->get('infill_extruder'), $config->get('infill_extruder'),
|
||||
'zero infill_extruder is not applied';
|
||||
}
|
||||
{
|
||||
my $config = Slic3r::Config->new;
|
||||
$config->set('extruder', 3);
|
||||
my $config2 = Slic3r::Config::PrintRegion->new;
|
||||
$config2->set('infill_extruder', 2);
|
||||
$config2->apply($config);
|
||||
is $config2->get('infill_extruder'), 2, 'extruder does not overwrite non-zero role extruders';
|
||||
is $config2->get('perimeter_extruder'), 3, 'extruder overwrites zero role extruders';
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
{
|
||||
my $config = Slic3r::Config->new;
|
||||
$config->set('support_material_extruder', 2);
|
||||
my $config2 = Slic3r::Config::PrintObject->new;
|
||||
$config2->apply($config);
|
||||
is $config2->get('support_material_extruder'), $config->get('support_material_extruder'),
|
||||
'non-zero support_material_extruder is applied';
|
||||
}
|
||||
{
|
||||
my $config = Slic3r::Config->new;
|
||||
$config->set('support_material_extruder', 0);
|
||||
my $config2 = Slic3r::Config::PrintObject->new;
|
||||
$config2->set('support_material_extruder', 3);
|
||||
$config2->apply($config);
|
||||
isnt $config2->get('support_material_extruder'), $config->get('support_material_extruder'),
|
||||
'zero support_material_extruder is not applied';
|
||||
}
|
||||
{
|
||||
my $config = Slic3r::Config->new;
|
||||
$config->set('extruder', 3);
|
||||
my $config2 = Slic3r::Config::PrintObject->new;
|
||||
$config2->set('support_material_extruder', 2);
|
||||
$config2->apply($config);
|
||||
is $config2->get('support_material_extruder'), 2, 'extruder does not overwrite non-zero role extruders';
|
||||
is $config2->get('support_material_interface_extruder'), 3, 'extruder overwrites zero role extruders';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,8 +102,6 @@
|
||||
double get_abs_value(t_config_option_key opt_key);
|
||||
%name{get_abs_value_over}
|
||||
double get_abs_value(t_config_option_key opt_key, double ratio_over);
|
||||
void apply(PrintObjectConfig* other)
|
||||
%code{% THIS->apply(*other, true); %};
|
||||
void apply_dynamic(DynamicPrintConfig* other)
|
||||
%code{% THIS->apply(*other, true); %};
|
||||
std::vector<std::string> get_keys()
|
||||
|
Loading…
Reference in New Issue
Block a user