Skip to content

Commit

Permalink
Change setting's "nullable" values by a proper "enabled" flag.
Browse files Browse the repository at this point in the history
  • Loading branch information
supermerill committed Aug 4, 2024
1 parent 842cec9 commit fef68ef
Show file tree
Hide file tree
Showing 34 changed files with 1,290 additions and 1,594 deletions.
6 changes: 4 additions & 2 deletions resources/ui_layout/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,10 @@ These functions can only be called in a `set` or `reset` function. If you need t
### others
* void **ask_for_refresh**()
ask for a OPTNAME_set() after the current OPTNAME_get(), to be able to set settings.
* bool **is_enabled**(string setting_key)
Experimental. Ask if this setting is currently enabled. Dangerous, as it will be true if it's not constructed.
* bool **is_enabled**(string setting_key, int idx)
Ask if this setting is currently enabled. `idx` is the index of the value if the settigns is a vector, it's ignored if it's a scalar.
* bool **is_widget_enabled**(string setting_key)
Experimental. Ask if a widget for this setting is currently enabled. Dangerous, as it will be true if it's not constructed.

### to get/set the value of a custom variable
The first argument is the index of the tab setting: 0 for print settings, 1 for filament settings and 2 for printer settings.
Expand Down
2 changes: 1 addition & 1 deletion resources/ui_layout/default/filament.ui
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ group:Temperature °C
line:Extruder
setting:id$0:first_layer_temperature
setting:id$0:temperature
setting:id$0:label$Idle:idle_temperature
end_line
line:Bed
setting:id$0:first_layer_bed_temperature
setting:id$0:label$Other layers:bed_temperature
end_line
setting:id$0:chamber_temperature
setting:id$0:label$Idle:idle_temperature
group:Filament properties
setting:id$0:width$7:filament_type
setting:id$0:filament_soluble
Expand Down
155 changes: 78 additions & 77 deletions src/libslic3r/Config.cpp

Large diffs are not rendered by default.

1,072 changes: 358 additions & 714 deletions src/libslic3r/Config.hpp

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions src/libslic3r/Extruder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ double Extruder::retract_before_wipe() const

double Extruder::retract_length() const
{
assert(!m_config->retract_length.is_nil());
assert(m_config->retract_length.is_enabled());
assert(m_config->retract_length.get_at(m_id) < std::numeric_limits<int32_t>::max());
assert(m_config->retract_length.get_at(m_id) > -std::numeric_limits<int32_t>::max());
assert(m_config->retract_length.size() > m_id);
Expand All @@ -258,7 +258,7 @@ double Extruder::retract_length() const

double Extruder::retract_lift() const
{
assert(!m_config->retract_lift.is_nil());
assert(m_config->retract_lift.is_enabled());
assert(m_config->retract_lift.get_at(m_id) < std::numeric_limits<int32_t>::max());
assert(m_config->retract_lift.get_at(m_id) > -std::numeric_limits<int32_t>::max());
assert(m_config->retract_lift.size() > m_id);
Expand All @@ -278,7 +278,7 @@ int Extruder::deretract_speed() const

double Extruder::retract_restart_extra() const
{
assert(!m_config->retract_restart_extra.is_nil());
assert(m_config->retract_restart_extra.is_enabled());
assert(m_config->retract_restart_extra.get_at(m_id) < std::numeric_limits<int32_t>::max());
assert(m_config->retract_restart_extra.get_at(m_id) > -std::numeric_limits<int32_t>::max());
assert(m_config->retract_restart_extra.size() > m_id);
Expand All @@ -292,7 +292,7 @@ double Extruder::retract_length_toolchange() const

double Extruder::retract_restart_extra_toolchange() const
{
assert(!m_config->retract_restart_extra_toolchange.is_nil());
assert(m_config->retract_restart_extra_toolchange.is_enabled());
assert(m_config->retract_restart_extra_toolchange.get_at(m_id) < std::numeric_limits<int32_t>::max());
assert(m_config->retract_restart_extra_toolchange.get_at(m_id) > -std::numeric_limits<int32_t>::max());
assert(m_config->retract_restart_extra_toolchange.size() > m_id);
Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/Format/CWS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void fill_slicerconf(ConfMap &m, const SLAPrint &print)

auto &cfg = print.full_print_config();
for (const std::string &key : cfg.keys())
if (! is_banned(key) && ! cfg.option(key)->is_nil())
if (!is_banned(key) && (cfg.option(key)->is_enabled() || !cfg.get_option_def(key)->is_optional))
m[key] = cfg.opt_serialize(key);

}
Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/Format/SL1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ void fill_slicerconf(ConfMap &m, const SLAPrint &print)

auto &cfg = print.full_print_config();
for (const std::string &key : cfg.keys())
if (! is_banned(key) && ! cfg.option(key)->is_nil())
if (!is_banned(key) && (cfg.option(key)->is_enabled() || !cfg.get_option_def(key)->is_optional))
m[key] = cfg.opt_serialize(key);

}
Expand Down
8 changes: 4 additions & 4 deletions src/libslic3r/GCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,8 @@ namespace Slic3r {
// gcode += gcodegen.writer().travel_to_xy(unscale(standby_point), 0.0, "move to standby position");
//}
unsigned int extruder_id = gcodegen.writer().tool()->id();
const ConfigOptionIntsNullable& filament_idle_temp = gcodegen.config().idle_temperature;
if (filament_idle_temp.is_nil(extruder_id)) {
const ConfigOptionInts& filament_idle_temp = gcodegen.config().idle_temperature;
if (!filament_idle_temp.is_enabled(extruder_id)) {
// There is no idle temperature defined in filament settings.
// Use the delta value from print config.
if (gcodegen.config().standby_temperature_delta.value != 0 && gcodegen.writer().tool_is_extruder() && this->_get_temp(gcodegen) > 0) {
Expand Down Expand Up @@ -2742,7 +2742,7 @@ void GCodeGenerator::_print_first_layer_extruder_temperatures(std::string &out,
if (temp == 0)
temp = print.config().temperature.get_at(tool.id());
if (print.config().ooze_prevention.value && tool.id() != first_printing_extruder_id)
if (print.config().idle_temperature.is_nil(tool.id()))
if (!print.config().idle_temperature.is_enabled(tool.id()))
temp += print.config().standby_temperature_delta.value;
else
temp = print.config().idle_temperature.get_at(tool.id());
Expand Down Expand Up @@ -3881,7 +3881,7 @@ void GCodeGenerator::encode_full_config(const Print& print, std::vector<std::pai
};
config.reserve(config.size() + cfg.keys().size());
for (const std::string& key : cfg.keys()) {
if (!is_banned(key) && !cfg.option(key)->is_nil())
if (!is_banned(key) && (cfg.option(key)->is_enabled() || !cfg.get_option_def(key)->is_optional))
config.emplace_back(key, cfg.opt_serialize(key));
}
config.shrink_to_fit();
Expand Down
75 changes: 30 additions & 45 deletions src/libslic3r/PlaceholderParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -984,18 +984,14 @@ namespace client
if (opt == nullptr)
ctx->throw_exception("Variable does not exist", opt_key);
if (opt->is_scalar()) {
if (opt->is_nil())
ctx->throw_exception("Trying to reference an undefined (nil) optional variable", opt_key);
output = opt->serialize();
} else {
const ConfigOptionVectorBase *vec = static_cast<const ConfigOptionVectorBase*>(opt);
if (vec->empty())
ctx->throw_exception("Indexing an empty vector variable", opt_key);
if (idx >= vec->size())
idx = 0;
if (vec->is_nil(idx))
ctx->throw_exception("Trying to reference an undefined (nil) element of vector of optional values", opt_key);
output = vec->vserialize()[idx];
output = vec->serialize_at(idx);
}
}

Expand Down Expand Up @@ -1038,9 +1034,7 @@ namespace client
ctx->throw_exception("Negative vector index", opt_key);
if (idx >= (int)vec->size())
idx = 0;
if (vec->is_nil(idx))
ctx->throw_exception("Trying to reference an undefined (nil) element of vector of optional values", opt_key);
output = vec->vserialize()[idx];
output = vec->serialize_at(idx);
}

static void resolve_variable(
Expand Down Expand Up @@ -1129,10 +1123,6 @@ namespace client
ctx->throw_exception("Referencing a vector variable when scalar is expected", opt.it_range);
}


if (opt.opt->is_nil())
ctx->throw_exception("Trying to reference an undefined (nil) optional variable", opt.it_range);

switch (opt.opt->type()) {
case coFloat: output.set_d(opt.opt->get_float()); break;
case coInt: output.set_i(opt.opt->get_int()); break;
Expand Down Expand Up @@ -1254,8 +1244,6 @@ namespace client
idx = size_t(opt.index);
else if (!opt.has_index())
ctx->throw_exception("Referencing a vector variable when scalar is expected", opt.it_range);
if (vec->is_nil(idx))
ctx->throw_exception("Trying to reference an undefined (nil) element of vector of optional values", opt.it_range);
switch (opt.opt->type()) {
case coFloats: output.set_d(static_cast<const ConfigOptionFloats *>(opt.opt)->get_at(idx)); break;
case coInts: output.set_i(static_cast<const ConfigOptionInts *>(opt.opt)->get_at(idx)); break;
Expand All @@ -1265,7 +1253,7 @@ namespace client
case coPoints: output.set_s(to_string(static_cast<const ConfigOptionPoints *>(opt.opt)->get_at(idx))); break;
case coGraphs: output.set_s(static_cast<const ConfigOptionGraphs *>(opt.opt)->get_at(idx).serialize()); break;
case coBools: output.set_b(static_cast<const ConfigOptionBools *>(opt.opt)->get_at(idx) != 0); break;
//case coEnums: output.set_s(opt.opt->vserialize()[idx]); break;
//case coEnums: output.set_s(opt.opt->serialize_at(idx)); break;
default:
ctx->throw_exception("Unsupported vector variable type", opt.it_range);
}
Expand Down Expand Up @@ -1427,22 +1415,17 @@ namespace client
output.it_range = opt.it_range;
}

// Return a boolean value, true if the scalar variable referenced by "opt" is nullable and it has a nil value.
// Return a boolean value, true if an element of a vector variable referenced by "opt[index]" is nullable and it has a nil value.
// Return a boolean value, true if the scalar variable referenced by "opt" or "opt[index]" is enabled.
static void is_enabled_test(const MyContext *ctx, OptWithPos &opt, expr &output)
{
output.set_b(opt.opt->is_enabled(opt.index));
output.it_range = opt.it_range;
}
// Return a boolean value, true if an element of a variable referenced by "opt" or "opt[index]" is disabled.
static void is_nil_test(const MyContext *ctx, OptWithPos &opt, expr &output)
{
if (ctx->skipping()) {
} else if (opt.opt->is_vector()) {
if (! opt.has_index())
ctx->throw_exception("Referencing a vector variable when scalar is expected", opt.it_range);
const ConfigOptionVectorBase *vec = static_cast<const ConfigOptionVectorBase*>(opt.opt);
if (vec->empty())
ctx->throw_exception("Indexing an empty vector variable", opt.it_range);
output.set_b(static_cast<const ConfigOptionVectorBase*>(opt.opt)->is_nil(opt.index >= int(vec->size()) ? 0 : size_t(opt.index)));
} else {
assert(opt.opt->is_scalar());
output.set_b(opt.opt->is_nil());
}
BOOST_LOG_TRIVIAL(warning) << "Warning: The macro 'is_nil' is deprecated. Please use '!is_enabled' instead.";
output.set_b(!opt.opt->is_enabled(opt.index));
output.it_range = opt.it_range;
}

Expand Down Expand Up @@ -1707,8 +1690,6 @@ namespace client
assert(lhs.opt->is_vector());
if (rhs.has_index() || ! rhs.opt->is_vector())
ctx->throw_exception("Cannot assign scalar to a vector", lhs.it_range);
if (rhs.opt->is_nil())
ctx->throw_exception("Some elements of the right hand side vector variable of optional values are undefined (nil)", rhs.it_range);
if (lhs.opt->type() != rhs.opt->type()) {
// Vector types are not compatible.
switch (lhs.opt->type()) {
Expand Down Expand Up @@ -1745,8 +1726,6 @@ namespace client
if (rhs.has_index() || ! rhs.opt->is_vector())
// Stop parsing, let the other rules resolve this case.
return false;
if (rhs.opt->is_nil())
ctx->throw_exception("Some elements of the right hand side vector variable of optional values are undefined (nil)", rhs.it_range);
// Clone the vector variable.
std::unique_ptr<ConfigOption> opt_new;
if (one_of(rhs.opt->type(), { coFloats, coInts, coStrings, coBools }))
Expand All @@ -1770,21 +1749,24 @@ namespace client

static void is_vector_empty(const MyContext *ctx, OptWithPos &opt, expr &out)
{
if (! ctx->skipping()) {
if (opt.has_index() || ! opt.opt->is_vector())
ctx->throw_exception("parameter of empty() is not a vector variable", opt.it_range);
out.set_b(static_cast<const ConfigOptionVectorBase*>(opt.opt)->size() == 0);
}
//if (! ctx->skipping()) {
// if (opt.has_index() || ! opt.opt->is_vector())
// ctx->throw_exception("parameter of empty() is not a vector variable", opt.it_range);
// out.set_b(static_cast<const ConfigOptionVectorBase*>(opt.opt)->size() == 0);
//}
out.set_b(opt.opt->size() == 0);
out.it_range = opt.it_range;
}

static void vector_size(const MyContext *ctx, OptWithPos &opt, expr &out)
{
if (! ctx->skipping()) {
if (opt.has_index() || ! opt.opt->is_vector())
ctx->throw_exception("parameter of size() is not a vector variable", opt.it_range);
out.set_i(int(static_cast<const ConfigOptionVectorBase*>(opt.opt)->size()));
}
//if (! ctx->skipping()) {
// if (opt.has_index() || ! opt.opt->is_vector())
// ctx->throw_exception("parameter of size() is not a vector variable", opt.it_range);
// out.set_i(int(static_cast<const ConfigOptionVectorBase*>(opt.opt)->size()));
//}

out.set_i(int(opt.opt->size()));
out.it_range = opt.it_range;
}

Expand Down Expand Up @@ -2429,7 +2411,8 @@ namespace client
[ px::bind(&expr::digits<true>, _val, _2, _3) ]
| (kw["int"] > '(' > conditional_expression(_r1) > ')') [ px::bind(&FactorActions::to_int, _1, _val) ]
| (kw["round"] > '(' > conditional_expression(_r1) > ')') [ px::bind(&FactorActions::round, _1, _val) ]
| (kw["is_nil"] > '(' > variable_reference(_r1) > ')') [px::bind(&MyContext::is_nil_test, _r1, _1, _val)]
| (kw["is_nil"] > '(' > variable_reference(_r1) > ')') [px::bind(&MyContext::is_nil_test, _r1, _1, _val)] // Deprecated same as !is_enabled
| (kw["is_enabled"] > '(' > variable_reference(_r1) > ')') [px::bind(&MyContext::is_enabled_test, _r1, _1, _val)]
| (kw["one_of"] > '(' > one_of(_r1) > ')') [ _val = _1 ]
| (kw["empty"] > '(' > variable_reference(_r1) > ')') [px::bind(&MyContext::is_vector_empty, _r1, _1, _val)]
| (kw["size"] > '(' > variable_reference(_r1) > ')') [px::bind(&MyContext::vector_size, _r1, _1, _val)]
Expand Down Expand Up @@ -2505,6 +2488,7 @@ namespace client
("if")
("int")
("is_nil")
("is_enabled")
("local")
//("inf")
("else")
Expand Down Expand Up @@ -2601,8 +2585,9 @@ namespace client
qi::rule<Iterator, OptWithPos(const MyContext*), qi::locals<OptWithPos, int>, skipper> variable_reference;
// Rule to translate an identifier to a ConfigOption, or to fail.
qi::rule<Iterator, OptWithPos(const MyContext*), skipper> variable;
// Evaluating whether a nullable variable is nil.
// Evaluating whether a variable is enabled.
qi::rule<Iterator, expr(const MyContext*), skipper> is_nil_test;
qi::rule<Iterator, expr(const MyContext*), skipper> is_enabled_test;
// Evaluating "one of" list of patterns.
qi::rule<Iterator, expr(const MyContext*), qi::locals<expr>, skipper> one_of;
qi::rule<Iterator, expr(const MyContext*, const expr &param), skipper> one_of_list;
Expand Down
4 changes: 3 additions & 1 deletion src/libslic3r/Preset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1315,7 +1315,9 @@ ExternalPreset PresetCollection::load_external_preset(
this->update_dirty();
// Don't save the newly loaded project as a "saved into project" state.
//update_saved_preset_from_current_preset();
assert(this->get_edited_preset().is_dirty);

// the get_edited_preset can be 'not dirty' if it's exactly the same as a saved preset.
//assert(this->get_edited_preset().is_dirty);
}
return ExternalPreset(&(*it), this->get_edited_preset().is_dirty, is_installed);
}
Expand Down
8 changes: 4 additions & 4 deletions src/libslic3r/PresetBundle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,14 @@ PresetBundle::PresetBundle() :
this->filaments.default_preset().config.option<ConfigOptionStrings>("filament_settings_id", true)->set({""});
this->filaments.default_preset().compatible_printers_condition();
this->filaments.default_preset().inherits();
// Set all the nullable values to nils.
this->filaments.default_preset().config.null_nullables();
// Disable all the optionals values.
this->filaments.default_preset().config.disable_optionals();

this->sla_materials.default_preset().config.optptr("sla_material_settings_id", true);
this->sla_materials.default_preset().compatible_printers_condition();
this->sla_materials.default_preset().inherits();
// Set all the nullable values to nils.
this->sla_materials.default_preset().config.null_nullables();
// Disable all the optionals values.
this->sla_materials.default_preset().config.disable_optionals();

this->sla_prints.default_preset().config.optptr("sla_print_settings_id", true);
this->sla_prints.default_preset().config.opt_string("output_filename_format", true) = "[input_filename_base].sl1";
Expand Down
7 changes: 3 additions & 4 deletions src/libslic3r/PrintApply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,11 @@ static t_config_option_keys print_config_diffs(
//FIXME This may happen when executing some test cases.
continue;
const ConfigOption *opt_new_filament = std::binary_search(extruder_retract_keys.begin(), extruder_retract_keys.end(), opt_key) ? new_full_config.option(filament_prefix + opt_key) : nullptr;
if (opt_new_filament != nullptr && ! opt_new_filament->is_nil()) {
if (opt_new_filament != nullptr) {
// An extruder retract override is available at some of the filament presets.
bool overriden = opt_new->overriden_by(opt_new_filament);
if (overriden || *opt_old != *opt_new) {
if (*opt_old != *opt_new || opt_new->overriden_by(opt_new_filament)) {
auto opt_copy = opt_new->clone();
opt_copy->apply_override(opt_new_filament);
bool overriden = opt_copy->apply_override(opt_new_filament);
bool changed = *opt_old != *opt_copy;
if (changed)
print_diff.emplace_back(opt_key);
Expand Down
Loading

0 comments on commit fef68ef

Please sign in to comment.