diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index 4e5904e88a..8df2d2202d 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -1529,12 +1529,22 @@ void Layer::make_ironing() if (ironing_params.extruder != -1) { //TODO just_infill is currently not used. ironing_params.just_infill = false; - ironing_params.line_spacing = config.ironing_spacing; - ironing_params.inset = config.ironing_inset; - ironing_params.height = default_layer_height * 0.01 * config.ironing_flow; - ironing_params.speed = config.ironing_speed; + // Get filament-specific overrides if configured, otherwise use default values + size_t extruder_idx = ironing_params.extruder - 1; + ironing_params.line_spacing = (!config.filament_ironing_spacing.is_nil(extruder_idx) + ? config.filament_ironing_spacing.get_at(extruder_idx) + : config.ironing_spacing); + ironing_params.inset = (!config.filament_ironing_inset.is_nil(extruder_idx) + ? config.filament_ironing_inset.get_at(extruder_idx) + : config.ironing_inset); + ironing_params.height = default_layer_height * 0.01 * (!config.filament_ironing_flow.is_nil(extruder_idx) + ? config.filament_ironing_flow.get_at(extruder_idx) + : config.ironing_flow); + ironing_params.speed = (!config.filament_ironing_speed.is_nil(extruder_idx) + ? config.filament_ironing_speed.get_at(extruder_idx) + : config.ironing_speed); ironing_params.angle = (config.ironing_angle_fixed ? 0 : calculate_infill_rotation_angle(this->object(), this->id(), config.solid_infill_direction.value, config.solid_infill_rotate_template.value)) + config.ironing_angle * M_PI / 180.; - ironing_params.fixed_angle = config.ironing_angle_fixed || !config.solid_infill_rotate_template.value.empty(); + ironing_params.fixed_angle = config.ironing_angle_fixed || !config.solid_infill_rotate_template.value.empty(); ironing_params.pattern = config.ironing_pattern; ironing_params.layerm = layerm; by_extruder.emplace_back(ironing_params); diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 08dc5de794..f024189b6a 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -974,6 +974,8 @@ static std::vector s_Preset_filament_options {/*"filament_colour", //SoftFever "enable_pressure_advance", "pressure_advance","adaptive_pressure_advance","adaptive_pressure_advance_model","adaptive_pressure_advance_overhangs", "adaptive_pressure_advance_bridges","chamber_temperature", "filament_shrink","filament_shrinkage_compensation_z", "support_material_interface_fan_speed","internal_bridge_fan_speed", "filament_notes" /*,"filament_seam_gap"*/, "ironing_fan_speed", + // Filament ironing overrides + "filament_ironing_flow", "filament_ironing_spacing", "filament_ironing_inset", "filament_ironing_speed", "filament_loading_speed", "filament_loading_speed_start", "filament_unloading_speed", "filament_unloading_speed_start", "filament_toolchange_delay", "filament_cooling_moves", "filament_stamping_loading_speed", "filament_stamping_distance", "filament_cooling_initial_speed", "filament_cooling_final_speed", "filament_ramming_parameters", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 7496af5091..77b4a6aa81 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -3147,6 +3147,50 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionInts{ -1 }); + // Filament ironing overrides + def = this->add("filament_ironing_flow", coPercents); + def->label = L("Ironing flow"); + def->tooltip = L("Filament-specific override for ironing flow. This allows you to customize the ironing flow " + "for each filament type. Too high value results in overextrusion on the surface."); + def->sidetext = "%"; + def->min = 0; + def->max = 100; + def->mode = comAdvanced; + def->nullable = true; + def->set_default_value(new ConfigOptionPercentsNullable{ ConfigOptionPercentsNullable::nil_value() }); + + def = this->add("filament_ironing_spacing", coFloats); + def->label = L("Ironing line spacing"); + def->tooltip = L("Filament-specific override for ironing line spacing. This allows you to customize the spacing " + "between ironing lines for each filament type."); + def->sidetext = "mm"; + def->min = 0; + def->max = 1; + def->mode = comAdvanced; + def->nullable = true; + def->set_default_value(new ConfigOptionFloatsNullable{ ConfigOptionFloatsNullable::nil_value() }); + + def = this->add("filament_ironing_inset", coFloats); + def->label = L("Ironing inset"); + def->tooltip = L("Filament-specific override for ironing inset. This allows you to customize the distance to keep " + "from the edges when ironing for each filament type."); + def->sidetext = "mm"; + def->min = 0; + def->max = 100; + def->mode = comAdvanced; + def->nullable = true; + def->set_default_value(new ConfigOptionFloatsNullable{ ConfigOptionFloatsNullable::nil_value() }); + + def = this->add("filament_ironing_speed", coFloats); + def->label = L("Ironing speed"); + def->tooltip = L("Filament-specific override for ironing speed. This allows you to customize the print speed " + "of ironing lines for each filament type."); + def->sidetext = "mm/s"; + def->min = 1; + def->mode = comAdvanced; + def->nullable = true; + def->set_default_value(new ConfigOptionFloatsNullable{ ConfigOptionFloatsNullable::nil_value() }); + def = this->add("fuzzy_skin", coEnum); def->label = L("Fuzzy Skin"); def->category = L("Others"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index a36cc21c51..0360b369cc 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1085,6 +1085,11 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloat, ironing_speed)) ((ConfigOptionFloat, ironing_angle)) ((ConfigOptionBool, ironing_angle_fixed)) + // Filament Ironing + ((ConfigOptionPercentsNullable, filament_ironing_flow)) + ((ConfigOptionFloatsNullable, filament_ironing_spacing)) + ((ConfigOptionFloatsNullable, filament_ironing_inset)) + ((ConfigOptionFloatsNullable, filament_ironing_speed)) // Detect bridging perimeters ((ConfigOptionBool, detect_overhang_wall)) ((ConfigOptionInt, wall_filament)) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index cbb7889182..7a9a1ac39b 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -39,6 +39,7 @@ #include "UnsavedChangesDialog.hpp" #include "SavePresetDialog.hpp" #include "EditGCodeDialog.hpp" + #include "MsgDialog.hpp" #include "Notebook.hpp" @@ -3546,15 +3547,16 @@ void TabFilament::add_filament_overrides_page() { //BBS PageShp page = add_options_page(L("Setting Overrides"), "custom-gcode_setting_override"); // ORCA: icon only visible on placeholders - ConfigOptionsGroupShp optgroup = page->new_optgroup(L("Retraction"), L"param_retraction"); - auto append_single_option_line = [optgroup, this](const std::string& opt_key, int opt_index) + const int extruder_idx = 0; // #ys_FIXME + + ConfigOptionsGroupShp retraction_optgroup = page->new_optgroup(L("Retraction"), L"param_retraction"); + auto append_retraction_option = [this, retraction_optgroup](const std::string& opt_key, int opt_index) { Line line {"",""}; - //BBS - line = optgroup->create_single_option_line(optgroup->get_option(opt_key)); + line = retraction_optgroup->create_single_option_line(retraction_optgroup->get_option(opt_key)); - line.near_label_widget = [this, optgroup_wk = ConfigOptionsGroupWkp(optgroup), opt_key, opt_index](wxWindow* parent) { + line.near_label_widget = [this, optgroup_wk = ConfigOptionsGroupWkp(retraction_optgroup), opt_key, opt_index](wxWindow* parent) { auto check_box = new ::CheckBox(parent); // ORCA modernize checkboxes check_box->Bind(wxEVT_TOGGLEBUTTON, [this, optgroup_wk, opt_key, opt_index](wxCommandEvent& evt) { const bool is_checked = evt.IsChecked(); @@ -3565,8 +3567,7 @@ void TabFilament::add_filament_overrides_page() if (is_checked) { field->update_na_value(_(L("N/A"))); field->set_last_meaningful_value(); - } - else { + } else { const std::string printer_opt_key = opt_key.substr(strlen("filament_")); const auto printer_config = m_preset_bundle->printers.get_edited_preset().config; const boost::any printer_config_value = optgroup_sh->get_config_value(printer_config, printer_opt_key, opt_index); @@ -3581,11 +3582,9 @@ void TabFilament::add_filament_overrides_page() return check_box; }; - optgroup->append_line(line); + retraction_optgroup->append_line(line); }; - const int extruder_idx = 0; // #ys_FIXME - for (const std::string opt_key : { "filament_retraction_length", "filament_z_hop", "filament_z_hop_types", @@ -3606,7 +3605,93 @@ void TabFilament::add_filament_overrides_page() //SoftFever // "filament_seam_gap" }) - append_single_option_line(opt_key, extruder_idx); + append_retraction_option(opt_key, extruder_idx); + + ConfigOptionsGroupShp ironing_optgroup = page->new_optgroup(L("Ironing"), L"param_ironing"); + auto append_ironing_option = [this, ironing_optgroup](const std::string& opt_key, int opt_index) + { + Line line {"",""}; + line = ironing_optgroup->create_single_option_line(ironing_optgroup->get_option(opt_key)); + + line.near_label_widget = [this, optgroup_wk = ConfigOptionsGroupWkp(ironing_optgroup), opt_key, opt_index](wxWindow* parent) { + auto check_box = new ::CheckBox(parent); // ORCA modernize checkboxes + check_box->Bind(wxEVT_TOGGLEBUTTON, [this, optgroup_wk, opt_key, opt_index](wxCommandEvent& evt) { + const bool is_checked = evt.IsChecked(); + if (auto optgroup_sh = optgroup_wk.lock(); optgroup_sh) { + if (Field *field = optgroup_sh->get_fieldc(opt_key, opt_index); field != nullptr) { + field->toggle(is_checked); + + const std::string process_opt_key = opt_key.substr(strlen("filament_")); + const auto process_config = m_preset_bundle->prints.get_edited_preset().config; + const ConfigOption *process_option = process_config.option(process_opt_key); + const auto *process_vector = dynamic_cast(process_option); + const size_t target_index = opt_index < 0 ? 0 : static_cast(opt_index); + bool has_process_value = process_option != nullptr; + if (has_process_value) { + if (process_vector != nullptr) { + has_process_value = target_index < process_vector->size() && !process_vector->is_nil(target_index); + } else { + has_process_value = !process_option->is_nil(); + } + } + + if (is_checked) { + bool applied_value = false; + if (has_process_value && process_option != nullptr) { + if (ConfigOption *filament_option = m_config->option(opt_key)) { + if (auto filament_vector = dynamic_cast(filament_option)) { + std::unique_ptr process_clone(process_option->clone()); + size_t source_index = 0; + if (process_vector != nullptr) + source_index = target_index; + + filament_vector->set_at(process_clone.get(), target_index, source_index); + + const boost::any filament_config_value = optgroup_sh->get_config_value(*m_config, opt_key, opt_index); + field->set_value(filament_config_value, false); + field->update_na_value(_(L("N/A"))); + applied_value = true; + } + } + } + + if (applied_value) + field->set_last_meaningful_value(); + else { + field->update_na_value(_(L("N/A"))); + field->set_na_value(); + } + } else { + if (has_process_value) { + const boost::any process_config_value = optgroup_sh->get_config_value(process_config, process_opt_key, opt_index); + field->update_na_value(process_config_value); + } else { + field->update_na_value(_(L("N/A"))); + } + field->set_na_value(); + + if (ConfigOption *filament_option = m_config->option(opt_key)) { + if (auto filament_vector = dynamic_cast(filament_option)) + filament_vector->set_at_to_nil(target_index); + } + } + } + } + }, check_box->GetId()); + + m_overrides_options[opt_key] = check_box; + return check_box; + }; + + ironing_optgroup->append_line(line); + }; + + for (const std::string opt_key : { "filament_ironing_flow", + "filament_ironing_spacing", + "filament_ironing_inset", + "filament_ironing_speed" + }) + append_ironing_option(opt_key, extruder_idx); } void TabFilament::update_filament_overrides_page(const DynamicPrintConfig* printers_config) @@ -3688,6 +3773,44 @@ void TabFilament::update_filament_overrides_page(const DynamicPrintConfig* print field->toggle(is_checked); } } + + // Handle ironing overrides + const auto og_ironing_it = std::find_if(page->m_optgroups.begin(), page->m_optgroups.end(), [](const ConfigOptionsGroupShp og) { return og->title == "Ironing"; }); + if (og_ironing_it != page->m_optgroups.end()) + { + ConfigOptionsGroupShp ironing_optgroup = *og_ironing_it; + + std::vector ironing_opt_keys = { + "filament_ironing_flow", + "filament_ironing_spacing", + "filament_ironing_inset", + "filament_ironing_speed" + }; + + for (const std::string& opt_key : ironing_opt_keys) + { + if (m_overrides_options.find(opt_key) == m_overrides_options.end()) + continue; + + bool is_checked = !dynamic_cast(m_config->option(opt_key))->is_nil(extruder_idx); + m_overrides_options[opt_key]->Enable(true); + m_overrides_options[opt_key]->SetValue(is_checked); + + Field* field = ironing_optgroup->get_fieldc(opt_key, 0); + if (field == nullptr) continue; + + if (!is_checked) { + // Get the default value from the process config (ironing_* without filament_ prefix) + const std::string process_opt_key = opt_key.substr(strlen("filament_")); + const auto process_config = m_preset_bundle->prints.get_edited_preset().config; + const boost::any process_config_value = ironing_optgroup->get_config_value(process_config, process_opt_key, 0); + field->update_na_value(process_config_value); + field->set_value(process_config_value, false); + } + + field->toggle(is_checked); + } + } } void TabFilament::build()