Reworked the FFF Print::update() to process the filament retract

override values and to store them into the output G-code.
This commit is contained in:
bubnikv 2019-07-25 14:39:19 +02:00
parent 42c8940795
commit f8218eb903
11 changed files with 210 additions and 66 deletions

View file

@ -485,25 +485,79 @@ bool layer_height_ranges_equal(const t_layer_config_ranges &lr1, const t_layer_c
return true;
}
Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &config_in)
// Collect diffs of configuration values at various containers,
// resolve the filament rectract overrides of extruder retract values.
void Print::config_diffs(
const DynamicPrintConfig &new_full_config,
t_config_option_keys &print_diff, t_config_option_keys &object_diff, t_config_option_keys &region_diff,
t_config_option_keys &full_config_diff,
DynamicPrintConfig &placeholder_parser_overrides,
DynamicPrintConfig &filament_overrides) const
{
// Collect changes to print config, account for overrides of extruder retract values by filament presets.
{
const std::vector<std::string> &extruder_retract_keys = print_config_def.extruder_retract_keys();
const std::string filament_prefix = "filament_";
for (const t_config_option_key &opt_key : m_config.keys()) {
const ConfigOption *opt_old = m_config.option(opt_key);
assert(opt_old != nullptr);
const ConfigOption *opt_new = new_full_config.option(opt_key);
assert(opt_new != nullptr);
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()) {
// An extruder retract override is available at some of the filament presets.
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);
if (*opt_old == *opt_copy)
delete opt_copy;
else {
filament_overrides.set_key_value(opt_key, opt_copy);
print_diff.emplace_back(opt_key);
}
}
} else if (*opt_new != *opt_old)
print_diff.emplace_back(opt_key);
}
}
// Collect changes to object and region configs.
object_diff = m_default_object_config.diff(new_full_config);
region_diff = m_default_region_config.diff(new_full_config);
// Prepare for storing of the full print config into new_full_config to be exported into the G-code and to be used by the PlaceholderParser.
// As the PlaceholderParser does not interpret the FloatOrPercent values itself, these values are stored into the PlaceholderParser converted to floats.
for (const t_config_option_key &opt_key : new_full_config.keys()) {
const ConfigOption *opt_old = m_full_print_config.option(opt_key);
const ConfigOption *opt_new = new_full_config.option(opt_key);
if (opt_old == nullptr || *opt_new != *opt_old)
full_config_diff.emplace_back(opt_key);
if (opt_new->type() == coFloatOrPercent) {
// The m_placeholder_parser is never modified by the background processing, GCode.cpp/hpp makes a copy.
const ConfigOption *opt_old_pp = this->placeholder_parser().config().option(opt_key);
double new_value = new_full_config.get_abs_value(opt_key);
if (opt_old_pp == nullptr || static_cast<const ConfigOptionFloat*>(opt_old_pp)->value != new_value)
placeholder_parser_overrides.set_key_value(opt_key, new ConfigOptionFloat(new_value));
}
}
}
Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_config)
{
#ifdef _DEBUG
check_model_ids_validity(model);
#endif /* _DEBUG */
// Make a copy of the config, normalize it.
DynamicPrintConfig config(config_in);
config.option("print_settings_id", true);
config.option("filament_settings_id", true);
config.option("printer_settings_id", true);
config.normalize();
// Collect changes to print config.
t_config_option_keys print_diff = m_config.diff(config);
t_config_option_keys object_diff = m_default_object_config.diff(config);
t_config_option_keys region_diff = m_default_region_config.diff(config);
t_config_option_keys placeholder_parser_diff = this->placeholder_parser().config_diff(config);
// Normalize the config.
new_full_config.option("print_settings_id", true);
new_full_config.option("filament_settings_id", true);
new_full_config.option("printer_settings_id", true);
new_full_config.normalize();
// Do not use the ApplyStatus as we will use the max function when updating apply_status.
// Find modified keys of the various configs. Resolve overrides extruder retract values by filament profiles.
t_config_option_keys print_diff, object_diff, region_diff, full_config_diff;
DynamicPrintConfig placeholder_parser_overrides, filament_overrides;
this->config_diffs(new_full_config, print_diff, object_diff, region_diff, full_config_diff, placeholder_parser_overrides, filament_overrides);
// Do not use the ApplyStatus as we will use the max function when updating apply_status.
unsigned int apply_status = APPLY_STATUS_UNCHANGED;
auto update_apply_status = [&apply_status](bool invalidated)
{ apply_status = std::max<unsigned int>(apply_status, invalidated ? APPLY_STATUS_INVALIDATED : APPLY_STATUS_CHANGED); };
@ -516,24 +570,26 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co
// The following call may stop the background processing.
if (! print_diff.empty())
update_apply_status(this->invalidate_state_by_config_options(print_diff));
// Apply variables to placeholder parser. The placeholder parser is used by G-code export,
// which should be stopped if print_diff is not empty.
if (! placeholder_parser_diff.empty()) {
if (! full_config_diff.empty() || ! placeholder_parser_overrides.empty()) {
update_apply_status(this->invalidate_step(psGCodeExport));
PlaceholderParser &pp = this->placeholder_parser();
pp.apply_only(config, placeholder_parser_diff);
pp.apply_config(std::move(placeholder_parser_overrides));
// Set the profile aliases for the PrintBase::output_filename()
pp.set("print_preset", config.option("print_settings_id")->clone());
pp.set("filament_preset", config.option("filament_settings_id")->clone());
pp.set("printer_preset", config.option("printer_settings_id")->clone());
pp.set("print_preset", new_full_config.option("print_settings_id")->clone());
pp.set("filament_preset", new_full_config.option("filament_settings_id")->clone());
pp.set("printer_preset", new_full_config.option("printer_settings_id")->clone());
// It is also safe to change m_config now after this->invalidate_state_by_config_options() call.
m_config.apply_only(new_full_config, print_diff, true);
m_config.apply(filament_overrides);
// Handle changes to object config defaults
m_default_object_config.apply_only(new_full_config, object_diff, true);
// Handle changes to regions config defaults
m_default_region_config.apply_only(new_full_config, region_diff, true);
m_full_print_config = std::move(new_full_config);
}
// It is also safe to change m_config now after this->invalidate_state_by_config_options() call.
m_config.apply_only(config, print_diff, true);
// Handle changes to object config defaults
m_default_object_config.apply_only(config, object_diff, true);
// Handle changes to regions config defaults
m_default_region_config.apply_only(config, region_diff, true);
class LayerRanges
{
@ -1698,8 +1754,8 @@ void Print::_make_wipe_tower()
(float)m_config.filament_cooling_initial_speed.get_at(i),
(float)m_config.filament_cooling_final_speed.get_at(i),
m_config.filament_ramming_parameters.get_at(i),
m_config.filament_max_volumetric_speed.get_at(i),
m_config.nozzle_diameter.get_at(i));
(float)m_config.filament_max_volumetric_speed.get_at(i),
(float)m_config.nozzle_diameter.get_at(i));
m_wipe_tower_data.priming = Slic3r::make_unique<std::vector<WipeTower::ToolChangeResult>>(
wipe_tower.prime((float)this->skirt_first_layer_height(), m_wipe_tower_data.tool_ordering.all_extruders(), false));