diff --git a/resources/calib/input_shaping/ringing_tower.stl b/resources/calib/input_shaping/ringing_tower.stl new file mode 100644 index 0000000000..70cae09ea6 Binary files /dev/null and b/resources/calib/input_shaping/ringing_tower.stl differ diff --git a/src/libslic3r/calib.hpp b/src/libslic3r/calib.hpp index 18cc583b62..f83631ac04 100644 --- a/src/libslic3r/calib.hpp +++ b/src/libslic3r/calib.hpp @@ -14,7 +14,8 @@ enum class CalibMode : int { Calib_Temp_Tower, Calib_Vol_speed_Tower, Calib_VFA_Tower, - Calib_Retraction_tower + Calib_Retraction_tower, + Calib_Input_shaping }; struct Calib_Params diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 27cc5d729b..ddc1878661 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -2651,6 +2651,16 @@ void MainFrame::init_menubar_as_editor() }, "", nullptr, [this]() {return m_plater->is_view3D_shown();; }, this); + + append_menu_item( + advance_menu, wxID_ANY, _L("Input Shaping"), _L("Input Shaping"), + [this](wxCommandEvent&) { + if (!m_IS_calib_dlg) + m_IS_calib_dlg = new Input_Shaping_Test_Dlg((wxWindow*)this, wxID_ANY, m_plater); + m_IS_calib_dlg->ShowModal(); + }, + "", nullptr, + [this]() {return m_plater->is_view3D_shown();; }, this); m_topbar->GetCalibMenu()->AppendSubMenu(advance_menu, _L("More...")); // help @@ -2726,6 +2736,16 @@ void MainFrame::init_menubar_as_editor() m_vfa_test_dlg->ShowModal(); }, "", nullptr, [this]() {return m_plater->is_view3D_shown();; }, this); + + append_menu_item( + advance_menu, wxID_ANY, _L("Input Shaping"), _L("Input Shaping"), + [this](wxCommandEvent&) { + if (!m_IS_calib_dlg) + m_IS_calib_dlg = new Input_Shaping_Test_Dlg((wxWindow*)this, wxID_ANY, m_plater); + m_IS_calib_dlg->ShowModal(); + }, "", nullptr, + [this]() {return m_plater->is_view3D_shown();; }, this); + append_submenu(calib_menu, advance_menu, wxID_ANY, _L("More..."), _L("More calibrations"), "", [this]() {return m_plater->is_view3D_shown();; }); // help diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 6550efa882..9350ea09c8 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -342,6 +342,7 @@ public: MaxVolumetricSpeed_Test_Dlg* m_vol_test_dlg { nullptr }; VFA_Test_Dlg* m_vfa_test_dlg { nullptr }; Retraction_Test_Dlg* m_retraction_calib_dlg{ nullptr }; + Input_Shaping_Test_Dlg* m_IS_calib_dlg{ nullptr }; // BBS. Replace title bar and menu bar with top bar. BBLTopbar* m_topbar{ nullptr }; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index cd5baa548c..05ad8a9712 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -8450,6 +8450,48 @@ void Plater::calib_VFA(const Calib_Params& params) p->background_process.fff_print()->set_calib_params(params); } + +void Plater::calib_input_shaping(const Calib_Params& params) +{ + const auto calib_vfa_name = wxString::Format(L"Input shaping test"); + new_project(false, false, calib_vfa_name); + wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor)); + if (params.mode != CalibMode::Calib_Input_shaping) + return; + + add_model(false, Slic3r::resources_dir() + "/calib/input_shaping/ringing_tower.stl"); + auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; + auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config; + filament_config->set_key_value("slow_down_layer_time", new ConfigOptionFloats { 2.0 }); + filament_config->set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats { 200 }); + print_config->set_key_value("enable_overhang_speed", new ConfigOptionBool { false }); + print_config->set_key_value("timelapse_type", new ConfigOptionEnum(tlTraditional)); + print_config->set_key_value("wall_loops", new ConfigOptionInt(1)); + print_config->set_key_value("top_shell_layers", new ConfigOptionInt(0)); + print_config->set_key_value("bottom_shell_layers", new ConfigOptionInt(1)); + print_config->set_key_value("sparse_infill_density", new ConfigOptionPercent(0)); + print_config->set_key_value("spiral_mode", new ConfigOptionBool(true)); + model().objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum(btOuterOnly)); + model().objects[0]->config.set_key_value("brim_width", new ConfigOptionFloat(3.0)); + model().objects[0]->config.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0)); + + changed_objects({ 0 }); + wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty(); + wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty(); + wxGetApp().get_tab(Preset::TYPE_PRINT)->update_ui_from_settings(); + wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_ui_from_settings(); + + // cut upper +// auto obj_bb = model().objects[0]->bounding_box(); +// auto height = 5 * ((params.end - params.start) / params.step + 1); +// if (height < obj_bb.size().z()) { +// std::array plane_pts = get_cut_plane(obj_bb, height); +// cut(0, 0, plane_pts, ModelObjectCutAttribute::KeepLower); +// } + +// p->background_process.fff_print()->set_calib_params(params); +} + BuildVolume_Type Plater::get_build_volume_type() const { return p->bed.get_build_volume_type(); } void Plater::import_sl1_archive() { diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 33ea0e7b20..02004f4c41 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -239,6 +239,7 @@ public: void calib_max_vol_speed(const Calib_Params& params); void calib_retraction(const Calib_Params& params); void calib_VFA(const Calib_Params& params); + void calib_input_shaping(const Calib_Params& params); BuildVolume_Type get_build_volume_type() const; diff --git a/src/slic3r/GUI/calib_dlg.cpp b/src/slic3r/GUI/calib_dlg.cpp index 14fdc6b143..c0bddf8028 100644 --- a/src/slic3r/GUI/calib_dlg.cpp +++ b/src/slic3r/GUI/calib_dlg.cpp @@ -628,7 +628,7 @@ Retraction_Test_Dlg::Retraction_Test_Dlg(wxWindow* parent, wxWindowID id, Plater auto end_length_sizer = new wxBoxSizer(wxHORIZONTAL); auto end_length_text = new wxStaticText(this, wxID_ANY, end_length_str, wxDefaultPosition, st_size, wxALIGN_LEFT); m_tiEnd = new TextInput(this, std::to_string(2), _L("mm"), "", wxDefaultPosition, ti_size, wxTE_CENTRE); - m_tiStart->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + m_tiEnd->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); end_length_sizer->Add(end_length_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); end_length_sizer->Add(m_tiEnd, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); settings_sizer->Add(end_length_sizer); @@ -695,5 +695,121 @@ void Retraction_Test_Dlg::on_dpi_changed(const wxRect& suggested_rect) { } +// Input_Shaping_Test_Dlg +// + +Input_Shaping_Test_Dlg::Input_Shaping_Test_Dlg(wxWindow* parent, wxWindowID id, Plater* plater) + : DPIDialog(parent, id, _L("Input shaping test"), wxDefaultPosition, parent->FromDIP(wxSize(-1, 280)), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), m_plater(plater) +{ + wxBoxSizer* v_sizer = new wxBoxSizer(wxVERTICAL); + SetSizer(v_sizer); + + // Settings + // + wxString start_length_str = _L("X Start: "); + wxString end_length_str = _L("X End: "); + wxString length_step_str = _L("step: "); + auto text_size = wxWindow::GetTextExtent(start_length_str); + text_size.IncTo(wxWindow::GetTextExtent(end_length_str)); + text_size.IncTo(wxWindow::GetTextExtent(length_step_str)); + text_size.x = text_size.x * 1.5; + wxStaticBoxSizer* settings_sizer = new wxStaticBoxSizer(wxVERTICAL, this, _L("Frequency settings")); + + auto st_size = FromDIP(wxSize(text_size.x, -1)); + auto ti_size = FromDIP(wxSize(90, -1)); + // X + auto start_length_sizer = new wxBoxSizer(wxHORIZONTAL); + auto start_length_text = new wxStaticText(this, wxID_ANY, start_length_str, wxDefaultPosition, st_size, wxALIGN_LEFT); + m_tiStartX = new TextInput(this, std::to_string(20), _L("HZ"), "", wxDefaultPosition, ti_size, wxTE_CENTRE); + m_tiStartX->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + auto end_length_text = new wxStaticText(this, wxID_ANY, end_length_str, wxDefaultPosition, st_size, wxALIGN_LEFT); + m_tiEndX = new TextInput(this, std::to_string(50), _L("HZ"), "", wxDefaultPosition, ti_size, wxTE_CENTRE); + m_tiEndX->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + + start_length_sizer->Add(start_length_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); + start_length_sizer->Add(m_tiStartX, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); + start_length_sizer->Add(end_length_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); + start_length_sizer->Add(m_tiEndX, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); + settings_sizer->Add(start_length_sizer); + + // Y + start_length_str = _L("Y Start: "); + end_length_str = _L("Y End: "); + start_length_sizer = new wxBoxSizer(wxHORIZONTAL); + start_length_text = new wxStaticText(this, wxID_ANY, start_length_str, wxDefaultPosition, st_size, wxALIGN_LEFT); + m_tiStartY = new TextInput(this, std::to_string(20), _L("HZ"), "", wxDefaultPosition, ti_size, wxTE_CENTRE); + m_tiStartY->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + end_length_text = new wxStaticText(this, wxID_ANY, end_length_str, wxDefaultPosition, st_size, wxALIGN_LEFT); + m_tiEndY = new TextInput(this, std::to_string(50), _L("HZ"), "", wxDefaultPosition, ti_size, wxTE_CENTRE); + m_tiEndY->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + + start_length_sizer->Add(start_length_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); + start_length_sizer->Add(m_tiStartY, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); + start_length_sizer->Add(end_length_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); + start_length_sizer->Add(m_tiEndY, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); + settings_sizer->Add(start_length_sizer); + + + // length step + auto length_step_sizer = new wxBoxSizer(wxHORIZONTAL); + auto length_step_text = new wxStaticText(this, wxID_ANY, length_step_str, wxDefaultPosition, st_size, wxALIGN_LEFT); + m_tiStep = new TextInput(this, wxString::FromDouble(0.1), _L("HZ"), "", wxDefaultPosition, ti_size, wxTE_CENTRE); + m_tiStartX->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + length_step_sizer->Add(length_step_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); + length_step_sizer->Add(m_tiStep, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); + settings_sizer->Add(length_step_sizer); + + v_sizer->Add(settings_sizer); + v_sizer->Add(0, FromDIP(10), 0, wxEXPAND, 5); + m_btnStart = new Button(this, _L("OK")); + StateColor btn_bg_green(std::pair(wxColour(0, 137, 123), StateColor::Pressed), + std::pair(wxColour(38, 166, 154), StateColor::Hovered), + std::pair(wxColour(0, 150, 136), StateColor::Normal)); + + m_btnStart->SetBackgroundColor(btn_bg_green); + m_btnStart->SetBorderColor(wxColour(0, 150, 136)); + m_btnStart->SetTextColor(wxColour("#FFFFFE")); + m_btnStart->SetSize(wxSize(FromDIP(48), FromDIP(24))); + m_btnStart->SetMinSize(wxSize(FromDIP(48), FromDIP(24))); + m_btnStart->SetCornerRadius(FromDIP(3)); + m_btnStart->Bind(wxEVT_BUTTON, &Input_Shaping_Test_Dlg::on_start, this); + v_sizer->Add(m_btnStart, 0, wxALL | wxALIGN_RIGHT, FromDIP(5)); + + m_btnStart->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Input_Shaping_Test_Dlg::on_start), NULL, this); + + //wxGetApp().UpdateDlgDarkUI(this); + + Layout(); + Fit(); +} + +Input_Shaping_Test_Dlg::~Input_Shaping_Test_Dlg() { + // Disconnect Events + m_btnStart->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Input_Shaping_Test_Dlg::on_start), NULL, this); +} + +void Input_Shaping_Test_Dlg::on_start(wxCommandEvent& event) { + bool read_double = false; + read_double = m_tiStartX->GetTextCtrl()->GetValue().ToDouble(&m_params.start); + read_double = read_double && m_tiEndX->GetTextCtrl()->GetValue().ToDouble(&m_params.end); + read_double = read_double && m_tiStep->GetTextCtrl()->GetValue().ToDouble(&m_params.step); + + if (!read_double || m_params.start < 0 || m_params.step <= 0 || m_params.end < (m_params.start + m_params.step)) { + MessageDialog msg_dlg(nullptr, _L("Please input valid values:\nstart > 0 \step >= 0\nend > start + step)"), wxEmptyString, wxICON_WARNING | wxOK); + msg_dlg.ShowModal(); + return; + } + + m_params.mode = CalibMode::Calib_Input_shaping; + m_plater->calib_input_shaping(m_params); + EndModal(wxID_OK); + +} + +void Input_Shaping_Test_Dlg::on_dpi_changed(const wxRect& suggested_rect) { + this->Refresh(); + Fit(); + +} }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/calib_dlg.hpp b/src/slic3r/GUI/calib_dlg.hpp index b1bf8d8616..16098756e5 100644 --- a/src/slic3r/GUI/calib_dlg.hpp +++ b/src/slic3r/GUI/calib_dlg.hpp @@ -122,6 +122,27 @@ protected: Plater* m_plater; }; +class Input_Shaping_Test_Dlg : public DPIDialog +{ +public: + Input_Shaping_Test_Dlg (wxWindow* parent, wxWindowID id, Plater* plater); + ~Input_Shaping_Test_Dlg (); + void on_dpi_changed(const wxRect& suggested_rect) override; + +protected: + + virtual void on_start(wxCommandEvent& event); + Calib_Params m_params; + + TextInput* m_tiStartX; + TextInput* m_tiEndX; + TextInput* m_tiStartY; + TextInput* m_tiEndY; + TextInput* m_tiStep; + Button* m_btnStart; + Plater* m_plater; +}; + }} // namespace Slic3r::GUI #endif