move my changes from tab.cpp to ConfigManipulation.cpp

This commit is contained in:
supermerill 2019-09-26 13:54:27 +02:00
parent 2f042e030c
commit 38965a1889
2 changed files with 65 additions and 303 deletions

View File

@ -69,15 +69,26 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
double fill_density = config->option<ConfigOptionPercent>("fill_density")->value;
if (config->opt_bool("spiral_vase") &&
!(config->opt_int("perimeters") == 1 && config->opt_int("top_solid_layers") == 0 &&
fill_density == 0)) {
if (config->opt_bool("spiral_vase") && !(
config->opt_int("perimeters") == 1
&& config->opt_int("top_solid_layers") == 0
&& fill_density == 0
&& config->opt_bool("support_material") == false
&& config->opt_int("support_material_enforce_layers") == 0
&& config->opt_bool("exact_last_layer_height") == false
&& config->opt_bool("ensure_vertical_shell_thickness") == false
&& config->opt_bool("infill_dense") == false
&& config->opt_bool("extra_perimeters") == false
)) {
wxString msg_text = _(L("The Spiral Vase mode requires:\n"
"- one perimeter\n"
"- no top solid layers\n"
"- 0% fill density\n"
"- no support material\n"
"- no ensure_vertical_shell_thickness"));
"- one perimeter\n"
"- no top solid layers\n"
"- 0% fill density\n"
"- no support material\n"
"- no ensure_vertical_shell_thickness\n"
"- unchecked 'exact last layer height'\n"
"- unchecked 'dense infill'\n"
"- unchecked 'extra perimeters'\n"));
if (is_global_config)
msg_text += "\n\n" + _(L("Shall I adjust those settings in order to enable Spiral Vase?"));
wxMessageDialog dialog(nullptr, msg_text, _(L("Spiral Vase")),
@ -90,7 +101,10 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
new_conf.set_key_value("fill_density", new ConfigOptionPercent(0));
new_conf.set_key_value("support_material", new ConfigOptionBool(false));
new_conf.set_key_value("support_material_enforce_layers", new ConfigOptionInt(0));
new_conf.set_key_value("exact_last_layer_height", new ConfigOptionBool(false));
new_conf.set_key_value("ensure_vertical_shell_thickness", new ConfigOptionBool(false));
new_conf.set_key_value("infill_dense", new ConfigOptionBool(false));
new_conf.set_key_value("extra_perimeters", new ConfigOptionBool(false));
fill_density = 0;
}
else {
@ -102,7 +116,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
}
if (config->opt_bool("wipe_tower") && config->opt_bool("support_material") &&
config->opt_float("support_material_contact_distance") > 0. &&
((ConfigOptionEnumGeneric*)config->option("support_material_contact_distance_type"))->value != zdNone &&
(config->opt_int("support_material_extruder") != 0 || config->opt_int("support_material_interface_extruder") != 0)) {
wxString msg_text = _(L("The Wipe Tower currently supports the non-soluble supports only\n"
"if they are printed with the current extruder without triggering a tool change.\n"
@ -123,7 +137,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
}
if (config->opt_bool("wipe_tower") && config->opt_bool("support_material") &&
config->opt_float("support_material_contact_distance") == 0 &&
((ConfigOptionEnumGeneric*)config->option("support_material_contact_distance_type"))->value != zdNone &&
!config->opt_bool("support_material_synchronize_layers")) {
wxString msg_text = _(L("For the Wipe Tower to work with the soluble supports, the support layers\n"
"need to be synchronized with the object layers."));
@ -187,19 +201,24 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
}
}
if (!str_fill_pattern.empty()) {
const std::vector<std::string>& external_fill_pattern = config->def()->get("top_fill_pattern")->enum_values;
const std::vector<std::string>& top_fill_pattern = config->def()->get("top_fill_pattern")->enum_values;
bool correct_100p_fill = false;
for (const std::string& fill : external_fill_pattern)
for (const std::string& fill : top_fill_pattern)
{
if (str_fill_pattern == fill)
correct_100p_fill = true;
}
const std::vector<std::string> bottom_fill_pattern = config->def()->get("bottom_fill_pattern")->enum_values;
for (const std::string &fill : bottom_fill_pattern) {
if (str_fill_pattern.compare(fill) == 0)
correct_100p_fill = true;
}
// get fill_pattern name from enum_labels for using this one at dialog_msg
str_fill_pattern = _utf8(config->def()->get("fill_pattern")->enum_labels[fill_pattern]);
if (!correct_100p_fill) {
wxString msg_text = GUI::from_u8((boost::format(_utf8(L("The %1% infill pattern is not supposed to work at 100%% density."))) % str_fill_pattern).str());
if (is_global_config)
msg_text += "\n\n" + _(L("Shall I switch to rectilinear fill pattern?"));
msg_text += "\n\n" + _(L("Shall I switch to "+ str_fill_pattern +" fill pattern?"));
wxMessageDialog dialog(nullptr, msg_text, _(L("Infill")),
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK) );
DynamicPrintConfig new_conf = *config;
@ -222,29 +241,43 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
{
bool have_perimeters = config->opt_int("perimeters") > 0;
for (auto el : { "extra_perimeters", "ensure_vertical_shell_thickness", "thin_walls", "overhangs",
"seam_position", "external_perimeters_first", "external_perimeter_extrusion_width",
"perimeter_speed", "small_perimeter_speed", "external_perimeter_speed" })
for (auto el : { "extra_perimeters", "only_one_perimeter_top", "ensure_vertical_shell_thickness", "thin_walls", "overhangs",
"seam_position", "external_perimeters_first", "external_perimeter_extrusion_width",
"perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "perimeter_loop", "perimeter_loop_seam" })
toggle_field(el, have_perimeters);
for (auto el : { "thin_walls_min_width", "thin_walls_overlap" })
toggle_field(el, config->opt_bool("thin_walls"));
toggle_field("perimeter_loop_seam", config->opt_bool("perimeter_loop"));
bool have_infill = config->option<ConfigOptionPercent>("fill_density")->value > 0;
// infill_extruder uses the same logic as in Print::extruders()
for (auto el : { "fill_pattern", "infill_every_layers", "infill_only_where_needed",
"solid_infill_every_layers", "solid_infill_below_area", "infill_extruder" })
"solid_infill_every_layers", "solid_infill_below_area", "infill_extruder" })
toggle_field(el, have_infill);
bool can_have_infill_dense = config->option<ConfigOptionPercent>("fill_density")->value < 50;
for (auto el : { "infill_dense" })
toggle_field(el, can_have_infill_dense);
bool have_infill_dense = config->opt_bool("infill_dense") && can_have_infill_dense;
for (auto el : { "infill_dense_algo" })
toggle_field(el, have_infill_dense);
bool have_solid_infill = config->opt_int("top_solid_layers") > 0 || config->opt_int("bottom_solid_layers") > 0;
// solid_infill_extruder uses the same logic as in Print::extruders()
for (auto el : { "top_fill_pattern", "bottom_fill_pattern", "infill_first", "solid_infill_extruder",
"solid_infill_extrusion_width", "solid_infill_speed" })
for (auto el : { "top_fill_pattern", "bottom_fill_pattern", "solid_fill_pattern", "enforce_full_fill_volume", "external_infill_margin",
"infill_first", "solid_infill_extruder", "solid_infill_extrusion_width", "solid_infill_speed" })
toggle_field(el, have_solid_infill);
for (auto el : { "fill_angle", "bridge_angle", "infill_extrusion_width",
"infill_speed", "bridge_speed" })
toggle_field(el, have_infill || have_solid_infill);
// Gap fill is newly allowed in between perimeter lines even for empty infill (see GH #1476).
toggle_field("gap_fill_speed", have_perimeters);
// gap fill can appear in infill
//toggle_field("gap_fill_speed", have_perimeters && config->opt_bool("gap_fill"));
bool have_top_solid_infill = config->opt_int("top_solid_layers") > 0;
for (auto el : { "top_infill_extrusion_width", "top_solid_infill_speed" })
@ -263,18 +296,26 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
// perimeter_extruder uses the same logic as in Print::extruders()
toggle_field("perimeter_extruder", have_perimeters || have_brim);
toggle_field("brim_ears", have_brim);
toggle_field("brim_ears_max_angle", have_brim && config->opt_bool("brim_ears"));
bool have_raft = config->opt_int("raft_layers") > 0;
bool have_support_material = config->opt_bool("support_material") || have_raft;
bool have_support_material_auto = have_support_material && config->opt_bool("support_material_auto");
bool have_support_interface = config->opt_int("support_material_interface_layers") > 0;
bool have_support_soluble = have_support_material && config->opt_float("support_material_contact_distance") == 0;
bool have_support_soluble = have_support_material && ((ConfigOptionEnumGeneric*)config->option("support_material_contact_distance_type"))->value == zdNone;
for (auto el : { "support_material_pattern", "support_material_with_sheath",
"support_material_spacing", "support_material_angle", "support_material_interface_layers",
"dont_support_bridges", "support_material_extrusion_width", "support_material_contact_distance",
"support_material_xy_spacing" })
"dont_support_bridges", "support_material_extrusion_width",
"support_material_contact_distance_type",
"support_material_xy_spacing", "support_material_interface_pattern" })
toggle_field(el, have_support_material);
toggle_field("support_material_threshold", have_support_material_auto);
for (auto el : { "support_material_contact_distance_top",
"support_material_contact_distance_bottom" })
toggle_field(el, have_support_material && !have_support_soluble);
for (auto el : { "support_material_interface_spacing", "support_material_interface_extruder",
"support_material_interface_speed", "support_material_interface_contact_loops" })
toggle_field(el, have_support_material && have_support_interface);

View File

@ -1335,286 +1335,7 @@ void TabPrint::update()
if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA)
return; // ys_FIXME
/*
// #ys_FIXME_to_delete
//! Temporary workaround for the correct updates of the TextCtrl (like "layer_height"):
// KillFocus() for the wxSpinCtrl use CallAfter function. So,
// to except the duplicate call of the update() after dialog->ShowModal(),
// let check if this process is already started.
if (is_msg_dlg_already_exist)
return;
*/
m_update_cnt++;
// Freeze();
/* #ys_FIXME_delete_after_testing (refactoring)
*
// layer_height shouldn't be equal to zero
if (m_config->opt_float("layer_height") < EPSILON)
{
const wxString msg_text = _(L("Zero layer height is not valid.\n\nThe layer height will be reset to 0.01."));
wxMessageDialog dialog(parent(), msg_text, _(L("Layer height")), wxICON_WARNING | wxOK);
DynamicPrintConfig new_conf = *m_config;
is_msg_dlg_already_exist = true;
dialog.ShowModal();
new_conf.set_key_value("layer_height", new ConfigOptionFloat(0.01));
load_config(new_conf);
is_msg_dlg_already_exist = false;
}
if (fabs(m_config->option<ConfigOptionFloatOrPercent>("first_layer_height")->value - 0) < EPSILON)
{
const wxString msg_text = _(L("Zero first layer height is not valid.\n\nThe first layer height will be reset to 0.01."));
wxMessageDialog dialog(parent(), msg_text, _(L("First layer height")), wxICON_WARNING | wxOK);
DynamicPrintConfig new_conf = *m_config;
is_msg_dlg_already_exist = true;
dialog.ShowModal();
new_conf.set_key_value("first_layer_height", new ConfigOptionFloatOrPercent(0.01, false));
load_config(new_conf);
is_msg_dlg_already_exist = false;
}
double fill_density = m_config->option<ConfigOptionPercent>("fill_density")->value;
if (m_config->opt_bool("spiral_vase") && !(
m_config->opt_int("perimeters") == 1
&& m_config->opt_int("top_solid_layers") == 0
&& fill_density == 0
&& m_config->opt_bool("support_material") == false
&& m_config->opt_int("support_material_enforce_layers") == 0
&& m_config->opt_bool("exact_last_layer_height") == false
&& m_config->opt_bool("ensure_vertical_shell_thickness") == false
&& m_config->opt_bool("infill_dense") == false
&& m_config->opt_bool("extra_perimeters") == false
)) {
wxString msg_text = _(L("The Spiral Vase mode requires:\n"
"- one perimeter\n"
"- no top solid layers\n"
"- 0% fill density\n"
"- no support material\n"
"- no ensure_vertical_shell_thickness\n"
"- unchecked 'exact last layer height'\n"
"- unchecked 'dense infill'\n"
"- unchecked 'extra perimeters'\n"
"\nShall I adjust those settings in order to enable Spiral Vase?"));
wxMessageDialog dialog(parent(), msg_text, _(L("Spiral Vase")), wxICON_WARNING | wxYES | wxNO);
DynamicPrintConfig new_conf = *m_config;
if (dialog.ShowModal() == wxID_YES) {
new_conf.set_key_value("perimeters", new ConfigOptionInt(1));
new_conf.set_key_value("top_solid_layers", new ConfigOptionInt(0));
new_conf.set_key_value("fill_density", new ConfigOptionPercent(0));
new_conf.set_key_value("support_material", new ConfigOptionBool(false));
new_conf.set_key_value("support_material_enforce_layers", new ConfigOptionInt(0));
new_conf.set_key_value("exact_last_layer_height", new ConfigOptionBool(false));
new_conf.set_key_value("ensure_vertical_shell_thickness", new ConfigOptionBool(false));
new_conf.set_key_value("infill_dense", new ConfigOptionBool(false));
new_conf.set_key_value("extra_perimeters", new ConfigOptionBool(false));
fill_density = 0;
}
else {
new_conf.set_key_value("spiral_vase", new ConfigOptionBool(false));
}
load_config(new_conf);
on_value_change("fill_density", fill_density);
}
if (m_config->opt_bool("wipe_tower") && m_config->opt_bool("support_material") &&
((ConfigOptionEnumGeneric*)m_config->option("support_material_contact_distance_type"))->value != zdNone &&
(m_config->opt_int("support_material_extruder") != 0 || m_config->opt_int("support_material_interface_extruder") != 0)) {
wxString msg_text = _(L("The Wipe Tower currently supports the non-soluble supports only\n"
"if they are printed with the current extruder without triggering a tool change.\n"
"(both support_material_extruder and support_material_interface_extruder need to be set to 0).\n"
"\nShall I adjust those settings in order to enable the Wipe Tower?"));
wxMessageDialog dialog(parent(), msg_text, _(L("Wipe Tower")), wxICON_WARNING | wxYES | wxNO);
DynamicPrintConfig new_conf = *m_config;
if (dialog.ShowModal() == wxID_YES) {
new_conf.set_key_value("support_material_extruder", new ConfigOptionInt(0));
new_conf.set_key_value("support_material_interface_extruder", new ConfigOptionInt(0));
}
else
new_conf.set_key_value("wipe_tower", new ConfigOptionBool(false));
load_config(new_conf);
}
if (m_config->opt_bool("wipe_tower") && m_config->opt_bool("support_material") &&
((ConfigOptionEnumGeneric*)m_config->option("support_material_contact_distance_type"))->value == zdNone &&
!m_config->opt_bool("support_material_synchronize_layers")) {
wxString msg_text = _(L("For the Wipe Tower to work with the soluble supports, the support layers\n"
"need to be synchronized with the object layers.\n"
"\nShall I synchronize support layers in order to enable the Wipe Tower?"));
wxMessageDialog dialog(parent(), msg_text, _(L("Wipe Tower")), wxICON_WARNING | wxYES | wxNO);
DynamicPrintConfig new_conf = *m_config;
if (dialog.ShowModal() == wxID_YES) {
new_conf.set_key_value("support_material_synchronize_layers", new ConfigOptionBool(true));
}
else
new_conf.set_key_value("wipe_tower", new ConfigOptionBool(false));
load_config(new_conf);
}
if (m_config->opt_bool("support_material")) {
// Ask only once.
if (!m_support_material_overhangs_queried) {
m_support_material_overhangs_queried = true;
if (!m_config->opt_bool("overhangs")/* != 1*/) {
wxString msg_text = _(L("Supports work better, if the following feature is enabled:\n"
"- Detect bridging perimeters\n"
"\nShall I adjust those settings for supports?"));
wxMessageDialog dialog(parent(), msg_text, _(L("Support Generator")), wxICON_WARNING | wxYES | wxNO | wxCANCEL);
DynamicPrintConfig new_conf = *m_config;
auto answer = dialog.ShowModal();
if (answer == wxID_YES) {
// Enable "detect bridging perimeters".
new_conf.set_key_value("overhangs", new ConfigOptionBool(true));
} else if (answer == wxID_NO) {
// Do nothing, leave supports on and "detect bridging perimeters" off.
} else if (answer == wxID_CANCEL) {
// Disable supports.
new_conf.set_key_value("support_material", new ConfigOptionBool(false));
m_support_material_overhangs_queried = false;
}
load_config(new_conf);
}
}
}
else {
m_support_material_overhangs_queried = false;
}
if (m_config->option<ConfigOptionPercent>("fill_density")->value == 100) {
auto fill_pattern = m_config->option<ConfigOptionEnum<InfillPattern>>("fill_pattern")->value;
std::string str_fill_pattern = "";
t_config_enum_values map_names = m_config->option<ConfigOptionEnum<InfillPattern>>("fill_pattern")->get_enum_values();
for (auto it : map_names) {
if (fill_pattern == it.second) {
str_fill_pattern = it.first;
break;
}
}
if (!str_fill_pattern.empty()) {
bool correct_100p_fill = false;
const std::vector<std::string> top_fill_pattern = m_config->def()->get("top_fill_pattern")->enum_values;
for (const std::string &fill : top_fill_pattern)
{
if (str_fill_pattern == fill)
correct_100p_fill = true;
}
const std::vector<std::string> bottom_fill_pattern = m_config->def()->get("bottom_fill_pattern")->enum_values;
for (const std::string &fill : bottom_fill_pattern) {
if (str_fill_pattern.compare(fill) == 0)
correct_100p_fill = true;
}
// get fill_pattern name from enum_labels for using this one at dialog_msg
str_fill_pattern = _utf8(m_config->def()->get("fill_pattern")->enum_labels[fill_pattern]);
if (!correct_100p_fill) {
wxString msg_text = GUI::from_u8((boost::format(_utf8(L("The %1% infill pattern is not supposed to work at 100%% density.\n\n"
"Shall I switch to rectilinear fill pattern?"))) % str_fill_pattern).str());
wxMessageDialog dialog(parent(), msg_text, _(L("Infill")), wxICON_WARNING | wxYES | wxNO);
DynamicPrintConfig new_conf = *m_config;
if (dialog.ShowModal() == wxID_YES) {
new_conf.set_key_value("fill_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinear));
fill_density = 100;
}
else
fill_density = m_presets->get_selected_preset().config.option<ConfigOptionPercent>("fill_density")->value;
new_conf.set_key_value("fill_density", new ConfigOptionPercent(fill_density));
load_config(new_conf);
on_value_change("fill_density", fill_density);
}
}
}
bool have_perimeters = m_config->opt_int("perimeters") > 0;
for (auto el : { "extra_perimeters", "only_one_perimeter_top", "ensure_vertical_shell_thickness", "thin_walls", "overhangs",
"seam_position", "external_perimeters_first", "external_perimeter_extrusion_width",
"perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "perimeter_loop", "perimeter_loop_seam" })
get_field(el)->toggle(have_perimeters);
for (auto el : { "thin_walls_min_width", "thin_walls_overlap" }) get_field(el)->toggle(m_config->opt_bool("thin_walls"));
get_field("perimeter_loop_seam")->toggle(m_config->opt_bool("perimeter_loop"));
bool have_infill = m_config->option<ConfigOptionPercent>("fill_density")->value > 0;
// infill_extruder uses the same logic as in Print::extruders()
for (auto el : {"fill_pattern", "infill_every_layers", "infill_only_where_needed",
"solid_infill_every_layers", "solid_infill_below_area", "infill_extruder" })
get_field(el)->toggle(have_infill);
bool can_have_infill_dense = m_config->option<ConfigOptionPercent>("fill_density")->value < 50;
for (auto el : { "infill_dense" })
get_field(el)->toggle(can_have_infill_dense);
bool have_infill_dense = m_config->opt_bool("infill_dense") && can_have_infill_dense;
for (auto el : { "infill_dense_algo" })
get_field(el)->toggle(have_infill_dense);
bool have_solid_infill = m_config->opt_int("top_solid_layers") > 0 || m_config->opt_int("bottom_solid_layers") > 0;
// solid_infill_extruder uses the same logic as in Print::extruders()
for (auto el : { "top_fill_pattern", "bottom_fill_pattern", "solid_fill_pattern", "enforce_full_fill_volume", "external_infill_margin",
"infill_first", "solid_infill_extruder", "solid_infill_extrusion_width", "solid_infill_speed" })
get_field(el)->toggle(have_solid_infill);
for (auto el : {"fill_angle", "bridge_angle", "infill_extrusion_width",
"infill_speed", "bridge_speed" })
get_field(el)->toggle(have_infill || have_solid_infill);
get_field("gap_fill_speed")->toggle(have_perimeters && m_config->opt_bool("gap_fill"));
bool have_top_solid_infill = m_config->opt_int("top_solid_layers") > 0;
for (auto el : { "top_infill_extrusion_width", "top_solid_infill_speed" })
get_field(el)->toggle(have_top_solid_infill);
bool have_default_acceleration = m_config->opt_float("default_acceleration") > 0;
for (auto el : {"perimeter_acceleration", "infill_acceleration",
"bridge_acceleration", "first_layer_acceleration" })
get_field(el)->toggle(have_default_acceleration);
bool have_skirt = m_config->opt_int("skirts") > 0 || m_config->opt_float("min_skirt_length") > 0;
for (auto el : { "skirt_distance", "skirt_height" })
get_field(el)->toggle(have_skirt);
bool have_brim = m_config->opt_float("brim_width") > 0;
// perimeter_extruder uses the same logic as in Print::extruders()
get_field("perimeter_extruder")->toggle(have_perimeters || have_brim);
get_field("brim_ears")->toggle(have_brim);
get_field("brim_ears_max_angle")->toggle(have_brim && m_config->opt_bool("brim_ears"));
bool have_raft = m_config->opt_int("raft_layers") > 0;
bool have_support_material = m_config->opt_bool("support_material") || have_raft;
bool have_support_material_auto = have_support_material && m_config->opt_bool("support_material_auto");
bool have_support_interface = m_config->opt_int("support_material_interface_layers") > 0;
bool have_support_soluble = have_support_material && ((ConfigOptionEnumGeneric*)m_config->option("support_material_contact_distance_type"))->value == zdNone;
for (auto el : {"support_material_pattern", "support_material_with_sheath",
"support_material_spacing", "support_material_angle", "support_material_interface_layers",
"dont_support_bridges", "support_material_extrusion_width",
"support_material_contact_distance_type",
"support_material_xy_spacing", "support_material_interface_pattern" })
get_field(el)->toggle(have_support_material);
get_field("support_material_threshold")->toggle(have_support_material_auto);
for (auto el : { "support_material_contact_distance_top",
"support_material_contact_distance_bottom"})
get_field(el)->toggle(have_support_material && !have_support_soluble);
for (auto el : {"support_material_interface_spacing", "support_material_interface_extruder",
"support_material_interface_speed", "support_material_interface_contact_loops" })
get_field(el)->toggle(have_support_material && have_support_interface);
get_field("support_material_synchronize_layers")->toggle(have_support_soluble);
get_field("perimeter_extrusion_width")->toggle(have_perimeters || have_skirt || have_brim);
get_field("support_material_extruder")->toggle(have_support_material || have_skirt);
get_field("support_material_speed")->toggle(have_support_material || have_brim || have_skirt);
bool have_sequential_printing = m_config->opt_bool("complete_objects");
for (auto el : { "extruder_clearance_radius", "extruder_clearance_height" })
get_field(el)->toggle(have_sequential_printing);
bool have_ooze_prevention = m_config->opt_bool("ooze_prevention");
get_field("standby_temperature_delta")->toggle(have_ooze_prevention);
bool have_wipe_tower = m_config->opt_bool("wipe_tower");
for (auto el : { "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging"})
get_field(el)->toggle(have_wipe_tower);
*/
m_config_manipulation.update_print_fff_config(m_config, true);