diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 3d7f4e19d..e6336e2bf 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3968,6 +3968,7 @@ std::string GCode::set_extruder(unsigned int extruder_id, double print_z) old_retract_length_toolchange = m_config.retract_length_toolchange.get_at(previous_extruder_id); old_filament_temp = this->on_first_layer()? m_config.nozzle_temperature_initial_layer.get_at(previous_extruder_id) : m_config.nozzle_temperature.get_at(previous_extruder_id); wipe_volume = flush_matrix[previous_extruder_id * number_of_extruders + extruder_id]; + wipe_volume *= m_config.flush_multiplier; old_filament_e_feedrate = (int)(60.0 * m_config.filament_max_volumetric_speed.get_at(previous_extruder_id) / filament_area); old_filament_e_feedrate = old_filament_e_feedrate == 0 ? 100 : old_filament_e_feedrate; } diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index b1c5e37df..294dfd8f7 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -38,9 +38,7 @@ static std::vector s_project_options { "wipe_tower_y", "wipe_tower_rotation_angle", "curr_bed_type", -#if !BBL_RELEASE_TO_PUBLIC "flush_multiplier", -#endif }; //BBS: add BBL as default diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index ae1a7e8a0..ec4137d83 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -2024,23 +2024,22 @@ void Print::_make_wipe_tower() for (auto &layer_tools : m_wipe_tower_data.tool_ordering.layer_tools()) { // for all layers if (!layer_tools.has_wipe_tower) continue; bool first_layer = &layer_tools == &m_wipe_tower_data.tool_ordering.front(); - wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height, current_extruder_id, current_extruder_id, false); + wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height, current_extruder_id, current_extruder_id); for (const auto extruder_id : layer_tools.extruders) { // BBS: priming logic is removed, so no need to do toolchange for first extruder if (/*(first_layer && extruder_id == m_wipe_tower_data.tool_ordering.all_extruders().back()) || */extruder_id != current_extruder_id) { float volume_to_purge = wipe_volumes[current_extruder_id][extruder_id]; + volume_to_purge *= m_config.flush_multiplier; // Not all of that can be used for infill purging: //volume_to_purge -= (float)m_config.filament_minimal_purge_on_wipe_tower.get_at(extruder_id); - volume_to_purge -= (float)m_config.nozzle_volume; // try to assign some infills/objects for the wiping: volume_to_purge = layer_tools.wiping_extrusions().mark_wiping_extrusions(*this, current_extruder_id, extruder_id, volume_to_purge); // add back the minimal amount toforce on the wipe tower: //volume_to_purge += (float)m_config.filament_minimal_purge_on_wipe_tower.get_at(extruder_id); - volume_to_purge += (float)m_config.nozzle_volume; // request a toolchange at the wipe tower with at least volume_to_wipe purging amount wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height, diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 98ea532cb..b2c003d60 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2841,8 +2841,6 @@ void PrintConfigDef::init_fff_params() def->label = L("Flush multiplier"); def->tooltip = L("The actual flushing volumes is equal to the flush multiplier multiplied by the flushing volumes in the table."); def->sidetext = ""; - def->mode = comDevelop; - def->min = 0; def->set_default_value(new ConfigOptionFloat(1.0)); // BBS diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 15bea19b4..a02e4b52c 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -684,8 +684,8 @@ Sidebar::Sidebar(Plater *parent) const std::vector& init_extruders = (project_config.option("flush_volumes_vector"))->values; ConfigOption* extra_flush_volume_opt = printer_config.option("nozzle_volume"); int extra_flush_volume = extra_flush_volume_opt ? (int)extra_flush_volume_opt->getFloat() : 0; - std::string str_flush_multiplier = wxGetApp().app_config->get("flush_multiplier"); - float flush_multiplier = str_flush_multiplier.empty() ? 1.f : std::stof(str_flush_multiplier); + ConfigOptionFloat* flush_multi_opt = project_config.option("flush_multiplier"); + float flush_multiplier = flush_multi_opt ? flush_multi_opt->getFloat() : 1.f; const std::vector extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config(); @@ -696,9 +696,8 @@ Sidebar::Sidebar(Plater *parent) std::vector extruders = dlg.get_extruders(); (project_config.option("flush_volumes_matrix"))->values = std::vector(matrix.begin(), matrix.end()); (project_config.option("flush_volumes_vector"))->values = std::vector(extruders.begin(), extruders.end()); -#if !BBL_RELEASE_TO_PUBLIC (project_config.option("flush_multiplier"))->set(new ConfigOptionFloat(dlg.get_flush_multiplier())); -#endif + wxGetApp().app_config->set("flush_multiplier", std::to_string(dlg.get_flush_multiplier())); wxGetApp().preset_bundle->update_filament_info_to_app_config(*wxGetApp().app_config); diff --git a/src/slic3r/GUI/WipeTowerDialog.cpp b/src/slic3r/GUI/WipeTowerDialog.cpp index 88b9bab3c..87c86f477 100644 --- a/src/slic3r/GUI/WipeTowerDialog.cpp +++ b/src/slic3r/GUI/WipeTowerDialog.cpp @@ -15,7 +15,7 @@ using namespace Slic3r::GUI; int scale(const int val) { return val * Slic3r::GUI::wxGetApp().em_unit() / 10; } int ITEM_WIDTH() { return scale(30); } -static const wxColour text_color = wxColour(107, 107, 107, 255); +static const wxColour g_text_color = wxColour(107, 107, 107, 255); #define ICON_SIZE wxSize(FromDIP(16), FromDIP(16)) #define TABLE_BORDER FromDIP(28) @@ -44,9 +44,11 @@ static void update_ui(wxWindow* window) #define style wxSP_ARROW_KEYS #endif -static const int g_max_flush_volume = 750.f; +static const int m_max_flush_volume = 750.f; static const int g_min_flush_volume_from_support = 420.f; static const int g_flush_volume_to_support = 230; +static const float g_min_flush_multiplier = 0.f; +static const float g_max_flush_multiplier = 3.f; wxBoxSizer* WipingDialog::create_btn_sizer(long flags) { @@ -223,7 +225,7 @@ void WipingPanel::create_panels(wxWindow* parent, const int num) { // This panel contains all control widgets for both simple and advanced mode (these reside in separate sizers) WipingPanel::WipingPanel(wxWindow* parent, const std::vector& matrix, const std::vector& extruders, const std::vector& extruder_colours, wxButton* widget_button, int extra_flush_volume, float flush_multiplier) -: wxPanel(parent,wxID_ANY, wxDefaultPosition, wxDefaultSize/*,wxBORDER_RAISED*/), m_extra_flush_volume(extra_flush_volume) +: wxPanel(parent,wxID_ANY, wxDefaultPosition, wxDefaultSize/*,wxBORDER_RAISED*/), m_min_flush_volume(extra_flush_volume), m_max_flush_volume(800) { // BBS: toggle button is removed //m_widget_button = widget_button; // pointer to the button in parent dialog @@ -282,17 +284,8 @@ WipingPanel::WipingPanel(wxWindow* parent, const std::vector& matrix, con }); auto on_apply_text_modify = [this, i, j](wxEvent &e) { - wxString str = edit_boxes[i][j]->GetValue(); - int value = wxAtoi(str); - if (value < int(m_extra_flush_volume)) { - wxGetApp().plater(); - str = wxString::Format(("%d"), int(m_extra_flush_volume)); - edit_boxes[i][j]->SetValue(str); - MessageDialog dlg(nullptr, - _L("The flush volume is less than the minimum value and will be automatically set to the minimum value."), - _L("Warning"), wxICON_WARNING | wxOK); - dlg.ShowModal(); - } + this->update_warning_texts(); + e.Skip(); }; edit_boxes[i][j]->Bind(wxEVT_TEXT_ENTER, on_apply_text_modify); @@ -326,29 +319,57 @@ WipingPanel::WipingPanel(wxWindow* parent, const std::vector& matrix, con create_panels(m_page_advanced, m_number_of_extruders); - m_sizer_advanced->AddSpacer(BTN_SIZE.y); + m_sizer_advanced->AddSpacer(10); auto info_str = new wxStaticText(m_page_advanced, wxID_ANY, _(L("Flushing volume (mm³) for each filament pair.")), wxDefaultPosition, wxDefaultSize, 0); - info_str->SetForegroundColour(text_color); + info_str->SetForegroundColour(g_text_color); m_sizer_advanced->Add(info_str, 0, wxEXPAND | wxLEFT, TEXT_BEG_PADDING); m_sizer_advanced->AddSpacer(BTN_SIZE.y); // BBS: for tunning flush volumes { wxBoxSizer* param_sizer = new wxBoxSizer(wxHORIZONTAL); - param_sizer->AddSpacer(FromDIP(15)); - wxStaticText* flush_multiplier_title = new wxStaticText(m_page_advanced, wxID_ANY, _L("Flush multiplier")); + wxStaticText* flush_multiplier_title = new wxStaticText(m_page_advanced, wxID_ANY, _L("Multiplier")); param_sizer->Add(flush_multiplier_title); param_sizer->AddSpacer(FromDIP(5)); - m_flush_multiplier_ebox = new wxTextCtrl(m_page_advanced, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(50), -1)); + m_flush_multiplier_ebox = new wxTextCtrl(m_page_advanced, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(50), -1), wxTE_PROCESS_ENTER); char flush_multi_str[32] = { 0 }; snprintf(flush_multi_str, sizeof(flush_multi_str), "%.2f", flush_multiplier); m_flush_multiplier_ebox->SetValue(flush_multi_str); param_sizer->Add(m_flush_multiplier_ebox); param_sizer->AddStretchSpacer(1); - - m_sizer_advanced->Add(param_sizer, 0, wxTOP | wxBOTTOM, 10); + m_sizer_advanced->Add(param_sizer, 0, wxEXPAND | wxLEFT, TEXT_BEG_PADDING); + + auto multi_desc_label = new wxStaticText(m_page_advanced, wxID_ANY, _(L("Actual Volume = Flushing Volume * Multiplier")), wxDefaultPosition, wxDefaultSize, 0); + multi_desc_label->SetForegroundColour(g_text_color); + m_sizer_advanced->Add(multi_desc_label, 0, wxEXPAND | wxLEFT, TEXT_BEG_PADDING); + + wxString min_flush_str = wxString::Format(_L("Suggestion: Actual Volume in range [%d, %d]"), m_min_flush_volume, m_max_flush_volume); + m_min_flush_label = new wxStaticText(m_page_advanced, wxID_ANY, min_flush_str, wxDefaultPosition, wxDefaultSize, 0); + m_min_flush_label->SetForegroundColour(g_text_color); + m_sizer_advanced->Add(m_min_flush_label, 0, wxEXPAND | wxLEFT, TEXT_BEG_PADDING); + + auto on_apply_text_modify = [this](wxEvent& e) { + wxString str = m_flush_multiplier_ebox->GetValue(); + float multiplier = wxAtof(str); + if (multiplier < g_min_flush_multiplier || multiplier > g_max_flush_multiplier) { + str = wxString::Format(("%.2f"), multiplier < g_min_flush_multiplier ? g_min_flush_multiplier : g_max_flush_multiplier); + m_flush_multiplier_ebox->SetValue(str); + MessageDialog dlg(nullptr, + wxString::Format(_L("The flush multiplier should be in range [%.2f, %.2f]."), g_min_flush_multiplier, g_max_flush_multiplier), + _L("Warning"), wxICON_WARNING | wxOK); + dlg.ShowModal(); + } + + this->update_warning_texts(); + e.Skip(); + }; + m_flush_multiplier_ebox->Bind(wxEVT_TEXT_ENTER, on_apply_text_modify); + m_flush_multiplier_ebox->Bind(wxEVT_KILL_FOCUS, on_apply_text_modify); + + m_sizer_advanced->AddSpacer(10); } + this->update_warning_texts(); m_page_advanced->Hide(); @@ -501,9 +522,53 @@ int WipingPanel::calc_flushing_volume(const wxColour& from, const wxColour& to) float flush_volume = calc_triangle_3rd_edge(hs_flush, lumi_flush, 120.f); flush_volume = std::max(flush_volume, 60.f); - float flush_multiplier = std::atof(m_flush_multiplier_ebox->GetValue().c_str()); - flush_volume = (flush_volume + m_extra_flush_volume) * flush_multiplier; - return std::min((int)flush_volume, g_max_flush_volume); + //float flush_multiplier = std::atof(m_flush_multiplier_ebox->GetValue().c_str()); + flush_volume += m_min_flush_volume; + return std::min((int)flush_volume, m_max_flush_volume); +} + +void WipingPanel::update_warning_texts() +{ + static const wxColour g_warning_color = *wxRED; + static const wxColour g_normal_color = *wxBLACK; + + wxString multi_str = m_flush_multiplier_ebox->GetValue(); + float multiplier = wxAtof(multi_str); + + bool has_exception_flush = false; + for (int i = 0; i < edit_boxes.size(); i++) { + auto& box_vec = edit_boxes[i]; + for (int j = 0; j < box_vec.size(); j++) { + if (i == j) + continue; + + auto text_box = box_vec[j]; + wxString str = text_box->GetValue(); + int actual_volume = wxAtoi(str) * multiplier; + if (actual_volume < m_min_flush_volume || actual_volume > m_max_flush_volume) { + if (text_box->GetForegroundColour() != g_warning_color) { + text_box->SetForegroundColour(g_warning_color); + text_box->Refresh(); + } + has_exception_flush = true; + } + else { + if (text_box->GetForegroundColour() != g_normal_color) { + text_box->SetForegroundColour(g_normal_color); + text_box->Refresh(); + } + } + } + } + + if (has_exception_flush && m_min_flush_label->GetForegroundColour() != g_warning_color) { + m_min_flush_label->SetForegroundColour(g_warning_color); + m_min_flush_label->Refresh(); + } + else if (!has_exception_flush && m_min_flush_label->GetForegroundColour() != g_text_color) { + m_min_flush_label->SetForegroundColour(g_text_color); + m_min_flush_label->Refresh(); + } } void WipingPanel::calc_flushing_volumes() @@ -526,6 +591,9 @@ void WipingPanel::calc_flushing_volumes() return support_option->get_at(0); }; + // Calculate flush volumes for flush_multiplier 1.0 + m_flush_multiplier_ebox->SetValue("1.0"); + for (int from_idx = 0; from_idx < m_colours.size(); from_idx++) { const wxColour& from = m_colours[from_idx]; bool is_from_support = is_support_filament(from_idx); @@ -551,6 +619,8 @@ void WipingPanel::calc_flushing_volumes() } } } + + this->update_warning_texts(); } diff --git a/src/slic3r/GUI/WipeTowerDialog.hpp b/src/slic3r/GUI/WipeTowerDialog.hpp index f54d2888f..1ee4708c0 100644 --- a/src/slic3r/GUI/WipeTowerDialog.hpp +++ b/src/slic3r/GUI/WipeTowerDialog.hpp @@ -29,6 +29,7 @@ private: void fill_in_matrix(); bool advanced_matches_simple(); int calc_flushing_volume(const wxColour& from, const wxColour& to); + void update_warning_texts(); std::vector m_old; std::vector m_new; @@ -45,8 +46,11 @@ private: wxGridSizer* m_gridsizer_advanced = nullptr; wxButton* m_widget_button = nullptr; + const int m_min_flush_volume; + const int m_max_flush_volume; + wxTextCtrl* m_flush_multiplier_ebox = nullptr; - float m_extra_flush_volume = 0; + wxStaticText* m_min_flush_label = nullptr; };