diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index c9cdff162..48335fcb2 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -69,15 +69,26 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con double fill_density = config->option("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& external_fill_pattern = config->def()->get("top_fill_pattern")->enum_values; + const std::vector& 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 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("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("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); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index cc9c3f041..8b50a0113 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -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("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("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("fill_density")->value == 100) { - auto fill_pattern = m_config->option>("fill_pattern")->value; - std::string str_fill_pattern = ""; - t_config_enum_values map_names = m_config->option>("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 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 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(ipRectilinear)); - fill_density = 100; - } - else - fill_density = m_presets->get_selected_preset().config.option("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("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("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);