From ef3493d7ea7c64f953a3d164d40b33a3f0853bde Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 29 Nov 2023 16:52:53 +0100 Subject: [PATCH] WIP: SLA material overrides (UI part) --- src/libslic3r/Preset.cpp | 20 ++- src/libslic3r/PresetBundle.cpp | 2 + src/libslic3r/PrintConfig.cpp | 29 ++++ src/slic3r/GUI/OptionsGroup.hpp | 1 + src/slic3r/GUI/Search.cpp | 2 +- src/slic3r/GUI/Tab.cpp | 192 +++++++++++++++++++++++- src/slic3r/GUI/Tab.hpp | 6 + src/slic3r/GUI/UnsavedChangesDialog.cpp | 2 +- 8 files changed, 244 insertions(+), 10 deletions(-) diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 75dda312ef..2831900e06 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -606,7 +606,25 @@ static std::vector s_Preset_sla_material_options { "material_print_speed", "default_sla_material_profile", "compatible_prints", "compatible_prints_condition", - "compatible_printers", "compatible_printers_condition", "inherits" + "compatible_printers", "compatible_printers_condition", "inherits", + + // overriden options + "material_support_head_front_diameter", + "material_support_head_penetration", + "material_support_head_width", + "material_support_pillar_diameter", + + "material_branchingsupport_head_front_diameter", + "material_branchingsupport_head_penetration", + "material_branchingsupport_head_width", + "material_branchingsupport_pillar_diameter", + + "material_support_points_density_relative", + + "material_relative_correction_x", + "material_relative_correction_y", + "material_relative_correction_z", + "material_elefant_foot_compensation" }; static std::vector s_Preset_sla_printer_options { diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index 943e5e9f63..ae79f60db6 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -74,6 +74,8 @@ PresetBundle::PresetBundle() : 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(); 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"; diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 34e513f571..6285102d02 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -4301,6 +4301,35 @@ void PrintConfigDef::init_sla_params() def->min = float(SCALING_FACTOR); def->mode = comExpert; def->set_default_value(new ConfigOptionFloat(0.001)); + + // Declare retract values for material profile, overriding the print and printer profiles. + for (const char* opt_key : { + // float + "support_head_front_diameter", "branchingsupport_head_front_diameter", + "support_head_penetration", "branchingsupport_head_penetration", + "support_head_width", "branchingsupport_head_width", + "support_pillar_diameter", "branchingsupport_pillar_diameter", + "relative_correction_x", "relative_correction_y", "relative_correction_z", + "elefant_foot_compensation", + // int + "support_points_density_relative" + }) { + auto it_opt = options.find(opt_key); + assert(it_opt != options.end()); + def = this->add_nullable(std::string("material_") + opt_key, it_opt->second.type == coFloat ? coFloats : coInts); + def->label = it_opt->second.label; + def->full_label = it_opt->second.full_label; + def->tooltip = it_opt->second.tooltip; + def->sidetext = it_opt->second.sidetext; + def->min = it_opt->second.min; + def->max = it_opt->second.max; + def->mode = it_opt->second.mode; + switch (def->type) { + case coFloats: def->set_default_value(new ConfigOptionFloatsNullable{ it_opt->second.default_value->getFloat() }); break; + case coInts: def->set_default_value(new ConfigOptionIntsNullable { it_opt->second.default_value->getInt() }); break; + default: assert(false); + } + } } // Ignore the following obsolete configuration keys: diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp index ae500c5d32..683182ec9a 100644 --- a/src/slic3r/GUI/OptionsGroup.hpp +++ b/src/slic3r/GUI/OptionsGroup.hpp @@ -206,6 +206,7 @@ public: wxGridSizer* get_grid_sizer() { return m_grid_sizer; } const std::vector& get_lines() { return m_lines; } + Line* get_last_line() { return m_lines.empty() ? nullptr : &m_lines[m_lines.size()-1]; } bool is_legend_line(); // if we have to set the same control alignment for different option groups, // we have to set same max contrtol width to all of them diff --git a/src/slic3r/GUI/Search.cpp b/src/slic3r/GUI/Search.cpp index 35dec1f481..3febe895f6 100644 --- a/src/slic3r/GUI/Search.cpp +++ b/src/slic3r/GUI/Search.cpp @@ -122,7 +122,7 @@ void OptionsSearcher::append_options(DynamicPrintConfig* config, Preset::Type ty int cnt = 0; - if ( type != Preset::TYPE_FILAMENT && !PresetCollection::is_independent_from_extruder_number_option(opt_key) ) + if ( type != Preset::TYPE_FILAMENT && type != Preset::TYPE_SLA_MATERIAL && !PresetCollection::is_independent_from_extruder_number_option(opt_key) ) switch (config->option(opt_key)->type()) { case coInts: change_opt_key(opt_key, config, cnt); break; diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 3dbab1cd1d..0666b58b02 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -687,7 +687,7 @@ void Tab::init_options_list() m_options_list.clear(); for (const std::string& opt_key : m_config->keys()) - emplace_option(opt_key, m_type != Preset::TYPE_FILAMENT && !PresetCollection::is_independent_from_extruder_number_option(opt_key)); + emplace_option(opt_key, m_type != Preset::TYPE_FILAMENT && m_type != Preset::TYPE_SLA_MATERIAL && !PresetCollection::is_independent_from_extruder_number_option(opt_key)); } template @@ -1960,7 +1960,7 @@ void TabFilament::update_line_with_near_label_widget(ConfigOptionsGroupShp optgr field->toggle(is_checked); } -std::vector>> option_keys { +std::vector>> filament_overrides_option_keys { {"Travel lift", { "filament_retract_lift", "filament_travel_ramping_lift", @@ -1992,7 +1992,7 @@ void TabFilament::add_filament_overrides_page() const int extruder_idx = 0; // #ys_FIXME - for (const auto&[title, keys] : option_keys) { + for (const auto&[title, keys] : filament_overrides_option_keys) { ConfigOptionsGroupShp optgroup = page->new_optgroup(L(title)); for (const std::string& opt_key : keys) { create_line_with_near_label_widget(optgroup, opt_key, extruder_idx); @@ -2038,7 +2038,7 @@ void TabFilament::update_filament_overrides_page() || m_config->opt_float("filament_retract_lift", extruder_idx) > 0 ); - for (const auto&[title, keys] : option_keys) { + for (const auto&[title, keys] : filament_overrides_option_keys) { std::optional optgroup{get_option_group(page, title)}; if (!optgroup) { continue; @@ -5351,6 +5351,8 @@ void TabSLAMaterial::build() optgroup->append_line(line); + add_material_overrides_page(); + page = add_options_page(L("Notes"), "note"); optgroup = page->new_optgroup(L("Notes"), 0); optgroup->label_width = 0; @@ -5391,6 +5393,9 @@ void TabSLAMaterial::toggle_options() const Preset ¤t_printer = wxGetApp().preset_bundle->printers.get_edited_preset(); std::string model = current_printer.config.opt_string("printer_model"); m_config_manipulation.toggle_field("material_print_speed", model != "SL1"); + + if (m_active_page->title() == "Material Overrides") + update_material_overrides_page(); } void TabSLAMaterial::update() @@ -5412,13 +5417,14 @@ void TabSLAMaterial::update() static void add_options_into_line(ConfigOptionsGroupShp &optgroup, const std::vector> &prefixes, - const std::string &optkey) + const std::string &optkey, + const std::string &preprefix = std::string()) { - auto opt = optgroup->get_option(prefixes.front().first + optkey); + auto opt = optgroup->get_option(preprefix + prefixes.front().first + optkey); Line line{ opt.opt.label, "" }; line.full_width = 1; for (auto &prefix : prefixes) { - opt = optgroup->get_option(prefix.first + optkey); + opt = optgroup->get_option(preprefix + prefix.first + optkey); opt.opt.label = prefix.second; opt.opt.width = 12; // TODO line.append_option(opt); @@ -5464,6 +5470,178 @@ void TabSLAPrint::build_sla_support_params(const std::vector get_override_opt_kyes_for_line(const std::string& title, const std::string& key) +{ + const std::string preprefix = "material_"; + + std::vector opt_keys; + opt_keys.reserve(3); + + if (title == "Support head" || title == "Support pillar") { + for (auto& prefix : { "", "branching" }) + opt_keys.push_back(preprefix + prefix + key); + } + else if (key == "relative_correction") { + for (auto& axis : { "x", "y", "z" }) + opt_keys.push_back(preprefix + key + "_" + char(axis[0])); + } + else + opt_keys.push_back(preprefix + key); + + return opt_keys; +} + +void TabSLAMaterial::create_line_with_near_label_widget(ConfigOptionsGroupShp optgroup, const std::string& key) +{ + if (optgroup->title == "Support head" || optgroup->title == "Support pillar") + add_options_into_line(optgroup, { {"", L("Default")}, {"branching", L("Branching")} }, key, "material_"); + else { + const std::string opt_key = std::string("material_") + key; + if (key == "relative_correction") { + Line line = Line{ m_preset_bundle->printers.get_edited_preset().config.def()->get("relative_correction")->full_label, "" }; + for (auto& axis : { "X", "Y", "Z" }) { + auto opt = optgroup->get_option(opt_key + "_" + char(std::tolower(axis[0]))); + opt.opt.label = axis; + line.append_option(opt); + } + optgroup->append_line(line); + } + else + optgroup->append_single_option_line(opt_key); + } + + Line* line = optgroup->get_last_line(); + if (!line) + return; + + line->near_label_widget = [this, optgroup_wk = ConfigOptionsGroupWkp(optgroup), key](wxWindow* parent) { + wxWindow* check_box = CheckBox::GetNewWin(parent); + wxGetApp().UpdateDarkUI(check_box); + + check_box->Bind(wxEVT_CHECKBOX, [optgroup_wk, key](wxCommandEvent& evt) { + const bool is_checked = evt.IsChecked(); + if (auto optgroup_sh = optgroup_wk.lock(); optgroup_sh) { + auto opt_keys = get_override_opt_kyes_for_line(optgroup_sh->title.ToStdString(), key); + for (const std::string& opt_key : opt_keys) + if (Field* field = optgroup_sh->get_fieldc(opt_key, 0); field != nullptr) { + field->toggle(is_checked); + if (is_checked) + field->set_last_meaningful_value(); + else + field->set_na_value(); + } + } + }); + + m_overrides_options[key] = check_box; + return check_box; + }; +} + +std::vector>> material_overrides_option_keys{ + {"Support head", { + "support_head_front_diameter", + "support_head_penetration", + "support_head_width" + }}, + {"Support pillar", { + "support_pillar_diameter", + }}, + {"Automatic generation", { + "support_points_density_relative" + }}, + {"Corrections", { + "relative_correction", + "elefant_foot_compensation" + }} +}; + +void TabSLAMaterial::add_material_overrides_page() +{ + PageShp page = add_options_page(L("Material Overrides"), "wrench"); + + for (const auto& [title, keys] : material_overrides_option_keys) { + ConfigOptionsGroupShp optgroup = page->new_optgroup(L(title)); + for (const std::string& opt_key : keys) { + create_line_with_near_label_widget(optgroup, opt_key); + } + } +} + +void TabSLAMaterial::update_line_with_near_label_widget(ConfigOptionsGroupShp optgroup, const std::string& key, bool is_checked/* = true*/) +{ + if (!m_overrides_options[key]) + return; + + const std::string preprefix = "material_"; + + std::vector opt_keys; + opt_keys.reserve(3); + + if (optgroup->title == "Support head" || optgroup->title == "Support pillar") { + for (auto& prefix : { "", "branching" }) { + std::string opt_key = preprefix + prefix + key; + is_checked &= !m_config->option(opt_key)->is_nil(); + opt_keys.push_back(opt_key); + } + } + else if (key == "relative_correction") { + for (auto& axis : { "x", "y", "z" }) { + std::string opt_key = preprefix + key + "_" + char(axis[0]); + is_checked &= !m_config->option(opt_key)->is_nil(); + opt_keys.push_back(opt_key); + } + } + else { + std::string opt_key = preprefix + key; + is_checked &= !m_config->option(opt_key)->is_nil(); + opt_keys.push_back(opt_key); + } + +// m_overrides_options[key]->Enable(is_checked); + + CheckBox::SetValue(m_overrides_options[key], is_checked); + + for (const std::string& opt_key : opt_keys) { + Field* field = optgroup->get_field(opt_key); + if (field != nullptr) + field->toggle(is_checked); + } +} + +void TabSLAMaterial::update_material_overrides_page() +{ + if (!m_active_page || m_active_page->title() != "Material Overrides") + return; + Page* page = m_active_page; + + for (const auto& [title, keys] : material_overrides_option_keys) { + std::optional optgroup{ get_option_group(page, title) }; + if (!optgroup) { + continue; + } + + for (const std::string& key : keys) { + update_line_with_near_label_widget(*optgroup, key, false); + continue; + + bool is_checked{ true }; + + const static std::string preprefix = "material_"; + if (title == "Support head" || title == "Support pillar") { + for (auto& prefix : { "", "branching" }) + update_line_with_near_label_widget(*optgroup, preprefix + prefix + key, is_checked); + } + else if (key == "relative_correction") { + for (auto& axis : { "x", "y", "z" }) + update_line_with_near_label_widget(*optgroup, preprefix + key + "_" + char(axis[0]), is_checked); + } + else + update_line_with_near_label_widget(*optgroup, preprefix + key, is_checked); + } + } +} + void TabSLAPrint::build() { m_presets = &m_preset_bundle->sla_prints; diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 1ee13905a1..505c47b199 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -566,6 +566,12 @@ public: class TabSLAMaterial : public Tab { + void create_line_with_near_label_widget(ConfigOptionsGroupShp optgroup, const std::string& opt_key); + void update_line_with_near_label_widget(ConfigOptionsGroupShp optgroup, const std::string& opt_key, bool is_checked = true); + void add_material_overrides_page(); + void update_material_overrides_page(); + + std::map m_overrides_options; public: TabSLAMaterial(wxBookCtrlBase* parent) : Tab(parent, _(L("Material Settings")), Slic3r::Preset::TYPE_SLA_MATERIAL) {} diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp index 43239561c3..ad3dbb6641 100644 --- a/src/slic3r/GUI/UnsavedChangesDialog.cpp +++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp @@ -1289,7 +1289,7 @@ void UnsavedChangesDialog::update_tree(Preset::Type type, PresetCollection* pres m_tree->model->AddPreset(type, from_u8(presets->get_edited_preset().name), old_pt, from_u8(new_selected_preset)); // Collect dirty options. - const bool deep_compare = type != Preset::TYPE_FILAMENT; + const bool deep_compare = type != Preset::TYPE_FILAMENT && type != Preset::TYPE_SLA_MATERIAL; auto dirty_options = presets->current_dirty_options(deep_compare); // process changes of extruders count